@svadmin/ui 0.72.0 → 0.74.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.
Files changed (276) hide show
  1. package/README.md +62 -22
  2. package/THIRD_PARTY_NOTICES.md +52 -0
  3. package/dist/app.css +8488 -6297
  4. package/dist/app.theme.css +8514 -6374
  5. package/dist/class-properties.generated.d.ts +1 -0
  6. package/dist/class-properties.generated.js +2 -0
  7. package/dist/classnames.d.ts +8 -0
  8. package/dist/classnames.js +26 -0
  9. package/dist/component-registry.d.ts +14977 -0
  10. package/dist/component-registry.js +216 -0
  11. package/dist/components/AboutSettings.svelte +7 -1
  12. package/dist/components/AboutSettings.svelte.d.ts +4 -1
  13. package/dist/components/ActivityFeed.svelte +9 -3
  14. package/dist/components/ActivityFeed.svelte.d.ts +3 -0
  15. package/dist/components/AdminApp.svelte +19 -10
  16. package/dist/components/AdminApp.svelte.d.ts +6 -0
  17. package/dist/components/ApiSettings.svelte +41 -5
  18. package/dist/components/ApprovalCenter.svelte +283 -0
  19. package/dist/components/ApprovalCenter.svelte.d.ts +10 -0
  20. package/dist/components/AuditLogViewer.svelte +3 -1
  21. package/dist/components/AutoForm.svelte +53 -9
  22. package/dist/components/AutoForm.svelte.d.ts +3 -0
  23. package/dist/components/AutoTable.svelte +846 -43
  24. package/dist/components/AutoTable.svelte.d.ts +22 -1
  25. package/dist/components/BoundRecordDetailDrawer.svelte +17 -2
  26. package/dist/components/BoundRecordDetailDrawer.svelte.d.ts +4 -0
  27. package/dist/components/Breadcrumbs.svelte +11 -1
  28. package/dist/components/CancelTaskButton.svelte +12 -42
  29. package/dist/components/ColorPicker.svelte +73 -0
  30. package/dist/components/ColorPicker.svelte.d.ts +15 -0
  31. package/dist/components/ComboboxField.svelte +143 -34
  32. package/dist/components/ComboboxField.svelte.d.ts +4 -2
  33. package/dist/components/CreatePage.svelte +4 -0
  34. package/dist/components/CreatePage.svelte.d.ts +2 -0
  35. package/dist/components/DashboardView.svelte +99 -0
  36. package/dist/components/DashboardView.svelte.d.ts +14 -0
  37. package/dist/components/DatePicker.svelte +10 -0
  38. package/dist/components/DatePicker.svelte.d.ts +6 -0
  39. package/dist/components/DateRangeInput.svelte +155 -0
  40. package/dist/components/DateRangeInput.svelte.d.ts +35 -0
  41. package/dist/components/DateRangePicker.svelte +10 -0
  42. package/dist/components/DateRangePicker.svelte.d.ts +6 -0
  43. package/dist/components/DateTimeInput.svelte +134 -0
  44. package/dist/components/DateTimeInput.svelte.d.ts +27 -0
  45. package/dist/components/DateTimePicker.svelte +10 -0
  46. package/dist/components/DateTimePicker.svelte.d.ts +6 -0
  47. package/dist/components/DevTools.svelte +36 -28
  48. package/dist/components/DevframePanel.svelte +123 -0
  49. package/dist/components/DevframePanel.svelte.d.ts +3 -0
  50. package/dist/components/EditPage.svelte +4 -0
  51. package/dist/components/EditPage.svelte.d.ts +2 -0
  52. package/dist/components/ErrorSummary.svelte +52 -0
  53. package/dist/components/ErrorSummary.svelte.d.ts +14 -0
  54. package/dist/components/FieldRenderer.svelte +172 -99
  55. package/dist/components/FileUpload.svelte +412 -0
  56. package/dist/components/FileUpload.svelte.d.ts +43 -0
  57. package/dist/components/FilterBuilder.svelte +244 -265
  58. package/dist/components/FilterBuilder.svelte.d.ts +3 -0
  59. package/dist/components/FilterCollectionInput.svelte +80 -0
  60. package/dist/components/FilterCollectionInput.svelte.d.ts +10 -0
  61. package/dist/components/GanttChart.svelte +66 -14
  62. package/dist/components/GanttChart.svelte.d.ts +6 -0
  63. package/dist/components/Header.svelte +18 -2
  64. package/dist/components/ImportWizard.svelte +509 -100
  65. package/dist/components/ImportWizard.svelte.d.ts +11 -0
  66. package/dist/components/JsonSchemaForm.svelte +322 -98
  67. package/dist/components/JsonSchemaForm.svelte.d.ts +18 -1
  68. package/dist/components/KanbanBoard.svelte +195 -40
  69. package/dist/components/KanbanBoard.svelte.d.ts +9 -2
  70. package/dist/components/Layout.svelte +4 -3
  71. package/dist/components/LazyAutoForm.svelte +28 -0
  72. package/dist/components/LazyAutoForm.svelte.d.ts +8 -0
  73. package/dist/components/LazyAutoTable.svelte +28 -0
  74. package/dist/components/LazyAutoTable.svelte.d.ts +8 -0
  75. package/dist/components/LazySettingsPage.svelte +28 -0
  76. package/dist/components/LazySettingsPage.svelte.d.ts +8 -0
  77. package/dist/components/LazyShowPage.svelte +28 -0
  78. package/dist/components/LazyShowPage.svelte.d.ts +8 -0
  79. package/dist/components/LazyTaskQueueDrawer.svelte.d.ts +1 -1
  80. package/dist/components/ListPage.svelte +9 -1
  81. package/dist/components/ListPage.svelte.d.ts +5 -0
  82. package/dist/components/LoginPage.svelte +2 -2
  83. package/dist/components/MoneyInput.svelte +25 -0
  84. package/dist/components/MoneyInput.svelte.d.ts +20 -0
  85. package/dist/components/MultiTabKeepAlive.svelte +11 -6
  86. package/dist/components/NotificationsSettings.svelte +69 -2
  87. package/dist/components/NotificationsSettings.svelte.d.ts +25 -1
  88. package/dist/components/NumberInput.svelte +25 -0
  89. package/dist/components/NumberInput.svelte.d.ts +19 -0
  90. package/dist/components/NumericInput.svelte +110 -0
  91. package/dist/components/NumericInput.svelte.d.ts +23 -0
  92. package/dist/components/PercentInput.svelte +25 -0
  93. package/dist/components/PercentInput.svelte.d.ts +20 -0
  94. package/dist/components/PermissionMatrix.svelte +20 -1
  95. package/dist/components/PivotExportButton.svelte +157 -0
  96. package/dist/components/PivotExportButton.svelte.d.ts +16 -0
  97. package/dist/components/PivotTable.svelte +229 -74
  98. package/dist/components/PivotTable.svelte.d.ts +19 -2
  99. package/dist/components/QuickEditDrawer.svelte +4 -1
  100. package/dist/components/QuickEditDrawer.svelte.d.ts +2 -0
  101. package/dist/components/RadioGroup.svelte +121 -0
  102. package/dist/components/RadioGroup.svelte.d.ts +43 -0
  103. package/dist/components/RangeSlider.svelte +127 -0
  104. package/dist/components/RangeSlider.svelte.d.ts +22 -0
  105. package/dist/components/Rate.svelte +121 -0
  106. package/dist/components/Rate.svelte.d.ts +16 -0
  107. package/dist/components/RecordDetailDrawer.svelte +6 -2
  108. package/dist/components/RecordDetailDrawer.svelte.d.ts +4 -0
  109. package/dist/components/RelationPicker.svelte +341 -0
  110. package/dist/components/RelationPicker.svelte.d.ts +26 -0
  111. package/dist/components/ResourceOperationsPage.svelte +25 -19
  112. package/dist/components/ResourceOperationsPage.svelte.d.ts +5 -1
  113. package/dist/components/RetryTaskButton.svelte +12 -42
  114. package/dist/components/SecuritySettings.svelte +29 -5
  115. package/dist/components/SegmentedControl.svelte +145 -0
  116. package/dist/components/SegmentedControl.svelte.d.ts +38 -0
  117. package/dist/components/SettingsPage.svelte +3 -1
  118. package/dist/components/SettingsPage.svelte.d.ts +1 -0
  119. package/dist/components/ShowInferencer.svelte +4 -2
  120. package/dist/components/ShowInferencer.svelte.d.ts +2 -0
  121. package/dist/components/ShowPage.svelte +25 -6
  122. package/dist/components/ShowPage.svelte.d.ts +5 -0
  123. package/dist/components/Sidebar.svelte +5 -5
  124. package/dist/components/Slider.svelte +100 -0
  125. package/dist/components/Slider.svelte.d.ts +19 -0
  126. package/dist/components/SpreadsheetView.svelte +1037 -124
  127. package/dist/components/SpreadsheetView.svelte.d.ts +19 -0
  128. package/dist/components/StepsForm.svelte +5 -5
  129. package/dist/components/SvarAutoTable.svelte +39 -0
  130. package/dist/components/SvarAutoTable.svelte.d.ts +13 -0
  131. package/dist/components/SvarDataGrid.svelte +362 -0
  132. package/dist/components/SvarDataGrid.svelte.d.ts +57 -0
  133. package/dist/components/SvarGridCell.svelte +10 -0
  134. package/dist/components/SvarGridCell.svelte.d.ts +7 -0
  135. package/dist/components/SvarResourceRead.svelte +50 -0
  136. package/dist/components/SvarResourceRead.svelte.d.ts +23 -0
  137. package/dist/components/SvarResourceTable.svelte +63 -0
  138. package/dist/components/SvarResourceTable.svelte.d.ts +42 -0
  139. package/dist/components/SvarResourceTableView.svelte +364 -0
  140. package/dist/components/SvarResourceTableView.svelte.d.ts +4 -0
  141. package/dist/components/TagsInput.svelte +178 -0
  142. package/dist/components/TagsInput.svelte.d.ts +17 -0
  143. package/dist/components/TaskQueueDrawer.svelte +72 -16
  144. package/dist/components/TimePicker.svelte +10 -0
  145. package/dist/components/TimePicker.svelte.d.ts +6 -0
  146. package/dist/components/TreeSelect.svelte +440 -46
  147. package/dist/components/TreeSelect.svelte.d.ts +6 -1
  148. package/dist/components/TreeTable.svelte +484 -82
  149. package/dist/components/TreeTable.svelte.d.ts +24 -1
  150. package/dist/components/TwoFactorAuthPage.svelte +85 -48
  151. package/dist/components/TwoFactorAuthPage.svelte.d.ts +12 -1
  152. package/dist/components/VirtualTable.svelte +116 -20
  153. package/dist/components/VirtualTable.svelte.d.ts +5 -0
  154. package/dist/components/account/CompanyProfilePage.svelte +74 -38
  155. package/dist/components/account/GetStartedPage.svelte +2 -1
  156. package/dist/components/account/ImportMembersPage.svelte +22 -167
  157. package/dist/components/account/ImportMembersPage.svelte.d.ts +4 -1
  158. package/dist/components/account/MemberDirectory.svelte +156 -0
  159. package/dist/components/account/MemberDirectory.svelte.d.ts +19 -0
  160. package/dist/components/account/MembersStarterPage.svelte +9 -55
  161. package/dist/components/account/MembersStarterPage.svelte.d.ts +5 -1
  162. package/dist/components/account/SecurityLogPage.svelte +4 -1
  163. package/dist/components/account/SettingsPlainPage.svelte +7 -38
  164. package/dist/components/account/SettingsPlainPage.svelte.d.ts +4 -1
  165. package/dist/components/account/SettingsSidebarPage.svelte +7 -20
  166. package/dist/components/account/TeamMembersPage.svelte +4 -20
  167. package/dist/components/account/TeamMembersPage.svelte.d.ts +5 -1
  168. package/dist/components/account/UserProfilePage.svelte +3 -25
  169. package/dist/components/account/UserProfilePage.svelte.d.ts +17 -2
  170. package/dist/components/auto-table-grid.d.ts +26 -0
  171. package/dist/components/auto-table-grid.js +1 -0
  172. package/dist/components/buttons/ExportButton.svelte +56 -12
  173. package/dist/components/buttons/ExportButton.svelte.d.ts +11 -0
  174. package/dist/components/content/ContentPageHeader.svelte +12 -9
  175. package/dist/components/content/ContentPageShell.svelte +6 -9
  176. package/dist/components/content/FileBrowser.svelte +35 -0
  177. package/dist/components/content/FileBrowser.svelte.d.ts +14 -0
  178. package/dist/components/content/MetricBlock.svelte +10 -13
  179. package/dist/components/content/NetworkTable.svelte +3 -3
  180. package/dist/components/content/NetworkTable.svelte.d.ts +1 -0
  181. package/dist/components/content/PageToolbar.svelte +6 -10
  182. package/dist/components/content/ReferenceNotice.svelte +5 -0
  183. package/dist/components/content/ReferenceNotice.svelte.d.ts +18 -0
  184. package/dist/components/content/SectionHeader.svelte +8 -13
  185. package/dist/components/content/SettingsFieldRow.svelte +9 -23
  186. package/dist/components/content/SettingsGroup.svelte +11 -27
  187. package/dist/components/content/StatusBadge.svelte +3 -8
  188. package/dist/components/content/WorkspaceLayout.svelte +8 -12
  189. package/dist/components/enterprise/filter-tree.d.ts +48 -0
  190. package/dist/components/enterprise/filter-tree.js +224 -0
  191. package/dist/components/enterprise/json-schema-form.d.ts +39 -0
  192. package/dist/components/enterprise/json-schema-form.js +195 -0
  193. package/dist/components/enterprise/recursive-schema-form.d.ts +30 -0
  194. package/dist/components/enterprise/recursive-schema-form.js +196 -0
  195. package/dist/components/enterprise/spreadsheet-formula.d.ts +12 -0
  196. package/dist/components/enterprise/spreadsheet-formula.js +245 -0
  197. package/dist/components/export-reference.d.ts +2 -0
  198. package/dist/components/export-reference.js +9 -0
  199. package/dist/components/fieldComponentMap.js +2 -0
  200. package/dist/components/fields/DateField.svelte +12 -12
  201. package/dist/components/fields/date-display.d.ts +6 -0
  202. package/dist/components/fields/date-display.js +24 -0
  203. package/dist/components/fields/date-field-value.d.ts +2 -0
  204. package/dist/components/fields/date-field-value.js +13 -0
  205. package/dist/components/json-schema-form-state.d.ts +37 -0
  206. package/dist/components/json-schema-form-state.js +168 -0
  207. package/dist/components/network/TeamCrewTablePage.svelte +6 -1
  208. package/dist/components/network/UserCardsNFTPage.svelte +2 -0
  209. package/dist/components/profile/PublicProfilePage.svelte +2 -0
  210. package/dist/components/record-detail.svelte.d.ts +3 -0
  211. package/dist/components/record-detail.svelte.js +10 -4
  212. package/dist/components/saved-list-views.d.ts +74 -1
  213. package/dist/components/saved-list-views.js +191 -3
  214. package/dist/components/svar-grid-cells.d.ts +14 -0
  215. package/dist/components/svar-grid-cells.js +2 -0
  216. package/dist/components/svar-grid-contract.d.ts +80 -0
  217. package/dist/components/svar-grid-contract.js +159 -0
  218. package/dist/components/svar-grid-interactions.d.ts +54 -0
  219. package/dist/components/svar-grid-interactions.js +174 -0
  220. package/dist/components/svar-grid-loading.d.ts +40 -0
  221. package/dist/components/svar-grid-loading.js +180 -0
  222. package/dist/components/svar-grid-operations.d.ts +37 -0
  223. package/dist/components/svar-grid-operations.js +186 -0
  224. package/dist/components/svar-grid-panes.d.ts +34 -0
  225. package/dist/components/svar-grid-panes.js +66 -0
  226. package/dist/components/svar-grid-resource-loading.d.ts +18 -0
  227. package/dist/components/svar-grid-resource-loading.js +68 -0
  228. package/dist/components/svar-grid-resource-session.svelte.d.ts +29 -0
  229. package/dist/components/svar-grid-resource-session.svelte.js +61 -0
  230. package/dist/components/table-contract.d.ts +12 -1
  231. package/dist/components/task-action.svelte.d.ts +13 -0
  232. package/dist/components/task-action.svelte.js +73 -0
  233. package/dist/components/ui/DesignSystemShowcase.svelte +164 -0
  234. package/dist/components/ui/DesignSystemShowcase.svelte.d.ts +3 -0
  235. package/dist/components/ui/badge/badge-variants.d.ts +3 -2
  236. package/dist/components/ui/badge/badge-variants.js +2 -1
  237. package/dist/components/ui/badge/badge.svelte +3 -0
  238. package/dist/components/ui/badge/badge.svelte.d.ts +1 -0
  239. package/dist/components/ui/button/button-variants.d.ts +5 -4
  240. package/dist/components/ui/button/button-variants.js +7 -2
  241. package/dist/components/ui/checkbox/checkbox.svelte +5 -1
  242. package/dist/components/ui/checkbox/checkbox.svelte.d.ts +5 -1
  243. package/dist/components/ui/input/input.svelte +8 -6
  244. package/dist/components/ui/input/input.svelte.d.ts +4 -1
  245. package/dist/components/ui/select/select.svelte +4 -1
  246. package/dist/components/ui/select/select.svelte.d.ts +2 -1
  247. package/dist/components/ui/textarea/textarea.svelte +2 -1
  248. package/dist/components.css +3110 -0
  249. package/dist/date-input-policy.d.ts +4 -0
  250. package/dist/date-input-policy.js +35 -0
  251. package/dist/design-contract.d.ts +13 -0
  252. package/dist/design-contract.js +11 -0
  253. package/dist/design-system-components.d.ts +100 -0
  254. package/dist/design-system-components.js +101 -0
  255. package/dist/design-system.d.ts +15 -0
  256. package/dist/design-system.js +7 -0
  257. package/dist/devtools-bridge.d.ts +80 -0
  258. package/dist/devtools-bridge.js +92 -0
  259. package/dist/index.d.ts +50 -1
  260. package/dist/index.js +32 -2
  261. package/dist/page-chrome.css +12 -49
  262. package/dist/recipes.d.ts +960 -0
  263. package/dist/recipes.js +264 -0
  264. package/dist/rendering/index.d.ts +87 -0
  265. package/dist/rendering/index.js +117 -0
  266. package/dist/styles/aliases.css +49 -0
  267. package/dist/styles/compatibility.epilogue.css +384 -0
  268. package/dist/styles/compatibility.prelude.css +5513 -0
  269. package/dist/styles/conditional-states.css +28 -0
  270. package/dist/styles/conditional-utilities.css +22 -0
  271. package/dist/tree-table-model.d.ts +24 -0
  272. package/dist/tree-table-model.js +111 -0
  273. package/dist/utils.d.ts +1 -1
  274. package/dist/utils.js +1 -1
  275. package/package.json +40 -10
  276. package/styles-compatibility.json +12 -0
