@widgetic/design-system 0.5.21 → 0.5.23
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/README.md +2 -0
- package/dist/components/CopyableHeader.svelte +260 -448
- package/dist/components/CopyableHeader.svelte.d.ts +8 -5
- package/dist/components/EmptyState.svelte +100 -128
- package/dist/components/EmptyState.svelte.d.ts +16 -19
- package/dist/components/GenerateLoader.svelte +17 -10
- package/dist/components/PasswordInput.svelte +41 -44
- package/dist/components/PasswordInput.svelte.d.ts +2 -0
- package/dist/components/ThumbHashImage.svelte +117 -119
- package/dist/components/WScrollArea.svelte +47 -41
- package/dist/components/chat/ActivityRow.svelte +115 -0
- package/dist/components/chat/ActivityRow.svelte.d.ts +18 -0
- package/dist/components/chat/ChatHeader.svelte +114 -0
- package/dist/components/chat/ChatHeader.svelte.d.ts +26 -0
- package/dist/components/chat/Composer.svelte +172 -0
- package/dist/components/chat/Composer.svelte.d.ts +27 -0
- package/dist/components/chat/Message.svelte +158 -0
- package/dist/components/chat/Message.svelte.d.ts +28 -0
- package/dist/components/chat/OptionRow.svelte +59 -0
- package/dist/components/chat/OptionRow.svelte.d.ts +14 -0
- package/dist/components/chat/PlanCard.svelte +220 -0
- package/dist/components/chat/PlanCard.svelte.d.ts +34 -0
- package/dist/components/chat/QuestionCard.svelte +265 -0
- package/dist/components/chat/QuestionCard.svelte.d.ts +38 -0
- package/dist/components/chat/ScrollToBottom.svelte +51 -0
- package/dist/components/chat/ScrollToBottom.svelte.d.ts +11 -0
- package/dist/components/chat/SuggestionCard.svelte +79 -0
- package/dist/components/chat/SuggestionCard.svelte.d.ts +20 -0
- package/dist/components/chat/TaskRow.svelte +59 -0
- package/dist/components/chat/TaskRow.svelte.d.ts +11 -0
- package/dist/components/chat/composerLogic.d.ts +16 -0
- package/dist/components/chat/composerLogic.js +29 -0
- package/dist/components/chat/index.d.ts +16 -0
- package/dist/components/chat/index.js +16 -0
- package/dist/components/chat/questionCardLogic.d.ts +11 -0
- package/dist/components/chat/questionCardLogic.js +39 -0
- package/dist/components/index.d.ts +10 -1
- package/dist/components/index.js +10 -0
- package/dist/components/modals/ActionModal.svelte +186 -180
- package/dist/components/modals/BaseModal.svelte +404 -395
- package/dist/components/modals/BaseModal.svelte.d.ts +3 -0
- package/dist/components/modals/NewItemDialog.svelte +200 -243
- package/dist/components/modals/Portal.svelte +107 -105
- package/dist/components/modals/README.md +16 -2
- package/dist/components/modals/RenameDialog.svelte +234 -292
- package/dist/components/navigation/Breadcrumbs.svelte +415 -377
- package/dist/components/navigation/Breadcrumbs.svelte.d.ts +3 -2
- package/dist/components/navigation/types.d.ts +2 -0
- package/dist/components/pdf/PDFViewer.svelte +54 -1
- package/dist/components/search-input/SearchInput.svelte +51 -104
- package/dist/components/search-input/SearchInput.svelte.d.ts +9 -27
- package/dist/components/shad-editor/editor.css +1 -1
- package/dist/components/shad-editor/i18n/messages.d.ts +1 -1
- package/dist/components/shad-editor/i18n/messages.js +1 -1
- package/dist/components/shell/AppShell.svelte +52 -0
- package/dist/components/shell/AppShell.svelte.d.ts +13 -0
- package/dist/components/shell/Banner.svelte +90 -0
- package/dist/components/shell/Banner.svelte.d.ts +61 -0
- package/dist/components/shell/ErrorState.svelte +60 -0
- package/dist/components/shell/ErrorState.svelte.d.ts +13 -0
- package/dist/components/shell/Link.svelte +63 -0
- package/dist/components/shell/Link.svelte.d.ts +53 -0
- package/dist/components/shell/NavDrawer.svelte +117 -0
- package/dist/components/shell/NavDrawer.svelte.d.ts +10 -0
- package/dist/components/shell/NavRow.svelte +128 -0
- package/dist/components/shell/NavRow.svelte.d.ts +65 -0
- package/dist/components/shell/NavSectionLabel.svelte +27 -0
- package/dist/components/shell/NavSectionLabel.svelte.d.ts +9 -0
- package/dist/components/shell/NotificationRow.svelte +76 -0
- package/dist/components/shell/NotificationRow.svelte.d.ts +16 -0
- package/dist/components/shell/PageHeader.svelte +42 -0
- package/dist/components/shell/PageHeader.svelte.d.ts +12 -0
- package/dist/components/shell/ProfileRow.svelte +95 -0
- package/dist/components/shell/ProfileRow.svelte.d.ts +54 -0
- package/dist/components/shell/SettingsDialog.svelte +118 -0
- package/dist/components/shell/SettingsDialog.svelte.d.ts +19 -0
- package/dist/components/shell/SettingsNav.svelte +46 -0
- package/dist/components/shell/SettingsNav.svelte.d.ts +11 -0
- package/dist/components/shell/Sidebar.svelte +82 -0
- package/dist/components/shell/Sidebar.svelte.d.ts +25 -0
- package/dist/components/shell/Stat.svelte +63 -0
- package/dist/components/shell/Stat.svelte.d.ts +58 -0
- package/dist/components/shell/TopBar.svelte +37 -0
- package/dist/components/shell/TopBar.svelte.d.ts +11 -0
- package/dist/components/shell/WidgetRow.svelte +126 -0
- package/dist/components/shell/WidgetRow.svelte.d.ts +78 -0
- package/dist/components/shell/error-state-messages.d.ts +7 -0
- package/dist/components/shell/error-state-messages.js +9 -0
- package/dist/components/shell/index.d.ts +22 -0
- package/dist/components/shell/index.js +25 -0
- package/dist/components/shell/link-external.d.ts +2 -0
- package/dist/components/shell/link-external.js +7 -0
- package/dist/components/shell/messages.d.ts +7 -0
- package/dist/components/shell/messages.js +5 -0
- package/dist/components/shell/settings-nav-types.d.ts +12 -0
- package/dist/components/shell/settings-nav-types.js +3 -0
- package/dist/components/shell/shell-utils.d.ts +7 -0
- package/dist/components/shell/shell-utils.js +27 -0
- package/dist/components/shell/stat-tone.d.ts +3 -0
- package/dist/components/shell/stat-tone.js +11 -0
- package/dist/components/toast/ToasterModal.svelte +102 -168
- package/dist/components/toast/ToasterModal.svelte.d.ts +2 -12
- package/dist/components/ui/accordion/accordion-content.svelte +3 -2
- package/dist/components/ui/accordion/accordion-item.svelte +10 -1
- package/dist/components/ui/accordion/accordion-trigger.svelte +4 -3
- package/dist/components/ui/alert/alert-description.svelte +5 -1
- package/dist/components/ui/alert/alert-title.svelte +2 -1
- package/dist/components/ui/alert/index.d.ts +13 -11
- package/dist/components/ui/alert/index.js +4 -4
- package/dist/components/ui/avatar/avatar-utils.d.ts +2 -0
- package/dist/components/ui/avatar/avatar-utils.js +9 -0
- package/dist/components/ui/avatar/avatar.svelte +63 -0
- package/dist/components/ui/avatar/avatar.svelte.d.ts +80 -0
- package/dist/components/ui/avatar/index.d.ts +4 -0
- package/dist/components/ui/avatar/index.js +4 -0
- package/dist/components/ui/badge/badge.svelte +22 -10
- package/dist/components/ui/badge/badge.svelte.d.ts +14 -15
- package/dist/components/ui/breadcrumb/breadcrumb-ellipsis.svelte +2 -2
- package/dist/components/ui/breadcrumb/breadcrumb-link.svelte +1 -1
- package/dist/components/ui/breadcrumb/breadcrumb-page.svelte +1 -1
- package/dist/components/ui/breadcrumb/breadcrumb-separator.svelte +2 -2
- package/dist/components/ui/button/button-padding.d.ts +9 -0
- package/dist/components/ui/button/button-padding.js +15 -0
- package/dist/components/ui/button/button.svelte +81 -31
- package/dist/components/ui/button/button.svelte.d.ts +48 -29
- package/dist/components/ui/calendar/calendar-cell.svelte +1 -1
- package/dist/components/ui/calendar/calendar-head-cell.svelte +1 -1
- package/dist/components/ui/calendar/calendar-next-button.svelte +2 -2
- package/dist/components/ui/calendar/calendar-prev-button.svelte +2 -2
- package/dist/components/ui/card/card-description.svelte +1 -1
- package/dist/components/ui/card/card-title.svelte +1 -1
- package/dist/components/ui/card/card.svelte +1 -1
- package/dist/components/ui/checkbox/checkbox.svelte +9 -5
- package/dist/components/ui/chip/chip.svelte +48 -0
- package/dist/components/ui/chip/chip.svelte.d.ts +13 -0
- package/dist/components/ui/chip/index.d.ts +2 -0
- package/dist/components/ui/chip/index.js +2 -0
- package/dist/components/ui/command/command-dialog.svelte +1 -1
- package/dist/components/ui/command/command-input.svelte +4 -4
- package/dist/components/ui/command/command-item.svelte +1 -1
- package/dist/components/ui/command/command.svelte +1 -1
- package/dist/components/ui/dialog/dialog-content.svelte +4 -4
- package/dist/components/ui/dialog/dialog-description.svelte +1 -1
- package/dist/components/ui/dialog/dialog-overlay.svelte +1 -1
- package/dist/components/ui/dialog/dialog-title.svelte +1 -1
- package/dist/components/ui/drawer/drawer-content.svelte +1 -1
- package/dist/components/ui/drawer/drawer-overlay.svelte +1 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +5 -5
- package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte +1 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte +1 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte +20 -2
- package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-label.svelte +5 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte +3 -3
- package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte +2 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte +1 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +3 -3
- package/dist/components/ui/field/field-ids.d.ts +7 -0
- package/dist/components/ui/field/field-ids.js +15 -0
- package/dist/components/ui/field/field.svelte +62 -0
- package/dist/components/ui/field/field.svelte.d.ts +21 -0
- package/dist/components/ui/field/index.d.ts +3 -0
- package/dist/components/ui/field/index.js +3 -0
- package/dist/components/ui/hover-card/hover-card-content.svelte +1 -1
- package/dist/components/ui/icon-button/icon-button.svelte +72 -0
- package/dist/components/ui/icon-button/icon-button.svelte.d.ts +90 -0
- package/dist/components/ui/icon-button/index.d.ts +2 -0
- package/dist/components/ui/icon-button/index.js +4 -0
- package/dist/components/ui/input/index.d.ts +1 -0
- package/dist/components/ui/input/input.svelte +11 -4
- package/dist/components/ui/input/input.svelte.d.ts +4 -1
- package/dist/components/ui/input-otp/input-otp-separator.svelte +2 -2
- package/dist/components/ui/input-otp/input-otp-slot.svelte +5 -4
- package/dist/components/ui/input-otp/input-otp-slot.svelte.d.ts +1 -1
- package/dist/components/ui/input-otp/input-otp.svelte +1 -1
- package/dist/components/ui/label/label.svelte +3 -2
- package/dist/components/ui/popover/popover-content.svelte +1 -1
- package/dist/components/ui/progress/progress.svelte +19 -5
- package/dist/components/ui/progress/progress.svelte.d.ts +4 -2
- package/dist/components/ui/radio-group/radio-group-item.svelte +4 -4
- package/dist/components/ui/range-calendar/range-calendar-head-cell.svelte +1 -1
- package/dist/components/ui/range-calendar/range-calendar-next-button.svelte +2 -2
- package/dist/components/ui/range-calendar/range-calendar-prev-button.svelte +2 -2
- package/dist/components/ui/scroll-area/scroll-area-scrollbar.svelte +4 -1
- package/dist/components/ui/scroll-area/scroll-area.svelte +1 -1
- package/dist/components/ui/select/select-content.svelte +1 -3
- package/dist/components/ui/select/select-item.svelte +5 -4
- package/dist/components/ui/select/select-scroll-down-button.svelte +2 -2
- package/dist/components/ui/select/select-scroll-up-button.svelte +2 -2
- package/dist/components/ui/select/select-trigger.svelte +4 -3
- package/dist/components/ui/skeleton/index.d.ts +2 -0
- package/dist/components/ui/skeleton/index.js +2 -0
- package/dist/components/ui/skeleton/skeleton.svelte +24 -0
- package/dist/components/ui/skeleton/skeleton.svelte.d.ts +8 -0
- package/dist/components/ui/slider/slider.svelte +5 -10
- package/dist/components/ui/sonner/sonner.svelte +19 -13
- package/dist/components/ui/stepper-button/index.d.ts +3 -0
- package/dist/components/ui/stepper-button/index.js +2 -0
- package/dist/components/ui/stepper-button/stepper-button.svelte +37 -0
- package/dist/components/ui/stepper-button/stepper-button.svelte.d.ts +9 -0
- package/dist/components/ui/switch/switch.svelte +8 -3
- package/dist/components/ui/table/table-cell.svelte +1 -1
- package/dist/components/ui/table/table-head.svelte +1 -1
- package/dist/components/ui/table/table-row.svelte +1 -1
- package/dist/components/ui/tabs/tabs-list.svelte +1 -1
- package/dist/components/ui/tabs/tabs-trigger.svelte +1 -1
- package/dist/components/ui/tag/index.d.ts +2 -0
- package/dist/components/ui/tag/index.js +2 -0
- package/dist/components/ui/tag/tag.svelte +42 -0
- package/dist/components/ui/tag/tag.svelte.d.ts +11 -0
- package/dist/components/ui/textarea/textarea.svelte +4 -3
- package/dist/components/ui/textarea/textarea.svelte.d.ts +2 -2
- package/dist/components/ui/toggle/toggle.svelte +9 -9
- package/dist/components/ui/toggle/toggle.svelte.d.ts +14 -21
- package/dist/components/ui/tooltip/tooltip-content.svelte +1 -1
- package/dist/fonts/Inter/Inter-Black.woff2 +0 -0
- package/dist/fonts/Inter/Inter-BlackItalic.woff2 +0 -0
- package/dist/fonts/Inter/Inter-Bold.woff2 +0 -0
- package/dist/fonts/Inter/Inter-BoldItalic.woff2 +0 -0
- package/dist/fonts/Inter/Inter-ExtraBold.woff2 +0 -0
- package/dist/fonts/Inter/Inter-ExtraBoldItalic.woff2 +0 -0
- package/dist/fonts/Inter/Inter-ExtraLight-BETA.woff2 +0 -0
- package/dist/fonts/Inter/Inter-ExtraLightItalic-BETA.woff2 +0 -0
- package/dist/fonts/Inter/Inter-Italic.woff2 +0 -0
- package/dist/fonts/Inter/Inter-Light-BETA.woff2 +0 -0
- package/dist/fonts/Inter/Inter-LightItalic-BETA.woff2 +0 -0
- package/dist/fonts/Inter/Inter-Medium.woff2 +0 -0
- package/dist/fonts/Inter/Inter-MediumItalic.woff2 +0 -0
- package/dist/fonts/Inter/Inter-Regular.woff2 +0 -0
- package/dist/fonts/Inter/Inter-SemiBold.woff2 +0 -0
- package/dist/fonts/Inter/Inter-SemiBoldItalic.woff2 +0 -0
- package/dist/fonts/Inter/Inter-Thin-BETA.woff2 +0 -0
- package/dist/fonts/Inter/Inter-ThinItalic-BETA.woff2 +0 -0
- package/dist/fonts/Inter/Inter-italic.var.woff2 +0 -0
- package/dist/fonts/Inter/Inter-upright.var.woff2 +0 -0
- package/dist/fonts/Inter/Inter.var.woff2 +0 -0
- package/dist/fonts/JetBrainsMono/JetBrainsMono-Regular.woff2 +0 -0
- package/dist/i18n/audit/designSystemWords.d.ts +1 -1
- package/dist/i18n/audit/designSystemWords.js +1 -1
- package/dist/styles/fonts.css +18 -14
- package/dist/styles/global.css +7 -19
- package/dist/styles/tokens.css +332 -0
- package/dist/utils.d.ts +27 -0
- package/dist/utils.js +33 -2
- package/package.json +2 -1
- package/tailwind.config.ts +7 -47
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<!-- Figma: Profile Row (component set 53:3, node 53:3). -->
|
|
2
|
+
<script lang="ts" module>
|
|
3
|
+
export const profileRowVariants = tv({
|
|
4
|
+
base: 'flex h-12 w-full min-w-0 items-center gap-2 rounded-lg p-2 text-start transition-colors duration-fast focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-sidebar-ring focus-visible:ring-offset-2 focus-visible:ring-offset-sidebar',
|
|
5
|
+
variants: {
|
|
6
|
+
interactive: {
|
|
7
|
+
true: 'cursor-pointer hover:bg-sidebar-accent',
|
|
8
|
+
false: ''
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
defaultVariants: {
|
|
12
|
+
interactive: true
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export type ProfileRowVisualState = 'default' | 'hover' | 'focus';
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<script lang="ts">
|
|
20
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
21
|
+
import type { Snippet } from 'svelte';
|
|
22
|
+
import IconSelector from '@tabler/icons-svelte/icons/selector';
|
|
23
|
+
import { cn, tv } from '../../utils.js';
|
|
24
|
+
import { Avatar } from '../ui/avatar/index.js';
|
|
25
|
+
|
|
26
|
+
let {
|
|
27
|
+
class: className,
|
|
28
|
+
title,
|
|
29
|
+
subtitle = '',
|
|
30
|
+
showSubtitle = false,
|
|
31
|
+
showTrailingIcon = true,
|
|
32
|
+
name = '',
|
|
33
|
+
src = undefined,
|
|
34
|
+
visualState = undefined,
|
|
35
|
+
menu,
|
|
36
|
+
onclick,
|
|
37
|
+
...restProps
|
|
38
|
+
}: HTMLAttributes<HTMLElement> & {
|
|
39
|
+
title: string;
|
|
40
|
+
subtitle?: string;
|
|
41
|
+
showSubtitle?: boolean;
|
|
42
|
+
showTrailingIcon?: boolean;
|
|
43
|
+
name?: string;
|
|
44
|
+
src?: string;
|
|
45
|
+
visualState?: ProfileRowVisualState;
|
|
46
|
+
menu?: Snippet;
|
|
47
|
+
} = $props();
|
|
48
|
+
|
|
49
|
+
const showcaseClass = $derived.by(() => {
|
|
50
|
+
if (!visualState || visualState === 'default') return '';
|
|
51
|
+
if (visualState === 'hover') return 'bg-sidebar-accent';
|
|
52
|
+
if (visualState === 'focus')
|
|
53
|
+
return 'ring-2 ring-sidebar-ring ring-offset-2 ring-offset-sidebar';
|
|
54
|
+
return '';
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const asButton = $derived(Boolean(onclick || menu));
|
|
58
|
+
</script>
|
|
59
|
+
|
|
60
|
+
{#if asButton}
|
|
61
|
+
<button
|
|
62
|
+
type="button"
|
|
63
|
+
class={cn(profileRowVariants({ interactive: true }), showcaseClass, className)}
|
|
64
|
+
{onclick}
|
|
65
|
+
{...restProps}
|
|
66
|
+
>
|
|
67
|
+
<Avatar size="default" {name} {src} class="shrink-0" />
|
|
68
|
+
<span class="min-w-0 flex-1 flex-col gap-0 overflow-hidden">
|
|
69
|
+
<span class="text-body-medium text-foreground block truncate">{title}</span>
|
|
70
|
+
{#if showSubtitle && subtitle}
|
|
71
|
+
<span class="text-caption text-muted-foreground block truncate">{subtitle}</span>
|
|
72
|
+
{/if}
|
|
73
|
+
</span>
|
|
74
|
+
{#if showTrailingIcon}
|
|
75
|
+
<IconSelector class="text-muted-foreground size-4 shrink-0" aria-hidden="true" />
|
|
76
|
+
{/if}
|
|
77
|
+
{@render menu?.()}
|
|
78
|
+
</button>
|
|
79
|
+
{:else}
|
|
80
|
+
<div
|
|
81
|
+
class={cn(profileRowVariants({ interactive: false }), showcaseClass, className)}
|
|
82
|
+
{...restProps}
|
|
83
|
+
>
|
|
84
|
+
<Avatar size="default" {name} {src} class="shrink-0" />
|
|
85
|
+
<span class="min-w-0 flex-1 flex-col gap-0 overflow-hidden">
|
|
86
|
+
<span class="text-body-medium text-foreground block truncate">{title}</span>
|
|
87
|
+
{#if showSubtitle && subtitle}
|
|
88
|
+
<span class="text-caption text-muted-foreground block truncate">{subtitle}</span>
|
|
89
|
+
{/if}
|
|
90
|
+
</span>
|
|
91
|
+
{#if showTrailingIcon}
|
|
92
|
+
<IconSelector class="text-muted-foreground size-4 shrink-0" aria-hidden="true" />
|
|
93
|
+
{/if}
|
|
94
|
+
</div>
|
|
95
|
+
{/if}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export declare const profileRowVariants: import("tailwind-variants").TVReturnType<{
|
|
2
|
+
interactive: {
|
|
3
|
+
true: string;
|
|
4
|
+
false: string;
|
|
5
|
+
};
|
|
6
|
+
}, undefined, "flex h-12 w-full min-w-0 items-center gap-2 rounded-lg p-2 text-start transition-colors duration-fast focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-sidebar-ring focus-visible:ring-offset-2 focus-visible:ring-offset-sidebar", {
|
|
7
|
+
responsiveVariants?: boolean | (string | number | symbol)[] | {
|
|
8
|
+
interactive?: boolean | (string | number | symbol)[] | undefined;
|
|
9
|
+
} | undefined;
|
|
10
|
+
} & import("tailwind-variants/dist/config.js").TWMConfig & {
|
|
11
|
+
twMergeConfig: {
|
|
12
|
+
classGroups: {
|
|
13
|
+
"font-size": {
|
|
14
|
+
text: ("display-hero" | "heading-page" | "heading-section" | "body" | "body-medium" | "body-large" | "caption" | "caption-medium" | "label" | "label-small" | "code")[];
|
|
15
|
+
}[];
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
}, {
|
|
19
|
+
interactive: {
|
|
20
|
+
true: string;
|
|
21
|
+
false: string;
|
|
22
|
+
};
|
|
23
|
+
}, undefined, import("tailwind-variants").TVReturnType<{
|
|
24
|
+
interactive: {
|
|
25
|
+
true: string;
|
|
26
|
+
false: string;
|
|
27
|
+
};
|
|
28
|
+
}, undefined, "flex h-12 w-full min-w-0 items-center gap-2 rounded-lg p-2 text-start transition-colors duration-fast focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-sidebar-ring focus-visible:ring-offset-2 focus-visible:ring-offset-sidebar", import("tailwind-variants/dist/config.js").TVConfig<{
|
|
29
|
+
interactive: {
|
|
30
|
+
true: string;
|
|
31
|
+
false: string;
|
|
32
|
+
};
|
|
33
|
+
}, {
|
|
34
|
+
interactive: {
|
|
35
|
+
true: string;
|
|
36
|
+
false: string;
|
|
37
|
+
};
|
|
38
|
+
}>, unknown, unknown, undefined>>;
|
|
39
|
+
export type ProfileRowVisualState = 'default' | 'hover' | 'focus';
|
|
40
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
41
|
+
import type { Snippet } from 'svelte';
|
|
42
|
+
type $$ComponentProps = HTMLAttributes<HTMLElement> & {
|
|
43
|
+
title: string;
|
|
44
|
+
subtitle?: string;
|
|
45
|
+
showSubtitle?: boolean;
|
|
46
|
+
showTrailingIcon?: boolean;
|
|
47
|
+
name?: string;
|
|
48
|
+
src?: string;
|
|
49
|
+
visualState?: ProfileRowVisualState;
|
|
50
|
+
menu?: Snippet;
|
|
51
|
+
};
|
|
52
|
+
declare const ProfileRow: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
53
|
+
type ProfileRow = ReturnType<typeof ProfileRow>;
|
|
54
|
+
export default ProfileRow;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Figma: Settings Dialog (component set 107:618, page Settings Dialog)
|
|
3
|
+
-->
|
|
4
|
+
<script lang="ts" module>
|
|
5
|
+
export type SettingsDialogProps = {
|
|
6
|
+
open?: boolean;
|
|
7
|
+
class?: string;
|
|
8
|
+
title: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
activeId: string;
|
|
11
|
+
groups: import('./settings-nav-types.js').SettingsNavGroup[];
|
|
12
|
+
onSelect?: (id: string) => void;
|
|
13
|
+
closeLabel?: string;
|
|
14
|
+
messages?: import('./messages.js').SettingsDialogMessages;
|
|
15
|
+
privacyHref?: string;
|
|
16
|
+
termsHref?: string;
|
|
17
|
+
cookieHref?: string;
|
|
18
|
+
children: import('svelte').Snippet;
|
|
19
|
+
descriptionSlot?: import('svelte').Snippet;
|
|
20
|
+
};
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<script lang="ts">
|
|
24
|
+
import { Dialog as DialogPrimitive } from 'bits-ui';
|
|
25
|
+
import IconX from '@tabler/icons-svelte/icons/x';
|
|
26
|
+
import type { Snippet } from 'svelte';
|
|
27
|
+
import * as Dialog from '../ui/dialog/index.js';
|
|
28
|
+
import { cn } from '../../utils.js';
|
|
29
|
+
import SettingsNav from './SettingsNav.svelte';
|
|
30
|
+
import { defaultSettingsDialogMessages, type SettingsDialogMessages } from './messages.js';
|
|
31
|
+
import type { SettingsNavGroup } from './settings-nav-types.js';
|
|
32
|
+
|
|
33
|
+
let {
|
|
34
|
+
open = $bindable(false),
|
|
35
|
+
class: className,
|
|
36
|
+
title,
|
|
37
|
+
description = undefined,
|
|
38
|
+
activeId,
|
|
39
|
+
groups,
|
|
40
|
+
onSelect,
|
|
41
|
+
closeLabel = 'Close',
|
|
42
|
+
messages = defaultSettingsDialogMessages,
|
|
43
|
+
privacyHref = '#',
|
|
44
|
+
termsHref = '#',
|
|
45
|
+
cookieHref = '#',
|
|
46
|
+
children,
|
|
47
|
+
descriptionSlot
|
|
48
|
+
}: SettingsDialogProps = $props();
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<Dialog.Root bind:open>
|
|
52
|
+
<Dialog.Portal>
|
|
53
|
+
<Dialog.Overlay class="bg-foreground/50 backdrop-blur-sm" />
|
|
54
|
+
<DialogPrimitive.Content
|
|
55
|
+
class={cn(
|
|
56
|
+
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 border-border bg-background duration-base fixed z-50 flex overflow-hidden border',
|
|
57
|
+
'inset-0 h-full max-h-none w-full rounded-none',
|
|
58
|
+
'lg:h-settings-modal lg:w-settings-modal lg:rounded-panel lg:start-1/2 lg:top-1/2 lg:max-h-[calc(100vh-2rem)] lg:max-w-[calc(100vw-2rem)] lg:-translate-x-1/2 lg:-translate-y-1/2',
|
|
59
|
+
className
|
|
60
|
+
)}
|
|
61
|
+
aria-describedby={description || descriptionSlot ? 'settings-dialog-description' : undefined}
|
|
62
|
+
>
|
|
63
|
+
<div class="flex min-h-0 min-w-0 flex-1 flex-col lg:flex-row">
|
|
64
|
+
<aside
|
|
65
|
+
class="border-border bg-sidebar flex w-full shrink-0 flex-col border-b p-3 lg:w-64 lg:border-e lg:border-b-0"
|
|
66
|
+
>
|
|
67
|
+
<SettingsNav {groups} {activeId} {onSelect} class="flex-1" />
|
|
68
|
+
<div class="mt-auto flex flex-col gap-1 px-2 pt-4 pb-1">
|
|
69
|
+
<a
|
|
70
|
+
href={privacyHref}
|
|
71
|
+
class="text-caption text-muted-foreground duration-fast hover:text-foreground w-fit transition-colors"
|
|
72
|
+
>{messages.privacyPolicy}</a
|
|
73
|
+
>
|
|
74
|
+
<a
|
|
75
|
+
href={termsHref}
|
|
76
|
+
class="text-caption text-muted-foreground duration-fast hover:text-foreground w-fit transition-colors"
|
|
77
|
+
>{messages.termsOfService}</a
|
|
78
|
+
>
|
|
79
|
+
<a
|
|
80
|
+
href={cookieHref}
|
|
81
|
+
class="text-caption text-muted-foreground duration-fast hover:text-foreground w-fit transition-colors"
|
|
82
|
+
>{messages.cookieSettings}</a
|
|
83
|
+
>
|
|
84
|
+
</div>
|
|
85
|
+
</aside>
|
|
86
|
+
<div class="flex min-h-0 min-w-0 flex-1 flex-col gap-6 overflow-y-auto p-8">
|
|
87
|
+
<header class="flex flex-col gap-1 pe-10">
|
|
88
|
+
<DialogPrimitive.Title class="text-heading-page text-foreground"
|
|
89
|
+
>{title}</DialogPrimitive.Title
|
|
90
|
+
>
|
|
91
|
+
{#if descriptionSlot}
|
|
92
|
+
<DialogPrimitive.Description
|
|
93
|
+
id="settings-dialog-description"
|
|
94
|
+
class="text-body text-muted-foreground"
|
|
95
|
+
>
|
|
96
|
+
{@render descriptionSlot()}
|
|
97
|
+
</DialogPrimitive.Description>
|
|
98
|
+
{:else if description}
|
|
99
|
+
<DialogPrimitive.Description
|
|
100
|
+
id="settings-dialog-description"
|
|
101
|
+
class="text-body text-muted-foreground"
|
|
102
|
+
>
|
|
103
|
+
{description}
|
|
104
|
+
</DialogPrimitive.Description>
|
|
105
|
+
{/if}
|
|
106
|
+
</header>
|
|
107
|
+
<div class="flex min-h-0 flex-1 flex-col gap-6">{@render children()}</div>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
<DialogPrimitive.Close
|
|
111
|
+
class="text-foreground hover:bg-accent duration-fast focus-visible:ring-ring focus-visible:ring-offset-background absolute end-4 top-4 inline-flex size-8 items-center justify-center rounded-lg transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden"
|
|
112
|
+
>
|
|
113
|
+
<IconX class="size-4 stroke-[1.333]" aria-hidden="true" />
|
|
114
|
+
<span class="sr-only">{closeLabel}</span>
|
|
115
|
+
</DialogPrimitive.Close>
|
|
116
|
+
</DialogPrimitive.Content>
|
|
117
|
+
</Dialog.Portal>
|
|
118
|
+
</Dialog.Root>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type SettingsDialogProps = {
|
|
2
|
+
open?: boolean;
|
|
3
|
+
class?: string;
|
|
4
|
+
title: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
activeId: string;
|
|
7
|
+
groups: import('./settings-nav-types.js').SettingsNavGroup[];
|
|
8
|
+
onSelect?: (id: string) => void;
|
|
9
|
+
closeLabel?: string;
|
|
10
|
+
messages?: import('./messages.js').SettingsDialogMessages;
|
|
11
|
+
privacyHref?: string;
|
|
12
|
+
termsHref?: string;
|
|
13
|
+
cookieHref?: string;
|
|
14
|
+
children: import('svelte').Snippet;
|
|
15
|
+
descriptionSlot?: import('svelte').Snippet;
|
|
16
|
+
};
|
|
17
|
+
declare const SettingsDialog: import("svelte").Component<SettingsDialogProps, {}, "open">;
|
|
18
|
+
type SettingsDialog = ReturnType<typeof SettingsDialog>;
|
|
19
|
+
export default SettingsDialog;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Figma: Settings Nav (component set 106:467, page Settings Dialog)
|
|
3
|
+
-->
|
|
4
|
+
<script lang="ts" module>
|
|
5
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
6
|
+
import type { SettingsNavGroup } from './settings-nav-types.js';
|
|
7
|
+
|
|
8
|
+
export type SettingsNavProps = HTMLAttributes<HTMLElement> & {
|
|
9
|
+
class?: string;
|
|
10
|
+
groups: SettingsNavGroup[];
|
|
11
|
+
activeId: string;
|
|
12
|
+
onSelect?: (id: string) => void;
|
|
13
|
+
};
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<script lang="ts">
|
|
17
|
+
import { cn } from '../../utils.js';
|
|
18
|
+
import NavRow from './NavRow.svelte';
|
|
19
|
+
import NavSectionLabel from './NavSectionLabel.svelte';
|
|
20
|
+
import { settingsNavItemIsActive } from './settings-nav-types.js';
|
|
21
|
+
|
|
22
|
+
let { class: className, groups, activeId, onSelect, ...restProps }: SettingsNavProps = $props();
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<nav class={cn('flex w-full flex-col gap-0.5', className)} aria-label="Settings" {...restProps}>
|
|
26
|
+
{#each groups as group (group.id)}
|
|
27
|
+
<div class="flex flex-col gap-0.5">
|
|
28
|
+
<NavSectionLabel label={group.label} />
|
|
29
|
+
{#each group.items as item (item.id)}
|
|
30
|
+
{@const active = settingsNavItemIsActive(activeId, item.id)}
|
|
31
|
+
<NavRow
|
|
32
|
+
label={item.label}
|
|
33
|
+
{active}
|
|
34
|
+
showIcon={Boolean(item.icon)}
|
|
35
|
+
onclick={() => onSelect?.(item.id)}
|
|
36
|
+
>
|
|
37
|
+
{#snippet icon()}
|
|
38
|
+
{#if item.icon}
|
|
39
|
+
{@render item.icon()}
|
|
40
|
+
{/if}
|
|
41
|
+
{/snippet}
|
|
42
|
+
</NavRow>
|
|
43
|
+
{/each}
|
|
44
|
+
</div>
|
|
45
|
+
{/each}
|
|
46
|
+
</nav>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import type { SettingsNavGroup } from './settings-nav-types.js';
|
|
3
|
+
export type SettingsNavProps = HTMLAttributes<HTMLElement> & {
|
|
4
|
+
class?: string;
|
|
5
|
+
groups: SettingsNavGroup[];
|
|
6
|
+
activeId: string;
|
|
7
|
+
onSelect?: (id: string) => void;
|
|
8
|
+
};
|
|
9
|
+
declare const SettingsNav: import("svelte").Component<SettingsNavProps, {}, "">;
|
|
10
|
+
type SettingsNav = ReturnType<typeof SettingsNav>;
|
|
11
|
+
export default SettingsNav;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<!-- Figma: Sidebar (component set 53:33, node 53:33). -->
|
|
2
|
+
<script lang="ts">
|
|
3
|
+
import type { Icon } from '@tabler/icons-svelte';
|
|
4
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
5
|
+
import type { Snippet } from 'svelte';
|
|
6
|
+
import { cn } from '../../utils.js';
|
|
7
|
+
import NavRow from './NavRow.svelte';
|
|
8
|
+
|
|
9
|
+
export type SidebarNavItem = {
|
|
10
|
+
id: string;
|
|
11
|
+
label: string;
|
|
12
|
+
/** Custom icon markup (advanced). */
|
|
13
|
+
icon?: Snippet;
|
|
14
|
+
/** Tabler icon component (preferred for standard nav icons). */
|
|
15
|
+
iconComponent?: Icon;
|
|
16
|
+
href?: string;
|
|
17
|
+
count?: string | number;
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
let {
|
|
22
|
+
class: className,
|
|
23
|
+
activeId = undefined,
|
|
24
|
+
items = undefined,
|
|
25
|
+
onNavigate,
|
|
26
|
+
header,
|
|
27
|
+
nav,
|
|
28
|
+
footer,
|
|
29
|
+
...restProps
|
|
30
|
+
}: HTMLAttributes<HTMLElement> & {
|
|
31
|
+
activeId?: string;
|
|
32
|
+
items?: SidebarNavItem[];
|
|
33
|
+
onNavigate?: (id: string) => void;
|
|
34
|
+
header?: Snippet;
|
|
35
|
+
nav?: Snippet;
|
|
36
|
+
footer?: Snippet;
|
|
37
|
+
} = $props();
|
|
38
|
+
|
|
39
|
+
function handleItemClick(id: string, href?: string) {
|
|
40
|
+
if (href) return;
|
|
41
|
+
onNavigate?.(id);
|
|
42
|
+
}
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<aside
|
|
46
|
+
class={cn(
|
|
47
|
+
'w-sidebar bg-sidebar text-sidebar-foreground flex h-full shrink-0 flex-col gap-0.5 p-3',
|
|
48
|
+
className
|
|
49
|
+
)}
|
|
50
|
+
{...restProps}
|
|
51
|
+
>
|
|
52
|
+
{#if header}
|
|
53
|
+
<div class="mb-0 shrink-0">{@render header()}</div>
|
|
54
|
+
{/if}
|
|
55
|
+
|
|
56
|
+
{#if items?.length}
|
|
57
|
+
<nav class="flex min-h-0 flex-1 flex-col gap-0.5" aria-label="Main">
|
|
58
|
+
{#each items as item (item.id)}
|
|
59
|
+
<NavRow
|
|
60
|
+
label={item.label}
|
|
61
|
+
href={item.href}
|
|
62
|
+
active={activeId === item.id}
|
|
63
|
+
disabled={item.disabled}
|
|
64
|
+
showIcon={Boolean(item.icon) || Boolean(item.iconComponent)}
|
|
65
|
+
showTrailing={item.count !== undefined && item.count !== null && item.count !== ''}
|
|
66
|
+
trailing={item.count != null ? String(item.count) : ''}
|
|
67
|
+
icon={item.icon}
|
|
68
|
+
iconComponent={item.iconComponent}
|
|
69
|
+
onclick={item.href ? undefined : () => handleItemClick(item.id, item.href)}
|
|
70
|
+
/>
|
|
71
|
+
{/each}
|
|
72
|
+
</nav>
|
|
73
|
+
{:else if nav}
|
|
74
|
+
<nav class="flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto" aria-label="Main">
|
|
75
|
+
{@render nav()}
|
|
76
|
+
</nav>
|
|
77
|
+
{/if}
|
|
78
|
+
|
|
79
|
+
{#if footer}
|
|
80
|
+
<div class="mt-auto shrink-0 pt-2">{@render footer()}</div>
|
|
81
|
+
{/if}
|
|
82
|
+
</aside>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Icon } from '@tabler/icons-svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
export type SidebarNavItem = {
|
|
5
|
+
id: string;
|
|
6
|
+
label: string;
|
|
7
|
+
/** Custom icon markup (advanced). */
|
|
8
|
+
icon?: Snippet;
|
|
9
|
+
/** Tabler icon component (preferred for standard nav icons). */
|
|
10
|
+
iconComponent?: Icon;
|
|
11
|
+
href?: string;
|
|
12
|
+
count?: string | number;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
};
|
|
15
|
+
type $$ComponentProps = HTMLAttributes<HTMLElement> & {
|
|
16
|
+
activeId?: string;
|
|
17
|
+
items?: SidebarNavItem[];
|
|
18
|
+
onNavigate?: (id: string) => void;
|
|
19
|
+
header?: Snippet;
|
|
20
|
+
nav?: Snippet;
|
|
21
|
+
footer?: Snippet;
|
|
22
|
+
};
|
|
23
|
+
declare const Sidebar: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
24
|
+
type Sidebar = ReturnType<typeof Sidebar>;
|
|
25
|
+
export default Sidebar;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Figma: Stat (component set 327:243, page Experiments)
|
|
3
|
+
-->
|
|
4
|
+
<script lang="ts" module>
|
|
5
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
6
|
+
import type { Snippet } from 'svelte';
|
|
7
|
+
import { type StatTone, statHintClass } from './stat-tone.js';
|
|
8
|
+
|
|
9
|
+
export const statVariants = tv({
|
|
10
|
+
base: 'flex flex-col gap-0.5 rounded-xl border border-border bg-background p-4',
|
|
11
|
+
variants: {
|
|
12
|
+
tone: {
|
|
13
|
+
default: '',
|
|
14
|
+
positive: '',
|
|
15
|
+
negative: ''
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
defaultVariants: {
|
|
19
|
+
tone: 'default'
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export type StatProps = HTMLAttributes<HTMLDivElement> & {
|
|
24
|
+
class?: string;
|
|
25
|
+
label: string;
|
|
26
|
+
value: string;
|
|
27
|
+
hint?: string;
|
|
28
|
+
delta?: string;
|
|
29
|
+
tone?: StatTone;
|
|
30
|
+
trendIcon?: Snippet;
|
|
31
|
+
};
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<script lang="ts">
|
|
35
|
+
import { cn, tv } from '../../utils.js';
|
|
36
|
+
|
|
37
|
+
let {
|
|
38
|
+
class: className,
|
|
39
|
+
label,
|
|
40
|
+
value,
|
|
41
|
+
hint = undefined,
|
|
42
|
+
delta = undefined,
|
|
43
|
+
tone = 'default',
|
|
44
|
+
trendIcon,
|
|
45
|
+
...restProps
|
|
46
|
+
}: StatProps = $props();
|
|
47
|
+
|
|
48
|
+
const hintLine = $derived(delta ?? hint);
|
|
49
|
+
const hintClass = $derived(statHintClass(tone));
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<div class={cn(statVariants({ tone }), className)} {...restProps}>
|
|
53
|
+
<p class="text-caption-medium text-muted-foreground">{label}</p>
|
|
54
|
+
<p class="text-heading-page text-foreground">{value}</p>
|
|
55
|
+
{#if hintLine}
|
|
56
|
+
<p class={cn('text-caption flex items-center gap-1', hintClass)}>
|
|
57
|
+
{#if trendIcon}
|
|
58
|
+
<span class="inline-flex shrink-0 items-center">{@render trendIcon()}</span>
|
|
59
|
+
{/if}
|
|
60
|
+
<span>{hintLine}</span>
|
|
61
|
+
</p>
|
|
62
|
+
{/if}
|
|
63
|
+
</div>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import { type StatTone } from './stat-tone.js';
|
|
4
|
+
export declare const statVariants: import("tailwind-variants").TVReturnType<{
|
|
5
|
+
tone: {
|
|
6
|
+
default: string;
|
|
7
|
+
positive: string;
|
|
8
|
+
negative: string;
|
|
9
|
+
};
|
|
10
|
+
}, undefined, "flex flex-col gap-0.5 rounded-xl border border-border bg-background p-4", {
|
|
11
|
+
responsiveVariants?: boolean | (string | number | symbol)[] | {
|
|
12
|
+
tone?: boolean | (string | number | symbol)[] | undefined;
|
|
13
|
+
} | undefined;
|
|
14
|
+
} & import("tailwind-variants/dist/config.js").TWMConfig & {
|
|
15
|
+
twMergeConfig: {
|
|
16
|
+
classGroups: {
|
|
17
|
+
"font-size": {
|
|
18
|
+
text: ("display-hero" | "heading-page" | "heading-section" | "body" | "body-medium" | "body-large" | "caption" | "caption-medium" | "label" | "label-small" | "code")[];
|
|
19
|
+
}[];
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
}, {
|
|
23
|
+
tone: {
|
|
24
|
+
default: string;
|
|
25
|
+
positive: string;
|
|
26
|
+
negative: string;
|
|
27
|
+
};
|
|
28
|
+
}, undefined, import("tailwind-variants").TVReturnType<{
|
|
29
|
+
tone: {
|
|
30
|
+
default: string;
|
|
31
|
+
positive: string;
|
|
32
|
+
negative: string;
|
|
33
|
+
};
|
|
34
|
+
}, undefined, "flex flex-col gap-0.5 rounded-xl border border-border bg-background p-4", import("tailwind-variants/dist/config.js").TVConfig<{
|
|
35
|
+
tone: {
|
|
36
|
+
default: string;
|
|
37
|
+
positive: string;
|
|
38
|
+
negative: string;
|
|
39
|
+
};
|
|
40
|
+
}, {
|
|
41
|
+
tone: {
|
|
42
|
+
default: string;
|
|
43
|
+
positive: string;
|
|
44
|
+
negative: string;
|
|
45
|
+
};
|
|
46
|
+
}>, unknown, unknown, undefined>>;
|
|
47
|
+
export type StatProps = HTMLAttributes<HTMLDivElement> & {
|
|
48
|
+
class?: string;
|
|
49
|
+
label: string;
|
|
50
|
+
value: string;
|
|
51
|
+
hint?: string;
|
|
52
|
+
delta?: string;
|
|
53
|
+
tone?: StatTone;
|
|
54
|
+
trendIcon?: Snippet;
|
|
55
|
+
};
|
|
56
|
+
declare const Stat: import("svelte").Component<StatProps, {}, "">;
|
|
57
|
+
type Stat = ReturnType<typeof Stat>;
|
|
58
|
+
export default Stat;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<!-- Figma: Top Bar (component set 142:2, node 142:2). -->
|
|
2
|
+
<script lang="ts">
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import type { Snippet } from 'svelte';
|
|
5
|
+
import IconMenu2 from '@tabler/icons-svelte/icons/menu-2';
|
|
6
|
+
import { cn } from '../../utils.js';
|
|
7
|
+
import { IconButton } from '../ui/icon-button/index.js';
|
|
8
|
+
|
|
9
|
+
let {
|
|
10
|
+
class: className,
|
|
11
|
+
title,
|
|
12
|
+
menuLabel = 'Open navigation',
|
|
13
|
+
onMenuClick,
|
|
14
|
+
action,
|
|
15
|
+
...restProps
|
|
16
|
+
}: HTMLAttributes<HTMLElement> & {
|
|
17
|
+
title: string;
|
|
18
|
+
menuLabel?: string;
|
|
19
|
+
onMenuClick?: () => void;
|
|
20
|
+
action?: Snippet;
|
|
21
|
+
} = $props();
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<header
|
|
25
|
+
class={cn('bg-sidebar flex h-14 w-full shrink-0 items-center gap-2 px-3 lg:hidden', className)}
|
|
26
|
+
{...restProps}
|
|
27
|
+
>
|
|
28
|
+
<IconButton variant="ghost" label={menuLabel} onclick={onMenuClick}>
|
|
29
|
+
<IconMenu2 />
|
|
30
|
+
</IconButton>
|
|
31
|
+
<h1 class="text-heading-section text-foreground min-w-0 flex-1 truncate">{title}</h1>
|
|
32
|
+
{#if action}
|
|
33
|
+
<div class="shrink-0">{@render action()}</div>
|
|
34
|
+
{:else}
|
|
35
|
+
<span class="size-8 shrink-0" aria-hidden="true"></span>
|
|
36
|
+
{/if}
|
|
37
|
+
</header>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
type $$ComponentProps = HTMLAttributes<HTMLElement> & {
|
|
4
|
+
title: string;
|
|
5
|
+
menuLabel?: string;
|
|
6
|
+
onMenuClick?: () => void;
|
|
7
|
+
action?: Snippet;
|
|
8
|
+
};
|
|
9
|
+
declare const TopBar: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
10
|
+
type TopBar = ReturnType<typeof TopBar>;
|
|
11
|
+
export default TopBar;
|