@svadmin/ui 0.45.0 → 0.46.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 (44) hide show
  1. package/dist/components/AuthPageShell.svelte +32 -0
  2. package/dist/components/AuthPageShell.svelte.d.ts +11 -0
  3. package/dist/components/ForgotPasswordPage.svelte +4 -68
  4. package/dist/components/LoginPage.svelte +33 -124
  5. package/dist/components/PermissionMatrix.svelte +5 -5
  6. package/dist/components/RegisterPage.svelte +7 -62
  7. package/dist/components/SvadminLogo.svelte +1 -1
  8. package/dist/components/UpdatePasswordPage.svelte +3 -55
  9. package/dist/components/account/CompanyProfilePage.svelte +11 -5
  10. package/dist/components/account/SettingsEnterprisePage.svelte +25 -4
  11. package/dist/components/account/SettingsPlainPage.svelte +25 -3
  12. package/dist/components/account/SettingsSidebarPage.svelte +31 -2
  13. package/dist/components/content/ApiKeyList.svelte +13 -4
  14. package/dist/components/content/ApiKeyList.svelte.d.ts +7 -0
  15. package/dist/components/content/DataState.svelte +25 -9
  16. package/dist/components/content/DataState.svelte.d.ts +2 -0
  17. package/dist/components/content/FileList.svelte +12 -4
  18. package/dist/components/content/FileList.svelte.d.ts +9 -0
  19. package/dist/components/content/FilterToolbar.svelte +10 -2
  20. package/dist/components/content/FilterToolbar.svelte.d.ts +1 -0
  21. package/dist/components/content/MemberList.svelte +13 -5
  22. package/dist/components/content/MemberList.svelte.d.ts +9 -0
  23. package/dist/components/content/MetricBlock.svelte +19 -2
  24. package/dist/components/content/MetricBlock.svelte.d.ts +2 -0
  25. package/dist/components/content/NetworkTable.svelte +9 -3
  26. package/dist/components/content/NetworkTable.svelte.d.ts +9 -0
  27. package/dist/components/content/NetworkUserCard.svelte +47 -7
  28. package/dist/components/content/NetworkUserCard.svelte.d.ts +13 -0
  29. package/dist/components/content/SectionHeader.svelte +3 -2
  30. package/dist/components/content/SectionHeader.svelte.d.ts +1 -0
  31. package/dist/components/content/SecurityEventTable.svelte +14 -5
  32. package/dist/components/content/SecurityEventTable.svelte.d.ts +9 -0
  33. package/dist/components/content/SettingsFieldRow.svelte +28 -0
  34. package/dist/components/content/SettingsFieldRow.svelte.d.ts +11 -0
  35. package/dist/components/content/SettingsGroup.svelte +33 -0
  36. package/dist/components/content/SettingsGroup.svelte.d.ts +12 -0
  37. package/dist/components/content/WorkspaceLayout.svelte +28 -0
  38. package/dist/components/content/WorkspaceLayout.svelte.d.ts +11 -0
  39. package/dist/components/content/index.d.ts +4 -1
  40. package/dist/components/content/index.js +3 -0
  41. package/dist/components/network/UserCardsNFTPage.svelte +25 -6
  42. package/dist/index.d.ts +6 -1
  43. package/dist/index.js +4 -0
  44. package/package.json +1 -1
@@ -1,3 +1,4 @@
1
+ import type { Snippet } from 'svelte';
1
2
  export interface NetworkUser {
2
3
  id: string;
3
4
  name: string;
@@ -6,10 +7,22 @@ export interface NetworkUser {
6
7
  avatar?: string;
7
8
  summary?: string;
8
9
  }
10
+ export interface NetworkMetric {
11
+ label: string;
12
+ value: string | number;
13
+ }
9
14
  interface Props {
10
15
  user: NetworkUser;
16
+ tags?: string[];
17
+ metrics?: NetworkMetric[];
18
+ verified?: boolean;
19
+ verifiedLabel?: string;
20
+ connected?: boolean;
21
+ connectLabel?: string;
22
+ connectedLabel?: string;
11
23
  onconnect?: () => void;
12
24
  onmessage?: () => void;
25
+ footer?: Snippet;
13
26
  class?: string;
14
27
  }
15
28
  declare const NetworkUserCard: import("svelte").Component<Props, {}, "">;
@@ -4,14 +4,15 @@
4
4
  title: string;
5
5
  description?: string;
6
6
  actions?: Snippet;
7
+ id?: string;
7
8
  class?: string;
8
9
  }
