@brytdesigns/web-component-collapsible 1.0.3 → 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,120 +1,62 @@
1
- import { animate } from 'motion';
2
- import { createEffect, on, onCleanup } from 'solid-js';
3
- import { controlsToPromise } from '@brytdesigns/web-component-core/animation';
4
- import { useCollapsibleItem } from '../hooks/index.js';
5
-
6
- const hideElement = (element) => {
7
- element.style.cssText = `
8
- display: none;
9
- opacity: 0;
10
- visibility: hidden;
11
- max-height: 0px;
12
- `;
13
- element.style.overflow = null;
14
- };
15
- const showElement = (element) => {
16
- element.style.cssText = `
17
- display: block;
18
- opacity: 1;
19
- visibility: visible;
20
- `;
21
- };
22
- const getHeight = (el) => {
23
- el.style.maxHeight = "max-content";
24
- const height = el.getBoundingClientRect().height;
25
- el.style.maxHeight = `${0}`;
26
- return height;
27
- };
28
- const getPaddingTop = (element) => {
29
- const paddingY = parseInt(getComputedStyle(element).paddingTop);
30
- return paddingY;
1
+ import { useCollapsibleItem } from "../hooks/useCollapsibleItem.js";
2
+ import "../hooks/index.js";
3
+ import { createGuardedEffect } from "@brytdesigns/web-component-core/utils";
4
+ import { collapseContent, controlsToPromise, expandContent, hideContent, onContentRevealed, shouldReduceMotion, showContent } from "@brytdesigns/web-component-core/animation";
5
+ import { onCleanup } from "solid-js";
6
+ //#region src/components/collapsible-content.ts
7
+ var Name = `collapsible-content`;
8
+ var Component = (props, { element }) => {
9
+ const [state, methods] = useCollapsibleItem(element);
10
+ let isFirstRender = true;
11
+ let revealCount = 0;
12
+ let seenRevealCount = 0;
13
+ onCleanup(onContentRevealed(element, () => {
14
+ revealCount += 1;
15
+ methods.expand();
16
+ }));
17
+ const expand = (element, isStale) => {
18
+ const animation = expandContent(element, isStale);
19
+ animation.then(() => {
20
+ if (isStale()) return;
21
+ if (props.shouldScrollIntoView) element.scrollIntoView({
22
+ behavior: shouldReduceMotion() ? "instant" : "smooth",
23
+ block: "start",
24
+ inline: "nearest"
25
+ });
26
+ });
27
+ return animation;
28
+ };
29
+ createGuardedEffect(() => state.isExpanded, (isExpanded) => {
30
+ const isRevealing = revealCount !== seenRevealCount;
31
+ seenRevealCount = revealCount;
32
+ if (isFirstRender || isRevealing) {
33
+ isFirstRender = false;
34
+ if (isExpanded) showContent(element);
35
+ else hideContent(element);
36
+ methods.finish();
37
+ return;
38
+ }
39
+ let stale = false;
40
+ const isStale = () => stale;
41
+ if (!isExpanded) {
42
+ methods.start();
43
+ const animation = collapseContent(element, isStale);
44
+ controlsToPromise(animation).finally(methods.finish);
45
+ return () => {
46
+ stale = true;
47
+ animation.complete();
48
+ };
49
+ }
50
+ methods.start();
51
+ const animation = expand(element, isStale);
52
+ controlsToPromise(animation).finally(methods.finish);
53
+ return () => {
54
+ stale = true;
55
+ animation.complete();
56
+ };
57
+ });
31
58
  };
32
- const getPaddingBottom = (element) => {
33
- const paddingY = parseInt(getComputedStyle(element).paddingBottom);
34
- return paddingY;
35
- };
36
- const Name = `collapsible-content`;
37
- const Component = (props, { element }) => {
38
- const [state, methods] = useCollapsibleItem(element);
39
- let isFirstRender = true;
40
- const expand = (element2) => {
41
- showElement(element2);
42
- const height = getHeight(element2), pt = getPaddingTop(element2), pb = getPaddingBottom(element2);
43
- Array.from(element2.children).forEach((child) => {
44
- child.style.opacity = "1";
45
- });
46
- const animation = animate(
47
- element2,
48
- {
49
- maxHeight: ["0px", `${height}px`],
50
- paddingTop: ["0px", `${pt}px`],
51
- paddingBottom: ["0px", `${pb}px`]
52
- },
53
- {
54
- duration: 0.35
55
- }
56
- );
57
- animation.then(() => {
58
- element2.style.maxHeight = "max-content";
59
- element2.style.overflow = null;
60
- if (props.shouldScrollIntoView)
61
- element2.scrollIntoView({
62
- behavior: "smooth",
63
- block: "start",
64
- inline: "nearest"
65
- });
66
- return;
67
- });
68
- return animation;
69
- };
70
- const collapse = (element2) => {
71
- const height = getHeight(element2), pt = getPaddingTop(element2), pb = getPaddingBottom(element2);
72
- element2.style.overflow = "hidden";
73
- Array.from(element2.children).forEach((child) => {
74
- child.style.opacity = "0";
75
- });
76
- const animation = animate(
77
- element2,
78
- {
79
- maxHeight: [`${height}px`, "0px"],
80
- paddingTop: [`${pt}px`, "0px"],
81
- paddingBottom: [`${pb}px`, "0px"]
82
- },
83
- {
84
- duration: 0.35
85
- }
86
- );
87
- animation.then(() => hideElement(element2));
88
- return animation;
89
- };
90
- createEffect(
91
- on(
92
- () => state.isExpanded,
93
- (isExpanded) => {
94
- if (!isExpanded) {
95
- isFirstRender = false;
96
- const animation2 = collapse(element);
97
- controlsToPromise(animation2).finally(methods.finish);
98
- return onCleanup(() => animation2.complete());
99
- }
100
- if (isFirstRender) {
101
- isFirstRender = false;
102
- showElement(element);
103
- Array.from(element.children).forEach((child) => {
104
- child.style.opacity = "1";
105
- });
106
- element.style.maxHeight = `max-content`;
107
- methods.finish();
108
- return;
109
- }
110
- const animation = expand(element);
111
- controlsToPromise(animation).finally(methods.finish);
112
- return onCleanup(() => animation.complete());
113
- }
114
- )
115
- );
116
- };
117
-
59
+ //#endregion
118
60
  export { Component, Name };
119
- //# sourceMappingURL=collapsible-content.js.map
61
+
120
62
  //# sourceMappingURL=collapsible-content.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/collapsible-content.ts"],"names":["element","animation"],"mappings":"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","file":"collapsible-content.js","sourcesContent":["import type { CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\nimport type { ICustomElement } from \"component-register\";\nimport { animate } from \"motion\";\nimport { createEffect, on, onCleanup, onMount } from \"solid-js\";\n\nimport { controlsToPromise } from \"@brytdesigns/web-component-core/animation\";\n\nimport { useCollapsibleItem } from \"../hooks/index.js\";\n\nexport type Props = {\n\tshouldScrollIntoView: boolean;\n};\n\nconst hideElement = (element: ICustomElement) => {\n\telement.style.cssText = `\n display: none;\n opacity: 0;\n visibility: hidden;\n max-height: 0px;\n `;\n\telement.style.overflow = null;\n};\n\nconst showElement = (element: ICustomElement) => {\n\telement.style.cssText = `\n display: block;\n opacity: 1;\n visibility: visible;\n `;\n};\n\nconst getHeight = (el: ICustomElement & HTMLElement) => {\n\tel.style.maxHeight = \"max-content\";\n\tconst height = el.getBoundingClientRect().height;\n\tel.style.maxHeight = `${0}`;\n\treturn height;\n};\n\nconst getPaddingTop = (element: ICustomElement & HTMLElement) => {\n\tconst paddingY = parseInt(getComputedStyle(element).paddingTop);\n\treturn paddingY;\n};\n\nconst getPaddingBottom = (element: ICustomElement & HTMLElement) => {\n\tconst paddingY = parseInt(getComputedStyle(element).paddingBottom);\n\treturn paddingY;\n};\n\nexport const Name = `collapsible-content`;\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n\tconst [state, methods] = useCollapsibleItem(element);\n\n\tlet isFirstRender = true;\n\n\tconst expand = (element: ICustomElement & HTMLElement) => {\n\t\tshowElement(element);\n\n\t\tconst height = getHeight(element),\n\t\t\tpt = getPaddingTop(element),\n\t\t\tpb = getPaddingBottom(element);\n\n\t\t(Array.from(element.children) as HTMLElement[]).forEach((child) => {\n\t\t\tchild.style.opacity = \"1\";\n\t\t});\n\n\t\tconst animation = animate(\n\t\t\telement,\n\t\t\t{\n\t\t\t\tmaxHeight: [\"0px\", `${height}px`],\n\t\t\t\tpaddingTop: [\"0px\", `${pt}px`],\n\t\t\t\tpaddingBottom: [\"0px\", `${pb}px`],\n\t\t\t},\n\t\t\t{\n\t\t\t\tduration: 0.35,\n\t\t\t},\n\t\t);\n\n\t\tanimation.then(() => {\n\t\t\telement.style.maxHeight = \"max-content\";\n\t\t\t//@ts-ignore\n\t\t\telement.style.overflow = null;\n\t\t\tif (props.shouldScrollIntoView)\n\t\t\t\telement.scrollIntoView({\n\t\t\t\t\tbehavior: \"smooth\",\n\t\t\t\t\tblock: \"start\",\n\t\t\t\t\tinline: \"nearest\",\n\t\t\t\t});\n\t\t\treturn;\n\t\t});\n\n\t\treturn animation;\n\t};\n\n\tconst collapse = (element: ICustomElement & HTMLElement) => {\n\t\tconst height = getHeight(element),\n\t\t\tpt = getPaddingTop(element),\n\t\t\tpb = getPaddingBottom(element);\n\n\t\telement.style.overflow = \"hidden\";\n\n\t\t(Array.from(element.children) as HTMLElement[]).forEach((child) => {\n\t\t\tchild.style.opacity = \"0\";\n\t\t});\n\n\t\tconst animation = animate(\n\t\t\telement,\n\t\t\t{\n\t\t\t\tmaxHeight: [`${height}px`, \"0px\"],\n\t\t\t\tpaddingTop: [`${pt}px`, \"0px\"],\n\t\t\t\tpaddingBottom: [`${pb}px`, \"0px\"],\n\t\t\t},\n\t\t\t{\n\t\t\t\tduration: 0.35,\n\t\t\t},\n\t\t);\n\n\t\tanimation.then(() => hideElement(element));\n\n\t\treturn animation;\n\t};\n\n\tcreateEffect(\n\t\ton(\n\t\t\t() => state.isExpanded,\n\t\t\t(isExpanded) => {\n\t\t\t\tif (!isExpanded) {\n\t\t\t\t\tisFirstRender = false;\n\t\t\t\t\tconst animation = collapse(element);\n\t\t\t\t\tcontrolsToPromise(animation).finally(methods.finish);\n\t\t\t\t\treturn onCleanup(() => animation.complete());\n\t\t\t\t}\n\n\t\t\t\tif (isFirstRender) {\n\t\t\t\t\tisFirstRender = false;\n\t\t\t\t\tshowElement(element);\n\t\t\t\t\t(Array.from(element.children) as HTMLElement[]).forEach((child) => {\n\t\t\t\t\t\tchild.style.opacity = \"1\";\n\t\t\t\t\t});\n\t\t\t\t\telement.style.maxHeight = `max-content`;\n\t\t\t\t\tmethods.finish();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst animation = expand(element);\n\t\t\t\tcontrolsToPromise(animation).finally(methods.finish);\n\t\t\t\treturn onCleanup(() => animation.complete());\n\t\t\t},\n\t\t),\n\t);\n};\n"]}
1
+ {"version":3,"file":"collapsible-content.js","names":[],"sources":["../../../src/components/collapsible-content.ts"],"sourcesContent":["import {\n\tcollapseContent,\n\tcontrolsToPromise,\n\texpandContent,\n\thideContent,\n\tonContentRevealed,\n\tshouldReduceMotion,\n\tshowContent,\n} from \"@brytdesigns/web-component-core/animation\";\nimport type { CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\nimport { createGuardedEffect } from \"@brytdesigns/web-component-core/utils\";\nimport { onCleanup } from \"solid-js\";\n\nimport { useCollapsibleItem } from \"../hooks/index.js\";\n\nexport type Props = {\n\tshouldScrollIntoView: boolean;\n};\n\nexport const Name = `collapsible-content`;\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n\tconst [state, methods] = useCollapsibleItem(element);\n\n\tlet isFirstRender = true;\n\t// Counted rather than held as a flag across the write: Solid 2 stages writes\n\t// and flushes their effects together, so a flag set before `expand()` and\n\t// cleared after it would already be back to `false` by the time the effect\n\t// below runs. A counter the effect compares against is independent of when\n\t// the flush happens.\n\tlet revealCount = 0;\n\tlet seenRevealCount = 0;\n\n\t// Find-in-page matched text in the closed content: open it without\n\t// animating, so it is settled before the browser scrolls to the match.\n\t// Component-level `onCleanup` does register and fire; inside an effect's\n\t// apply phase it would not, because the apply phase is not a computation.\n\tonCleanup(\n\t\tonContentRevealed(element, () => {\n\t\t\trevealCount += 1;\n\t\t\tmethods.expand();\n\t\t}),\n\t);\n\n\tconst expand = (element: HTMLElement, isStale: () => boolean) => {\n\t\tconst animation = expandContent(element, isStale);\n\n\t\tanimation.then(() => {\n\t\t\tif (isStale()) return;\n\t\t\tif (props.shouldScrollIntoView)\n\t\t\t\telement.scrollIntoView({\n\t\t\t\t\tbehavior: shouldReduceMotion() ? \"instant\" : \"smooth\",\n\t\t\t\t\tblock: \"start\",\n\t\t\t\t\tinline: \"nearest\",\n\t\t\t\t});\n\t\t});\n\n\t\treturn animation;\n\t};\n\n\tcreateGuardedEffect(\n\t\t() => state.isExpanded,\n\t\t(isExpanded) => {\n\t\t\tconst isRevealing = revealCount !== seenRevealCount;\n\t\t\tseenRevealCount = revealCount;\n\n\t\t\t// The first render applies the starting state without animating, as\n\t\t\t// does a find-in-page reveal: the match is scrolled to straight after,\n\t\t\t// so the layout has to be settled by then.\n\t\t\tif (isFirstRender || isRevealing) {\n\t\t\t\tisFirstRender = false;\n\t\t\t\tif (isExpanded) showContent(element);\n\t\t\t\telse hideContent(element);\n\t\t\t\tmethods.finish();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Flipped by this run's cleanup, so a completed-but-still-pending\n\t\t\t// animation cannot write styles for a direction we have left.\n\t\t\t// Expanding within the 0.35s of a collapse used to leave the content\n\t\t\t// `display: none` with `is-expanded=\"true\"`.\n\t\t\tlet stale = false;\n\t\t\tconst isStale = () => stale;\n\n\t\t\tif (!isExpanded) {\n\t\t\t\tmethods.start();\n\t\t\t\tconst animation = collapseContent(element, isStale);\n\t\t\t\tcontrolsToPromise(animation).finally(methods.finish);\n\t\t\t\t// v2 treats the apply phase's return value as the cleanup, so the\n\t\t\t\t// function is returned directly rather than via `onCleanup`.\n\t\t\t\treturn () => {\n\t\t\t\t\tstale = true;\n\t\t\t\t\tanimation.complete();\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tmethods.start();\n\t\t\tconst animation = expand(element, isStale);\n\t\t\tcontrolsToPromise(animation).finally(methods.finish);\n\t\t\treturn () => {\n\t\t\t\tstale = true;\n\t\t\t\tanimation.complete();\n\t\t\t};\n\t\t},\n\t);\n};\n"],"mappings":";;;;;;AAmBA,IAAa,OAAO;AAEpB,IAAa,aAA0C,OAAO,EAAE,cAAc;CAC7E,MAAM,CAAC,OAAO,WAAW,mBAAmB,OAAO;CAEnD,IAAI,gBAAgB;CAMpB,IAAI,cAAc;CAClB,IAAI,kBAAkB;CAMtB,UACC,kBAAkB,eAAe;EAChC,eAAe;EACf,QAAQ,OAAO;CAChB,CAAC,CACF;CAEA,MAAM,UAAU,SAAsB,YAA2B;EAChE,MAAM,YAAY,cAAc,SAAS,OAAO;EAEhD,UAAU,WAAW;GACpB,IAAI,QAAQ,GAAG;GACf,IAAI,MAAM,sBACT,QAAQ,eAAe;IACtB,UAAU,mBAAmB,IAAI,YAAY;IAC7C,OAAO;IACP,QAAQ;GACT,CAAC;EACH,CAAC;EAED,OAAO;CACR;CAEA,0BACO,MAAM,aACX,eAAe;EACf,MAAM,cAAc,gBAAgB;EACpC,kBAAkB;EAKlB,IAAI,iBAAiB,aAAa;GACjC,gBAAgB;GAChB,IAAI,YAAY,YAAY,OAAO;QAC9B,YAAY,OAAO;GACxB,QAAQ,OAAO;GACf;EACD;EAMA,IAAI,QAAQ;EACZ,MAAM,gBAAgB;EAEtB,IAAI,CAAC,YAAY;GAChB,QAAQ,MAAM;GACd,MAAM,YAAY,gBAAgB,SAAS,OAAO;GAClD,kBAAkB,SAAS,CAAC,CAAC,QAAQ,QAAQ,MAAM;GAGnD,aAAa;IACZ,QAAQ;IACR,UAAU,SAAS;GACpB;EACD;EAEA,QAAQ,MAAM;EACd,MAAM,YAAY,OAAO,SAAS,OAAO;EACzC,kBAAkB,SAAS,CAAC,CAAC,QAAQ,QAAQ,MAAM;EACnD,aAAa;GACZ,QAAQ;GACR,UAAU,SAAS;EACpB;CACD,CACD;AACD"}
@@ -1,10 +1,11 @@
1
- import { provideCollapsibleItemContext } from '../hooks/index.js';
2
-
3
- const Name = `collapsible-item`;
4
- const Component = (props, { element }) => {
5
- provideCollapsibleItemContext(props, element);
1
+ import { provideCollapsibleItemContext } from "../hooks/useCollapsibleItem.js";
2
+ import "../hooks/index.js";
3
+ //#region src/components/collapsible-item.ts
4
+ var Name = `collapsible-item`;
5
+ var Component = (props, { element }) => {
6
+ provideCollapsibleItemContext(props, element);
6
7
  };
7
-
8
+ //#endregion
8
9
  export { Component, Name };
9
- //# sourceMappingURL=collapsible-item.js.map
10
+
10
11
  //# sourceMappingURL=collapsible-item.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/collapsible-item.ts"],"names":[],"mappings":";;AAUO,MAAM,IAAO,GAAA,CAAA,gBAAA;AAEb,MAAM,SAAyC,GAAA,CAAC,KAAO,EAAA,EAAE,SAAc,KAAA;AAC7E,EAAA,6BAAA,CAA8B,OAAO,OAAO,CAAA;AAC7C","file":"collapsible-item.js","sourcesContent":["import type { CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\n\nimport { provideCollapsibleItemContext } from \"../hooks/index.js\";\n\nexport type Props = {\n\tisExpanded: boolean;\n\tisAnimating: boolean;\n\tariaExpanded: boolean;\n};\n\nexport const Name = `collapsible-item`;\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n\tprovideCollapsibleItemContext(props, element);\n};\n"]}
1
+ {"version":3,"file":"collapsible-item.js","names":[],"sources":["../../../src/components/collapsible-item.ts"],"sourcesContent":["import type { CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\n\nimport { provideCollapsibleItemContext } from \"../hooks/index.js\";\n\nexport type Props = {\n\tisExpanded: boolean;\n\tisAnimating: boolean;\n};\n\nexport const Name = `collapsible-item`;\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n\tprovideCollapsibleItemContext(props, element);\n};\n"],"mappings":";;;AASA,IAAa,OAAO;AAEpB,IAAa,aAA0C,OAAO,EAAE,cAAc;CAC7E,8BAA8B,OAAO,OAAO;AAC7C"}
@@ -1,27 +1,35 @@
1
- import { createEffect, onCleanup } from 'solid-js';
2
- import { useCollapsibleItem } from '../hooks/index.js';
3
-
4
- const Name = `collapsible-trigger`;
5
- const Component = (props, { element }) => {
6
- const [state, methods] = useCollapsibleItem(element);
7
- createEffect(() => {
8
- const isAnimating = state.isAnimating;
9
- if (isAnimating) return;
10
- const controller = new AbortController(), preventDefault = props.preventDefault;
11
- element.addEventListener(
12
- "click",
13
- (event) => {
14
- if (preventDefault) event.preventDefault();
15
- methods.toggle();
16
- },
17
- { signal: controller.signal }
18
- );
19
- return onCleanup(() => {
20
- controller.abort();
21
- });
22
- });
1
+ import { useCollapsibleItem } from "../hooks/useCollapsibleItem.js";
2
+ import "../hooks/index.js";
3
+ import { createGuardedEffect, findDisclosureContent, findDisclosureControl, linkDisclosureControl } from "@brytdesigns/web-component-core/utils";
4
+ //#region src/components/collapsible-trigger.ts
5
+ var Name = `collapsible-trigger`;
6
+ var Component = (props, { element }) => {
7
+ const [state, methods] = useCollapsibleItem(element);
8
+ const control = findDisclosureControl(element);
9
+ if (!control) console.warn(`${Name}: put a <button> inside the trigger so assistive tech can operate it`, element);
10
+ else {
11
+ let isLinked = false;
12
+ createGuardedEffect(() => state.isExpanded, (isExpanded) => {
13
+ control.setAttribute("aria-expanded", isExpanded ? "true" : "false");
14
+ if (!isLinked) isLinked = linkDisclosureControl(control, findDisclosureContent(element, "collapsible-item", "collapsible-content"), "collapsible-content");
15
+ });
16
+ }
17
+ createGuardedEffect(() => ({
18
+ isAnimating: state.isAnimating,
19
+ preventDefault: props.preventDefault
20
+ }), ({ isAnimating, preventDefault }) => {
21
+ if (isAnimating) return;
22
+ const controller = new AbortController();
23
+ element.addEventListener("click", (event) => {
24
+ if (preventDefault) event.preventDefault();
25
+ methods.toggle();
26
+ }, { signal: controller.signal });
27
+ return () => {
28
+ controller.abort();
29
+ };
30
+ });
23
31
  };
24
-
32
+ //#endregion
25
33
  export { Component, Name };
26
- //# sourceMappingURL=collapsible-trigger.js.map
34
+
27
35
  //# sourceMappingURL=collapsible-trigger.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/collapsible-trigger.ts"],"names":[],"mappings":";;;AAUO,MAAM,IAAO,GAAA,CAAA,mBAAA;AAEb,MAAM,SAAyC,GAAA,CAAC,KAAO,EAAA,EAAE,SAAc,KAAA;AAC7E,EAAA,MAAM,CAAC,KAAA,EAAO,OAAO,CAAA,GAAI,mBAAmB,OAAO,CAAA;AAEnD,EAAA,YAAA,CAAa,MAAM;AAClB,IAAA,MAAM,cAAc,KAAM,CAAA,WAAA;AAC1B,IAAA,IAAI,WAAa,EAAA;AAEjB,IAAA,MAAM,UAAa,GAAA,IAAI,eAAgB,EAAA,EACtC,iBAAiB,KAAM,CAAA,cAAA;AAExB,IAAQ,OAAA,CAAA,gBAAA;AAAA,MACP,OAAA;AAAA,MACA,CAAC,KAAU,KAAA;AACV,QAAI,IAAA,cAAA,QAAsB,cAAe,EAAA;AACzC,QAAA,OAAA,CAAQ,MAAO,EAAA;AAAA,OAChB;AAAA,MACA,EAAE,MAAQ,EAAA,UAAA,CAAW,MAAO;AAAA,KAC7B;AAEA,IAAA,OAAO,UAAU,MAAM;AACtB,MAAA,UAAA,CAAW,KAAM,EAAA;AAAA,KACjB,CAAA;AAAA,GACD,CAAA;AACF","file":"collapsible-trigger.js","sourcesContent":["import type { CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\n\nimport { createEffect, onCleanup } from \"solid-js\";\n\nimport { useCollapsibleItem } from \"../hooks/index.js\";\n\nexport type Props = {\n\tpreventDefault: boolean;\n};\n\nexport const Name = `collapsible-trigger`;\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n\tconst [state, methods] = useCollapsibleItem(element);\n\n\tcreateEffect(() => {\n\t\tconst isAnimating = state.isAnimating;\n\t\tif (isAnimating) return;\n\n\t\tconst controller = new AbortController(),\n\t\t\tpreventDefault = props.preventDefault;\n\n\t\telement.addEventListener(\n\t\t\t\"click\",\n\t\t\t(event) => {\n\t\t\t\tif (preventDefault) event.preventDefault();\n\t\t\t\tmethods.toggle();\n\t\t\t},\n\t\t\t{ signal: controller.signal },\n\t\t);\n\n\t\treturn onCleanup(() => {\n\t\t\tcontroller.abort();\n\t\t});\n\t});\n};\n"]}
1
+ {"version":3,"file":"collapsible-trigger.js","names":[],"sources":["../../../src/components/collapsible-trigger.ts"],"sourcesContent":["import {\n\ttype CorrectComponentType,\n\tcreateGuardedEffect,\n\tfindDisclosureContent,\n\tfindDisclosureControl,\n\tlinkDisclosureControl,\n} from \"@brytdesigns/web-component-core/utils\";\n\nimport { useCollapsibleItem } from \"../hooks/index.js\";\n\nexport type Props = {\n\tpreventDefault: boolean;\n};\n\nexport const Name = `collapsible-trigger`;\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n\tconst [state, methods] = useCollapsibleItem(element);\n\n\t// `aria-expanded` belongs on the element with the button role, not on\n\t// `collapsible-trigger`, which has no role at all — assistive tech ignored\n\t// it there.\n\tconst control = findDisclosureControl(element);\n\tif (!control) {\n\t\tconsole.warn(\n\t\t\t`${Name}: put a <button> inside the trigger so assistive tech can operate it`,\n\t\t\telement,\n\t\t);\n\t} else {\n\t\tlet isLinked = false;\n\t\tcreateGuardedEffect(\n\t\t\t() => state.isExpanded,\n\t\t\t(isExpanded) => {\n\t\t\t\tcontrol.setAttribute(\"aria-expanded\", isExpanded ? \"true\" : \"false\");\n\t\t\t\t// The content may not be parsed yet when the trigger first renders.\n\t\t\t\tif (!isLinked)\n\t\t\t\t\tisLinked = linkDisclosureControl(\n\t\t\t\t\t\tcontrol,\n\t\t\t\t\t\tfindDisclosureContent(\n\t\t\t\t\t\t\telement,\n\t\t\t\t\t\t\t\"collapsible-item\",\n\t\t\t\t\t\t\t\"collapsible-content\",\n\t\t\t\t\t\t),\n\t\t\t\t\t\t\"collapsible-content\",\n\t\t\t\t\t);\n\t\t\t},\n\t\t);\n\t}\n\n\tcreateGuardedEffect(\n\t\t// `preventDefault` belongs in the compute: read in apply it is untracked,\n\t\t// so changing the attribute would not rewire the listener.\n\t\t() => ({\n\t\t\tisAnimating: state.isAnimating,\n\t\t\tpreventDefault: props.preventDefault,\n\t\t}),\n\t\t({ isAnimating, preventDefault }) => {\n\t\t\tif (isAnimating) return;\n\n\t\t\tconst controller = new AbortController();\n\n\t\t\telement.addEventListener(\n\t\t\t\t\"click\",\n\t\t\t\t(event) => {\n\t\t\t\t\tif (preventDefault) event.preventDefault();\n\t\t\t\t\tmethods.toggle();\n\t\t\t\t},\n\t\t\t\t{ signal: controller.signal },\n\t\t\t);\n\n\t\t\treturn () => {\n\t\t\t\tcontroller.abort();\n\t\t\t};\n\t\t},\n\t);\n};\n"],"mappings":";;;;AAcA,IAAa,OAAO;AAEpB,IAAa,aAA0C,OAAO,EAAE,cAAc;CAC7E,MAAM,CAAC,OAAO,WAAW,mBAAmB,OAAO;CAKnD,MAAM,UAAU,sBAAsB,OAAO;CAC7C,IAAI,CAAC,SACJ,QAAQ,KACP,GAAG,KAAK,uEACR,OACD;MACM;EACN,IAAI,WAAW;EACf,0BACO,MAAM,aACX,eAAe;GACf,QAAQ,aAAa,iBAAiB,aAAa,SAAS,OAAO;GAEnE,IAAI,CAAC,UACJ,WAAW,sBACV,SACA,sBACC,SACA,oBACA,qBACD,GACA,qBACD;EACF,CACD;CACD;CAEA,2BAGQ;EACN,aAAa,MAAM;EACnB,gBAAgB,MAAM;CACvB,KACC,EAAE,aAAa,qBAAqB;EACpC,IAAI,aAAa;EAEjB,MAAM,aAAa,IAAI,gBAAgB;EAEvC,QAAQ,iBACP,UACC,UAAU;GACV,IAAI,gBAAgB,MAAM,eAAe;GACzC,QAAQ,OAAO;EAChB,GACA,EAAE,QAAQ,WAAW,OAAO,CAC7B;EAEA,aAAa;GACZ,WAAW,MAAM;EAClB;CACD,CACD;AACD"}
@@ -1,8 +1,3 @@
1
- import * as collapsibleContent_js from './collapsible-content.js';
2
- export { collapsibleContent_js as CollapsibleContent };
3
- import * as collapsibleTrigger_js from './collapsible-trigger.js';
4
- export { collapsibleTrigger_js as CollapsibleTrigger };
5
- import * as collapsibleItem_js from './collapsible-item.js';
6
- export { collapsibleItem_js as CollapsibleItem };
7
- //# sourceMappingURL=index.js.map
8
- //# sourceMappingURL=index.js.map
1
+ import "./collapsible-content.js";
2
+ import "./collapsible-item.js";
3
+ import "./collapsible-trigger.js";
@@ -1,3 +1,2 @@
1
- export * from './useCollapsibleItem.js';
2
- //# sourceMappingURL=index.js.map
3
- //# sourceMappingURL=index.js.map
1
+ import { getCollapsibleItemContext, provideCollapsibleItemContext, useCollapsibleItem, useCollapsibleItemAt, useCollapsibleItemContext } from "./useCollapsibleItem.js";
2
+ export { getCollapsibleItemContext, provideCollapsibleItemContext, useCollapsibleItem, useCollapsibleItemAt, useCollapsibleItemContext };
@@ -1,86 +1,73 @@
1
- import { createContext, provide, consume } from 'component-register';
2
- import { splitProps, createEffect, on, batch, untrack, mergeProps } from 'solid-js';
3
- import { createWithElementContext, toHyphenated, getContextFromProvider } from '@brytdesigns/web-component-core/utils';
4
-
1
+ import { createRemoteContext, getContextFromProvider, toHyphenated } from "@brytdesigns/web-component-core/utils";
2
+ import { merge, omit, untrack } from "solid-js";
3
+ import { consume, createContext, provide } from "component-register";
4
+ //#region src/hooks/useCollapsibleItem.ts
5
5
  function initializeCollapsibleItemContext(props) {
6
- const [element, _, stateProps] = splitProps(
7
- props,
8
- ["root"],
9
- ["ariaExpanded"]
10
- );
11
- function setElementState(key, value) {
12
- const currentValue = untrack(() => props[key]);
13
- if (typeof value === "function") {
14
- let result = false;
15
- if (typeof currentValue === "number") {
16
- result = value(currentValue || 0);
17
- } else if (typeof currentValue === "boolean") {
18
- result = value(currentValue || false);
19
- }
20
- if (`${currentValue}` === `${value}`) return;
21
- element.root.setAttribute(toHyphenated(key), `${result}`);
22
- return;
23
- }
24
- if (`${currentValue}` === `${value}`) return;
25
- return element.root.setAttribute(toHyphenated(key), `${value}`);
26
- }
27
- createEffect(
28
- on(
29
- () => stateProps.isExpanded,
30
- (isExpanded) => {
31
- batch(() => {
32
- setElementState("ariaExpanded", isExpanded);
33
- setElementState("isAnimating", true);
34
- });
35
- }
36
- )
37
- );
38
- return [stateProps, { setElementState }];
6
+ const stateProps = omit(props, "root");
7
+ function setElementState(key, value) {
8
+ const currentValue = untrack(() => props[key]);
9
+ if (typeof value === "function") {
10
+ let result = false;
11
+ if (typeof currentValue === "number") result = value(currentValue || 0);
12
+ else if (typeof currentValue === "boolean") result = value(currentValue || false);
13
+ if (`${currentValue}` === `${result}`) return;
14
+ props.root.setAttribute(toHyphenated(key), `${result}`);
15
+ return;
16
+ }
17
+ if (`${currentValue}` === `${value}`) return;
18
+ return props.root.setAttribute(toHyphenated(key), `${value}`);
19
+ }
20
+ return [stateProps, { setElementState }];
39
21
  }
40
- const CollapsibleItemContextState = createContext(
41
- initializeCollapsibleItemContext
42
- );
43
- const provideCollapsibleItemContext = (initialState, element) => {
44
- const props = mergeProps(initialState, { root: element });
45
- return provide(CollapsibleItemContextState, props, element);
22
+ var CollapsibleItemContextState = createContext(initializeCollapsibleItemContext);
23
+ var provideCollapsibleItemContext = (initialState, element) => {
24
+ const props = merge(initialState, { root: element });
25
+ return provide(CollapsibleItemContextState, props, element);
46
26
  };
47
- const useCollapsibleItemContext = (context) => {
48
- const [state, { setElementState }] = context;
49
- function expand() {
50
- setElementState("isExpanded", true);
51
- }
52
- function collapse() {
53
- setElementState("isExpanded", false);
54
- }
55
- function toggle() {
56
- setElementState("isExpanded", (v) => !v);
57
- }
58
- function finish() {
59
- setElementState("isAnimating", false);
60
- }
61
- return [state, { expand, collapse, toggle, finish }];
27
+ var useCollapsibleItemContext = (context) => {
28
+ const [state, { setElementState }] = context;
29
+ function expand() {
30
+ setElementState("isExpanded", true);
31
+ }
32
+ function collapse() {
33
+ setElementState("isExpanded", false);
34
+ }
35
+ function toggle() {
36
+ setElementState("isExpanded", (v) => !v);
37
+ }
38
+ /**
39
+ * `is-animating` is owned by `collapsible-content`, which is the only part
40
+ * that knows whether a state change animates or is applied outright. The
41
+ * item used to flag it from an effect on every `is-expanded` change, which
42
+ * raced the content: on a find-in-page reveal the content snapped open and
43
+ * cleared the flag before the item set it, leaving `is-animating="true"`
44
+ * with nothing animating — and `collapsible-trigger` ignores clicks while
45
+ * that is set.
46
+ */
47
+ function start() {
48
+ setElementState("isAnimating", true);
49
+ }
50
+ function finish() {
51
+ setElementState("isAnimating", false);
52
+ }
53
+ return [state, {
54
+ expand,
55
+ collapse,
56
+ toggle,
57
+ start,
58
+ finish
59
+ }];
62
60
  };
63
- const useCollapsibleItem = (element) => {
64
- const context = consume(
65
- CollapsibleItemContextState,
66
- element
67
- );
68
- if (!context) {
69
- throw console.error(
70
- "AccordionItemContext not found! Please ensure to wrap your custom element with accordion-item element."
71
- );
72
- }
73
- return useCollapsibleItemContext(context);
61
+ var useCollapsibleItem = (element) => {
62
+ const context = consume(CollapsibleItemContextState, element);
63
+ if (!context) throw new Error("AccordionItemContext not found! Please ensure to wrap your custom element with accordion-item element.");
64
+ return useCollapsibleItemContext(context);
74
65
  };
75
- const withCollapsibleItemElementContext = createWithElementContext(CollapsibleItemContextState);
76
- const getCollapsibleItemContext = (element) => {
77
- const context = getContextFromProvider(
78
- CollapsibleItemContextState,
79
- element
80
- );
81
- return useCollapsibleItemContext(context);
66
+ var useCollapsibleItemAt = createRemoteContext(CollapsibleItemContextState);
67
+ var getCollapsibleItemContext = (element) => {
68
+ return useCollapsibleItemContext(getContextFromProvider(CollapsibleItemContextState, element));
82
69
  };
70
+ //#endregion
71
+ export { getCollapsibleItemContext, provideCollapsibleItemContext, useCollapsibleItem, useCollapsibleItemAt, useCollapsibleItemContext };
83
72
 
84
- export { getCollapsibleItemContext, provideCollapsibleItemContext, useCollapsibleItem, useCollapsibleItemContext, withCollapsibleItemElementContext };
85
- //# sourceMappingURL=useCollapsibleItem.js.map
86
73
  //# sourceMappingURL=useCollapsibleItem.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/hooks/useCollapsibleItem.ts"],"names":[],"mappings":"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","file":"useCollapsibleItem.js","sourcesContent":["import {\n\ttype ICustomElement,\n\tcreateContext,\n\tprovide,\n\tconsume,\n} from \"component-register\";\nimport {\n\tbatch,\n\tcreateEffect,\n\tmergeProps,\n\ton,\n\tsplitProps,\n\tuntrack,\n} from \"solid-js\";\nimport {\n\ttoHyphenated,\n\tgetContextFromProvider,\n\tcreateWithElementContext,\n} from \"@brytdesigns/web-component-core/utils\";\n\ntype CreateContextOptions = {\n\troot: HTMLElement & ICustomElement;\n\tisExpanded: boolean;\n\tariaExpanded: boolean;\n\tisAnimating: boolean;\n};\n\ntype WalkableNode = Parameters<typeof provide>[2];\n\ntype CollapsibleItemContext = ReturnType<\n\ttypeof initializeCollapsibleItemContext\n>;\n\nfunction initializeCollapsibleItemContext(props: CreateContextOptions) {\n\tconst [element, _, stateProps] = splitProps(\n\t\tprops,\n\t\t[\"root\"],\n\t\t[\"ariaExpanded\"],\n\t);\n\n\tfunction setElementState(\n\t\tkey: keyof Omit<CreateContextOptions, \"root\">,\n\t\tvalue: boolean | number | ((v: boolean | number) => boolean | number),\n\t) {\n\t\tconst currentValue = untrack(() => props[key]);\n\t\tif (typeof value === \"function\") {\n\t\t\tlet result: boolean | number = false;\n\t\t\tif (typeof currentValue === \"number\") {\n\t\t\t\tresult = value(currentValue || 0);\n\t\t\t} else if (typeof currentValue === \"boolean\") {\n\t\t\t\tresult = value(currentValue || false);\n\t\t\t}\n\t\t\tif (`${currentValue}` === `${value}`) return;\n\t\t\telement.root.setAttribute(toHyphenated(key), `${result}`);\n\t\t\treturn;\n\t\t}\n\t\tif (`${currentValue}` === `${value}`) return;\n\t\treturn element.root.setAttribute(toHyphenated(key), `${value}`);\n\t}\n\n\tcreateEffect(\n\t\ton(\n\t\t\t() => stateProps.isExpanded,\n\t\t\t(isExpanded) => {\n\t\t\t\tbatch(() => {\n\t\t\t\t\tsetElementState(\"ariaExpanded\", isExpanded);\n\t\t\t\t\tsetElementState(\"isAnimating\", true);\n\t\t\t\t});\n\t\t\t},\n\t\t),\n\t);\n\n\treturn [stateProps, { setElementState }] as const;\n}\n\nconst CollapsibleItemContextState = createContext(\n\tinitializeCollapsibleItemContext,\n);\n\nexport const provideCollapsibleItemContext = (\n\tinitialState: Omit<CreateContextOptions, \"root\">,\n\telement: WalkableNode,\n): CollapsibleItemContext => {\n\tconst props = mergeProps(initialState, { root: element });\n\treturn provide(CollapsibleItemContextState, props, element);\n};\n\nexport const useCollapsibleItemContext = (context: CollapsibleItemContext) => {\n\tconst [state, { setElementState }] = context;\n\n\tfunction expand() {\n\t\tsetElementState(\"isExpanded\", true);\n\t}\n\n\tfunction collapse() {\n\t\tsetElementState(\"isExpanded\", false);\n\t}\n\n\tfunction toggle() {\n\t\tsetElementState(\"isExpanded\", (v) => !v);\n\t}\n\n\tfunction finish() {\n\t\tsetElementState(\"isAnimating\", false);\n\t}\n\n\treturn [state, { expand, collapse, toggle, finish }] as const;\n};\n\nexport const useCollapsibleItem = (element: HTMLElement & ICustomElement) => {\n\tconst context: CollapsibleItemContext = consume(\n\t\tCollapsibleItemContextState,\n\t\telement,\n\t);\n\n\tif (!context) {\n\t\tthrow console.error(\n\t\t\t\"AccordionItemContext not found! Please ensure to wrap your custom element with accordion-item element.\",\n\t\t);\n\t}\n\n\treturn useCollapsibleItemContext(context);\n};\n\nexport const withCollapsibleItemElementContext = createWithElementContext<\n\ttypeof CollapsibleItemContextState,\n\tCollapsibleItemContext\n>(CollapsibleItemContextState);\n\nexport const getCollapsibleItemContext = (element: Element) => {\n\tconst context = getContextFromProvider<CollapsibleItemContext>(\n\t\tCollapsibleItemContextState,\n\t\telement,\n\t);\n\treturn useCollapsibleItemContext(context);\n};\n"]}
1
+ {"version":3,"file":"useCollapsibleItem.js","names":[],"sources":["../../../src/hooks/useCollapsibleItem.ts"],"sourcesContent":["import {\n\tcreateRemoteContext,\n\tgetContextFromProvider,\n\ttoHyphenated,\n} from \"@brytdesigns/web-component-core/utils\";\nimport {\n\tconsume,\n\tcreateContext,\n\ttype ICustomElement,\n\tprovide,\n} from \"component-register\";\nimport { merge, omit, untrack } from \"solid-js\";\n\ntype CreateContextOptions = {\n\troot: HTMLElement & ICustomElement;\n\tisExpanded: boolean;\n\tisAnimating: boolean;\n};\n\ntype WalkableNode = Parameters<typeof provide>[2];\n\ntype CollapsibleItemContext = ReturnType<\n\ttypeof initializeCollapsibleItemContext\n>;\n\nfunction initializeCollapsibleItemContext(props: CreateContextOptions) {\n\t// `splitProps` is gone; `omit` returns only the rest, so the picked keys are\n\t// read straight off `props` instead of through a split group.\n\tconst stateProps = omit(props, \"root\");\n\n\tfunction setElementState(\n\t\tkey: keyof Omit<CreateContextOptions, \"root\">,\n\t\tvalue: boolean | number | ((v: boolean | number) => boolean | number),\n\t) {\n\t\tconst currentValue = untrack(() => props[key]);\n\t\tif (typeof value === \"function\") {\n\t\t\tlet result: boolean | number = false;\n\t\t\tif (typeof currentValue === \"number\") {\n\t\t\t\tresult = value(currentValue || 0);\n\t\t\t} else if (typeof currentValue === \"boolean\") {\n\t\t\t\tresult = value(currentValue || false);\n\t\t\t}\n\t\t\t// Compare against the computed result, not `value` — `value` is the\n\t\t\t// updater function here, and its source text never equals a state\n\t\t\t// value, so this guard never fired on the updater path. Latent\n\t\t\t// rather than active today: every updater in the repo is a\n\t\t\t// negation, so the result always differs anyway.\n\t\t\tif (`${currentValue}` === `${result}`) return;\n\t\t\tprops.root.setAttribute(toHyphenated(key), `${result}`);\n\t\t\treturn;\n\t\t}\n\t\tif (`${currentValue}` === `${value}`) return;\n\t\treturn props.root.setAttribute(toHyphenated(key), `${value}`);\n\t}\n\n\treturn [stateProps, { setElementState }] as const;\n}\n\nconst CollapsibleItemContextState = createContext(\n\tinitializeCollapsibleItemContext,\n);\n\nexport const provideCollapsibleItemContext = (\n\tinitialState: Omit<CreateContextOptions, \"root\">,\n\telement: WalkableNode,\n): CollapsibleItemContext => {\n\tconst props = merge(initialState, { root: element });\n\treturn provide(CollapsibleItemContextState, props, element);\n};\n\nexport const useCollapsibleItemContext = (context: CollapsibleItemContext) => {\n\tconst [state, { setElementState }] = context;\n\n\tfunction expand() {\n\t\tsetElementState(\"isExpanded\", true);\n\t}\n\n\tfunction collapse() {\n\t\tsetElementState(\"isExpanded\", false);\n\t}\n\n\tfunction toggle() {\n\t\tsetElementState(\"isExpanded\", (v) => !v);\n\t}\n\n\t/**\n\t * `is-animating` is owned by `collapsible-content`, which is the only part\n\t * that knows whether a state change animates or is applied outright. The\n\t * item used to flag it from an effect on every `is-expanded` change, which\n\t * raced the content: on a find-in-page reveal the content snapped open and\n\t * cleared the flag before the item set it, leaving `is-animating=\"true\"`\n\t * with nothing animating — and `collapsible-trigger` ignores clicks while\n\t * that is set.\n\t */\n\tfunction start() {\n\t\tsetElementState(\"isAnimating\", true);\n\t}\n\n\tfunction finish() {\n\t\tsetElementState(\"isAnimating\", false);\n\t}\n\n\treturn [state, { expand, collapse, toggle, start, finish }] as const;\n};\n\nexport const useCollapsibleItem = (element: HTMLElement & ICustomElement) => {\n\tconst context: CollapsibleItemContext = consume(\n\t\tCollapsibleItemContextState,\n\t\telement,\n\t);\n\n\tif (!context) {\n\t\tthrow new Error(\n\t\t\t\"AccordionItemContext not found! Please ensure to wrap your custom element with accordion-item element.\",\n\t\t);\n\t}\n\n\treturn useCollapsibleItemContext(context);\n};\n\nexport const useCollapsibleItemAt = createRemoteContext<CollapsibleItemContext>(\n\tCollapsibleItemContextState,\n);\n\nexport const getCollapsibleItemContext = (element: Element) => {\n\tconst context = getContextFromProvider<CollapsibleItemContext>(\n\t\tCollapsibleItemContextState,\n\t\telement,\n\t);\n\treturn useCollapsibleItemContext(context);\n};\n"],"mappings":";;;;AAyBA,SAAS,iCAAiC,OAA6B;CAGtE,MAAM,aAAa,KAAK,OAAO,MAAM;CAErC,SAAS,gBACR,KACA,OACC;EACD,MAAM,eAAe,cAAc,MAAM,IAAI;EAC7C,IAAI,OAAO,UAAU,YAAY;GAChC,IAAI,SAA2B;GAC/B,IAAI,OAAO,iBAAiB,UAC3B,SAAS,MAAM,gBAAgB,CAAC;QAC1B,IAAI,OAAO,iBAAiB,WAClC,SAAS,MAAM,gBAAgB,KAAK;GAOrC,IAAI,GAAG,mBAAmB,GAAG,UAAU;GACvC,MAAM,KAAK,aAAa,aAAa,GAAG,GAAG,GAAG,QAAQ;GACtD;EACD;EACA,IAAI,GAAG,mBAAmB,GAAG,SAAS;EACtC,OAAO,MAAM,KAAK,aAAa,aAAa,GAAG,GAAG,GAAG,OAAO;CAC7D;CAEA,OAAO,CAAC,YAAY,EAAE,gBAAgB,CAAC;AACxC;AAEA,IAAM,8BAA8B,cACnC,gCACD;AAEA,IAAa,iCACZ,cACA,YAC4B;CAC5B,MAAM,QAAQ,MAAM,cAAc,EAAE,MAAM,QAAQ,CAAC;CACnD,OAAO,QAAQ,6BAA6B,OAAO,OAAO;AAC3D;AAEA,IAAa,6BAA6B,YAAoC;CAC7E,MAAM,CAAC,OAAO,EAAE,qBAAqB;CAErC,SAAS,SAAS;EACjB,gBAAgB,cAAc,IAAI;CACnC;CAEA,SAAS,WAAW;EACnB,gBAAgB,cAAc,KAAK;CACpC;CAEA,SAAS,SAAS;EACjB,gBAAgB,eAAe,MAAM,CAAC,CAAC;CACxC;;;;;;;;;;CAWA,SAAS,QAAQ;EAChB,gBAAgB,eAAe,IAAI;CACpC;CAEA,SAAS,SAAS;EACjB,gBAAgB,eAAe,KAAK;CACrC;CAEA,OAAO,CAAC,OAAO;EAAE;EAAQ;EAAU;EAAQ;EAAO;CAAO,CAAC;AAC3D;AAEA,IAAa,sBAAsB,YAA0C;CAC5E,MAAM,UAAkC,QACvC,6BACA,OACD;CAEA,IAAI,CAAC,SACJ,MAAM,IAAI,MACT,wGACD;CAGD,OAAO,0BAA0B,OAAO;AACzC;AAEA,IAAa,uBAAuB,oBACnC,2BACD;AAEA,IAAa,6BAA6B,YAAqB;CAK9D,OAAO,0BAJS,uBACf,6BACA,OAEgC,CAAO;AACzC"}
@@ -2,6 +2,11 @@
2
2
 
3
3
  import { ICustomElement, provide } from 'component-register';
4
4
 
5
+ /**
6
+ * `component-register` types `options.element` as a bare `ICustomElement`, but
7
+ * at runtime it is always also an `HTMLElement`. Every component in this repo
8
+ * needs the DOM half.
9
+ */
5
10
  export type CorrectComponentOptions = {
6
11
  element: HTMLElement & ICustomElement;
7
12
  };
@@ -19,63 +24,60 @@ declare const Component$1: CorrectComponentType<Props$1>;
19
24
  export type CreateContextOptions = {
20
25
  root: HTMLElement & ICustomElement;
21
26
  isExpanded: boolean;
22
- ariaExpanded: boolean;
23
27
  isAnimating: boolean;
24
28
  };
25
29
  export type WalkableNode = Parameters<typeof provide>[2];
26
30
  export type CollapsibleItemContext = ReturnType<typeof initializeCollapsibleItemContext>;
27
31
  declare function initializeCollapsibleItemContext(props: CreateContextOptions): readonly [
28
- {
29
- isExpanded: boolean;
30
- isAnimating: boolean;
31
- },
32
+ import("solid-js").Omit<CreateContextOptions, [
33
+ "root"
34
+ ]>,
32
35
  {
33
36
  readonly setElementState: (key: keyof Omit<CreateContextOptions, "root">, value: boolean | number | ((v: boolean | number) => boolean | number)) => void;
34
37
  }
35
38
  ];
36
39
  export declare const provideCollapsibleItemContext: (initialState: Omit<CreateContextOptions, "root">, element: WalkableNode) => CollapsibleItemContext;
37
40
  export declare const useCollapsibleItemContext: (context: CollapsibleItemContext) => readonly [
38
- {
39
- isExpanded: boolean;
40
- isAnimating: boolean;
41
- },
41
+ import("solid-js").Omit<CreateContextOptions, [
42
+ "root"
43
+ ]>,
42
44
  {
43
45
  readonly expand: () => void;
44
46
  readonly collapse: () => void;
45
47
  readonly toggle: () => void;
48
+ readonly start: () => void;
46
49
  readonly finish: () => void;
47
50
  }
48
51
  ];
49
52
  export declare const useCollapsibleItem: (element: HTMLElement & ICustomElement) => readonly [
50
- {
51
- isExpanded: boolean;
52
- isAnimating: boolean;
53
- },
53
+ import("solid-js").Omit<CreateContextOptions, [
54
+ "root"
55
+ ]>,
54
56
  {
55
57
  readonly expand: () => void;
56
58
  readonly collapse: () => void;
57
59
  readonly toggle: () => void;
60
+ readonly start: () => void;
58
61
  readonly finish: () => void;
59
62
  }
60
63
  ];
61
- export declare const withCollapsibleItemElementContext: <D extends unknown>(target: string | import("solid-js").Accessor<string> | import("solid-js").Accessor<() => Element>, dependencies: import("solid-js").Accessor<D> | undefined, cb: (context: readonly [
62
- {
63
- isExpanded: boolean;
64
- isAnimating: boolean;
65
- },
64
+ export declare const useCollapsibleItemAt: (target: () => string | undefined, host: HTMLElement) => import("solid-js").SourceAccessor<readonly [
65
+ import("solid-js").Omit<CreateContextOptions, [
66
+ "root"
67
+ ]>,
66
68
  {
67
69
  readonly setElementState: (key: keyof Omit<CreateContextOptions, "root">, value: boolean | number | ((v: boolean | number) => boolean | number)) => void;
68
70
  }
69
- ], dependencies: D) => void | (() => void)) => void;
71
+ ]>;
70
72
  export declare const getCollapsibleItemContext: (element: Element) => readonly [
71
- {
72
- isExpanded: boolean;
73
- isAnimating: boolean;
74
- },
73
+ import("solid-js").Omit<CreateContextOptions, [
74
+ "root"
75
+ ]>,
75
76
  {
76
77
  readonly expand: () => void;
77
78
  readonly collapse: () => void;
78
79
  readonly toggle: () => void;
80
+ readonly start: () => void;
79
81
  readonly finish: () => void;
80
82
  }
81
83
  ];
@@ -1,21 +1,19 @@
1
- import { customShadowlessElement, correctElementType } from '@brytdesigns/web-component-core/utils';
2
- import { CollapsibleItem, CollapsibleTrigger, CollapsibleContent } from './components/index.js';
3
- export * from './hooks/index.js';
1
+ import { getCollapsibleItemContext, provideCollapsibleItemContext, useCollapsibleItem, useCollapsibleItemAt, useCollapsibleItemContext } from "./hooks/useCollapsibleItem.js";
2
+ import "./hooks/index.js";
3
+ import { Component, Name } from "./components/collapsible-content.js";
4
+ import { Component as Component$1, Name as Name$1 } from "./components/collapsible-item.js";
5
+ import { Component as Component$2, Name as Name$2 } from "./components/collapsible-trigger.js";
6
+ import "./components/index.js";
7
+ import { customShadowlessElement } from "@brytdesigns/web-component-core/utils";
8
+ //#region src/index.ts
9
+ customShadowlessElement(Name$1, {
10
+ index: 0,
11
+ isExpanded: false,
12
+ isAnimating: false
13
+ }, Component$1);
14
+ customShadowlessElement(Name$2, { preventDefault: true }, Component$2);
15
+ customShadowlessElement(Name, { shouldScrollIntoView: false }, Component);
16
+ //#endregion
17
+ export { getCollapsibleItemContext, provideCollapsibleItemContext, useCollapsibleItem, useCollapsibleItemAt, useCollapsibleItemContext };
4
18
 
5
- customShadowlessElement(
6
- CollapsibleItem.Name,
7
- { index: 0, isExpanded: false, ariaExpanded: false, isAnimating: false },
8
- correctElementType(CollapsibleItem.Component)
9
- );
10
- customShadowlessElement(
11
- CollapsibleTrigger.Name,
12
- { preventDefault: true },
13
- correctElementType(CollapsibleTrigger.Component)
14
- );
15
- customShadowlessElement(
16
- CollapsibleContent.Name,
17
- { shouldScrollIntoView: false },
18
- correctElementType(CollapsibleContent.Component)
19
- );
20
- //# sourceMappingURL=index.js.map
21
19
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts"],"names":[],"mappings":";;;;AAeA,uBAAA;AAAA,EACC,eAAgB,CAAA,IAAA;AAAA,EAChB,EAAE,OAAO,CAAG,EAAA,UAAA,EAAY,OAAO,YAAc,EAAA,KAAA,EAAO,aAAa,KAAM,EAAA;AAAA,EACvE,kBAAA,CAAmB,gBAAgB,SAAS;AAC7C,CAAA;AAEA,uBAAA;AAAA,EACC,kBAAmB,CAAA,IAAA;AAAA,EACnB,EAAE,gBAAgB,IAAK,EAAA;AAAA,EACvB,kBAAA,CAAmB,mBAAmB,SAAS;AAChD,CAAA;AAEA,uBAAA;AAAA,EACC,kBAAmB,CAAA,IAAA;AAAA,EACnB,EAAE,sBAAsB,KAAM,EAAA;AAAA,EAC9B,kBAAA,CAAmB,mBAAmB,SAAS;AAChD,CAAA","file":"index.js","sourcesContent":["import {\n\tcorrectElementType,\n\tcustomShadowlessElement,\n} from \"@brytdesigns/web-component-core/utils\";\n\nimport {\n\tCollapsibleItem,\n\tCollapsibleContent,\n\tCollapsibleTrigger,\n} from \"./components/index.js\";\n\nexport type CollapsibleItemProps = CollapsibleContent.Props;\nexport type CollapsibleTriggerProps = CollapsibleTrigger.Props;\nexport type CollapsibleContentProps = CollapsibleContent.Props;\n\ncustomShadowlessElement(\n\tCollapsibleItem.Name,\n\t{ index: 0, isExpanded: false, ariaExpanded: false, isAnimating: false },\n\tcorrectElementType(CollapsibleItem.Component),\n);\n\ncustomShadowlessElement(\n\tCollapsibleTrigger.Name,\n\t{ preventDefault: true },\n\tcorrectElementType(CollapsibleTrigger.Component),\n);\n\ncustomShadowlessElement(\n\tCollapsibleContent.Name,\n\t{ shouldScrollIntoView: false },\n\tcorrectElementType(CollapsibleContent.Component),\n);\n\nexport * from \"./hooks/index.js\";\n"]}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["import { customShadowlessElement } from \"@brytdesigns/web-component-core/utils\";\n\nimport {\n\tCollapsibleContent,\n\tCollapsibleItem,\n\tCollapsibleTrigger,\n} from \"./components/index.js\";\n\nexport type CollapsibleItemProps = CollapsibleContent.Props;\nexport type CollapsibleTriggerProps = CollapsibleTrigger.Props;\nexport type CollapsibleContentProps = CollapsibleContent.Props;\n\ncustomShadowlessElement(\n\tCollapsibleItem.Name,\n\t{ index: 0, isExpanded: false, isAnimating: false },\n\tCollapsibleItem.Component,\n);\n\ncustomShadowlessElement(\n\tCollapsibleTrigger.Name,\n\t{ preventDefault: true },\n\tCollapsibleTrigger.Component,\n);\n\ncustomShadowlessElement(\n\tCollapsibleContent.Name,\n\t{ shouldScrollIntoView: false },\n\tCollapsibleContent.Component,\n);\n\nexport * from \"./hooks/index.js\";\n"],"mappings":";;;;;;;;AAYA,wBACC,QACA;CAAE,OAAO;CAAG,YAAY;CAAO,aAAa;AAAM,GAClD,WACD;AAEA,wBACC,QACA,EAAE,gBAAgB,KAAK,GACvB,WACD;AAEA,wBACC,MACA,EAAE,sBAAsB,MAAM,GAC9B,SACD"}
@@ -0,0 +1,35 @@
1
+ /*
2
+ * collapsible-content is a flow-root once the component starts, open or closed.
3
+ * Making it one from the first paint stops open content shifting (its padding
4
+ * and margins taking effect) when the script loads. Theme rules override this.
5
+ *
6
+ * flow-root rather than block: it establishes a block formatting context, so
7
+ * the panel contains its children's margins. The component applies the same,
8
+ * and the two must agree or the content shifts on load — which is the whole
9
+ * point of this rule.
10
+ */
11
+ collapsible-content {
12
+ display: flow-root;
13
+ }
14
+
15
+ /*
16
+ * Closed collapsible content before the component starts.
17
+ *
18
+ * Render closed content with hidden="until-found" and load this stylesheet
19
+ * before the markup, so it does not flash open while the script loads.
20
+ *
21
+ * - display: flow-root lets hidden="until-found" hide the content (it works
22
+ * through content-visibility, which does not apply to an inline box, and
23
+ * custom elements are inline by default). Where it is supported, the text
24
+ * stays reachable by find-in-page.
25
+ * - The rest keeps the content collapsed where hidden="until-found" is not
26
+ * supported, or where theme CSS overrides the browser's [hidden] style.
27
+ *
28
+ * Once the component starts it manages the closed state itself.
29
+ */
30
+ collapsible-content[hidden] {
31
+ display: flow-root;
32
+ overflow: hidden;
33
+ max-height: 0;
34
+ padding-block: 0;
35
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brytdesigns/web-component-collapsible",
3
- "version": "1.0.3",
3
+ "version": "3.0.0",
4
4
  "description": "Headless collapsible web component",
5
5
  "main": "./dist/main/index.js",
6
6
  "module": "./dist/main/index.js",
@@ -9,8 +9,9 @@
9
9
  "exports": {
10
10
  ".": {
11
11
  "types": "./dist/main/index.d.ts",
12
- "module": "./dist/main/index.js"
13
- }
12
+ "default": "./dist/main/index.js"
13
+ },
14
+ "./styles.css": "./dist/styles.css"
14
15
  },
15
16
  "files": [
16
17
  "dist"
@@ -19,18 +20,17 @@
19
20
  "author": "Bryt Designs",
20
21
  "license": "ISC",
21
22
  "dependencies": {
23
+ "@brytdesigns/web-component-core": "3.0.0",
22
24
  "component-register": "0.8.7",
23
- "motion": "^12.18.1",
24
- "solid-element": "^1.9.1",
25
- "solid-js": "^1.9.9",
26
- "@brytdesigns/web-component-core": "1.1.6"
25
+ "motion": "^12.43.0",
26
+ "solid-js": "2.0.0-rc.14"
27
27
  },
28
28
  "devDependencies": {
29
- "dts-bundle-generator": "^9.5.1",
30
- "tsup": "^8.4.0"
29
+ "@repo/vite-config": "0.0.0",
30
+ "vite": "^8.2.2"
31
31
  },
32
32
  "scripts": {
33
- "build": "tsup --clean",
33
+ "build": "vite build",
34
34
  "typecheck": "tsc --noEmit"
35
35
  }
36
36
  }
package/dist/esm/index.js DELETED
@@ -1,268 +0,0 @@
1
- import { createWithElementContext, customShadowlessElement, correctElementType, toHyphenated, getContextFromProvider } from '@brytdesigns/web-component-core/utils';
2
- import { animate } from 'motion';
3
- import { splitProps, createEffect, on, batch, untrack, mergeProps, onCleanup } from 'solid-js';
4
- import { controlsToPromise } from '@brytdesigns/web-component-core/animation';
5
- import { createContext, provide, consume } from 'component-register';
6
-
7
- var __defProp = Object.defineProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
-
13
- // src/components/collapsible-content.ts
14
- var collapsible_content_exports = {};
15
- __export(collapsible_content_exports, {
16
- Component: () => Component,
17
- Name: () => Name
18
- });
19
- function initializeCollapsibleItemContext(props) {
20
- const [element, _, stateProps] = splitProps(
21
- props,
22
- ["root"],
23
- ["ariaExpanded"]
24
- );
25
- function setElementState(key, value) {
26
- const currentValue = untrack(() => props[key]);
27
- if (typeof value === "function") {
28
- let result = false;
29
- if (typeof currentValue === "number") {
30
- result = value(currentValue || 0);
31
- } else if (typeof currentValue === "boolean") {
32
- result = value(currentValue || false);
33
- }
34
- if (`${currentValue}` === `${value}`) return;
35
- element.root.setAttribute(toHyphenated(key), `${result}`);
36
- return;
37
- }
38
- if (`${currentValue}` === `${value}`) return;
39
- return element.root.setAttribute(toHyphenated(key), `${value}`);
40
- }
41
- createEffect(
42
- on(
43
- () => stateProps.isExpanded,
44
- (isExpanded) => {
45
- batch(() => {
46
- setElementState("ariaExpanded", isExpanded);
47
- setElementState("isAnimating", true);
48
- });
49
- }
50
- )
51
- );
52
- return [stateProps, { setElementState }];
53
- }
54
- var CollapsibleItemContextState = createContext(
55
- initializeCollapsibleItemContext
56
- );
57
- var provideCollapsibleItemContext = (initialState, element) => {
58
- const props = mergeProps(initialState, { root: element });
59
- return provide(CollapsibleItemContextState, props, element);
60
- };
61
- var useCollapsibleItemContext = (context) => {
62
- const [state, { setElementState }] = context;
63
- function expand() {
64
- setElementState("isExpanded", true);
65
- }
66
- function collapse() {
67
- setElementState("isExpanded", false);
68
- }
69
- function toggle() {
70
- setElementState("isExpanded", (v) => !v);
71
- }
72
- function finish() {
73
- setElementState("isAnimating", false);
74
- }
75
- return [state, { expand, collapse, toggle, finish }];
76
- };
77
- var useCollapsibleItem = (element) => {
78
- const context = consume(
79
- CollapsibleItemContextState,
80
- element
81
- );
82
- if (!context) {
83
- throw console.error(
84
- "AccordionItemContext not found! Please ensure to wrap your custom element with accordion-item element."
85
- );
86
- }
87
- return useCollapsibleItemContext(context);
88
- };
89
- var withCollapsibleItemElementContext = createWithElementContext(CollapsibleItemContextState);
90
- var getCollapsibleItemContext = (element) => {
91
- const context = getContextFromProvider(
92
- CollapsibleItemContextState,
93
- element
94
- );
95
- return useCollapsibleItemContext(context);
96
- };
97
-
98
- // src/components/collapsible-content.ts
99
- var hideElement = (element) => {
100
- element.style.cssText = `
101
- display: none;
102
- opacity: 0;
103
- visibility: hidden;
104
- max-height: 0px;
105
- `;
106
- element.style.overflow = null;
107
- };
108
- var showElement = (element) => {
109
- element.style.cssText = `
110
- display: block;
111
- opacity: 1;
112
- visibility: visible;
113
- `;
114
- };
115
- var getHeight = (el) => {
116
- el.style.maxHeight = "max-content";
117
- const height = el.getBoundingClientRect().height;
118
- el.style.maxHeight = `${0}`;
119
- return height;
120
- };
121
- var getPaddingTop = (element) => {
122
- const paddingY = parseInt(getComputedStyle(element).paddingTop);
123
- return paddingY;
124
- };
125
- var getPaddingBottom = (element) => {
126
- const paddingY = parseInt(getComputedStyle(element).paddingBottom);
127
- return paddingY;
128
- };
129
- var Name = `collapsible-content`;
130
- var Component = (props, { element }) => {
131
- const [state, methods] = useCollapsibleItem(element);
132
- let isFirstRender = true;
133
- const expand = (element2) => {
134
- showElement(element2);
135
- const height = getHeight(element2), pt = getPaddingTop(element2), pb = getPaddingBottom(element2);
136
- Array.from(element2.children).forEach((child) => {
137
- child.style.opacity = "1";
138
- });
139
- const animation = animate(
140
- element2,
141
- {
142
- maxHeight: ["0px", `${height}px`],
143
- paddingTop: ["0px", `${pt}px`],
144
- paddingBottom: ["0px", `${pb}px`]
145
- },
146
- {
147
- duration: 0.35
148
- }
149
- );
150
- animation.then(() => {
151
- element2.style.maxHeight = "max-content";
152
- element2.style.overflow = null;
153
- if (props.shouldScrollIntoView)
154
- element2.scrollIntoView({
155
- behavior: "smooth",
156
- block: "start",
157
- inline: "nearest"
158
- });
159
- return;
160
- });
161
- return animation;
162
- };
163
- const collapse = (element2) => {
164
- const height = getHeight(element2), pt = getPaddingTop(element2), pb = getPaddingBottom(element2);
165
- element2.style.overflow = "hidden";
166
- Array.from(element2.children).forEach((child) => {
167
- child.style.opacity = "0";
168
- });
169
- const animation = animate(
170
- element2,
171
- {
172
- maxHeight: [`${height}px`, "0px"],
173
- paddingTop: [`${pt}px`, "0px"],
174
- paddingBottom: [`${pb}px`, "0px"]
175
- },
176
- {
177
- duration: 0.35
178
- }
179
- );
180
- animation.then(() => hideElement(element2));
181
- return animation;
182
- };
183
- createEffect(
184
- on(
185
- () => state.isExpanded,
186
- (isExpanded) => {
187
- if (!isExpanded) {
188
- isFirstRender = false;
189
- const animation2 = collapse(element);
190
- controlsToPromise(animation2).finally(methods.finish);
191
- return onCleanup(() => animation2.complete());
192
- }
193
- if (isFirstRender) {
194
- isFirstRender = false;
195
- showElement(element);
196
- Array.from(element.children).forEach((child) => {
197
- child.style.opacity = "1";
198
- });
199
- element.style.maxHeight = `max-content`;
200
- methods.finish();
201
- return;
202
- }
203
- const animation = expand(element);
204
- controlsToPromise(animation).finally(methods.finish);
205
- return onCleanup(() => animation.complete());
206
- }
207
- )
208
- );
209
- };
210
-
211
- // src/components/collapsible-trigger.ts
212
- var collapsible_trigger_exports = {};
213
- __export(collapsible_trigger_exports, {
214
- Component: () => Component2,
215
- Name: () => Name2
216
- });
217
- var Name2 = `collapsible-trigger`;
218
- var Component2 = (props, { element }) => {
219
- const [state, methods] = useCollapsibleItem(element);
220
- createEffect(() => {
221
- const isAnimating = state.isAnimating;
222
- if (isAnimating) return;
223
- const controller = new AbortController(), preventDefault = props.preventDefault;
224
- element.addEventListener(
225
- "click",
226
- (event) => {
227
- if (preventDefault) event.preventDefault();
228
- methods.toggle();
229
- },
230
- { signal: controller.signal }
231
- );
232
- return onCleanup(() => {
233
- controller.abort();
234
- });
235
- });
236
- };
237
-
238
- // src/components/collapsible-item.ts
239
- var collapsible_item_exports = {};
240
- __export(collapsible_item_exports, {
241
- Component: () => Component3,
242
- Name: () => Name3
243
- });
244
- var Name3 = `collapsible-item`;
245
- var Component3 = (props, { element }) => {
246
- provideCollapsibleItemContext(props, element);
247
- };
248
-
249
- // src/index.ts
250
- customShadowlessElement(
251
- collapsible_item_exports.Name,
252
- { index: 0, isExpanded: false, ariaExpanded: false, isAnimating: false },
253
- correctElementType(collapsible_item_exports.Component)
254
- );
255
- customShadowlessElement(
256
- collapsible_trigger_exports.Name,
257
- { preventDefault: true },
258
- correctElementType(collapsible_trigger_exports.Component)
259
- );
260
- customShadowlessElement(
261
- collapsible_content_exports.Name,
262
- { shouldScrollIntoView: false },
263
- correctElementType(collapsible_content_exports.Component)
264
- );
265
-
266
- export { getCollapsibleItemContext, provideCollapsibleItemContext, useCollapsibleItem, useCollapsibleItemContext, withCollapsibleItemElementContext };
267
- //# sourceMappingURL=index.js.map
268
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/components/collapsible-content.ts","../../src/hooks/useCollapsibleItem.ts","../../src/components/collapsible-trigger.ts","../../src/components/collapsible-item.ts","../../src/index.ts"],"names":["element","createEffect","on","animation","Component","Name","onCleanup"],"mappings":"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","file":"index.js","sourcesContent":["import type { CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\nimport type { ICustomElement } from \"component-register\";\nimport { animate } from \"motion\";\nimport { createEffect, on, onCleanup, onMount } from \"solid-js\";\n\nimport { controlsToPromise } from \"@brytdesigns/web-component-core/animation\";\n\nimport { useCollapsibleItem } from \"../hooks/index.js\";\n\nexport type Props = {\n\tshouldScrollIntoView: boolean;\n};\n\nconst hideElement = (element: ICustomElement) => {\n\telement.style.cssText = `\n display: none;\n opacity: 0;\n visibility: hidden;\n max-height: 0px;\n `;\n\telement.style.overflow = null;\n};\n\nconst showElement = (element: ICustomElement) => {\n\telement.style.cssText = `\n display: block;\n opacity: 1;\n visibility: visible;\n `;\n};\n\nconst getHeight = (el: ICustomElement & HTMLElement) => {\n\tel.style.maxHeight = \"max-content\";\n\tconst height = el.getBoundingClientRect().height;\n\tel.style.maxHeight = `${0}`;\n\treturn height;\n};\n\nconst getPaddingTop = (element: ICustomElement & HTMLElement) => {\n\tconst paddingY = parseInt(getComputedStyle(element).paddingTop);\n\treturn paddingY;\n};\n\nconst getPaddingBottom = (element: ICustomElement & HTMLElement) => {\n\tconst paddingY = parseInt(getComputedStyle(element).paddingBottom);\n\treturn paddingY;\n};\n\nexport const Name = `collapsible-content`;\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n\tconst [state, methods] = useCollapsibleItem(element);\n\n\tlet isFirstRender = true;\n\n\tconst expand = (element: ICustomElement & HTMLElement) => {\n\t\tshowElement(element);\n\n\t\tconst height = getHeight(element),\n\t\t\tpt = getPaddingTop(element),\n\t\t\tpb = getPaddingBottom(element);\n\n\t\t(Array.from(element.children) as HTMLElement[]).forEach((child) => {\n\t\t\tchild.style.opacity = \"1\";\n\t\t});\n\n\t\tconst animation = animate(\n\t\t\telement,\n\t\t\t{\n\t\t\t\tmaxHeight: [\"0px\", `${height}px`],\n\t\t\t\tpaddingTop: [\"0px\", `${pt}px`],\n\t\t\t\tpaddingBottom: [\"0px\", `${pb}px`],\n\t\t\t},\n\t\t\t{\n\t\t\t\tduration: 0.35,\n\t\t\t},\n\t\t);\n\n\t\tanimation.then(() => {\n\t\t\telement.style.maxHeight = \"max-content\";\n\t\t\t//@ts-ignore\n\t\t\telement.style.overflow = null;\n\t\t\tif (props.shouldScrollIntoView)\n\t\t\t\telement.scrollIntoView({\n\t\t\t\t\tbehavior: \"smooth\",\n\t\t\t\t\tblock: \"start\",\n\t\t\t\t\tinline: \"nearest\",\n\t\t\t\t});\n\t\t\treturn;\n\t\t});\n\n\t\treturn animation;\n\t};\n\n\tconst collapse = (element: ICustomElement & HTMLElement) => {\n\t\tconst height = getHeight(element),\n\t\t\tpt = getPaddingTop(element),\n\t\t\tpb = getPaddingBottom(element);\n\n\t\telement.style.overflow = \"hidden\";\n\n\t\t(Array.from(element.children) as HTMLElement[]).forEach((child) => {\n\t\t\tchild.style.opacity = \"0\";\n\t\t});\n\n\t\tconst animation = animate(\n\t\t\telement,\n\t\t\t{\n\t\t\t\tmaxHeight: [`${height}px`, \"0px\"],\n\t\t\t\tpaddingTop: [`${pt}px`, \"0px\"],\n\t\t\t\tpaddingBottom: [`${pb}px`, \"0px\"],\n\t\t\t},\n\t\t\t{\n\t\t\t\tduration: 0.35,\n\t\t\t},\n\t\t);\n\n\t\tanimation.then(() => hideElement(element));\n\n\t\treturn animation;\n\t};\n\n\tcreateEffect(\n\t\ton(\n\t\t\t() => state.isExpanded,\n\t\t\t(isExpanded) => {\n\t\t\t\tif (!isExpanded) {\n\t\t\t\t\tisFirstRender = false;\n\t\t\t\t\tconst animation = collapse(element);\n\t\t\t\t\tcontrolsToPromise(animation).finally(methods.finish);\n\t\t\t\t\treturn onCleanup(() => animation.complete());\n\t\t\t\t}\n\n\t\t\t\tif (isFirstRender) {\n\t\t\t\t\tisFirstRender = false;\n\t\t\t\t\tshowElement(element);\n\t\t\t\t\t(Array.from(element.children) as HTMLElement[]).forEach((child) => {\n\t\t\t\t\t\tchild.style.opacity = \"1\";\n\t\t\t\t\t});\n\t\t\t\t\telement.style.maxHeight = `max-content`;\n\t\t\t\t\tmethods.finish();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst animation = expand(element);\n\t\t\t\tcontrolsToPromise(animation).finally(methods.finish);\n\t\t\t\treturn onCleanup(() => animation.complete());\n\t\t\t},\n\t\t),\n\t);\n};\n","import {\n\ttype ICustomElement,\n\tcreateContext,\n\tprovide,\n\tconsume,\n} from \"component-register\";\nimport {\n\tbatch,\n\tcreateEffect,\n\tmergeProps,\n\ton,\n\tsplitProps,\n\tuntrack,\n} from \"solid-js\";\nimport {\n\ttoHyphenated,\n\tgetContextFromProvider,\n\tcreateWithElementContext,\n} from \"@brytdesigns/web-component-core/utils\";\n\ntype CreateContextOptions = {\n\troot: HTMLElement & ICustomElement;\n\tisExpanded: boolean;\n\tariaExpanded: boolean;\n\tisAnimating: boolean;\n};\n\ntype WalkableNode = Parameters<typeof provide>[2];\n\ntype CollapsibleItemContext = ReturnType<\n\ttypeof initializeCollapsibleItemContext\n>;\n\nfunction initializeCollapsibleItemContext(props: CreateContextOptions) {\n\tconst [element, _, stateProps] = splitProps(\n\t\tprops,\n\t\t[\"root\"],\n\t\t[\"ariaExpanded\"],\n\t);\n\n\tfunction setElementState(\n\t\tkey: keyof Omit<CreateContextOptions, \"root\">,\n\t\tvalue: boolean | number | ((v: boolean | number) => boolean | number),\n\t) {\n\t\tconst currentValue = untrack(() => props[key]);\n\t\tif (typeof value === \"function\") {\n\t\t\tlet result: boolean | number = false;\n\t\t\tif (typeof currentValue === \"number\") {\n\t\t\t\tresult = value(currentValue || 0);\n\t\t\t} else if (typeof currentValue === \"boolean\") {\n\t\t\t\tresult = value(currentValue || false);\n\t\t\t}\n\t\t\tif (`${currentValue}` === `${value}`) return;\n\t\t\telement.root.setAttribute(toHyphenated(key), `${result}`);\n\t\t\treturn;\n\t\t}\n\t\tif (`${currentValue}` === `${value}`) return;\n\t\treturn element.root.setAttribute(toHyphenated(key), `${value}`);\n\t}\n\n\tcreateEffect(\n\t\ton(\n\t\t\t() => stateProps.isExpanded,\n\t\t\t(isExpanded) => {\n\t\t\t\tbatch(() => {\n\t\t\t\t\tsetElementState(\"ariaExpanded\", isExpanded);\n\t\t\t\t\tsetElementState(\"isAnimating\", true);\n\t\t\t\t});\n\t\t\t},\n\t\t),\n\t);\n\n\treturn [stateProps, { setElementState }] as const;\n}\n\nconst CollapsibleItemContextState = createContext(\n\tinitializeCollapsibleItemContext,\n);\n\nexport const provideCollapsibleItemContext = (\n\tinitialState: Omit<CreateContextOptions, \"root\">,\n\telement: WalkableNode,\n): CollapsibleItemContext => {\n\tconst props = mergeProps(initialState, { root: element });\n\treturn provide(CollapsibleItemContextState, props, element);\n};\n\nexport const useCollapsibleItemContext = (context: CollapsibleItemContext) => {\n\tconst [state, { setElementState }] = context;\n\n\tfunction expand() {\n\t\tsetElementState(\"isExpanded\", true);\n\t}\n\n\tfunction collapse() {\n\t\tsetElementState(\"isExpanded\", false);\n\t}\n\n\tfunction toggle() {\n\t\tsetElementState(\"isExpanded\", (v) => !v);\n\t}\n\n\tfunction finish() {\n\t\tsetElementState(\"isAnimating\", false);\n\t}\n\n\treturn [state, { expand, collapse, toggle, finish }] as const;\n};\n\nexport const useCollapsibleItem = (element: HTMLElement & ICustomElement) => {\n\tconst context: CollapsibleItemContext = consume(\n\t\tCollapsibleItemContextState,\n\t\telement,\n\t);\n\n\tif (!context) {\n\t\tthrow console.error(\n\t\t\t\"AccordionItemContext not found! Please ensure to wrap your custom element with accordion-item element.\",\n\t\t);\n\t}\n\n\treturn useCollapsibleItemContext(context);\n};\n\nexport const withCollapsibleItemElementContext = createWithElementContext<\n\ttypeof CollapsibleItemContextState,\n\tCollapsibleItemContext\n>(CollapsibleItemContextState);\n\nexport const getCollapsibleItemContext = (element: Element) => {\n\tconst context = getContextFromProvider<CollapsibleItemContext>(\n\t\tCollapsibleItemContextState,\n\t\telement,\n\t);\n\treturn useCollapsibleItemContext(context);\n};\n","import type { CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\n\nimport { createEffect, onCleanup } from \"solid-js\";\n\nimport { useCollapsibleItem } from \"../hooks/index.js\";\n\nexport type Props = {\n\tpreventDefault: boolean;\n};\n\nexport const Name = `collapsible-trigger`;\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n\tconst [state, methods] = useCollapsibleItem(element);\n\n\tcreateEffect(() => {\n\t\tconst isAnimating = state.isAnimating;\n\t\tif (isAnimating) return;\n\n\t\tconst controller = new AbortController(),\n\t\t\tpreventDefault = props.preventDefault;\n\n\t\telement.addEventListener(\n\t\t\t\"click\",\n\t\t\t(event) => {\n\t\t\t\tif (preventDefault) event.preventDefault();\n\t\t\t\tmethods.toggle();\n\t\t\t},\n\t\t\t{ signal: controller.signal },\n\t\t);\n\n\t\treturn onCleanup(() => {\n\t\t\tcontroller.abort();\n\t\t});\n\t});\n};\n","import type { CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\n\nimport { provideCollapsibleItemContext } from \"../hooks/index.js\";\n\nexport type Props = {\n\tisExpanded: boolean;\n\tisAnimating: boolean;\n\tariaExpanded: boolean;\n};\n\nexport const Name = `collapsible-item`;\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n\tprovideCollapsibleItemContext(props, element);\n};\n","import {\n\tcorrectElementType,\n\tcustomShadowlessElement,\n} from \"@brytdesigns/web-component-core/utils\";\n\nimport {\n\tCollapsibleItem,\n\tCollapsibleContent,\n\tCollapsibleTrigger,\n} from \"./components/index.js\";\n\nexport type CollapsibleItemProps = CollapsibleContent.Props;\nexport type CollapsibleTriggerProps = CollapsibleTrigger.Props;\nexport type CollapsibleContentProps = CollapsibleContent.Props;\n\ncustomShadowlessElement(\n\tCollapsibleItem.Name,\n\t{ index: 0, isExpanded: false, ariaExpanded: false, isAnimating: false },\n\tcorrectElementType(CollapsibleItem.Component),\n);\n\ncustomShadowlessElement(\n\tCollapsibleTrigger.Name,\n\t{ preventDefault: true },\n\tcorrectElementType(CollapsibleTrigger.Component),\n);\n\ncustomShadowlessElement(\n\tCollapsibleContent.Name,\n\t{ shouldScrollIntoView: false },\n\tcorrectElementType(CollapsibleContent.Component),\n);\n\nexport * from \"./hooks/index.js\";\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}