@svadmin/ui 0.29.1 → 0.29.2

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 (224) hide show
  1. package/package.json +20 -9
  2. package/src/README.md +0 -18
  3. package/src/actions.ts +0 -110
  4. package/src/app.css +0 -673
  5. package/src/component-registry.svelte.ts +0 -60
  6. package/src/components/AICommandBar.svelte +0 -180
  7. package/src/components/AboutSettings.svelte +0 -106
  8. package/src/components/AdminApp.svelte +0 -199
  9. package/src/components/AnimatedCounter.svelte +0 -46
  10. package/src/components/AnomalyBadge.svelte +0 -65
  11. package/src/components/AppearanceSettings.svelte +0 -183
  12. package/src/components/AuditLogDrawer.svelte +0 -93
  13. package/src/components/AuditLogViewer.svelte +0 -226
  14. package/src/components/Authenticated.svelte +0 -51
  15. package/src/components/AutoForm.svelte +0 -242
  16. package/src/components/AutoSaveIndicator.svelte +0 -35
  17. package/src/components/AutoTable.svelte +0 -839
  18. package/src/components/Breadcrumbs.svelte +0 -58
  19. package/src/components/CanAccess.svelte +0 -23
  20. package/src/components/CatchAllNavigate.svelte +0 -21
  21. package/src/components/ChatDialog.svelte +0 -535
  22. package/src/components/ComboboxField.svelte +0 -129
  23. package/src/components/CommandPalette.svelte +0 -135
  24. package/src/components/ConfigErrorScreen.svelte +0 -126
  25. package/src/components/ConfirmDialog.svelte +0 -53
  26. package/src/components/CopilotPanel.svelte +0 -163
  27. package/src/components/CreatePage.svelte +0 -39
  28. package/src/components/DevTools.svelte +0 -149
  29. package/src/components/DraggableGrid.svelte +0 -86
  30. package/src/components/DraggableHeader.svelte +0 -112
  31. package/src/components/DrawerForm.svelte +0 -35
  32. package/src/components/EditPage.svelte +0 -52
  33. package/src/components/EmptyState.svelte +0 -31
  34. package/src/components/ErrorBoundary.svelte +0 -49
  35. package/src/components/ErrorComponent.svelte +0 -36
  36. package/src/components/FieldRenderer.svelte +0 -357
  37. package/src/components/ForgotPasswordPage.svelte +0 -112
  38. package/src/components/Header.svelte +0 -94
  39. package/src/components/InferencerPanel.svelte +0 -192
  40. package/src/components/InfiniteList.svelte +0 -93
  41. package/src/components/InlineEdit.svelte +0 -88
  42. package/src/components/InsightCard.svelte +0 -98
  43. package/src/components/KeyboardShortcuts.svelte +0 -61
  44. package/src/components/Layout.svelte +0 -167
  45. package/src/components/ListPage.svelte +0 -71
  46. package/src/components/LiveIndicator.svelte +0 -58
  47. package/src/components/LoginPage.svelte +0 -163
  48. package/src/components/MarkdownRenderer.svelte +0 -127
  49. package/src/components/ModalForm.svelte +0 -38
  50. package/src/components/NavigateToResource.svelte +0 -20
  51. package/src/components/PageHeader.svelte +0 -39
  52. package/src/components/PageSkeleton.svelte +0 -71
  53. package/src/components/PasswordInput.svelte +0 -96
  54. package/src/components/PermissionMatrix.svelte +0 -185
  55. package/src/components/ProfilePage.svelte +0 -284
  56. package/src/components/RegisterPage.svelte +0 -112
  57. package/src/components/RolesSettings.svelte +0 -146
  58. package/src/components/SettingsPage.svelte +0 -113
  59. package/src/components/ShowPage.svelte +0 -73
  60. package/src/components/Sidebar.svelte +0 -417
  61. package/src/components/SidebarItem.svelte +0 -129
  62. package/src/components/SmartSuggest.svelte +0 -158
  63. package/src/components/StatsCard.svelte +0 -79
  64. package/src/components/StepsForm.svelte +0 -192
  65. package/src/components/TaskQueueDrawer.svelte +0 -158
  66. package/src/components/TenantSwitcher.svelte +0 -84
  67. package/src/components/ThemedTitle.svelte +0 -32
  68. package/src/components/Toast.svelte +0 -46
  69. package/src/components/TooltipButton.svelte +0 -42
  70. package/src/components/UndoableNotification.svelte +0 -69
  71. package/src/components/UpdatePasswordPage.svelte +0 -89
  72. package/src/components/VirtualTable.svelte +0 -76
  73. package/src/components/VoiceInput.svelte +0 -120
  74. package/src/components/buttons/CloneButton.svelte +0 -30
  75. package/src/components/buttons/CreateButton.svelte +0 -29
  76. package/src/components/buttons/DeleteButton.svelte +0 -59
  77. package/src/components/buttons/EditButton.svelte +0 -30
  78. package/src/components/buttons/ExportButton.svelte +0 -30
  79. package/src/components/buttons/ImportButton.svelte +0 -56
  80. package/src/components/buttons/ListButton.svelte +0 -23
  81. package/src/components/buttons/RefreshButton.svelte +0 -36
  82. package/src/components/buttons/SaveButton.svelte +0 -27
  83. package/src/components/buttons/ShowButton.svelte +0 -31
  84. package/src/components/buttons/index.ts +0 -10
  85. package/src/components/charts/BarChart.svelte +0 -69
  86. package/src/components/charts/LineChart.svelte +0 -115
  87. package/src/components/charts/PieChart.svelte +0 -95
  88. package/src/components/charts/index.ts +0 -3
  89. package/src/components/fieldComponentMap.ts +0 -79
  90. package/src/components/fields/ArrayField.svelte +0 -86
  91. package/src/components/fields/BooleanField.svelte +0 -13
  92. package/src/components/fields/DateField.svelte +0 -6
  93. package/src/components/fields/EmailField.svelte +0 -9
  94. package/src/components/fields/FileField.svelte +0 -14
  95. package/src/components/fields/ImageField.svelte +0 -9
  96. package/src/components/fields/JsonField.svelte +0 -72
  97. package/src/components/fields/MarkdownField.svelte +0 -9
  98. package/src/components/fields/MultiSelectField.svelte +0 -21
  99. package/src/components/fields/NumberField.svelte +0 -6
  100. package/src/components/fields/RelationField.svelte +0 -24
  101. package/src/components/fields/RichTextField.svelte +0 -35
  102. package/src/components/fields/SelectField.svelte +0 -14
  103. package/src/components/fields/TagField.svelte +0 -12
  104. package/src/components/fields/TextField.svelte +0 -11
  105. package/src/components/fields/UrlField.svelte +0 -14
  106. package/src/components/ui/alert/alert-description.svelte +0 -17
  107. package/src/components/ui/alert/alert-title.svelte +0 -17
  108. package/src/components/ui/alert/alert.svelte +0 -44
  109. package/src/components/ui/alert/index.ts +0 -15
  110. package/src/components/ui/alert-dialog/alert-dialog-content.svelte +0 -29
  111. package/src/components/ui/alert-dialog/alert-dialog-description.svelte +0 -16
  112. package/src/components/ui/alert-dialog/alert-dialog-footer.svelte +0 -11
  113. package/src/components/ui/alert-dialog/alert-dialog-header.svelte +0 -11
  114. package/src/components/ui/alert-dialog/alert-dialog-overlay.svelte +0 -16
  115. package/src/components/ui/alert-dialog/alert-dialog-portal.svelte +0 -6
  116. package/src/components/ui/alert-dialog/alert-dialog-title.svelte +0 -16
  117. package/src/components/ui/alert-dialog/index.ts +0 -20
  118. package/src/components/ui/avatar/avatar.svelte +0 -63
  119. package/src/components/ui/avatar/index.ts +0 -2
  120. package/src/components/ui/badge/badge.svelte +0 -49
  121. package/src/components/ui/badge/index.ts +0 -3
  122. package/src/components/ui/breadcrumb/breadcrumb-ellipsis.svelte +0 -18
  123. package/src/components/ui/breadcrumb/breadcrumb-item.svelte +0 -15
  124. package/src/components/ui/breadcrumb/breadcrumb-link.svelte +0 -15
  125. package/src/components/ui/breadcrumb/breadcrumb-list.svelte +0 -15
  126. package/src/components/ui/breadcrumb/breadcrumb-page.svelte +0 -18
  127. package/src/components/ui/breadcrumb/breadcrumb-separator.svelte +0 -22
  128. package/src/components/ui/breadcrumb/breadcrumb.svelte +0 -11
  129. package/src/components/ui/breadcrumb/index.ts +0 -7
  130. package/src/components/ui/button/button.svelte +0 -90
  131. package/src/components/ui/button/index.ts +0 -18
  132. package/src/components/ui/card/card-action.svelte +0 -23
  133. package/src/components/ui/card/card-content.svelte +0 -20
  134. package/src/components/ui/card/card-description.svelte +0 -20
  135. package/src/components/ui/card/card-footer.svelte +0 -20
  136. package/src/components/ui/card/card-header.svelte +0 -23
  137. package/src/components/ui/card/card-title.svelte +0 -15
  138. package/src/components/ui/card/card.svelte +0 -22
  139. package/src/components/ui/card/index.ts +0 -25
  140. package/src/components/ui/checkbox/checkbox.svelte +0 -39
  141. package/src/components/ui/checkbox/index.ts +0 -6
  142. package/src/components/ui/collapsible/index.ts +0 -7
  143. package/src/components/ui/command/command-dialog.svelte +0 -31
  144. package/src/components/ui/command/index.ts +0 -2
  145. package/src/components/ui/context-menu/index.ts +0 -11
  146. package/src/components/ui/dialog/dialog-close.svelte +0 -11
  147. package/src/components/ui/dialog/dialog-content.svelte +0 -48
  148. package/src/components/ui/dialog/dialog-description.svelte +0 -17
  149. package/src/components/ui/dialog/dialog-footer.svelte +0 -32
  150. package/src/components/ui/dialog/dialog-header.svelte +0 -20
  151. package/src/components/ui/dialog/dialog-overlay.svelte +0 -17
  152. package/src/components/ui/dialog/dialog-portal.svelte +0 -7
  153. package/src/components/ui/dialog/dialog-title.svelte +0 -17
  154. package/src/components/ui/dialog/dialog-trigger.svelte +0 -11
  155. package/src/components/ui/dialog/dialog.svelte +0 -7
  156. package/src/components/ui/dialog/index.ts +0 -34
  157. package/src/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +0 -43
  158. package/src/components/ui/dropdown-menu/dropdown-menu-content.svelte +0 -35
  159. package/src/components/ui/dropdown-menu/dropdown-menu-item.svelte +0 -36
  160. package/src/components/ui/dropdown-menu/dropdown-menu-separator.svelte +0 -10
  161. package/src/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +0 -27
  162. package/src/components/ui/dropdown-menu/dropdown-menu.svelte +0 -45
  163. package/src/components/ui/dropdown-menu/index.ts +0 -21
  164. package/src/components/ui/input/index.ts +0 -7
  165. package/src/components/ui/input/input.svelte +0 -48
  166. package/src/components/ui/label/index.ts +0 -1
  167. package/src/components/ui/label/label.svelte +0 -18
  168. package/src/components/ui/pagination/index.ts +0 -7
  169. package/src/components/ui/pagination/pagination-content.svelte +0 -11
  170. package/src/components/ui/pagination/pagination-ellipsis.svelte +0 -12
  171. package/src/components/ui/pagination/pagination-item.svelte +0 -11
  172. package/src/components/ui/pagination/pagination-link.svelte +0 -26
  173. package/src/components/ui/pagination/pagination-next.svelte +0 -22
  174. package/src/components/ui/pagination/pagination-previous.svelte +0 -22
  175. package/src/components/ui/pagination/pagination.svelte +0 -11
  176. package/src/components/ui/popover/index.ts +0 -12
  177. package/src/components/ui/popover/popover-content.svelte +0 -25
  178. package/src/components/ui/progress/index.ts +0 -1
  179. package/src/components/ui/progress/progress.svelte +0 -22
  180. package/src/components/ui/scroll-area/index.ts +0 -1
  181. package/src/components/ui/scroll-area/scroll-area.svelte +0 -20
  182. package/src/components/ui/select/index.ts +0 -2
  183. package/src/components/ui/select/select.svelte +0 -36
  184. package/src/components/ui/separator/index.ts +0 -7
  185. package/src/components/ui/separator/separator.svelte +0 -23
  186. package/src/components/ui/sheet/index.ts +0 -16
  187. package/src/components/ui/sheet/sheet-content.svelte +0 -28
  188. package/src/components/ui/sheet/sheet-description.svelte +0 -22
  189. package/src/components/ui/sheet/sheet-footer.svelte +0 -22
  190. package/src/components/ui/sheet/sheet-header.svelte +0 -22
  191. package/src/components/ui/sheet/sheet-title.svelte +0 -22
  192. package/src/components/ui/sheet/sheet.svelte +0 -78
  193. package/src/components/ui/skeleton/index.ts +0 -2
  194. package/src/components/ui/skeleton/skeleton.svelte +0 -21
  195. package/src/components/ui/switch/index.ts +0 -2
  196. package/src/components/ui/switch/switch.svelte +0 -49
  197. package/src/components/ui/table/index.ts +0 -28
  198. package/src/components/ui/table/table-body.svelte +0 -15
  199. package/src/components/ui/table/table-caption.svelte +0 -20
  200. package/src/components/ui/table/table-cell.svelte +0 -15
  201. package/src/components/ui/table/table-footer.svelte +0 -20
  202. package/src/components/ui/table/table-head.svelte +0 -15
  203. package/src/components/ui/table/table-header.svelte +0 -20
  204. package/src/components/ui/table/table-row.svelte +0 -15
  205. package/src/components/ui/table/table.svelte +0 -17
  206. package/src/components/ui/tabs/index.ts +0 -15
  207. package/src/components/ui/tabs/tabs-content.svelte +0 -30
  208. package/src/components/ui/tabs/tabs-list.svelte +0 -26
  209. package/src/components/ui/tabs/tabs-trigger.svelte +0 -37
  210. package/src/components/ui/tabs/tabs.svelte +0 -27
  211. package/src/components/ui/textarea/index.ts +0 -2
  212. package/src/components/ui/textarea/textarea.svelte +0 -24
  213. package/src/components/ui/tooltip/index.ts +0 -19
  214. package/src/components/ui/tooltip/tooltip-content.svelte +0 -52
  215. package/src/components/ui/tooltip/tooltip-portal.svelte +0 -7
  216. package/src/components/ui/tooltip/tooltip-provider.svelte +0 -7
  217. package/src/components/ui/tooltip/tooltip-trigger.svelte +0 -7
  218. package/src/components/ui/tooltip/tooltip.svelte +0 -10
  219. package/src/editor-config.svelte.ts +0 -23
  220. package/src/index.ts +0 -155
  221. package/src/markdown-deps.d.ts +0 -21
  222. package/src/router-state.svelte.ts +0 -65
  223. package/src/types.ts +0 -33
  224. package/src/utils.ts +0 -28
