1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
export default function (Alpine) {
Alpine.directive('dialog', (el, directive) => {
if (directive.value === 'overlay') handleOverlay(el, Alpine)
else if (directive.value === 'panel') handlePanel(el, Alpine)
else if (directive.value === 'title') handleTitle(el, Alpine)
else if (directive.value === 'description') handleDescription(el, Alpine)
else handleRoot(el, Alpine)
})
Alpine.magic('dialog', el => {
let $data = Alpine.$data(el)
return {
get open() {
return $data.__isOpen
},
close() {
$data.__close()
}
}
})
}
function handleRoot(el, Alpine) {
Alpine.bind(el, {
'x-data'() {
return {
init() {
// If the user chose to use :open and @close instead of x-model.
(Alpine.bound(el, 'open') !== undefined) && Alpine.effect(() => {
this.__isOpenState = Alpine.bound(el, 'open')
})
if (Alpine.bound(el, 'initial-focus') !== undefined) this.$watch('__isOpenState', () => {
if (! this.__isOpenState) return
setTimeout(() => {
Alpine.bound(el, 'initial-focus').focus()
}, 0);
})
},
__isOpenState: false,
__close() {
if (Alpine.bound(el, 'open')) this.$dispatch('close')
else this.__isOpenState = false
},
get __isOpen() {
return Alpine.bound(el, 'static', this.__isOpenState)
},
}
},
'x-modelable': '__isOpenState',
'x-id'() { return ['alpine-dialog-title', 'alpine-dialog-description'] },
'x-show'() { return this.__isOpen },
'x-trap.inert.noscroll'() { return this.__isOpen },
'@keydown.escape'() { this.__close() },
':aria-labelledby'() { return this.$id('alpine-dialog-title') },
':aria-describedby'() { return this.$id('alpine-dialog-description') },
'role': 'dialog',
'aria-modal': 'true',
})
}
function handleOverlay(el, Alpine) {
Alpine.bind(el, {
'x-init'() { if (this.$data.__isOpen === undefined) console.warn('"x-dialog:overlay" is missing a parent element with "x-dialog".') },
'x-show'() { return this.__isOpen },
'@click.prevent.stop'() { this.$data.__close() },
})
}
function handlePanel(el, Alpine) {
Alpine.bind(el, {
'@click.outside'() { this.$data.__close() },
'x-show'() { return this.$data.__isOpen },
})
}
function handleTitle(el, Alpine) {
Alpine.bind(el, {
'x-init'() { if (this.$data.__isOpen === undefined) console.warn('"x-dialog:title" is missing a parent element with "x-dialog".') },
':id'() { return this.$id('alpine-dialog-title') },
})
}
function handleDescription(el, Alpine) {
Alpine.bind(el, {
':id'() { return this.$id('alpine-dialog-description') },
})
}
|