Skip to content

Commit 4602662

Browse files
committed
Release v2.2
1 parent 002d9d9 commit 4602662

File tree

7 files changed

+348
-283
lines changed

7 files changed

+348
-283
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
## [2.2.0] - 2025-10-09
10+
### Added
11+
- Support for native `closeby` attribute,
12+
This will replace the custom `closeby` Alpine modifier, in a later release
13+
- Support for handling the evaluate action when the native dialog close event is triggered.
14+
This extending the first step we made for form submits, but now also for the backdrop and escape key
15+
16+
### Fixed
17+
- Closing of all open dialogs when pressing the escape key
18+
919
## [2.1.1] - 2025-05-08
1020
### Fixed
1121
- Return value for `closeby`

dist/index.cjs

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -29,49 +29,68 @@ function dialog_default(Alpine) {
2929
function fylgjaAlpineDialog(el, { expression, modifiers }, { evaluateLater, cleanup }) {
3030
const evaluate = expression.length ? evaluateLater(expression) : () => {
3131
};
32+
const canEvaluate = expression.length > 0;
3233
const lockPageScroll = modifiers.includes("noscroll");
33-
const closeby = modifierValue(modifiers, "closeby", "any");
34+
const closeBy = el.hasAttribute("closeby") ? el.getAttribute("closeby") : modifierValue(modifiers, "closeby", "closerequest");
3435
el.style.display = null;
35-
el.hidden = false;
3636
el.style.length === 0 && el.removeAttribute("style");
37-
el.addEventListener("keydown", escapeDialog);
38-
el.addEventListener("click", backdropDialog);
39-
el.addEventListener("submit", methodDialog);
37+
if (el._x_isShown) {
38+
open();
39+
}
40+
const closeBySupported = (() => {
41+
return "closedBy" in HTMLDialogElement.prototype;
42+
})();
4043
function scrollLock(use = true) {
4144
document.body.style.overflow = use ? "hidden" : "";
4245
}
43-
function methodDialog(event) {
44-
if (event.target.getAttribute("method") === "dialog" || event.submitter && event.submitter.getAttribute("formmethod") === "dialog") {
45-
evaluate();
46+
function dialogSubmit(event) {
47+
var _a;
48+
if ((event.target.getAttribute("method") === "dialog" || ((_a = event.submitter) == null ? void 0 : _a.getAttribute("formmethod")) === "dialog") && !canEvaluate) {
49+
event.preventDefault();
4650
}
4751
}
4852
function escapeDialog(event) {
49-
if (event.key !== "Escape") return;
50-
event.preventDefault();
51-
if (closeby !== "any" && closeby !== "closerequest") return;
52-
evaluate();
53+
if (event.key === "Escape" && !canEvaluate) {
54+
event.preventDefault();
55+
}
5356
}
54-
function backdropDialog(event) {
55-
if (event.target !== el || closeby !== "any") return;
57+
function handleCloseByEvent(event) {
58+
if (event.target !== el) return;
5659
const rect = el.getBoundingClientRect();
5760
const isInDialog = rect.top <= event.clientY && event.clientY <= rect.top + rect.height && rect.left <= event.clientX && event.clientX <= rect.left + rect.width;
58-
if (isInDialog) return;
61+
if (!isInDialog) {
62+
if (closeBy === "any") {
63+
if (closeBySupported) {
64+
event.preventDefault();
65+
}
66+
evaluate();
67+
}
68+
}
69+
}
70+
function handleCloseEvent() {
5971
evaluate();
6072
}
61-
el._x_doShow = () => {
73+
function open() {
6274
if (el.hasAttribute("open")) return;
6375
el.showModal();
6476
scrollLock(lockPageScroll);
65-
};
66-
el._x_doHide = () => {
77+
}
78+
function close() {
6779
if (!el.hasAttribute("open")) return;
6880
el.close();
6981
scrollLock(false);
70-
};
82+
}
83+
el._x_doShow = () => open();
84+
el._x_doHide = () => close();
85+
el.addEventListener("keydown", escapeDialog);
86+
el.addEventListener("submit", dialogSubmit);
87+
el.addEventListener("click", handleCloseByEvent);
88+
el.addEventListener("cancel", handleCloseEvent);
7189
cleanup(() => {
7290
el.removeEventListener("keydown", escapeDialog);
73-
el.removeEventListener("click", backdropDialog);
74-
el.removeEventListener("submit", methodDialog);
91+
el.removeEventListener("submit", dialogSubmit);
92+
el.removeEventListener("click", handleCloseByEvent);
93+
el.removeEventListener("cancel", handleCloseEvent);
7594
scrollLock(false);
7695
});
7796
}

dist/index.js

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,49 +5,67 @@
55
function fylgjaAlpineDialog(el, { expression, modifiers }, { evaluateLater, cleanup }) {
66
const evaluate = expression.length ? evaluateLater(expression) : () => {
77
};
8+
const canEvaluate = expression.length > 0;
89
const lockPageScroll = modifiers.includes("noscroll");
9-
const closeby = modifierValue(modifiers, "closeby", "any");
10+
const closeBy = el.hasAttribute("closeby") ? el.getAttribute("closeby") : modifierValue(modifiers, "closeby", "closerequest");
1011
el.style.display = null;
11-
el.hidden = false;
1212
el.style.length === 0 && el.removeAttribute("style");
13-
el.addEventListener("keydown", escapeDialog);
14-
el.addEventListener("click", backdropDialog);
15-
el.addEventListener("submit", methodDialog);
13+
if (el._x_isShown) {
14+
open();
15+
}
16+
const closeBySupported = (() => {
17+
return "closedBy" in HTMLDialogElement.prototype;
18+
})();
1619
function scrollLock(use = true) {
1720
document.body.style.overflow = use ? "hidden" : "";
1821
}
19-
function methodDialog(event) {
20-
if (event.target.getAttribute("method") === "dialog" || event.submitter && event.submitter.getAttribute("formmethod") === "dialog") {
21-
evaluate();
22+
function dialogSubmit(event) {
23+
if ((event.target.getAttribute("method") === "dialog" || event.submitter?.getAttribute("formmethod") === "dialog") && !canEvaluate) {
24+
event.preventDefault();
2225
}
2326
}
2427
function escapeDialog(event) {
25-
if (event.key !== "Escape") return;
26-
event.preventDefault();
27-
if (closeby !== "any" && closeby !== "closerequest") return;
28-
evaluate();
28+
if (event.key === "Escape" && !canEvaluate) {
29+
event.preventDefault();
30+
}
2931
}
30-
function backdropDialog(event) {
31-
if (event.target !== el || closeby !== "any") return;
32+
function handleCloseByEvent(event) {
33+
if (event.target !== el) return;
3234
const rect = el.getBoundingClientRect();
3335
const isInDialog = rect.top <= event.clientY && event.clientY <= rect.top + rect.height && rect.left <= event.clientX && event.clientX <= rect.left + rect.width;
34-
if (isInDialog) return;
36+
if (!isInDialog) {
37+
if (closeBy === "any") {
38+
if (closeBySupported) {
39+
event.preventDefault();
40+
}
41+
evaluate();
42+
}
43+
}
44+
}
45+
function handleCloseEvent() {
3546
evaluate();
3647
}
37-
el._x_doShow = () => {
48+
function open() {
3849
if (el.hasAttribute("open")) return;
3950
el.showModal();
4051
scrollLock(lockPageScroll);
41-
};
42-
el._x_doHide = () => {
52+
}
53+
function close() {
4354
if (!el.hasAttribute("open")) return;
4455
el.close();
4556
scrollLock(false);
46-
};
57+
}
58+
el._x_doShow = () => open();
59+
el._x_doHide = () => close();
60+
el.addEventListener("keydown", escapeDialog);
61+
el.addEventListener("submit", dialogSubmit);
62+
el.addEventListener("click", handleCloseByEvent);
63+
el.addEventListener("cancel", handleCloseEvent);
4764
cleanup(() => {
4865
el.removeEventListener("keydown", escapeDialog);
49-
el.removeEventListener("click", backdropDialog);
50-
el.removeEventListener("submit", methodDialog);
66+
el.removeEventListener("submit", dialogSubmit);
67+
el.removeEventListener("click", handleCloseByEvent);
68+
el.removeEventListener("cancel", handleCloseEvent);
5169
scrollLock(false);
5270
});
5371
}

dist/index.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.mjs

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,49 +4,67 @@ function dialog_default(Alpine) {
44
function fylgjaAlpineDialog(el, { expression, modifiers }, { evaluateLater, cleanup }) {
55
const evaluate = expression.length ? evaluateLater(expression) : () => {
66
};
7+
const canEvaluate = expression.length > 0;
78
const lockPageScroll = modifiers.includes("noscroll");
8-
const closeby = modifierValue(modifiers, "closeby", "any");
9+
const closeBy = el.hasAttribute("closeby") ? el.getAttribute("closeby") : modifierValue(modifiers, "closeby", "closerequest");
910
el.style.display = null;
10-
el.hidden = false;
1111
el.style.length === 0 && el.removeAttribute("style");
12-
el.addEventListener("keydown", escapeDialog);
13-
el.addEventListener("click", backdropDialog);
14-
el.addEventListener("submit", methodDialog);
12+
if (el._x_isShown) {
13+
open();
14+
}
15+
const closeBySupported = (() => {
16+
return "closedBy" in HTMLDialogElement.prototype;
17+
})();
1518
function scrollLock(use = true) {
1619
document.body.style.overflow = use ? "hidden" : "";
1720
}
18-
function methodDialog(event) {
19-
if (event.target.getAttribute("method") === "dialog" || event.submitter && event.submitter.getAttribute("formmethod") === "dialog") {
20-
evaluate();
21+
function dialogSubmit(event) {
22+
if ((event.target.getAttribute("method") === "dialog" || event.submitter?.getAttribute("formmethod") === "dialog") && !canEvaluate) {
23+
event.preventDefault();
2124
}
2225
}
2326
function escapeDialog(event) {
24-
if (event.key !== "Escape") return;
25-
event.preventDefault();
26-
if (closeby !== "any" && closeby !== "closerequest") return;
27-
evaluate();
27+
if (event.key === "Escape" && !canEvaluate) {
28+
event.preventDefault();
29+
}
2830
}
29-
function backdropDialog(event) {
30-
if (event.target !== el || closeby !== "any") return;
31+
function handleCloseByEvent(event) {
32+
if (event.target !== el) return;
3133
const rect = el.getBoundingClientRect();
3234
const isInDialog = rect.top <= event.clientY && event.clientY <= rect.top + rect.height && rect.left <= event.clientX && event.clientX <= rect.left + rect.width;
33-
if (isInDialog) return;
35+
if (!isInDialog) {
36+
if (closeBy === "any") {
37+
if (closeBySupported) {
38+
event.preventDefault();
39+
}
40+
evaluate();
41+
}
42+
}
43+
}
44+
function handleCloseEvent() {
3445
evaluate();
3546
}
36-
el._x_doShow = () => {
47+
function open() {
3748
if (el.hasAttribute("open")) return;
3849
el.showModal();
3950
scrollLock(lockPageScroll);
40-
};
41-
el._x_doHide = () => {
51+
}
52+
function close() {
4253
if (!el.hasAttribute("open")) return;
4354
el.close();
4455
scrollLock(false);
45-
};
56+
}
57+
el._x_doShow = () => open();
58+
el._x_doHide = () => close();
59+
el.addEventListener("keydown", escapeDialog);
60+
el.addEventListener("submit", dialogSubmit);
61+
el.addEventListener("click", handleCloseByEvent);
62+
el.addEventListener("cancel", handleCloseEvent);
4663
cleanup(() => {
4764
el.removeEventListener("keydown", escapeDialog);
48-
el.removeEventListener("click", backdropDialog);
49-
el.removeEventListener("submit", methodDialog);
65+
el.removeEventListener("submit", dialogSubmit);
66+
el.removeEventListener("click", handleCloseByEvent);
67+
el.removeEventListener("cancel", handleCloseEvent);
5068
scrollLock(false);
5169
});
5270
}

0 commit comments

Comments
 (0)