@@ -0,0 +1,61 @@
1
+ import { onDestroy, untrack } from 'svelte';
2
+ import { SvelteMap } from 'svelte/reactivity';
3
+ import { SvarLoadCancelled } from './svar-grid-loading.js';
4
+ /** Query workers remain descendants of the host AdminContext and QueryClientProvider. */
5
+ export function createSvarResourceReads(options) {
6
+ const requests = new SvelteMap();
7
+ const pending = new Map();
8
+ let sequence = 0;
9
+ let alive = true;
10
+ function cancelAll() { for (const entry of [...pending.values()])
11
+ entry.cancel(); }
12
+ onDestroy(() => { alive = false; cancelAll(); });
13
+ $effect.pre(() => {
14
+ const scope = options.scope();
15
+ const available = options.current(scope);
16
+ untrack(() => {
17
+ for (const entry of [...pending.values()])
18
+ if (!available || entry.scope !== scope)
19
+ entry.cancel();
20
+ });
21
+ });
22
+ async function read(input) {
23
+ const { scope, signal } = input;
24
+ const current = () => alive && !signal.aborted && options.current(scope);
25
+ if (!current())
26
+ throw new SvarLoadCancelled();
27
+ if (!await options.authorize(scope, input.parentId))
28
+ throw new Error('Resource read access denied');
29
+ if (!current())
30
+ throw new SvarLoadCancelled();
31
+ return new Promise((resolve, reject) => {
32
+ const id = ++sequence;
33
+ let settled = false;
34
+ const finish = (callback) => {
35
+ if (settled)
36
+ return;
37
+ settled = true;
38
+ signal.removeEventListener('abort', abort);
39
+ pending.delete(id);
40
+ requests.delete(id);
41
+ callback();
42
+ };
43
+ const abort = () => finish(() => reject(new SvarLoadCancelled()));
44
+ pending.set(id, { scope, cancel: abort });
45
+ signal.addEventListener('abort', abort, { once: true });
46
+ if (!current()) {
47
+ abort();
48
+ return;
49
+ }
50
+ const childrenKey = options.childrenKey();
51
+ requests.set(id, {
52
+ resourceName: options.resourceName(), dataScopeKey: options.dataScopeKey(), primaryKey: options.primaryKey(),
53
+ ...(childrenKey === undefined ? {} : { childrenKey }),
54
+ pagination: { ...input.pagination }, filters: input.filters, sorters: input.sorters,
55
+ resolve(page) { finish(() => current() ? resolve(page) : reject(new SvarLoadCancelled())); },
56
+ reject(error) { finish(() => reject(current() ? error : new SvarLoadCancelled())); },
57
+ });
58
+ });
59
+ }
60
+ return { requests, read, cancelAll };
61
+ }
@@ -1,7 +1,18 @@
1
- import type { BaseRecord } from '@svadmin/core';
1
+ import type { BaseRecord, Filter, Sort } from '@svadmin/core';
2
2
  export type TableRecord = BaseRecord & {
3
3
  id: string | number;
4
4
  };
