├── .gitignore
├── README.md
├── example.css
├── example.js
├── index.html
├── index.js
├── package.json
└── test
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | bundle.js
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # modal-element
2 |
3 | A basic modal element built on [yo-yo](https://github.com/maxogden/yo-yo).
4 |
5 | ## Example
6 |
7 | ```js
8 | var createModal = require('modal-element')
9 | var yo = require('yo-yo')
10 |
11 | var contents = yo`
12 |
Header
13 |
This is a modal
14 |
`
15 |
16 | // Render the modal with contents
17 | var modal = createModal(modalContents)
18 |
19 | // Call to hide modal
20 | modal.hide()
21 |
22 | // Call to show the modal again
23 | modal.show()
24 | ```
25 |
26 | ## API
27 |
28 | ### `var modal = createModal(contents)`
29 | Creates a new modal element.
30 |
31 | #### `modal.toggle([newContents])`
32 | Will hide or show modal.
33 |
34 | #### `modal.show([newContents])`
35 | Shows the modal and/or overrides the contents.
36 |
37 | #### `modal.hide()`
38 | Hides the modal.
39 |
40 | # license
41 | (c) 2016 Kyle Robinson Young. MIT License
42 |
--------------------------------------------------------------------------------
/example.css:
--------------------------------------------------------------------------------
1 | @import url(http://fonts.googleapis.com/css?family=Roboto);
2 |
3 | * {
4 | box-sizing: border-box;
5 | }
6 | body {
7 | font-family: 'Roboto', Helvetica, sans-serif;
8 | color: #212121;
9 | background-color: #e3f2fd;
10 | }
11 |
12 | button.open-modal {
13 | position: fixed;
14 | top: 20%;
15 | left: 50%;
16 | padding: 1em;
17 | font-size: 2em;
18 | width: 10em;
19 | margin-left: -5em;
20 | cursor: pointer;
21 | background-color: #fafafa;
22 | color: #212121;
23 | border: none;
24 | -webkit-box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
25 | -moz-box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
26 | box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
27 | border-radius: 3px;
28 | }
29 |
30 | .modal {
31 | background-color: #fafafa;
32 | width: 20rem;
33 | padding: 1rem;
34 | border-radius: 3px;
35 | }
36 | .modal-overlay {
37 | background-color: rgba(0, 0, 0, .3);
38 | display: flex;
39 | justify-content: center;
40 | align-items: center;
41 | }
42 |
--------------------------------------------------------------------------------
/example.js:
--------------------------------------------------------------------------------
1 | var document = require('global/document')
2 | var createModal = require('./index.js')
3 | var yo = require('yo-yo')
4 |
5 | var modalContents = yo`
6 |
Oh, hi there!
7 |
10 | `
11 | var modal = createModal(modalContents)
12 |
13 | function render () {
14 | return yo`
15 |
18 | ${modal}
19 |
`
20 | }
21 |
22 | var root = render()
23 | document.body.appendChild(root)
24 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | modal-element
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | var yo = require('yo-yo')
2 | var assign = require('object-assign')
3 | var document = require('global/document')
4 | var onload = require('on-load')
5 |
6 | module.exports = function modalElement (contents) {
7 | var el = render(contents)
8 | function modalShow (newContents) {
9 | if (newContents) contents = newContents
10 | el = yo.update(el, render(contents))
11 | }
12 | function modalHide () {
13 | el = yo.update(el, document.createTextNode(''))
14 | }
15 | function modalToggle (newContents) {
16 | if (!el || el.nodeName === '#text') {
17 | modalShow(newContents)
18 | } else {
19 | modalHide()
20 | }
21 | }
22 | function didClickOut (e) {
23 | var modal = el.children[0]
24 | var source = e.target
25 | while (source.parentNode) {
26 | if (source === modal) {
27 | return true
28 | }
29 | source = source.parentNode
30 | }
31 | modalHide()
32 | }
33 | el.show = modalShow
34 | el.hide = modalHide
35 | el.toggle = modalToggle
36 | return el
37 |
38 | function render (contents) {
39 | var modal = yo`${contents}
`
40 | var overlay = yo`${modal}
`
41 | onload(overlay, function () {
42 | document.addEventListener('mousedown', didClickOut, false)
43 | }, function () {
44 | document.removeEventListener('mousedown', didClickOut, false)
45 | })
46 | assign(overlay.style, {
47 | position: 'fixed',
48 | height: '100%',
49 | width: '100%',
50 | top: 0,
51 | left: 0,
52 | 'z-index': '9999'
53 | })
54 | return overlay
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "modal-element",
3 | "version": "2.0.0",
4 | "description": "A basic modal DOM element",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "budo example.js:bundle.js",
8 | "gh": "browserify example.js -o bundle.js",
9 | "test:lint": "standard --format",
10 | "test:browser": "browserify test/*.js | tape-run",
11 | "test": "npm run test:lint && npm run test:browser"
12 | },
13 | "author": "Kyle Robinson Young (http://dontkry.com)",
14 | "license": "MIT",
15 | "repository": {
16 | "type": "git",
17 | "url": "git@github.com:shama/modal-element.git"
18 | },
19 | "keywords": [
20 | "yo-yo",
21 | "dom",
22 | "element",
23 | "modal"
24 | ],
25 | "dependencies": {
26 | "global": "^4.3.0",
27 | "object-assign": "^2.1.1",
28 | "on-load": "^2.1.0",
29 | "yo-yo": "^1.2.1"
30 | },
31 | "devDependencies": {
32 | "browserify": "^13.1.0",
33 | "budo": "^8.3.0",
34 | "standard": "^3.7.1",
35 | "tape": "^4.6.0",
36 | "tape-run": "^2.1.4"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | /* global HTMLDivElement */
2 | const yo = require('yo-yo')
3 | const test = require('tape')
4 |
5 | const modalElement = require('../')
6 |
7 | test('create with no contents', function (t) {
8 | var modal = modalElement()
9 | isModal(t, modal)
10 | t.equal(modal.textContent, '')
11 | var body = getBody(modal)
12 | t.equal(body, undefined)
13 | t.end()
14 | })
15 |
16 | test('create with some contents', function (t) {
17 | var modal = modalElement(yo`
18 | modal!
19 | `)
20 | isModal(t, modal)
21 | t.equal(modal.textContent, 'modal!')
22 | var body = getBody(modal)
23 | t.equal(body.className, 'test')
24 | t.equal(body.innerHTML, 'modal!')
25 | t.end()
26 | })
27 |
28 | test('update the contents', function (t) {
29 | var modal = modalElement()
30 | modal.show(yo`
31 | modal!
32 | `)
33 | isModal(t, modal)
34 | var body = getBody(modal)
35 | t.equal(body.className, 'test')
36 | t.equal(body.innerHTML, 'modal!')
37 | t.end()
38 | })
39 |
40 | test('remove the contents', function (t) {
41 | var modal = modalElement(yo`
42 | modal!
43 | `)
44 | modal.hide()
45 | var body = getBody(modal)
46 | t.equal(body.className, 'test')
47 | t.equal(body.innerHTML, 'modal!')
48 | t.end()
49 | })
50 |
51 | test('remove and re-create the contents', function (t) {
52 | var modal = modalElement()
53 | modal.hide()
54 | modal.show(yo`
55 | modal!
56 | `)
57 | var body = getBody(modal)
58 | t.equal(body, undefined)
59 | t.end()
60 | })
61 |
62 | function isModal (t, modal) {
63 | t.ok(modal instanceof HTMLDivElement)
64 | t.equal(modal.className, 'modal-overlay')
65 | t.equal(modal.children[0].className, 'modal')
66 | t.equal(typeof modal.show, 'function')
67 | t.equal(typeof modal.hide, 'function')
68 | t.equal(typeof modal.toggle, 'function')
69 | }
70 |
71 | function getBody (modal) {
72 | return modal.children[0].children[0]
73 | }
74 |
--------------------------------------------------------------------------------