@@ -1,242 +0,0 @@
1
- <script lang="ts">
2
- import { useForm, getResource, deriveValidator } from '@svadmin/core';
3
- import type { FieldDefinition } from '@svadmin/core';
4
- import { t } from '@svadmin/core/i18n';
5
- import { navigate } from '@svadmin/core/router';
6
- import { Button } from './ui/button/index.js';
7
- import TooltipButton from './TooltipButton.svelte';
8
- import * as Card from './ui/card/index.js';
9
- import { Badge } from './ui/badge/index.js';
10
- import { Save, ArrowLeft, Loader2, AlertCircle } from '@lucide/svelte';
11
- import FieldRenderer from './FieldRenderer.svelte';
12
- import * as Alert from './ui/alert/index.js';
13
- import { Skeleton } from './ui/skeleton/index.js';
14
- import ConfirmDialog from './ConfirmDialog.svelte';
15
- import type { Snippet } from 'svelte';
16
-
17
- interface Props {
18
- resourceName: string;
19
- id?: string | number;
20
- mode?: 'create' | 'edit';
21
- fieldRenderer?: Snippet<[{ field: FieldDefinition; value: unknown; onchange: (v: unknown) => void }]>;
22
- formActions?: Snippet<[{ isLoading: boolean; onSubmit: () => void }]>;
23
- headerContent?: Snippet;
24
- }
25
-
26
- let { resourceName, id, mode = 'create', fieldRenderer, formActions, headerContent }: Props = $props();
27
-
28
- // ─── Resource metadata ────────────────────────────────────────────
29
- const resource = $derived(getResource(resourceName));
30
- const primaryKey = $derived(resource.primaryKey ?? 'id');
31
-
32
- const formFields = $derived(resource.fields.filter(f => {
33
- if (f.key === primaryKey) return false;
34
- if (f.showInForm === false) return false;
35
- if (mode === 'create' && f.showInCreate === false) return false;
36
- if (mode === 'edit' && f.showInEdit === false) return false;
37
- return true;
38
- }));
39
-
40
- const hasGroups = $derived(formFields.some(f => f.group));
41
- const groups = $derived((() => {
42
- if (!hasGroups) return [];
43
- const order: string[] = [];
44
- const map = new Map<string, FieldDefinition[]>();
45
- for (const f of formFields) {
46
- const g = f.group ?? '';
47
- if (!map.has(g)) { order.push(g); map.set(g, []); }
48
- map.get(g)!.push(f);
49
- }
50
- return order.map(g => ({ name: g, fields: map.get(g)! }));
51
- })());
52
-
53
- // ─── Default values from field metadata ───────────────────────────
54
- function getDefaultForType(field: FieldDefinition): unknown {
55
- switch (field.type) {
56
- case 'text': case 'textarea': case 'richtext': case 'image': return '';
57
- case 'number': return 0;
58
- case 'boolean': return false;
59
- case 'tags': case 'images': case 'multiselect': return [];
60
- case 'select': return field.options?.[0]?.value ?? '';
61
- case 'json': return {};
62
- default: return '';
63
- }
64
- }
65
-
66
- const defaults = $derived((() => {
67
- const d: Record<string, unknown> = {};
68
- for (const f of formFields) d[f.key] = f.defaultValue ?? getDefaultForType(f);
69
- return d;
70
- })());
71
-
72
- // ─── useForm: single source of truth for values, errors, tainted ──
73
- const form = useForm({
74
- get resource() { return resourceName; },
75
- get action() { return mode; },
76
- get id() { return id; },
77
- defaultValues: defaults,
78
- redirect: 'list',
79
- warnWhenUnsavedChanges: true,
80
- validate: deriveValidator(formFields),
81
- });
82
-
83
- // ─── Submission error (non-field, e.g. network error) ─────────────
84
- let submitError = $state<string | null>(null);
85
-
86
- async function handleSubmit() {
87
- submitError = null;
88
- try {
89
- await form.submit();
90
- } catch (e) {
91
- submitError = e instanceof Error ? e.message : t('common.operationFailed');
92
- }
93
- }
94
-
95
- const pageTitle = $derived(
96
- mode === 'create'
97
- ? `${t('common.create')}${resource.label}`
98
- : `${t('common.edit')}${resource.label}`
99
- );
100
-
101
- // ─── Unsaved changes guard ────────────────────────────────────────
102
- let confirmOpen = $state(false);
103
- let pendingNavigation: (() => void) | null = null;
104
-
105
- function guardNavigate(fn: () => void) {
106
- if (form.isTainted()) {
107
- pendingNavigation = fn;
108
- confirmOpen = true;
109
- } else {
110
- fn();
111
- }
112
- }
113
-
114
- function confirmNavigate() {
115
- confirmOpen = false;
116
- pendingNavigation?.();
117
- pendingNavigation = null;
118
- }
119
-
120
- function cancelNavigate() {
121
- confirmOpen = false;
122
- pendingNavigation = null;
123
- }
124
- </script>
125
-
126
- <div class="space-y-6">
127
- <div class="flex items-center gap-4">
128
- <TooltipButton
129
- tooltip={t('common.back')}
130
- onclick={() => guardNavigate(() => navigate(`/${resourceName}`))}
131
- >
132
- <ArrowLeft class="h-5 w-5" />
133
- </TooltipButton>
134
- <h1 class="text-xl font-semibold text-foreground">{pageTitle}</h1>
135
- {#if form.isTainted()}
136
- <Badge variant="outline" class="border-warning/30 bg-warning/10 text-warning-foreground">{t('common.unsaved')}</Badge>
137
- {/if}
138
- </div>
139
-
140
- {#if form.loading}
141
- <div class="max-w-3xl space-y-6">
142
- <div class="rounded-lg shadow-sm ring-1 ring-border/10 p-6 space-y-5">
143
- {#each Array(4) as _}
144
- <div class="space-y-2">
145
- <Skeleton class="h-4 w-24" />
146
- <Skeleton class="h-10 w-full" />
147
- </div>
148
- {/each}
149
- </div>
150
- </div>
151
- {:else}
152
- <form onsubmit={(e: Event) => { e.preventDefault(); handleSubmit(); }} class="max-w-3xl space-y-6">
153
- {#if submitError}
154
- <Alert.Root variant="destructive">
155
- <AlertCircle class="h-4 w-4" />
156
- <Alert.Description>{submitError}</Alert.Description>
157
- </Alert.Root>
158
- {/if}
159
-
160
- {#if hasGroups}
161
- {#each groups as group}
162
- <Card.Root class="border-border/40 shadow-sm">
163
- {#if group.name}
164
- <Card.Header>
165
- <Card.Title class="text-lg">{group.name}</Card.Title>
166
- </Card.Header>
167
- {/if}
168
- <Card.Content class="space-y-5 px-4 sm:px-6 pb-4 sm:pb-6 pt-0">
169
- {#each group.fields as field (field.key)}
170
- <div class:border-destructive={!!form.errors[field.key]}>
171
- {#if fieldRenderer}
172
- {@render fieldRenderer({ field, value: form.values[field.key], onchange: (val: unknown) => form.setFieldValue(field.key, val) })}
173
- {:else}
174
- <FieldRenderer
175
- {field}
176
- value={form.values[field.key]}
177
- onchange={(val: unknown) => form.setFieldValue(field.key, val)}
178
- />
179
- {/if}
180
- {#if form.errors[field.key]}
181
- <p class="text-destructive text-[0.8125rem] mt-1">{form.errors[field.key]}</p>
182
- {/if}
183
- </div>
184
- {/each}
185
- </Card.Content>
186
- </Card.Root>
187
- {/each}
188
- {:else}
189
- <Card.Root class="border-border/40 shadow-sm">
190
- <Card.Content class="space-y-5 px-4 sm:px-6 pb-4 sm:pb-6 pt-0">
191
- {#each formFields as field (field.key)}
192
- <div class:border-destructive={!!form.errors[field.key]}>
193
- {#if fieldRenderer}
194
- {@render fieldRenderer({ field, value: form.values[field.key], onchange: (val: unknown) => form.setFieldValue(field.key, val) })}
195
- {:else}
196
- <FieldRenderer
197
- {field}
198
- value={form.values[field.key]}
199
- onchange={(val: unknown) => form.setFieldValue(field.key, val)}
200
- />
201
- {/if}
202
- {#if form.errors[field.key]}
203
- <p class="text-destructive text-[0.8125rem] mt-1">{form.errors[field.key]}</p>
204
- {/if}
205
- </div>
206
- {/each}
207
- </Card.Content>
208
- </Card.Root>
209
- {/if}
210
-
211
- <div class="flex items-center gap-3">
212
- {#if formActions}
213
- {@render formActions({ isLoading: form.submitting, onSubmit: handleSubmit })}
214
- {:else}
215
- <Button type="submit" disabled={form.submitting}>
216
- {#if form.submitting}
217
- <Loader2 class="h-4 w-4 animate-spin" data-icon="inline-start" />
218
- {:else}
219
- <Save class="h-4 w-4" data-icon="inline-start" />
220
- {/if}
221
- {t('common.save')}
222
- </Button>
223
- <Button
224
- type="button"
225
- variant="outline"
226
- onclick={() => guardNavigate(() => navigate(`/${resourceName}`))}
227
- >
228
- {t('common.cancel')}
229
- </Button>
230
- {/if}
231
- </div>
232
- </form>
233
- {/if}
234
- </div>
235
-
236
- <ConfirmDialog
237
- open={confirmOpen}
238
- message={t('common.unsavedChanges')}
239
- confirmText={t('common.confirm')}
240
- onconfirm={confirmNavigate}
241
- oncancel={cancelNavigate}
242
- />
@@ -1,35 +0,0 @@
1
- <script lang="ts">
2
- import { fade, fly } from 'svelte/transition';
3
- import { Loader2, Check, X, Cloud } from '@lucide/svelte';
4
- import { t } from '@svadmin/core/i18n';
5
-
6
- let {
7
- status = 'idle',
8
- error,
9
- } = $props<{
10
- /** The current auto-save status */
11
- status?: 'idle' | 'loading' | 'success' | 'error';
12
- /** Optional error message */
13
- error?: string;
14
- }>();
15
- </script>
16
-
17
- <div class="flex items-center gap-2 text-sm text-muted-foreground">
18
- {#key status}
19
- <div class="flex items-center gap-2" in:fly={{ y: -8, duration: 200 }} out:fade={{ duration: 150 }}>
20
- {#if status === 'idle'}
21
- <Cloud class="h-4 w-4" />
22
- <span>{t('autoSave.idle')}</span>
23
- {:else if status === 'loading'}
24
- <Loader2 class="h-4 w-4 animate-spin text-primary" />
25
- <span>{t('autoSave.saving')}</span>
26
- {:else if status === 'success'}
27
- <Check class="h-4 w-4 text-green-500" />
28
- <span class="text-green-500">{t('autoSave.saved')}</span>
29
- {:else if status === 'error'}
30
- <X class="h-4 w-4 text-destructive" />
31
- <span class="text-destructive" title={error}>{t('autoSave.error')}</span>
32
- {/if}
33
- </div>
34
- {/key}
35
- </div>