5
+ export type BatchSelection = {
6
+ scope: 'selected';
7
+ ids: (string | number)[];
8
+ currentPageIds: (string | number)[];
9
+ } | {
10
+ scope: 'all';
11
+ filters: Filter[];
12
+ sorters: Sort[];
13
+ total: number;
14
+ excludedIds: (string | number)[];
15
+ };
5
16
  /** The list hook validates business fields; this adapter proves table identity and detaches UI reads. */
6
17
  export declare function copyTableRecord(value: unknown): TableRecord;
7
18
  export declare function tableRowKey(id: string | number): string;
@@ -0,0 +1,13 @@
1
+ import type { TaskProvider } from '@svadmin/core';
2
+ export declare function createTaskAction(options: {
3
+ action: 'cancel' | 'retry';
4
+ taskId: string;
5
+ provider?: TaskProvider | undefined;
6
+ disabled: boolean;
7
+ onSuccess?: (() => void) | undefined;
8
+ onError?: ((error: unknown) => void) | undefined;
9
+ }): {
10
+ run: () => Promise<void>;
11
+ readonly pending: boolean;
12
+ readonly available: boolean;
13
+ };
@@ -0,0 +1,73 @@
1
+ import { onDestroy } from 'svelte';
2
+ import { captureAdminContext, captureAuthSession, queryKeyMatches, TaskError, withValidatedTaskProvider } from '@svadmin/core';
3
+ import { useQueryClient } from '@tanstack/svelte-query';
4
+ export function createTaskAction(options) {
5
+ const context = captureAdminContext();
6
+ const client = useQueryClient();
7
+ const provider = $derived(options.provider ?? context.taskProvider);
8
+ const scope = $derived({
9
+ provider, id: options.taskId, tenant: context.tenantCacheKey?.__svadminTenant,
10
+ auth: context.authProvider, session: captureAuthSession(context.authProvider),
11
+ router: context.routerProvider, access: context.accessControlProvider,
12
+ });
13
+ let mounted = true;
14
+ let attempt = $state.raw();
15
+ function current(origin) {
16
+ return mounted && origin.provider === scope.provider && origin.id === scope.id
17
+ && origin.tenant === scope.tenant && origin.auth === scope.auth
18
+ && origin.router === scope.router && origin.access === scope.access
19
+ && origin.session.isCurrent();
20
+ }
21
+ onDestroy(() => { mounted = false; attempt = undefined; });
22
+ $effect.pre(() => {
23
+ if (attempt && !current(attempt.scope))
24
+ attempt = undefined;
25
+ });
26
+ const pending = $derived(!!attempt && current(attempt.scope));
27
+ const available = $derived(!options.disabled && scope.session.available && !!provider?.[options.action]);
28
+ async function run() {
29
+ if (!available || pending || !mounted || !provider)
30
+ return;
31
+ const origin = scope;
32
+ const token = { scope: origin };
33
+ const matcher = context.queryKeyMatcher();
34
+ const success = options.onSuccess;
35
+ const failure = options.onError;
36
+ attempt = token;
37
+ let error;
38
+ let failed = false;
39
+ let deliver;
40
+ try {
41
+ const operation = withValidatedTaskProvider(provider)[options.action];
42
+ if (!operation)
43
+ return;
44
+ await operation(origin.id);
45
+ if (!current(origin) || attempt !== token)
46
+ return;
47
+ await Promise.allSettled([client.invalidateQueries({
48
+ predicate: query => queryKeyMatches(query.queryKey, { ...matcher, kind: 'task', action: 'list' })
49
+ || queryKeyMatches(query.queryKey, { ...matcher, kind: 'task', action: 'one', id: origin.id }),
50
+ })]);
51
+ }
52
+ catch (cause) {
53
+ failed = true;
54
+ error = cause instanceof TaskError ? cause : new TaskError('TASK_PROVIDER_FAILED');
55
+ }
56
+ finally {
57
+ deliver = current(origin) && attempt === token;
58
+ if (attempt === token)
59
+ attempt = undefined;
60
+ }
61
+ if (!deliver || !current(origin))
62
+ return;
63
+ // 观察者异常不能被误报为服务端操作失败,也不能形成未处理的 Promise。
64
+ try {
65
+ if (failed)
66
+ await failure?.(error);
67
+ else
68
+ await success?.();
69
+ }
70
+ catch { /* 回调由宿主管理,不重试已发出的写入。 */ }
71
+ }
72
+ return { run, get pending() { return pending; }, get available() { return available; } };
73
+ }
@@ -0,0 +1,164 @@
1
+ <script lang="ts">
2
+ import { Button } from "./button/index.js";
3
+ import Badge from "./badge/badge.svelte";
4
+ import Checkbox from "./checkbox/checkbox.svelte";
5
+ import Input from "./input/input.svelte";
6
+ import Select from "./select/select.svelte";
7
+ import * as Tabs from "./tabs/index.js";
8
+ import * as DropdownMenu from "./dropdown-menu/index.js";
9
+ import * as Dialog from "./dialog/index.js";
10
+ import * as Tooltip from "./tooltip/index.js";
11
+ import * as Table from "./table/index.js";
12
+ import StatusBadge from "../content/StatusBadge.svelte";
13
+
14
+ let dialogOpen = $state(false);
15
+ </script>
16
+
17
+ <div class="svadmin-design-system-showcase">
18
+ <section aria-labelledby="buttons-heading">
19
+ <h2 id="buttons-heading">Button states / 按钮状态</h2>
20
+ <div class="svadmin-design-system-showcase__row">
21
+ <Button>Default</Button>
22
+ <Button variant="outline">Outline</Button>
23
+ <Button variant="secondary" size="sm">Compact</Button>
24
+ <Button disabled>Disabled</Button>
25
+ </div>
26
+ </section>
27
+
28
+ <section aria-labelledby="fields-heading">
29
+ <h2 id="fields-heading">Fields and selection / 字段与选择</h2>
30
+ <div class="svadmin-design-system-showcase__grid">
31
+ <Input aria-label="Default input" placeholder="Default" />
32
+ <Input aria-label="Compact input" size="compact" placeholder="Compact" />
33
+ <Select aria-label="Status" size="compact" placeholder="Choose a status" />
34
+ <label class="svadmin-design-system-showcase__checkbox">
35
+ <Checkbox aria-label="Enabled" size="compact" />
36
+ Enabled
37
+ </label>
38
+ </div>
39
+ </section>
40
+
41
+ <section aria-labelledby="status-heading">
42
+ <h2 id="status-heading">Semantic status / 语义状态</h2>
43
+ <div class="svadmin-design-system-showcase__row">
44
+ <Badge variant="subtle-success">Success</Badge>
45
+ <Badge variant="subtle-warning">Warning</Badge>
46
+ <Badge variant="subtle-destructive">Danger</Badge>
47
+ <Badge variant="outline" size="compact">Compact</Badge>
48
+ </div>
49
+ </section>
50
+
51
+ <section aria-labelledby="tabs-heading">
52
+ <h2 id="tabs-heading">Tabs interaction / 标签页交互</h2>
53
+ <Tabs.Root value="overview">
54
+ <Tabs.List aria-label="Design system sections">
55
+ <Tabs.Trigger value="overview">Overview</Tabs.Trigger>
56
+ <Tabs.Trigger value="states">States</Tabs.Trigger>
57
+ <Tabs.Trigger value="disabled" disabled>Disabled</Tabs.Trigger>
58
+ </Tabs.List>
59
+ <Tabs.Content value="overview">Overview content</Tabs.Content>
60
+ <Tabs.Content value="states">State content</Tabs.Content>
61
+ </Tabs.Root>
62
+ </section>
63
+
64
+ <section aria-labelledby="overlay-heading">
65
+ <h2 id="overlay-heading">Menus and overlays / 菜单与浮层</h2>
66
+ <div class="svadmin-design-system-showcase__row">
67
+ <DropdownMenu.Root>
68
+ <DropdownMenu.Trigger class="svadmin-design-system-showcase__trigger">Menu</DropdownMenu.Trigger>
69
+ <DropdownMenu.Content>
70
+ <DropdownMenu.Item>View details</DropdownMenu.Item>
71
+ <DropdownMenu.Item disabled>Disabled action</DropdownMenu.Item>
72
+ </DropdownMenu.Content>
73
+ </DropdownMenu.Root>
74
+ <Dialog.Root bind:open={dialogOpen}>
75
+ <Dialog.Trigger class="svadmin-design-system-showcase__trigger">Open dialog</Dialog.Trigger>
76
+ <Dialog.Content>
77
+ <Dialog.Header>
78
+ <Dialog.Title>Component dialog</Dialog.Title>
79
+ <Dialog.Description>Dialog focus and close behavior.</Dialog.Description>
80
+ </Dialog.Header>
81
+ <Dialog.Footer>
82
+ <Dialog.Close class="svadmin-design-system-showcase__trigger">Close</Dialog.Close>
83
+ </Dialog.Footer>
84
+ </Dialog.Content>
85
+ </Dialog.Root>
86
+ <Tooltip.Root>
87
+ <Tooltip.Trigger class="svadmin-design-system-showcase__trigger">Hover hint</Tooltip.Trigger>
88
+ <Tooltip.Content>Tooltip content</Tooltip.Content>
89
+ </Tooltip.Root>
90
+ </div>
91
+ </section>
92
+
93
+ <section aria-labelledby="table-heading">
94
+ <h2 id="table-heading">Table and status / 表格与状态</h2>
95
+ <div class="svadmin-design-system-showcase__row">
96
+ <StatusBadge status="success" label="Ready" />
97
+ <StatusBadge status="warning" label="Review" />
98
+ <StatusBadge status="danger" label="Blocked" />
99
+ </div>
100
+ <Table.Root>
101
+ <Table.Header>
102
+ <Table.Row>
103
+ <Table.Head>Component</Table.Head>
104
+ <Table.Head>State</Table.Head>
105
+ </Table.Row>
106
+ </Table.Header>
107
+ <Table.Body>
108
+ <Table.Row>
109
+ <Table.Cell>Table</Table.Cell>
110
+ <Table.Cell>Ready</Table.Cell>
111
+ </Table.Row>
112
+ </Table.Body>
113
+ </Table.Root>
114
+ </section>
115
+ </div>
116
+
117
+ <style>
118
+ .svadmin-design-system-showcase {
119
+ display: grid;
120
+ gap: 1.5rem;
121
+ max-width: 64rem;
122
+ padding: 1.5rem;
123
+ color: var(--foreground);
124
+ background: var(--background);
125
+ }
126
+
127
+ .svadmin-design-system-showcase section {
128
+ display: grid;
129
+ gap: 0.75rem;
130
+ }
131
+
132
+ .svadmin-design-system-showcase h2 {
133
+ margin: 0;
134
+ font-size: 0.875rem;
135
+ font-weight: 600;
136
+ }
137
+
138
+ .svadmin-design-system-showcase__row,
139
+ .svadmin-design-system-showcase__grid {
140
+ display: flex;
141
+ flex-wrap: wrap;
142
+ align-items: center;
143
+ gap: 0.75rem;
144
+ }
145
+
146
+ .svadmin-design-system-showcase__grid > :global(*) {
147
+ min-width: 12rem;
148
+ flex: 1 1 12rem;
149
+ }
150
+
151
+ .svadmin-design-system-showcase__checkbox {
152
+ display: flex;
153
+ align-items: center;
154
+ gap: 0.5rem;
155
+ }
156
+
157
+ :global(.svadmin-design-system-showcase__trigger) {
158
+ border: 1px solid var(--border);
159
+ border-radius: 0.375rem;
160
+ background: var(--background);
161
+ padding: 0.375rem 0.625rem;
162
+ color: var(--foreground);
163
+ }
164
+ </style>
@@ -0,0 +1,3 @@
1
+ declare const DesignSystemShowcase: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type DesignSystemShowcase = ReturnType<typeof DesignSystemShowcase>;
3
+ export default DesignSystemShowcase;
@@ -1,6 +1,7 @@
1
- export type BadgeVariant = "default" | "secondary" | "destructive" | "subtle" | "subtle-success" | "subtle-warning" | "subtle-destructive" | "subtle-pill" | "outline" | "ghost" | "link";
1
+ import { type BadgeRecipeProps } from '../../../recipes.js';
2
+ export type BadgeVariant = NonNullable<BadgeRecipeProps["variant"]>;
2
3
  export declare const badgeVariants: ({ variant, class: className, className: extraClassName, }?: {
3
- variant?: BadgeVariant | null;
4
+ variant?: BadgeVariant | null | undefined;
4
5
  class?: string;
5
6
  className?: string;
6
7
  }) => string;
