@getmicdrop/svelte-components 5.3.2 → 5.3.6
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/calendar/Calendar/MiniMonthCalendar.svelte +10 -10
- package/dist/calendar/Calendar/MiniMonthCalendar.svelte.d.ts +6 -6
- package/dist/calendar/OrderSummary/OrderSummary.svelte +2 -2
- package/dist/calendar/OrderSummary/OrderSummary.svelte.d.ts +2 -2
- package/dist/calendar/PublicCard/PublicCard.svelte +2 -2
- package/dist/calendar/PublicCard/PublicCard.svelte.d.ts +2 -2
- package/dist/calendar/ShowCard/ShowCard.svelte +2 -2
- package/dist/calendar/ShowCard/ShowCard.svelte.d.ts +2 -2
- package/dist/patterns/navigation/Header.svelte +38 -27
- package/dist/patterns/page/PageLayout.svelte +1 -1
- package/dist/primitives/Accordion/Accordion.stories.svelte +75 -0
- package/dist/primitives/Accordion/Accordion.stories.svelte.d.ts +28 -0
- package/dist/primitives/Accordion/Accordion.stories.svelte.d.ts.map +1 -0
- package/dist/primitives/Alert/Alert.stories.svelte +88 -0
- package/dist/primitives/Alert/Alert.stories.svelte.d.ts +28 -0
- package/dist/primitives/Alert/Alert.stories.svelte.d.ts.map +1 -0
- package/dist/primitives/Avatar/Avatar.stories.svelte +94 -0
- package/dist/primitives/Avatar/Avatar.stories.svelte.d.ts +28 -0
- package/dist/primitives/Avatar/Avatar.stories.svelte.d.ts.map +1 -0
- package/dist/primitives/Breadcrumb/Breadcrumb.svelte +1 -1
- package/dist/primitives/Button/Button.svelte +87 -22
- package/dist/primitives/Button/Button.svelte.d.ts +4 -0
- package/dist/primitives/Button/Button.svelte.d.ts.map +1 -1
- package/dist/primitives/Checkbox/Checkbox.stories.svelte +84 -0
- package/dist/primitives/Checkbox/Checkbox.stories.svelte.d.ts +28 -0
- package/dist/primitives/Checkbox/Checkbox.stories.svelte.d.ts.map +1 -0
- package/dist/primitives/Drawer/Drawer.stories.svelte +100 -0
- package/dist/primitives/Drawer/Drawer.stories.svelte.d.ts +28 -0
- package/dist/primitives/Drawer/Drawer.stories.svelte.d.ts.map +1 -0
- package/dist/primitives/Dropdown/Dropdown.stories.svelte +137 -0
- package/dist/primitives/Dropdown/Dropdown.stories.svelte.d.ts +28 -0
- package/dist/primitives/Dropdown/Dropdown.stories.svelte.d.ts.map +1 -0
- package/dist/primitives/Dropdown/Dropdown.svelte +13 -15
- package/dist/primitives/Dropdown/Dropdown.svelte.d.ts.map +1 -1
- package/dist/primitives/Icons/Icon.svelte +2 -1
- package/dist/primitives/Icons/Icon.svelte.d.ts.map +1 -1
- package/dist/primitives/Input/Select.stories.svelte +112 -0
- package/dist/primitives/Input/Select.stories.svelte.d.ts +28 -0
- package/dist/primitives/Input/Select.stories.svelte.d.ts.map +1 -0
- package/dist/primitives/Input/Textarea.stories.svelte +137 -0
- package/dist/primitives/Input/Textarea.stories.svelte.d.ts +28 -0
- package/dist/primitives/Input/Textarea.stories.svelte.d.ts.map +1 -0
- package/dist/primitives/Pagination/Pagination.stories.svelte +76 -0
- package/dist/primitives/Pagination/Pagination.stories.svelte.d.ts +28 -0
- package/dist/primitives/Pagination/Pagination.stories.svelte.d.ts.map +1 -0
- package/dist/primitives/Pagination/Pagination.svelte +3 -3
- package/dist/primitives/Pagination/Pagination.svelte.d.ts +1 -1
- package/dist/primitives/Radio/Radio.stories.svelte +80 -0
- package/dist/primitives/Radio/Radio.stories.svelte.d.ts +28 -0
- package/dist/primitives/Radio/Radio.stories.svelte.d.ts.map +1 -0
- package/dist/primitives/Skeleton/Skeleton.stories.svelte +151 -0
- package/dist/primitives/Skeleton/Skeleton.stories.svelte.d.ts +28 -0
- package/dist/primitives/Skeleton/Skeleton.stories.svelte.d.ts.map +1 -0
- package/dist/primitives/Tabs/Tabs.stories.svelte +112 -0
- package/dist/primitives/Tabs/Tabs.stories.svelte.d.ts +28 -0
- package/dist/primitives/Tabs/Tabs.stories.svelte.d.ts.map +1 -0
- package/dist/primitives/Tabs/Tabs.svelte +1 -1
- package/dist/primitives/Toggle.svelte +4 -4
- package/dist/primitives/ValidationError.spec.js +25 -1
- package/dist/primitives/ValidationError.stories.svelte +24 -0
- package/dist/primitives/ValidationError.stories.svelte.d.ts.map +1 -1
- package/dist/primitives/ValidationError.svelte +8 -4
- package/dist/primitives/ValidationError.svelte.d.ts +2 -0
- package/dist/primitives/ValidationError.svelte.d.ts.map +1 -1
- package/dist/recipes/CropImage/CropImage.svelte +3 -3
- package/dist/recipes/SuperLogin/SuperLogin.svelte +34 -23
- package/dist/recipes/SuperLogin/SuperLogin.svelte.d.ts.map +1 -1
- package/dist/recipes/feedback/EmptyState/EmptyState.svelte +2 -1
- package/dist/recipes/feedback/EmptyState/EmptyState.svelte.d.ts.map +1 -1
- package/dist/recipes/inputs/MultiSelect.svelte +2 -2
- package/dist/recipes/modals/InputModal.svelte +2 -1
- package/dist/recipes/modals/InputModal.svelte.d.ts.map +1 -1
- package/dist/stories/ComponentConsolidation.stories.svelte +276 -188
- package/dist/stories/ComponentConsolidation.stories.svelte.d.ts.map +1 -1
- package/dist/stories/PatternsGallery.stories.svelte +19 -0
- package/dist/stories/PatternsGallery.stories.svelte.d.ts +28 -0
- package/dist/stories/PatternsGallery.stories.svelte.d.ts.map +1 -0
- package/dist/stories/PatternsGallery.svelte +388 -0
- package/dist/stories/PatternsGallery.svelte.d.ts +4 -0
- package/dist/stories/PatternsGallery.svelte.d.ts.map +1 -0
- package/dist/stories/PrimitivesGallery.stories.svelte +19 -0
- package/dist/stories/PrimitivesGallery.stories.svelte.d.ts +28 -0
- package/dist/stories/PrimitivesGallery.stories.svelte.d.ts.map +1 -0
- package/dist/stories/PrimitivesGallery.svelte +752 -0
- package/dist/stories/PrimitivesGallery.svelte.d.ts +4 -0
- package/dist/stories/PrimitivesGallery.svelte.d.ts.map +1 -0
- package/dist/stories/RecipesGallery.stories.svelte +19 -0
- package/dist/stories/RecipesGallery.stories.svelte.d.ts +28 -0
- package/dist/stories/RecipesGallery.stories.svelte.d.ts.map +1 -0
- package/dist/stories/RecipesGallery.svelte +441 -0
- package/dist/stories/RecipesGallery.svelte.d.ts +4 -0
- package/dist/stories/RecipesGallery.svelte.d.ts.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export default Avatar;
|
|
2
|
+
type Avatar = SvelteComponent<{
|
|
3
|
+
[x: string]: never;
|
|
4
|
+
}, {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
}, {}> & {
|
|
7
|
+
$$bindings?: string | undefined;
|
|
8
|
+
};
|
|
9
|
+
declare const Avatar: $$__sveltets_2_IsomorphicComponent<{
|
|
10
|
+
[x: string]: never;
|
|
11
|
+
}, {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
}, {}, {}, string>;
|
|
14
|
+
import Avatar from './Avatar.svelte';
|
|
15
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
16
|
+
new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
|
|
17
|
+
$$bindings?: Bindings;
|
|
18
|
+
} & Exports;
|
|
19
|
+
(internal: unknown, props: {
|
|
20
|
+
$$events?: Events;
|
|
21
|
+
$$slots?: Slots;
|
|
22
|
+
}): Exports & {
|
|
23
|
+
$set?: any;
|
|
24
|
+
$on?: any;
|
|
25
|
+
};
|
|
26
|
+
z_$$bindings?: Bindings;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=Avatar.stories.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Avatar.stories.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Avatar/Avatar.stories.svelte.js"],"names":[],"mappings":";;;;;;;;AA4GA;;;;mBAAkH;mBAxG7F,iBAAiB;6CA+FO,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,OAAO,OAAO,QAAQ;IAC3L,cAAc,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,WAAW,OAAO,SAAS;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,eAAe,QAAQ,CAAC"}
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
}
|
|
36
36
|
</script>
|
|
37
37
|
|
|
38
|
-
<div class="flex flex-col gap-
|
|
38
|
+
<div class="flex flex-col items-start gap-2 min-w-0">
|
|
39
39
|
{#if data.length > 0}
|
|
40
40
|
<nav class="flex items-center text-sm font-medium text-gray-500 dark:text-gray-400 {className}" aria-label="Breadcrumb">
|
|
41
41
|
<ol class="inline-flex items-center space-x-1 md:space-x-2 rtl:space-x-reverse flex-wrap">
|
|
@@ -13,6 +13,11 @@
|
|
|
13
13
|
* - ghost-red: Destructive text button
|
|
14
14
|
* - icon: Icon-only button
|
|
15
15
|
* - toggle: Toggle/pill button
|
|
16
|
+
* - avatar: Avatar/image trigger button (no padding, opacity hover)
|
|
17
|
+
* - menu-item: Dropdown/sheet menu item (full width, left-aligned)
|
|
18
|
+
* - menu-item-danger: Destructive menu item (red text)
|
|
19
|
+
* - card: Selectable card button (bordered, for list selections)
|
|
20
|
+
* - sidebar-toggle: Compact pill for sidebar expand/collapse
|
|
16
21
|
*
|
|
17
22
|
* Sizes (Flowbite native): xs, sm, md, lg, xl
|
|
18
23
|
*/
|
|
@@ -27,7 +32,9 @@
|
|
|
27
32
|
successText?: string,
|
|
28
33
|
active?: boolean,
|
|
29
34
|
href?: string | null,
|
|
35
|
+
type?: 'button' | 'submit' | 'reset',
|
|
30
36
|
children?: any,
|
|
37
|
+
trailing?: any,
|
|
31
38
|
class?: string,
|
|
32
39
|
onclick?: (e: MouseEvent) => void,
|
|
33
40
|
[key: string]: any
|
|
@@ -41,7 +48,9 @@
|
|
|
41
48
|
successText = "",
|
|
42
49
|
active = false,
|
|
43
50
|
href = null,
|
|
51
|
+
type = "button",
|
|
44
52
|
children,
|
|
53
|
+
trailing,
|
|
45
54
|
class: className = "",
|
|
46
55
|
onclick,
|
|
47
56
|
...restProps
|
|
@@ -82,55 +91,108 @@
|
|
|
82
91
|
lg: "p-3",
|
|
83
92
|
};
|
|
84
93
|
|
|
85
|
-
//
|
|
86
|
-
|
|
94
|
+
// Avatar variant sizes (no padding, just min dimensions)
|
|
95
|
+
const avatarSizes = {
|
|
96
|
+
sm: "min-w-8 min-h-8",
|
|
97
|
+
md: "min-w-10 min-h-10",
|
|
98
|
+
lg: "min-w-12 min-h-12",
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// Menu item sizes
|
|
102
|
+
const menuItemSizes = {
|
|
103
|
+
sm: "py-2 px-4 text-sm",
|
|
104
|
+
md: "py-3 px-4 text-sm",
|
|
105
|
+
lg: "py-4 px-6 text-base",
|
|
106
|
+
nav: "py-2 px-3 text-base font-normal",
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// Card sizes (larger padding for card-like buttons)
|
|
110
|
+
const cardSizes = {
|
|
111
|
+
sm: "p-3 text-sm",
|
|
112
|
+
md: "p-4 text-sm",
|
|
113
|
+
lg: "p-5 text-base",
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// Variant classes with all states in Tailwind (no focus rings - design decision)
|
|
87
117
|
const variantClasses = {
|
|
88
|
-
default: "text-white bg-blue-700 border border-blue-700 hover:bg-blue-800
|
|
89
|
-
alternative: "text-gray-900 bg-white border border-gray-200 hover:bg-gray-100 hover:text-blue-700
|
|
90
|
-
outline: "text-blue-700 bg-transparent border border-blue-700 hover:text-white hover:bg-blue-800
|
|
91
|
-
red: "text-white bg-red-700 border border-red-700 hover:bg-red-800
|
|
92
|
-
"red-outline": "text-red-700 bg-transparent border border-red-700 hover:text-white hover:bg-red-800
|
|
93
|
-
ghost: "text-gray-500 bg-transparent border-transparent hover:bg-gray-100 hover:text-gray-900
|
|
94
|
-
"ghost-red": "text-red-700 bg-transparent border-transparent hover:bg-red-100 hover:text-red-900
|
|
118
|
+
default: "text-white bg-blue-700 border border-blue-700 hover:bg-blue-800 dark:bg-blue-600 dark:hover:bg-blue-700",
|
|
119
|
+
alternative: "text-gray-900 bg-white border border-gray-200 hover:bg-gray-100 hover:text-blue-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700",
|
|
120
|
+
outline: "text-blue-700 bg-transparent border border-blue-700 hover:text-white hover:bg-blue-800 dark:border-blue-500 dark:text-blue-500 dark:hover:text-white dark:hover:bg-blue-500",
|
|
121
|
+
red: "text-white bg-red-700 border border-red-700 hover:bg-red-800 dark:bg-red-600 dark:hover:bg-red-700",
|
|
122
|
+
"red-outline": "text-red-700 bg-transparent border border-red-700 hover:text-white hover:bg-red-800 dark:border-red-500 dark:text-red-500 dark:hover:text-white dark:hover:bg-red-600",
|
|
123
|
+
ghost: "text-gray-500 bg-transparent border-transparent hover:bg-gray-100 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white",
|
|
124
|
+
"ghost-red": "text-red-700 bg-transparent border-transparent hover:bg-red-100 hover:text-red-900 dark:text-red-500 dark:hover:bg-red-900/50 dark:hover:text-red-400",
|
|
95
125
|
link: "text-blue-700 bg-transparent border-transparent hover:underline dark:text-blue-500",
|
|
96
126
|
icon: "text-gray-500 bg-transparent border-transparent hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700",
|
|
97
|
-
toggle: "text-gray-500 bg-gray-100 border border-gray-200 hover:bg-gray-200
|
|
127
|
+
toggle: "text-gray-500 bg-gray-100 border border-gray-200 hover:bg-gray-200 dark:bg-gray-700 dark:text-gray-400 dark:border-gray-600 dark:hover:bg-gray-600",
|
|
98
128
|
success: "text-white bg-green-600 border border-green-600",
|
|
129
|
+
// Avatar/image trigger - no background, opacity hover
|
|
130
|
+
avatar: "bg-transparent border-transparent hover:opacity-80",
|
|
131
|
+
// Menu items - full width, left-aligned, for dropdowns/sheets and sidebar nav
|
|
132
|
+
"menu-item": "w-full text-left text-gray-900 bg-transparent border-transparent hover:bg-gray-100 dark:text-white dark:hover:bg-gray-600",
|
|
133
|
+
// Danger menu item - red text version
|
|
134
|
+
"menu-item-danger": "w-full text-left text-red-600 bg-transparent border-transparent hover:bg-red-50 dark:text-red-500 dark:hover:bg-gray-700",
|
|
135
|
+
// Selectable card - bordered card-like button for list selections
|
|
136
|
+
card: "w-full text-left text-gray-900 bg-white border border-gray-300 hover:bg-gray-50 dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700",
|
|
137
|
+
// Search result item - blue hover for search dropdowns
|
|
138
|
+
"search-result": "w-full text-left text-gray-900 bg-transparent border-transparent hover:bg-blue-50 focus:bg-blue-50 dark:text-white dark:hover:bg-blue-900/20 dark:focus:bg-blue-900/20",
|
|
139
|
+
// Sidebar toggle - compact pill for sidebar expand/collapse
|
|
140
|
+
"sidebar-toggle": "w-6 h-7 text-gray-900 bg-blue-100 border border-blue-200 hover:bg-blue-200 shadow-lg dark:text-white dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700",
|
|
99
141
|
};
|
|
100
142
|
|
|
101
|
-
// Active state classes for ghost and
|
|
143
|
+
// Active state classes for ghost, toggle, and menu-item
|
|
102
144
|
const activeClasses = {
|
|
103
145
|
ghost: "text-blue-700 bg-blue-50 dark:text-white dark:bg-gray-900",
|
|
104
146
|
toggle: "text-white bg-blue-600 border-blue-600 hover:bg-blue-700 dark:bg-blue-600 dark:hover:bg-blue-700",
|
|
147
|
+
"menu-item": "bg-blue-50 dark:bg-gray-700",
|
|
105
148
|
};
|
|
106
149
|
|
|
107
150
|
// Disabled classes
|
|
108
151
|
const disabledClasses = "bg-gray-200 border-gray-200 text-gray-400 cursor-not-allowed dark:bg-gray-700 dark:border-gray-700 dark:text-gray-500";
|
|
109
152
|
|
|
110
|
-
let sizeClass = $derived(
|
|
111
|
-
resolvedVariant === "icon"
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
153
|
+
let sizeClass = $derived((() => {
|
|
154
|
+
if (resolvedVariant === "icon") return iconSizes[size] || iconSizes.sm;
|
|
155
|
+
if (resolvedVariant === "avatar") return avatarSizes[size] || avatarSizes.md;
|
|
156
|
+
if (resolvedVariant === "menu-item" || resolvedVariant === "menu-item-danger" || resolvedVariant === "search-result") {
|
|
157
|
+
return menuItemSizes[size] || menuItemSizes.md;
|
|
158
|
+
}
|
|
159
|
+
if (resolvedVariant === "card") return cardSizes[size] || cardSizes.md;
|
|
160
|
+
if (resolvedVariant === "link") return "text-sm";
|
|
161
|
+
if (resolvedVariant === "sidebar-toggle") return ""; // Fixed dimensions in variant
|
|
162
|
+
return sizeClasses[size] || sizeClasses.md;
|
|
163
|
+
})());
|
|
117
164
|
|
|
118
165
|
let variantClass = $derived((() => {
|
|
119
166
|
if (success) return variantClasses.success;
|
|
120
167
|
if (disabled && !loading && !success) return disabledClasses;
|
|
121
|
-
if (active && (resolvedVariant === "ghost" || resolvedVariant === "toggle")) {
|
|
122
|
-
return activeClasses[resolvedVariant];
|
|
168
|
+
if (active && (resolvedVariant === "ghost" || resolvedVariant === "toggle" || resolvedVariant === "menu-item")) {
|
|
169
|
+
return (activeClasses[resolvedVariant] || "") + " " + (variantClasses[resolvedVariant] || "");
|
|
123
170
|
}
|
|
124
171
|
return variantClasses[resolvedVariant] || variantClasses.default;
|
|
125
172
|
})());
|
|
126
173
|
|
|
174
|
+
// Menu items, cards, and search results need left alignment, others are centered
|
|
175
|
+
let isLeftAligned = $derived(
|
|
176
|
+
resolvedVariant === "menu-item" ||
|
|
177
|
+
resolvedVariant === "menu-item-danger" ||
|
|
178
|
+
resolvedVariant === "card" ||
|
|
179
|
+
resolvedVariant === "search-result"
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
// Use justify-between when there's trailing content (e.g., chevrons in nav items)
|
|
183
|
+
let hasTrailing = $derived(typeof trailing === 'function' || trailing);
|
|
184
|
+
|
|
127
185
|
let buttonClasses = $derived([
|
|
128
186
|
"relative",
|
|
129
|
-
|
|
187
|
+
isLeftAligned
|
|
188
|
+
? (hasTrailing ? "flex items-center justify-between" : "flex items-center justify-start")
|
|
189
|
+
: "inline-flex items-center justify-center",
|
|
130
190
|
"rounded-lg",
|
|
131
191
|
"font-medium leading-none",
|
|
132
192
|
"focus:outline-none",
|
|
133
|
-
|
|
193
|
+
// Apple-style micro-interactions (only when not disabled)
|
|
194
|
+
"transition-all duration-150 ease-out",
|
|
195
|
+
effectiveDisabled ? "" : "active:scale-[0.97] active:opacity-90",
|
|
134
196
|
"select-none",
|
|
135
197
|
sizeClass,
|
|
136
198
|
variantClass,
|
|
@@ -152,9 +214,11 @@
|
|
|
152
214
|
<span class="inline-flex items-center gap-1.5" class:invisible={loading || success}>
|
|
153
215
|
{#if typeof children === 'function'}{@render children()}{:else if children}{children}{/if}
|
|
154
216
|
</span>
|
|
217
|
+
{#if typeof trailing === 'function'}{@render trailing()}{:else if trailing}{trailing}{/if}
|
|
155
218
|
</a>
|
|
156
219
|
{:else}
|
|
157
220
|
<button
|
|
221
|
+
{type}
|
|
158
222
|
class="{buttonClasses} {loading ? 'loading-pulse' : ''}"
|
|
159
223
|
disabled={effectiveDisabled}
|
|
160
224
|
{onclick}
|
|
@@ -166,6 +230,7 @@
|
|
|
166
230
|
<span class="inline-flex items-center gap-1.5" class:invisible={loading || success}>
|
|
167
231
|
{#if typeof children === 'function'}{@render children()}{:else if children}{children}{/if}
|
|
168
232
|
</span>
|
|
233
|
+
{#if typeof trailing === 'function'}{@render trailing()}{:else if trailing}{trailing}{/if}
|
|
169
234
|
{#if success}
|
|
170
235
|
<span class="absolute inset-0 flex items-center justify-center gap-2">
|
|
171
236
|
<CheckOutline class="w-5 h-5" />
|
|
@@ -11,7 +11,9 @@ type Button = {
|
|
|
11
11
|
successText?: string | undefined;
|
|
12
12
|
active?: boolean | undefined;
|
|
13
13
|
href?: string | null | undefined;
|
|
14
|
+
type?: "button" | "submit" | "reset" | undefined;
|
|
14
15
|
children?: any;
|
|
16
|
+
trailing?: any;
|
|
15
17
|
class?: string | undefined;
|
|
16
18
|
onclick?: ((e: MouseEvent) => void) | undefined;
|
|
17
19
|
}>): void;
|
|
@@ -26,7 +28,9 @@ declare const Button: import("svelte").Component<{
|
|
|
26
28
|
successText?: string;
|
|
27
29
|
active?: boolean;
|
|
28
30
|
href?: string | null;
|
|
31
|
+
type?: "button" | "submit" | "reset";
|
|
29
32
|
children?: any;
|
|
33
|
+
trailing?: any;
|
|
30
34
|
class?: string;
|
|
31
35
|
onclick?: (e: MouseEvent) => void;
|
|
32
36
|
}, {}, "">;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Button/Button.svelte.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Button.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Button/Button.svelte.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAgQA;;cAfc,MAAM;WACT,MAAM;eACF,OAAO;cACR,OAAO;cACP,OAAO;kBACH,MAAM;aACX,OAAO;WACT,MAAM,GAAG,IAAI;WACb,QAAQ,GAAG,QAAQ,GAAG,OAAO;eACzB,GAAG;eACH,GAAG;YACN,MAAM;cACJ,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI;WAGgB"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import Checkbox from './Checkbox.svelte';
|
|
4
|
+
|
|
5
|
+
const { Story } = defineMeta({
|
|
6
|
+
title: 'Primitives/Checkbox',
|
|
7
|
+
component: Checkbox,
|
|
8
|
+
tags: ['autodocs'],
|
|
9
|
+
argTypes: {
|
|
10
|
+
label: { control: 'text' },
|
|
11
|
+
checked: { control: 'boolean' },
|
|
12
|
+
disabled: { control: 'boolean' },
|
|
13
|
+
required: { control: 'boolean' },
|
|
14
|
+
},
|
|
15
|
+
parameters: {
|
|
16
|
+
docs: {
|
|
17
|
+
description: {
|
|
18
|
+
component: 'Checkbox input component for boolean selections.',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
let checked = $state(false);
|
|
25
|
+
let checkedItems = $state({ terms: false, updates: true, marketing: false });
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<Story name="Default" args={{ label: 'Accept terms' }}>
|
|
29
|
+
{#snippet template(args)}
|
|
30
|
+
<Checkbox {...args} />
|
|
31
|
+
{/snippet}
|
|
32
|
+
</Story>
|
|
33
|
+
|
|
34
|
+
<Story name="Checked" args={{ label: 'Already checked', checked: true }}>
|
|
35
|
+
{#snippet template(args)}
|
|
36
|
+
<Checkbox {...args} />
|
|
37
|
+
{/snippet}
|
|
38
|
+
</Story>
|
|
39
|
+
|
|
40
|
+
<Story name="Disabled" args={{ label: 'Disabled checkbox', disabled: true }}>
|
|
41
|
+
{#snippet template(args)}
|
|
42
|
+
<Checkbox {...args} />
|
|
43
|
+
{/snippet}
|
|
44
|
+
</Story>
|
|
45
|
+
|
|
46
|
+
<Story name="Disabled Checked" args={{ label: 'Disabled and checked', disabled: true, checked: true }}>
|
|
47
|
+
{#snippet template(args)}
|
|
48
|
+
<Checkbox {...args} />
|
|
49
|
+
{/snippet}
|
|
50
|
+
</Story>
|
|
51
|
+
|
|
52
|
+
<Story name="Interactive">
|
|
53
|
+
{#snippet template()}
|
|
54
|
+
<div class="space-y-4">
|
|
55
|
+
<Checkbox label="Click to toggle" bind:checked={checked} />
|
|
56
|
+
<p class="text-sm text-gray-500">Checked: {checked ? 'Yes' : 'No'}</p>
|
|
57
|
+
</div>
|
|
58
|
+
{/snippet}
|
|
59
|
+
</Story>
|
|
60
|
+
|
|
61
|
+
<Story name="Group">
|
|
62
|
+
{#snippet template()}
|
|
63
|
+
<div class="space-y-3">
|
|
64
|
+
<p class="text-sm font-medium text-gray-700">Notification preferences:</p>
|
|
65
|
+
<Checkbox label="I accept the terms and conditions" bind:checked={checkedItems.terms} />
|
|
66
|
+
<Checkbox label="Send me product updates" bind:checked={checkedItems.updates} />
|
|
67
|
+
<Checkbox label="Send me marketing emails" bind:checked={checkedItems.marketing} />
|
|
68
|
+
<p class="text-xs text-gray-500 mt-2">
|
|
69
|
+
Selected: {Object.entries(checkedItems).filter(([_, v]) => v).map(([k]) => k).join(', ') || 'none'}
|
|
70
|
+
</p>
|
|
71
|
+
</div>
|
|
72
|
+
{/snippet}
|
|
73
|
+
</Story>
|
|
74
|
+
|
|
75
|
+
<Story name="All States">
|
|
76
|
+
{#snippet template()}
|
|
77
|
+
<div class="space-y-4">
|
|
78
|
+
<Checkbox label="Unchecked" />
|
|
79
|
+
<Checkbox label="Checked" checked={true} />
|
|
80
|
+
<Checkbox label="Disabled unchecked" disabled />
|
|
81
|
+
<Checkbox label="Disabled checked" disabled checked={true} />
|
|
82
|
+
</div>
|
|
83
|
+
{/snippet}
|
|
84
|
+
</Story>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export default Checkbox;
|
|
2
|
+
type Checkbox = SvelteComponent<{
|
|
3
|
+
[x: string]: never;
|
|
4
|
+
}, {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
}, {}> & {
|
|
7
|
+
$$bindings?: string | undefined;
|
|
8
|
+
};
|
|
9
|
+
declare const Checkbox: $$__sveltets_2_IsomorphicComponent<{
|
|
10
|
+
[x: string]: never;
|
|
11
|
+
}, {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
}, {}, {}, string>;
|
|
14
|
+
import Checkbox from './Checkbox.svelte';
|
|
15
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
16
|
+
new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
|
|
17
|
+
$$bindings?: Bindings;
|
|
18
|
+
} & Exports;
|
|
19
|
+
(internal: unknown, props: {
|
|
20
|
+
$$events?: Events;
|
|
21
|
+
$$slots?: Slots;
|
|
22
|
+
}): Exports & {
|
|
23
|
+
$set?: any;
|
|
24
|
+
$on?: any;
|
|
25
|
+
};
|
|
26
|
+
z_$$bindings?: Bindings;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=Checkbox.stories.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Checkbox.stories.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Checkbox/Checkbox.stories.svelte.js"],"names":[],"mappings":";;;;;;;;AAkGA;;;;mBAAoH;qBA9F7F,mBAAmB;6CAqFG,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,OAAO,OAAO,QAAQ;IAC3L,cAAc,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,WAAW,OAAO,SAAS;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import Drawer from './Drawer.svelte';
|
|
4
|
+
import Button from '../Button/Button.svelte';
|
|
5
|
+
|
|
6
|
+
const { Story } = defineMeta({
|
|
7
|
+
title: 'Primitives/Drawer',
|
|
8
|
+
component: Drawer,
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
argTypes: {
|
|
11
|
+
position: {
|
|
12
|
+
control: 'select',
|
|
13
|
+
options: ['left', 'right'],
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
parameters: {
|
|
17
|
+
docs: {
|
|
18
|
+
description: {
|
|
19
|
+
component: 'Sliding panel overlay that appears from the side of the screen.',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
let openLeft = $state(false);
|
|
26
|
+
let openRight = $state(false);
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<Story name="Right (Default)">
|
|
30
|
+
{#snippet template()}
|
|
31
|
+
<div>
|
|
32
|
+
<Button onclick={() => openRight = true}>Open Right Drawer</Button>
|
|
33
|
+
<Drawer bind:open={openRight} position="right">
|
|
34
|
+
<div class="p-6">
|
|
35
|
+
<h2 class="text-xl font-semibold mb-4">Drawer Title</h2>
|
|
36
|
+
<p class="text-gray-600 mb-4">
|
|
37
|
+
This drawer slides in from the right side. Click outside or use the close button to dismiss.
|
|
38
|
+
</p>
|
|
39
|
+
<div class="space-y-4">
|
|
40
|
+
<p class="text-sm text-gray-500">Some content here...</p>
|
|
41
|
+
<Button onclick={() => openRight = false}>Close</Button>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</Drawer>
|
|
45
|
+
</div>
|
|
46
|
+
{/snippet}
|
|
47
|
+
</Story>
|
|
48
|
+
|
|
49
|
+
<Story name="Left">
|
|
50
|
+
{#snippet template()}
|
|
51
|
+
<div>
|
|
52
|
+
<Button onclick={() => openLeft = true}>Open Left Drawer</Button>
|
|
53
|
+
<Drawer bind:open={openLeft} position="left">
|
|
54
|
+
<div class="p-6">
|
|
55
|
+
<h2 class="text-xl font-semibold mb-4">Navigation</h2>
|
|
56
|
+
<nav class="space-y-2">
|
|
57
|
+
<a href="#" class="block px-3 py-2 rounded hover:bg-gray-100">Dashboard</a>
|
|
58
|
+
<a href="#" class="block px-3 py-2 rounded hover:bg-gray-100">Shows</a>
|
|
59
|
+
<a href="#" class="block px-3 py-2 rounded hover:bg-gray-100">Performers</a>
|
|
60
|
+
<a href="#" class="block px-3 py-2 rounded hover:bg-gray-100">Settings</a>
|
|
61
|
+
</nav>
|
|
62
|
+
<div class="mt-6">
|
|
63
|
+
<Button variant="ghost" onclick={() => openLeft = false}>Close</Button>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
</Drawer>
|
|
67
|
+
</div>
|
|
68
|
+
{/snippet}
|
|
69
|
+
</Story>
|
|
70
|
+
|
|
71
|
+
<Story name="With Form">
|
|
72
|
+
{#snippet template()}
|
|
73
|
+
<div>
|
|
74
|
+
<Button onclick={() => openRight = true}>Edit Profile</Button>
|
|
75
|
+
<Drawer bind:open={openRight} position="right">
|
|
76
|
+
<div class="p-6">
|
|
77
|
+
<h2 class="text-xl font-semibold mb-6">Edit Profile</h2>
|
|
78
|
+
<form class="space-y-4">
|
|
79
|
+
<div>
|
|
80
|
+
<label class="block text-sm font-medium mb-1">Name</label>
|
|
81
|
+
<input type="text" class="w-full border rounded px-3 py-2" placeholder="John Doe" />
|
|
82
|
+
</div>
|
|
83
|
+
<div>
|
|
84
|
+
<label class="block text-sm font-medium mb-1">Email</label>
|
|
85
|
+
<input type="email" class="w-full border rounded px-3 py-2" placeholder="john@example.com" />
|
|
86
|
+
</div>
|
|
87
|
+
<div>
|
|
88
|
+
<label class="block text-sm font-medium mb-1">Bio</label>
|
|
89
|
+
<textarea class="w-full border rounded px-3 py-2" rows="3" placeholder="Tell us about yourself"></textarea>
|
|
90
|
+
</div>
|
|
91
|
+
</form>
|
|
92
|
+
<div class="flex gap-2 mt-6">
|
|
93
|
+
<Button variant="ghost" onclick={() => openRight = false}>Cancel</Button>
|
|
94
|
+
<Button onclick={() => openRight = false}>Save Changes</Button>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
</Drawer>
|
|
98
|
+
</div>
|
|
99
|
+
{/snippet}
|
|
100
|
+
</Story>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export default Drawer;
|
|
2
|
+
type Drawer = SvelteComponent<{
|
|
3
|
+
[x: string]: never;
|
|
4
|
+
}, {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
}, {}> & {
|
|
7
|
+
$$bindings?: string | undefined;
|
|
8
|
+
};
|
|
9
|
+
declare const Drawer: $$__sveltets_2_IsomorphicComponent<{
|
|
10
|
+
[x: string]: never;
|
|
11
|
+
}, {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
}, {}, {}, string>;
|
|
14
|
+
import Drawer from './Drawer.svelte';
|
|
15
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
16
|
+
new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
|
|
17
|
+
$$bindings?: Bindings;
|
|
18
|
+
} & Exports;
|
|
19
|
+
(internal: unknown, props: {
|
|
20
|
+
$$events?: Events;
|
|
21
|
+
$$slots?: Slots;
|
|
22
|
+
}): Exports & {
|
|
23
|
+
$set?: any;
|
|
24
|
+
$on?: any;
|
|
25
|
+
};
|
|
26
|
+
z_$$bindings?: Bindings;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=Drawer.stories.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Drawer.stories.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Drawer/Drawer.stories.svelte.js"],"names":[],"mappings":";;;;;;;;AAkHA;;;;mBAAkH;mBA9G7F,iBAAiB;6CAqGO,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,OAAO,OAAO,QAAQ;IAC3L,cAAc,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,WAAW,OAAO,SAAS;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import Dropdown from './Dropdown.svelte';
|
|
4
|
+
import DropdownItem from './DropdownItem.svelte';
|
|
5
|
+
import Button from '../Button/Button.svelte';
|
|
6
|
+
|
|
7
|
+
const { Story } = defineMeta({
|
|
8
|
+
title: 'Primitives/Dropdown',
|
|
9
|
+
component: Dropdown,
|
|
10
|
+
tags: ['autodocs'],
|
|
11
|
+
parameters: {
|
|
12
|
+
docs: {
|
|
13
|
+
description: {
|
|
14
|
+
component: 'Dropdown menu component for actions and navigation.',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
let open1 = $state(false);
|
|
21
|
+
let open2 = $state(false);
|
|
22
|
+
let open3 = $state(false);
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<Story name="Default">
|
|
26
|
+
{#snippet template()}
|
|
27
|
+
<div class="relative inline-block">
|
|
28
|
+
<Button onclick={() => open1 = !open1}>
|
|
29
|
+
Options ▼
|
|
30
|
+
</Button>
|
|
31
|
+
{#if open1}
|
|
32
|
+
<Dropdown class="absolute mt-1 z-10">
|
|
33
|
+
<DropdownItem onclick={() => { console.log('Edit'); open1 = false; }}>Edit</DropdownItem>
|
|
34
|
+
<DropdownItem onclick={() => { console.log('Duplicate'); open1 = false; }}>Duplicate</DropdownItem>
|
|
35
|
+
<DropdownItem onclick={() => { console.log('Archive'); open1 = false; }}>Archive</DropdownItem>
|
|
36
|
+
</Dropdown>
|
|
37
|
+
{/if}
|
|
38
|
+
</div>
|
|
39
|
+
{/snippet}
|
|
40
|
+
</Story>
|
|
41
|
+
|
|
42
|
+
<Story name="With Dividers">
|
|
43
|
+
{#snippet template()}
|
|
44
|
+
<div class="relative inline-block">
|
|
45
|
+
<Button onclick={() => open2 = !open2}>
|
|
46
|
+
Actions ▼
|
|
47
|
+
</Button>
|
|
48
|
+
{#if open2}
|
|
49
|
+
<Dropdown class="absolute mt-1 z-10">
|
|
50
|
+
<DropdownItem onclick={() => open2 = false}>View Details</DropdownItem>
|
|
51
|
+
<DropdownItem onclick={() => open2 = false}>Edit</DropdownItem>
|
|
52
|
+
<div class="border-t my-1"></div>
|
|
53
|
+
<DropdownItem onclick={() => open2 = false}>Share</DropdownItem>
|
|
54
|
+
<DropdownItem onclick={() => open2 = false}>Export</DropdownItem>
|
|
55
|
+
<div class="border-t my-1"></div>
|
|
56
|
+
<DropdownItem onclick={() => open2 = false} class="text-red-600">Delete</DropdownItem>
|
|
57
|
+
</Dropdown>
|
|
58
|
+
{/if}
|
|
59
|
+
</div>
|
|
60
|
+
{/snippet}
|
|
61
|
+
</Story>
|
|
62
|
+
|
|
63
|
+
<Story name="Right Aligned">
|
|
64
|
+
{#snippet template()}
|
|
65
|
+
<div class="flex justify-end">
|
|
66
|
+
<div class="relative inline-block">
|
|
67
|
+
<Button onclick={() => open3 = !open3}>
|
|
68
|
+
Menu ▼
|
|
69
|
+
</Button>
|
|
70
|
+
{#if open3}
|
|
71
|
+
<Dropdown class="absolute mt-1 right-0 z-10">
|
|
72
|
+
<DropdownItem onclick={() => open3 = false}>Profile</DropdownItem>
|
|
73
|
+
<DropdownItem onclick={() => open3 = false}>Settings</DropdownItem>
|
|
74
|
+
<DropdownItem onclick={() => open3 = false}>Help</DropdownItem>
|
|
75
|
+
<div class="border-t my-1"></div>
|
|
76
|
+
<DropdownItem onclick={() => open3 = false}>Sign Out</DropdownItem>
|
|
77
|
+
</Dropdown>
|
|
78
|
+
{/if}
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
{/snippet}
|
|
82
|
+
</Story>
|
|
83
|
+
|
|
84
|
+
<Story name="With Icons">
|
|
85
|
+
{#snippet template()}
|
|
86
|
+
<div class="relative inline-block">
|
|
87
|
+
<Button onclick={() => open1 = !open1}>
|
|
88
|
+
User Menu ▼
|
|
89
|
+
</Button>
|
|
90
|
+
{#if open1}
|
|
91
|
+
<Dropdown class="absolute mt-1 z-10 min-w-[180px]">
|
|
92
|
+
<DropdownItem onclick={() => open1 = false}>
|
|
93
|
+
<span class="mr-2">👤</span> Profile
|
|
94
|
+
</DropdownItem>
|
|
95
|
+
<DropdownItem onclick={() => open1 = false}>
|
|
96
|
+
<span class="mr-2">⚙️</span> Settings
|
|
97
|
+
</DropdownItem>
|
|
98
|
+
<DropdownItem onclick={() => open1 = false}>
|
|
99
|
+
<span class="mr-2">📊</span> Analytics
|
|
100
|
+
</DropdownItem>
|
|
101
|
+
<div class="border-t my-1"></div>
|
|
102
|
+
<DropdownItem onclick={() => open1 = false}>
|
|
103
|
+
<span class="mr-2">🚪</span> Sign Out
|
|
104
|
+
</DropdownItem>
|
|
105
|
+
</Dropdown>
|
|
106
|
+
{/if}
|
|
107
|
+
</div>
|
|
108
|
+
{/snippet}
|
|
109
|
+
</Story>
|
|
110
|
+
|
|
111
|
+
<Story name="In Card Context">
|
|
112
|
+
{#snippet template()}
|
|
113
|
+
<div class="border rounded-lg p-4 max-w-sm">
|
|
114
|
+
<div class="flex justify-between items-center mb-4">
|
|
115
|
+
<h3 class="font-medium">Card Title</h3>
|
|
116
|
+
<div class="relative">
|
|
117
|
+
<button
|
|
118
|
+
class="p-1 hover:bg-gray-100 rounded"
|
|
119
|
+
onclick={() => open1 = !open1}
|
|
120
|
+
>
|
|
121
|
+
⋮
|
|
122
|
+
</button>
|
|
123
|
+
{#if open1}
|
|
124
|
+
<Dropdown class="absolute mt-1 right-0 z-10">
|
|
125
|
+
<DropdownItem onclick={() => open1 = false}>Edit</DropdownItem>
|
|
126
|
+
<DropdownItem onclick={() => open1 = false}>Share</DropdownItem>
|
|
127
|
+
<DropdownItem onclick={() => open1 = false} class="text-red-600">Delete</DropdownItem>
|
|
128
|
+
</Dropdown>
|
|
129
|
+
{/if}
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
<p class="text-gray-600 text-sm">
|
|
133
|
+
This is a card with a dropdown menu in the header for common actions.
|
|
134
|
+
</p>
|
|
135
|
+
</div>
|
|
136
|
+
{/snippet}
|
|
137
|
+
</Story>
|