@ramstack/alpinegear-dialog 1.4.3 → 1.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +365 -394
- package/alpinegear-dialog.esm.js +190 -190
- package/alpinegear-dialog.esm.min.js +1 -1
- package/alpinegear-dialog.js +190 -190
- package/alpinegear-dialog.min.js +1 -1
- package/package.json +9 -3
package/alpinegear-dialog.js
CHANGED
|
@@ -1,199 +1,199 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
const warn = (...args) => console.warn("alpinegear.js:", ...args);
|
|
5
|
-
const is_dialog = el => el.matches("dialog");
|
|
6
|
-
|
|
7
|
-
const listen = (target, type, listener, options) => {
|
|
8
|
-
target.addEventListener(type, listener, options);
|
|
9
|
-
return () => target.removeEventListener(type, listener, options);
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
const closest = (el, callback) => {
|
|
13
|
-
while (el && !callback(el)) {
|
|
14
|
-
el = (el._x_teleportBack ?? el).parentElement;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return el;
|
|
4
|
+
const warn = (...args) => console.warn("alpinegear.js:", ...args);
|
|
5
|
+
const is_dialog = el => el.matches("dialog");
|
|
6
|
+
|
|
7
|
+
const listen = (target, type, listener, options) => {
|
|
8
|
+
target.addEventListener(type, listener, options);
|
|
9
|
+
return () => target.removeEventListener(type, listener, options);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const closest = (el, callback) => {
|
|
13
|
+
while (el && !callback(el)) {
|
|
14
|
+
el = (el._x_teleportBack ?? el).parentElement;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return el;
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
function plugin({ bind, directive }) {
|
|
21
|
-
directive("dialog", (el, { value }, { cleanup }) => {
|
|
22
|
-
const get_dialog_info = () => closest(el, n => n._r_dialog)?._r_dialog;
|
|
23
|
-
|
|
24
|
-
value ||= "";
|
|
25
|
-
|
|
26
|
-
if (!get_dialog_info() && value !== "modal" && value !== "") {
|
|
27
|
-
warn(`x-dialog:${value} is missing a parent x-dialog`);
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (value === "panel") {
|
|
32
|
-
process_panel();
|
|
33
|
-
}
|
|
34
|
-
else if (value === "trigger") {
|
|
35
|
-
process_trigger();
|
|
36
|
-
}
|
|
37
|
-
else if (value === "action") {
|
|
38
|
-
process_action();
|
|
39
|
-
}
|
|
40
|
-
else if (value === "modal" || !value) {
|
|
41
|
-
process_dialog();
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
warn(`Unknown x-dialog:${value} directive`);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function process_dialog() {
|
|
48
|
-
el._r_dialog = {
|
|
49
|
-
owner: el,
|
|
50
|
-
panel: null,
|
|
51
|
-
modal: value === "modal"
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
Object.defineProperty(el, "open", {
|
|
55
|
-
get() {
|
|
56
|
-
return !!el._r_dialog?.panel.open;
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
Object.assign(el, {
|
|
61
|
-
show() {
|
|
62
|
-
return dialog_show();
|
|
63
|
-
},
|
|
64
|
-
close(value) {
|
|
65
|
-
dialog_close(value);
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
bind(el, {
|
|
70
|
-
"x-data"() {
|
|
71
|
-
return {
|
|
72
|
-
open: false,
|
|
73
|
-
show() {
|
|
74
|
-
return dialog_show();
|
|
75
|
-
},
|
|
76
|
-
close(value) {
|
|
77
|
-
dialog_close(value);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function process_panel() {
|
|
85
|
-
if (get_dialog_info().panel) {
|
|
86
|
-
warn("x-dialog:panel is already present. Only the last one will be used.");
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (!is_dialog(el)) {
|
|
90
|
-
warn("x-dialog:panel should be used on a <dialog> element");
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const owner = get_dialog_info().owner;
|
|
95
|
-
get_dialog_info().panel = el;
|
|
96
|
-
|
|
97
|
-
bind(el, {
|
|
98
|
-
"x-init"() {
|
|
99
|
-
this.open = el.open;
|
|
100
|
-
},
|
|
101
|
-
"@toggle"(e) {
|
|
102
|
-
(this.open = el.open) && dispatch(owner, "open");
|
|
103
|
-
dispatch(owner, "toggle", { state: e.newState });
|
|
104
|
-
},
|
|
105
|
-
"@cancel.prevent"() {
|
|
106
|
-
dialog_close();
|
|
107
|
-
},
|
|
108
|
-
//
|
|
109
|
-
// https://issues.chromium.org/issues/346597066
|
|
110
|
-
// HTMLDialogElement's "cancel" event is not cancelable when "ESC" key is pressed several times
|
|
111
|
-
//
|
|
112
|
-
"@keydown.escape.prevent.stop"() {
|
|
113
|
-
//
|
|
114
|
-
// https://bugs.webkit.org/show_bug.cgi?id=284592
|
|
115
|
-
// Safari still lacks native support for the "closedby" attribute on <dialog>
|
|
116
|
-
//
|
|
117
|
-
if (["any", "closerequest"].includes(el.getAttribute("closedby"))) {
|
|
118
|
-
//
|
|
119
|
-
// "requestClose" fires a "cancel" event before firing the "close" event
|
|
120
|
-
//
|
|
121
|
-
el.requestClose();
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
cleanup(
|
|
127
|
-
//
|
|
128
|
-
// Listening to the "submit" event on the document element, ensuring (to some extent)
|
|
129
|
-
// that our handler executes last among all handlers listening for this event.
|
|
130
|
-
// This allows us to determine whether the event was canceled by someone else.
|
|
131
|
-
//
|
|
132
|
-
listen(document, "submit", e => {
|
|
133
|
-
if (e.target.method === "dialog" && closest(e.target, n => n === el) && !e.defaultPrevented) {
|
|
134
|
-
//
|
|
135
|
-
// Prevent the dialog from closing immediately,
|
|
136
|
-
// as we need to trigger our own custom events first.
|
|
137
|
-
//
|
|
138
|
-
e.preventDefault();
|
|
139
|
-
|
|
140
|
-
dialog_close(e.submitter?.value);
|
|
141
|
-
}
|
|
142
|
-
})
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function process_trigger() {
|
|
147
|
-
bind(el, {
|
|
148
|
-
"@click.prevent": "show"
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function process_action() {
|
|
153
|
-
if (!closest(el, is_dialog)) {
|
|
154
|
-
warn("x-dialog:action is missing a parent x-dialog:panel");
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
el.form || bind(el, {
|
|
159
|
-
"@click.prevent"() {
|
|
160
|
-
dialog_close(el.value);
|
|
161
|
-
}
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function dialog_show() {
|
|
166
|
-
const { panel, modal } = get_dialog_info();
|
|
167
|
-
|
|
168
|
-
if (panel) {
|
|
169
|
-
return new Promise(resolve => {
|
|
170
|
-
listen(panel, "close", () => resolve(panel.returnValue), { once: true });
|
|
171
|
-
panel[modal ? "showModal" : "show"]();
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return Promise.resolve();
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
function dialog_close(value) {
|
|
179
|
-
value ??= "";
|
|
180
|
-
|
|
181
|
-
const { owner, panel } = get_dialog_info();
|
|
182
|
-
const detail = { value };
|
|
183
|
-
|
|
184
|
-
if (dispatch(owner, "beforeclose", detail, { cancelable: true })) {
|
|
185
|
-
value && dispatch(owner, "close:" + value.toLowerCase(), detail);
|
|
186
|
-
dispatch(owner, "close", detail);
|
|
187
|
-
panel.close(value);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
function dispatch(el, name, detail = {}, options = {}) {
|
|
192
|
-
return el.dispatchEvent(new CustomEvent(name, { detail, ...options }));
|
|
193
|
-
}
|
|
194
|
-
});
|
|
20
|
+
function plugin({ bind, directive }) {
|
|
21
|
+
directive("dialog", (el, { value }, { cleanup }) => {
|
|
22
|
+
const get_dialog_info = () => closest(el, n => n._r_dialog)?._r_dialog;
|
|
23
|
+
|
|
24
|
+
value ||= "";
|
|
25
|
+
|
|
26
|
+
if (!get_dialog_info() && value !== "modal" && value !== "") {
|
|
27
|
+
warn(`x-dialog:${value} is missing a parent x-dialog`);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (value === "panel") {
|
|
32
|
+
process_panel();
|
|
33
|
+
}
|
|
34
|
+
else if (value === "trigger") {
|
|
35
|
+
process_trigger();
|
|
36
|
+
}
|
|
37
|
+
else if (value === "action") {
|
|
38
|
+
process_action();
|
|
39
|
+
}
|
|
40
|
+
else if (value === "modal" || !value) {
|
|
41
|
+
process_dialog();
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
warn(`Unknown x-dialog:${value} directive`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function process_dialog() {
|
|
48
|
+
el._r_dialog = {
|
|
49
|
+
owner: el,
|
|
50
|
+
panel: null,
|
|
51
|
+
modal: value === "modal"
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
Object.defineProperty(el, "open", {
|
|
55
|
+
get() {
|
|
56
|
+
return !!el._r_dialog?.panel.open;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
Object.assign(el, {
|
|
61
|
+
show() {
|
|
62
|
+
return dialog_show();
|
|
63
|
+
},
|
|
64
|
+
close(value) {
|
|
65
|
+
dialog_close(value);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
bind(el, {
|
|
70
|
+
"x-data"() {
|
|
71
|
+
return {
|
|
72
|
+
open: false,
|
|
73
|
+
show() {
|
|
74
|
+
return dialog_show();
|
|
75
|
+
},
|
|
76
|
+
close(value) {
|
|
77
|
+
dialog_close(value);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function process_panel() {
|
|
85
|
+
if (get_dialog_info().panel) {
|
|
86
|
+
warn("x-dialog:panel is already present. Only the last one will be used.");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (!is_dialog(el)) {
|
|
90
|
+
warn("x-dialog:panel should be used on a <dialog> element");
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const owner = get_dialog_info().owner;
|
|
95
|
+
get_dialog_info().panel = el;
|
|
96
|
+
|
|
97
|
+
bind(el, {
|
|
98
|
+
"x-init"() {
|
|
99
|
+
this.open = el.open;
|
|
100
|
+
},
|
|
101
|
+
"@toggle"(e) {
|
|
102
|
+
(this.open = el.open) && dispatch(owner, "open");
|
|
103
|
+
dispatch(owner, "toggle", { state: e.newState });
|
|
104
|
+
},
|
|
105
|
+
"@cancel.prevent"() {
|
|
106
|
+
dialog_close();
|
|
107
|
+
},
|
|
108
|
+
//
|
|
109
|
+
// https://issues.chromium.org/issues/346597066
|
|
110
|
+
// HTMLDialogElement's "cancel" event is not cancelable when "ESC" key is pressed several times
|
|
111
|
+
//
|
|
112
|
+
"@keydown.escape.prevent.stop"() {
|
|
113
|
+
//
|
|
114
|
+
// https://bugs.webkit.org/show_bug.cgi?id=284592
|
|
115
|
+
// Safari still lacks native support for the "closedby" attribute on <dialog>
|
|
116
|
+
//
|
|
117
|
+
if (["any", "closerequest"].includes(el.getAttribute("closedby"))) {
|
|
118
|
+
//
|
|
119
|
+
// "requestClose" fires a "cancel" event before firing the "close" event
|
|
120
|
+
//
|
|
121
|
+
el.requestClose();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
cleanup(
|
|
127
|
+
//
|
|
128
|
+
// Listening to the "submit" event on the document element, ensuring (to some extent)
|
|
129
|
+
// that our handler executes last among all handlers listening for this event.
|
|
130
|
+
// This allows us to determine whether the event was canceled by someone else.
|
|
131
|
+
//
|
|
132
|
+
listen(document, "submit", e => {
|
|
133
|
+
if (e.target.method === "dialog" && closest(e.target, n => n === el) && !e.defaultPrevented) {
|
|
134
|
+
//
|
|
135
|
+
// Prevent the dialog from closing immediately,
|
|
136
|
+
// as we need to trigger our own custom events first.
|
|
137
|
+
//
|
|
138
|
+
e.preventDefault();
|
|
139
|
+
|
|
140
|
+
dialog_close(e.submitter?.value);
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function process_trigger() {
|
|
147
|
+
bind(el, {
|
|
148
|
+
"@click.prevent": "show"
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function process_action() {
|
|
153
|
+
if (!closest(el, is_dialog)) {
|
|
154
|
+
warn("x-dialog:action is missing a parent x-dialog:panel");
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
el.form || bind(el, {
|
|
159
|
+
"@click.prevent"() {
|
|
160
|
+
dialog_close(el.value);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function dialog_show() {
|
|
166
|
+
const { panel, modal } = get_dialog_info();
|
|
167
|
+
|
|
168
|
+
if (panel) {
|
|
169
|
+
return new Promise(resolve => {
|
|
170
|
+
listen(panel, "close", () => resolve(panel.returnValue), { once: true });
|
|
171
|
+
panel[modal ? "showModal" : "show"]();
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return Promise.resolve();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function dialog_close(value) {
|
|
179
|
+
value ??= "";
|
|
180
|
+
|
|
181
|
+
const { owner, panel } = get_dialog_info();
|
|
182
|
+
const detail = { value };
|
|
183
|
+
|
|
184
|
+
if (dispatch(owner, "beforeclose", detail, { cancelable: true })) {
|
|
185
|
+
value && dispatch(owner, "close:" + value.toLowerCase(), detail);
|
|
186
|
+
dispatch(owner, "close", detail);
|
|
187
|
+
panel.close(value);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function dispatch(el, name, detail = {}, options = {}) {
|
|
192
|
+
return el.dispatchEvent(new CustomEvent(name, { detail, ...options }));
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
document
|
|
197
|
+
listen(document, "alpine:init", () => Alpine.plugin(plugin));
|
|
198
198
|
|
|
199
199
|
})();
|
package/alpinegear-dialog.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(){"use strict";const e=(...e)=>console.warn("alpinegear.js:",...e),n=e=>e.matches("dialog"),o=(e,n,o,t)=>(e.addEventListener(n,o,t),()=>e.removeEventListener(n,o,t)),t=(e,n)=>{for(;e&&!n(e);)e=(e._x_teleportBack??e).parentElement;return e};function
|
|
1
|
+
!function(){"use strict";const e=(...e)=>console.warn("alpinegear.js:",...e),n=e=>e.matches("dialog"),o=(e,n,o,t)=>(e.addEventListener(n,o,t),()=>e.removeEventListener(n,o,t)),t=(e,n)=>{for(;e&&!n(e);)e=(e._x_teleportBack??e).parentElement;return e};function l({bind:l,directive:a}){a("dialog",(a,{value:i},{cleanup:s})=>{const r=()=>t(a,e=>e._r_dialog)?._r_dialog;function c(){const{panel:e,modal:n}=r();return e?new Promise(t=>{o(e,"close",()=>t(e.returnValue),{once:!0}),e[n?"showModal":"show"]()}):Promise.resolve()}function d(e){e??="";const{owner:n,panel:o}=r(),t={value:e};p(n,"beforeclose",t,{cancelable:!0})&&(e&&p(n,"close:"+e.toLowerCase(),t),p(n,"close",t),o.close(e))}function p(e,n,o={},t={}){return e.dispatchEvent(new CustomEvent(n,{detail:o,...t}))}i||="",r()||"modal"===i||""===i?"panel"===i?function(){if(!n(a))return void e("x-dialog:panel should be used on a <dialog> element");const i=r().owner;r().panel=a,l(a,{"x-init"(){this.open=a.open},"@toggle"(e){(this.open=a.open)&&p(i,"open"),p(i,"toggle",{state:e.newState})},"@cancel.prevent"(){d()},"@keydown.escape.prevent.stop"(){["any","closerequest"].includes(a.getAttribute("closedby"))&&a.requestClose()}}),s(o(document,"submit",e=>{"dialog"===e.target.method&&t(e.target,e=>e===a)&&!e.defaultPrevented&&(e.preventDefault(),d(e.submitter?.value))}))}():"trigger"===i?l(a,{"@click.prevent":"show"}):"action"===i?t(a,n)?a.form||l(a,{"@click.prevent"(){d(a.value)}}):e("x-dialog:action is missing a parent x-dialog:panel"):"modal"!==i&&i||(a._r_dialog={owner:a,panel:null,modal:"modal"===i},Object.defineProperty(a,"open",{get:()=>!!a._r_dialog?.panel.open}),Object.assign(a,{show:()=>c(),close(e){d(e)}}),l(a,{"x-data":()=>({open:!1,show:()=>c(),close(e){d(e)}})})):e(`x-dialog:${i} is missing a parent x-dialog`)})}o(document,"alpine:init",()=>Alpine.plugin(l))}();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ramstack/alpinegear-dialog",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.4",
|
|
4
4
|
"description": "A headless, unstyled directive-based dialog (modal) component for Alpine.js, built on the native <dialog> element",
|
|
5
5
|
"author": "Rameel Burhan",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,6 +21,12 @@
|
|
|
21
21
|
"alpinejs-component",
|
|
22
22
|
"htmx"
|
|
23
23
|
],
|
|
24
|
-
"
|
|
25
|
-
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"import": {
|
|
27
|
+
"production": "./alpinegear-dialog.esm.min.js",
|
|
28
|
+
"default": "./alpinegear-dialog.esm.js"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
26
32
|
}
|