@@ -1 +1,2 @@
1
- export const badgeVariants = ({ variant = "default", class: className = "", className: extraClassName = "", } = {}) => ["svadmin-badge", variant && `svadmin-badge--${variant}`, className, extraClassName].filter(Boolean).join(" ");
1
+ import { badgeRecipe as uiBadge } from '../../../recipes.js';
2
+ export const badgeVariants = ({ variant, class: className = "", className: extraClassName = "", } = {}) => uiBadge({ variant, class: [className, extraClassName].filter(Boolean).join(" ") }).root;
@@ -13,10 +13,12 @@
13
13
  href,
14
14
  class: className,
15
15
  variant = "default",
16
+ size = "default",
16
17
  children,
17
18
  ...restProps
18
19
  }: WithElementRef<HTMLAnchorAttributes> & {
19
20
  variant?: BadgeVariantValue;
21
+ size?: "default" | "compact";
20
22
  } = $props();
21
23
  </script>
22
24
 
@@ -25,6 +27,7 @@
25
27
  bind:this={ref}
26
28
  data-slot="badge"
27
29
  data-variant={variant}
30
+ data-size={size}
28
31
  {href}
29
32
  class={cn(resolveBadgeVariants({ variant }), className)}
30
33
  {...restProps}
@@ -4,6 +4,7 @@ import type { HTMLAnchorAttributes } from "svelte/elements";
4
4
  import { type WithElementRef } from "../../../utils.js";
