@brytdesigns/web-component-accordion 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.js +357 -0
- package/dist/esm/index.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import { customShadowlessElement, correctElementType, toHyphenated, getContextFromProvider } from '@brytdesigns/web-component-utils';
|
|
2
|
+
import { animate } from 'motion';
|
|
3
|
+
import { splitProps, createEffect, on, batch, untrack, mergeProps, onCleanup, createSelector } from 'solid-js';
|
|
4
|
+
import { createContext, consume, provide } from 'component-register';
|
|
5
|
+
import { createStore } from 'solid-js/store';
|
|
6
|
+
|
|
7
|
+
// src/index.ts
|
|
8
|
+
function initializeAccordionContext(props) {
|
|
9
|
+
const [element, stateProps] = splitProps(props, ["root"]);
|
|
10
|
+
const [store, setStore] = createStore({ animationQueue: [] });
|
|
11
|
+
createEffect(
|
|
12
|
+
on(
|
|
13
|
+
() => store.animationQueue,
|
|
14
|
+
(animationQueue) => {
|
|
15
|
+
if (!animationQueue.length) return;
|
|
16
|
+
const animations = Promise.allSettled(store.animationQueue);
|
|
17
|
+
setElementState("isAnimating", true);
|
|
18
|
+
animations.finally(() => {
|
|
19
|
+
batch(() => {
|
|
20
|
+
setElementState("isAnimating", false);
|
|
21
|
+
setStore("animationQueue", []);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
)
|
|
26
|
+
);
|
|
27
|
+
function setElementState(key, value) {
|
|
28
|
+
const currentValue = untrack(() => props[key]);
|
|
29
|
+
if (typeof value === "function") {
|
|
30
|
+
let result = false;
|
|
31
|
+
if (typeof currentValue === "number") {
|
|
32
|
+
result = value(currentValue || 0);
|
|
33
|
+
} else if (typeof currentValue === "boolean") {
|
|
34
|
+
result = value(currentValue || false);
|
|
35
|
+
}
|
|
36
|
+
if (`${currentValue}` === `${value}`) return;
|
|
37
|
+
element.root.setAttribute(toHyphenated(key), `${result}`);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (`${currentValue}` === `${value}`) return;
|
|
41
|
+
return element.root.setAttribute(toHyphenated(key), `${value}`);
|
|
42
|
+
}
|
|
43
|
+
return [
|
|
44
|
+
mergeProps(store, stateProps),
|
|
45
|
+
{ setElementState, setStore }
|
|
46
|
+
];
|
|
47
|
+
}
|
|
48
|
+
var AccordionContextState = createContext(initializeAccordionContext);
|
|
49
|
+
var provideAccordionContext = (initialState, element) => {
|
|
50
|
+
const props = mergeProps(initialState, { root: element });
|
|
51
|
+
return provide(AccordionContextState, props, element);
|
|
52
|
+
};
|
|
53
|
+
var useAccordionContext = (context) => {
|
|
54
|
+
const [state, { setElementState, setStore: setState }] = context;
|
|
55
|
+
function updateAnimationQueue(animation) {
|
|
56
|
+
setState("animationQueue", (state2) => [...state2, animation]);
|
|
57
|
+
}
|
|
58
|
+
function updateActiveIndex(index) {
|
|
59
|
+
setElementState("activeIndex", index);
|
|
60
|
+
}
|
|
61
|
+
const isActive = createSelector(() => state.activeIndex);
|
|
62
|
+
return [
|
|
63
|
+
state,
|
|
64
|
+
{ updateAnimationQueue, item: { update: updateActiveIndex, isActive } }
|
|
65
|
+
];
|
|
66
|
+
};
|
|
67
|
+
var useAccordion = (element) => {
|
|
68
|
+
const context = consume(AccordionContextState, element);
|
|
69
|
+
if (!context) {
|
|
70
|
+
throw console.error(
|
|
71
|
+
"AccordionContext not found! Please ensure to wrap your custom element with accordion-context element."
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
return useAccordionContext(context);
|
|
75
|
+
};
|
|
76
|
+
var getAccordionContext = (element) => {
|
|
77
|
+
const context = getContextFromProvider(
|
|
78
|
+
AccordionContextState,
|
|
79
|
+
element
|
|
80
|
+
);
|
|
81
|
+
return useAccordionContext(context);
|
|
82
|
+
};
|
|
83
|
+
function initializeAccordionItemContext(props) {
|
|
84
|
+
const [element, privateProps, stateProps] = splitProps(
|
|
85
|
+
props,
|
|
86
|
+
["root"],
|
|
87
|
+
["ariaExpanded"]
|
|
88
|
+
);
|
|
89
|
+
const [context, methods] = useAccordion(element.root);
|
|
90
|
+
function setElementState(key, value) {
|
|
91
|
+
const currentValue = untrack(() => props[key]);
|
|
92
|
+
if (typeof value === "function") {
|
|
93
|
+
let result = false;
|
|
94
|
+
if (typeof currentValue === "number") {
|
|
95
|
+
result = value(currentValue || 0);
|
|
96
|
+
} else if (typeof currentValue === "boolean") {
|
|
97
|
+
result = value(currentValue || false);
|
|
98
|
+
}
|
|
99
|
+
if (`${currentValue}` === `${value}`) return;
|
|
100
|
+
element.root.setAttribute(toHyphenated(key), `${result}`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (`${currentValue}` === `${value}`) return;
|
|
104
|
+
return element.root.setAttribute(toHyphenated(key), `${value}`);
|
|
105
|
+
}
|
|
106
|
+
createEffect(() => {
|
|
107
|
+
const isActive = methods.item.isActive(props.index);
|
|
108
|
+
batch(() => {
|
|
109
|
+
setElementState("isExpanded", isActive);
|
|
110
|
+
setElementState("ariaExpanded", isActive);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
createEffect(() => {
|
|
114
|
+
const index = untrack(() => stateProps.index);
|
|
115
|
+
const isExpanded = stateProps.isExpanded;
|
|
116
|
+
if (isExpanded) methods.item.update(index);
|
|
117
|
+
});
|
|
118
|
+
function setActive(index) {
|
|
119
|
+
methods.item.update(index);
|
|
120
|
+
}
|
|
121
|
+
return [
|
|
122
|
+
mergeProps(stateProps, {
|
|
123
|
+
get isAnimating() {
|
|
124
|
+
return context.isAnimating;
|
|
125
|
+
}
|
|
126
|
+
}),
|
|
127
|
+
{ setElementState, setActive }
|
|
128
|
+
];
|
|
129
|
+
}
|
|
130
|
+
var AccordionItemContextState = createContext(initializeAccordionItemContext);
|
|
131
|
+
var provideAccordionItemContext = (initialState, element) => {
|
|
132
|
+
const props = mergeProps(initialState, { root: element });
|
|
133
|
+
return provide(AccordionItemContextState, props, element);
|
|
134
|
+
};
|
|
135
|
+
var useAccordionItemContext = (context) => {
|
|
136
|
+
const [state, { setElementState, setActive }] = context;
|
|
137
|
+
function expand() {
|
|
138
|
+
const index = untrack(() => state.index);
|
|
139
|
+
batch(() => {
|
|
140
|
+
setActive(index);
|
|
141
|
+
setElementState("isExpanded", true);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
function collapse() {
|
|
145
|
+
batch(() => {
|
|
146
|
+
setActive(-1);
|
|
147
|
+
setElementState("isExpanded", false);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
function toggle() {
|
|
151
|
+
setElementState("isExpanded", (v) => {
|
|
152
|
+
const index = untrack(() => state.index);
|
|
153
|
+
const newValue = !v;
|
|
154
|
+
if (newValue) setActive(index);
|
|
155
|
+
else setActive(-1);
|
|
156
|
+
return newValue;
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return [state, { expand, collapse, toggle }];
|
|
160
|
+
};
|
|
161
|
+
var useAccordionItem = (element) => {
|
|
162
|
+
const context = consume(
|
|
163
|
+
AccordionItemContextState,
|
|
164
|
+
element
|
|
165
|
+
);
|
|
166
|
+
if (!context) {
|
|
167
|
+
throw console.error(
|
|
168
|
+
"AccordionItemContext not found! Please ensure to wrap your custom element with accordion-item element."
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
return useAccordionItemContext(context);
|
|
172
|
+
};
|
|
173
|
+
var getAccordionItemContext = (element) => {
|
|
174
|
+
const context = getContextFromProvider(
|
|
175
|
+
AccordionItemContextState,
|
|
176
|
+
element
|
|
177
|
+
);
|
|
178
|
+
return useAccordionItemContext(context);
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
// src/components/accordion-content.ts
|
|
182
|
+
async function controlPromise(controls) {
|
|
183
|
+
return new Promise((resolve) => {
|
|
184
|
+
controls.then(() => resolve(null));
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
var hideElement = (element) => {
|
|
188
|
+
element.style.cssText = `
|
|
189
|
+
display: none;
|
|
190
|
+
opacity: 0;
|
|
191
|
+
visibility: hidden;
|
|
192
|
+
max-height: 0px;
|
|
193
|
+
`;
|
|
194
|
+
element.style.overflow = null;
|
|
195
|
+
};
|
|
196
|
+
var showElement = (element) => {
|
|
197
|
+
element.style.cssText = `
|
|
198
|
+
display: block;
|
|
199
|
+
opacity: 1;
|
|
200
|
+
visibility: visible;
|
|
201
|
+
`;
|
|
202
|
+
};
|
|
203
|
+
var getHeight = (el) => {
|
|
204
|
+
el.style.maxHeight = "max-content";
|
|
205
|
+
const height = el.getBoundingClientRect().height;
|
|
206
|
+
el.style.maxHeight = `${0}`;
|
|
207
|
+
return height;
|
|
208
|
+
};
|
|
209
|
+
var getPaddingTop = (element) => {
|
|
210
|
+
const paddingY = parseInt(getComputedStyle(element).paddingTop);
|
|
211
|
+
return paddingY;
|
|
212
|
+
};
|
|
213
|
+
var getPaddingBottom = (element) => {
|
|
214
|
+
const paddingY = parseInt(getComputedStyle(element).paddingBottom);
|
|
215
|
+
return paddingY;
|
|
216
|
+
};
|
|
217
|
+
var AccordionContent = (props, { element }) => {
|
|
218
|
+
const [state] = useAccordionItem(element);
|
|
219
|
+
const [_, accordionMethods] = useAccordion(element);
|
|
220
|
+
let isFirstRender = true;
|
|
221
|
+
const expand = (element2) => {
|
|
222
|
+
showElement(element2);
|
|
223
|
+
const height = getHeight(element2), pt = getPaddingTop(element2), pb = getPaddingBottom(element2);
|
|
224
|
+
Array.from(element2.children).forEach(
|
|
225
|
+
(child) => child.style.opacity = "1"
|
|
226
|
+
);
|
|
227
|
+
const animation = animate(
|
|
228
|
+
element2,
|
|
229
|
+
{
|
|
230
|
+
maxHeight: ["0px", `${height}px`],
|
|
231
|
+
paddingTop: ["0px", `${pt}px`],
|
|
232
|
+
paddingBottom: ["0px", `${pb}px`]
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
duration: 0.35
|
|
236
|
+
}
|
|
237
|
+
);
|
|
238
|
+
animation.then(() => {
|
|
239
|
+
element2.style.maxHeight = "max-content";
|
|
240
|
+
element2.style.overflow = null;
|
|
241
|
+
if (props.shouldScrollIntoView)
|
|
242
|
+
element2.scrollIntoView({
|
|
243
|
+
behavior: "smooth",
|
|
244
|
+
block: "start",
|
|
245
|
+
inline: "nearest"
|
|
246
|
+
});
|
|
247
|
+
return;
|
|
248
|
+
});
|
|
249
|
+
return animation;
|
|
250
|
+
};
|
|
251
|
+
const collapse = (element2) => {
|
|
252
|
+
const height = getHeight(element2), pt = getPaddingTop(element2), pb = getPaddingBottom(element2);
|
|
253
|
+
element2.style.overflow = "hidden";
|
|
254
|
+
Array.from(element2.children).forEach(
|
|
255
|
+
(child) => child.style.opacity = "0"
|
|
256
|
+
);
|
|
257
|
+
const animation = animate(
|
|
258
|
+
element2,
|
|
259
|
+
{
|
|
260
|
+
maxHeight: [`${height}px`, "0px"],
|
|
261
|
+
paddingTop: [`${pt}px`, "0px"],
|
|
262
|
+
paddingBottom: [`${pb}px`, "0px"]
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
duration: 0.35
|
|
266
|
+
}
|
|
267
|
+
);
|
|
268
|
+
animation.then(() => hideElement(element2));
|
|
269
|
+
return animation;
|
|
270
|
+
};
|
|
271
|
+
createEffect(
|
|
272
|
+
on(
|
|
273
|
+
() => state.isExpanded,
|
|
274
|
+
(isExpanded) => {
|
|
275
|
+
if (!isExpanded) {
|
|
276
|
+
const animation2 = collapse(element);
|
|
277
|
+
accordionMethods.updateAnimationQueue(controlPromise(animation2));
|
|
278
|
+
return onCleanup(() => animation2.complete());
|
|
279
|
+
}
|
|
280
|
+
if (isFirstRender) {
|
|
281
|
+
isFirstRender = false;
|
|
282
|
+
showElement(element);
|
|
283
|
+
}
|
|
284
|
+
const animation = expand(element);
|
|
285
|
+
accordionMethods.updateAnimationQueue(controlPromise(animation));
|
|
286
|
+
return onCleanup(() => animation.complete());
|
|
287
|
+
}
|
|
288
|
+
)
|
|
289
|
+
);
|
|
290
|
+
};
|
|
291
|
+
var AccordionItem = (props, { element }) => {
|
|
292
|
+
if (element.parentElement?.tagName !== "ACCORDION-CONTEXT")
|
|
293
|
+
return console.warn(
|
|
294
|
+
"accordion-item must be an immediate child of accordion-context",
|
|
295
|
+
element
|
|
296
|
+
);
|
|
297
|
+
provideAccordionItemContext(props, element);
|
|
298
|
+
};
|
|
299
|
+
var AccordionTrigger = (props, { element }) => {
|
|
300
|
+
const [state, methods] = useAccordionItem(element);
|
|
301
|
+
createEffect(() => {
|
|
302
|
+
const isAnimating = state.isAnimating;
|
|
303
|
+
if (isAnimating) return;
|
|
304
|
+
const controller = new AbortController(), preventDefault = props.preventDefault;
|
|
305
|
+
element.addEventListener(
|
|
306
|
+
"click",
|
|
307
|
+
(event) => {
|
|
308
|
+
if (preventDefault) event.preventDefault();
|
|
309
|
+
methods.toggle();
|
|
310
|
+
},
|
|
311
|
+
{ signal: controller.signal }
|
|
312
|
+
);
|
|
313
|
+
return onCleanup(() => {
|
|
314
|
+
controller.abort();
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
};
|
|
318
|
+
var AccordionContext = (props, { element }) => {
|
|
319
|
+
const context = provideAccordionContext(props, element);
|
|
320
|
+
const [_, methods] = useAccordionContext(context);
|
|
321
|
+
const children = Array.from(element.children);
|
|
322
|
+
const accordionItems = children.filter(
|
|
323
|
+
(child) => child.tagName === "ACCORDION-ITEM"
|
|
324
|
+
);
|
|
325
|
+
accordionItems.forEach((accordionItem, index) => {
|
|
326
|
+
accordionItem.setAttribute("index", `${index + 1}`);
|
|
327
|
+
if (accordionItem.getAttribute(toHyphenated("isExpanded")) !== "true")
|
|
328
|
+
return;
|
|
329
|
+
methods.item.update(index + 1);
|
|
330
|
+
});
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
// src/index.ts
|
|
334
|
+
customShadowlessElement(
|
|
335
|
+
"accordion-context",
|
|
336
|
+
{ activeIndex: -1, isAnimating: false },
|
|
337
|
+
correctElementType(AccordionContext)
|
|
338
|
+
);
|
|
339
|
+
customShadowlessElement(
|
|
340
|
+
"accordion-item",
|
|
341
|
+
{ index: 0, isExpanded: false, ariaExpanded: false },
|
|
342
|
+
correctElementType(AccordionItem)
|
|
343
|
+
);
|
|
344
|
+
customShadowlessElement(
|
|
345
|
+
"accordion-trigger",
|
|
346
|
+
{ preventDefault: true },
|
|
347
|
+
correctElementType(AccordionTrigger)
|
|
348
|
+
);
|
|
349
|
+
customShadowlessElement(
|
|
350
|
+
"accordion-content",
|
|
351
|
+
{ shouldScrollIntoView: false },
|
|
352
|
+
correctElementType(AccordionContent)
|
|
353
|
+
);
|
|
354
|
+
|
|
355
|
+
export { getAccordionContext, getAccordionItemContext, provideAccordionContext, provideAccordionItemContext, useAccordion, useAccordionContext, useAccordionItem, useAccordionItemContext };
|
|
356
|
+
//# sourceMappingURL=index.js.map
|
|
357
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/useAccordion.ts","../../src/hooks/useAccordionItem.ts","../../src/components/accordion-content.ts","../../src/components/accordion-item.ts","../../src/components/accordion-trigger.ts","../../src/components/accordion-context.ts","../../src/index.ts"],"names":["state","splitProps","untrack","toHyphenated","createEffect","batch","mergeProps","createContext","provide","consume","getContextFromProvider","element","on","animation","onCleanup"],"mappings":"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","file":"index.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","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 createEffect(() => {\n const index = untrack(() => stateProps.index);\n const isExpanded = stateProps.isExpanded;\n if (isExpanded) methods.item.update(index);\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","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","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","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","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","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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brytdesigns/web-component-accordion",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "Headless accordion web component",
|
|
5
5
|
"main": "./dist/main/index.js",
|
|
6
6
|
"module": "./dist/main/index.js",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"motion": "^12.5.0",
|
|
24
24
|
"solid-element": "^1.9.1",
|
|
25
25
|
"solid-js": "^1.9.7",
|
|
26
|
-
"@brytdesigns/web-component-utils": "0.1.
|
|
26
|
+
"@brytdesigns/web-component-utils": "0.1.13"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"dts-bundle-generator": "^9.5.1",
|