Files: 2b05be8ee023fdd9580d6a845ba074a425756685 / app / html / modal.js
1517 bytesRaw
1 | const nest = require('depnest') |
2 | const { h, Value } = require('mutant') |
3 | |
4 | exports.gives = nest('app.html.modal') |
5 | |
6 | exports.create = (api) => { |
7 | return nest('app.html.modal', (content, { isOpen, onOpen, onClose, className = '' } = {}) => { |
8 | if (typeof isOpen !== 'function') isOpen = Value(false) |
9 | |
10 | const openMe = () => { |
11 | isOpen.set(true) |
12 | } |
13 | const closeMe = () => { |
14 | isOpen.set(false) |
15 | if (typeof onClose === 'function') onClose() |
16 | } |
17 | |
18 | const modal = h('Modal -closed', |
19 | { |
20 | className, |
21 | 'ev-click': closeMe, |
22 | 'ev-keydown': ev => { |
23 | if (ev.keyCode === 27) closeMe() // Escape |
24 | } |
25 | }, |
26 | [ |
27 | h('div.content', { 'ev-click': (ev) => ev.stopPropagation() }, [ |
28 | content |
29 | // I think content must be in the DOM for any downstream mutant Observers to be updating |
30 | ]) |
31 | ] |
32 | ) |
33 | |
34 | isOpen(state => { |
35 | if (state === true) { |
36 | modal.classList.remove('-closed') |
37 | modal.classList.add('-open') |
38 | } else { |
39 | modal.classList.remove('-open') |
40 | modal.classList.add('-closed') |
41 | return |
42 | } |
43 | |
44 | if (typeof onOpen === 'function') onOpen() |
45 | focus() |
46 | |
47 | function focus () { |
48 | if (!modal.isConnected) setTimeout(focus, 200) |
49 | else { |
50 | const target = modal.querySelector('input') || modal.querySelector('textarea') |
51 | if (target) target.focus() |
52 | } |
53 | } |
54 | }) |
55 | |
56 | modal.open = openMe |
57 | modal.close = closeMe |
58 | |
59 | return modal |
60 | }) |
61 | } |
62 |
Built with git-ssb-web