You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
59 lines
1.3 KiB
TypeScript
59 lines
1.3 KiB
TypeScript
import {
|
|
createSignal,
|
|
FlowComponent,
|
|
JSX,
|
|
mergeProps,
|
|
splitProps,
|
|
} from "solid-js";
|
|
import Collapsible from "./Collapsible";
|
|
|
|
const createAccordion = (defaultItem: number | null = 0) => {
|
|
const [item, setItem] = createSignal(defaultItem);
|
|
const AccordionItem: FlowComponent<
|
|
{
|
|
alignCenter?: boolean;
|
|
label?: JSX.Element;
|
|
item?: number;
|
|
} & Parameters<typeof Collapsible>[0]
|
|
> = (p) => {
|
|
const mprops = mergeProps({ alignCenter: true, item: Math.random() }, p);
|
|
const [props, rest] = splitProps(mprops, [
|
|
"alignCenter",
|
|
"item",
|
|
"label",
|
|
"children",
|
|
]);
|
|
|
|
return (
|
|
<Collapsible
|
|
class="border-b-0 last:border-b first:rounded-t last:rounded-b"
|
|
value={item() === props.item}
|
|
label={
|
|
<div
|
|
classList={{
|
|
"flex items-center gap-2": true,
|
|
"justify-center": props.alignCenter,
|
|
}}
|
|
>
|
|
{props.label}
|
|
</div>
|
|
}
|
|
onChange={(evt: any) =>
|
|
setItem(evt.currentTarget.checked && props.item)
|
|
}
|
|
{...rest}
|
|
>
|
|
{props.children}
|
|
</Collapsible>
|
|
);
|
|
};
|
|
|
|
return [AccordionItem, item, setItem] as [
|
|
typeof AccordionItem,
|
|
typeof item,
|
|
typeof setItem
|
|
];
|
|
};
|
|
|
|
export default createAccordion;
|