@brytdesigns/web-component-accordion 1.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.
@@ -0,0 +1,118 @@
1
+ import '@brytdesigns/web-component-utils';
2
+ import { animate } from 'motion';
3
+ import { createEffect, on, onCleanup } from 'solid-js';
4
+ import { useAccordionItem, useAccordion } from '../hooks/index.js';
5
+
6
+ async function controlPromise(controls) {
7
+ return new Promise((resolve) => {
8
+ controls.then(() => resolve(null));
9
+ });
10
+ }
11
+ const hideElement = (element) => {
12
+ element.style.cssText = `
13
+ display: none;
14
+ opacity: 0;
15
+ visibility: hidden;
16
+ max-height: 0px;
17
+ `;
18
+ element.style.overflow = null;
19
+ };
20
+ const showElement = (element) => {
21
+ element.style.cssText = `
22
+ display: block;
23
+ opacity: 1;
24
+ visibility: visible;
25
+ `;
26
+ };
27
+ const getHeight = (el) => {
28
+ el.style.maxHeight = "max-content";
29
+ const height = el.getBoundingClientRect().height;
30
+ el.style.maxHeight = `${0}`;
31
+ return height;
32
+ };
33
+ const getPaddingTop = (element) => {
34
+ const paddingY = parseInt(getComputedStyle(element).paddingTop);
35
+ return paddingY;
36
+ };
37
+ const getPaddingBottom = (element) => {
38
+ const paddingY = parseInt(getComputedStyle(element).paddingBottom);
39
+ return paddingY;
40
+ };
41
+ const AccordionContent = (props, { element }) => {
42
+ const [state] = useAccordionItem(element);
43
+ const [_, accordionMethods] = useAccordion(element);
44
+ let isFirstRender = true;
45
+ const expand = (element2) => {
46
+ showElement(element2);
47
+ const height = getHeight(element2), pt = getPaddingTop(element2), pb = getPaddingBottom(element2);
48
+ Array.from(element2.children).forEach(
49
+ (child) => child.style.opacity = "1"
50
+ );
51
+ const animation = animate(
52
+ element2,
53
+ {
54
+ maxHeight: ["0px", `${height}px`],
55
+ paddingTop: ["0px", `${pt}px`],
56
+ paddingBottom: ["0px", `${pb}px`]
57
+ },
58
+ {
59
+ duration: 0.35
60
+ }
61
+ );
62
+ animation.then(() => {
63
+ element2.style.maxHeight = "max-content";
64
+ element2.style.overflow = null;
65
+ if (props.shouldScrollIntoView)
66
+ element2.scrollIntoView({
67
+ behavior: "smooth",
68
+ block: "start",
69
+ inline: "nearest"
70
+ });
71
+ return;
72
+ });
73
+ return animation;
74
+ };
75
+ const collapse = (element2) => {
76
+ const height = getHeight(element2), pt = getPaddingTop(element2), pb = getPaddingBottom(element2);
77
+ element2.style.overflow = "hidden";
78
+ Array.from(element2.children).forEach(
79
+ (child) => child.style.opacity = "0"
80
+ );
81
+ const animation = animate(
82
+ element2,
83
+ {
84
+ maxHeight: [`${height}px`, "0px"],
85
+ paddingTop: [`${pt}px`, "0px"],
86
+ paddingBottom: [`${pb}px`, "0px"]
87
+ },
88
+ {
89
+ duration: 0.35
90
+ }
91
+ );
92
+ animation.then(() => hideElement(element2));
93
+ return animation;
94
+ };
95
+ createEffect(
96
+ on(
97
+ () => state.isExpanded,
98
+ (isExpanded) => {
99
+ if (isExpanded) {
100
+ const animation2 = collapse(element);
101
+ accordionMethods.updateAnimationQueue(controlPromise(animation2));
102
+ return onCleanup(() => animation2.complete());
103
+ }
104
+ if (isFirstRender) {
105
+ isFirstRender = false;
106
+ showElement(element);
107
+ }
108
+ const animation = expand(element);
109
+ accordionMethods.updateAnimationQueue(controlPromise(animation));
110
+ return onCleanup(() => animation.complete());
111
+ }
112
+ )
113
+ );
114
+ };
115
+
116
+ export { AccordionContent };
117
+ //# sourceMappingURL=accordion-content.js.map
118
+ //# sourceMappingURL=accordion-content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/accordion-content.ts"],"names":["element","animation"],"mappings":"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","file":"accordion-content.js","sourcesContent":["import { type CorrectComponentType } from \"@brytdesigns/web-component-utils\";\nimport type { ICustomElement } from \"component-register\";\nimport { animate, type AnimationPlaybackControls } from \"motion\";\nimport { createEffect, on, onCleanup } from \"solid-js\";\n\nimport { useAccordion, useAccordionItem } from \"../hooks/index.js\";\n\ntype AccordionContentProps = {\n shouldScrollIntoView: boolean;\n};\n\nasync function controlPromise(controls: AnimationPlaybackControls) {\n return new Promise((resolve) => {\n controls.then(() => resolve(null));\n });\n}\n\nconst hideElement = (element: ICustomElement) => {\n element.style.cssText = `\n display: none;\n opacity: 0;\n visibility: hidden;\n max-height: 0px;\n `;\n element.style.overflow = null;\n};\n\nconst showElement = (element: ICustomElement) => {\n element.style.cssText = `\n display: block;\n opacity: 1;\n visibility: visible;\n `;\n};\n\nconst getHeight = (el: ICustomElement & HTMLElement) => {\n el.style.maxHeight = \"max-content\";\n const height = el.getBoundingClientRect().height;\n el.style.maxHeight = `${0}`;\n return height;\n};\n\nconst getPaddingTop = (element: ICustomElement & HTMLElement) => {\n const paddingY = parseInt(getComputedStyle(element).paddingTop);\n return paddingY;\n};\n\nconst getPaddingBottom = (element: ICustomElement & HTMLElement) => {\n const paddingY = parseInt(getComputedStyle(element).paddingBottom);\n return paddingY;\n};\n\nexport const AccordionContent: CorrectComponentType<AccordionContentProps> = (\n props,\n { element },\n) => {\n const [state] = useAccordionItem(element);\n const [_, accordionMethods] = useAccordion(element);\n\n let isFirstRender = true;\n\n const expand = (element: ICustomElement & HTMLElement) => {\n showElement(element);\n\n const height = getHeight(element),\n pt = getPaddingTop(element),\n pb = getPaddingBottom(element);\n\n (Array.from(element.children) as HTMLElement[]).forEach(\n (child) => (child.style.opacity = \"1\"),\n );\n\n const animation = animate(\n element,\n {\n maxHeight: [\"0px\", `${height}px`],\n paddingTop: [\"0px\", `${pt}px`],\n paddingBottom: [\"0px\", `${pb}px`],\n },\n {\n duration: 0.35,\n },\n );\n\n animation.then(() => {\n element.style.maxHeight = \"max-content\";\n //@ts-ignore\n element.style.overflow = null;\n if (props.shouldScrollIntoView)\n element.scrollIntoView({\n behavior: \"smooth\",\n block: \"start\",\n inline: \"nearest\",\n });\n return;\n });\n\n return animation;\n };\n\n const collapse = (element: ICustomElement & HTMLElement) => {\n const height = getHeight(element),\n pt = getPaddingTop(element),\n pb = getPaddingBottom(element);\n\n element.style.overflow = \"hidden\";\n\n (Array.from(element.children) as HTMLElement[]).forEach(\n (child) => (child.style.opacity = \"0\"),\n );\n\n const animation = animate(\n element,\n {\n maxHeight: [`${height}px`, \"0px\"],\n paddingTop: [`${pt}px`, \"0px\"],\n paddingBottom: [`${pb}px`, \"0px\"],\n },\n {\n duration: 0.35,\n },\n );\n\n animation.then(() => hideElement(element));\n\n return animation;\n };\n\n createEffect(\n on(\n () => state.isExpanded,\n (isExpanded) => {\n if (isExpanded) {\n const animation = collapse(element);\n accordionMethods.updateAnimationQueue(controlPromise(animation));\n return onCleanup(() => animation.complete());\n }\n\n if (isFirstRender) {\n isFirstRender = false;\n showElement(element);\n }\n\n const animation = expand(element);\n accordionMethods.updateAnimationQueue(controlPromise(animation));\n return onCleanup(() => animation.complete());\n },\n ),\n );\n};\n"]}
@@ -0,0 +1,21 @@
1
+ import { toHyphenated } from '@brytdesigns/web-component-utils';
2
+ import { provideAccordionContext, useAccordionContext } from '../hooks/index.js';
3
+
4
+ const AccordionContext = (props, { element }) => {
5
+ const context = provideAccordionContext(props, element);
6
+ const [_, methods] = useAccordionContext(context);
7
+ const children = Array.from(element.children);
8
+ const accordionItems = children.filter(
9
+ (child) => child.tagName === "ACCORDION-ITEM"
10
+ );
11
+ accordionItems.forEach((accordionItem, index) => {
12
+ accordionItem.setAttribute("index", `${index + 1}`);
13
+ if (accordionItem.getAttribute(toHyphenated("isExpanded")) !== "true")
14
+ return;
15
+ methods.item.update(index + 1);
16
+ });
17
+ };
18
+
19
+ export { AccordionContext };
20
+ //# sourceMappingURL=accordion-context.js.map
21
+ //# sourceMappingURL=accordion-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/accordion-context.ts"],"names":[],"mappings":";;;AAeO,MAAM,gBAAgE,GAAA,CAC3E,KACA,EAAA,EAAE,SACC,KAAA;AACH,EAAM,MAAA,OAAA,GAAU,uBAAwB,CAAA,KAAA,EAAO,OAAO,CAAA;AACtD,EAAA,MAAM,CAAC,CAAA,EAAG,OAAO,CAAA,GAAI,oBAAoB,OAAO,CAAA;AAChD,EAAA,MAAM,QAAW,GAAA,KAAA,CAAM,IAAK,CAAA,OAAA,CAAQ,QAAQ,CAAA;AAC5C,EAAA,MAAM,iBAAiB,QAAS,CAAA,MAAA;AAAA,IAC9B,CAAC,KAAU,KAAA,KAAA,CAAM,OAAY,KAAA;AAAA,GAC/B;AACA,EAAe,cAAA,CAAA,OAAA,CAAQ,CAAC,aAAA,EAAe,KAAU,KAAA;AAC/C,IAAA,aAAA,CAAc,YAAa,CAAA,OAAA,EAAS,CAAG,EAAA,KAAA,GAAQ,CAAC,CAAE,CAAA,CAAA;AAClD,IAAA,IAAI,aAAc,CAAA,YAAA,CAAa,YAAa,CAAA,YAAY,CAAC,CAAM,KAAA,MAAA;AAC7D,MAAA;AACF,IAAQ,OAAA,CAAA,IAAA,CAAK,MAAO,CAAA,KAAA,GAAQ,CAAC,CAAA;AAAA,GAC9B,CAAA;AACH","file":"accordion-context.js","sourcesContent":["import {\n toHyphenated,\n type CorrectComponentType,\n} from \"@brytdesigns/web-component-utils\";\n\nimport {\n provideAccordionContext,\n useAccordionContext,\n} from \"../hooks/index.js\";\n\ntype AccordionContextProps = {\n activeIndex: number;\n isAnimating: boolean;\n};\n\nexport const AccordionContext: CorrectComponentType<AccordionContextProps> = (\n props,\n { element },\n) => {\n const context = provideAccordionContext(props, element);\n const [_, methods] = useAccordionContext(context);\n const children = Array.from(element.children) as HTMLElement[];\n const accordionItems = children.filter(\n (child) => child.tagName === \"ACCORDION-ITEM\",\n );\n accordionItems.forEach((accordionItem, index) => {\n accordionItem.setAttribute(\"index\", `${index + 1}`);\n if (accordionItem.getAttribute(toHyphenated(\"isExpanded\")) !== \"true\")\n return;\n methods.item.update(index + 1);\n });\n};\n"]}
@@ -0,0 +1,15 @@
1
+ import '@brytdesigns/web-component-utils';
2
+ import { provideAccordionItemContext } from '../hooks/index.js';
3
+
4
+ const AccordionItem = (props, { element }) => {
5
+ if (element.parentElement?.tagName !== "ACCORDION-CONTEXT")
6
+ return console.warn(
7
+ "accordion-item must be an immediate child of accordion-context",
8
+ element
9
+ );
10
+ provideAccordionItemContext(props, element);
11
+ };
12
+
13
+ export { AccordionItem };
14
+ //# sourceMappingURL=accordion-item.js.map
15
+ //# sourceMappingURL=accordion-item.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/accordion-item.ts"],"names":[],"mappings":";;;AAUO,MAAM,aAA0D,GAAA,CACrE,KACA,EAAA,EAAE,SACC,KAAA;AACH,EAAI,IAAA,OAAA,CAAQ,eAAe,OAAY,KAAA,mBAAA;AACrC,IAAA,OAAO,OAAQ,CAAA,IAAA;AAAA,MACb,gEAAA;AAAA,MACA;AAAA,KACF;AAEF,EAAA,2BAAA,CAA4B,OAAO,OAAO,CAAA;AAC5C","file":"accordion-item.js","sourcesContent":["import { type CorrectComponentType } from \"@brytdesigns/web-component-utils\";\n\nimport { provideAccordionItemContext } from \"../hooks/index.js\";\n\ntype AccordionItemProps = {\n index: number;\n isExpanded: boolean;\n ariaExpanded: boolean;\n};\n\nexport const AccordionItem: CorrectComponentType<AccordionItemProps> = (\n props,\n { element },\n) => {\n if (element.parentElement?.tagName !== \"ACCORDION-CONTEXT\")\n return console.warn(\n \"accordion-item must be an immediate child of accordion-context\",\n element,\n );\n\n provideAccordionItemContext(props, element);\n};\n"]}
@@ -0,0 +1,27 @@
1
+ import '@brytdesigns/web-component-utils';
2
+ import { createEffect, onCleanup } from 'solid-js';
3
+ import { useAccordionItem } from '../hooks/index.js';
4
+
5
+ const AccordionTrigger = (props, { element }) => {
6
+ const [state, methods] = useAccordionItem(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
+ });
23
+ };
24
+
25
+ export { AccordionTrigger };
26
+ //# sourceMappingURL=accordion-trigger.js.map
27
+ //# sourceMappingURL=accordion-trigger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/accordion-trigger.ts"],"names":[],"mappings":";;;;AAUO,MAAM,gBAAgE,GAAA,CAC3E,KACA,EAAA,EAAE,SACC,KAAA;AACH,EAAA,MAAM,CAAC,KAAA,EAAO,OAAO,CAAA,GAAI,iBAAiB,OAAO,CAAA;AAEjD,EAAA,YAAA,CAAa,MAAM;AACjB,IAAA,MAAM,cAAc,KAAM,CAAA,WAAA;AAC1B,IAAA,IAAI,WAAa,EAAA;AAEjB,IAAA,MAAM,UAAa,GAAA,IAAI,eAAgB,EAAA,EACrC,iBAAiB,KAAM,CAAA,cAAA;AAEzB,IAAQ,OAAA,CAAA,gBAAA;AAAA,MACN,OAAA;AAAA,MACA,CAAC,KAAU,KAAA;AACT,QAAI,IAAA,cAAA,QAAsB,cAAe,EAAA;AACzC,QAAA,OAAA,CAAQ,MAAO,EAAA;AAAA,OACjB;AAAA,MACA,EAAE,MAAQ,EAAA,UAAA,CAAW,MAAO;AAAA,KAC9B;AAEA,IAAA,OAAO,UAAU,MAAM;AACrB,MAAA,UAAA,CAAW,KAAM,EAAA;AAAA,KAClB,CAAA;AAAA,GACF,CAAA;AACH","file":"accordion-trigger.js","sourcesContent":["import { type CorrectComponentType } from \"@brytdesigns/web-component-utils\";\n\nimport { createEffect, onCleanup } from \"solid-js\";\n\nimport { useAccordionItem } from \"../hooks/index.js\";\n\ntype AccordionTriggerProps = {\n preventDefault: boolean;\n};\n\nexport const AccordionTrigger: CorrectComponentType<AccordionTriggerProps> = (\n props,\n { element },\n) => {\n const [state, methods] = useAccordionItem(element);\n\n createEffect(() => {\n const isAnimating = state.isAnimating;\n if (isAnimating) return;\n\n const controller = new AbortController(),\n preventDefault = props.preventDefault;\n\n element.addEventListener(\n \"click\",\n (event) => {\n if (preventDefault) event.preventDefault();\n methods.toggle();\n },\n { signal: controller.signal },\n );\n\n return onCleanup(() => {\n controller.abort();\n });\n });\n};\n"]}
@@ -0,0 +1,6 @@
1
+ export * from './accordion-content.js';
2
+ export * from './accordion-item.js';
3
+ export * from './accordion-trigger.js';
4
+ export * from './accordion-context.js';
5
+ //# sourceMappingURL=index.js.map
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
@@ -0,0 +1,4 @@
1
+ export * from './useAccordion.js';
2
+ export * from './useAccordionItem.js';
3
+ //# sourceMappingURL=index.js.map
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
@@ -0,0 +1,84 @@
1
+ import { createContext, provide, consume } from 'component-register';
2
+ import { splitProps, createEffect, on, batch, untrack, mergeProps, createSelector } from 'solid-js';
3
+ import { createStore } from 'solid-js/store';
4
+ import { toHyphenated, getContextFromProvider } from '@brytdesigns/web-component-utils';
5
+
6
+ function initializeAccordionContext(props) {
7
+ const [element, stateProps] = splitProps(props, ["root"]);
8
+ const [store, setStore] = createStore({ animationQueue: [] });
9
+ createEffect(
10
+ on(
11
+ () => store.animationQueue,
12
+ (animationQueue) => {
13
+ if (!animationQueue.length) return;
14
+ const animations = Promise.allSettled(store.animationQueue);
15
+ setElementState("isAnimating", true);
16
+ animations.finally(() => {
17
+ batch(() => {
18
+ setElementState("isAnimating", false);
19
+ setStore("animationQueue", []);
20
+ });
21
+ });
22
+ }
23
+ )
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
+ return [
42
+ mergeProps(store, stateProps),
43
+ { setElementState, setStore }
44
+ ];
45
+ }
46
+ const AccordionContextState = createContext(initializeAccordionContext);
47
+ const provideAccordionContext = (initialState, element) => {
48
+ const props = mergeProps(initialState, { root: element });
49
+ return provide(AccordionContextState, props, element);
50
+ };
51
+ const useAccordionContext = (context) => {
52
+ const [state, { setElementState, setStore: setState }] = context;
53
+ function updateAnimationQueue(animation) {
54
+ setState("animationQueue", (state2) => [...state2, animation]);
55
+ }
56
+ function updateActiveIndex(index) {
57
+ setElementState("activeIndex", index);
58
+ }
59
+ const isActive = createSelector(() => state.activeIndex);
60
+ return [
61
+ state,
62
+ { updateAnimationQueue, item: { update: updateActiveIndex, isActive } }
63
+ ];
64
+ };
65
+ const useAccordion = (element) => {
66
+ const context = consume(AccordionContextState, element);
67
+ if (!context) {
68
+ throw console.error(
69
+ "AccordionContext not found! Please ensure to wrap your custom element with accordion-context element."
70
+ );
71
+ }
72
+ return useAccordionContext(context);
73
+ };
74
+ const getAccordionContext = (element) => {
75
+ const context = getContextFromProvider(
76
+ AccordionContextState,
77
+ element
78
+ );
79
+ return useAccordionContext(context);
80
+ };
81
+
82
+ export { getAccordionContext, provideAccordionContext, useAccordion, useAccordionContext };
83
+ //# sourceMappingURL=useAccordion.js.map
84
+ //# sourceMappingURL=useAccordion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/hooks/useAccordion.ts"],"names":["state"],"mappings":"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","file":"useAccordion.js","sourcesContent":["import {\n type ICustomElement,\n createContext,\n provide,\n consume,\n} from \"component-register\";\nimport {\n createEffect,\n mergeProps,\n on,\n batch,\n splitProps,\n createSelector,\n untrack,\n} from \"solid-js\";\nimport { createStore } from \"solid-js/store\";\nimport {\n toHyphenated,\n getContextFromProvider,\n} from \"@brytdesigns/web-component-utils\";\n\ntype StoreContext = {\n animationQueue: Promise<unknown>[];\n};\n\ntype CreateContextOptions = {\n root: HTMLElement & ICustomElement;\n isAnimating: boolean;\n activeIndex: number;\n};\n\ntype WalkableNode = Parameters<typeof provide>[2];\n\ntype AccordionContext = ReturnType<typeof initializeAccordionContext>;\n\nfunction initializeAccordionContext(props: CreateContextOptions) {\n const [element, stateProps] = splitProps(props, [\"root\"]);\n const [store, setStore] = createStore<StoreContext>({ animationQueue: [] });\n\n createEffect(\n on(\n () => store.animationQueue,\n (animationQueue) => {\n if (!animationQueue.length) return;\n const animations = Promise.allSettled(store.animationQueue);\n setElementState(\"isAnimating\", true);\n animations.finally(() => {\n batch(() => {\n setElementState(\"isAnimating\", false);\n setStore(\"animationQueue\", []);\n });\n });\n },\n ),\n );\n\n function setElementState(\n key: keyof Omit<CreateContextOptions, \"root\">,\n value: boolean | number | ((v: boolean | number) => boolean | number),\n ) {\n const currentValue = untrack(() => props[key]);\n if (typeof value === \"function\") {\n let result: boolean | number = false;\n if (typeof currentValue === \"number\") {\n result = value(currentValue || 0);\n } else if (typeof currentValue === \"boolean\") {\n result = value(currentValue || false);\n }\n if (`${currentValue}` === `${value}`) return;\n element.root.setAttribute(toHyphenated(key), `${result}`);\n return;\n }\n if (`${currentValue}` === `${value}`) return;\n return element.root.setAttribute(toHyphenated(key), `${value}`);\n }\n\n return [\n mergeProps(store, stateProps),\n { setElementState, setStore },\n ] as const;\n}\n\nconst AccordionContextState = createContext(initializeAccordionContext);\n\nexport const provideAccordionContext = (\n initialState: Omit<CreateContextOptions, \"root\">,\n element: WalkableNode,\n): AccordionContext => {\n const props = mergeProps(initialState, { root: element });\n return provide(AccordionContextState, props, element);\n};\n\nexport const useAccordionContext = (context: AccordionContext) => {\n const [state, { setElementState, setStore: setState }] = context;\n\n function updateAnimationQueue(animation: Promise<unknown>) {\n setState(\"animationQueue\", (state) => [...state, animation]);\n }\n\n function updateActiveIndex(index: number) {\n setElementState(\"activeIndex\", index);\n }\n\n const isActive = createSelector(() => state.activeIndex);\n\n return [\n state,\n { updateAnimationQueue, item: { update: updateActiveIndex, isActive } },\n ] as const;\n};\n\nexport const useAccordion = (element: HTMLElement & ICustomElement) => {\n const context: AccordionContext = consume(AccordionContextState, element);\n\n if (!context) {\n throw console.error(\n \"AccordionContext not found! Please ensure to wrap your custom element with accordion-context element.\",\n );\n }\n\n return useAccordionContext(context);\n};\n\nexport const getAccordionContext = (element: Element) => {\n const context = getContextFromProvider<AccordionContext>(\n AccordionContextState,\n element,\n );\n return useAccordionContext(context);\n};\n"]}
@@ -0,0 +1,101 @@
1
+ import { createContext, provide, consume } from 'component-register';
2
+ import { splitProps, createEffect, batch, mergeProps, untrack } from 'solid-js';
3
+ import { toHyphenated, getContextFromProvider } from '@brytdesigns/web-component-utils';
4
+ import { useAccordion } from './useAccordion.js';
5
+
6
+ function initializeAccordionItemContext(props) {
7
+ const [element, privateProps, stateProps] = splitProps(
8
+ props,
9
+ ["root"],
10
+ ["ariaExpanded"]
11
+ );
12
+ const [context, methods] = useAccordion(element.root);
13
+ function setElementState(key, value) {
14
+ const currentValue = untrack(() => props[key]);
15
+ if (typeof value === "function") {
16
+ let result = false;
17
+ if (typeof currentValue === "number") {
18
+ result = value(currentValue || 0);
19
+ } else if (typeof currentValue === "boolean") {
20
+ result = value(currentValue || false);
21
+ }
22
+ if (`${currentValue}` === `${value}`) return;
23
+ element.root.setAttribute(toHyphenated(key), `${result}`);
24
+ return;
25
+ }
26
+ if (`${currentValue}` === `${value}`) return;
27
+ return element.root.setAttribute(toHyphenated(key), `${value}`);
28
+ }
29
+ createEffect(() => {
30
+ const isActive = methods.item.isActive(props.index);
31
+ batch(() => {
32
+ setElementState("isExpanded", isActive);
33
+ setElementState("ariaExpanded", isActive);
34
+ });
35
+ });
36
+ function setActive(index) {
37
+ methods.item.update(index);
38
+ }
39
+ return [
40
+ mergeProps(stateProps, {
41
+ get isAnimating() {
42
+ return context.isAnimating;
43
+ }
44
+ }),
45
+ { setElementState, setActive }
46
+ ];
47
+ }
48
+ const AccordionItemContextState = createContext(initializeAccordionItemContext);
49
+ const provideAccordionItemContext = (initialState, element) => {
50
+ const props = mergeProps(initialState, { root: element });
51
+ return provide(AccordionItemContextState, props, element);
52
+ };
53
+ const useAccordionItemContext = (context) => {
54
+ const [state, { setElementState, setActive }] = context;
55
+ function expand() {
56
+ const index = untrack(() => state.index);
57
+ batch(() => {
58
+ setActive(index);
59
+ setElementState("isExpanded", true);
60
+ });
61
+ }
62
+ function collapse() {
63
+ batch(() => {
64
+ setActive(-1);
65
+ setElementState("isExpanded", false);
66
+ });
67
+ }
68
+ function toggle() {
69
+ setElementState("isExpanded", (v) => {
70
+ const index = untrack(() => state.index);
71
+ const newValue = !v;
72
+ if (newValue) setActive(index);
73
+ else setActive(-1);
74
+ return newValue;
75
+ });
76
+ }
77
+ return [state, { expand, collapse, toggle }];
78
+ };
79
+ const useAccordionItem = (element) => {
80
+ const context = consume(
81
+ AccordionItemContextState,
82
+ element
83
+ );
84
+ if (!context) {
85
+ throw console.error(
86
+ "AccordionItemContext not found! Please ensure to wrap your custom element with accordion-item element."
87
+ );
88
+ }
89
+ return useAccordionItemContext(context);
90
+ };
91
+ const getAccordionItemContext = (element) => {
92
+ const context = getContextFromProvider(
93
+ AccordionItemContextState,
94
+ element
95
+ );
96
+ return useAccordionItemContext(context);
97
+ };
98
+
99
+ export { getAccordionItemContext, provideAccordionItemContext, useAccordionItem, useAccordionItemContext };
100
+ //# sourceMappingURL=useAccordionItem.js.map
101
+ //# sourceMappingURL=useAccordionItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/hooks/useAccordionItem.ts"],"names":[],"mappings":"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","file":"useAccordionItem.js","sourcesContent":["import {\n type ICustomElement,\n createContext,\n provide,\n consume,\n} from \"component-register\";\nimport { batch, createEffect, mergeProps, splitProps, untrack } from \"solid-js\";\nimport {\n toHyphenated,\n getContextFromProvider,\n} from \"@brytdesigns/web-component-utils\";\nimport { useAccordion } from \"./useAccordion.js\";\n\ntype CreateContextOptions = {\n root: HTMLElement & ICustomElement;\n isExpanded: boolean;\n index: number;\n ariaExpanded: boolean;\n};\n\ntype WalkableNode = Parameters<typeof provide>[2];\n\ntype AccordionItemContext = ReturnType<typeof initializeAccordionItemContext>;\n\nfunction initializeAccordionItemContext(props: CreateContextOptions) {\n const [element, privateProps, stateProps] = splitProps(\n props,\n [\"root\"],\n [\"ariaExpanded\"],\n );\n const [context, methods] = useAccordion(element.root);\n\n function setElementState(\n key: keyof Omit<CreateContextOptions, \"root\">,\n value: boolean | number | ((v: boolean | number) => boolean | number),\n ) {\n const currentValue = untrack(() => props[key]);\n if (typeof value === \"function\") {\n let result: boolean | number = false;\n if (typeof currentValue === \"number\") {\n result = value(currentValue || 0);\n } else if (typeof currentValue === \"boolean\") {\n result = value(currentValue || false);\n }\n if (`${currentValue}` === `${value}`) return;\n element.root.setAttribute(toHyphenated(key), `${result}`);\n return;\n }\n if (`${currentValue}` === `${value}`) return;\n return element.root.setAttribute(toHyphenated(key), `${value}`);\n }\n\n createEffect(() => {\n const isActive = methods.item.isActive(props.index);\n batch(() => {\n setElementState(\"isExpanded\", isActive);\n setElementState(\"ariaExpanded\", isActive);\n });\n });\n\n function setActive(index: number) {\n methods.item.update(index);\n }\n\n return [\n mergeProps(stateProps, {\n get isAnimating() {\n return context.isAnimating;\n },\n }),\n { setElementState, setActive },\n ] as const;\n}\n\nconst AccordionItemContextState = createContext(initializeAccordionItemContext);\n\nexport const provideAccordionItemContext = (\n initialState: Omit<CreateContextOptions, \"root\">,\n element: WalkableNode,\n): AccordionItemContext => {\n const props = mergeProps(initialState, { root: element });\n return provide(AccordionItemContextState, props, element);\n};\n\nexport const useAccordionItemContext = (context: AccordionItemContext) => {\n const [state, { setElementState, setActive }] = context;\n\n function expand() {\n const index = untrack(() => state.index);\n batch(() => {\n setActive(index);\n setElementState(\"isExpanded\", true);\n });\n }\n\n function collapse() {\n batch(() => {\n setActive(-1);\n setElementState(\"isExpanded\", false);\n });\n }\n\n function toggle() {\n setElementState(\"isExpanded\", (v) => {\n const index = untrack(() => state.index);\n const newValue = !v;\n if (newValue) setActive(index);\n else setActive(-1);\n return newValue;\n });\n }\n\n return [state, { expand, collapse, toggle }] as const;\n};\n\nexport const useAccordionItem = (element: HTMLElement & ICustomElement) => {\n const context: AccordionItemContext = consume(\n AccordionItemContextState,\n element,\n );\n\n if (!context) {\n throw console.error(\n \"AccordionItemContext not found! Please ensure to wrap your custom element with accordion-item element.\",\n );\n }\n\n return useAccordionItemContext(context);\n};\n\nexport const getAccordionItemContext = (element: Element) => {\n const context = getContextFromProvider<AccordionItemContext>(\n AccordionItemContextState,\n element,\n );\n return useAccordionItemContext(context);\n};\n"]}
@@ -0,0 +1,126 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ import { ICustomElement, provide } from 'component-register';
4
+
5
+ export type StoreContext = {
6
+ animationQueue: Promise<unknown>[];
7
+ };
8
+ export type CreateContextOptions = {
9
+ root: HTMLElement & ICustomElement;
10
+ isAnimating: boolean;
11
+ activeIndex: number;
12
+ };
13
+ export type WalkableNode = Parameters<typeof provide>[2];
14
+ export type AccordionContext = ReturnType<typeof initializeAccordionContext>;
15
+ declare function initializeAccordionContext(props: CreateContextOptions): readonly [
16
+ {
17
+ animationQueue: Promise<unknown>[];
18
+ isAnimating: boolean;
19
+ activeIndex: number;
20
+ },
21
+ {
22
+ readonly setElementState: (key: keyof Omit<CreateContextOptions, "root">, value: boolean | number | ((v: boolean | number) => boolean | number)) => void;
23
+ readonly setStore: import("solid-js/store").SetStoreFunction<StoreContext>;
24
+ }
25
+ ];
26
+ export declare const provideAccordionContext: (initialState: Omit<CreateContextOptions, "root">, element: WalkableNode) => AccordionContext;
27
+ export declare const useAccordionContext: (context: AccordionContext) => readonly [
28
+ {
29
+ animationQueue: Promise<unknown>[];
30
+ isAnimating: boolean;
31
+ activeIndex: number;
32
+ },
33
+ {
34
+ readonly updateAnimationQueue: (animation: Promise<unknown>) => void;
35
+ readonly item: {
36
+ readonly update: (index: number) => void;
37
+ readonly isActive: (key: number) => boolean;
38
+ };
39
+ }
40
+ ];
41
+ export declare const useAccordion: (element: HTMLElement & ICustomElement) => readonly [
42
+ {
43
+ animationQueue: Promise<unknown>[];
44
+ isAnimating: boolean;
45
+ activeIndex: number;
46
+ },
47
+ {
48
+ readonly updateAnimationQueue: (animation: Promise<unknown>) => void;
49
+ readonly item: {
50
+ readonly update: (index: number) => void;
51
+ readonly isActive: (key: number) => boolean;
52
+ };
53
+ }
54
+ ];
55
+ export declare const getAccordionContext: (element: Element) => readonly [
56
+ {
57
+ animationQueue: Promise<unknown>[];
58
+ isAnimating: boolean;
59
+ activeIndex: number;
60
+ },
61
+ {
62
+ readonly updateAnimationQueue: (animation: Promise<unknown>) => void;
63
+ readonly item: {
64
+ readonly update: (index: number) => void;
65
+ readonly isActive: (key: number) => boolean;
66
+ };
67
+ }
68
+ ];
69
+ type CreateContextOptions$1 = {
70
+ root: HTMLElement & ICustomElement;
71
+ isExpanded: boolean;
72
+ index: number;
73
+ ariaExpanded: boolean;
74
+ };
75
+ type WalkableNode$1 = Parameters<typeof provide>[2];
76
+ export type AccordionItemContext = ReturnType<typeof initializeAccordionItemContext>;
77
+ declare function initializeAccordionItemContext(props: CreateContextOptions$1): readonly [
78
+ {
79
+ isExpanded: boolean;
80
+ index: number;
81
+ readonly isAnimating: boolean;
82
+ },
83
+ {
84
+ readonly setElementState: (key: keyof Omit<CreateContextOptions$1, "root">, value: boolean | number | ((v: boolean | number) => boolean | number)) => void;
85
+ readonly setActive: (index: number) => void;
86
+ }
87
+ ];
88
+ export declare const provideAccordionItemContext: (initialState: Omit<CreateContextOptions$1, "root">, element: WalkableNode$1) => AccordionItemContext;
89
+ export declare const useAccordionItemContext: (context: AccordionItemContext) => readonly [
90
+ {
91
+ isExpanded: boolean;
92
+ index: number;
93
+ readonly isAnimating: boolean;
94
+ },
95
+ {
96
+ readonly expand: () => void;
97
+ readonly collapse: () => void;
98
+ readonly toggle: () => void;
99
+ }
100
+ ];
101
+ export declare const useAccordionItem: (element: HTMLElement & ICustomElement) => readonly [
102
+ {
103
+ isExpanded: boolean;
104
+ index: number;
105
+ readonly isAnimating: boolean;
106
+ },
107
+ {
108
+ readonly expand: () => void;
109
+ readonly collapse: () => void;
110
+ readonly toggle: () => void;
111
+ }
112
+ ];
113
+ export declare const getAccordionItemContext: (element: Element) => readonly [
114
+ {
115
+ isExpanded: boolean;
116
+ index: number;
117
+ readonly isAnimating: boolean;
118
+ },
119
+ {
120
+ readonly expand: () => void;
121
+ readonly collapse: () => void;
122
+ readonly toggle: () => void;
123
+ }
124
+ ];
125
+
126
+ export {};
@@ -0,0 +1,26 @@
1
+ import { customShadowlessElement, correctElementType } from '@brytdesigns/web-component-utils';
2
+ import { AccordionContext, AccordionItem, AccordionTrigger, AccordionContent } from './components/index.js';
3
+ export * from './hooks/index.js';
4
+
5
+ customShadowlessElement(
6
+ "accordion-context",
7
+ { activeIndex: -1, isAnimating: false },
8
+ correctElementType(AccordionContext)
9
+ );
10
+ customShadowlessElement(
11
+ "accordion-item",
12
+ { index: 0, isExpanded: false, ariaExpanded: false },
13
+ correctElementType(AccordionItem)
14
+ );
15
+ customShadowlessElement(
16
+ "accordion-trigger",
17
+ { preventDefault: true },
18
+ correctElementType(AccordionTrigger)
19
+ );
20
+ customShadowlessElement(
21
+ "accordion-content",
22
+ { shouldScrollIntoView: false },
23
+ correctElementType(AccordionContent)
24
+ );
25
+ //# sourceMappingURL=index.js.map
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/index.ts"],"names":[],"mappings":";;;;AAYA,uBAAA;AAAA,EACE,mBAAA;AAAA,EACA,EAAE,WAAA,EAAa,EAAI,EAAA,WAAA,EAAa,KAAM,EAAA;AAAA,EACtC,mBAAmB,gBAAgB;AACrC,CAAA;AAEA,uBAAA;AAAA,EACE,gBAAA;AAAA,EACA,EAAE,KAAO,EAAA,CAAA,EAAG,UAAY,EAAA,KAAA,EAAO,cAAc,KAAM,EAAA;AAAA,EACnD,mBAAmB,aAAa;AAClC,CAAA;AAEA,uBAAA;AAAA,EACE,mBAAA;AAAA,EACA,EAAE,gBAAgB,IAAK,EAAA;AAAA,EACvB,mBAAmB,gBAAgB;AACrC,CAAA;AAEA,uBAAA;AAAA,EACE,mBAAA;AAAA,EACA,EAAE,sBAAsB,KAAM,EAAA;AAAA,EAC9B,mBAAmB,gBAAgB;AACrC,CAAA","file":"index.js","sourcesContent":["import {\n customShadowlessElement,\n correctElementType,\n} from \"@brytdesigns/web-component-utils\";\n\nimport {\n AccordionContext,\n AccordionItem,\n AccordionContent,\n AccordionTrigger,\n} from \"./components/index.js\";\n\ncustomShadowlessElement(\n \"accordion-context\",\n { activeIndex: -1, isAnimating: false },\n correctElementType(AccordionContext),\n);\n\ncustomShadowlessElement(\n \"accordion-item\",\n { index: 0, isExpanded: false, ariaExpanded: false },\n correctElementType(AccordionItem),\n);\n\ncustomShadowlessElement(\n \"accordion-trigger\",\n { preventDefault: true },\n correctElementType(AccordionTrigger),\n);\n\ncustomShadowlessElement(\n \"accordion-content\",\n { shouldScrollIntoView: false },\n correctElementType(AccordionContent),\n);\n\nexport * from \"./hooks/index.js\";\n"]}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@brytdesigns/web-component-accordion",
3
+ "version": "1.0.0",
4
+ "description": "Headless accordion web component",
5
+ "main": "./dist/main/index.js",
6
+ "module": "./dist/main/index.js",
7
+ "types": "./dist/main/index.d.ts",
8
+ "type": "module",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/main/index.d.ts",
12
+ "module": "./dist/main/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "keywords": [],
19
+ "author": "Bryt Designs",
20
+ "license": "ISC",
21
+ "dependencies": {
22
+ "component-register": "^0.8.7",
23
+ "motion": "^12.5.0",
24
+ "solid-element": "^1.9.1",
25
+ "solid-js": "^1.9.5",
26
+ "@brytdesigns/web-component-utils": "0.1.8"
27
+ },
28
+ "devDependencies": {
29
+ "dts-bundle-generator": "^9.5.1",
30
+ "tsup": "^8.4.0"
31
+ },
32
+ "scripts": {
33
+ "build": "tsup --clean",
34
+ "typecheck": "tsc --noEmit"
35
+ }
36
+ }