5
5
  type $$ComponentProps = WithElementRef<HTMLAnchorAttributes> & {
6
6
  variant?: BadgeVariantValue;
7
+ size?: "default" | "compact";
7
8
  };
8
9
  declare const Badge: import("svelte").Component<$$ComponentProps, {}, "ref">;
9
10
  type Badge = ReturnType<typeof Badge>;
@@ -1,8 +1,9 @@
1
- export type ButtonVariant = "default" | "outline" | "secondary" | "ghost" | "destructive" | "link";
2
- export type ButtonSize = "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg";
1
+ import { type ButtonRecipeProps } from '../../../recipes.js';
2
+ export type ButtonVariant = NonNullable<ButtonRecipeProps["variant"]>;
3
+ export type ButtonSize = NonNullable<ButtonRecipeProps["size"]>;
3
4
  export declare const buttonVariants: ({ variant, size, class: className, className: extraClassName, }?: {
4
- variant?: ButtonVariant | null;
5
- size?: ButtonSize | null;
5
+ variant?: ButtonVariant | null | undefined;
6
+ size?: ButtonSize | null | undefined;
6
7
  class?: string;
7
8
  className?: string;
8
9
  }) => string;
@@ -1,2 +1,7 @@
1
- // Keep the public helper for composition, while styles are owned by app.css.
2
- export const buttonVariants = ({ variant = "default", size = "default", class: className = "", className: extraClassName = "", } = {}) => ["svadmin-button", variant && `svadmin-button--${variant}`, size && `svadmin-button-size--${size}`, className, extraClassName].filter(Boolean).join(" ");
1
+ import { buttonRecipe } from '../../../recipes.js';
2
+ // 只组合语义类,不要求消费者安装 Tailwind 编译器或 class merger。
3
+ export const buttonVariants = ({ variant, size, class: className = "", className: extraClassName = "", } = {}) => buttonRecipe({
4
+ variant,
5
+ size,
6
+ class: [className, extraClassName].filter(Boolean).join(" "),
7
+ }).root;
@@ -8,14 +8,18 @@
8
8
  ref = $bindable(null),
