@makolabs/ripple 2.5.9 → 3.0.1
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 +403 -497
- package/dist/adapters/storage/S3Adapter.d.ts +49 -1
- package/dist/adapters/storage/S3Adapter.js +38 -1
- package/dist/adapters/storage/types.d.ts +20 -0
- package/dist/ai/AIChatInterface.svelte +2 -1
- package/dist/ai/AIChatInterface.svelte.d.ts +2 -1
- package/dist/ai/CodeRenderer.svelte +7 -2
- package/dist/ai/CodeRenderer.svelte.d.ts +2 -1
- package/dist/ai/ComposeDropdown.svelte +1 -1
- package/dist/ai/MessageBox.svelte +3 -3
- package/dist/ai/MessageBox.svelte.d.ts +3 -2
- package/dist/ai/ThinkingDisplay.svelte +4 -3
- package/dist/ai/ThinkingDisplay.svelte.d.ts +2 -1
- package/dist/ai/ai-types.d.ts +55 -1
- package/dist/button/Button.svelte +5 -5
- package/dist/button/button-types.d.ts +49 -4
- package/dist/button/button.d.ts +9 -9
- package/dist/button/button.js +6 -6
- package/dist/charts/Chart.svelte +8 -16
- package/dist/charts/chart-types.d.ts +78 -1
- package/dist/drawer/Drawer.svelte +6 -26
- package/dist/drawer/drawer-types.d.ts +33 -12
- package/dist/drawer/drawer.d.ts +3 -3
- package/dist/drawer/drawer.js +1 -1
- package/dist/elements/accordion/Accordion.svelte +6 -17
- package/dist/elements/accordion/accordion-types.d.ts +53 -6
- package/dist/elements/alert/Alert.svelte +3 -0
- package/dist/elements/badge/Badge.svelte +1 -1
- package/dist/elements/badge/badge-types.d.ts +22 -0
- package/dist/elements/badge/badge.d.ts +3 -3
- package/dist/elements/badge/badge.js +1 -1
- package/dist/elements/combobox/ComboBox.svelte +244 -0
- package/dist/elements/combobox/ComboBox.svelte.d.ts +4 -0
- package/dist/elements/combobox/combobox-types.d.ts +41 -0
- package/dist/elements/combobox/combobox-types.js +1 -0
- package/dist/elements/context-menu/ContextMenu.svelte +137 -0
- package/dist/elements/context-menu/ContextMenu.svelte.d.ts +4 -0
- package/dist/elements/context-menu/context-menu-types.d.ts +40 -0
- package/dist/elements/context-menu/context-menu-types.js +1 -0
- package/dist/elements/dropdown/Dropdown.svelte +1 -1
- package/dist/elements/dropdown/Select.svelte +4 -1
- package/dist/elements/dropdown/dropdown-types.d.ts +114 -0
- package/dist/elements/dropdown/dropdown.d.ts +3 -3
- package/dist/elements/dropdown/dropdown.js +2 -2
- package/dist/elements/dropdown/select.d.ts +3 -108
- package/dist/elements/dropdown/select.js +38 -47
- package/dist/elements/empty-state/EmptyState.svelte +1 -1
- package/dist/elements/empty-state/empty-state-types.d.ts +32 -1
- package/dist/elements/empty-state/empty-state.d.ts +3 -3
- package/dist/elements/empty-state/empty-state.js +2 -2
- package/dist/elements/file-upload/FileUpload.svelte +5 -0
- package/dist/elements/file-upload/file-upload-types.d.ts +59 -0
- package/dist/elements/pagination/Pagination.svelte +53 -21
- package/dist/elements/pagination/Pagination.svelte.d.ts +33 -5
- package/dist/elements/popover/Popover.svelte +254 -0
- package/dist/elements/popover/Popover.svelte.d.ts +4 -0
- package/dist/elements/popover/index.d.ts +2 -0
- package/dist/elements/popover/index.js +1 -0
- package/dist/elements/popover/popover-types.d.ts +60 -0
- package/dist/elements/popover/popover-types.js +1 -0
- package/dist/elements/progress/Progress.svelte +32 -7
- package/dist/elements/progress/progress-types.d.ts +48 -1
- package/dist/elements/skeleton/Skeleton.svelte +56 -0
- package/dist/elements/skeleton/Skeleton.svelte.d.ts +4 -0
- package/dist/elements/skeleton/index.d.ts +2 -0
- package/dist/elements/skeleton/index.js +1 -0
- package/dist/elements/skeleton/skeleton-types.d.ts +50 -0
- package/dist/elements/skeleton/skeleton-types.js +1 -0
- package/dist/elements/spinner/Spinner.svelte +1 -1
- package/dist/elements/spinner/spinner-types.d.ts +20 -0
- package/dist/elements/spinner/spinner.d.ts +3 -3
- package/dist/elements/spinner/spinner.js +2 -2
- package/dist/elements/tooltip/Tooltip.svelte +108 -11
- package/dist/elements/tooltip/tooltip-types.d.ts +49 -1
- package/dist/file-browser/FileBrowser.svelte +21 -12
- package/dist/filters/CompactFilters.svelte +221 -33
- package/dist/filters/CompactFilters.svelte.d.ts +1 -1
- package/dist/filters/FilterBar.svelte +184 -0
- package/dist/filters/FilterBar.svelte.d.ts +4 -0
- package/dist/filters/FilterPopover.svelte +346 -0
- package/dist/filters/FilterPopover.svelte.d.ts +4 -0
- package/dist/filters/date-presets.d.ts +15 -0
- package/dist/filters/date-presets.js +107 -0
- package/dist/filters/filter-types.d.ts +69 -3
- package/dist/filters/index.d.ts +5 -0
- package/dist/filters/index.js +4 -0
- package/dist/filters/sync-filters-to-url.svelte.d.ts +37 -0
- package/dist/filters/sync-filters-to-url.svelte.js +114 -0
- package/dist/forms/Checkbox.svelte +24 -9
- package/dist/forms/DateRange.svelte +23 -6
- package/dist/forms/Input.svelte +19 -19
- package/dist/forms/MarketSelector.svelte +9 -4
- package/dist/forms/NumberInput.svelte +14 -18
- package/dist/forms/RadioGroup.svelte +127 -0
- package/dist/forms/RadioGroup.svelte.d.ts +4 -0
- package/dist/forms/SegmentedControl.svelte +11 -4
- package/dist/forms/Slider.svelte +72 -3
- package/dist/forms/Tags.svelte +44 -14
- package/dist/forms/Textarea.svelte +121 -0
- package/dist/forms/Textarea.svelte.d.ts +4 -0
- package/dist/forms/Toggle.svelte +30 -22
- package/dist/forms/calendar/Calendar.svelte +315 -0
- package/dist/forms/calendar/Calendar.svelte.d.ts +4 -0
- package/dist/forms/calendar/calendar-types.d.ts +54 -0
- package/dist/forms/calendar/calendar-types.js +1 -0
- package/dist/forms/calendar/index.d.ts +2 -0
- package/dist/forms/calendar/index.js +1 -0
- package/dist/forms/date-picker/DatePicker.svelte +141 -0
- package/dist/forms/date-picker/DatePicker.svelte.d.ts +4 -0
- package/dist/forms/date-picker/date-picker-types.d.ts +29 -0
- package/dist/forms/date-picker/date-picker-types.js +1 -0
- package/dist/forms/form-size.d.ts +37 -0
- package/dist/forms/form-size.js +67 -0
- package/dist/forms/form-types.d.ts +430 -6
- package/dist/forms/market/market-selector-types.d.ts +52 -1
- package/dist/forms/segmented-control.d.ts +5 -2
- package/dist/forms/segmented-control.js +25 -13
- package/dist/forms/slider.d.ts +3 -3
- package/dist/forms/slider.js +37 -30
- package/dist/funcs/user-management.remote.js +1 -1
- package/dist/header/Breadcrumbs.svelte +4 -20
- package/dist/header/PageHeader.svelte +6 -14
- package/dist/header/breadcrumbs.d.ts +3 -11
- package/dist/header/breadcrumbs.js +10 -5
- package/dist/header/header-types.d.ts +62 -11
- package/dist/index.d.ts +35 -9
- package/dist/index.js +24 -4
- package/dist/layout/activity-list/ActivityList.svelte +13 -7
- package/dist/layout/activity-list/activity-list-types.d.ts +46 -7
- package/dist/layout/card/Card.svelte +12 -15
- package/dist/layout/card/MetricCard.svelte +50 -32
- package/dist/layout/card/card-types.d.ts +114 -4
- package/dist/layout/navbar/navbar-types.d.ts +48 -0
- package/dist/layout/navbar/navbar.d.ts +3 -3
- package/dist/layout/navbar/navbar.js +2 -2
- package/dist/layout/sidebar/Sidebar.svelte +87 -11
- package/dist/layout/sidebar/sidebar-types.d.ts +60 -1
- package/dist/layout/stepper/Stepper.svelte +288 -0
- package/dist/layout/stepper/Stepper.svelte.d.ts +4 -0
- package/dist/layout/stepper/stepper-types.d.ts +80 -0
- package/dist/layout/stepper/stepper-types.js +1 -0
- package/dist/layout/table/Table.svelte +91 -85
- package/dist/layout/table/table-types.d.ts +148 -24
- package/dist/layout/table/table.d.ts +3 -3
- package/dist/layout/table/table.js +2 -2
- package/dist/layout/tabs/Tab.svelte +6 -2
- package/dist/layout/tabs/Tab.svelte.d.ts +4 -1
- package/dist/layout/tabs/TabGroup.svelte +9 -2
- package/dist/layout/tabs/tabs-types.d.ts +63 -0
- package/dist/layout/tabs/tabs.d.ts +3 -3
- package/dist/layout/tabs/tabs.js +12 -6
- package/dist/modal/ConfirmDialog.svelte +65 -0
- package/dist/modal/ConfirmDialog.svelte.d.ts +4 -0
- package/dist/modal/Modal.svelte +6 -26
- package/dist/modal/confirm-dialog-types.d.ts +39 -0
- package/dist/modal/confirm-dialog-types.js +1 -0
- package/dist/modal/modal-types.d.ts +51 -12
- package/dist/modal/modal.d.ts +3 -3
- package/dist/modal/modal.js +3 -3
- package/dist/pipeline/Pipeline.svelte +8 -3
- package/dist/pipeline/pipeline-types.d.ts +55 -3
- package/dist/pipeline/pipeline.d.ts +18 -3
- package/dist/pipeline/pipeline.js +7 -2
- package/dist/server/s3.d.ts +35 -3
- package/dist/sonner/Toaster.svelte +29 -0
- package/dist/sonner/Toaster.svelte.d.ts +4 -0
- package/dist/sonner/index.d.ts +21 -0
- package/dist/sonner/index.js +20 -0
- package/dist/user-management/UserManagement.svelte +22 -16
- package/dist/user-management/UserModal.svelte +10 -7
- package/dist/user-management/UserTable.svelte +16 -17
- package/dist/user-management/UserViewModal.svelte +11 -11
- package/dist/user-management/user-management-types.d.ts +118 -31
- package/dist/variants.d.ts +1 -1
- package/dist/variants.js +1 -1
- package/package.json +7 -4
- package/dist/config/ai.d.ts +0 -13
- package/dist/config/ai.js +0 -44
- package/dist/elements/empty-state/EmptyStateTestWrapper.svelte +0 -25
- package/dist/elements/empty-state/EmptyStateTestWrapper.svelte.d.ts +0 -8
- package/dist/elements/tooltip/TooltipTestWrapper.svelte +0 -14
- package/dist/elements/tooltip/TooltipTestWrapper.svelte.d.ts +0 -7
- package/dist/helper/deprecation.d.ts +0 -14
- package/dist/helper/deprecation.js +0 -24
- package/dist/modal/ModalFooterTestWrapper.svelte +0 -17
- package/dist/modal/ModalFooterTestWrapper.svelte.d.ts +0 -8
|
@@ -2,53 +2,149 @@ import type { ClassValue } from 'tailwind-variants';
|
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { Component } from 'svelte';
|
|
4
4
|
import type { VariantSizes } from '../../index.js';
|
|
5
|
+
/** Single menu entry in a `<Dropdown>` section. */
|
|
5
6
|
export type DropdownItem = {
|
|
7
|
+
/** Visible text. */
|
|
6
8
|
label: string;
|
|
9
|
+
/** If set, renders the item as a link; otherwise as a button. Typed to SvelteKit routes. */
|
|
7
10
|
href?: `/${string}`;
|
|
11
|
+
/** Optional icon rendered on the left. */
|
|
8
12
|
icon?: Component;
|
|
13
|
+
/** Click handler (ignored when `href` is set — native navigation wins). */
|
|
9
14
|
onclick?: () => void;
|
|
15
|
+
/** Visually highlight the item as the current route/selection. */
|
|
10
16
|
active?: boolean;
|
|
11
17
|
};
|
|
18
|
+
/** A visually grouped subset of items — renders with a separator between sections. */
|
|
12
19
|
export type DropSection = {
|
|
13
20
|
items: DropdownItem[];
|
|
14
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Optional header at the top of the dropdown panel (user profile snippet,
|
|
24
|
+
* workspace switcher heading, etc.).
|
|
25
|
+
*/
|
|
15
26
|
export type DropHeaderConfig = {
|
|
16
27
|
title?: string;
|
|
17
28
|
subtitle?: string;
|
|
29
|
+
/** Custom header content. Takes precedence over `title`/`subtitle`. */
|
|
18
30
|
content?: Snippet<[]>;
|
|
19
31
|
class?: ClassValue;
|
|
20
32
|
titleClass?: ClassValue;
|
|
21
33
|
subtitleClass?: ClassValue;
|
|
34
|
+
/** Click handler for the header row. */
|
|
22
35
|
onclick?: () => void;
|
|
23
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* Props for `<Dropdown>` — an action menu attached to a trigger button.
|
|
39
|
+
* Use for context actions, overflow menus, user profile menus, etc.
|
|
40
|
+
*
|
|
41
|
+
* For *form* selection (picking one of many values), use `<Select>`
|
|
42
|
+
* instead — that's a controlled form input.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```svelte
|
|
46
|
+
* <Dropdown
|
|
47
|
+
* label="Actions"
|
|
48
|
+
* sections={[
|
|
49
|
+
* {
|
|
50
|
+
* items: [
|
|
51
|
+
* { label: 'Edit', icon: EditIcon, onclick: () => edit() },
|
|
52
|
+
* { label: 'Duplicate', icon: CopyIcon, onclick: () => duplicate() }
|
|
53
|
+
* ]
|
|
54
|
+
* },
|
|
55
|
+
* { items: [{ label: 'Delete', icon: TrashIcon, onclick: () => remove() }] }
|
|
56
|
+
* ]}
|
|
57
|
+
* />
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
24
60
|
export type DropdownMenuProps = {
|
|
61
|
+
/** Bindable open state. @default false */
|
|
25
62
|
open?: boolean;
|
|
63
|
+
/** Ordered sections of items. A divider renders between adjacent sections. */
|
|
26
64
|
sections: DropSection[];
|
|
65
|
+
/** Trigger button label. */
|
|
27
66
|
label?: string;
|
|
67
|
+
/** Trigger button icon (rendered instead of or alongside `label`). */
|
|
28
68
|
icon?: Component;
|
|
69
|
+
/** Classes on the outer positioned wrapper. */
|
|
29
70
|
containerClass?: ClassValue;
|
|
71
|
+
/** Classes on each item button. */
|
|
30
72
|
itemClass?: ClassValue;
|
|
73
|
+
/** Classes on the trigger button. */
|
|
31
74
|
class?: ClassValue;
|
|
32
75
|
size?: VariantSizes;
|
|
33
76
|
disabled?: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Panel placement anchored to the trigger's corner:
|
|
79
|
+
* - `'bottom-right'` (default) — typical dropdown to the right
|
|
80
|
+
* - `'bottom-left'` — dropdown aligned to the trigger's left edge
|
|
81
|
+
* - `'top-right'` / `'top-left'` — upward-opening (use when near page bottom)
|
|
82
|
+
*/
|
|
34
83
|
position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
84
|
+
/**
|
|
85
|
+
* Explicit panel width. Accepts any CSS value (`'200px'`, `'12rem'`,
|
|
86
|
+
* `'100%'`). @default auto-sized to content
|
|
87
|
+
*/
|
|
35
88
|
width?: string;
|
|
89
|
+
/** Optional header shown above the first section. */
|
|
36
90
|
header?: DropHeaderConfig;
|
|
37
91
|
testId?: string;
|
|
38
92
|
};
|
|
93
|
+
/** Single option in a `<Select>` list. */
|
|
39
94
|
export type SelectItem = {
|
|
95
|
+
/** Visible text. */
|
|
40
96
|
label: string;
|
|
97
|
+
/** Underlying form value. */
|
|
41
98
|
value: string;
|
|
42
99
|
disabled?: boolean;
|
|
100
|
+
/** Optional icon rendered next to the label. */
|
|
43
101
|
icon?: Component;
|
|
102
|
+
/** Short helper text shown below the label in the dropdown. */
|
|
44
103
|
description?: string;
|
|
104
|
+
/**
|
|
105
|
+
* Group name — items with the same `group` are rendered together
|
|
106
|
+
* under a group heading. Items without `group` render at the top.
|
|
107
|
+
*/
|
|
45
108
|
group?: string;
|
|
46
109
|
};
|
|
110
|
+
/**
|
|
111
|
+
* Props for `<Select>` — a controlled single- or multi-select form input
|
|
112
|
+
* with optional search. For free-typing + filter UX prefer `<ComboBox>`;
|
|
113
|
+
* for a short list of radio-style options use `<RadioGroup>`.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```svelte
|
|
117
|
+
* <Select
|
|
118
|
+
* items={[
|
|
119
|
+
* { value: 'draft', label: 'Draft' },
|
|
120
|
+
* { value: 'published', label: 'Published' },
|
|
121
|
+
* { value: 'archived', label: 'Archived' }
|
|
122
|
+
* ]}
|
|
123
|
+
* bind:value={status}
|
|
124
|
+
* />
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```svelte
|
|
129
|
+
* <!-- Multi-select with server-side search -->
|
|
130
|
+
* <Select
|
|
131
|
+
* multiple
|
|
132
|
+
* searchable
|
|
133
|
+
* items={[]}
|
|
134
|
+
* onsearch={async (q) => await api.searchTags(q)}
|
|
135
|
+
* bind:value={selectedTags}
|
|
136
|
+
* />
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
47
139
|
export type SelectProps = {
|
|
140
|
+
/** Static list of options. Omit + pair with `onsearch` for server-side search. */
|
|
48
141
|
items?: SelectItem[];
|
|
142
|
+
/** Bindable selected value (string) or values (`multiple` mode). */
|
|
49
143
|
value?: string | string[];
|
|
144
|
+
/** Allow selecting multiple items. Changes `value` to `string[]`. @default false */
|
|
50
145
|
multiple?: boolean;
|
|
51
146
|
placeholder?: string;
|
|
147
|
+
/** Show a search input at the top of the dropdown. @default false */
|
|
52
148
|
searchable?: boolean;
|
|
53
149
|
disabled?: boolean;
|
|
54
150
|
size?: VariantSizes;
|
|
@@ -58,21 +154,39 @@ export type SelectProps = {
|
|
|
58
154
|
itemClass?: ClassValue;
|
|
59
155
|
triggerClass?: ClassValue;
|
|
60
156
|
searchInputClass?: ClassValue;
|
|
157
|
+
/** Show a × when a value is selected. @default true */
|
|
61
158
|
clearable?: boolean;
|
|
159
|
+
/** Icon rendered in the trigger (e.g. search icon for an "Add filter" menu). */
|
|
62
160
|
icon?: Component;
|
|
63
161
|
iconClass?: ClassValue;
|
|
64
162
|
errors?: string[];
|
|
163
|
+
/** Fires on selection change. Value shape depends on `multiple`. */
|
|
65
164
|
onselect?: ({ value }: {
|
|
66
165
|
value: string | string[];
|
|
67
166
|
}) => void;
|
|
167
|
+
/** Fires when the dropdown panel opens. */
|
|
68
168
|
onopen?: () => void;
|
|
169
|
+
/** Fires when the dropdown panel closes. */
|
|
69
170
|
onclose?: () => void;
|
|
70
171
|
testId?: string;
|
|
172
|
+
/**
|
|
173
|
+
* Server-side search handler. When set, local filtering is bypassed
|
|
174
|
+
* and this is called (debounced by `debounceMs`) whenever the user
|
|
175
|
+
* types. Return items to display.
|
|
176
|
+
*/
|
|
71
177
|
onsearch?: (query: string) => SelectItem[] | Promise<SelectItem[]>;
|
|
178
|
+
/** Debounce delay for `onsearch`. @default 200 */
|
|
72
179
|
debounceMs?: number;
|
|
180
|
+
/** Minimum query length before `onsearch` fires. @default 0 */
|
|
73
181
|
minSearchLength?: number;
|
|
182
|
+
/** Text shown while an async `onsearch` is in flight. @default 'Loading…' */
|
|
74
183
|
loadingText?: string;
|
|
184
|
+
/** Text shown when the item list is empty. @default 'No results' */
|
|
75
185
|
emptyText?: string;
|
|
186
|
+
/**
|
|
187
|
+
* Per-item custom rendering. Receives the item and its state flags.
|
|
188
|
+
* Use for rich options (avatars, two-line cards, etc.).
|
|
189
|
+
*/
|
|
76
190
|
itemSnippet?: Snippet<[SelectItem, {
|
|
77
191
|
highlighted: boolean;
|
|
78
192
|
selected: boolean;
|
|
@@ -30,7 +30,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
|
|
|
30
30
|
headerTitle: string;
|
|
31
31
|
headerSubtitle: string;
|
|
32
32
|
};
|
|
33
|
-
|
|
33
|
+
md: {
|
|
34
34
|
trigger: string;
|
|
35
35
|
item: string;
|
|
36
36
|
itemIcon: string;
|
|
@@ -113,7 +113,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
|
|
|
113
113
|
headerTitle: string;
|
|
114
114
|
headerSubtitle: string;
|
|
115
115
|
};
|
|
116
|
-
|
|
116
|
+
md: {
|
|
117
117
|
trigger: string;
|
|
118
118
|
item: string;
|
|
119
119
|
itemIcon: string;
|
|
@@ -196,7 +196,7 @@ export declare const dropdownMenu: import("tailwind-variants").TVReturnType<{
|
|
|
196
196
|
headerTitle: string;
|
|
197
197
|
headerSubtitle: string;
|
|
198
198
|
};
|
|
199
|
-
|
|
199
|
+
md: {
|
|
200
200
|
trigger: string;
|
|
201
201
|
item: string;
|
|
202
202
|
itemIcon: string;
|
|
@@ -44,7 +44,7 @@ export const dropdownMenu = tv({
|
|
|
44
44
|
headerTitle: 'text-xs',
|
|
45
45
|
headerSubtitle: 'text-xs'
|
|
46
46
|
},
|
|
47
|
-
[Size.
|
|
47
|
+
[Size.MD]: {
|
|
48
48
|
trigger: 'px-3 py-2 text-sm',
|
|
49
49
|
item: 'px-4 py-2 text-sm',
|
|
50
50
|
itemIcon: 'mr-3 size-5',
|
|
@@ -88,7 +88,7 @@ export const dropdownMenu = tv({
|
|
|
88
88
|
},
|
|
89
89
|
defaultVariants: {
|
|
90
90
|
position: 'bottom-right',
|
|
91
|
-
size: Size.
|
|
91
|
+
size: Size.MD,
|
|
92
92
|
isOpen: false,
|
|
93
93
|
iconOnly: false
|
|
94
94
|
}
|
|
@@ -1,45 +1,10 @@
|
|
|
1
1
|
export declare const selectTV: import("tailwind-variants").TVReturnType<{
|
|
2
2
|
size: {
|
|
3
|
-
|
|
3
|
+
[k: string]: {
|
|
4
4
|
trigger: string;
|
|
5
5
|
triggerIcon: string;
|
|
6
|
-
container: string;
|
|
7
|
-
item: string;
|
|
8
|
-
base: string;
|
|
9
|
-
};
|
|
10
|
-
sm: {
|
|
11
|
-
trigger: string;
|
|
12
|
-
triggerIcon: string;
|
|
13
|
-
container: string;
|
|
14
6
|
item: string;
|
|
15
|
-
base: string;
|
|
16
|
-
};
|
|
17
|
-
base: {
|
|
18
|
-
trigger: string;
|
|
19
|
-
triggerIcon: string;
|
|
20
7
|
container: string;
|
|
21
|
-
item: string;
|
|
22
|
-
base: string;
|
|
23
|
-
};
|
|
24
|
-
lg: {
|
|
25
|
-
trigger: string;
|
|
26
|
-
triggerIcon: string;
|
|
27
|
-
container: string;
|
|
28
|
-
item: string;
|
|
29
|
-
base: string;
|
|
30
|
-
};
|
|
31
|
-
xl: {
|
|
32
|
-
trigger: string;
|
|
33
|
-
triggerIcon: string;
|
|
34
|
-
container: string;
|
|
35
|
-
item: string;
|
|
36
|
-
base: string;
|
|
37
|
-
};
|
|
38
|
-
"2xl": {
|
|
39
|
-
trigger: string;
|
|
40
|
-
triggerIcon: string;
|
|
41
|
-
container: string;
|
|
42
|
-
item: string;
|
|
43
8
|
base: string;
|
|
44
9
|
};
|
|
45
10
|
};
|
|
@@ -71,46 +36,11 @@ export declare const selectTV: import("tailwind-variants").TVReturnType<{
|
|
|
71
36
|
emptyMessage: string;
|
|
72
37
|
}, undefined, {
|
|
73
38
|
size: {
|
|
74
|
-
|
|
75
|
-
trigger: string;
|
|
76
|
-
triggerIcon: string;
|
|
77
|
-
container: string;
|
|
78
|
-
item: string;
|
|
79
|
-
base: string;
|
|
80
|
-
};
|
|
81
|
-
sm: {
|
|
82
|
-
trigger: string;
|
|
83
|
-
triggerIcon: string;
|
|
84
|
-
container: string;
|
|
85
|
-
item: string;
|
|
86
|
-
base: string;
|
|
87
|
-
};
|
|
88
|
-
base: {
|
|
89
|
-
trigger: string;
|
|
90
|
-
triggerIcon: string;
|
|
91
|
-
container: string;
|
|
92
|
-
item: string;
|
|
93
|
-
base: string;
|
|
94
|
-
};
|
|
95
|
-
lg: {
|
|
39
|
+
[k: string]: {
|
|
96
40
|
trigger: string;
|
|
97
41
|
triggerIcon: string;
|
|
98
|
-
container: string;
|
|
99
42
|
item: string;
|
|
100
|
-
base: string;
|
|
101
|
-
};
|
|
102
|
-
xl: {
|
|
103
|
-
trigger: string;
|
|
104
|
-
triggerIcon: string;
|
|
105
43
|
container: string;
|
|
106
|
-
item: string;
|
|
107
|
-
base: string;
|
|
108
|
-
};
|
|
109
|
-
"2xl": {
|
|
110
|
-
trigger: string;
|
|
111
|
-
triggerIcon: string;
|
|
112
|
-
container: string;
|
|
113
|
-
item: string;
|
|
114
44
|
base: string;
|
|
115
45
|
};
|
|
116
46
|
};
|
|
@@ -142,46 +72,11 @@ export declare const selectTV: import("tailwind-variants").TVReturnType<{
|
|
|
142
72
|
emptyMessage: string;
|
|
143
73
|
}, import("tailwind-variants").TVReturnType<{
|
|
144
74
|
size: {
|
|
145
|
-
|
|
75
|
+
[k: string]: {
|
|
146
76
|
trigger: string;
|
|
147
77
|
triggerIcon: string;
|
|
148
|
-
container: string;
|
|
149
78
|
item: string;
|
|
150
|
-
base: string;
|
|
151
|
-
};
|
|
152
|
-
sm: {
|
|
153
|
-
trigger: string;
|
|
154
|
-
triggerIcon: string;
|
|
155
79
|
container: string;
|
|
156
|
-
item: string;
|
|
157
|
-
base: string;
|
|
158
|
-
};
|
|
159
|
-
base: {
|
|
160
|
-
trigger: string;
|
|
161
|
-
triggerIcon: string;
|
|
162
|
-
container: string;
|
|
163
|
-
item: string;
|
|
164
|
-
base: string;
|
|
165
|
-
};
|
|
166
|
-
lg: {
|
|
167
|
-
trigger: string;
|
|
168
|
-
triggerIcon: string;
|
|
169
|
-
container: string;
|
|
170
|
-
item: string;
|
|
171
|
-
base: string;
|
|
172
|
-
};
|
|
173
|
-
xl: {
|
|
174
|
-
trigger: string;
|
|
175
|
-
triggerIcon: string;
|
|
176
|
-
container: string;
|
|
177
|
-
item: string;
|
|
178
|
-
base: string;
|
|
179
|
-
};
|
|
180
|
-
"2xl": {
|
|
181
|
-
trigger: string;
|
|
182
|
-
triggerIcon: string;
|
|
183
|
-
container: string;
|
|
184
|
-
item: string;
|
|
185
80
|
base: string;
|
|
186
81
|
};
|
|
187
82
|
};
|
|
@@ -1,15 +1,49 @@
|
|
|
1
1
|
import { tv } from 'tailwind-variants';
|
|
2
2
|
import { Size } from '../../variants.js';
|
|
3
|
+
import { formSizeTokens } from '../../forms/form-size.js';
|
|
4
|
+
// Build the per-size slot overrides from the canonical form-size tokens
|
|
5
|
+
// so Select coordinates visually with Input/Textarea/NumberInput at the
|
|
6
|
+
// same `size` prop. Container max-heights and base min-widths stay here
|
|
7
|
+
// because they're Select-specific (not tied to field sizing).
|
|
8
|
+
const containerHeights = {
|
|
9
|
+
[Size.XS]: 'max-h-32',
|
|
10
|
+
[Size.SM]: 'max-h-40',
|
|
11
|
+
[Size.MD]: 'max-h-56',
|
|
12
|
+
[Size.LG]: 'max-h-64',
|
|
13
|
+
[Size.XL]: 'max-h-72',
|
|
14
|
+
[Size.XXL]: 'max-h-80'
|
|
15
|
+
};
|
|
16
|
+
const minWidths = {
|
|
17
|
+
[Size.XS]: 'min-w-20',
|
|
18
|
+
[Size.SM]: 'min-w-28',
|
|
19
|
+
[Size.MD]: 'min-w-32',
|
|
20
|
+
[Size.LG]: 'min-w-40',
|
|
21
|
+
[Size.XL]: 'min-w-48',
|
|
22
|
+
[Size.XXL]: 'min-w-56'
|
|
23
|
+
};
|
|
24
|
+
const sizeVariants = Object.fromEntries(Object.keys(formSizeTokens).map((key) => {
|
|
25
|
+
const t = formSizeTokens[key];
|
|
26
|
+
return [
|
|
27
|
+
key,
|
|
28
|
+
{
|
|
29
|
+
trigger: `${t.height} ${t.padX} ${t.padY} ${t.text} ${t.gap} ${t.radius} ${t.shadow}`,
|
|
30
|
+
triggerIcon: t.iconSize,
|
|
31
|
+
item: `${t.padX} ${t.padY} ${t.text}`,
|
|
32
|
+
container: containerHeights[key],
|
|
33
|
+
base: minWidths[key]
|
|
34
|
+
}
|
|
35
|
+
];
|
|
36
|
+
}));
|
|
3
37
|
export const selectTV = tv({
|
|
4
38
|
slots: {
|
|
5
39
|
base: 'w-full',
|
|
6
40
|
trigger: `relative flex items-center justify-between w-full text-left bg-white border
|
|
7
|
-
border-default-300
|
|
41
|
+
border-default-300 focus-within:outline-none focus-within:ring-2 focus-within:ring-offset-2 focus-within:border-primary-500 focus-within:ring-primary-500 cursor-pointer transition-colors hover:border-default-400`,
|
|
8
42
|
triggerIcon: 'transition-transform duration-200 text-default-500',
|
|
9
43
|
container: 'absolute z-50 w-full mt-1 bg-white overflow-clip border border-default-200 rounded-md shadow-sm origin-top-left top-full left-0 mt-2',
|
|
10
44
|
searchInput: 'flex items-center gap-x-3 w-full outline-none px-2 h-10 border-b border-b-default-200',
|
|
11
45
|
list: 'py-1 max-h-60 overflow-x-clip overflow-y-auto h-full',
|
|
12
|
-
item: `w-full
|
|
46
|
+
item: `w-full text-left
|
|
13
47
|
data-[highlighted=true]:bg-default-100 data-[highlighted=true]:text-default-700
|
|
14
48
|
data-[selected=true]:bg-info-100 data-[selected=true]:text-info-500 data-[selected=true]:font-medium
|
|
15
49
|
data-[selected=true]:data-[highlighted=true]:bg-info-200 data-[selected=true]:data-[highlighted=true]:text-info-500
|
|
@@ -17,50 +51,7 @@ export const selectTV = tv({
|
|
|
17
51
|
emptyMessage: 'px-3 py-2 text-sm text-default-500'
|
|
18
52
|
},
|
|
19
53
|
variants: {
|
|
20
|
-
size:
|
|
21
|
-
[Size.XS]: {
|
|
22
|
-
trigger: 'h-6 px-2 py-1 text-xs gap-1',
|
|
23
|
-
triggerIcon: 'h-3 w-3',
|
|
24
|
-
container: 'max-h-40',
|
|
25
|
-
item: 'px-2 py-1 text-xs',
|
|
26
|
-
base: 'min-w-24'
|
|
27
|
-
},
|
|
28
|
-
[Size.SM]: {
|
|
29
|
-
trigger: 'h-8 px-3 py-2 text-sm gap-1.5',
|
|
30
|
-
triggerIcon: 'h-3.5 w-3.5',
|
|
31
|
-
container: 'max-h-48',
|
|
32
|
-
item: 'px-2.5 py-1.5 text-xs',
|
|
33
|
-
base: 'min-w-32'
|
|
34
|
-
},
|
|
35
|
-
[Size.BASE]: {
|
|
36
|
-
trigger: 'h-10 px-3 py-2 text-base gap-2',
|
|
37
|
-
triggerIcon: 'h-4 w-4',
|
|
38
|
-
container: 'max-h-60',
|
|
39
|
-
item: 'px-3 py-2 text-sm',
|
|
40
|
-
base: 'min-w-40'
|
|
41
|
-
},
|
|
42
|
-
[Size.LG]: {
|
|
43
|
-
trigger: 'h-12 px-3 py-2 text-lg gap-2.5',
|
|
44
|
-
triggerIcon: 'h-5 w-5',
|
|
45
|
-
container: 'max-h-72',
|
|
46
|
-
item: 'px-4 py-2.5 text-base',
|
|
47
|
-
base: 'min-w-48'
|
|
48
|
-
},
|
|
49
|
-
[Size.XL]: {
|
|
50
|
-
trigger: 'h-12 px-5 py-3 text-lg gap-3',
|
|
51
|
-
triggerIcon: 'h-6 w-6',
|
|
52
|
-
container: 'max-h-80',
|
|
53
|
-
item: 'px-5 py-3 text-lg',
|
|
54
|
-
base: 'min-w-56'
|
|
55
|
-
},
|
|
56
|
-
[Size.XXL]: {
|
|
57
|
-
trigger: 'h-14 px-6 py-3.5 text-xl gap-4',
|
|
58
|
-
triggerIcon: 'h-7 w-7',
|
|
59
|
-
container: 'max-h-96',
|
|
60
|
-
item: 'px-6 py-3.5 text-xl',
|
|
61
|
-
base: 'min-w-64'
|
|
62
|
-
}
|
|
63
|
-
},
|
|
54
|
+
size: sizeVariants,
|
|
64
55
|
disabled: {
|
|
65
56
|
true: {
|
|
66
57
|
trigger: 'opacity-50 cursor-not-allowed hover:border-default-300',
|
|
@@ -80,7 +71,7 @@ export const selectTV = tv({
|
|
|
80
71
|
}
|
|
81
72
|
},
|
|
82
73
|
defaultVariants: {
|
|
83
|
-
size: '
|
|
74
|
+
size: 'md',
|
|
84
75
|
disabled: false,
|
|
85
76
|
multiple: false,
|
|
86
77
|
error: false
|
|
@@ -1,12 +1,43 @@
|
|
|
1
1
|
import type { ClassValue } from 'tailwind-variants';
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
-
|
|
3
|
+
/** Density variants specific to EmptyState. */
|
|
4
|
+
export type EmptyStateSize = 'sm' | 'md' | 'lg' | 'xl';
|
|
5
|
+
/**
|
|
6
|
+
* Props for `<EmptyState>` — centered placeholder shown when a list,
|
|
7
|
+
* table, or panel has no content to display yet. Put an illustration,
|
|
8
|
+
* a clear title, a helpful description, and a primary action that
|
|
9
|
+
* breaks the blank-page anxiety.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```svelte
|
|
13
|
+
* <EmptyState
|
|
14
|
+
* title="No customers yet"
|
|
15
|
+
* description="Once you import or create a customer they'll appear here."
|
|
16
|
+
* >
|
|
17
|
+
* {#snippet icon()}
|
|
18
|
+
* <svg viewBox="0 0 24 24">…</svg>
|
|
19
|
+
* {/snippet}
|
|
20
|
+
* {#snippet action()}
|
|
21
|
+
* <Button color="primary" onclick={create}>Add customer</Button>
|
|
22
|
+
* {/snippet}
|
|
23
|
+
* </EmptyState>
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
4
26
|
export type EmptyStateProps = {
|
|
27
|
+
/** Heading — keep short, focus on what's missing. */
|
|
5
28
|
title: string;
|
|
29
|
+
/** One-sentence explanation of what's missing and what to do. */
|
|
6
30
|
description?: string;
|
|
31
|
+
/** @default 'md' */
|
|
7
32
|
size?: EmptyStateSize;
|
|
8
33
|
class?: ClassValue;
|
|
34
|
+
/**
|
|
35
|
+
* Icon/illustration snippet. Unlike other components that take an icon
|
|
36
|
+
* `Component`, EmptyState uses a `Snippet` so consumers can inline SVGs
|
|
37
|
+
* or illustrations with arbitrary markup (common empty-state pattern).
|
|
38
|
+
*/
|
|
9
39
|
icon?: Snippet;
|
|
40
|
+
/** Primary action snippet — usually a single Button. */
|
|
10
41
|
action?: Snippet;
|
|
11
42
|
testId?: string;
|
|
12
43
|
};
|
|
@@ -6,7 +6,7 @@ export declare const emptyState: import("tailwind-variants").TVReturnType<{
|
|
|
6
6
|
title: string;
|
|
7
7
|
description: string;
|
|
8
8
|
};
|
|
9
|
-
|
|
9
|
+
md: {
|
|
10
10
|
wrapper: string;
|
|
11
11
|
iconWrapper: string;
|
|
12
12
|
title: string;
|
|
@@ -39,7 +39,7 @@ export declare const emptyState: import("tailwind-variants").TVReturnType<{
|
|
|
39
39
|
title: string;
|
|
40
40
|
description: string;
|
|
41
41
|
};
|
|
42
|
-
|
|
42
|
+
md: {
|
|
43
43
|
wrapper: string;
|
|
44
44
|
iconWrapper: string;
|
|
45
45
|
title: string;
|
|
@@ -72,7 +72,7 @@ export declare const emptyState: import("tailwind-variants").TVReturnType<{
|
|
|
72
72
|
title: string;
|
|
73
73
|
description: string;
|
|
74
74
|
};
|
|
75
|
-
|
|
75
|
+
md: {
|
|
76
76
|
wrapper: string;
|
|
77
77
|
iconWrapper: string;
|
|
78
78
|
title: string;
|
|
@@ -16,7 +16,7 @@ export const emptyState = tv({
|
|
|
16
16
|
title: 'text-sm',
|
|
17
17
|
description: 'text-xs'
|
|
18
18
|
},
|
|
19
|
-
[Size.
|
|
19
|
+
[Size.MD]: {
|
|
20
20
|
wrapper: 'gap-3 p-8',
|
|
21
21
|
iconWrapper: 'h-10 w-10',
|
|
22
22
|
title: 'text-base',
|
|
@@ -37,6 +37,6 @@ export const emptyState = tv({
|
|
|
37
37
|
}
|
|
38
38
|
},
|
|
39
39
|
defaultVariants: {
|
|
40
|
-
size: Size.
|
|
40
|
+
size: Size.MD
|
|
41
41
|
}
|
|
42
42
|
});
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
import Button from '../../button/Button.svelte';
|
|
5
5
|
import Spinner from '../spinner/Spinner.svelte';
|
|
6
6
|
import { Size, Color } from '../../variants.js';
|
|
7
|
+
import { fade } from 'svelte/transition';
|
|
8
|
+
import { flip } from 'svelte/animate';
|
|
9
|
+
import { quintOut } from 'svelte/easing';
|
|
7
10
|
import type { FileUploadProps, StagedFile } from '../../index.js';
|
|
8
11
|
|
|
9
12
|
let {
|
|
@@ -330,6 +333,8 @@
|
|
|
330
333
|
class={cn('flex items-center gap-3 px-3 py-2', status === 'success' && 'opacity-60')}
|
|
331
334
|
data-fileupload-row=""
|
|
332
335
|
data-status={status}
|
|
336
|
+
transition:fade={{ duration: 300, easing: quintOut }}
|
|
337
|
+
animate:flip={{ duration: 350, easing: quintOut }}
|
|
333
338
|
>
|
|
334
339
|
{#if status === 'ready'}
|
|
335
340
|
<span
|
|
@@ -24,6 +24,54 @@ export interface StagedFile {
|
|
|
24
24
|
/** Optional error message rendered under the file name while status='error'. */
|
|
25
25
|
error?: string;
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Props for `<FileUpload>` — a flexible drag-and-drop zone that supports
|
|
29
|
+
* single-file pick, multi-file staging, and "rich mode" with per-file
|
|
30
|
+
* upload progress.
|
|
31
|
+
*
|
|
32
|
+
* **Mode selection** is via `maxFiles`:
|
|
33
|
+
* - `maxFiles=1` (default) → single-file: `onfiles` fires immediately.
|
|
34
|
+
* - `maxFiles>1` (omit `bind:files`) → simple multi-file staging.
|
|
35
|
+
* - `maxFiles>1` + `bind:files` + `clearAfterUpload={false}` → rich mode
|
|
36
|
+
* with per-file status icons + progress bars driven by the consumer.
|
|
37
|
+
*
|
|
38
|
+
* For browsing files already on a remote storage (S3, GDrive), use
|
|
39
|
+
* `<FileBrowser>` instead.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```svelte
|
|
43
|
+
* <!-- Simple single-file -->
|
|
44
|
+
* <FileUpload allowedMimeTypes={['.csv']} onfiles={(files) => upload(files[0])} />
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```svelte
|
|
49
|
+
* <!-- Multi-file rich mode with per-row progress -->
|
|
50
|
+
* <script lang="ts">
|
|
51
|
+
* let files = $state<StagedFile[]>([]);
|
|
52
|
+
* async function handleFiles(toUpload: File[]) {
|
|
53
|
+
* for (const file of toUpload) {
|
|
54
|
+
* const item = files.find(f => f.file === file)!;
|
|
55
|
+
* item.status = 'uploading';
|
|
56
|
+
* try {
|
|
57
|
+
* await api.upload(file, (pct) => (item.progress = pct));
|
|
58
|
+
* item.status = 'success';
|
|
59
|
+
* } catch (err) {
|
|
60
|
+
* item.status = 'error';
|
|
61
|
+
* item.error = String(err);
|
|
62
|
+
* }
|
|
63
|
+
* }
|
|
64
|
+
* }
|
|
65
|
+
* </script>
|
|
66
|
+
*
|
|
67
|
+
* <FileUpload
|
|
68
|
+
* maxFiles={10}
|
|
69
|
+
* bind:files
|
|
70
|
+
* clearAfterUpload={false}
|
|
71
|
+
* onfiles={handleFiles}
|
|
72
|
+
* />
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
27
75
|
export interface FileUploadProps {
|
|
28
76
|
/**
|
|
29
77
|
* Array of allowed file MIME types or extensions.
|
|
@@ -119,12 +167,23 @@ export interface FileUploadProps {
|
|
|
119
167
|
/** Optional snippet rendered above the dropzone (for titles, selects, banners). */
|
|
120
168
|
header?: Snippet;
|
|
121
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* Props for `<FilesPreview>` — renders a list of already-uploaded files
|
|
172
|
+
* with per-row delete affordance. Pair with `<FileUpload>` to show the
|
|
173
|
+
* "files uploaded so far" beneath the dropzone.
|
|
174
|
+
*/
|
|
122
175
|
export interface FilePreviewProps {
|
|
123
176
|
files: UploadedFile[];
|
|
177
|
+
/** Fires when the user clicks the × on a file row. */
|
|
124
178
|
ondelete?: (fileId: string, index: number) => void;
|
|
125
179
|
class?: ClassValue;
|
|
126
180
|
testId?: string;
|
|
127
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* A file that has already been uploaded to your backend (vs `StagedFile`,
|
|
184
|
+
* which represents a file in flight). Field naming mirrors common
|
|
185
|
+
* server-returned shapes — adapt as needed.
|
|
186
|
+
*/
|
|
128
187
|
export interface UploadedFile {
|
|
129
188
|
FileID: string;
|
|
130
189
|
OriginalFilename: string;
|