@svadmin/create 0.41.1 → 0.42.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.
@@ -16,7 +16,7 @@ bun run dev
16
16
 
17
17
  在编码助手中提出需求即可,例如:
18
18
 
19
- > 基于当前客户工作台,把全站调整为高密度运营,保留客户 CRUD 和跟进流程。
19
+ > 基于当前客户工作台,把全站调整为宽屏运营布局,保留客户 CRUD 和跟进流程。
20
20
  > 先读取 svadmin.vibe.json 和设计规范,修改后运行检查并查看移动端截图。
21
21
 
22
22
  `AGENTS.md` 提供通用规则,`.agents/skills/svadmin-vibe/SKILL.md` 提供生成与
@@ -3,7 +3,6 @@ import { initialPreset } from './design-selection';
3
3
 
4
4
  interface DesignPreset {
5
5
  label: string;
6
- density: 'compact' | 'comfortable';
7
6
  width: 'wide' | 'default';
8
7
  formColumns: 1 | 2;
9
8
  detailLayout: 'list' | 'grid';
@@ -12,17 +11,17 @@ interface DesignPreset {
12
11
 
13
12
  export const designPresets = {
14
13
  operations: {
15
- label: '高密度运营', density: 'compact', width: 'wide',
14
+ label: '宽屏运营', width: 'wide',
16
15
  formColumns: 2, detailLayout: 'list',
17
16
  theme: { colorPreset: 'neutral', layoutPreset: 'clean-flat' },
18
17
  },
19
18
  enterprise: {
20
- label: '标准企业', density: 'comfortable', width: 'wide',
19
+ label: '标准企业', width: 'wide',
21
20
  formColumns: 2, detailLayout: 'grid',
22
21
  theme: { colorPreset: 'stripe', layoutPreset: 'clean-flat' },
23
22
  },
24
23
  collaboration: {
25
- label: '轻量协作', density: 'comfortable', width: 'default',
24
+ label: '轻量协作', width: 'default',
26
25
  formColumns: 1, detailLayout: 'list',
27
26
  theme: { colorPreset: 'green', layoutPreset: 'clean-flat' },
28
27
  },
@@ -2,8 +2,6 @@
2
2
  import { useList, useCan } from '@svadmin/core';
3
3
  import { AutoTable, Button, DashboardPage, DataState, MetricBlock, PageSection } from '@svadmin/ui';
4
4
  import { customers, followups, approvals } from './contracts';
5
- import { getDesign } from '../../design.svelte';
6
- const design = $derived(getDesign());
7
5
  const access = useCan(() => ({ resource: 'customers', action: 'list' }));
8
6
  const followupAccess = useCan(() => ({ resource: 'followups', action: 'list' }));
9
7
  const approvalAccess = useCan(() => ({ resource: 'approvals', action: 'list' }));
@@ -37,7 +35,7 @@
37
35
  {/if}
38
36
  <PageSection title="客户">
39
37
  <AutoTable resourceName="customers" showHeader={false} selectable={false}
40
- syncWithLocation={false} density={design.density} />
38
+ syncWithLocation={false} />
41
39
  </PageSection>
42
40
  {#snippet secondary()}
43
41
  <PageSection title="待办">
@@ -15,9 +15,9 @@
15
15
  }));
16
16
  </script>
17
17
 
18
- <ContentPageShell pageId="customer-detail" width={design.width} density={design.density}>
18
+ <ContentPageShell pageId="customer-detail" width={design.width}>
19
19
  {#if id !== undefined}
20
- <ShowPage {resourceName} {id} layout={design.detailLayout} density={design.density}>
20
+ <ShowPage {resourceName} {id} layout={design.detailLayout}>
21
21
  <PageSection title="最近跟进">
22
22
  {#snippet actions()}<Button variant="ghost" href="#/followups">全部记录</Button>{/snippet}
23
23
  {#if permission.isLoading || records.isLoading}
@@ -7,7 +7,7 @@
7
7
  const design = $derived(getDesign());
8
8
  </script>
9
9
 
10
- <ContentPageShell pageId="customer-form" width={design.width} density={design.density}>
10
+ <ContentPageShell pageId="customer-form" width={design.width}>
11
11
  <AutoForm {resourceName} {mode} {...(id === undefined ? {} : { id })}
12
- columns={design.formColumns} density={design.density} />
12
+ columns={design.formColumns} />
13
13
  </ContentPageShell>
@@ -5,6 +5,6 @@
5
5
  const design = $derived(getDesign());
6
6
  </script>
7
7
 
8
- <ContentPageShell pageId="customer-list" width={design.width} density={design.density}>
9
- <AutoTable {resourceName} density={design.density} />
8
+ <ContentPageShell pageId="customer-list" width={design.width}>
9
+ <AutoTable {resourceName} />
10
10
  </ContentPageShell>
@@ -1,13 +1,11 @@
1
1
  <script lang="ts">
2
2
  import { AutoForm, ContentPageShell, DataState, PageSection, ShowPage } from '@svadmin/ui';
3
- import { getDesign } from '../../design.svelte';
4
3
  let { resourceName, id }: { resourceName: string; id?: string | number } = $props();
5
- const design = $derived(getDesign());
6
4
  </script>
7
5
 
8
- <ContentPageShell pageId="approval-review" width="default" density={design.density}>
6
+ <ContentPageShell pageId="approval-review" width="default">
9
7
  {#if id !== undefined}
10
- <ShowPage {resourceName} {id} density={design.density}>
8
+ <ShowPage {resourceName} {id}>
11
9
  <PageSection title="审批决定">
12
10
  <AutoForm {resourceName} {id} mode="edit" showHeader={false} columns={1} />
13
11
  </PageSection>
@@ -70,7 +70,6 @@ test('global design preset changes without losing customer data', async ({ page
70
70
  await page.goto('/#/workspace_settings');
71
71
  await page.getByRole('combobox', { name: '设计预设', exact: true }).selectOption('operations');
72
72
  await page.evaluate(() => { location.hash = '/customers'; });
73
- await expect(page.locator('[data-svadmin-content-page="customer-list"]')).toHaveAttribute('data-density', 'compact');
74
73
  await expect(visibleText(page, '澄川科技')).toBeVisible();
75
74
  await page.evaluate(() => { location.hash = '/workspace_settings'; });
76
75
  await page.getByRole('combobox', { name: '设计预设', exact: true }).selectOption('collaboration');
@@ -84,7 +83,6 @@ for (const preset of catalog.presets) {
84
83
  await page.getByRole('combobox', { name: '设计预设', exact: true }).selectOption(preset);
85
84
  await page.evaluate(() => { location.hash = '/customers'; });
86
85
  await expect(visibleText(page, '澄川科技')).toBeVisible();
87
- await expect(page.locator('[data-svadmin-content-page="customer-list"]')).toHaveAttribute('data-density', preset === 'operations' ? 'compact' : 'comfortable');
88
86
  await page.screenshot({ path: testInfo.outputPath(`${preset}.png`), fullPage: true, animations: 'disabled' });
89
87
  });
90
88
  }
@@ -36,7 +36,7 @@ The CLI commands remain the fallback when no MCP client is configured.
36
36
  internal/example-only imports.
37
37
  - Translate "compact", "standard", or "lightweight" requests into the existing
38
38
  application-wide presets in `src/design.svelte.ts`. Keep layout, form columns,
39
- table density, and detail layout consistent. Change `src/design-selection.ts`
39
+ and detail layout consistent. Change `src/design-selection.ts`
40
40
  for the initial preset. Do not silently reset a user's saved preferences.
41
41
  - Preserve resource contracts, providers, permissions, routes, and active form
42
42
  values when making visual-only changes. Keep metric values provider-backed.
@@ -131,7 +131,7 @@ not become a mixed visual theme:
131
131
  | --- | --- | --- |
132
132
  | Stripe style prompt | theme-menu chip `#635bff`, painted `--primary: oklch(0.54 0.24 293)`, technical grid, hairline borders, layered elevation, lift/depress feedback | Stripe brand assets, marketing gradients, oversized hero treatment |
133
133
  | Corporate-clean prompt | neutral enterprise surfaces, readable hierarchy, generous spacing, focus-ring offset, motion capped at 200ms | blue-only palette, rigid utility-class recipes, decorative cards |
134
- | Fuse / Midone / Skote | navigation anatomy, page-family coverage, toolbar/table/form composition, density observations | vendor palette, logos, fonts, CSS, copied markup or component chrome |
134
+ | Fuse / Midone / Skote | navigation anatomy, page-family coverage, toolbar/table/form composition, layout observations | vendor palette, logos, fonts, CSS, copied markup or component chrome |
135
135
  | svadmin | semantic tokens, component API, state ownership, accessibility, responsive contracts | no second visual authority |
136
136
 
137
137
  When references conflict, svadmin semantics and accessibility win first, the
@@ -170,7 +170,7 @@ The same contract is used at every delivery surface:
170
170
  remains the preset chip `#635bff`, not the oklch `--primary` used by
171
171
  `@svadmin/ui`.
172
172
 
173
- Theme refinements must preserve component density, invalid and selected states.
173
+ Theme refinements must preserve component geometry, invalid and selected states.
174
174
  Focus belongs to the active control, not every enclosing card. Search icons and
175
175
  clear actions use logical positioning so the same layout works in RTL.
176
176
 
@@ -205,7 +205,7 @@ and documentation:
205
205
  move the primary action or force an unnecessary page transition.
206
206
  3. **Consistent by contract:** semantic tokens, component variants, state names,
207
207
  page skeletons, and feedback lifecycles remain stable across products. Layout
208
- presets may change density and composition, not interaction meaning.
208
+ presets may change composition, not interaction meaning.
209
209
  4. **Trustworthy in every state:** loading, empty, partial, error, forbidden,
210
210
  destructive, reversible, and completed states expose their scope and next
211
211
  step. Data freshness, permission boundaries, and action consequences must be
@@ -298,18 +298,20 @@ unframed layouts with a stable content width. Cards represent individual
298
298
  objects or bounded tools; page sections are not decorative floating cards and
299
299
  cards are not nested for visual effect.
300
300
 
301
- ### Visual Density Dials
301
+ ### Spacing Rhythm
302
302
 
303
- svadmin components support systematic density levels to balance scanning speed
304
- and operational throughput:
303
+ svadmin components ship one comfortable baseline rhythm so pages scan
304
+ consistently and generated output matches hand-built pages:
305
305
 
306
- - **Density 8–10 (Dense / Dashboard)**: 2px/4px/8px rhythm with 28px–32px row
307
- heights. Used for `AutoTable`, `FilterToolbar`, `RecordDetailDrawer`, and
308
- operations work areas.
309
- - **Density 4–6 (Comfortable / Standard)**: 4px/8px/16px rhythm with 40px–44px
310
- control heights. Used for settings forms, account profiles, and overview cards.
311
- - **Density 1–3 (Spacious / Onboarding)**: 16px/24px/32px rhythm for public
312
- portals and introductory workflows.
306
+ - **Components**: 4px/8px/16px rhythm with 40px–44px control heights and
307
+ 40px–44px table row heights, used across `AutoTable`, `FilterToolbar`,
308
+ `RecordDetailDrawer`, forms, and operations work areas.
309
+ - **Spacious onboarding or marketing surfaces** may widen vertical padding with
310
+ page-local layout choices, but must not fork component recipes.
311
+
312
+ Density is not a component or page-pattern option; there is no compact or
313
+ comfortable modifier to coordinate across `AutoTable`, `ContentPageShell`, or
314
+ Surface widgets.
313
315
 
314
316
  ## Elevation & Depth
315
317
 
@@ -339,7 +341,9 @@ another titled page shell. Keep `DashboardPage` for existing dashboards.
339
341
 
340
342
  Use `PagePattern` for custom business compositions that do not fit those
341
343
  resource routes. It supplies layout only, not querying, permissions, form
342
- submission, or loading/error handling:
344
+ submission, or business data fetching. It owns the default page-state
345
+ presentation so custom pages do not need to recreate loading/error/empty
346
+ layouts:
343
347
 
344
348
  - `list`: comfortable title, toolbar, table/list content, and list empty states.
345
349
  - `form`: narrow reading width, comfortable grouped fields and a single save area.
@@ -347,6 +351,11 @@ submission, or loading/error handling:
347
351
  - `workspace`: comfortable primary work area plus an optional secondary panel.
348
352
  - `dashboard`: wide layout with optional metrics and secondary context.
349
353
 
354
+ Set `state` to `loading`, `empty`, `error`, or `forbidden` while the page is
355
+ not ready. Page content is hidden during those states, and the shared `DataState`
356
+ component supplies the accessible default. Use `retry` only for `error`; use
357
+ `stateAction` for an explicitly permitted next step. `ready` is the default.
358
+
350
359
  Optional `secondary` content renders beside the primary content for every kind.
351
360
  For advanced resizable, collapsible, or independently scrolling work areas,
352
361
  compose `WorkspaceLayout` or `MasterDetailView` directly. The pattern does not
@@ -398,10 +407,8 @@ cards, repeated title bars, or unrestricted two-column fields.
398
407
  persistence request succeeds; preserve edits after failure.
399
408
  - Separate initial-empty content from filtered-no-results content. Offer
400
409
  creation only when permitted, and clearing filters only when filters exist.
401
- - Page patterns default to comfortable density so generated and custom pages
402
- have a consistent baseline. Use compact density explicitly for operational
403
- work that prioritizes scanning speed; use comfortable density for forms and
404
- general-purpose pages.
410
+ - Page patterns use a single comfortable baseline so generated and custom pages
411
+ share the same rhythm across forms, detail, list, and workspace families.
405
412
  - Reference `packages/ui/stories/ConfigurationExample.svelte` in the SVAdmin
406
413
  source for a working composition; its save action is in-memory demo state,
407
414
  not a persistence implementation.
@@ -414,7 +421,7 @@ passing component tests alone does not establish visual acceptance.
414
421
 
415
422
  Buttons, fields, tabs, tables, badges, empty states, skeletons, alerts, and
416
423
  feedback use shared components and semantic tokens. Layout presets may adjust
417
- density and composition, but they must not replace component color, typography,
424
+ composition, but they must not replace component color, typography,
418
425
  focus, or elevation with hard-coded values.
419
426
 
420
427
  ### Shell anatomy
@@ -462,11 +469,11 @@ Transitions provide clear state confirmation without delaying user action:
462
469
  The reference stack is layered. It is not a visual mixture:
463
470
 
464
471
  - **svadmin owns its visual principles:** hierarchy, restraint, neutral surfaces,
465
- typography, density, and interaction tone.
472
+ typography, spacing, and interaction tone.
466
473
  - **Refine is an application-model reference:** resource routing, CRUD flows,
467
474
  provider state, access control, and mutation ownership.
468
475
  - **Ant Design is a behavior reference:** field validation, alerts, messages,
469
- notifications, results, empty states, loading, and high-density data tasks.
476
+ notifications, results, empty states, loading, and data-heavy tasks.
470
477
  - **shadcn/ui is a composition reference:** accessible primitives, source-owned
471
478
  components, semantic tokens, variants, and AI-readable assembly patterns.
472
479
  - **Carbon and PatternFly are enterprise-pattern references:** notification
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svadmin/create",
3
- "version": "0.41.1",
3
+ "version": "0.42.0",
4
4
  "description": "Scaffolding tool for svadmin projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -30,7 +30,7 @@
30
30
  "@types/node": "^26.4.0",
31
31
  "@types/prompts": "^2.4.9",
32
32
  "typescript": "^7.0.2",
33
- "@svadmin/core": "^0.61.1"
33
+ "@svadmin/core": "^0.62.0"
34
34
  },
35
35
  "keywords": [
36
36
  "svadmin",
@@ -10,10 +10,10 @@
10
10
  "check": "svelte-check --tsconfig ./tsconfig.json"
11
11
  },
12
12
  "dependencies": {
13
- "@svadmin/core": "^0.61.1",
14
- "@svadmin/app": "^0.2.5",
15
- "@svadmin/ai-elements": "^0.11.3",
16
- "@svadmin/ui": "^0.84.1",
13
+ "@svadmin/core": "^0.62.0",
14
+ "@svadmin/app": "^0.2.6",
15
+ "@svadmin/ai-elements": "^0.12.0",
16
+ "@svadmin/ui": "^0.86.0",
17
17
  "typebox": "^1.3.34",
18
18
  "@tanstack/svelte-query": "^6.1.48",
19
19
  "@lucide/svelte": "^1.35.0"
@@ -42,76 +42,76 @@
42
42
  "graphql": "^16.8.0"
43
43
  },
44
44
  "simple-rest": {
45
- "@svadmin/simple-rest": "^0.12.6",
45
+ "@svadmin/simple-rest": "^0.12.7",
46
46
  "@refinedev/simple-rest": "^6.0.1"
47
47
  },
48
48
  "supabase": {
49
- "@svadmin/supabase": "^0.19.3",
49
+ "@svadmin/supabase": "^0.19.4",
50
50
  "@supabase/supabase-js": "^2.112.4",
51
51
  "@refinedev/supabase": "^6.0.2"
52
52
  },
53
53
  "graphql": {
54
- "@svadmin/graphql": "^0.12.6",
54
+ "@svadmin/graphql": "^0.12.7",
55
55
  "@refinedev/graphql": "^8.0.1",
56
56
  "graphql-request": "^7.4.0",
57
57
  "graphql": "^16.8.0"
58
58
  },
59
59
  "rest": {
60
- "@svadmin/rest": "^0.2.5",
60
+ "@svadmin/rest": "^0.2.6",
61
61
  "@refinedev/rest": "^2.1.1",
62
62
  "@nestjsx/crud-request": "^5.0.0-alpha.3"
63
63
  },
64
64
  "airtable": {
65
- "@svadmin/airtable": "^0.12.6",
65
+ "@svadmin/airtable": "^0.12.7",
66
66
  "@refinedev/airtable": "^5.0.1"
67
67
  },
68
68
  "appwrite": {
69
- "@svadmin/appwrite": "^0.11.6",
69
+ "@svadmin/appwrite": "^0.11.7",
70
70
  "appwrite": ">=26.2.0",
71
71
  "@refinedev/appwrite": "^8.0.1"
72
72
  },
73
73
  "directus": {
74
- "@svadmin/directus": "^0.11.6"
74
+ "@svadmin/directus": "^0.11.7"
75
75
  },
76
76
  "drizzle": {
77
- "@svadmin/drizzle": "^0.14.3",
77
+ "@svadmin/drizzle": "^0.14.4",
78
78
  "drizzle-orm": "^1.0.0-rc.1",
79
79
  "refine-sqlx": "^0.10.3"
80
80
  },
81
81
  "elysia": {
82
- "@svadmin/elysia": "^0.14.6",
82
+ "@svadmin/elysia": "^0.14.7",
83
83
  "elysia": ">=1.4.30",
84
84
  "@elysiajs/eden": ">=1.4.9"
85
85
  },
86
86
  "firebase": {
87
- "@svadmin/firebase": "^0.12.6"
87
+ "@svadmin/firebase": "^0.12.7"
88
88
  },
89
89
  "hasura": {
90
- "@svadmin/hasura": "^0.12.6",
90
+ "@svadmin/hasura": "^0.12.7",
91
91
  "@refinedev/hasura": "^7.0.1",
92
92
  "graphql-request": "^7.4.0"
93
93
  },
94
94
  "medusa": {
95
- "@svadmin/medusa": "^0.12.6",
95
+ "@svadmin/medusa": "^0.12.7",
96
96
  "@refinedev/medusa": "^5.0.0"
97
97
  },
98
98
  "nestjs-query": {
99
- "@svadmin/nestjs-query": "^0.12.6",
99
+ "@svadmin/nestjs-query": "^0.12.7",
100
100
  "@refinedev/nestjs-query": "^5.0.0"
101
101
  },
102
102
  "nestjsx-crud": {
103
- "@svadmin/nestjsx-crud": "^0.12.6",
103
+ "@svadmin/nestjsx-crud": "^0.12.7",
104
104
  "@refinedev/nestjsx-crud": "^6.0.1"
105
105
  },
106
106
  "pocketbase": {
107
- "@svadmin/pocketbase": "^0.13.3",
107
+ "@svadmin/pocketbase": "^0.13.4",
108
108
  "pocketbase": ">=0.28.0"
109
109
  },
110
110
  "sanity": {
111
- "@svadmin/sanity": "^0.11.6"
111
+ "@svadmin/sanity": "^0.11.7"
112
112
  },
113
113
  "strapi": {
114
- "@svadmin/strapi": "^0.12.6",
114
+ "@svadmin/strapi": "^0.12.7",
115
115
  "@refinedev/strapi-v4": "^7.0.1"
116
116
  }
117
117
  },