forked from 2sys/phonograph
52 lines
1.3 KiB
Svelte
52 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>
|