@brytdesigns/web-component-collapsible 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.
- package/dist/esm/index.js +262 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/main/components/collapsible-content.js +113 -0
- package/dist/main/components/collapsible-content.js.map +1 -0
- package/dist/main/components/collapsible-item.js +10 -0
- package/dist/main/components/collapsible-item.js.map +1 -0
- package/dist/main/components/collapsible-trigger.js +27 -0
- package/dist/main/components/collapsible-trigger.js.map +1 -0
- package/dist/main/components/index.js +8 -0
- package/dist/main/components/index.js.map +1 -0
- package/dist/main/hooks/index.js +3 -0
- package/dist/main/hooks/index.js.map +1 -0
- package/dist/main/hooks/useCollapsibleItem.js +87 -0
- package/dist/main/hooks/useCollapsibleItem.js.map +1 -0
- package/dist/main/index.d.ts +90 -0
- package/dist/main/index.js +21 -0
- package/dist/main/index.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { createWithElementContext, customShadowlessElement, correctElementType, toHyphenated, getContextFromProvider } from '@brytdesigns/web-component-core/utils';
|
|
2
|
+
import { animate } from 'motion';
|
|
3
|
+
import { splitProps, untrack, mergeProps, createEffect, on, onCleanup, batch } 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
|
+
return [stateProps, { setElementState }];
|
|
42
|
+
}
|
|
43
|
+
var CollapsibleItemContextState = createContext(
|
|
44
|
+
initializeCollapsibleItemContext
|
|
45
|
+
);
|
|
46
|
+
var provideCollapsibleItemContext = (initialState, element) => {
|
|
47
|
+
const props = mergeProps(initialState, { root: element });
|
|
48
|
+
return provide(CollapsibleItemContextState, props, element);
|
|
49
|
+
};
|
|
50
|
+
var useCollapsibleItemContext = (context) => {
|
|
51
|
+
const [state, { setElementState }] = context;
|
|
52
|
+
function expand() {
|
|
53
|
+
batch(() => {
|
|
54
|
+
setElementState("isExpanded", true);
|
|
55
|
+
setElementState("ariaExpanded", true);
|
|
56
|
+
setElementState("isAnimating", true);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function collapse() {
|
|
60
|
+
batch(() => {
|
|
61
|
+
setElementState("isExpanded", false);
|
|
62
|
+
setElementState("ariaExpanded", false);
|
|
63
|
+
setElementState("isAnimating", true);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function toggle() {
|
|
67
|
+
batch(() => {
|
|
68
|
+
setElementState("isExpanded", (v) => !v);
|
|
69
|
+
setElementState("ariaExpanded", (v) => !v);
|
|
70
|
+
setElementState("isAnimating", true);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
function finish() {
|
|
74
|
+
setElementState("isAnimating", false);
|
|
75
|
+
}
|
|
76
|
+
return [state, { expand, collapse, toggle, finish }];
|
|
77
|
+
};
|
|
78
|
+
var useCollapsibleItem = (element) => {
|
|
79
|
+
const context = consume(
|
|
80
|
+
CollapsibleItemContextState,
|
|
81
|
+
element
|
|
82
|
+
);
|
|
83
|
+
if (!context) {
|
|
84
|
+
throw console.error(
|
|
85
|
+
"AccordionItemContext not found! Please ensure to wrap your custom element with accordion-item element."
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
return useCollapsibleItemContext(context);
|
|
89
|
+
};
|
|
90
|
+
var withCollapsibleItemElementContext = createWithElementContext(CollapsibleItemContextState);
|
|
91
|
+
var getCollapsibleItemContext = (element) => {
|
|
92
|
+
const context = getContextFromProvider(
|
|
93
|
+
CollapsibleItemContextState,
|
|
94
|
+
element
|
|
95
|
+
);
|
|
96
|
+
return useCollapsibleItemContext(context);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// src/components/collapsible-content.ts
|
|
100
|
+
var hideElement = (element) => {
|
|
101
|
+
element.style.cssText = `
|
|
102
|
+
display: none;
|
|
103
|
+
opacity: 0;
|
|
104
|
+
visibility: hidden;
|
|
105
|
+
max-height: 0px;
|
|
106
|
+
`;
|
|
107
|
+
element.style.overflow = null;
|
|
108
|
+
};
|
|
109
|
+
var showElement = (element) => {
|
|
110
|
+
element.style.cssText = `
|
|
111
|
+
display: block;
|
|
112
|
+
opacity: 1;
|
|
113
|
+
visibility: visible;
|
|
114
|
+
`;
|
|
115
|
+
};
|
|
116
|
+
var getHeight = (el) => {
|
|
117
|
+
el.style.maxHeight = "max-content";
|
|
118
|
+
const height = el.getBoundingClientRect().height;
|
|
119
|
+
el.style.maxHeight = `${0}`;
|
|
120
|
+
return height;
|
|
121
|
+
};
|
|
122
|
+
var getPaddingTop = (element) => {
|
|
123
|
+
const paddingY = parseInt(getComputedStyle(element).paddingTop);
|
|
124
|
+
return paddingY;
|
|
125
|
+
};
|
|
126
|
+
var getPaddingBottom = (element) => {
|
|
127
|
+
const paddingY = parseInt(getComputedStyle(element).paddingBottom);
|
|
128
|
+
return paddingY;
|
|
129
|
+
};
|
|
130
|
+
var Name = `collapsible-content`;
|
|
131
|
+
var Component = (props, { element }) => {
|
|
132
|
+
const [state, methods] = useCollapsibleItem(element);
|
|
133
|
+
let isFirstRender = true;
|
|
134
|
+
const expand = (element2) => {
|
|
135
|
+
showElement(element2);
|
|
136
|
+
const height = getHeight(element2), pt = getPaddingTop(element2), pb = getPaddingBottom(element2);
|
|
137
|
+
Array.from(element2.children).forEach((child) => {
|
|
138
|
+
child.style.opacity = "1";
|
|
139
|
+
});
|
|
140
|
+
const animation = animate(
|
|
141
|
+
element2,
|
|
142
|
+
{
|
|
143
|
+
maxHeight: ["0px", `${height}px`],
|
|
144
|
+
paddingTop: ["0px", `${pt}px`],
|
|
145
|
+
paddingBottom: ["0px", `${pb}px`]
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
duration: 0.35
|
|
149
|
+
}
|
|
150
|
+
);
|
|
151
|
+
animation.then(() => {
|
|
152
|
+
element2.style.maxHeight = "max-content";
|
|
153
|
+
element2.style.overflow = null;
|
|
154
|
+
if (props.shouldScrollIntoView)
|
|
155
|
+
element2.scrollIntoView({
|
|
156
|
+
behavior: "smooth",
|
|
157
|
+
block: "start",
|
|
158
|
+
inline: "nearest"
|
|
159
|
+
});
|
|
160
|
+
return;
|
|
161
|
+
});
|
|
162
|
+
return animation;
|
|
163
|
+
};
|
|
164
|
+
const collapse = (element2) => {
|
|
165
|
+
const height = getHeight(element2), pt = getPaddingTop(element2), pb = getPaddingBottom(element2);
|
|
166
|
+
element2.style.overflow = "hidden";
|
|
167
|
+
Array.from(element2.children).forEach((child) => {
|
|
168
|
+
child.style.opacity = "0";
|
|
169
|
+
});
|
|
170
|
+
const animation = animate(
|
|
171
|
+
element2,
|
|
172
|
+
{
|
|
173
|
+
maxHeight: [`${height}px`, "0px"],
|
|
174
|
+
paddingTop: [`${pt}px`, "0px"],
|
|
175
|
+
paddingBottom: [`${pb}px`, "0px"]
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
duration: 0.35
|
|
179
|
+
}
|
|
180
|
+
);
|
|
181
|
+
animation.then(() => hideElement(element2));
|
|
182
|
+
return animation;
|
|
183
|
+
};
|
|
184
|
+
createEffect(
|
|
185
|
+
on(
|
|
186
|
+
() => state.isExpanded,
|
|
187
|
+
(isExpanded) => {
|
|
188
|
+
if (!isExpanded) {
|
|
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
|
+
}
|
|
197
|
+
const animation = expand(element);
|
|
198
|
+
controlsToPromise(animation).finally(methods.finish);
|
|
199
|
+
return onCleanup(() => animation.complete());
|
|
200
|
+
}
|
|
201
|
+
)
|
|
202
|
+
);
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// src/components/collapsible-trigger.ts
|
|
206
|
+
var collapsible_trigger_exports = {};
|
|
207
|
+
__export(collapsible_trigger_exports, {
|
|
208
|
+
Component: () => Component2,
|
|
209
|
+
Name: () => Name2
|
|
210
|
+
});
|
|
211
|
+
var Name2 = `collapsible-trigger`;
|
|
212
|
+
var Component2 = (props, { element }) => {
|
|
213
|
+
const [state, methods] = useCollapsibleItem(element);
|
|
214
|
+
createEffect(() => {
|
|
215
|
+
const isAnimating = state.isAnimating;
|
|
216
|
+
if (isAnimating) return;
|
|
217
|
+
const controller = new AbortController(), preventDefault = props.preventDefault;
|
|
218
|
+
element.addEventListener(
|
|
219
|
+
"click",
|
|
220
|
+
(event) => {
|
|
221
|
+
if (preventDefault) event.preventDefault();
|
|
222
|
+
methods.toggle();
|
|
223
|
+
},
|
|
224
|
+
{ signal: controller.signal }
|
|
225
|
+
);
|
|
226
|
+
return onCleanup(() => {
|
|
227
|
+
controller.abort();
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
// src/components/collapsible-item.ts
|
|
233
|
+
var collapsible_item_exports = {};
|
|
234
|
+
__export(collapsible_item_exports, {
|
|
235
|
+
Component: () => Component3,
|
|
236
|
+
Name: () => Name3
|
|
237
|
+
});
|
|
238
|
+
var Name3 = `collapsible-item`;
|
|
239
|
+
var Component3 = (props, { element }) => {
|
|
240
|
+
provideCollapsibleItemContext(props, element);
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
// src/index.ts
|
|
244
|
+
customShadowlessElement(
|
|
245
|
+
collapsible_item_exports.Name,
|
|
246
|
+
{ index: 0, isExpanded: false, ariaExpanded: false, isAnimating: false },
|
|
247
|
+
correctElementType(collapsible_item_exports.Component)
|
|
248
|
+
);
|
|
249
|
+
customShadowlessElement(
|
|
250
|
+
collapsible_trigger_exports.Name,
|
|
251
|
+
{ preventDefault: true },
|
|
252
|
+
correctElementType(collapsible_trigger_exports.Component)
|
|
253
|
+
);
|
|
254
|
+
customShadowlessElement(
|
|
255
|
+
collapsible_content_exports.Name,
|
|
256
|
+
{ shouldScrollIntoView: false },
|
|
257
|
+
correctElementType(collapsible_content_exports.Component)
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
export { getCollapsibleItemContext, provideCollapsibleItemContext, useCollapsibleItem, useCollapsibleItemContext, withCollapsibleItemElementContext };
|
|
261
|
+
//# sourceMappingURL=index.js.map
|
|
262
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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","animation","Component","Name","createEffect","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 } 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\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}\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 { batch, mergeProps, splitProps, untrack } 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\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\tbatch(() => {\n\t\t\tsetElementState(\"isExpanded\", true);\n\t\t\tsetElementState(\"ariaExpanded\", true);\n\t\t\tsetElementState(\"isAnimating\", true);\n\t\t});\n\t}\n\n\tfunction collapse() {\n\t\tbatch(() => {\n\t\t\tsetElementState(\"isExpanded\", false);\n\t\t\tsetElementState(\"ariaExpanded\", false);\n\t\t\tsetElementState(\"isAnimating\", true);\n\t\t});\n\t}\n\n\tfunction toggle() {\n\t\tbatch(() => {\n\t\t\tsetElementState(\"isExpanded\", (v) => !v);\n\t\t\tsetElementState(\"ariaExpanded\", (v) => !v);\n\t\t\tsetElementState(\"isAnimating\", true);\n\t\t});\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"]}
|
|
@@ -0,0 +1,113 @@
|
|
|
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;
|
|
31
|
+
};
|
|
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
|
+
const animation2 = collapse(element);
|
|
96
|
+
controlsToPromise(animation2).finally(methods.finish);
|
|
97
|
+
return onCleanup(() => animation2.complete());
|
|
98
|
+
}
|
|
99
|
+
if (isFirstRender) {
|
|
100
|
+
isFirstRender = false;
|
|
101
|
+
showElement(element);
|
|
102
|
+
}
|
|
103
|
+
const animation = expand(element);
|
|
104
|
+
controlsToPromise(animation).finally(methods.finish);
|
|
105
|
+
return onCleanup(() => animation.complete());
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
);
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export { Component, Name };
|
|
112
|
+
//# sourceMappingURL=collapsible-content.js.map
|
|
113
|
+
//# sourceMappingURL=collapsible-content.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/collapsible-content.ts"],"names":["element","animation"],"mappings":";;;;;AAaA,MAAM,WAAA,GAAc,CAAC,OAA4B,KAAA;AAChD,EAAA,OAAA,CAAQ,MAAM,OAAU,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA;AAMxB,EAAA,OAAA,CAAQ,MAAM,QAAW,GAAA,IAAA;AAC1B,CAAA;AAEA,MAAM,WAAA,GAAc,CAAC,OAA4B,KAAA;AAChD,EAAA,OAAA,CAAQ,MAAM,OAAU,GAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA;AAKzB,CAAA;AAEA,MAAM,SAAA,GAAY,CAAC,EAAqC,KAAA;AACvD,EAAA,EAAA,CAAG,MAAM,SAAY,GAAA,aAAA;AACrB,EAAM,MAAA,MAAA,GAAS,EAAG,CAAA,qBAAA,EAAwB,CAAA,MAAA;AAC1C,EAAG,EAAA,CAAA,KAAA,CAAM,SAAY,GAAA,CAAA,EAAG,CAAC,CAAA,CAAA;AACzB,EAAO,OAAA,MAAA;AACR,CAAA;AAEA,MAAM,aAAA,GAAgB,CAAC,OAA0C,KAAA;AAChE,EAAA,MAAM,QAAW,GAAA,QAAA,CAAS,gBAAiB,CAAA,OAAO,EAAE,UAAU,CAAA;AAC9D,EAAO,OAAA,QAAA;AACR,CAAA;AAEA,MAAM,gBAAA,GAAmB,CAAC,OAA0C,KAAA;AACnE,EAAA,MAAM,QAAW,GAAA,QAAA,CAAS,gBAAiB,CAAA,OAAO,EAAE,aAAa,CAAA;AACjE,EAAO,OAAA,QAAA;AACR,CAAA;AAEO,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,IAAI,aAAgB,GAAA,IAAA;AAEpB,EAAM,MAAA,MAAA,GAAS,CAACA,QAA0C,KAAA;AACzD,IAAA,WAAA,CAAYA,QAAO,CAAA;AAEnB,IAAM,MAAA,MAAA,GAAS,SAAUA,CAAAA,QAAO,CAC/B,EAAA,EAAA,GAAK,cAAcA,QAAO,CAAA,EAC1B,EAAK,GAAA,gBAAA,CAAiBA,QAAO,CAAA;AAE9B,IAAC,MAAM,IAAKA,CAAAA,QAAAA,CAAQ,QAAQ,CAAoB,CAAA,OAAA,CAAQ,CAAC,KAAU,KAAA;AAClE,MAAA,KAAA,CAAM,MAAM,OAAU,GAAA,GAAA;AAAA,KACtB,CAAA;AAED,IAAA,MAAM,SAAY,GAAA,OAAA;AAAA,MACjBA,QAAAA;AAAA,MACA;AAAA,QACC,SAAW,EAAA,CAAC,KAAO,EAAA,CAAA,EAAG,MAAM,CAAI,EAAA,CAAA,CAAA;AAAA,QAChC,UAAY,EAAA,CAAC,KAAO,EAAA,CAAA,EAAG,EAAE,CAAI,EAAA,CAAA,CAAA;AAAA,QAC7B,aAAe,EAAA,CAAC,KAAO,EAAA,CAAA,EAAG,EAAE,CAAI,EAAA,CAAA;AAAA,OACjC;AAAA,MACA;AAAA,QACC,QAAU,EAAA;AAAA;AACX,KACD;AAEA,IAAA,SAAA,CAAU,KAAK,MAAM;AACpB,MAAAA,QAAAA,CAAQ,MAAM,SAAY,GAAA,aAAA;AAE1B,MAAAA,QAAAA,CAAQ,MAAM,QAAW,GAAA,IAAA;AACzB,MAAA,IAAI,KAAM,CAAA,oBAAA;AACT,QAAAA,SAAQ,cAAe,CAAA;AAAA,UACtB,QAAU,EAAA,QAAA;AAAA,UACV,KAAO,EAAA,OAAA;AAAA,UACP,MAAQ,EAAA;AAAA,SACR,CAAA;AACF,MAAA;AAAA,KACA,CAAA;AAED,IAAO,OAAA,SAAA;AAAA,GACR;AAEA,EAAM,MAAA,QAAA,GAAW,CAACA,QAA0C,KAAA;AAC3D,IAAM,MAAA,MAAA,GAAS,SAAUA,CAAAA,QAAO,CAC/B,EAAA,EAAA,GAAK,cAAcA,QAAO,CAAA,EAC1B,EAAK,GAAA,gBAAA,CAAiBA,QAAO,CAAA;AAE9B,IAAAA,QAAAA,CAAQ,MAAM,QAAW,GAAA,QAAA;AAEzB,IAAC,MAAM,IAAKA,CAAAA,QAAAA,CAAQ,QAAQ,CAAoB,CAAA,OAAA,CAAQ,CAAC,KAAU,KAAA;AAClE,MAAA,KAAA,CAAM,MAAM,OAAU,GAAA,GAAA;AAAA,KACtB,CAAA;AAED,IAAA,MAAM,SAAY,GAAA,OAAA;AAAA,MACjBA,QAAAA;AAAA,MACA;AAAA,QACC,SAAW,EAAA,CAAC,CAAG,EAAA,MAAM,MAAM,KAAK,CAAA;AAAA,QAChC,UAAY,EAAA,CAAC,CAAG,EAAA,EAAE,MAAM,KAAK,CAAA;AAAA,QAC7B,aAAe,EAAA,CAAC,CAAG,EAAA,EAAE,MAAM,KAAK;AAAA,OACjC;AAAA,MACA;AAAA,QACC,QAAU,EAAA;AAAA;AACX,KACD;AAEA,IAAA,SAAA,CAAU,IAAK,CAAA,MAAM,WAAYA,CAAAA,QAAO,CAAC,CAAA;AAEzC,IAAO,OAAA,SAAA;AAAA,GACR;AAEA,EAAA,YAAA;AAAA,IACC,EAAA;AAAA,MACC,MAAM,KAAM,CAAA,UAAA;AAAA,MACZ,CAAC,UAAe,KAAA;AACf,QAAA,IAAI,CAAC,UAAY,EAAA;AAChB,UAAMC,MAAAA,UAAAA,GAAY,SAAS,OAAO,CAAA;AAClC,UAAA,iBAAA,CAAkBA,UAAS,CAAA,CAAE,OAAQ,CAAA,OAAA,CAAQ,MAAM,CAAA;AACnD,UAAA,OAAO,SAAU,CAAA,MAAMA,UAAU,CAAA,QAAA,EAAU,CAAA;AAAA;AAG5C,QAAA,IAAI,aAAe,EAAA;AAClB,UAAgB,aAAA,GAAA,KAAA;AAChB,UAAA,WAAA,CAAY,OAAO,CAAA;AAAA;AAGpB,QAAM,MAAA,SAAA,GAAY,OAAO,OAAO,CAAA;AAChC,QAAA,iBAAA,CAAkB,SAAS,CAAA,CAAE,OAAQ,CAAA,OAAA,CAAQ,MAAM,CAAA;AACnD,QAAA,OAAO,SAAU,CAAA,MAAM,SAAU,CAAA,QAAA,EAAU,CAAA;AAAA;AAC5C;AACD,GACD;AACD","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 } 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\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}\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"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { provideCollapsibleItemContext } from '../hooks/index.js';
|
|
2
|
+
|
|
3
|
+
const Name = `collapsible-item`;
|
|
4
|
+
const Component = (props, { element }) => {
|
|
5
|
+
provideCollapsibleItemContext(props, element);
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export { Component, Name };
|
|
9
|
+
//# sourceMappingURL=collapsible-item.js.map
|
|
10
|
+
//# sourceMappingURL=collapsible-item.js.map
|
|
@@ -0,0 +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"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
});
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export { Component, Name };
|
|
26
|
+
//# sourceMappingURL=collapsible-trigger.js.map
|
|
27
|
+
//# sourceMappingURL=collapsible-trigger.js.map
|
|
@@ -0,0 +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"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { createContext, provide, consume } from 'component-register';
|
|
2
|
+
import { splitProps, untrack, mergeProps, batch } from 'solid-js';
|
|
3
|
+
import { createWithElementContext, toHyphenated, getContextFromProvider } from '@brytdesigns/web-component-core/utils';
|
|
4
|
+
|
|
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
|
+
return [stateProps, { setElementState }];
|
|
28
|
+
}
|
|
29
|
+
const CollapsibleItemContextState = createContext(
|
|
30
|
+
initializeCollapsibleItemContext
|
|
31
|
+
);
|
|
32
|
+
const provideCollapsibleItemContext = (initialState, element) => {
|
|
33
|
+
const props = mergeProps(initialState, { root: element });
|
|
34
|
+
return provide(CollapsibleItemContextState, props, element);
|
|
35
|
+
};
|
|
36
|
+
const useCollapsibleItemContext = (context) => {
|
|
37
|
+
const [state, { setElementState }] = context;
|
|
38
|
+
function expand() {
|
|
39
|
+
batch(() => {
|
|
40
|
+
setElementState("isExpanded", true);
|
|
41
|
+
setElementState("ariaExpanded", true);
|
|
42
|
+
setElementState("isAnimating", true);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function collapse() {
|
|
46
|
+
batch(() => {
|
|
47
|
+
setElementState("isExpanded", false);
|
|
48
|
+
setElementState("ariaExpanded", false);
|
|
49
|
+
setElementState("isAnimating", true);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function toggle() {
|
|
53
|
+
batch(() => {
|
|
54
|
+
setElementState("isExpanded", (v) => !v);
|
|
55
|
+
setElementState("ariaExpanded", (v) => !v);
|
|
56
|
+
setElementState("isAnimating", true);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function finish() {
|
|
60
|
+
setElementState("isAnimating", false);
|
|
61
|
+
}
|
|
62
|
+
return [state, { expand, collapse, toggle, finish }];
|
|
63
|
+
};
|
|
64
|
+
const useCollapsibleItem = (element) => {
|
|
65
|
+
const context = consume(
|
|
66
|
+
CollapsibleItemContextState,
|
|
67
|
+
element
|
|
68
|
+
);
|
|
69
|
+
if (!context) {
|
|
70
|
+
throw console.error(
|
|
71
|
+
"AccordionItemContext not found! Please ensure to wrap your custom element with accordion-item element."
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
return useCollapsibleItemContext(context);
|
|
75
|
+
};
|
|
76
|
+
const withCollapsibleItemElementContext = createWithElementContext(CollapsibleItemContextState);
|
|
77
|
+
const getCollapsibleItemContext = (element) => {
|
|
78
|
+
const context = getContextFromProvider(
|
|
79
|
+
CollapsibleItemContextState,
|
|
80
|
+
element
|
|
81
|
+
);
|
|
82
|
+
return useCollapsibleItemContext(context);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export { getCollapsibleItemContext, provideCollapsibleItemContext, useCollapsibleItem, useCollapsibleItemContext, withCollapsibleItemElementContext };
|
|
86
|
+
//# sourceMappingURL=useCollapsibleItem.js.map
|
|
87
|
+
//# sourceMappingURL=useCollapsibleItem.js.map
|
|
@@ -0,0 +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 { batch, mergeProps, splitProps, untrack } 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\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\tbatch(() => {\n\t\t\tsetElementState(\"isExpanded\", true);\n\t\t\tsetElementState(\"ariaExpanded\", true);\n\t\t\tsetElementState(\"isAnimating\", true);\n\t\t});\n\t}\n\n\tfunction collapse() {\n\t\tbatch(() => {\n\t\t\tsetElementState(\"isExpanded\", false);\n\t\t\tsetElementState(\"ariaExpanded\", false);\n\t\t\tsetElementState(\"isAnimating\", true);\n\t\t});\n\t}\n\n\tfunction toggle() {\n\t\tbatch(() => {\n\t\t\tsetElementState(\"isExpanded\", (v) => !v);\n\t\t\tsetElementState(\"ariaExpanded\", (v) => !v);\n\t\t\tsetElementState(\"isAnimating\", true);\n\t\t});\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"]}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Generated by dts-bundle-generator v9.5.1
|
|
2
|
+
|
|
3
|
+
import { ICustomElement, provide } from 'component-register';
|
|
4
|
+
|
|
5
|
+
export type CorrectComponentOptions = {
|
|
6
|
+
element: HTMLElement & ICustomElement;
|
|
7
|
+
};
|
|
8
|
+
export type CorrectComponentType<T> = (props: T, options: CorrectComponentOptions) => unknown;
|
|
9
|
+
export type Props = {
|
|
10
|
+
shouldScrollIntoView: boolean;
|
|
11
|
+
};
|
|
12
|
+
declare const Name = "collapsible-content";
|
|
13
|
+
declare const Component: CorrectComponentType<Props>;
|
|
14
|
+
type Props$1 = {
|
|
15
|
+
preventDefault: boolean;
|
|
16
|
+
};
|
|
17
|
+
declare const Name$1 = "collapsible-trigger";
|
|
18
|
+
declare const Component$1: CorrectComponentType<Props$1>;
|
|
19
|
+
export type CreateContextOptions = {
|
|
20
|
+
root: HTMLElement & ICustomElement;
|
|
21
|
+
isExpanded: boolean;
|
|
22
|
+
ariaExpanded: boolean;
|
|
23
|
+
isAnimating: boolean;
|
|
24
|
+
};
|
|
25
|
+
export type WalkableNode = Parameters<typeof provide>[2];
|
|
26
|
+
export type CollapsibleItemContext = ReturnType<typeof initializeCollapsibleItemContext>;
|
|
27
|
+
declare function initializeCollapsibleItemContext(props: CreateContextOptions): readonly [
|
|
28
|
+
{
|
|
29
|
+
isExpanded: boolean;
|
|
30
|
+
isAnimating: boolean;
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
readonly setElementState: (key: keyof Omit<CreateContextOptions, "root">, value: boolean | number | ((v: boolean | number) => boolean | number)) => void;
|
|
34
|
+
}
|
|
35
|
+
];
|
|
36
|
+
export declare const provideCollapsibleItemContext: (initialState: Omit<CreateContextOptions, "root">, element: WalkableNode) => CollapsibleItemContext;
|
|
37
|
+
export declare const useCollapsibleItemContext: (context: CollapsibleItemContext) => readonly [
|
|
38
|
+
{
|
|
39
|
+
isExpanded: boolean;
|
|
40
|
+
isAnimating: boolean;
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
readonly expand: () => void;
|
|
44
|
+
readonly collapse: () => void;
|
|
45
|
+
readonly toggle: () => void;
|
|
46
|
+
readonly finish: () => void;
|
|
47
|
+
}
|
|
48
|
+
];
|
|
49
|
+
export declare const useCollapsibleItem: (element: HTMLElement & ICustomElement) => readonly [
|
|
50
|
+
{
|
|
51
|
+
isExpanded: boolean;
|
|
52
|
+
isAnimating: boolean;
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
readonly expand: () => void;
|
|
56
|
+
readonly collapse: () => void;
|
|
57
|
+
readonly toggle: () => void;
|
|
58
|
+
readonly finish: () => void;
|
|
59
|
+
}
|
|
60
|
+
];
|
|
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
|
+
},
|
|
66
|
+
{
|
|
67
|
+
readonly setElementState: (key: keyof Omit<CreateContextOptions, "root">, value: boolean | number | ((v: boolean | number) => boolean | number)) => void;
|
|
68
|
+
}
|
|
69
|
+
], dependencies: D) => void | (() => void)) => void;
|
|
70
|
+
export declare const getCollapsibleItemContext: (element: Element) => readonly [
|
|
71
|
+
{
|
|
72
|
+
isExpanded: boolean;
|
|
73
|
+
isAnimating: boolean;
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
readonly expand: () => void;
|
|
77
|
+
readonly collapse: () => void;
|
|
78
|
+
readonly toggle: () => void;
|
|
79
|
+
readonly finish: () => void;
|
|
80
|
+
}
|
|
81
|
+
];
|
|
82
|
+
export type CollapsibleItemProps = Props;
|
|
83
|
+
export type CollapsibleTriggerProps = CollapsibleTrigger.Props;
|
|
84
|
+
export type CollapsibleContentProps = Props;
|
|
85
|
+
|
|
86
|
+
declare namespace CollapsibleTrigger {
|
|
87
|
+
export { Component$1 as Component, Name$1 as Name, Props$1 as Props };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
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';
|
|
4
|
+
|
|
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
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@brytdesigns/web-component-collapsible",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Headless collapsible 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.18.1",
|
|
24
|
+
"solid-element": "^1.9.1",
|
|
25
|
+
"solid-js": "^1.9.9",
|
|
26
|
+
"@brytdesigns/web-component-core": "1.1.5"
|
|
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
|
+
}
|