9
9
  checked = $bindable(false),
10
10
  indeterminate = $bindable(false),
11
+ size = "default",
11
12
  class: className,
12
13
  ...restProps
13
- }: WithoutChildrenOrChild<CheckboxPrimitive.RootProps> = $props();
14
+ }: Omit<WithoutChildrenOrChild<CheckboxPrimitive.RootProps>, "size"> & {
15
+ size?: "default" | "compact";
16
+ } = $props();
14
17
  </script>
15
18
 
16
19
  <CheckboxPrimitive.Root
17
20
  bind:ref
18
21
  data-slot="checkbox"
22
+ data-size={size}
19
23
  class={cn("svadmin-checkbox", className)}
20
24
  bind:checked
21
25
  bind:indeterminate
@@ -1,4 +1,8 @@
1
1
  import { Checkbox as CheckboxPrimitive } from "bits-ui";
2
- declare const Checkbox: import("svelte").Component<Omit<CheckboxPrimitive.RootProps, "children" | "child">, {}, "ref" | "checked" | "indeterminate">;
2
+ import { type WithoutChildrenOrChild } from "../../../utils.js";
3
+ type $$ComponentProps = Omit<WithoutChildrenOrChild<CheckboxPrimitive.RootProps>, "size"> & {
4
+ size?: "default" | "compact";
5
+ };
6
+ declare const Checkbox: import("svelte").Component<$$ComponentProps, {}, "ref" | "checked" | "indeterminate">;
3
7
  type Checkbox = ReturnType<typeof Checkbox>;
