Welcome to mirror list, hosted at ThFree Co, Russian Federation.

dialog.js « src « ui « packages « alpinejs - github.com/gohugoio/hugo-mod-jslibs-dist.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 6bb7a35e3872b2a3bad82e2c029cdc1144aea414 (plain)
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') },
    })
}