@lucasvu/scope-ui 0.0.7 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI_SETUP.md +11 -4
- package/README.md +10 -8
- package/bin/scope-ui-init.mjs +210 -18
- package/dist/index.cjs +67 -12
- package/dist/index.d.cts +90 -6
- package/dist/index.d.ts +90 -6
- package/dist/index.js +67 -12
- package/package.json +3 -3
package/AI_SETUP.md
CHANGED
|
@@ -17,7 +17,7 @@ npx scope-ui-init --list-themes
|
|
|
17
17
|
|
|
18
18
|
Nếu chưa cài `@lucasvu/scope-ui`, các lệnh trên sẽ báo `E404` vì npm sẽ cố tải package tên `scope-ui-init`.
|
|
19
19
|
|
|
20
|
-
CLI này sẽ tạo `AGENTS.md
|
|
20
|
+
CLI này sẽ tạo `AGENTS.md`, `src/styles/ui-theme.css`, và `src/layout-presets/workspace-admin-v1.ts` theo đúng convention bên dưới. `AGENTS.md` giờ khóa luôn flow hỏi input -> đọc layout preset -> dựng shell -> mới tới page body. Nếu không truyền `--theme`, preset mặc định là `ocean`.
|
|
21
21
|
|
|
22
22
|
## 1. Import style đúng thứ tự
|
|
23
23
|
|
|
@@ -43,7 +43,9 @@ npx scope-ui-init --theme graphite
|
|
|
43
43
|
|
|
44
44
|
File generate ra sẽ là source of truth cho palette, surface, radius và shadow của project. Agent phải bám vào file này thay vì tự nghĩ màu mới.
|
|
45
45
|
|
|
46
|
-
`AGENTS.md` sẽ có thêm
|
|
46
|
+
`AGENTS.md` sẽ có thêm shell brief + screen brief dạng YAML để agent điền các giá trị như `workspaceLabel`, `pageTabs`, `searchPlaceholder`, `routeUrl`, `sidebarItems`, `pageTitle`, `filters`, `fields`, `tableColumns` trước khi bắt đầu viết JSX.
|
|
47
|
+
|
|
48
|
+
`src/layout-presets/workspace-admin-v1.ts` là source of truth cho shared shell: dark sidebar, gradient topbar, intro card, optional segmented tabs, toolbar card, rồi mới tới body card/table/form.
|
|
47
49
|
|
|
48
50
|
```css
|
|
49
51
|
:root {
|
|
@@ -63,6 +65,8 @@ File generate ra sẽ là source of truth cho palette, surface, radius và shado
|
|
|
63
65
|
|
|
64
66
|
Không nên override màu trực tiếp trong từng component nếu chỉ đang đổi theme.
|
|
65
67
|
|
|
68
|
+
`src/layout-presets/workspace-admin-v1.ts` không cần import vào runtime. Đây là layout contract cho agent/codegen đọc để giữ dark sidebar, gradient topbar, intro card, tab row, và toolbar card nhất quán giữa các màn.
|
|
69
|
+
|
|
66
70
|
## 3. Rule cho AI của project
|
|
67
71
|
|
|
68
72
|
Copy phần này vào system prompt, repo instructions, `AGENTS.md`, Cursor rules, hoặc bất kỳ chỗ nào project đang dùng để ép AI theo convention:
|
|
@@ -75,14 +79,16 @@ Always:
|
|
|
75
79
|
- import the project theme override file after the package stylesheet
|
|
76
80
|
- use root exports from `@lucasvu/scope-ui`
|
|
77
81
|
- stay inside the approved preset declared by `src/styles/ui-theme.css`
|
|
82
|
+
- read `src/layout-presets/workspace-admin-v1.ts` before changing the app shell or page frame
|
|
78
83
|
- follow the step-by-step UI build workflow from `AGENTS.md` before writing JSX
|
|
79
|
-
- fill the screen brief first: `routeUrl`, `sidebarItems`, `activeSidebarItemId`, `pageTitle`, `actions`, and the page-specific schema
|
|
84
|
+
- fill the shell + screen brief first: `workspaceLabel`, `pageTabs`, `searchPlaceholder`, `routeUrl`, `sidebarItems`, `activeSidebarItemId`, `pageTitle`, `actions`, and the page-specific schema
|
|
80
85
|
- read `uiAiManifest` to choose the right component by intent
|
|
81
86
|
- read `uiScreenBlueprint` and `uiThemeContract` before changing layout, colors, surfaces, borders, or shadows
|
|
82
87
|
|
|
83
88
|
Do not:
|
|
84
89
|
- import from `MainFe` unless the task explicitly targets a legacy screen
|
|
85
90
|
- invent a second palette outside the preset file
|
|
91
|
+
- replace the shared dark-sidebar + gradient-topbar shell unless the task explicitly asks for a new shell
|
|
86
92
|
- hardcode brand colors inside page components when a theme token already exists
|
|
87
93
|
- create duplicate Button/Input/Select wrappers unless a project-specific behavior is required
|
|
88
94
|
|
|
@@ -107,7 +113,7 @@ import { uiAiManifest, uiScreenBlueprint, uiThemeContract, uiThemePresets, uiPro
|
|
|
107
113
|
```
|
|
108
114
|
|
|
109
115
|
- `uiAiManifest`: chọn component theo intent
|
|
110
|
-
- `uiScreenBlueprint`: brief input và khung layout chuẩn cho `list | form | detail | dashboard`
|
|
116
|
+
- `uiScreenBlueprint`: brief input và khung layout chuẩn cho `list | form | detail | dashboard`, gồm cả shell fields như `layoutPreset`, `workspaceLabel`, `pageTabs`, `searchPlaceholder`
|
|
111
117
|
- `uiThemeContract`: biết override token nào và override ở đâu
|
|
112
118
|
- `uiThemePresets`: danh sách preset được duyệt để nhiều project dùng chung một visual language
|
|
113
119
|
- `uiProjectAiRules`: rule ngắn gọn để inject vào agent của project
|
|
@@ -118,6 +124,7 @@ Nếu project có app shell:
|
|
|
118
124
|
|
|
119
125
|
- import `@lucasvu/scope-ui/styles.css` ở app entry
|
|
120
126
|
- import `src/styles/ui-theme.css` ngay sau đó
|
|
127
|
+
- để agent đọc `src/layout-presets/workspace-admin-v1.ts` trước khi build page shell
|
|
121
128
|
- toggle dark mode bằng class `.dark` trên `html` hoặc `body`, hoặc dùng `[data-ui-theme='dark']`
|
|
122
129
|
|
|
123
130
|
Nếu project có nhiều brand/theme:
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ npm install @lucasvu/scope-ui
|
|
|
16
16
|
import '@lucasvu/scope-ui/styles.css';
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
3. Nếu muốn bootstrap rule/theme cho AI trong project consumer:
|
|
19
|
+
3. Nếu muốn bootstrap rule/theme/layout cho AI trong project consumer:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
22
|
npm install @lucasvu/scope-ui
|
|
@@ -31,7 +31,7 @@ npx scope-ui-init --list-themes
|
|
|
31
31
|
|
|
32
32
|
Lưu ý: các lệnh này chỉ chạy được sau khi project đã cài `@lucasvu/scope-ui`. Nếu chưa cài package, `npx` sẽ đi tìm một package riêng tên `scope-ui-init` trên npm và báo `E404`.
|
|
33
33
|
|
|
34
|
-
Lệnh này sẽ tạo `AGENTS.md
|
|
34
|
+
Lệnh này sẽ tạo `AGENTS.md`, `src/styles/ui-theme.css`, và `src/layout-presets/workspace-admin-v1.ts` trong repo hiện tại theo preset đã chọn. `AGENTS.md` giờ có thêm playbook step-by-step để agent hỏi đủ input, đọc layout preset, rồi dựng màn hình đúng layout/component/theme chung. Nếu không truyền `--theme`, preset mặc định là `ocean`. Dùng `--force` nếu muốn overwrite file đã tồn tại.
|
|
35
35
|
|
|
36
36
|
4. Dùng component:
|
|
37
37
|
|
|
@@ -112,10 +112,10 @@ Nếu muốn AI render UI đúng và ổn định theo thư viện này, đừng
|
|
|
112
112
|
- Import file theme override của project ngay sau package CSS, ví dụ `./styles/ui-theme.css`
|
|
113
113
|
- Cài package trước khi bootstrap: `npm install @lucasvu/scope-ui`
|
|
114
114
|
- Chạy `npx scope-ui-init --list-themes` để xem preset được duyệt
|
|
115
|
-
- Chạy `npx scope-ui-init --theme <preset>` ở project consumer sau khi đã cài `@lucasvu/scope-ui` để tạo `AGENTS.md
|
|
115
|
+
- Chạy `npx scope-ui-init --theme <preset>` ở project consumer sau khi đã cài `@lucasvu/scope-ui` để tạo `AGENTS.md`, `src/styles/ui-theme.css`, và `src/layout-presets/workspace-admin-v1.ts`
|
|
116
116
|
- Khoá project vào một preset thay vì tự bịa palette mới cho từng page
|
|
117
|
-
- Để agent đọc luôn playbook trong `AGENTS.md` để đi đúng thứ tự:
|
|
118
|
-
- Buộc agent điền screen brief trước khi code: `routeUrl`, `sidebarItems`, `activeSidebarItemId`, `pageTitle`, `actions`, `filters`, `fields`, `tableColumns`
|
|
117
|
+
- Để agent đọc luôn playbook trong `AGENTS.md` và `src/layout-presets/workspace-admin-v1.ts` để đi đúng thứ tự: hỏi input, khóa shell, chọn component, dựng layout, rồi mới tinh chỉnh token
|
|
118
|
+
- Buộc agent điền shell + screen brief trước khi code: `workspaceLabel`, `pageTabs`, `searchPlaceholder`, `routeUrl`, `sidebarItems`, `activeSidebarItemId`, `pageTitle`, `actions`, `filters`, `fields`, `tableColumns`
|
|
119
119
|
- `AGENTS.md` mới sẽ có sẵn block brief dạng YAML để agent hoặc dev điền trực tiếp trước khi code
|
|
120
120
|
- Chỉ dùng các component canonical ở root package; tránh `MainFe` nếu không phải legacy screen
|
|
121
121
|
- Cho agent đọc `uiAiManifest` để biết component nào dùng cho intent nào, props quan trọng là gì, và khi nào không nên dùng
|
|
@@ -133,19 +133,19 @@ import {
|
|
|
133
133
|
|
|
134
134
|
`uiAiManifest` mô tả luật chọn component theo intent như: text input, textarea, fixed select, searchable select, async combobox, multi select, data table, alert, card và field wrapper.
|
|
135
135
|
|
|
136
|
-
`uiScreenBlueprint` mô tả input brief bắt buộc cho từng màn hình như `routeUrl`, `sidebarItems`, `activeSidebarItemId`, `pageTitle`, `actions`, `filters`, `fields`, `tableColumns` và frame recipe cho `list | form | detail | dashboard`.
|
|
136
|
+
`uiScreenBlueprint` mô tả input brief bắt buộc cho từng màn hình như `layoutPreset`, `workspaceLabel`, `routeUrl`, `sidebarItems`, `activeSidebarItemId`, `pageTitle`, `pageTabs`, `searchPlaceholder`, `actions`, `filters`, `fields`, `tableColumns` và frame recipe cho `list | form | detail | dashboard`.
|
|
137
137
|
|
|
138
138
|
`uiThemeContract` mô tả token màu, surface, border, shadow, radius, gradient và selector theme (`:root`, `.dark`, `[data-ui-theme='*']`) để AI không hardcode màu sai chỗ.
|
|
139
139
|
|
|
140
140
|
`uiThemePresets` là danh sách preset được duyệt sẵn để nhiều project có thể chọn cùng một visual language mà không cần tự dựng theme từ đầu.
|
|
141
141
|
|
|
142
|
-
`AI_SETUP.md` và CLI `scope-ui-init` giúp bootstrap rule/theme cho repo consumer mà không cần copy tay.
|
|
142
|
+
`AI_SETUP.md` và CLI `scope-ui-init` giúp bootstrap rule/theme/layout cho repo consumer mà không cần copy tay.
|
|
143
143
|
|
|
144
144
|
## Theme Override
|
|
145
145
|
|
|
146
146
|
Nên để toàn bộ override theme của project vào một file riêng, ví dụ `src/styles/ui-theme.css`, rồi import file này sau `@lucasvu/scope-ui/styles.css`.
|
|
147
147
|
|
|
148
|
-
Cách nhanh nhất là generate file này từ preset:
|
|
148
|
+
Cách nhanh nhất là generate bộ file này từ preset:
|
|
149
149
|
|
|
150
150
|
```bash
|
|
151
151
|
npm install @lucasvu/scope-ui
|
|
@@ -158,6 +158,8 @@ import '@lucasvu/scope-ui/styles.css';
|
|
|
158
158
|
import './styles/ui-theme.css';
|
|
159
159
|
```
|
|
160
160
|
|
|
161
|
+
`src/layout-presets/workspace-admin-v1.ts` không cần import ở runtime. File này dùng để agent/codegen đọc và giữ shell layout ổn định giữa các màn.
|
|
162
|
+
|
|
161
163
|
Ví dụ:
|
|
162
164
|
|
|
163
165
|
```css
|
package/bin/scope-ui-init.mjs
CHANGED
|
@@ -6,6 +6,44 @@ import process from 'node:process'
|
|
|
6
6
|
|
|
7
7
|
const PACKAGE_NAME = '@lucasvu/scope-ui'
|
|
8
8
|
const DEFAULT_THEME_PRESET = 'ocean'
|
|
9
|
+
const DEFAULT_LAYOUT_FILE = 'src/layout-presets/workspace-admin-v1.ts'
|
|
10
|
+
|
|
11
|
+
const LAYOUT_PRESET = {
|
|
12
|
+
id: 'workspace-admin-v1',
|
|
13
|
+
label: 'Workspace Admin v1',
|
|
14
|
+
description:
|
|
15
|
+
'Shared admin shell with a dark sidebar, gradient topbar, soft intro card, optional segmented tabs, and card-based content blocks inspired by the Campaigns screen.',
|
|
16
|
+
recommendedFor: [
|
|
17
|
+
'Admin workspaces',
|
|
18
|
+
'Operations dashboards',
|
|
19
|
+
'CRUD-heavy backoffice screens that should share one shell',
|
|
20
|
+
],
|
|
21
|
+
shellRecipe: [
|
|
22
|
+
'Dark left sidebar with icon + label navigation and one active item',
|
|
23
|
+
'Gradient workspace topbar with workspace label on the left and timezone/user slots on the right',
|
|
24
|
+
'Large page intro card with breadcrumb, title, and optional subtitle',
|
|
25
|
+
'Optional segmented tabs row directly under the intro card',
|
|
26
|
+
'Toolbar card with search/filters on the left and actions on the right',
|
|
27
|
+
'Main body rendered as one or more content cards instead of a flat page',
|
|
28
|
+
],
|
|
29
|
+
requiredFields: [
|
|
30
|
+
'layoutPreset',
|
|
31
|
+
'workspaceLabel',
|
|
32
|
+
'pageKind',
|
|
33
|
+
'routeUrl',
|
|
34
|
+
'sidebarItems',
|
|
35
|
+
'activeSidebarItemId',
|
|
36
|
+
'pageTitle',
|
|
37
|
+
],
|
|
38
|
+
askBeforeCoding: [
|
|
39
|
+
'What workspace label should appear in the topbar?',
|
|
40
|
+
'What timezone or top-right meta label should appear beside the user badge?',
|
|
41
|
+
'What sidebar items exist and which one is active on this screen?',
|
|
42
|
+
'Does this screen need segmented tabs? If yes, what are the tab labels and which tab is active?',
|
|
43
|
+
'What search placeholder, filters, and primary action belong in the toolbar card?',
|
|
44
|
+
'What columns, fields, or summary blocks should be rendered in the page body?',
|
|
45
|
+
],
|
|
46
|
+
}
|
|
9
47
|
|
|
10
48
|
const THEME_PRESETS = {
|
|
11
49
|
ocean: {
|
|
@@ -216,6 +254,7 @@ function parseArgs(argv) {
|
|
|
216
254
|
force: false,
|
|
217
255
|
agentsFile: 'AGENTS.md',
|
|
218
256
|
themeFile: 'src/styles/ui-theme.css',
|
|
257
|
+
layoutFile: DEFAULT_LAYOUT_FILE,
|
|
219
258
|
theme: DEFAULT_THEME_PRESET,
|
|
220
259
|
listThemes: false,
|
|
221
260
|
}
|
|
@@ -248,6 +287,16 @@ function parseArgs(argv) {
|
|
|
248
287
|
continue
|
|
249
288
|
}
|
|
250
289
|
|
|
290
|
+
if (arg === '--layout-file') {
|
|
291
|
+
const value = argv[index + 1]
|
|
292
|
+
if (!value || value.startsWith('--')) {
|
|
293
|
+
exitWithMissingValue('--layout-file')
|
|
294
|
+
}
|
|
295
|
+
args.layoutFile = value
|
|
296
|
+
index += 1
|
|
297
|
+
continue
|
|
298
|
+
}
|
|
299
|
+
|
|
251
300
|
if (arg === '--theme') {
|
|
252
301
|
const value = argv[index + 1]
|
|
253
302
|
if (!value || value.startsWith('--')) {
|
|
@@ -288,12 +337,13 @@ Usage:
|
|
|
288
337
|
Optional: inspect approved presets before choosing one.
|
|
289
338
|
|
|
290
339
|
npx scope-ui-init --theme forest --force
|
|
291
|
-
npx scope-ui-init --agents-file AGENTS.md --theme-file src/styles/ui-theme.css
|
|
340
|
+
npx scope-ui-init --agents-file AGENTS.md --theme-file src/styles/ui-theme.css --layout-file ${DEFAULT_LAYOUT_FILE}
|
|
292
341
|
|
|
293
342
|
Options:
|
|
294
343
|
--force overwrite existing files
|
|
295
344
|
--agents-file target path for the generated AGENTS.md file
|
|
296
345
|
--theme-file target path for the generated theme override file
|
|
346
|
+
--layout-file target path for the generated layout preset file
|
|
297
347
|
--theme theme preset id (${Object.keys(THEME_PRESETS).join(', ')})
|
|
298
348
|
--list-themes show the approved preset list
|
|
299
349
|
--help, -h show this help
|
|
@@ -333,38 +383,72 @@ function renderTokenBlock(tokens) {
|
|
|
333
383
|
.join('\n')
|
|
334
384
|
}
|
|
335
385
|
|
|
336
|
-
function
|
|
386
|
+
function renderMarkdownList(items) {
|
|
387
|
+
return items.map((item) => `- ${item}`).join('\n')
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function createAgentsTemplate({ themeFile, layoutFile, themePreset, layoutPreset }) {
|
|
337
391
|
return `# Agent Rules
|
|
338
392
|
|
|
339
393
|
This repo uses \`${PACKAGE_NAME}\` as the default UI library.
|
|
340
394
|
This repo is locked to the \`${themePreset.label}\` theme preset (\`${themePreset.id}\`).
|
|
395
|
+
This repo uses the \`${layoutPreset.label}\` shell preset (\`${layoutPreset.id}\`) as the shared layout baseline.
|
|
341
396
|
|
|
342
397
|
Primary references:
|
|
343
398
|
- \`node_modules/${PACKAGE_NAME}/README.md\`
|
|
344
399
|
- \`node_modules/${PACKAGE_NAME}/AI_SETUP.md\`
|
|
345
400
|
- \`uiScreenBlueprint\` and \`uiAiManifest\` from \`${PACKAGE_NAME}\`
|
|
346
401
|
- \`${themeFile}\`
|
|
402
|
+
- \`${layoutFile}\`
|
|
347
403
|
|
|
348
404
|
Theme preset summary:
|
|
349
405
|
- ${themePreset.description}
|
|
350
406
|
- Recommended for: ${themePreset.recommendedFor.join(', ')}
|
|
351
407
|
|
|
408
|
+
Layout preset summary:
|
|
409
|
+
${renderMarkdownList(layoutPreset.shellRecipe)}
|
|
410
|
+
|
|
352
411
|
## Required Flow
|
|
353
412
|
|
|
354
413
|
When asked to build or edit a screen, follow these steps in order:
|
|
355
414
|
|
|
356
|
-
1. Read \`${themeFile}\`, \`node_modules/${PACKAGE_NAME}/README.md\`, \`node_modules/${PACKAGE_NAME}/AI_SETUP.md\`, and the exported \`uiScreenBlueprint\` contract before generating UI.
|
|
357
|
-
2. Fill the screen brief first. If
|
|
415
|
+
1. Read \`${themeFile}\`, \`${layoutFile}\`, \`node_modules/${PACKAGE_NAME}/README.md\`, \`node_modules/${PACKAGE_NAME}/AI_SETUP.md\`, and the exported \`uiScreenBlueprint\` contract before generating UI.
|
|
416
|
+
2. Fill the shell brief and screen brief first. If a required field is missing, stop and ask for that exact value before writing JSX. Only leave TODO placeholders when the user explicitly asks for an incomplete scaffold.
|
|
358
417
|
3. Verify the app entry imports \`${PACKAGE_NAME}/styles.css\` first and the project theme file right after it.
|
|
359
|
-
4.
|
|
360
|
-
5.
|
|
361
|
-
6.
|
|
362
|
-
7.
|
|
363
|
-
8.
|
|
418
|
+
4. Treat \`${layoutFile}\` as the source of truth for the app shell. Keep the dark sidebar, gradient topbar, intro card, and card-based body structure aligned with that preset unless the user explicitly asks for a different shell.
|
|
419
|
+
5. Identify the page kind (\`list | form | detail | dashboard\`), then map each block to canonical components from \`uiAiManifest\` before writing JSX.
|
|
420
|
+
6. Build the shell in this exact order: \`Sidebar\` -> workspace topbar -> intro card (\`Breadcrumb\` + \`PageTitle\`) -> optional segmented tabs -> toolbar card -> page body cards/grids.
|
|
421
|
+
7. For list pages, build the toolbar card first and then the \`DataTable\`. For form pages, keep the same shell and swap the body into section cards and a bottom action row. For detail pages, keep the shell and render summary/detail cards plus related tables. For dashboard pages, keep the shell and render stat cards plus supporting cards/tables.
|
|
422
|
+
8. If \`${layoutFile}\` says a slot is optional, omit it cleanly when the brief does not request it. Do not invent tabs, workspace labels, filters, or toolbar actions.
|
|
423
|
+
9. Keep all colors, radius, surface, and shadow decisions inside \`${themeFile}\`. If the preset is insufficient, update tokens there instead of styling one page ad hoc.
|
|
424
|
+
10. Before finishing, run the output checklist in this file.
|
|
425
|
+
|
|
426
|
+
## Ask For Missing Input
|
|
427
|
+
|
|
428
|
+
If any of these are missing, ask the user directly before writing JSX:
|
|
429
|
+
|
|
430
|
+
${renderMarkdownList(layoutPreset.askBeforeCoding)}
|
|
431
|
+
|
|
432
|
+
## Shell Brief
|
|
433
|
+
|
|
434
|
+
Complete this shell brief before writing JSX:
|
|
435
|
+
|
|
436
|
+
\`\`\`yaml
|
|
437
|
+
layoutPreset: ${layoutPreset.id}
|
|
438
|
+
workspaceLabel:
|
|
439
|
+
timezoneLabel:
|
|
440
|
+
userBadgeLabel:
|
|
441
|
+
pageTabs:
|
|
442
|
+
- value:
|
|
443
|
+
label:
|
|
444
|
+
activePageTab:
|
|
445
|
+
searchPlaceholder:
|
|
446
|
+
toolbarNote:
|
|
447
|
+
\`\`\`
|
|
364
448
|
|
|
365
449
|
## Screen Brief
|
|
366
450
|
|
|
367
|
-
Complete this brief before writing JSX:
|
|
451
|
+
Complete this screen brief before writing JSX:
|
|
368
452
|
|
|
369
453
|
\`\`\`yaml
|
|
370
454
|
pageKind: list | form | detail | dashboard
|
|
@@ -373,6 +457,7 @@ sidebarItems:
|
|
|
373
457
|
- id:
|
|
374
458
|
title:
|
|
375
459
|
href:
|
|
460
|
+
icon:
|
|
376
461
|
activeSidebarItemId:
|
|
377
462
|
breadcrumbs:
|
|
378
463
|
- label:
|
|
@@ -421,12 +506,18 @@ emptyState:
|
|
|
421
506
|
permissions: []
|
|
422
507
|
\`\`\`
|
|
423
508
|
|
|
509
|
+
## Shell Lock
|
|
510
|
+
|
|
511
|
+
Keep the layout aligned with \`${layoutPreset.id}\`:
|
|
512
|
+
|
|
513
|
+
${renderMarkdownList(layoutPreset.shellRecipe)}
|
|
514
|
+
|
|
424
515
|
## Page Frame Recipes
|
|
425
516
|
|
|
426
|
-
- \`list\`: \`Sidebar\` ->
|
|
427
|
-
- \`form\`: \`Sidebar\` ->
|
|
428
|
-
- \`detail\`: \`Sidebar\` ->
|
|
429
|
-
- \`dashboard\`: \`Sidebar\` ->
|
|
517
|
+
- \`list\`: dark \`Sidebar\` -> workspace topbar -> intro card -> optional segmented tabs -> toolbar \`Card\` -> \`DataTable\` \`Card\`
|
|
518
|
+
- \`form\`: dark \`Sidebar\` -> workspace topbar -> intro card -> optional segmented tabs -> top actions -> sectioned form \`Card\` blocks -> bottom action row
|
|
519
|
+
- \`detail\`: dark \`Sidebar\` -> workspace topbar -> intro card -> optional segmented tabs -> status/actions -> summary metadata \`Card\` -> detail \`Card\` blocks -> related \`DataTable\`
|
|
520
|
+
- \`dashboard\`: dark \`Sidebar\` -> workspace topbar -> intro card -> optional segmented tabs -> toolbar \`Card\` -> \`Stat\` row -> insight \`Card\` blocks and \`DataTable\`
|
|
430
521
|
|
|
431
522
|
## Hard Rules
|
|
432
523
|
|
|
@@ -434,6 +525,7 @@ permissions: []
|
|
|
434
525
|
- import the project theme override file after the package stylesheet
|
|
435
526
|
- use root exports from \`${PACKAGE_NAME}\`
|
|
436
527
|
- use \`${themeFile}\` as the only source of truth for colors, radius, surfaces, and shadows
|
|
528
|
+
- use \`${layoutFile}\` as the source of truth for the shell layout and shared page frame
|
|
437
529
|
- keep layouts and component choices aligned with the shared preset-driven UI used across projects
|
|
438
530
|
- read \`uiAiManifest\` before choosing components
|
|
439
531
|
- read \`uiThemeContract\` before changing colors, surfaces, borders, radius, or shadows
|
|
@@ -442,6 +534,7 @@ permissions: []
|
|
|
442
534
|
Do not:
|
|
443
535
|
- import from \`MainFe\` unless the task explicitly targets a legacy screen
|
|
444
536
|
- invent a second palette or one-off brand colors outside \`${themeFile}\`
|
|
537
|
+
- replace the shared dark-sidebar + gradient-topbar shell with a flat blank layout unless the user explicitly requests it
|
|
445
538
|
- restyle individual pages if the preset tokens can solve it globally
|
|
446
539
|
- create duplicate Button/Input/Select wrappers unless a project-specific behavior is required
|
|
447
540
|
|
|
@@ -461,13 +554,15 @@ Do not:
|
|
|
461
554
|
|
|
462
555
|
Before finishing, confirm all of these are true:
|
|
463
556
|
|
|
464
|
-
- The
|
|
465
|
-
-
|
|
557
|
+
- The shell brief and screen brief are complete.
|
|
558
|
+
- Any missing required input was explicitly asked for before coding.
|
|
559
|
+
- The shell matches \`${layoutPreset.id}\` with a dark sidebar, gradient topbar, intro card, and card-based body structure.
|
|
466
560
|
- The chosen components match the page kind and the brief.
|
|
467
561
|
- No \`MainFe\` imports were used.
|
|
468
562
|
- No hardcoded brand colors were added in page components.
|
|
469
563
|
- Theme decisions live in \`${themeFile}\`, not in ad hoc JSX styling.
|
|
470
564
|
- Spacing, card structure, and actions are consistent with the shared preset.
|
|
565
|
+
- The layout shell stayed stable even if the page body changed.
|
|
471
566
|
`
|
|
472
567
|
}
|
|
473
568
|
|
|
@@ -487,6 +582,90 @@ ${renderTokenBlock(themePreset.tokens.dark)}
|
|
|
487
582
|
`
|
|
488
583
|
}
|
|
489
584
|
|
|
585
|
+
function createLayoutTemplate({ themeFile, layoutPreset }) {
|
|
586
|
+
return `/* Generated by scope-ui-init. */
|
|
587
|
+
/* Layout preset: ${layoutPreset.label} (${layoutPreset.id}) */
|
|
588
|
+
/* Use this file as the shared app-shell source of truth for AI/codegen. */
|
|
589
|
+
|
|
590
|
+
export const uiLayoutPreset = {
|
|
591
|
+
id: '${layoutPreset.id}',
|
|
592
|
+
label: '${layoutPreset.label}',
|
|
593
|
+
description:
|
|
594
|
+
'${layoutPreset.description}',
|
|
595
|
+
themeSource: '${themeFile}',
|
|
596
|
+
recommendedFor: [
|
|
597
|
+
${layoutPreset.recommendedFor.map((item) => ` '${item}',`).join('\n')}
|
|
598
|
+
],
|
|
599
|
+
shellRecipe: [
|
|
600
|
+
${layoutPreset.shellRecipe.map((item) => ` '${item}',`).join('\n')}
|
|
601
|
+
],
|
|
602
|
+
requiredFields: [
|
|
603
|
+
${layoutPreset.requiredFields.map((item) => ` '${item}',`).join('\n')}
|
|
604
|
+
],
|
|
605
|
+
askBeforeCoding: [
|
|
606
|
+
${layoutPreset.askBeforeCoding.map((item) => ` '${item}',`).join('\n')}
|
|
607
|
+
],
|
|
608
|
+
shell: {
|
|
609
|
+
sidebar: {
|
|
610
|
+
tone: 'dark',
|
|
611
|
+
width: '240px',
|
|
612
|
+
content: ['workspace badge', 'icon + label navigation', 'active state'],
|
|
613
|
+
},
|
|
614
|
+
topbar: {
|
|
615
|
+
background: 'theme gradient from --primary-grad-from to --primary-grad-to',
|
|
616
|
+
leftSlot: 'workspaceLabel',
|
|
617
|
+
rightSlots: ['timezoneLabel', 'userBadgeLabel'],
|
|
618
|
+
},
|
|
619
|
+
introCard: {
|
|
620
|
+
content: ['breadcrumbs', 'pageTitle', 'pageSubtitle'],
|
|
621
|
+
surface: 'soft elevated card',
|
|
622
|
+
},
|
|
623
|
+
pageTabs: {
|
|
624
|
+
optional: true,
|
|
625
|
+
style: 'segmented pills',
|
|
626
|
+
fields: ['pageTabs', 'activePageTab'],
|
|
627
|
+
},
|
|
628
|
+
toolbarCard: {
|
|
629
|
+
optional: true,
|
|
630
|
+
leftSlots: ['searchPlaceholder', 'filters'],
|
|
631
|
+
rightSlots: ['secondaryActions', 'primaryAction'],
|
|
632
|
+
},
|
|
633
|
+
},
|
|
634
|
+
pageBodies: {
|
|
635
|
+
list: ['toolbar card', 'DataTable card', 'rowActions', 'emptyState'],
|
|
636
|
+
form: ['sectioned form cards', 'fields', 'bottom action row'],
|
|
637
|
+
detail: ['summary metadata card', 'detailSections', 'related tables'],
|
|
638
|
+
dashboard: ['summaryStats', 'filters', 'insight cards', 'DataTable'],
|
|
639
|
+
},
|
|
640
|
+
hardRules: [
|
|
641
|
+
'Keep the dark sidebar and gradient topbar shell stable across screens.',
|
|
642
|
+
'Do not replace the intro card with a bare page title row.',
|
|
643
|
+
'Use the shared theme tokens from the themeSource file for color, border, surface, and shadow decisions.',
|
|
644
|
+
'Only omit tabs or toolbar sections when the brief explicitly leaves them out.',
|
|
645
|
+
'Ask for missing required fields before generating JSX instead of guessing from the screenshot.',
|
|
646
|
+
],
|
|
647
|
+
exampleBrief: {
|
|
648
|
+
layoutPreset: '${layoutPreset.id}',
|
|
649
|
+
workspaceLabel: 'Workspace',
|
|
650
|
+
timezoneLabel: 'UTC+07:00',
|
|
651
|
+
userBadgeLabel: 'L',
|
|
652
|
+
pageKind: 'list',
|
|
653
|
+
routeUrl: '/campaigns/new',
|
|
654
|
+
activeSidebarItemId: 'campaigns',
|
|
655
|
+
pageTabs: [
|
|
656
|
+
{ value: 'overview', label: 'Overview' },
|
|
657
|
+
{ value: 'coupons', label: 'Coupons' },
|
|
658
|
+
{ value: 'redemption', label: 'Redemption' },
|
|
659
|
+
],
|
|
660
|
+
activePageTab: 'coupons',
|
|
661
|
+
searchPlaceholder: 'Search by coupon code',
|
|
662
|
+
},
|
|
663
|
+
} as const
|
|
664
|
+
|
|
665
|
+
export type UiLayoutPreset = typeof uiLayoutPreset
|
|
666
|
+
`
|
|
667
|
+
}
|
|
668
|
+
|
|
490
669
|
function writeFile(targetPath, content, force) {
|
|
491
670
|
const absolutePath = resolve(process.cwd(), targetPath)
|
|
492
671
|
const alreadyExists = existsSync(absolutePath)
|
|
@@ -511,7 +690,12 @@ const themePreset = resolveThemePreset(options.theme)
|
|
|
511
690
|
|
|
512
691
|
const agentsResult = writeFile(
|
|
513
692
|
options.agentsFile,
|
|
514
|
-
createAgentsTemplate({
|
|
693
|
+
createAgentsTemplate({
|
|
694
|
+
themeFile: options.themeFile,
|
|
695
|
+
layoutFile: options.layoutFile,
|
|
696
|
+
themePreset,
|
|
697
|
+
layoutPreset: LAYOUT_PRESET,
|
|
698
|
+
}),
|
|
515
699
|
options.force,
|
|
516
700
|
)
|
|
517
701
|
|
|
@@ -521,13 +705,21 @@ const themeResult = writeFile(
|
|
|
521
705
|
options.force,
|
|
522
706
|
)
|
|
523
707
|
|
|
708
|
+
const layoutResult = writeFile(
|
|
709
|
+
options.layoutFile,
|
|
710
|
+
createLayoutTemplate({ themeFile: options.themeFile, layoutPreset: LAYOUT_PRESET }),
|
|
711
|
+
options.force,
|
|
712
|
+
)
|
|
713
|
+
|
|
524
714
|
console.log(`Initialized ${PACKAGE_NAME}`)
|
|
525
715
|
console.log(`- theme preset: ${themePreset.label} (${themePreset.id})`)
|
|
716
|
+
console.log(`- layout preset: ${LAYOUT_PRESET.label} (${LAYOUT_PRESET.id})`)
|
|
526
717
|
console.log(`- ${agentsResult.path}: ${agentsResult.status}`)
|
|
527
718
|
console.log(`- ${themeResult.path}: ${themeResult.status}`)
|
|
719
|
+
console.log(`- ${layoutResult.path}: ${layoutResult.status}`)
|
|
528
720
|
console.log('')
|
|
529
721
|
console.log('Next steps:')
|
|
530
722
|
console.log(`1. Import \`${PACKAGE_NAME}/styles.css\` once at your app entry.`)
|
|
531
723
|
console.log(`2. Import \`${options.themeFile}\` right after the package stylesheet.`)
|
|
532
|
-
console.log(`3. Let your agent read \`${options.agentsFile}\` before generating UI.`)
|
|
724
|
+
console.log(`3. Let your agent read \`${options.agentsFile}\` and \`${options.layoutFile}\` before generating UI.`)
|
|
533
725
|
console.log(`4. Re-run this command with \`--theme <preset> --force\` if you want another approved preset.`)
|
package/dist/index.cjs
CHANGED
|
@@ -6647,7 +6647,8 @@ var uiAiManifest = {
|
|
|
6647
6647
|
rules: [
|
|
6648
6648
|
"Import the stylesheet once at the app entry before rendering any component.",
|
|
6649
6649
|
"If the project declares an approved theme preset in AGENTS.md or ui-theme.css, stay inside that preset and do not invent a second palette.",
|
|
6650
|
-
"Collect the screen brief first: route url, sidebar items, active sidebar item, page title, actions, and the page-specific content schema.",
|
|
6650
|
+
"Collect the shell + screen brief first: layout preset, workspace label, route url, sidebar items, active sidebar item, page title, tabs/actions, and the page-specific content schema.",
|
|
6651
|
+
"If the project ships a generated layout preset file, keep the shell aligned with it instead of inventing a new page frame.",
|
|
6651
6652
|
"Prefer the canonical component for each intent instead of mixing legacy MainFe components.",
|
|
6652
6653
|
"Use Input/Textarea/Select label props directly for simple fields; use Field only to wrap custom controls or grouped content.",
|
|
6653
6654
|
"Use Select for small fixed option lists, SearchableSelect for larger local lists, Combobox for type-and-pick flows, and AsyncCombobox for remote search.",
|
|
@@ -6865,6 +6866,30 @@ var uiAiManifest = {
|
|
|
6865
6866
|
|
|
6866
6867
|
// src/screen-blueprint.ts
|
|
6867
6868
|
var uiScreenBriefFields = [
|
|
6869
|
+
{
|
|
6870
|
+
id: "layoutPreset",
|
|
6871
|
+
label: "Layout preset",
|
|
6872
|
+
description: "Shared shell preset id that locks the sidebar/topbar/page-card structure.",
|
|
6873
|
+
required: false,
|
|
6874
|
+
appliesTo: ["all"],
|
|
6875
|
+
example: "workspace-admin-v1"
|
|
6876
|
+
},
|
|
6877
|
+
{
|
|
6878
|
+
id: "workspaceLabel",
|
|
6879
|
+
label: "Workspace label",
|
|
6880
|
+
description: "Short label shown in the sidebar or workspace topbar.",
|
|
6881
|
+
required: false,
|
|
6882
|
+
appliesTo: ["all"],
|
|
6883
|
+
example: "Workspace"
|
|
6884
|
+
},
|
|
6885
|
+
{
|
|
6886
|
+
id: "timezoneLabel",
|
|
6887
|
+
label: "Timezone/meta label",
|
|
6888
|
+
description: "Short meta label shown in the top-right shell area, such as a timezone or environment.",
|
|
6889
|
+
required: false,
|
|
6890
|
+
appliesTo: ["all"],
|
|
6891
|
+
example: "UTC+07:00"
|
|
6892
|
+
},
|
|
6868
6893
|
{
|
|
6869
6894
|
id: "pageKind",
|
|
6870
6895
|
label: "Page kind",
|
|
@@ -6921,6 +6946,22 @@ var uiScreenBriefFields = [
|
|
|
6921
6946
|
appliesTo: ["all"],
|
|
6922
6947
|
example: "Manage internal user accounts and permissions."
|
|
6923
6948
|
},
|
|
6949
|
+
{
|
|
6950
|
+
id: "pageTabs",
|
|
6951
|
+
label: "Page tabs",
|
|
6952
|
+
description: "Optional segmented tabs rendered under the intro card.",
|
|
6953
|
+
required: false,
|
|
6954
|
+
appliesTo: ["all"],
|
|
6955
|
+
example: '[{ value: "overview", label: "Overview" }, { value: "coupons", label: "Coupons" }]'
|
|
6956
|
+
},
|
|
6957
|
+
{
|
|
6958
|
+
id: "activePageTab",
|
|
6959
|
+
label: "Active page tab",
|
|
6960
|
+
description: "The selected segmented tab value when tabs are present.",
|
|
6961
|
+
required: false,
|
|
6962
|
+
appliesTo: ["all"],
|
|
6963
|
+
example: "coupons"
|
|
6964
|
+
},
|
|
6924
6965
|
{
|
|
6925
6966
|
id: "primaryAction",
|
|
6926
6967
|
label: "Primary action",
|
|
@@ -6953,6 +6994,14 @@ var uiScreenBriefFields = [
|
|
|
6953
6994
|
appliesTo: ["list", "dashboard"],
|
|
6954
6995
|
example: '[{ type: "search", label: "Search user" }, { type: "select", label: "Role" }]'
|
|
6955
6996
|
},
|
|
6997
|
+
{
|
|
6998
|
+
id: "searchPlaceholder",
|
|
6999
|
+
label: "Search placeholder",
|
|
7000
|
+
description: "Placeholder text for the main toolbar search input when the shell includes one.",
|
|
7001
|
+
required: false,
|
|
7002
|
+
appliesTo: ["list", "dashboard"],
|
|
7003
|
+
example: "Search by coupon code"
|
|
7004
|
+
},
|
|
6956
7005
|
{
|
|
6957
7006
|
id: "tableColumns",
|
|
6958
7007
|
label: "Table columns",
|
|
@@ -7017,10 +7066,11 @@ var uiScreenBlueprint = {
|
|
|
7017
7066
|
label: "List page",
|
|
7018
7067
|
frame: [
|
|
7019
7068
|
"Sidebar shell",
|
|
7020
|
-
"
|
|
7021
|
-
"
|
|
7069
|
+
"Workspace topbar",
|
|
7070
|
+
"Page intro card with Breadcrumb and PageTitle",
|
|
7071
|
+
"Optional segmented tabs",
|
|
7072
|
+
"Toolbar card",
|
|
7022
7073
|
"Optional stats",
|
|
7023
|
-
"Filter card",
|
|
7024
7074
|
"DataTable card"
|
|
7025
7075
|
]
|
|
7026
7076
|
},
|
|
@@ -7029,8 +7079,10 @@ var uiScreenBlueprint = {
|
|
|
7029
7079
|
label: "Form page",
|
|
7030
7080
|
frame: [
|
|
7031
7081
|
"Sidebar shell",
|
|
7032
|
-
"
|
|
7033
|
-
"
|
|
7082
|
+
"Workspace topbar",
|
|
7083
|
+
"Page intro card with Breadcrumb and PageTitle",
|
|
7084
|
+
"Optional segmented tabs",
|
|
7085
|
+
"Header actions",
|
|
7034
7086
|
"Sectioned form cards",
|
|
7035
7087
|
"Bottom action row"
|
|
7036
7088
|
]
|
|
@@ -7040,7 +7092,9 @@ var uiScreenBlueprint = {
|
|
|
7040
7092
|
label: "Detail page",
|
|
7041
7093
|
frame: [
|
|
7042
7094
|
"Sidebar shell",
|
|
7043
|
-
"
|
|
7095
|
+
"Workspace topbar",
|
|
7096
|
+
"Page intro card with Breadcrumb and PageTitle",
|
|
7097
|
+
"Optional segmented tabs",
|
|
7044
7098
|
"PageTitle with status/actions",
|
|
7045
7099
|
"Summary stats or metadata card",
|
|
7046
7100
|
"Detail cards and related tables"
|
|
@@ -7051,17 +7105,18 @@ var uiScreenBlueprint = {
|
|
|
7051
7105
|
label: "Dashboard page",
|
|
7052
7106
|
frame: [
|
|
7053
7107
|
"Sidebar shell",
|
|
7054
|
-
"
|
|
7055
|
-
"
|
|
7108
|
+
"Workspace topbar",
|
|
7109
|
+
"Page intro card with Breadcrumb and PageTitle",
|
|
7110
|
+
"Optional segmented tabs",
|
|
7111
|
+
"Toolbar card with actions",
|
|
7056
7112
|
"Stat cards row",
|
|
7057
|
-
"Filters",
|
|
7058
7113
|
"Main insight cards and tables"
|
|
7059
7114
|
]
|
|
7060
7115
|
}
|
|
7061
7116
|
],
|
|
7062
7117
|
workflow: [
|
|
7063
|
-
"Collect the screen brief before coding. Do not invent sidebar items, route urls, filters, fields, or table columns if the brief is missing.",
|
|
7064
|
-
"Use Sidebar plus
|
|
7118
|
+
"Collect the shell + screen brief before coding. Do not invent layout presets, workspace labels, sidebar items, route urls, tabs, filters, fields, or table columns if the brief is missing.",
|
|
7119
|
+
"Use Sidebar plus the workspace topbar and intro card to lock the shell before building the page body.",
|
|
7065
7120
|
"Choose only canonical root exports from @lucasvu/scope-ui.",
|
|
7066
7121
|
"Use Card and ui-grid utilities to create the frame first, then place controls and data components inside.",
|
|
7067
7122
|
"Keep all palette, radius, surface, and shadow decisions in the shared ui-theme.css preset file.",
|
package/dist/index.d.cts
CHANGED
|
@@ -875,7 +875,7 @@ type UiAiComponentDescriptor = {
|
|
|
875
875
|
declare const uiAiManifest: {
|
|
876
876
|
readonly packageName: "@lucasvu/scope-ui";
|
|
877
877
|
readonly styleImport: "@lucasvu/scope-ui/styles.css";
|
|
878
|
-
readonly rules: readonly ["Import the stylesheet once at the app entry before rendering any component.", "If the project declares an approved theme preset in AGENTS.md or ui-theme.css, stay inside that preset and do not invent a second palette.", "Collect the screen brief first: route url, sidebar items, active sidebar item, page title, actions, and the page-specific content schema.", "Prefer the canonical component for each intent instead of mixing legacy MainFe components.", "Use Input/Textarea/Select label props directly for simple fields; use Field only to wrap custom controls or grouped content.", "Use Select for small fixed option lists, SearchableSelect for larger local lists, Combobox for type-and-pick flows, and AsyncCombobox for remote search.", "Always provide a stable rowKey to DataTable and use sortMode=\"server\" when sorting happens on the backend.", "Prefer Card as the outer layout section and keep alerts, stats, and tables inside CardContent when building dashboards or forms.", "Do not import MainFe components unless the target explicitly asks for legacy main-fe styling."];
|
|
878
|
+
readonly rules: readonly ["Import the stylesheet once at the app entry before rendering any component.", "If the project declares an approved theme preset in AGENTS.md or ui-theme.css, stay inside that preset and do not invent a second palette.", "Collect the shell + screen brief first: layout preset, workspace label, route url, sidebar items, active sidebar item, page title, tabs/actions, and the page-specific content schema.", "If the project ships a generated layout preset file, keep the shell aligned with it instead of inventing a new page frame.", "Prefer the canonical component for each intent instead of mixing legacy MainFe components.", "Use Input/Textarea/Select label props directly for simple fields; use Field only to wrap custom controls or grouped content.", "Use Select for small fixed option lists, SearchableSelect for larger local lists, Combobox for type-and-pick flows, and AsyncCombobox for remote search.", "Always provide a stable rowKey to DataTable and use sortMode=\"server\" when sorting happens on the backend.", "Prefer Card as the outer layout section and keep alerts, stats, and tables inside CardContent when building dashboards or forms.", "Do not import MainFe components unless the target explicitly asks for legacy main-fe styling."];
|
|
879
879
|
readonly components: ({
|
|
880
880
|
name: string;
|
|
881
881
|
importName: string;
|
|
@@ -921,6 +921,27 @@ type UiScreenBriefField = {
|
|
|
921
921
|
example: string;
|
|
922
922
|
};
|
|
923
923
|
declare const uiScreenBriefFields: readonly [{
|
|
924
|
+
readonly id: "layoutPreset";
|
|
925
|
+
readonly label: "Layout preset";
|
|
926
|
+
readonly description: "Shared shell preset id that locks the sidebar/topbar/page-card structure.";
|
|
927
|
+
readonly required: false;
|
|
928
|
+
readonly appliesTo: ["all"];
|
|
929
|
+
readonly example: "workspace-admin-v1";
|
|
930
|
+
}, {
|
|
931
|
+
readonly id: "workspaceLabel";
|
|
932
|
+
readonly label: "Workspace label";
|
|
933
|
+
readonly description: "Short label shown in the sidebar or workspace topbar.";
|
|
934
|
+
readonly required: false;
|
|
935
|
+
readonly appliesTo: ["all"];
|
|
936
|
+
readonly example: "Workspace";
|
|
937
|
+
}, {
|
|
938
|
+
readonly id: "timezoneLabel";
|
|
939
|
+
readonly label: "Timezone/meta label";
|
|
940
|
+
readonly description: "Short meta label shown in the top-right shell area, such as a timezone or environment.";
|
|
941
|
+
readonly required: false;
|
|
942
|
+
readonly appliesTo: ["all"];
|
|
943
|
+
readonly example: "UTC+07:00";
|
|
944
|
+
}, {
|
|
924
945
|
readonly id: "pageKind";
|
|
925
946
|
readonly label: "Page kind";
|
|
926
947
|
readonly description: "Choose the base recipe for the screen.";
|
|
@@ -969,6 +990,20 @@ declare const uiScreenBriefFields: readonly [{
|
|
|
969
990
|
readonly required: false;
|
|
970
991
|
readonly appliesTo: ["all"];
|
|
971
992
|
readonly example: "Manage internal user accounts and permissions.";
|
|
993
|
+
}, {
|
|
994
|
+
readonly id: "pageTabs";
|
|
995
|
+
readonly label: "Page tabs";
|
|
996
|
+
readonly description: "Optional segmented tabs rendered under the intro card.";
|
|
997
|
+
readonly required: false;
|
|
998
|
+
readonly appliesTo: ["all"];
|
|
999
|
+
readonly example: "[{ value: \"overview\", label: \"Overview\" }, { value: \"coupons\", label: \"Coupons\" }]";
|
|
1000
|
+
}, {
|
|
1001
|
+
readonly id: "activePageTab";
|
|
1002
|
+
readonly label: "Active page tab";
|
|
1003
|
+
readonly description: "The selected segmented tab value when tabs are present.";
|
|
1004
|
+
readonly required: false;
|
|
1005
|
+
readonly appliesTo: ["all"];
|
|
1006
|
+
readonly example: "coupons";
|
|
972
1007
|
}, {
|
|
973
1008
|
readonly id: "primaryAction";
|
|
974
1009
|
readonly label: "Primary action";
|
|
@@ -997,6 +1032,13 @@ declare const uiScreenBriefFields: readonly [{
|
|
|
997
1032
|
readonly required: false;
|
|
998
1033
|
readonly appliesTo: ["list", "dashboard"];
|
|
999
1034
|
readonly example: "[{ type: \"search\", label: \"Search user\" }, { type: \"select\", label: \"Role\" }]";
|
|
1035
|
+
}, {
|
|
1036
|
+
readonly id: "searchPlaceholder";
|
|
1037
|
+
readonly label: "Search placeholder";
|
|
1038
|
+
readonly description: "Placeholder text for the main toolbar search input when the shell includes one.";
|
|
1039
|
+
readonly required: false;
|
|
1040
|
+
readonly appliesTo: ["list", "dashboard"];
|
|
1041
|
+
readonly example: "Search by coupon code";
|
|
1000
1042
|
}, {
|
|
1001
1043
|
readonly id: "tableColumns";
|
|
1002
1044
|
readonly label: "Table columns";
|
|
@@ -1051,22 +1093,43 @@ declare const uiScreenBlueprint: {
|
|
|
1051
1093
|
readonly pageKinds: readonly [{
|
|
1052
1094
|
readonly id: "list";
|
|
1053
1095
|
readonly label: "List page";
|
|
1054
|
-
readonly frame: readonly ["Sidebar shell", "
|
|
1096
|
+
readonly frame: readonly ["Sidebar shell", "Workspace topbar", "Page intro card with Breadcrumb and PageTitle", "Optional segmented tabs", "Toolbar card", "Optional stats", "DataTable card"];
|
|
1055
1097
|
}, {
|
|
1056
1098
|
readonly id: "form";
|
|
1057
1099
|
readonly label: "Form page";
|
|
1058
|
-
readonly frame: readonly ["Sidebar shell", "
|
|
1100
|
+
readonly frame: readonly ["Sidebar shell", "Workspace topbar", "Page intro card with Breadcrumb and PageTitle", "Optional segmented tabs", "Header actions", "Sectioned form cards", "Bottom action row"];
|
|
1059
1101
|
}, {
|
|
1060
1102
|
readonly id: "detail";
|
|
1061
1103
|
readonly label: "Detail page";
|
|
1062
|
-
readonly frame: readonly ["Sidebar shell", "Breadcrumb", "PageTitle with status/actions", "Summary stats or metadata card", "Detail cards and related tables"];
|
|
1104
|
+
readonly frame: readonly ["Sidebar shell", "Workspace topbar", "Page intro card with Breadcrumb and PageTitle", "Optional segmented tabs", "PageTitle with status/actions", "Summary stats or metadata card", "Detail cards and related tables"];
|
|
1063
1105
|
}, {
|
|
1064
1106
|
readonly id: "dashboard";
|
|
1065
1107
|
readonly label: "Dashboard page";
|
|
1066
|
-
readonly frame: readonly ["Sidebar shell", "
|
|
1108
|
+
readonly frame: readonly ["Sidebar shell", "Workspace topbar", "Page intro card with Breadcrumb and PageTitle", "Optional segmented tabs", "Toolbar card with actions", "Stat cards row", "Main insight cards and tables"];
|
|
1067
1109
|
}];
|
|
1068
|
-
readonly workflow: readonly ["Collect the screen brief before coding. Do not invent sidebar items, route urls, filters, fields, or table columns if the brief is missing.", "Use Sidebar plus
|
|
1110
|
+
readonly workflow: readonly ["Collect the shell + screen brief before coding. Do not invent layout presets, workspace labels, sidebar items, route urls, tabs, filters, fields, or table columns if the brief is missing.", "Use Sidebar plus the workspace topbar and intro card to lock the shell before building the page body.", "Choose only canonical root exports from @lucasvu/scope-ui.", "Use Card and ui-grid utilities to create the frame first, then place controls and data components inside.", "Keep all palette, radius, surface, and shadow decisions in the shared ui-theme.css preset file.", "End with a consistency check against the selected preset and the screen brief."];
|
|
1069
1111
|
readonly briefFields: readonly [{
|
|
1112
|
+
readonly id: "layoutPreset";
|
|
1113
|
+
readonly label: "Layout preset";
|
|
1114
|
+
readonly description: "Shared shell preset id that locks the sidebar/topbar/page-card structure.";
|
|
1115
|
+
readonly required: false;
|
|
1116
|
+
readonly appliesTo: ["all"];
|
|
1117
|
+
readonly example: "workspace-admin-v1";
|
|
1118
|
+
}, {
|
|
1119
|
+
readonly id: "workspaceLabel";
|
|
1120
|
+
readonly label: "Workspace label";
|
|
1121
|
+
readonly description: "Short label shown in the sidebar or workspace topbar.";
|
|
1122
|
+
readonly required: false;
|
|
1123
|
+
readonly appliesTo: ["all"];
|
|
1124
|
+
readonly example: "Workspace";
|
|
1125
|
+
}, {
|
|
1126
|
+
readonly id: "timezoneLabel";
|
|
1127
|
+
readonly label: "Timezone/meta label";
|
|
1128
|
+
readonly description: "Short meta label shown in the top-right shell area, such as a timezone or environment.";
|
|
1129
|
+
readonly required: false;
|
|
1130
|
+
readonly appliesTo: ["all"];
|
|
1131
|
+
readonly example: "UTC+07:00";
|
|
1132
|
+
}, {
|
|
1070
1133
|
readonly id: "pageKind";
|
|
1071
1134
|
readonly label: "Page kind";
|
|
1072
1135
|
readonly description: "Choose the base recipe for the screen.";
|
|
@@ -1115,6 +1178,20 @@ declare const uiScreenBlueprint: {
|
|
|
1115
1178
|
readonly required: false;
|
|
1116
1179
|
readonly appliesTo: ["all"];
|
|
1117
1180
|
readonly example: "Manage internal user accounts and permissions.";
|
|
1181
|
+
}, {
|
|
1182
|
+
readonly id: "pageTabs";
|
|
1183
|
+
readonly label: "Page tabs";
|
|
1184
|
+
readonly description: "Optional segmented tabs rendered under the intro card.";
|
|
1185
|
+
readonly required: false;
|
|
1186
|
+
readonly appliesTo: ["all"];
|
|
1187
|
+
readonly example: "[{ value: \"overview\", label: \"Overview\" }, { value: \"coupons\", label: \"Coupons\" }]";
|
|
1188
|
+
}, {
|
|
1189
|
+
readonly id: "activePageTab";
|
|
1190
|
+
readonly label: "Active page tab";
|
|
1191
|
+
readonly description: "The selected segmented tab value when tabs are present.";
|
|
1192
|
+
readonly required: false;
|
|
1193
|
+
readonly appliesTo: ["all"];
|
|
1194
|
+
readonly example: "coupons";
|
|
1118
1195
|
}, {
|
|
1119
1196
|
readonly id: "primaryAction";
|
|
1120
1197
|
readonly label: "Primary action";
|
|
@@ -1143,6 +1220,13 @@ declare const uiScreenBlueprint: {
|
|
|
1143
1220
|
readonly required: false;
|
|
1144
1221
|
readonly appliesTo: ["list", "dashboard"];
|
|
1145
1222
|
readonly example: "[{ type: \"search\", label: \"Search user\" }, { type: \"select\", label: \"Role\" }]";
|
|
1223
|
+
}, {
|
|
1224
|
+
readonly id: "searchPlaceholder";
|
|
1225
|
+
readonly label: "Search placeholder";
|
|
1226
|
+
readonly description: "Placeholder text for the main toolbar search input when the shell includes one.";
|
|
1227
|
+
readonly required: false;
|
|
1228
|
+
readonly appliesTo: ["list", "dashboard"];
|
|
1229
|
+
readonly example: "Search by coupon code";
|
|
1146
1230
|
}, {
|
|
1147
1231
|
readonly id: "tableColumns";
|
|
1148
1232
|
readonly label: "Table columns";
|
package/dist/index.d.ts
CHANGED
|
@@ -875,7 +875,7 @@ type UiAiComponentDescriptor = {
|
|
|
875
875
|
declare const uiAiManifest: {
|
|
876
876
|
readonly packageName: "@lucasvu/scope-ui";
|
|
877
877
|
readonly styleImport: "@lucasvu/scope-ui/styles.css";
|
|
878
|
-
readonly rules: readonly ["Import the stylesheet once at the app entry before rendering any component.", "If the project declares an approved theme preset in AGENTS.md or ui-theme.css, stay inside that preset and do not invent a second palette.", "Collect the screen brief first: route url, sidebar items, active sidebar item, page title, actions, and the page-specific content schema.", "Prefer the canonical component for each intent instead of mixing legacy MainFe components.", "Use Input/Textarea/Select label props directly for simple fields; use Field only to wrap custom controls or grouped content.", "Use Select for small fixed option lists, SearchableSelect for larger local lists, Combobox for type-and-pick flows, and AsyncCombobox for remote search.", "Always provide a stable rowKey to DataTable and use sortMode=\"server\" when sorting happens on the backend.", "Prefer Card as the outer layout section and keep alerts, stats, and tables inside CardContent when building dashboards or forms.", "Do not import MainFe components unless the target explicitly asks for legacy main-fe styling."];
|
|
878
|
+
readonly rules: readonly ["Import the stylesheet once at the app entry before rendering any component.", "If the project declares an approved theme preset in AGENTS.md or ui-theme.css, stay inside that preset and do not invent a second palette.", "Collect the shell + screen brief first: layout preset, workspace label, route url, sidebar items, active sidebar item, page title, tabs/actions, and the page-specific content schema.", "If the project ships a generated layout preset file, keep the shell aligned with it instead of inventing a new page frame.", "Prefer the canonical component for each intent instead of mixing legacy MainFe components.", "Use Input/Textarea/Select label props directly for simple fields; use Field only to wrap custom controls or grouped content.", "Use Select for small fixed option lists, SearchableSelect for larger local lists, Combobox for type-and-pick flows, and AsyncCombobox for remote search.", "Always provide a stable rowKey to DataTable and use sortMode=\"server\" when sorting happens on the backend.", "Prefer Card as the outer layout section and keep alerts, stats, and tables inside CardContent when building dashboards or forms.", "Do not import MainFe components unless the target explicitly asks for legacy main-fe styling."];
|
|
879
879
|
readonly components: ({
|
|
880
880
|
name: string;
|
|
881
881
|
importName: string;
|
|
@@ -921,6 +921,27 @@ type UiScreenBriefField = {
|
|
|
921
921
|
example: string;
|
|
922
922
|
};
|
|
923
923
|
declare const uiScreenBriefFields: readonly [{
|
|
924
|
+
readonly id: "layoutPreset";
|
|
925
|
+
readonly label: "Layout preset";
|
|
926
|
+
readonly description: "Shared shell preset id that locks the sidebar/topbar/page-card structure.";
|
|
927
|
+
readonly required: false;
|
|
928
|
+
readonly appliesTo: ["all"];
|
|
929
|
+
readonly example: "workspace-admin-v1";
|
|
930
|
+
}, {
|
|
931
|
+
readonly id: "workspaceLabel";
|
|
932
|
+
readonly label: "Workspace label";
|
|
933
|
+
readonly description: "Short label shown in the sidebar or workspace topbar.";
|
|
934
|
+
readonly required: false;
|
|
935
|
+
readonly appliesTo: ["all"];
|
|
936
|
+
readonly example: "Workspace";
|
|
937
|
+
}, {
|
|
938
|
+
readonly id: "timezoneLabel";
|
|
939
|
+
readonly label: "Timezone/meta label";
|
|
940
|
+
readonly description: "Short meta label shown in the top-right shell area, such as a timezone or environment.";
|
|
941
|
+
readonly required: false;
|
|
942
|
+
readonly appliesTo: ["all"];
|
|
943
|
+
readonly example: "UTC+07:00";
|
|
944
|
+
}, {
|
|
924
945
|
readonly id: "pageKind";
|
|
925
946
|
readonly label: "Page kind";
|
|
926
947
|
readonly description: "Choose the base recipe for the screen.";
|
|
@@ -969,6 +990,20 @@ declare const uiScreenBriefFields: readonly [{
|
|
|
969
990
|
readonly required: false;
|
|
970
991
|
readonly appliesTo: ["all"];
|
|
971
992
|
readonly example: "Manage internal user accounts and permissions.";
|
|
993
|
+
}, {
|
|
994
|
+
readonly id: "pageTabs";
|
|
995
|
+
readonly label: "Page tabs";
|
|
996
|
+
readonly description: "Optional segmented tabs rendered under the intro card.";
|
|
997
|
+
readonly required: false;
|
|
998
|
+
readonly appliesTo: ["all"];
|
|
999
|
+
readonly example: "[{ value: \"overview\", label: \"Overview\" }, { value: \"coupons\", label: \"Coupons\" }]";
|
|
1000
|
+
}, {
|
|
1001
|
+
readonly id: "activePageTab";
|
|
1002
|
+
readonly label: "Active page tab";
|
|
1003
|
+
readonly description: "The selected segmented tab value when tabs are present.";
|
|
1004
|
+
readonly required: false;
|
|
1005
|
+
readonly appliesTo: ["all"];
|
|
1006
|
+
readonly example: "coupons";
|
|
972
1007
|
}, {
|
|
973
1008
|
readonly id: "primaryAction";
|
|
974
1009
|
readonly label: "Primary action";
|
|
@@ -997,6 +1032,13 @@ declare const uiScreenBriefFields: readonly [{
|
|
|
997
1032
|
readonly required: false;
|
|
998
1033
|
readonly appliesTo: ["list", "dashboard"];
|
|
999
1034
|
readonly example: "[{ type: \"search\", label: \"Search user\" }, { type: \"select\", label: \"Role\" }]";
|
|
1035
|
+
}, {
|
|
1036
|
+
readonly id: "searchPlaceholder";
|
|
1037
|
+
readonly label: "Search placeholder";
|
|
1038
|
+
readonly description: "Placeholder text for the main toolbar search input when the shell includes one.";
|
|
1039
|
+
readonly required: false;
|
|
1040
|
+
readonly appliesTo: ["list", "dashboard"];
|
|
1041
|
+
readonly example: "Search by coupon code";
|
|
1000
1042
|
}, {
|
|
1001
1043
|
readonly id: "tableColumns";
|
|
1002
1044
|
readonly label: "Table columns";
|
|
@@ -1051,22 +1093,43 @@ declare const uiScreenBlueprint: {
|
|
|
1051
1093
|
readonly pageKinds: readonly [{
|
|
1052
1094
|
readonly id: "list";
|
|
1053
1095
|
readonly label: "List page";
|
|
1054
|
-
readonly frame: readonly ["Sidebar shell", "
|
|
1096
|
+
readonly frame: readonly ["Sidebar shell", "Workspace topbar", "Page intro card with Breadcrumb and PageTitle", "Optional segmented tabs", "Toolbar card", "Optional stats", "DataTable card"];
|
|
1055
1097
|
}, {
|
|
1056
1098
|
readonly id: "form";
|
|
1057
1099
|
readonly label: "Form page";
|
|
1058
|
-
readonly frame: readonly ["Sidebar shell", "
|
|
1100
|
+
readonly frame: readonly ["Sidebar shell", "Workspace topbar", "Page intro card with Breadcrumb and PageTitle", "Optional segmented tabs", "Header actions", "Sectioned form cards", "Bottom action row"];
|
|
1059
1101
|
}, {
|
|
1060
1102
|
readonly id: "detail";
|
|
1061
1103
|
readonly label: "Detail page";
|
|
1062
|
-
readonly frame: readonly ["Sidebar shell", "Breadcrumb", "PageTitle with status/actions", "Summary stats or metadata card", "Detail cards and related tables"];
|
|
1104
|
+
readonly frame: readonly ["Sidebar shell", "Workspace topbar", "Page intro card with Breadcrumb and PageTitle", "Optional segmented tabs", "PageTitle with status/actions", "Summary stats or metadata card", "Detail cards and related tables"];
|
|
1063
1105
|
}, {
|
|
1064
1106
|
readonly id: "dashboard";
|
|
1065
1107
|
readonly label: "Dashboard page";
|
|
1066
|
-
readonly frame: readonly ["Sidebar shell", "
|
|
1108
|
+
readonly frame: readonly ["Sidebar shell", "Workspace topbar", "Page intro card with Breadcrumb and PageTitle", "Optional segmented tabs", "Toolbar card with actions", "Stat cards row", "Main insight cards and tables"];
|
|
1067
1109
|
}];
|
|
1068
|
-
readonly workflow: readonly ["Collect the screen brief before coding. Do not invent sidebar items, route urls, filters, fields, or table columns if the brief is missing.", "Use Sidebar plus
|
|
1110
|
+
readonly workflow: readonly ["Collect the shell + screen brief before coding. Do not invent layout presets, workspace labels, sidebar items, route urls, tabs, filters, fields, or table columns if the brief is missing.", "Use Sidebar plus the workspace topbar and intro card to lock the shell before building the page body.", "Choose only canonical root exports from @lucasvu/scope-ui.", "Use Card and ui-grid utilities to create the frame first, then place controls and data components inside.", "Keep all palette, radius, surface, and shadow decisions in the shared ui-theme.css preset file.", "End with a consistency check against the selected preset and the screen brief."];
|
|
1069
1111
|
readonly briefFields: readonly [{
|
|
1112
|
+
readonly id: "layoutPreset";
|
|
1113
|
+
readonly label: "Layout preset";
|
|
1114
|
+
readonly description: "Shared shell preset id that locks the sidebar/topbar/page-card structure.";
|
|
1115
|
+
readonly required: false;
|
|
1116
|
+
readonly appliesTo: ["all"];
|
|
1117
|
+
readonly example: "workspace-admin-v1";
|
|
1118
|
+
}, {
|
|
1119
|
+
readonly id: "workspaceLabel";
|
|
1120
|
+
readonly label: "Workspace label";
|
|
1121
|
+
readonly description: "Short label shown in the sidebar or workspace topbar.";
|
|
1122
|
+
readonly required: false;
|
|
1123
|
+
readonly appliesTo: ["all"];
|
|
1124
|
+
readonly example: "Workspace";
|
|
1125
|
+
}, {
|
|
1126
|
+
readonly id: "timezoneLabel";
|
|
1127
|
+
readonly label: "Timezone/meta label";
|
|
1128
|
+
readonly description: "Short meta label shown in the top-right shell area, such as a timezone or environment.";
|
|
1129
|
+
readonly required: false;
|
|
1130
|
+
readonly appliesTo: ["all"];
|
|
1131
|
+
readonly example: "UTC+07:00";
|
|
1132
|
+
}, {
|
|
1070
1133
|
readonly id: "pageKind";
|
|
1071
1134
|
readonly label: "Page kind";
|
|
1072
1135
|
readonly description: "Choose the base recipe for the screen.";
|
|
@@ -1115,6 +1178,20 @@ declare const uiScreenBlueprint: {
|
|
|
1115
1178
|
readonly required: false;
|
|
1116
1179
|
readonly appliesTo: ["all"];
|
|
1117
1180
|
readonly example: "Manage internal user accounts and permissions.";
|
|
1181
|
+
}, {
|
|
1182
|
+
readonly id: "pageTabs";
|
|
1183
|
+
readonly label: "Page tabs";
|
|
1184
|
+
readonly description: "Optional segmented tabs rendered under the intro card.";
|
|
1185
|
+
readonly required: false;
|
|
1186
|
+
readonly appliesTo: ["all"];
|
|
1187
|
+
readonly example: "[{ value: \"overview\", label: \"Overview\" }, { value: \"coupons\", label: \"Coupons\" }]";
|
|
1188
|
+
}, {
|
|
1189
|
+
readonly id: "activePageTab";
|
|
1190
|
+
readonly label: "Active page tab";
|
|
1191
|
+
readonly description: "The selected segmented tab value when tabs are present.";
|
|
1192
|
+
readonly required: false;
|
|
1193
|
+
readonly appliesTo: ["all"];
|
|
1194
|
+
readonly example: "coupons";
|
|
1118
1195
|
}, {
|
|
1119
1196
|
readonly id: "primaryAction";
|
|
1120
1197
|
readonly label: "Primary action";
|
|
@@ -1143,6 +1220,13 @@ declare const uiScreenBlueprint: {
|
|
|
1143
1220
|
readonly required: false;
|
|
1144
1221
|
readonly appliesTo: ["list", "dashboard"];
|
|
1145
1222
|
readonly example: "[{ type: \"search\", label: \"Search user\" }, { type: \"select\", label: \"Role\" }]";
|
|
1223
|
+
}, {
|
|
1224
|
+
readonly id: "searchPlaceholder";
|
|
1225
|
+
readonly label: "Search placeholder";
|
|
1226
|
+
readonly description: "Placeholder text for the main toolbar search input when the shell includes one.";
|
|
1227
|
+
readonly required: false;
|
|
1228
|
+
readonly appliesTo: ["list", "dashboard"];
|
|
1229
|
+
readonly example: "Search by coupon code";
|
|
1146
1230
|
}, {
|
|
1147
1231
|
readonly id: "tableColumns";
|
|
1148
1232
|
readonly label: "Table columns";
|
package/dist/index.js
CHANGED
|
@@ -6625,7 +6625,8 @@ var uiAiManifest = {
|
|
|
6625
6625
|
rules: [
|
|
6626
6626
|
"Import the stylesheet once at the app entry before rendering any component.",
|
|
6627
6627
|
"If the project declares an approved theme preset in AGENTS.md or ui-theme.css, stay inside that preset and do not invent a second palette.",
|
|
6628
|
-
"Collect the screen brief first: route url, sidebar items, active sidebar item, page title, actions, and the page-specific content schema.",
|
|
6628
|
+
"Collect the shell + screen brief first: layout preset, workspace label, route url, sidebar items, active sidebar item, page title, tabs/actions, and the page-specific content schema.",
|
|
6629
|
+
"If the project ships a generated layout preset file, keep the shell aligned with it instead of inventing a new page frame.",
|
|
6629
6630
|
"Prefer the canonical component for each intent instead of mixing legacy MainFe components.",
|
|
6630
6631
|
"Use Input/Textarea/Select label props directly for simple fields; use Field only to wrap custom controls or grouped content.",
|
|
6631
6632
|
"Use Select for small fixed option lists, SearchableSelect for larger local lists, Combobox for type-and-pick flows, and AsyncCombobox for remote search.",
|
|
@@ -6843,6 +6844,30 @@ var uiAiManifest = {
|
|
|
6843
6844
|
|
|
6844
6845
|
// src/screen-blueprint.ts
|
|
6845
6846
|
var uiScreenBriefFields = [
|
|
6847
|
+
{
|
|
6848
|
+
id: "layoutPreset",
|
|
6849
|
+
label: "Layout preset",
|
|
6850
|
+
description: "Shared shell preset id that locks the sidebar/topbar/page-card structure.",
|
|
6851
|
+
required: false,
|
|
6852
|
+
appliesTo: ["all"],
|
|
6853
|
+
example: "workspace-admin-v1"
|
|
6854
|
+
},
|
|
6855
|
+
{
|
|
6856
|
+
id: "workspaceLabel",
|
|
6857
|
+
label: "Workspace label",
|
|
6858
|
+
description: "Short label shown in the sidebar or workspace topbar.",
|
|
6859
|
+
required: false,
|
|
6860
|
+
appliesTo: ["all"],
|
|
6861
|
+
example: "Workspace"
|
|
6862
|
+
},
|
|
6863
|
+
{
|
|
6864
|
+
id: "timezoneLabel",
|
|
6865
|
+
label: "Timezone/meta label",
|
|
6866
|
+
description: "Short meta label shown in the top-right shell area, such as a timezone or environment.",
|
|
6867
|
+
required: false,
|
|
6868
|
+
appliesTo: ["all"],
|
|
6869
|
+
example: "UTC+07:00"
|
|
6870
|
+
},
|
|
6846
6871
|
{
|
|
6847
6872
|
id: "pageKind",
|
|
6848
6873
|
label: "Page kind",
|
|
@@ -6899,6 +6924,22 @@ var uiScreenBriefFields = [
|
|
|
6899
6924
|
appliesTo: ["all"],
|
|
6900
6925
|
example: "Manage internal user accounts and permissions."
|
|
6901
6926
|
},
|
|
6927
|
+
{
|
|
6928
|
+
id: "pageTabs",
|
|
6929
|
+
label: "Page tabs",
|
|
6930
|
+
description: "Optional segmented tabs rendered under the intro card.",
|
|
6931
|
+
required: false,
|
|
6932
|
+
appliesTo: ["all"],
|
|
6933
|
+
example: '[{ value: "overview", label: "Overview" }, { value: "coupons", label: "Coupons" }]'
|
|
6934
|
+
},
|
|
6935
|
+
{
|
|
6936
|
+
id: "activePageTab",
|
|
6937
|
+
label: "Active page tab",
|
|
6938
|
+
description: "The selected segmented tab value when tabs are present.",
|
|
6939
|
+
required: false,
|
|
6940
|
+
appliesTo: ["all"],
|
|
6941
|
+
example: "coupons"
|
|
6942
|
+
},
|
|
6902
6943
|
{
|
|
6903
6944
|
id: "primaryAction",
|
|
6904
6945
|
label: "Primary action",
|
|
@@ -6931,6 +6972,14 @@ var uiScreenBriefFields = [
|
|
|
6931
6972
|
appliesTo: ["list", "dashboard"],
|
|
6932
6973
|
example: '[{ type: "search", label: "Search user" }, { type: "select", label: "Role" }]'
|
|
6933
6974
|
},
|
|
6975
|
+
{
|
|
6976
|
+
id: "searchPlaceholder",
|
|
6977
|
+
label: "Search placeholder",
|
|
6978
|
+
description: "Placeholder text for the main toolbar search input when the shell includes one.",
|
|
6979
|
+
required: false,
|
|
6980
|
+
appliesTo: ["list", "dashboard"],
|
|
6981
|
+
example: "Search by coupon code"
|
|
6982
|
+
},
|
|
6934
6983
|
{
|
|
6935
6984
|
id: "tableColumns",
|
|
6936
6985
|
label: "Table columns",
|
|
@@ -6995,10 +7044,11 @@ var uiScreenBlueprint = {
|
|
|
6995
7044
|
label: "List page",
|
|
6996
7045
|
frame: [
|
|
6997
7046
|
"Sidebar shell",
|
|
6998
|
-
"
|
|
6999
|
-
"
|
|
7047
|
+
"Workspace topbar",
|
|
7048
|
+
"Page intro card with Breadcrumb and PageTitle",
|
|
7049
|
+
"Optional segmented tabs",
|
|
7050
|
+
"Toolbar card",
|
|
7000
7051
|
"Optional stats",
|
|
7001
|
-
"Filter card",
|
|
7002
7052
|
"DataTable card"
|
|
7003
7053
|
]
|
|
7004
7054
|
},
|
|
@@ -7007,8 +7057,10 @@ var uiScreenBlueprint = {
|
|
|
7007
7057
|
label: "Form page",
|
|
7008
7058
|
frame: [
|
|
7009
7059
|
"Sidebar shell",
|
|
7010
|
-
"
|
|
7011
|
-
"
|
|
7060
|
+
"Workspace topbar",
|
|
7061
|
+
"Page intro card with Breadcrumb and PageTitle",
|
|
7062
|
+
"Optional segmented tabs",
|
|
7063
|
+
"Header actions",
|
|
7012
7064
|
"Sectioned form cards",
|
|
7013
7065
|
"Bottom action row"
|
|
7014
7066
|
]
|
|
@@ -7018,7 +7070,9 @@ var uiScreenBlueprint = {
|
|
|
7018
7070
|
label: "Detail page",
|
|
7019
7071
|
frame: [
|
|
7020
7072
|
"Sidebar shell",
|
|
7021
|
-
"
|
|
7073
|
+
"Workspace topbar",
|
|
7074
|
+
"Page intro card with Breadcrumb and PageTitle",
|
|
7075
|
+
"Optional segmented tabs",
|
|
7022
7076
|
"PageTitle with status/actions",
|
|
7023
7077
|
"Summary stats or metadata card",
|
|
7024
7078
|
"Detail cards and related tables"
|
|
@@ -7029,17 +7083,18 @@ var uiScreenBlueprint = {
|
|
|
7029
7083
|
label: "Dashboard page",
|
|
7030
7084
|
frame: [
|
|
7031
7085
|
"Sidebar shell",
|
|
7032
|
-
"
|
|
7033
|
-
"
|
|
7086
|
+
"Workspace topbar",
|
|
7087
|
+
"Page intro card with Breadcrumb and PageTitle",
|
|
7088
|
+
"Optional segmented tabs",
|
|
7089
|
+
"Toolbar card with actions",
|
|
7034
7090
|
"Stat cards row",
|
|
7035
|
-
"Filters",
|
|
7036
7091
|
"Main insight cards and tables"
|
|
7037
7092
|
]
|
|
7038
7093
|
}
|
|
7039
7094
|
],
|
|
7040
7095
|
workflow: [
|
|
7041
|
-
"Collect the screen brief before coding. Do not invent sidebar items, route urls, filters, fields, or table columns if the brief is missing.",
|
|
7042
|
-
"Use Sidebar plus
|
|
7096
|
+
"Collect the shell + screen brief before coding. Do not invent layout presets, workspace labels, sidebar items, route urls, tabs, filters, fields, or table columns if the brief is missing.",
|
|
7097
|
+
"Use Sidebar plus the workspace topbar and intro card to lock the shell before building the page body.",
|
|
7043
7098
|
"Choose only canonical root exports from @lucasvu/scope-ui.",
|
|
7044
7099
|
"Use Card and ui-grid utilities to create the frame first, then place controls and data components inside.",
|
|
7045
7100
|
"Keep all palette, radius, surface, and shadow decisions in the shared ui-theme.css preset file.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lucasvu/scope-ui",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"autoprefixer": "^10.4.23",
|
|
51
51
|
"postcss": "^8.5.6",
|
|
52
52
|
"tailwindcss": "3.4.17",
|
|
53
|
-
"tsup": "^8.5.
|
|
53
|
+
"tsup": "^8.5.1",
|
|
54
54
|
"typescript": "^5.8.3"
|
|
55
55
|
}
|
|
56
|
-
}
|
|
56
|
+
}
|