4
8
  export default Checkbox;
@@ -11,7 +11,8 @@
11
11
  ? number | null | undefined
12
12
  : string | null | undefined;
13
13
 
14
- type Props = WithElementRef<Omit<HTMLInputAttributes, "type" | "value">> &
14
+ type Props = WithElementRef<Omit<HTMLInputAttributes, "type" | "value" | "size">> &
15
+ { size?: "default" | "compact"; nativeSize?: number } &
15
16
  (Type extends "file"
16
17
  ? { type: "file"; files?: FileList; value?: never }
17
18
  : { type?: Type; files?: undefined; value?: InputValue });
@@ -22,6 +23,8 @@
22
23
  type,
23
24
  files = $bindable(),
24
25
  disabled,
26
+ size = "default",
27
+ nativeSize,
25
28
  class: className,
26
29
  "data-slot": dataSlot = "input",
27
30
  ...restProps
@@ -30,7 +33,7 @@
30
33
  const i18n = useTranslation();
31
34
  const isFileInput = $derived(type?.toLowerCase() === "file");
32
35
  const isDateInput = $derived(["date", "datetime-local", "month", "week", "time"].includes(type?.toLowerCase() ?? ""));
33
- const attributes = $derived(definedOptions({ ...restProps, disabled }));
36
+ const attributes = $derived(definedOptions({ ...restProps, disabled, size: nativeSize }));
34
37
  const selectedFiles = $derived(files ? Array.from(files) : []);
