@brytdesigns/web-component-modal 1.1.8 → 3.0.0

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.
@@ -1,10 +1,4 @@
1
- import * as modalPanel_js from './modal-panel.js';
2
- export { modalPanel_js as ModalPanel };
3
- import * as modalTrigger_js from './modal-trigger.js';
4
- export { modalTrigger_js as ModalTrigger };
5
- import * as modalBackdrop_js from './modal-backdrop.js';
6
- export { modalBackdrop_js as ModalBackdrop };
7
- import * as modalContext_js from './modal-context.js';
8
- export { modalContext_js as ModalContext };
9
- //# sourceMappingURL=index.js.map
10
- //# sourceMappingURL=index.js.map
1
+ import "./modal-backdrop.js";
2
+ import "./modal-context.js";
3
+ import "./modal-panel.js";
4
+ import "./modal-trigger.js";
@@ -1,79 +1,53 @@
1
- import { createEffect, on, onMount, onCleanup } from 'solid-js';
2
- import { animate } from 'motion';
3
- import { getTransitionConfig } from '@brytdesigns/web-component-core/animation';
4
- import { useModal } from '../hooks/index.js';
5
-
6
- const Name = "modal-backdrop";
7
- const Component = (_, { element }) => {
8
- const [state, { updateAnimationQueue, close }] = useModal(element);
9
- const controller = new AbortController();
10
- let isFirstRender = true;
11
- createEffect(
12
- on(
13
- () => state.isOpen,
14
- (isOpen) => {
15
- if (!isOpen || isFirstRender) return;
16
- const animation = enter(element);
17
- updateAnimationQueue(animation);
18
- return onCleanup(() => {
19
- if (animation.state !== "finished") animation.complete();
20
- });
21
- }
22
- )
23
- );
24
- createEffect(
25
- on(
26
- () => state.isOpen,
27
- (isOpen) => {
28
- if (isOpen || isFirstRender) return;
29
- const animation = exit(element);
30
- updateAnimationQueue(animation);
31
- return onCleanup(() => {
32
- if (animation.state !== "finished") animation.complete();
33
- });
34
- }
35
- )
36
- );
37
- onMount(() => {
38
- isFirstRender = false;
39
- });
40
- function enter(element2) {
41
- const style = window.getComputedStyle(element2);
42
- const options = getTransitionConfig(style);
43
- return animate(
44
- element2,
45
- {
46
- opacity: [`var(--${Name}--opacity-from)`, `var(--${Name}--opacity-to)`]
47
- },
48
- options
49
- );
50
- }
51
- function exit(element2) {
52
- const style = window.getComputedStyle(element2);
53
- const options = getTransitionConfig(style);
54
- return animate(
55
- element2,
56
- {
57
- opacity: [`var(--${Name}--opacity-to)`, `var(--${Name}--opacity-from)`]
58
- },
59
- options
60
- );
61
- }
62
- element.addEventListener(
63
- "click",
64
- () => {
65
- if (state.isAnimating) return;
66
- close();
67
- },
68
- {
69
- signal: controller.signal
70
- }
71
- );
72
- onCleanup(() => {
73
- controller.abort();
74
- });
1
+ import { useModal } from "../hooks/useModal.js";
2
+ import "../hooks/index.js";
3
+ import { createGuardedEffect } from "@brytdesigns/web-component-core/utils";
4
+ import { getTransitionConfig } from "@brytdesigns/web-component-core/animation";
5
+ import { animate } from "motion";
6
+ import { onCleanup, onSettled } from "solid-js";
7
+ //#region src/components/modal-backdrop.ts
8
+ var Name = "modal-backdrop";
9
+ var Component = (_, { element }) => {
10
+ const [state, { updateAnimationQueue, close }] = useModal(element);
11
+ const controller = new AbortController();
12
+ let isFirstRender = true;
13
+ createGuardedEffect(() => state.isOpen, (isOpen) => {
14
+ if (!isOpen || isFirstRender) return;
15
+ const animation = enter(element);
16
+ updateAnimationQueue(animation);
17
+ return () => {
18
+ if (animation.state !== "finished") animation.complete();
19
+ };
20
+ });
21
+ createGuardedEffect(() => state.isOpen, (isOpen) => {
22
+ if (isOpen || isFirstRender) return;
23
+ const animation = exit(element);
24
+ updateAnimationQueue(animation);
25
+ return () => {
26
+ if (animation.state !== "finished") animation.complete();
27
+ };
28
+ });
29
+ onSettled(() => {
30
+ isFirstRender = false;
31
+ });
32
+ function enter(element) {
33
+ const style = window.getComputedStyle(element);
34
+ const options = getTransitionConfig(style);
35
+ return animate(element, { opacity: [`var(--${Name}--opacity-from)`, `var(--${Name}--opacity-to)`] }, options);
36
+ }
37
+ function exit(element) {
38
+ const style = window.getComputedStyle(element);
39
+ const options = getTransitionConfig(style);
40
+ return animate(element, { opacity: [`var(--${Name}--opacity-to)`, `var(--${Name}--opacity-from)`] }, options);
41
+ }
42
+ element.addEventListener("click", () => {
43
+ if (state.isAnimating) return;
44
+ close();
45
+ }, { signal: controller.signal });
46
+ onCleanup(() => {
47
+ controller.abort();
48
+ });
75
49
  };
76
-
50
+ //#endregion
77
51
  export { Component, Name };
78
- //# sourceMappingURL=modal-backdrop.js.map
52
+
79
53
  //# sourceMappingURL=modal-backdrop.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/modal-backdrop.ts"],"names":["element"],"mappings":";;;;;AAUO,MAAM,IAAO,GAAA;AAEb,MAAM,SAAyC,GAAA,CAAC,CAAG,EAAA,EAAE,SAAc,KAAA;AACxE,EAAM,MAAA,CAAC,OAAO,EAAE,oBAAA,EAAsB,OAAO,CAAA,GAAI,SAAS,OAAO,CAAA;AACjE,EAAM,MAAA,UAAA,GAAa,IAAI,eAAgB,EAAA;AAEvC,EAAA,IAAI,aAAgB,GAAA,IAAA;AAEpB,EAAA,YAAA;AAAA,IACE,EAAA;AAAA,MACE,MAAM,KAAM,CAAA,MAAA;AAAA,MACZ,CAAC,MAAW,KAAA;AACV,QAAI,IAAA,CAAC,UAAU,aAAe,EAAA;AAC9B,QAAM,MAAA,SAAA,GAAY,MAAM,OAAO,CAAA;AAC/B,QAAA,oBAAA,CAAqB,SAAS,CAAA;AAC9B,QAAA,OAAO,UAAU,MAAM;AACrB,UAAA,IAAI,SAAU,CAAA,KAAA,KAAU,UAAY,EAAA,SAAA,CAAU,QAAS,EAAA;AAAA,SACxD,CAAA;AAAA;AACH;AACF,GACF;AAEA,EAAA,YAAA;AAAA,IACE,EAAA;AAAA,MACE,MAAM,KAAM,CAAA,MAAA;AAAA,MACZ,CAAC,MAAW,KAAA;AACV,QAAA,IAAI,UAAU,aAAe,EAAA;AAC7B,QAAM,MAAA,SAAA,GAAY,KAAK,OAAO,CAAA;AAC9B,QAAA,oBAAA,CAAqB,SAAS,CAAA;AAC9B,QAAA,OAAO,UAAU,MAAM;AACrB,UAAA,IAAI,SAAU,CAAA,KAAA,KAAU,UAAY,EAAA,SAAA,CAAU,QAAS,EAAA;AAAA,SACxD,CAAA;AAAA;AACH;AACF,GACF;AAEA,EAAA,OAAA,CAAQ,MAAM;AACZ,IAAgB,aAAA,GAAA,KAAA;AAAA,GACjB,CAAA;AAED,EAAA,SAAS,MAAMA,QAAsB,EAAA;AACnC,IAAM,MAAA,KAAA,GAAQ,MAAO,CAAA,gBAAA,CAAiBA,QAAO,CAAA;AAC7C,IAAM,MAAA,OAAA,GAAU,oBAAoB,KAAK,CAAA;AACzC,IAAO,OAAA,OAAA;AAAA,MACLA,QAAAA;AAAA,MACA;AAAA,QACE,SAAS,CAAC,CAAA,MAAA,EAAS,IAAI,CAAmB,eAAA,CAAA,EAAA,CAAA,MAAA,EAAS,IAAI,CAAe,aAAA,CAAA;AAAA,OACxE;AAAA,MACA;AAAA,KACF;AAAA;AAGF,EAAA,SAAS,KAAKA,QAAsB,EAAA;AAClC,IAAM,MAAA,KAAA,GAAQ,MAAO,CAAA,gBAAA,CAAiBA,QAAO,CAAA;AAC7C,IAAM,MAAA,OAAA,GAAU,oBAAoB,KAAK,CAAA;AACzC,IAAO,OAAA,OAAA;AAAA,MACLA,QAAAA;AAAA,MACA;AAAA,QACE,SAAS,CAAC,CAAA,MAAA,EAAS,IAAI,CAAiB,aAAA,CAAA,EAAA,CAAA,MAAA,EAAS,IAAI,CAAiB,eAAA,CAAA;AAAA,OACxE;AAAA,MACA;AAAA,KACF;AAAA;AAGF,EAAQ,OAAA,CAAA,gBAAA;AAAA,IACN,OAAA;AAAA,IACA,MAAM;AACJ,MAAA,IAAI,MAAM,WAAa,EAAA;AACvB,MAAM,KAAA,EAAA;AAAA,KACR;AAAA,IACA;AAAA,MACE,QAAQ,UAAW,CAAA;AAAA;AACrB,GACF;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,UAAA,CAAW,KAAM,EAAA;AAAA,GAClB,CAAA;AACH","file":"modal-backdrop.js","sourcesContent":["import type { CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\n\nimport { createEffect, onMount, on, onCleanup } from \"solid-js\";\nimport { animate } from \"motion\";\nimport { getTransitionConfig } from \"@brytdesigns/web-component-core/animation\";\n\nimport { useModal } from \"../hooks/index.js\";\n\nexport type Props = {};\n\nexport const Name = \"modal-backdrop\";\n\nexport const Component: CorrectComponentType<Props> = (_, { element }) => {\n const [state, { updateAnimationQueue, close }] = useModal(element);\n const controller = new AbortController();\n\n let isFirstRender = true;\n\n createEffect(\n on(\n () => state.isOpen,\n (isOpen) => {\n if (!isOpen || isFirstRender) return;\n const animation = enter(element);\n updateAnimationQueue(animation);\n return onCleanup(() => {\n if (animation.state !== \"finished\") animation.complete();\n });\n },\n ),\n );\n\n createEffect(\n on(\n () => state.isOpen,\n (isOpen) => {\n if (isOpen || isFirstRender) return;\n const animation = exit(element);\n updateAnimationQueue(animation);\n return onCleanup(() => {\n if (animation.state !== \"finished\") animation.complete();\n });\n },\n ),\n );\n\n onMount(() => {\n isFirstRender = false;\n });\n\n function enter(element: HTMLElement) {\n const style = window.getComputedStyle(element);\n const options = getTransitionConfig(style);\n return animate(\n element,\n {\n opacity: [`var(--${Name}--opacity-from)`, `var(--${Name}--opacity-to)`],\n },\n options,\n );\n }\n\n function exit(element: HTMLElement) {\n const style = window.getComputedStyle(element);\n const options = getTransitionConfig(style);\n return animate(\n element,\n {\n opacity: [`var(--${Name}--opacity-to)`, `var(--${Name}--opacity-from)`],\n },\n options,\n );\n }\n\n element.addEventListener(\n \"click\",\n () => {\n if (state.isAnimating) return;\n close();\n },\n {\n signal: controller.signal,\n },\n );\n\n onCleanup(() => {\n controller.abort();\n });\n};\n"]}
1
+ {"version":3,"file":"modal-backdrop.js","names":[],"sources":["../../../src/components/modal-backdrop.ts"],"sourcesContent":["import { getTransitionConfig } from \"@brytdesigns/web-component-core/animation\";\nimport type { CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\nimport { createGuardedEffect } from \"@brytdesigns/web-component-core/utils\";\nimport { animate } from \"motion\";\nimport { onCleanup, onSettled } from \"solid-js\";\n\nimport { useModal } from \"../hooks/index.js\";\n\nexport type Props = {};\n\nexport const Name = \"modal-backdrop\";\n\nexport const Component: CorrectComponentType<Props> = (_, { element }) => {\n\tconst [state, { updateAnimationQueue, close }] = useModal(element);\n\tconst controller = new AbortController();\n\n\tlet isFirstRender = true;\n\n\tcreateGuardedEffect(\n\t\t() => state.isOpen,\n\t\t(isOpen) => {\n\t\t\tif (!isOpen || isFirstRender) return;\n\t\t\tconst animation = enter(element);\n\t\t\tupdateAnimationQueue(animation);\n\t\t\treturn () => {\n\t\t\t\tif (animation.state !== \"finished\") animation.complete();\n\t\t\t};\n\t\t},\n\t);\n\n\tcreateGuardedEffect(\n\t\t() => state.isOpen,\n\t\t(isOpen) => {\n\t\t\tif (isOpen || isFirstRender) return;\n\t\t\tconst animation = exit(element);\n\t\t\tupdateAnimationQueue(animation);\n\t\t\treturn () => {\n\t\t\t\tif (animation.state !== \"finished\") animation.complete();\n\t\t\t};\n\t\t},\n\t);\n\n\tonSettled(() => {\n\t\tisFirstRender = false;\n\t});\n\n\tfunction enter(element: HTMLElement) {\n\t\tconst style = window.getComputedStyle(element);\n\t\tconst options = getTransitionConfig(style);\n\t\treturn animate(\n\t\t\telement,\n\t\t\t{\n\t\t\t\topacity: [`var(--${Name}--opacity-from)`, `var(--${Name}--opacity-to)`],\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t}\n\n\tfunction exit(element: HTMLElement) {\n\t\tconst style = window.getComputedStyle(element);\n\t\tconst options = getTransitionConfig(style);\n\t\treturn animate(\n\t\t\telement,\n\t\t\t{\n\t\t\t\topacity: [`var(--${Name}--opacity-to)`, `var(--${Name}--opacity-from)`],\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t}\n\n\telement.addEventListener(\n\t\t\"click\",\n\t\t() => {\n\t\t\tif (state.isAnimating) return;\n\t\t\tclose();\n\t\t},\n\t\t{\n\t\t\tsignal: controller.signal,\n\t\t},\n\t);\n\n\tonCleanup(() => {\n\t\tcontroller.abort();\n\t});\n};\n"],"mappings":";;;;;;;AAUA,IAAa,OAAO;AAEpB,IAAa,aAA0C,GAAG,EAAE,cAAc;CACzE,MAAM,CAAC,OAAO,EAAE,sBAAsB,WAAW,SAAS,OAAO;CACjE,MAAM,aAAa,IAAI,gBAAgB;CAEvC,IAAI,gBAAgB;CAEpB,0BACO,MAAM,SACX,WAAW;EACX,IAAI,CAAC,UAAU,eAAe;EAC9B,MAAM,YAAY,MAAM,OAAO;EAC/B,qBAAqB,SAAS;EAC9B,aAAa;GACZ,IAAI,UAAU,UAAU,YAAY,UAAU,SAAS;EACxD;CACD,CACD;CAEA,0BACO,MAAM,SACX,WAAW;EACX,IAAI,UAAU,eAAe;EAC7B,MAAM,YAAY,KAAK,OAAO;EAC9B,qBAAqB,SAAS;EAC9B,aAAa;GACZ,IAAI,UAAU,UAAU,YAAY,UAAU,SAAS;EACxD;CACD,CACD;CAEA,gBAAgB;EACf,gBAAgB;CACjB,CAAC;CAED,SAAS,MAAM,SAAsB;EACpC,MAAM,QAAQ,OAAO,iBAAiB,OAAO;EAC7C,MAAM,UAAU,oBAAoB,KAAK;EACzC,OAAO,QACN,SACA,EACC,SAAS,CAAC,SAAS,KAAK,kBAAkB,SAAS,KAAK,cAAc,EACvE,GACA,OACD;CACD;CAEA,SAAS,KAAK,SAAsB;EACnC,MAAM,QAAQ,OAAO,iBAAiB,OAAO;EAC7C,MAAM,UAAU,oBAAoB,KAAK;EACzC,OAAO,QACN,SACA,EACC,SAAS,CAAC,SAAS,KAAK,gBAAgB,SAAS,KAAK,gBAAgB,EACvE,GACA,OACD;CACD;CAEA,QAAQ,iBACP,eACM;EACL,IAAI,MAAM,aAAa;EACvB,MAAM;CACP,GACA,EACC,QAAQ,WAAW,OACpB,CACD;CAEA,gBAAgB;EACf,WAAW,MAAM;CAClB,CAAC;AACF"}
@@ -1,129 +1,128 @@
1
- import { disableBodyScroll, enableBodyScroll } from '@brytdesigns/web-component-core/utils';
2
- import { splitProps, createEffect, on, onCleanup, onMount } from 'solid-js';
3
- import { createFocusTrap } from '@brytdesigns/web-component-core/focusTrap';
4
- import { provideModalContext, useModalContext } from '../hooks/index.js';
5
- import { showElement, hideElement } from '../utils.js';
6
-
7
- const Name = "modal-context";
8
- const Component = (props, { element }) => {
9
- const [contextProps, restProps] = splitProps(props, [
10
- "isOpen",
11
- "isAnimating"
12
- ]);
13
- const context = provideModalContext(contextProps, element);
14
- const [state, { setElementState }] = context;
15
- const [_, { updateAnimationQueue, ...events }] = useModalContext(context);
16
- element.actions = events;
17
- const focusTrap = createFocusTrap(element, () => ({
18
- allowOutsideClick: true,
19
- escapeDeactivates: restProps.closeOnEscape,
20
- onDeactivate: () => {
21
- setElementState("isOpen", false);
22
- }
23
- }));
24
- createEffect(
25
- on(
26
- () => state.isOpen,
27
- (isOpen) => {
28
- const eventName = isOpen ? "modal:open" : "modal:close";
29
- element.dispatchEvent(
30
- new CustomEvent(eventName, {
31
- bubbles: true,
32
- detail: { isOpen, relatedTarget: element }
33
- })
34
- );
35
- element.dispatchEvent(
36
- new CustomEvent("drawer:toggle", {
37
- bubbles: true,
38
- detail: { isOpen, relatedTarget: element }
39
- })
40
- );
41
- }
42
- )
43
- );
44
- createEffect(
45
- on(
46
- () => ({
47
- isOpen: state.isOpen,
48
- focusTrap: focusTrap(),
49
- shouldTrapFocus: restProps.shouldTrapFocus
50
- }),
51
- ({ isOpen, focusTrap: focusTrap2, shouldTrapFocus }) => {
52
- if (!isOpen) return;
53
- showElement(element);
54
- if (!shouldTrapFocus) return;
55
- focusTrap2.activate();
56
- onCleanup(focusTrap2.deactivate);
57
- }
58
- )
59
- );
60
- createEffect(
61
- on(
62
- () => ({
63
- isOpen: state.isOpen,
64
- isAnimating: state.isAnimating,
65
- shouldTrapFocus: restProps.shouldTrapFocus
66
- }),
67
- ({ isOpen, isAnimating, shouldTrapFocus }) => {
68
- if (isOpen && !isAnimating && shouldTrapFocus)
69
- return disableBodyScroll(element, {
70
- allowTouchMove: (el) => {
71
- if (el instanceof HTMLElement) {
72
- let element2 = el;
73
- while (element2 && element2 !== document.body) {
74
- if (element2.tagName === "MODAL-PANEL") {
75
- return true;
76
- }
77
- element2 = element2.parentElement;
78
- }
79
- }
80
- return false;
81
- }
82
- });
83
- onCleanup(() => {
84
- enableBodyScroll(element);
85
- });
86
- }
87
- )
88
- );
89
- createEffect(
90
- on(
91
- () => ({ isOpen: state.isOpen, animationQueue: state.animationQueue }),
92
- ({ isOpen, animationQueue }) => {
93
- if (isOpen) return;
94
- return Promise.all(animationQueue).then(() => hideElement(element));
95
- }
96
- )
97
- );
98
- let openAfterDelayTimeoutId = null;
99
- onMount(() => {
100
- if (!restProps.delay || contextProps.isOpen) return;
101
- openAfterDelayTimeoutId = setTimeout(() => {
102
- setElementState("isOpen", true);
103
- }, props.delay);
104
- return onCleanup(() => {
105
- clearTimeout(openAfterDelayTimeoutId);
106
- });
107
- });
108
- createEffect(
109
- on(
110
- () => ({
111
- isOpen: state.isOpen,
112
- openAfterDelay: restProps.delay > 0
113
- }),
114
- ({ isOpen, openAfterDelay }) => {
115
- if (!openAfterDelay && openAfterDelayTimeoutId)
116
- clearTimeout(openAfterDelayTimeoutId);
117
- if (isOpen && openAfterDelayTimeoutId)
118
- clearTimeout(openAfterDelayTimeoutId);
119
- }
120
- )
121
- );
122
- onCleanup(() => {
123
- enableBodyScroll(element);
124
- });
1
+ import { provideModalContext, useModalContext } from "../hooks/useModal.js";
2
+ import "../hooks/index.js";
3
+ import { hideElement, showElement } from "../utils.js";
4
+ import { closeNestedOverlays, createEscapeHandler, createFocusReturn, createGuardedEffect, disableBodyScroll, enableBodyScroll, findOverlayPanel } from "@brytdesigns/web-component-core/utils";
5
+ import { omit, onCleanup, onSettled } from "solid-js";
6
+ import { createFocusTrap } from "@brytdesigns/web-component-core/focusTrap";
7
+ //#region src/components/modal-context.ts
8
+ var Name = "modal-context";
9
+ var Component = (props, { element }) => {
10
+ const restProps = omit(props, "isOpen", "isAnimating");
11
+ const contextProps = {
12
+ get isOpen() {
13
+ return props.isOpen;
14
+ },
15
+ get isAnimating() {
16
+ return props.isAnimating;
17
+ }
18
+ };
19
+ const context = provideModalContext(contextProps, element);
20
+ const [state, { setElementState }] = context;
21
+ const [_, { updateAnimationQueue, ...events }] = useModalContext(context);
22
+ element.actions = events;
23
+ const panel = () => findOverlayPanel(element, "modal-panel");
24
+ const focusReturn = createFocusReturn(element);
25
+ const focusTrap = createFocusTrap(element, () => ({
26
+ allowOutsideClick: true,
27
+ escapeDeactivates: false,
28
+ returnFocusOnDeactivate: false,
29
+ initialFocus: () => panel() ?? false,
30
+ fallbackFocus: () => panel() ?? element
31
+ }));
32
+ createGuardedEffect(() => ({
33
+ isOpen: state.isOpen,
34
+ closeOnEscape: restProps.closeOnEscape
35
+ }), ({ isOpen, closeOnEscape }) => {
36
+ if (!isOpen || !closeOnEscape) return;
37
+ return createEscapeHandler({
38
+ element,
39
+ onEscape: () => setElementState("isOpen", false)
40
+ });
41
+ });
42
+ createGuardedEffect(() => state.isOpen, (isOpen) => {
43
+ const eventName = isOpen ? "modal:open" : "modal:close";
44
+ element.dispatchEvent(new CustomEvent(eventName, {
45
+ bubbles: true,
46
+ detail: {
47
+ isOpen,
48
+ relatedTarget: element
49
+ }
50
+ }));
51
+ element.dispatchEvent(new CustomEvent("drawer:toggle", {
52
+ bubbles: true,
53
+ detail: {
54
+ isOpen,
55
+ relatedTarget: element
56
+ }
57
+ }));
58
+ });
59
+ createGuardedEffect(() => ({
60
+ isOpen: state.isOpen,
61
+ isAnimating: state.isAnimating,
62
+ focusTrap: focusTrap(),
63
+ shouldTrapFocus: restProps.shouldTrapFocus
64
+ }), ({ isOpen, isAnimating, focusTrap, shouldTrapFocus }) => {
65
+ if (!isOpen) return;
66
+ showElement(element);
67
+ if (!shouldTrapFocus || isAnimating) return;
68
+ focusReturn.record();
69
+ focusTrap.activate();
70
+ return () => {
71
+ focusTrap.deactivate();
72
+ focusReturn.restore();
73
+ };
74
+ });
75
+ createGuardedEffect(() => ({
76
+ isOpen: state.isOpen,
77
+ isAnimating: state.isAnimating,
78
+ shouldTrapFocus: restProps.shouldTrapFocus
79
+ }), ({ isOpen, isAnimating, shouldTrapFocus }) => {
80
+ if (!isOpen || isAnimating || !shouldTrapFocus) return;
81
+ disableBodyScroll(element, { allowTouchMove: (el) => {
82
+ if (el instanceof HTMLElement) {
83
+ let element = el;
84
+ while (element && element !== document.body) {
85
+ if (element.tagName === "MODAL-PANEL") return true;
86
+ element = element.parentElement;
87
+ }
88
+ }
89
+ return false;
90
+ } });
91
+ return () => enableBodyScroll(element);
92
+ });
93
+ createGuardedEffect(() => state.isOpen, (isOpen, previous) => {
94
+ if (previous === void 0 || isOpen) return;
95
+ closeNestedOverlays(element);
96
+ });
97
+ createGuardedEffect(() => ({
98
+ isOpen: state.isOpen,
99
+ animationQueue: state.animationQueue
100
+ }), ({ isOpen, animationQueue }) => {
101
+ if (isOpen) return;
102
+ Promise.all(animationQueue).then(() => hideElement(element));
103
+ });
104
+ let openAfterDelayTimeoutId = null;
105
+ onSettled(() => {
106
+ if (!restProps.delay || contextProps.isOpen) return;
107
+ openAfterDelayTimeoutId = setTimeout(() => {
108
+ setElementState("isOpen", true);
109
+ }, props.delay);
110
+ return () => {
111
+ clearTimeout(openAfterDelayTimeoutId);
112
+ };
113
+ });
114
+ createGuardedEffect(() => ({
115
+ isOpen: state.isOpen,
116
+ openAfterDelay: restProps.delay > 0
117
+ }), ({ isOpen, openAfterDelay }) => {
118
+ if (!openAfterDelay && openAfterDelayTimeoutId) clearTimeout(openAfterDelayTimeoutId);
119
+ if (isOpen && openAfterDelayTimeoutId) clearTimeout(openAfterDelayTimeoutId);
120
+ });
121
+ onCleanup(() => {
122
+ enableBodyScroll(element);
123
+ });
125
124
  };
126
-
125
+ //#endregion
127
126
  export { Component, Name };
128
- //# sourceMappingURL=modal-context.js.map
127
+
129
128
  //# sourceMappingURL=modal-context.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/modal-context.ts"],"names":["focusTrap","element"],"mappings":"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","file":"modal-context.js","sourcesContent":["import {\n type CorrectComponentType,\n enableBodyScroll,\n disableBodyScroll,\n} from \"@brytdesigns/web-component-core/utils\";\n\nimport { createEffect, on, onCleanup, onMount, splitProps } from \"solid-js\";\nimport { createFocusTrap } from \"@brytdesigns/web-component-core/focusTrap\";\n\nimport { provideModalContext, useModalContext } from \"../hooks/index.js\";\nimport { hideElement, showElement } from \"../utils.js\";\n\nexport type Props = {\n isOpen: boolean;\n id: string;\n closeOnEscape: boolean;\n shouldTrapFocus: boolean;\n isAnimating: boolean;\n delay: number;\n};\n\nexport const Name = \"modal-context\";\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n const [contextProps, restProps] = splitProps(props, [\n \"isOpen\",\n \"isAnimating\",\n ]);\n\n const context = provideModalContext(contextProps, element);\n\n const [state, { setElementState }] = context;\n\n const [_, { updateAnimationQueue, ...events }] = useModalContext(context);\n\n element.actions = events;\n\n const focusTrap = createFocusTrap(element, () => ({\n allowOutsideClick: true,\n escapeDeactivates: restProps.closeOnEscape,\n onDeactivate: () => {\n setElementState(\"isOpen\", false);\n },\n }));\n\n createEffect(\n on(\n () => state.isOpen,\n (isOpen) => {\n const eventName = isOpen ? \"modal:open\" : \"modal:close\";\n element.dispatchEvent(\n new CustomEvent(eventName, {\n bubbles: true,\n detail: { isOpen, relatedTarget: element },\n }),\n );\n element.dispatchEvent(\n new CustomEvent(\"drawer:toggle\", {\n bubbles: true,\n detail: { isOpen, relatedTarget: element },\n }),\n );\n },\n ),\n );\n\n createEffect(\n on(\n () => ({\n isOpen: state.isOpen,\n focusTrap: focusTrap(),\n shouldTrapFocus: restProps.shouldTrapFocus,\n }),\n ({ isOpen, focusTrap, shouldTrapFocus }) => {\n if (!isOpen) return;\n showElement(element);\n if (!shouldTrapFocus) return;\n focusTrap.activate();\n onCleanup(focusTrap.deactivate);\n },\n ),\n );\n\n createEffect(\n on(\n () => ({\n isOpen: state.isOpen,\n isAnimating: state.isAnimating,\n shouldTrapFocus: restProps.shouldTrapFocus,\n }),\n ({ isOpen, isAnimating, shouldTrapFocus }) => {\n if (isOpen && !isAnimating && shouldTrapFocus)\n return disableBodyScroll(element, {\n allowTouchMove: (el: EventTarget) => {\n if (el instanceof HTMLElement) {\n let element = el as (EventTarget & HTMLElement) | null;\n while (element && element !== document.body) {\n if (element.tagName === \"MODAL-PANEL\") {\n return true;\n }\n\n element = element.parentElement;\n }\n }\n return false;\n },\n });\n onCleanup(() => {\n enableBodyScroll(element);\n });\n },\n ),\n );\n\n createEffect(\n on(\n () => ({ isOpen: state.isOpen, animationQueue: state.animationQueue }),\n ({ isOpen, animationQueue }) => {\n if (isOpen) return;\n return Promise.all(animationQueue).then(() => hideElement(element));\n },\n ),\n );\n\n let openAfterDelayTimeoutId: any = null;\n\n onMount(() => {\n if (!restProps.delay || contextProps.isOpen) return;\n\n openAfterDelayTimeoutId = setTimeout(() => {\n setElementState(\"isOpen\", true);\n }, props.delay);\n\n return onCleanup(() => {\n clearTimeout(openAfterDelayTimeoutId);\n });\n });\n\n createEffect(\n on(\n () => ({\n isOpen: state.isOpen,\n openAfterDelay: restProps.delay > 0,\n }),\n ({ isOpen, openAfterDelay }) => {\n if (!openAfterDelay && openAfterDelayTimeoutId)\n clearTimeout(openAfterDelayTimeoutId);\n if (isOpen && openAfterDelayTimeoutId)\n clearTimeout(openAfterDelayTimeoutId);\n },\n ),\n );\n\n onCleanup(() => {\n enableBodyScroll(element);\n });\n};\n"]}
1
+ {"version":3,"file":"modal-context.js","names":[],"sources":["../../../src/components/modal-context.ts"],"sourcesContent":["import { createFocusTrap } from \"@brytdesigns/web-component-core/focusTrap\";\nimport {\n\ttype CorrectComponentType,\n\tcloseNestedOverlays,\n\tcreateEscapeHandler,\n\tcreateFocusReturn,\n\tcreateGuardedEffect,\n\tdisableBodyScroll,\n\tenableBodyScroll,\n\tfindOverlayPanel,\n} from \"@brytdesigns/web-component-core/utils\";\nimport { omit, onCleanup, onSettled, untrack } from \"solid-js\";\n\nimport { provideModalContext, useModalContext } from \"../hooks/index.js\";\nimport { hideElement, showElement } from \"../utils.js\";\n\nexport type Props = {\n\tisOpen: boolean;\n\tid: string;\n\tcloseOnEscape: boolean;\n\tshouldTrapFocus: boolean;\n\tisAnimating: boolean;\n\tdelay: number;\n};\n\nexport const Name = \"modal-context\";\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n\t// `splitProps` is gone. `omit` gives the rest; the picked half is a getter\n\t// object so it stays reactive, which is what splitProps returned.\n\tconst restProps = omit(props, \"isOpen\", \"isAnimating\");\n\tconst contextProps = {\n\t\tget isOpen() {\n\t\t\treturn props.isOpen;\n\t\t},\n\t\tget isAnimating() {\n\t\t\treturn props.isAnimating;\n\t\t},\n\t};\n\n\tconst context = provideModalContext(contextProps, element);\n\n\tconst [state, { setElementState }] = context;\n\n\tconst [_, { updateAnimationQueue, ...events }] = useModalContext(context);\n\n\telement.actions = events;\n\n\tconst panel = () => findOverlayPanel(element, \"modal-panel\");\n\tconst focusReturn = createFocusReturn(element);\n\n\tconst focusTrap = createFocusTrap(element, () => ({\n\t\tallowOutsideClick: true,\n\t\t// Escape and focus return are handled explicitly below rather than as\n\t\t// focus-trap options. As options they only applied while a trap was\n\t\t// active, so `close-on-escape=\"true\" should-trap-focus=\"false\"` silently\n\t\t// did nothing, and returning focus was a side effect of trapping it.\n\t\tescapeDeactivates: false,\n\t\treturnFocusOnDeactivate: false,\n\t\t// The panel, not its first button: a screen reader then announces the\n\t\t// dialog's name and role on open instead of \"Close\".\n\t\tinitialFocus: () => panel() ?? false,\n\t\t// Without this, an overlay holding nothing tabbable throws on activate.\n\t\tfallbackFocus: () => panel() ?? element,\n\t\t// No `onDeactivate`. It used to close the overlay, because deactivation\n\t\t// was how focus-trap's `escapeDeactivates` reported an Escape press —\n\t\t// and with Escape handled explicitly above, closing on *any* deactivation\n\t\t// is actively wrong: the trap is also deactivated whenever this effect\n\t\t// re-runs, so an overlay would close itself the moment it started\n\t\t// animating open.\n\t}));\n\n\tcreateGuardedEffect(\n\t\t() => ({\n\t\t\tisOpen: state.isOpen,\n\t\t\tcloseOnEscape: restProps.closeOnEscape,\n\t\t}),\n\t\t({ isOpen, closeOnEscape }) => {\n\t\t\tif (!isOpen || !closeOnEscape) return;\n\t\t\t// Only the innermost open overlay responds, so Escape inside a nested\n\t\t\t// overlay closes that one rather than collapsing the whole stack.\n\t\t\treturn createEscapeHandler({\n\t\t\t\telement,\n\t\t\t\tonEscape: () => setElementState(\"isOpen\", false),\n\t\t\t});\n\t\t},\n\t);\n\n\tcreateGuardedEffect(\n\t\t() => state.isOpen,\n\t\t(isOpen) => {\n\t\t\tconst eventName = isOpen ? \"modal:open\" : \"modal:close\";\n\t\t\telement.dispatchEvent(\n\t\t\t\tnew CustomEvent(eventName, {\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tdetail: { isOpen, relatedTarget: element },\n\t\t\t\t}),\n\t\t\t);\n\t\t\telement.dispatchEvent(\n\t\t\t\tnew CustomEvent(\"drawer:toggle\", {\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tdetail: { isOpen, relatedTarget: element },\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t);\n\n\tcreateGuardedEffect(\n\t\t() => ({\n\t\t\tisOpen: state.isOpen,\n\t\t\tisAnimating: state.isAnimating,\n\t\t\tfocusTrap: focusTrap(),\n\t\t\tshouldTrapFocus: restProps.shouldTrapFocus,\n\t\t}),\n\t\t({ isOpen, isAnimating, focusTrap, shouldTrapFocus }) => {\n\t\t\tif (!isOpen) return;\n\t\t\tshowElement(element);\n\t\t\t// Waiting out the enter animation keeps the trap off content that is\n\t\t\t// still transitioning, and means `record()` reads the trigger rather\n\t\t\t// than whatever the animation left focused.\n\t\t\tif (!shouldTrapFocus || isAnimating) return;\n\t\t\tfocusReturn.record();\n\t\t\tfocusTrap.activate();\n\t\t\t// The apply phase is not a computation, so `onCleanup` here would\n\t\t\t// never register. Its return value IS the cleanup.\n\t\t\treturn () => {\n\t\t\t\tfocusTrap.deactivate();\n\t\t\t\tfocusReturn.restore();\n\t\t\t};\n\t\t},\n\t);\n\n\tcreateGuardedEffect(\n\t\t() => ({\n\t\t\tisOpen: state.isOpen,\n\t\t\tisAnimating: state.isAnimating,\n\t\t\tshouldTrapFocus: restProps.shouldTrapFocus,\n\t\t}),\n\t\t({ isOpen, isAnimating, shouldTrapFocus }) => {\n\t\t\tif (!isOpen || isAnimating || !shouldTrapFocus) return;\n\n\t\t\tdisableBodyScroll(element, {\n\t\t\t\tallowTouchMove: (el: EventTarget) => {\n\t\t\t\t\tif (el instanceof HTMLElement) {\n\t\t\t\t\t\tlet element = el as (EventTarget & HTMLElement) | null;\n\t\t\t\t\t\twhile (element && element !== document.body) {\n\t\t\t\t\t\t\tif (element.tagName === \"MODAL-PANEL\") {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\telement = element.parentElement;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// The apply phase’s return value IS the cleanup, and\n\t\t\t// `disableBodyScroll` returns void — so returning its call registered\n\t\t\t// no cleanup at all. The lock was only released on the *next* run’s\n\t\t\t// cleanup, i.e. when the drawer reopened, so closing it left the page\n\t\t\t// unscrollable.\n\t\t\treturn () => enableBodyScroll(element);\n\t\t},\n\t);\n\n\tcreateGuardedEffect(\n\t\t() => state.isOpen,\n\t\t(isOpen, previous) => {\n\t\t\t// Nothing to close on the mount run: a descendant that starts open was\n\t\t\t// authored that way, and closing it here would fight the markup.\n\t\t\tif (previous === undefined || isOpen) return;\n\t\t\t// Closing this one hides everything inside it, but a nested overlay\n\t\t\t// keeps its own `isOpen` until something changes it — so it would stay\n\t\t\t// \"open\" while invisible, never fire its close event, and reappear\n\t\t\t// still open when this one is opened again.\n\t\t\tcloseNestedOverlays(element);\n\t\t},\n\t);\n\n\tcreateGuardedEffect(\n\t\t() => ({ isOpen: state.isOpen, animationQueue: state.animationQueue }),\n\t\t({ isOpen, animationQueue }) => {\n\t\t\tif (isOpen) return;\n\t\t\t// Not returned: in v2 the apply phase's return value is the cleanup\n\t\t\t// function, and this is a promise chain.\n\t\t\tvoid Promise.all(animationQueue).then(() => hideElement(element));\n\t\t},\n\t);\n\n\tlet openAfterDelayTimeoutId: any = null;\n\n\tonSettled(() => {\n\t\tif (!restProps.delay || contextProps.isOpen) return;\n\n\t\topenAfterDelayTimeoutId = setTimeout(() => {\n\t\t\tsetElementState(\"isOpen\", true);\n\t\t}, props.delay);\n\n\t\treturn () => {\n\t\t\tclearTimeout(openAfterDelayTimeoutId);\n\t\t};\n\t});\n\n\tcreateGuardedEffect(\n\t\t() => ({\n\t\t\tisOpen: state.isOpen,\n\t\t\topenAfterDelay: restProps.delay > 0,\n\t\t}),\n\t\t({ isOpen, openAfterDelay }) => {\n\t\t\tif (!openAfterDelay && openAfterDelayTimeoutId)\n\t\t\t\tclearTimeout(openAfterDelayTimeoutId);\n\t\t\tif (isOpen && openAfterDelayTimeoutId)\n\t\t\t\tclearTimeout(openAfterDelayTimeoutId);\n\t\t},\n\t);\n\n\tonCleanup(() => {\n\t\tenableBodyScroll(element);\n\t});\n};\n"],"mappings":"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"}
@@ -1,73 +1,66 @@
1
- import { createEffect, on, onMount, onCleanup } from 'solid-js';
2
- import { animate } from 'motion';
3
- import { getTransitionConfig } from '@brytdesigns/web-component-core/animation';
4
- import { useModal } from '../hooks/index.js';
5
-
6
- const Name = "modal-panel";
7
- const Component = (_, { element }) => {
8
- const [state, { updateAnimationQueue }] = useModal(element);
9
- let isFirstRender = true;
10
- createEffect(
11
- on(
12
- () => state.isOpen,
13
- (isOpen) => {
14
- if (!isOpen || isFirstRender) return;
15
- const animation = enter(element);
16
- updateAnimationQueue(animation);
17
- return onCleanup(() => {
18
- if (animation.state !== "finished") animation.complete();
19
- });
20
- }
21
- )
22
- );
23
- createEffect(
24
- on(
25
- () => state.isOpen,
26
- (isOpen) => {
27
- if (isOpen || isFirstRender) return;
28
- const animation = exit(element);
29
- updateAnimationQueue(animation);
30
- return onCleanup(() => {
31
- if (animation.state !== "finished") animation.complete();
32
- });
33
- }
34
- )
35
- );
36
- onMount(() => {
37
- isFirstRender = false;
38
- });
39
- function enter(element2) {
40
- const style = window.getComputedStyle(element2);
41
- const transition = getTransitionConfig(style);
42
- return animate(
43
- element2,
44
- {
45
- x: [`var(--${Name}--slide-x-from)`, `var(--${Name}--slide-x-to)`],
46
- y: [`var(--${Name}--slide-y-from)`, `var(--${Name}--slide-y-to)`],
47
- scaleY: [`var(--${Name}--scale-y-from)`, `var(--${Name}--scale-y-to)`],
48
- scaleX: [`var(--${Name}--scale-x-from)`, `var(--${Name}--scale-x-to)`],
49
- opacity: [`var(--${Name}--opacity-from)`, `var(--${Name}--opacity-to)`]
50
- },
51
- transition
52
- );
53
- }
54
- function exit(element2) {
55
- const style = window.getComputedStyle(element2);
56
- const transition = getTransitionConfig(style);
57
- return animate(
58
- element2,
59
- {
60
- x: [`var(--${Name}--slide-x-to)`, `var(--${Name}--slide-x-from)`],
61
- y: [`var(--${Name}--slide-y-to)`, `var(--${Name}--slide-y-from)`],
62
- scaleY: [`var(--${Name}--scale-y-to)`, `var(--${Name}--scale-y-from)`],
63
- scaleX: [`var(--${Name}--scale-x-to)`, `var(--${Name}--scale-x-from)`],
64
- opacity: [`var(--${Name}--opacity-to)`, `var(--${Name}--opacity-from)`]
65
- },
66
- transition
67
- );
68
- }
1
+ import { useModal } from "../hooks/useModal.js";
2
+ import "../hooks/index.js";
3
+ import { createGuardedEffect } from "@brytdesigns/web-component-core/utils";
4
+ import { getTransitionConfig } from "@brytdesigns/web-component-core/animation";
5
+ import { animate } from "motion";
6
+ import { onSettled } from "solid-js";
7
+ //#region src/components/modal-panel.ts
8
+ var Name = "modal-panel";
9
+ var Component = (_, { element }) => {
10
+ const [state, { updateAnimationQueue }] = useModal(element);
11
+ let isFirstRender = true;
12
+ if (!element.hasAttribute("role")) element.setAttribute("role", "dialog");
13
+ if (!element.hasAttribute("tabindex")) element.setAttribute("tabindex", "-1");
14
+ onSettled(() => {
15
+ if (!(element.hasAttribute("aria-labelledby") || element.hasAttribute("aria-label"))) console.warn("modal-panel: no accessible name. Add an aria-label, or an aria-labelledby pointing at the heading inside it.", element);
16
+ });
17
+ createGuardedEffect(() => state.isOpen, (isOpen) => {
18
+ if (isOpen) element.setAttribute("aria-modal", "true");
19
+ else element.removeAttribute("aria-modal");
20
+ });
21
+ createGuardedEffect(() => state.isOpen, (isOpen) => {
22
+ if (!isOpen || isFirstRender) return;
23
+ const animation = enter(element);
24
+ updateAnimationQueue(animation);
25
+ return () => {
26
+ if (animation.state !== "finished") animation.complete();
27
+ };
28
+ });
29
+ createGuardedEffect(() => state.isOpen, (isOpen) => {
30
+ if (isOpen || isFirstRender) return;
31
+ const animation = exit(element);
32
+ updateAnimationQueue(animation);
33
+ return () => {
34
+ if (animation.state !== "finished") animation.complete();
35
+ };
36
+ });
37
+ onSettled(() => {
38
+ isFirstRender = false;
39
+ });
40
+ function enter(element) {
41
+ const style = window.getComputedStyle(element);
42
+ const transition = getTransitionConfig(style);
43
+ return animate(element, {
44
+ x: [`var(--${Name}--slide-x-from)`, `var(--${Name}--slide-x-to)`],
45
+ y: [`var(--${Name}--slide-y-from)`, `var(--${Name}--slide-y-to)`],
46
+ scaleY: [`var(--${Name}--scale-y-from)`, `var(--${Name}--scale-y-to)`],
47
+ scaleX: [`var(--${Name}--scale-x-from)`, `var(--${Name}--scale-x-to)`],
48
+ opacity: [`var(--${Name}--opacity-from)`, `var(--${Name}--opacity-to)`]
49
+ }, transition);
50
+ }
51
+ function exit(element) {
52
+ const style = window.getComputedStyle(element);
53
+ const transition = getTransitionConfig(style);
54
+ return animate(element, {
55
+ x: [`var(--${Name}--slide-x-to)`, `var(--${Name}--slide-x-from)`],
56
+ y: [`var(--${Name}--slide-y-to)`, `var(--${Name}--slide-y-from)`],
57
+ scaleY: [`var(--${Name}--scale-y-to)`, `var(--${Name}--scale-y-from)`],
58
+ scaleX: [`var(--${Name}--scale-x-to)`, `var(--${Name}--scale-x-from)`],
59
+ opacity: [`var(--${Name}--opacity-to)`, `var(--${Name}--opacity-from)`]
60
+ }, transition);
61
+ }
69
62
  };
70
-
63
+ //#endregion
71
64
  export { Component, Name };
72
- //# sourceMappingURL=modal-panel.js.map
65
+
73
66
  //# sourceMappingURL=modal-panel.js.map