@makolabs/ripple 2.5.8 → 3.0.0
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 +247 -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 -3
- package/dist/elements/dropdown/select.js +2 -2
- 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 +234 -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/DateRange.svelte +4 -2
- package/dist/forms/Input.svelte +2 -2
- package/dist/forms/MarketSelector.svelte +8 -3
- package/dist/forms/NumberInput.svelte +4 -4
- package/dist/forms/RadioGroup.svelte +123 -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 +14 -5
- package/dist/forms/Textarea.svelte +126 -0
- package/dist/forms/Textarea.svelte.d.ts +4 -0
- package/dist/forms/Toggle.svelte +8 -8
- package/dist/forms/calendar/Calendar.svelte +218 -0
- package/dist/forms/calendar/Calendar.svelte.d.ts +4 -0
- package/dist/forms/calendar/calendar-types.d.ts +46 -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 +144 -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-types.d.ts +425 -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 +16 -5
- package/dist/forms/slider.d.ts +3 -3
- package/dist/forms/slider.js +2 -2
- package/dist/funcs/user-management.remote.d.ts +1 -1
- package/dist/funcs/user-management.remote.js +2 -2
- 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
|
}
|
|
@@ -14,7 +14,7 @@ export declare const selectTV: import("tailwind-variants").TVReturnType<{
|
|
|
14
14
|
item: string;
|
|
15
15
|
base: string;
|
|
16
16
|
};
|
|
17
|
-
|
|
17
|
+
md: {
|
|
18
18
|
trigger: string;
|
|
19
19
|
triggerIcon: string;
|
|
20
20
|
container: string;
|
|
@@ -85,7 +85,7 @@ export declare const selectTV: import("tailwind-variants").TVReturnType<{
|
|
|
85
85
|
item: string;
|
|
86
86
|
base: string;
|
|
87
87
|
};
|
|
88
|
-
|
|
88
|
+
md: {
|
|
89
89
|
trigger: string;
|
|
90
90
|
triggerIcon: string;
|
|
91
91
|
container: string;
|
|
@@ -156,7 +156,7 @@ export declare const selectTV: import("tailwind-variants").TVReturnType<{
|
|
|
156
156
|
item: string;
|
|
157
157
|
base: string;
|
|
158
158
|
};
|
|
159
|
-
|
|
159
|
+
md: {
|
|
160
160
|
trigger: string;
|
|
161
161
|
triggerIcon: string;
|
|
162
162
|
container: string;
|
|
@@ -32,7 +32,7 @@ export const selectTV = tv({
|
|
|
32
32
|
item: 'px-2.5 py-1.5 text-xs',
|
|
33
33
|
base: 'min-w-32'
|
|
34
34
|
},
|
|
35
|
-
[Size.
|
|
35
|
+
[Size.MD]: {
|
|
36
36
|
trigger: 'h-10 px-3 py-2 text-base gap-2',
|
|
37
37
|
triggerIcon: 'h-4 w-4',
|
|
38
38
|
container: 'max-h-60',
|
|
@@ -80,7 +80,7 @@ export const selectTV = tv({
|
|
|
80
80
|
}
|
|
81
81
|
},
|
|
82
82
|
defaultVariants: {
|
|
83
|
-
size: '
|
|
83
|
+
size: 'md',
|
|
84
84
|
disabled: false,
|
|
85
85
|
multiple: false,
|
|
86
86
|
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;
|
|
@@ -4,7 +4,35 @@
|
|
|
4
4
|
import type { ClassValue } from 'tailwind-variants';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Pagination
|
|
7
|
+
* Props for `<Pagination>` — page navigation controls. Used standalone
|
|
8
|
+
* for client-driven lists, or automatically inside `<Table>` when
|
|
9
|
+
* `pagination` is on.
|
|
10
|
+
*
|
|
11
|
+
* `currentPage` is a regular (non-bindable) prop — pass it in and
|
|
12
|
+
* update via `onpagechange`, or set `internalState={true}` and omit
|
|
13
|
+
* `currentPage` to let the component track pages itself. Most apps
|
|
14
|
+
* prefer external state so the URL or a store can drive it.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```svelte
|
|
18
|
+
* <Pagination
|
|
19
|
+
* currentPage={page}
|
|
20
|
+
* totalItems={42}
|
|
21
|
+
* pageSize={10}
|
|
22
|
+
* onpagechange={(p) => goto(`?page=${p}`)}
|
|
23
|
+
* />
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```svelte
|
|
28
|
+
* <!-- Compact "Page 3 of 7" mode for tight footers -->
|
|
29
|
+
* <Pagination
|
|
30
|
+
* {totalItems}
|
|
31
|
+
* pageSize={20}
|
|
32
|
+
* template="compact"
|
|
33
|
+
* showFirstLast={false}
|
|
34
|
+
* />
|
|
35
|
+
* ```
|
|
8
36
|
*/
|
|
9
37
|
export interface PaginationProps {
|
|
10
38
|
/** Current page number (1-indexed). If not provided, component manages state internally. */
|
|
@@ -14,13 +42,13 @@
|
|
|
14
42
|
/** Number of items per page */
|
|
15
43
|
pageSize?: number;
|
|
16
44
|
/** Callback when page changes */
|
|
17
|
-
|
|
45
|
+
onpagechange?: (page: number) => void;
|
|
18
46
|
/** Callback when page size changes */
|
|
19
|
-
|
|
47
|
+
onpagesizechange?: (pageSize: number) => void;
|
|
20
48
|
/** Callback when first page is clicked */
|
|
21
|
-
|
|
49
|
+
onfirstpage?: () => void;
|
|
22
50
|
/** Callback when last page is clicked */
|
|
23
|
-
|
|
51
|
+
onlastpage?: () => void;
|
|
24
52
|
/** Whether pagination controls are disabled */
|
|
25
53
|
disabled?: boolean;
|
|
26
54
|
/** Show page size selector */
|
|
@@ -62,10 +90,10 @@
|
|
|
62
90
|
currentPage: externalCurrentPage,
|
|
63
91
|
totalItems,
|
|
64
92
|
pageSize: externalPageSize,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
93
|
+
onpagechange,
|
|
94
|
+
onpagesizechange,
|
|
95
|
+
onfirstpage,
|
|
96
|
+
onlastpage,
|
|
69
97
|
disabled = false,
|
|
70
98
|
showPageSize = false,
|
|
71
99
|
pageSizeOptions = [5, 10, 25, 50, 100],
|
|
@@ -140,7 +168,7 @@
|
|
|
140
168
|
if (internalState && externalCurrentPage === undefined) {
|
|
141
169
|
internalCurrentPage = page;
|
|
142
170
|
}
|
|
143
|
-
|
|
171
|
+
onpagechange?.(page);
|
|
144
172
|
}
|
|
145
173
|
}
|
|
146
174
|
|
|
@@ -150,8 +178,8 @@
|
|
|
150
178
|
if (internalState && externalCurrentPage === undefined) {
|
|
151
179
|
internalCurrentPage = targetPage;
|
|
152
180
|
}
|
|
153
|
-
|
|
154
|
-
|
|
181
|
+
onpagechange?.(targetPage);
|
|
182
|
+
onfirstpage?.();
|
|
155
183
|
}
|
|
156
184
|
}
|
|
157
185
|
|
|
@@ -161,8 +189,8 @@
|
|
|
161
189
|
if (internalState && externalCurrentPage === undefined) {
|
|
162
190
|
internalCurrentPage = targetPage;
|
|
163
191
|
}
|
|
164
|
-
|
|
165
|
-
|
|
192
|
+
onpagechange?.(targetPage);
|
|
193
|
+
onlastpage?.();
|
|
166
194
|
}
|
|
167
195
|
}
|
|
168
196
|
|
|
@@ -172,7 +200,7 @@
|
|
|
172
200
|
if (internalState && externalCurrentPage === undefined) {
|
|
173
201
|
internalCurrentPage = targetPage;
|
|
174
202
|
}
|
|
175
|
-
|
|
203
|
+
onpagechange?.(targetPage);
|
|
176
204
|
}
|
|
177
205
|
}
|
|
178
206
|
|
|
@@ -182,7 +210,7 @@
|
|
|
182
210
|
if (internalState && externalCurrentPage === undefined) {
|
|
183
211
|
internalCurrentPage = targetPage;
|
|
184
212
|
}
|
|
185
|
-
|
|
213
|
+
onpagechange?.(targetPage);
|
|
186
214
|
}
|
|
187
215
|
}
|
|
188
216
|
|
|
@@ -203,14 +231,14 @@
|
|
|
203
231
|
if (internalState && externalCurrentPage === undefined) {
|
|
204
232
|
internalCurrentPage = adjustedPage;
|
|
205
233
|
}
|
|
206
|
-
|
|
234
|
+
onpagechange?.(adjustedPage);
|
|
207
235
|
}
|
|
208
236
|
|
|
209
237
|
// Update page size
|
|
210
238
|
if (internalState && externalPageSize === undefined) {
|
|
211
239
|
internalPageSize = newPageSize;
|
|
212
240
|
}
|
|
213
|
-
|
|
241
|
+
onpagesizechange?.(newPageSize);
|
|
214
242
|
}
|
|
215
243
|
|
|
216
244
|
/**
|
|
@@ -246,8 +274,10 @@
|
|
|
246
274
|
const shouldShowPagination = $derived(!hideWhenNoItems || validTotalItems > 0);
|
|
247
275
|
const shouldShowControls = $derived(!hideWhenSinglePage || totalPages > 1);
|
|
248
276
|
|
|
249
|
-
// Default classes using ripple-ui design system
|
|
250
|
-
|
|
277
|
+
// Default classes using ripple-ui design system.
|
|
278
|
+
// `flex-wrap` + `gap-y-3` stacks the info row and button row on narrow
|
|
279
|
+
// viewports instead of squeezing them onto one line.
|
|
280
|
+
const defaultWrapperClass = 'flex flex-wrap items-center justify-between gap-y-3 p-4';
|
|
251
281
|
const defaultInfoClass = 'text-default-500 text-sm';
|
|
252
282
|
const defaultButtonClass =
|
|
253
283
|
'relative inline-flex items-center rounded-md px-2 py-1 text-sm font-medium';
|
|
@@ -293,7 +323,9 @@
|
|
|
293
323
|
{/if}
|
|
294
324
|
|
|
295
325
|
{#if shouldShowControls && showNavigation}
|
|
296
|
-
|
|
326
|
+
<!-- `flex-wrap` lets page-number buttons wrap to a second row
|
|
327
|
+
rather than overflowing the container on narrow viewports. -->
|
|
328
|
+
<div class="flex flex-wrap items-center gap-1">
|
|
297
329
|
{#if showFirstLast}
|
|
298
330
|
<button
|
|
299
331
|
onclick={firstPage}
|