35
38
  const selectedFileLabel = $derived.by(() => {
36
39
  const firstFile = selectedFiles[0];
@@ -48,6 +51,7 @@
48
51
  <input
49
52
  bind:this={ref}
50
53
  data-slot={dataSlot}
54
+ data-size={size}
51
55
  data-input-type="file"
52
56
  class={cn("svadmin-input", className)}
53
57
  type="file"
@@ -63,10 +67,8 @@
63
67
  <input
64
68
  bind:this={ref}
65
69
  data-slot={dataSlot}
66
- class={cn(
67
- "svadmin-input",
68
- className
69
- )}
70
+ data-size={size}
71
+ class={cn("svadmin-input", className)}
70
72
  {type}
71
73
  lang={isDateInput ? i18n.locale : undefined}
72
74
  bind:value
@@ -1,7 +1,10 @@
1
1
  import type { HTMLInputAttributes, HTMLInputTypeAttribute } from "svelte/elements";
2
2
  declare function $$render<Type extends HTMLInputTypeAttribute | undefined = undefined>(): {
3
- props: Omit<HTMLInputAttributes, "type" | "value"> & {
3
+ props: Omit<HTMLInputAttributes, "type" | "size" | "value"> & {
4
4
  ref?: HTMLElement | null;
5
+ } & {
6
+ size?: "default" | "compact";
7
+ nativeSize?: number;
5
8
  } & (Type extends "file" ? {
6
9
  type: "file";
7
10
  files?: FileList;
@@ -4,8 +4,9 @@
4
4
 
5
5
  // Use HTMLElement instead of HTMLSelectElement to avoid TS error:
6
6
  // HTMLSelectElement.remove() returns void, incompatible with HTMLElement's Element return
7
- type Props = WithElementRef<HTMLSelectAttributes, HTMLElement> & {
7
+ type Props = Omit<WithElementRef<HTMLSelectAttributes, HTMLElement>, "size"> & {
8
8
  placeholder?: string;
9
+ size?: "default" | "compact";
9
10
  };
10
11
 
11
12
  let {
@@ -13,6 +14,7 @@
13
14
  value = $bindable(""),
14
15
  class: className,
15
16
  placeholder,
17
+ size = "default",
16
18
  children,
17
19
  ...restProps
18
20
  }: Props = $props();
@@ -21,6 +23,7 @@
21
23
  <select
22
24
  bind:this={ref}
23
25
  data-slot="select"
26
+ data-size={size}
24
27
  class={cn(
25
28
  "svadmin-select",
26
29
  className
@@ -1,7 +1,8 @@
1
1
  import { type WithElementRef } from "../../../utils.js";
2
2
  import type { HTMLSelectAttributes } from "svelte/elements";
3
- type Props = WithElementRef<HTMLSelectAttributes, HTMLElement> & {
3
+ type Props = Omit<WithElementRef<HTMLSelectAttributes, HTMLElement>, "size"> & {
4
4
  placeholder?: string;
5
+ size?: "default" | "compact";
5
6
  };
6
7
  declare const Select: import("svelte").Component<Props, {}, "value" | "ref">;
7
8
  type Select = ReturnType<typeof Select>;
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { HTMLTextareaAttributes } from "svelte/elements";
3
3
  import { cn, type WithElementRef } from "../../../utils.js";
4
+ import { textareaRecipe as uiTextarea } from "../../../recipes.js";
4
5
 
5
6
  type Props = WithElementRef<HTMLTextareaAttributes, HTMLTextAreaElement>;
6
7
 
@@ -15,7 +16,7 @@
15
16
  <textarea
16
17
  bind:this={ref}
17
18
  data-slot="textarea"
18
- class={cn("svadmin-textarea", className)}
19
+ class={cn(uiTextarea().root, className)}
19
20
  bind:value
20
21
  {...restProps}
21
22
  ></textarea>