9
- let { title, description, actions, class: className = '' }: Props = $props();
10
+ let { title, description, actions, id, class: className = '' }: Props = $props();
10
11
  </script>
11
12
 
12
13
  <div class={'flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between ' + className}>
13
14
  <div class="min-w-0 space-y-1">
14
- <h2 class="text-base font-semibold text-foreground">{title}</h2>
15
+ <h2 {id} class="text-base font-semibold text-foreground">{title}</h2>
15
16
  {#if description}<p class="text-sm text-muted-foreground">{description}</p>{/if}
16
17
  </div>
17
18
  {#if actions}<div class="flex shrink-0 flex-wrap items-center gap-2">{@render actions()}</div>{/if}
@@ -3,6 +3,7 @@ interface Props {
3
3
  title: string;
4
4
  description?: string;
5
5
  actions?: Snippet;
6
+ id?: string;
6
7
  class?: string;
7
8
  }
8
9
  declare const SectionHeader: import("svelte").Component<Props, {}, "">;
@@ -1,18 +1,27 @@
1
1
  <script lang="ts">
2
2
  import * as Table from '../ui/table/index.js';
3
+ import { useTranslation } from '@svadmin/core/i18n';
3
4
  import StatusBadge from './StatusBadge.svelte';
5
+ import DataState from './DataState.svelte';
6
+ import type { DataStateKind } from './DataState.svelte';
4
7
  export interface SecurityEvent { id: string; event: string; actor?: string; location?: string; createdAt: string; severity: 'info' | 'warning' | 'danger'; }
5
- interface Props { events?: SecurityEvent[]; class?: string; }
6
- let { events = [], class: className = '' }: Props = $props();
8
+ interface Props { events?: SecurityEvent[]; state?: DataStateKind; stateTitle?: string; stateDescription?: string; emptyTitle?: string; emptyDescription?: string; retry?: () => void; retryLabel?: string; loadingLabel?: string; class?: string; }
9
+ const i18n = useTranslation();
10
+ let { events = [], state, stateTitle, stateDescription, emptyTitle, emptyDescription, retry, retryLabel, loadingLabel, class: className = '' }: Props = $props();
11
+ const resolvedState = $derived(state ?? (events.length === 0 ? 'empty' : undefined));
12
+ const isZh = $derived(i18n.locale === 'zh-CN');
7
13
  </script>
14
+ {#if resolvedState}
15
+ <DataState state={resolvedState} title={stateTitle ?? emptyTitle} description={stateDescription ?? emptyDescription} {retry} {retryLabel} {loadingLabel} class={className} />
16
+ {:else}
8
17
  <div class={'overflow-x-auto rounded-lg border border-border bg-card ' + className}>
9
18
  <Table.Root data-svadmin-datatable>
10
- <Table.Header data-svadmin-table-head><Table.Row><Table.Head>Event</Table.Head><Table.Head>Actor</Table.Head><Table.Head>Location</Table.Head><Table.Head>Time</Table.Head><Table.Head>Risk</Table.Head></Table.Row></Table.Header>
19
+ <Table.Header data-svadmin-table-head><Table.Row><Table.Head>{isZh ? '事件' : 'Event'}</Table.Head><Table.Head>{isZh ? '操作者' : 'Actor'}</Table.Head><Table.Head>{isZh ? '位置' : 'Location'}</Table.Head><Table.Head>{isZh ? '时间' : 'Time'}</Table.Head><Table.Head>{isZh ? '风险' : 'Risk'}</Table.Head></Table.Row></Table.Header>
11
20
  <Table.Body>
12
21
  {#each events as event (event.id)}
13
- <Table.Row data-svadmin-table-row><Table.Cell class="font-medium">{event.event}</Table.Cell><Table.Cell>{event.actor ?? 'System'}</Table.Cell><Table.Cell>{event.location ?? 'Unknown'}</Table.Cell><Table.Cell class="whitespace-nowrap">{event.createdAt}</Table.Cell><Table.Cell><StatusBadge status={event.severity} label={event.severity} /></Table.Cell></Table.Row>
22
+ <Table.Row data-svadmin-table-row><Table.Cell class="font-medium">{event.event}</Table.Cell><Table.Cell>{event.actor ?? (isZh ? '系统' : 'System')}</Table.Cell><Table.Cell>{event.location ?? (isZh ? '未知' : 'Unknown')}</Table.Cell><Table.Cell class="whitespace-nowrap">{event.createdAt}</Table.Cell><Table.Cell><StatusBadge status={event.severity} label={event.severity} /></Table.Cell></Table.Row>
14
23
  {/each}
15
24
  </Table.Body>
16
25
  </Table.Root>
17
- {#if events.length === 0}<div class="p-6 text-center text-sm text-muted-foreground">No security events</div>{/if}
18
26
  </div>
27
+ {/if}
@@ -1,3 +1,4 @@
1
+ import type { DataStateKind } from './DataState.svelte';
1
2
  export interface SecurityEvent {
2
3
  id: string;
3
4
  event: string;
@@ -8,6 +9,14 @@ export interface SecurityEvent {
8
9
  }
9
10
  interface Props {
10
11
  events?: SecurityEvent[];
12
+ state?: DataStateKind;
13
+ stateTitle?: string;
14
+ stateDescription?: string;
15
+ emptyTitle?: string;
16
+ emptyDescription?: string;
17
+ retry?: () => void;
18
+ retryLabel?: string;
19
+ loadingLabel?: string;
11
20
  class?: string;
12
21
  }
13
22
  declare const SecurityEventTable: import("svelte").Component<Props, {}, "">;
@@ -0,0 +1,28 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import { cn } from '../../utils.js';
4
+
5
+ interface Props {
6
+ label: string;
7
+ description?: string;
8
+ control: Snippet;
9
+ separated?: boolean;
10
+ class?: string;
11
+ }
12
+
13
+ let {
14
+ label,
15
+ description,
16
+ control,
17
+ separated = false,
18
+ class: className = '',
19
+ }: Props = $props();
20
+ </script>
21
+
22
+ <div class={cn('flex min-h-11 items-center justify-between gap-4 py-3', separated && 'border-t border-border', className)} data-svadmin-settings-field-row>
23
+ <div class="min-w-0">
24
+ <p class="text-sm font-medium text-foreground">{label}</p>
25
+ {#if description}<p class="mt-1 max-w-2xl text-sm leading-5 text-muted-foreground">{description}</p>{/if}
26
+ </div>
27
+ <div class="shrink-0">{@render control()}</div>
28
+ </div>
@@ -0,0 +1,11 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ label: string;
4
+ description?: string;
5
+ control: Snippet;
6
+ separated?: boolean;
7
+ class?: string;
8
+ }
9
+ declare const SettingsFieldRow: import("svelte").Component<Props, {}, "">;
10
+ type SettingsFieldRow = ReturnType<typeof SettingsFieldRow>;
11
+ export default SettingsFieldRow;
@@ -0,0 +1,33 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import { cn } from '../../utils.js';
4
+
5
+ interface Props {
6
+ title: string;
7
+ description?: string;
8
+ actions?: Snippet;
9
+ children: Snippet;
10
+ class?: string;
11
+ bodyClass?: string;
12
+ }
13
+
14
+ let {
15
+ title,
16
+ description,
17
+ actions,
18
+ children,
19
+ class: className = '',
20
+ bodyClass = '',
21
+ }: Props = $props();
22
+ </script>
23
+
24
+ <section class={cn('overflow-hidden rounded-lg border border-border bg-card shadow-sm', className)} data-svadmin-settings-group>
25
+ <header class="flex flex-col gap-3 border-b border-border px-5 py-4 sm:flex-row sm:items-start sm:justify-between">
26
+ <div class="min-w-0 space-y-1">
27
+ <h2 class="text-sm font-semibold text-foreground">{title}</h2>
28
+ {#if description}<p class="max-w-2xl text-sm leading-6 text-muted-foreground">{description}</p>{/if}
29
+ </div>
30
+ {#if actions}<div class="flex shrink-0 flex-wrap items-center gap-2">{@render actions()}</div>{/if}
31
+ </header>
32
+ <div class={cn('p-5', bodyClass)}>{@render children()}</div>
33
+ </section>
@@ -0,0 +1,12 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ title: string;
4
+ description?: string;
5
+ actions?: Snippet;
6
+ children: Snippet;
7
+ class?: string;
8
+ bodyClass?: string;
9
+ }
10
+ declare const SettingsGroup: import("svelte").Component<Props, {}, "">;
11
+ type SettingsGroup = ReturnType<typeof SettingsGroup>;
12
+ export default SettingsGroup;
@@ -0,0 +1,28 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import { cn } from '../../utils.js';
4
+
5
+ interface Props {
6
+ primary: Snippet;
7
+ secondary?: Snippet;
8
+ summary?: Snippet;
9
+ secondaryWidth?: string;
10
+ class?: string;
11
+ }
12
+
13
+ let {
14
+ primary,
15
+ secondary,
16
+ summary,
17
+ secondaryWidth = '22rem',
18
+ class: className = '',
19
+ }: Props = $props();
20
+ </script>
21
+
22
+ <div class={cn('flex flex-col gap-6', className)} data-svadmin-workspace-layout style:--workspace-secondary-width={secondaryWidth}>
23
+ {#if summary}<div class="order-2 sm:order-1">{@render summary()}</div>{/if}
24
+ <div class="order-1 grid min-w-0 gap-6 sm:order-2 lg:grid-cols-[minmax(0,1fr)_var(--workspace-secondary-width)]">
25
+ <div class="min-w-0" data-svadmin-workspace-primary>{@render primary()}</div>
26
+ {#if secondary}<aside class="min-w-0">{@render secondary()}</aside>{/if}
27
+ </div>
28
+ </div>
@@ -0,0 +1,11 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ primary: Snippet;
4
+ secondary?: Snippet;
5
+ summary?: Snippet;
6
+ secondaryWidth?: string;
7
+ class?: string;
8
+ }
9
+ declare const WorkspaceLayout: import("svelte").Component<Props, {}, "">;
10
+ type WorkspaceLayout = ReturnType<typeof WorkspaceLayout>;
11
+ export default WorkspaceLayout;
@@ -2,6 +2,9 @@ export { default as ContentPageShell } from './ContentPageShell.svelte';
2
2
  export { default as ContentPageHeader } from './ContentPageHeader.svelte';
3
3
  export { default as SectionHeader } from './SectionHeader.svelte';
4
4
  export { default as PageToolbar } from './PageToolbar.svelte';
5
+ export { default as WorkspaceLayout } from './WorkspaceLayout.svelte';
6
+ export { default as SettingsGroup } from './SettingsGroup.svelte';
7
+ export { default as SettingsFieldRow } from './SettingsFieldRow.svelte';
5
8
  export { default as MetricBlock } from './MetricBlock.svelte';
6
9
  export { default as DescriptionList } from './DescriptionList.svelte';
7
10
  export { default as StatusBadge } from './StatusBadge.svelte';
@@ -24,7 +27,7 @@ export { default as MemberList } from './MemberList.svelte';
24
27
  export type { MemberSummary } from './MemberList.svelte';
25
28
  export { default as ImportDropzone } from './ImportDropzone.svelte';
26
29
  export { default as NetworkUserCard } from './NetworkUserCard.svelte';
27
- export type { NetworkUser } from './NetworkUserCard.svelte';
30
+ export type { NetworkUser, NetworkMetric } from './NetworkUserCard.svelte';
28
31
  export { default as NetworkTable } from './NetworkTable.svelte';
29
32
  export type { NetworkColumn } from './NetworkTable.types.js';
30
33
  export { default as OtpInput } from './OtpInput.svelte';
@@ -2,6 +2,9 @@ export { default as ContentPageShell } from './ContentPageShell.svelte';
2
2
  export { default as ContentPageHeader } from './ContentPageHeader.svelte';
3
3
  export { default as SectionHeader } from './SectionHeader.svelte';
4
4
  export { default as PageToolbar } from './PageToolbar.svelte';
5
+ export { default as WorkspaceLayout } from './WorkspaceLayout.svelte';
6
+ export { default as SettingsGroup } from './SettingsGroup.svelte';
7
+ export { default as SettingsFieldRow } from './SettingsFieldRow.svelte';
5
8
  export { default as MetricBlock } from './MetricBlock.svelte';
6
9
  export { default as DescriptionList } from './DescriptionList.svelte';
7
10
  export { default as StatusBadge } from './StatusBadge.svelte';
@@ -1,13 +1,10 @@
1
1
  <script lang="ts">
2
2
  import { useTranslation } from '@svadmin/core/i18n';
3
- import { Check, Plus } from '@lucide/svelte';
4
- import { Button } from '../ui/button/index.js';
5
- import { Badge } from '../ui/badge/index.js';
6
- import * as Card from '../ui/card/index.js';
7
3
  import ContentPageShell from '../content/ContentPageShell.svelte';
8
4
  import ContentPageHeader from '../content/ContentPageHeader.svelte';
9
5
  import FilterToolbar from '../content/FilterToolbar.svelte';
10
6
  import DataState from '../content/DataState.svelte';
7
+ import NetworkUserCard from '../content/NetworkUserCard.svelte';
11
8
  import type { NetworkUser } from '../content/NetworkUserCard.svelte';
12
9
 
13
10
  const i18n = useTranslation();
@@ -28,6 +25,28 @@
28
25
 
29
26
  <ContentPageShell pageId="network-user-cards" width="wide">
30
27
  <ContentPageHeader title={i18n.t('network.userCards')} description={i18n.t('network.userCardsDescription')} />
31
- <FilterToolbar bind:query placeholder={i18n.t('common.search')} />
32
- {#if filtered.length === 0}<DataState state="empty" title={i18n.t('network.userCards')} />{:else}<div class="grid gap-4 md:grid-cols-2 xl:grid-cols-3">{#each filtered as user (user.id)}<Card.Card><Card.CardContent class="space-y-4 p-4"><div class="flex items-start gap-3"><span class="flex size-10 items-center justify-center rounded-md bg-muted text-sm font-semibold text-muted-foreground">{user.name.slice(0, 2).toUpperCase()}</span><div class="min-w-0 flex-1"><div class="flex items-center gap-1.5"><h2 class="truncate text-sm font-semibold text-foreground">{user.name}</h2>{#if user.verified}<Check class="size-3.5 text-primary" />{/if}</div><p class="text-xs text-muted-foreground">{user.handle}</p></div></div><p class="text-sm text-muted-foreground">{user.summary}</p><div class="flex flex-wrap gap-1.5">{#each user.tags as tag (tag)}<Badge variant="outline">{tag}</Badge>{/each}</div><div class="grid grid-cols-3 gap-2 border-t border-border pt-3 text-center"><div><p class="text-sm font-semibold text-foreground">{user.collectionCount}</p><p class="text-xs text-muted-foreground">{i18n.t('network.nftCollection')}</p></div><div><p class="text-sm font-semibold text-foreground">{user.floorPrice}</p><p class="text-xs text-muted-foreground">{i18n.t('network.floorPrice')}</p></div><div><p class="text-sm font-semibold text-foreground">{user.volume}</p><p class="text-xs text-muted-foreground">{i18n.t('network.volume')}</p></div></div><Button size="sm" variant={connected.includes(user.id) ? 'outline' : 'default'} class="w-full" onclick={() => toggle(user.id)}>{#if connected.includes(user.id)}<Check class="size-3.5" />{i18n.t('network.connected')}{:else}<Plus class="size-3.5" />{i18n.t('network.connect')}{/if}</Button></Card.CardContent></Card.Card>{/each}</div>{/if}
28
+ <FilterToolbar bind:query placeholder={i18n.t('common.search')} clearLabel={i18n.locale === 'zh-CN' ? '清除搜索' : 'Clear search'} />
29
+ {#if filtered.length === 0}
30
+ <DataState state="empty" title={i18n.t('network.userCards')} />
31
+ {:else}
32
+ <div class="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
33
+ {#each filtered as user (user.id)}
34
+ <NetworkUserCard
35
+ {user}
36
+ tags={user.tags}
37
+ verified={user.verified}
38
+ verifiedLabel={i18n.locale === 'zh-CN' ? '已验证' : 'Verified'}
39
+ metrics={[
40
+ { label: i18n.t('network.nftCollection'), value: user.collectionCount },
41
+ { label: i18n.t('network.floorPrice'), value: user.floorPrice },
42
+ { label: i18n.t('network.volume'), value: user.volume },
43
+ ]}
44
+ connected={connected.includes(user.id)}
45
+ connectLabel={i18n.t('network.connect')}
46
+ connectedLabel={i18n.t('network.connected')}
47
+ onconnect={() => toggle(user.id)}
48
+ />
49
+ {/each}
50
+ </div>
51
+ {/if}
33
52
  </ContentPageShell>
package/dist/index.d.ts CHANGED
@@ -16,6 +16,7 @@ export { default as StatsCard } from './components/StatsCard.svelte';
16
16
  export { default as PageHeader } from './components/PageHeader.svelte';
17
17
  export { default as ResourceOperationsPage } from './components/ResourceOperationsPage.svelte';
18
18
  export { default as LoginPage } from './components/LoginPage.svelte';
19
+ export { default as AuthPageShell } from './components/AuthPageShell.svelte';
19
20
  export { default as RegisterPage } from './components/RegisterPage.svelte';
20
21
  export { default as ForgotPasswordPage } from './components/ForgotPasswordPage.svelte';
21
22
  export { default as CanAccess } from './components/CanAccess.svelte';
@@ -157,7 +158,11 @@ export { default as ContentPageShell } from './components/content/ContentPageShe
157
158
  export { default as ContentPageHeader } from './components/content/ContentPageHeader.svelte';
158
159
  export { default as SectionHeader } from './components/content/SectionHeader.svelte';
159
160
  export { default as PageToolbar } from './components/content/PageToolbar.svelte';
161
+ export { default as WorkspaceLayout } from './components/content/WorkspaceLayout.svelte';
162
+ export { default as SettingsGroup } from './components/content/SettingsGroup.svelte';
163
+ export { default as SettingsFieldRow } from './components/content/SettingsFieldRow.svelte';
160
164
  export { default as MetricBlock } from './components/content/MetricBlock.svelte';
165
+ export type { MetricTrendTone } from './components/content/MetricBlock.svelte';
161
166
  export { default as DescriptionList } from './components/content/DescriptionList.svelte';
162
167
  export type { DescriptionItem } from './components/content/DescriptionList.svelte';
163
168
  export { default as StatusBadge } from './components/content/StatusBadge.svelte';
@@ -181,7 +186,7 @@ export { default as MemberList } from './components/content/MemberList.svelte';
181
186
  export type { MemberSummary } from './components/content/MemberList.svelte';
182
187
  export { default as ImportDropzone } from './components/content/ImportDropzone.svelte';
183
188
  export { default as NetworkUserCard } from './components/content/NetworkUserCard.svelte';
184
- export type { NetworkUser } from './components/content/NetworkUserCard.svelte';
189
+ export type { NetworkUser, NetworkMetric } from './components/content/NetworkUserCard.svelte';
185
190
  export { default as NetworkTable } from './components/content/NetworkTable.svelte';
186
191
  export type { NetworkColumn } from './components/content/NetworkTable.types.js';
187
192
  export { default as OtpInput } from './components/content/OtpInput.svelte';
package/dist/index.js CHANGED
@@ -19,6 +19,7 @@ export { default as StatsCard } from './components/StatsCard.svelte';
19
19
  export { default as PageHeader } from './components/PageHeader.svelte';
20
20
  export { default as ResourceOperationsPage } from './components/ResourceOperationsPage.svelte';
21
21
  export { default as LoginPage } from './components/LoginPage.svelte';
22
+ export { default as AuthPageShell } from './components/AuthPageShell.svelte';
22
23
  export { default as RegisterPage } from './components/RegisterPage.svelte';
23
24
  export { default as ForgotPasswordPage } from './components/ForgotPasswordPage.svelte';
24
25
  export { default as CanAccess } from './components/CanAccess.svelte';
@@ -172,6 +173,9 @@ export { default as ContentPageShell } from './components/content/ContentPageShe
172
173
  export { default as ContentPageHeader } from './components/content/ContentPageHeader.svelte';
173
174
  export { default as SectionHeader } from './components/content/SectionHeader.svelte';
174
175
  export { default as PageToolbar } from './components/content/PageToolbar.svelte';
176
+ export { default as WorkspaceLayout } from './components/content/WorkspaceLayout.svelte';
177
+ export { default as SettingsGroup } from './components/content/SettingsGroup.svelte';
178
+ export { default as SettingsFieldRow } from './components/content/SettingsFieldRow.svelte';
175
179
  export { default as MetricBlock } from './components/content/MetricBlock.svelte';
176
180
  export { default as DescriptionList } from './components/content/DescriptionList.svelte';
177
181
  export { default as StatusBadge } from './components/content/StatusBadge.svelte';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svadmin/ui",
3
- "version": "0.45.0",
3
+ "version": "0.46.0",
4
4
  "description": "Pre-built admin UI components — AdminApp, AutoTable, AutoForm, Sidebar, Layout",
5
5
  "type": "module",
6
6
  "sideEffects": [