Skip to content

Commit

Permalink
feat: Extend nanocomponent API
Browse files Browse the repository at this point in the history
BREAKING CHANGE: .element is deprecated for similar .render
  • Loading branch information
finnp committed Mar 24, 2018
1 parent 45d98d8 commit 5f4d05f
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 98 deletions.
4 changes: 2 additions & 2 deletions example/example.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ var button = document.querySelector('button')
var message = document.querySelector('#message')
var repo = document.querySelector('#repo')

document.body.appendChild(notifications.element())
document.body.appendChild(notifications.render([]))

button.onclick = function () {
var type = document.querySelector('input:checked').value
notifications.options.repo = repo.value
notifications.repo = repo.value
notifications.add({message: message.value, type: type})
}
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
var main = require('./main')
var Notifications = require('./main')
var style = require('./style')
var insertCss = require('insert-css')

module.exports = function (opts) {
insertCss(style)
return main(opts)
return new Notifications(opts)
}
143 changes: 65 additions & 78 deletions main.js
Original file line number Diff line number Diff line change
@@ -1,104 +1,91 @@
var yo = require('yo-yo')
var defaults = require('lodash.defaults')
var Nanocomponent = require('nanocomponent')
var html = require('nanohtml')

module.exports = function (opts) {
opts = opts || {}
class Notifications extends Nanocomponent {
constructor (opts) {
opts = opts || {}
super()

opts.icons = defaults(opts.icons, {
error: 'octicon octicon-flame',
warning: 'octicon octicon-alert',
info: 'octicon octicon-info',
success: 'octicon octicon-check',
close: 'octicon octicon-x'
})
this.repo = opts.repo
this.icons = Object.assign({
error: 'octicon octicon-flame',
warning: 'octicon octicon-alert',
info: 'octicon octicon-info',
success: 'octicon octicon-check',
close: 'octicon octicon-x'
}, opts.icons)

var notifications = []
var tree

return {
element: element,
render: render,
add: add,
error: error,
info: info,
warning: warning,
success: success,
state: notifications,
options: opts
}

function add (notification) {
if (typeof notification === 'string') notification = {message: notification}
notifications.push(notification)
update()
}

function error (message) {
add({type: 'error', message: message})
}

function info (message) {
add({type: 'info', message: message})
this.getMessageBody = this.getMessageBody.bind(this)
this.notifications = []
}

function warning (message) {
add({type: 'warning', message: message})
add (notification) {
this.notifications.push(notification)
this.rerender()
}

function success (message) {
add({type: 'success', message: message})
info (text) {
this.add({type: 'info', message: text})
}

function element () {
tree = render()
return tree
error (text) {
this.add({type: 'error', message: text})
}

function update () {
yo.update(tree, render())
warning (text) {
this.add({type: 'warning', message: text})
}

function render () {
return yo`
<div class="notification-container">
${
notifications
.map(function (notification) {
var classNames = [
'notification',
notification.closed ? 'notification-hidden' : 'notification-show',
'notification-' + (notification.type || 'info')
]
return yo`
<div class="${classNames.join(' ')}">
<div class="notification-icon">
<span>
<span class="${opts.icons[notification.type || 'info']}"></span>
</span>
</div>
${getMessageBody(notification)}
<span onclick=${function () { notification.closed = true; update() }} class="notification-close" title="Dismiss this notification">
<span class="${opts.icons.close}"></span>
</span>
</div>`
})
}
</div>`
success (text) {
this.add({type: 'success', message: text})
}

function getMessageBody (notification) {
getMessageBody (notification) {
if (notification.element) {
notification.element.className = 'notification-message'
return notification.element
}
if (opts.repo && notification.type === 'error') {
return yo`
if (this.repo && notification.type === 'error') {
return html`
<div class="notification-message">
${notification.message}<br>
<a href="${opts.repo}/issues/new?title=${encodeURI(notification.message)}" target="_blank" rel="noopener noreferrer" class="notification-btn">Create an issue for this error</a>
<a href="${this.repo}/issues/new?title=${encodeURI(notification.message)}" target="_blank" rel="noopener noreferrer" class="notification-btn">Create an issue for this error</a>
</div>`
} else {
return yo`<div class="notification-message">${notification.message}</div>`
return html`<div class="notification-message">${notification.message}</div>`
}
}

createElement (notifications) {
if (notifications) this.notifications = notifications
return html`<div class="notification-container">${
notifications
.map((notification) => {
var classNames = [
'notification',
notification.closed ? 'notification-hidden' : 'notification-show',
'notification-' + (notification.type || 'info')
]
return html`
<div class="${classNames.join(' ')}">
<div class="notification-icon">
<span>
<span class="${this.icons[notification.type || 'info']}"></span>
</span>
</div>
${this.getMessageBody(notification)}
<span onclick=${() => { notification.closed = true; this.rerender() }} class="notification-close" title="Dismiss this notification">
<span class="${this.icons.close}"></span>
</span>
</div>`
})
}
</div>`
}

update (notifications) {
return notifications !== this.notifications
}
}

module.exports = Notifications
20 changes: 13 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@
"license": "ISC",
"dependencies": {
"insert-css": "2.0.0",
"lodash.defaults": "4.2.0",
"yo-yo": "^1.2.2"
"nanocomponent": "6.5.1",
"nanohtml": "1.2.2"
},
"devDependencies": {
"browserify": "15.2.0",
"cz-conventional-changelog": "^2.1.0",
"gh-pages": "1.1.0",
"standard": "10.0.3",
"semantic-release": "^12.2.4"
"semantic-release": "^12.2.4",
"standard": "^11.0.1"
},
"directories": {
"example": "example"
Expand All @@ -29,15 +30,20 @@
"url": "https://github.com/finnp/dom-notifications.git"
},
"keywords": [
"nanohtml",
"yo-yo",
"bel",
"choo",
"atom",
"notifications",
"tcby"
"notifications"
],
"bugs": {
"url": "https://github.com/finnp/dom-notifications/issues"
},
"homepage": "https://github.com/finnp/dom-notifications#readme"
"homepage": "https://github.com/finnp/dom-notifications#readme",
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
}
21 changes: 12 additions & 9 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# dom-notifications [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)

# dom-notifications
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
[![Greenkeeper badge](https://badges.greenkeeper.io/finnp/dom-notifications.svg)](https://greenkeeper.io/)
[![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard)
[![nanocomponent 6](https://img.shields.io/badge/nanocomponent-6-green.svg)](https://github.com/choojs/nanocomponent)

![example gif](http://i.giphy.com/l41YBkA7AKgVXXwjK.gif)

Expand All @@ -16,7 +16,7 @@ Install with `npm install dom-notifications --save` and use something like
var domNotifications = require('dom-notifications')
var notifications = domNotifications(options)

document.body.appendChild(notifications.element())
document.body.appendChild(notifications.render())

notifications.add({message: 'You are now logged in'}) // defaults to `info`
notifications.add({message: 'This is a warning', type: 'warning'})
Expand Down Expand Up @@ -51,21 +51,22 @@ button to the error notifications.
If you need more customization, instead of using the `message` property, you
can also specify an `element` property and set it to `DOMElement` that will be the content.
For example with [yo-yo](https://github.com/maxogden/yo-yo):
For example with [nanohtml](http://github.com/choojs/nanohtml):
```js
notifications.add({
type: 'error',
element: yo`<div>
element: html`<div>
<strong>My super custom <em>message</em>!</strong>
</div>`
})
```
Notifications extends [Nanocomponent](https://github.com/choojs/nanocomponent).
### `notifications.element()`
### `notifications.render(state?)`
Creates the root element for the component. Call this ones to append it to
the DOM.
the DOM. Optionally state is an array of notifications
### `notifications.add(notification)`
Expand Down Expand Up @@ -93,7 +94,9 @@ If you don't want the styles to be used (or applied automatically),
you can also use the module like this:
```js
var domNotifications = require('dom-notifications/main')
var Notifications = require('dom-notifications/main')
var notifications = new Notifications()
// optionally apply styles yourself
var styles = require('dom-notifications/styles')
Expand Down

0 comments on commit 5f4d05f

Please sign in to comment.