This repository has no description
1<script module lang="ts">
2 import { defineMeta } from "@storybook/addon-svelte-csf";
3 import ChevronDown from "$icon/chevron-down";
4 import Pencil from "$icon/pencil";
5 import Settings from "$icon/settings";
6 import LogOut from "$icon/log-out";
7 import Dropdown from "./Dropdown.svelte";
8 import DropdownItem from "./DropdownItem.svelte";
9
10 const { Story } = defineMeta({
11 title: "UI/Dropdown",
12 component: Dropdown,
13 tags: ["autodocs"]
14 });
15</script>
16
17<!-- Dropdown's `trigger` and `children` are snippet props, so the trigger content is
18 declared once below and passed by reference; every story renders via `asChild` rather
19 than through the args table. Click the trigger in the canvas to open the menu —
20 `open` is internal state, not a prop. -->
21
22{#snippet menuTrigger()}
23 <span>Menu</span>
24 <ChevronDown class="size-4" />
25{/snippet}
26
27{#snippet actionsTrigger()}
28 <span>Actions</span>
29 <ChevronDown class="size-4" />
30{/snippet}
31
32{#snippet firstTrigger()}
33 <span>First</span>
34 <ChevronDown class="size-4" />
35{/snippet}
36
37{#snippet secondTrigger()}
38 <span>Second</span>
39 <ChevronDown class="size-4" />
40{/snippet}
41
42<Story name="Plain trigger" asChild>
43 <Dropdown trigger={menuTrigger} label="Menu">
44 <DropdownItem icon={Pencil}>Edit</DropdownItem>
45 <DropdownItem icon={Settings}>Settings</DropdownItem>
46 <DropdownItem icon={LogOut} danger>Log out</DropdownItem>
47 </Dropdown>
48</Story>
49
50<Story name="Button trigger" asChild>
51 <Dropdown variant="button" trigger={actionsTrigger} label="Actions">
52 <DropdownItem icon={Pencil}>Edit</DropdownItem>
53 <DropdownItem icon={Settings}>Settings</DropdownItem>
54 </Dropdown>
55</Story>
56
57<!-- `size` goes straight to the trigger Button, so it drives the trigger's height,
58 padding and label size the same way it does on a standalone Button. -->
59<Story name="Button trigger sizes" asChild>
60 <div class="flex items-center gap-3">
61 <Dropdown variant="button" size="sm" trigger={actionsTrigger} label="Actions">
62 <DropdownItem icon={Pencil}>Edit</DropdownItem>
63 <DropdownItem icon={Settings}>Settings</DropdownItem>
64 </Dropdown>
65 <Dropdown variant="button" size="md" trigger={actionsTrigger} label="Actions">
66 <DropdownItem icon={Pencil}>Edit</DropdownItem>
67 <DropdownItem icon={Settings}>Settings</DropdownItem>
68 </Dropdown>
69 <Dropdown variant="button" size="lg" trigger={actionsTrigger} label="Actions">
70 <DropdownItem icon={Pencil}>Edit</DropdownItem>
71 <DropdownItem icon={Settings}>Settings</DropdownItem>
72 </Dropdown>
73 </div>
74</Story>
75
76<!-- `align="right"` anchors the menu's right edge to the trigger, for triggers near
77 the right edge of the viewport (e.g. the topbar profile menu). Default is left. -->
78<Story name="Right aligned" asChild>
79 <div class="flex justify-end">
80 <Dropdown align="right" trigger={menuTrigger} label="Menu">
81 <DropdownItem icon={Pencil}>Edit</DropdownItem>
82 <DropdownItem icon={Settings}>Settings</DropdownItem>
83 </Dropdown>
84 </div>
85</Story>
86
87<!-- DropdownItem states: plain text, with icon, as a link (href), and the danger variant. -->
88<Story name="Item states" asChild>
89 <Dropdown trigger={menuTrigger} label="Menu">
90 <DropdownItem>Plain item</DropdownItem>
91 <DropdownItem icon={Settings}>With icon</DropdownItem>
92 <DropdownItem href="/">Link item</DropdownItem>
93 <DropdownItem icon={LogOut} danger>Danger item</DropdownItem>
94 </Dropdown>
95</Story>
96
97<!-- Dropdowns sharing a `group` close their siblings when one opens. -->
98<Story name="Grouped" asChild>
99 <div class="flex gap-3">
100 <Dropdown group="story-group" trigger={firstTrigger} label="First">
101 <DropdownItem>One</DropdownItem>
102 <DropdownItem>Two</DropdownItem>
103 </Dropdown>
104 <Dropdown group="story-group" trigger={secondTrigger} label="Second">
105 <DropdownItem>Three</DropdownItem>
106 <DropdownItem>Four</DropdownItem>
107 </Dropdown>
108 </div>
109</Story>