1
0
Fork 0
forked from 2sys/phonograph
phonograph/svelte/src/collapsible-menu.webc.svelte
Brent Schroeter f6118e4d5b misc cleanup
2025-09-14 16:22:42 -04:00

51 lines
1.3 KiB
Svelte

<svelte:options
customElement={{
props: { expanded: { type: "Boolean" } },
shadow: "none",
tag: "collapsible-menu",
}}
/>
<!--
@component
An accordion-style collapsible list, designed for vertical navigation.
It exposes two named slots, "summary" (clickable and always visible) and
"content" (visible only when expanded).
-->
<script lang="ts">
type Props = {
expanded?: boolean;
};
// `expanded` is marked as $bindable to make it clear that it takes the place
// of dynamic (that is, uncontrolled) internal state as well as an externally
// controllable and inspectable value. In practice this may be used to set an
// initial value for `expanded` without the need for, e.g., an
// `initial_expanded` prop as well as an internal variable to keep track of
// the actual current state.
let { expanded = $bindable(true) }: Props = $props();
function handle_summary_click() {
expanded = !expanded;
}
</script>
<div class="collapsible-menu">
<button
class="collapsible-menu__sumary"
onclick={handle_summary_click}
type="button"
>
<slot name="summary"></slot>
</button>
<div
class={[
"collapsible-menu__content",
expanded && "collapsible-menu__content--expanded",
]}
>
<slot name="content"></slot>
</div>
</div>