├── .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`` 40 | var overlay = yo`` 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 | --------------------------------------------------------------------------------