@nextop-os/ui-system 0.0.17 → 0.0.18
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/AGENTS.md +30 -8
- package/README.md +11 -14
- package/agent/install-skill.mjs +65 -5
- package/agent/nextop-ui-system/SKILL.md +119 -8
- package/agent/nextop-ui-system/references/extract-base-component.md +50 -6
- package/agent/nextop-ui-system/references/maintain-inventory.md +5 -0
- package/agent/nextop-ui-system/references/promote-business-component.md +94 -208
- package/dist/chunk-GE5YVRTV.js +859 -0
- package/dist/chunk-GE5YVRTV.js.map +1 -0
- package/dist/chunk-KJQ366TA.js +70 -0
- package/dist/chunk-KJQ366TA.js.map +1 -0
- package/dist/chunk-LVHEV755.js +2553 -0
- package/dist/chunk-LVHEV755.js.map +1 -0
- package/dist/components/index.d.ts +162 -11
- package/dist/components/index.js +62 -2
- package/dist/date-format.d.ts +6 -0
- package/dist/date-format.js +11 -0
- package/dist/date-format.js.map +1 -0
- package/dist/dev-vite.js +12 -5
- package/dist/dev-vite.js.map +1 -1
- package/dist/icons/index.d.ts +90 -47
- package/dist/icons/index.js +91 -11
- package/dist/index.d.ts +3 -2
- package/dist/index.js +159 -11
- package/dist/metadata/components.json +1320 -265
- package/dist/metadata/components.schema.json +4 -0
- package/dist/metadata/index.d.ts +3 -1
- package/dist/metadata/index.js +1320 -265
- package/dist/metadata/index.js.map +1 -1
- package/dist/styles/base.css +85 -0
- package/dist/styles/index.css +1 -0
- package/dist/styles/semantic.css +7 -0
- package/dist/styles/theme.css +82 -1
- package/package.json +10 -3
- package/ui-system.md +640 -0
- package/UI_SYSTEM_GUIDELINES.md +0 -148
- package/dist/chunk-FT633NLJ.js +0 -1159
- package/dist/chunk-FT633NLJ.js.map +0 -1
- package/dist/chunk-NFSMZKML.js +0 -208
- package/dist/chunk-NFSMZKML.js.map +0 -1
package/AGENTS.md
CHANGED
|
@@ -11,8 +11,12 @@ components, component metadata, storyboard inventory, and the bundled
|
|
|
11
11
|
`nextop-ui-system` agent skill.
|
|
12
12
|
|
|
13
13
|
Before changing components, icons, metadata, styles, storyboard examples, or
|
|
14
|
-
the bundled skill, read
|
|
15
|
-
|
|
14
|
+
the bundled skill, read `ui-system.md`.
|
|
15
|
+
|
|
16
|
+
UI-system design compliance is a release gate for this package, not a follow-up
|
|
17
|
+
task. If a promoted component does not yet follow the shared token model,
|
|
18
|
+
surface language, primitive vocabulary, and storyboard evidence standard, do
|
|
19
|
+
not report it as complete.
|
|
16
20
|
|
|
17
21
|
## Public API
|
|
18
22
|
|
|
@@ -45,10 +49,26 @@ Rules:
|
|
|
45
49
|
task, agent, status, permission, and callbacks, but must not own daemon,
|
|
46
50
|
Electron, router, store, query, filesystem, persistence, or workflow calls
|
|
47
51
|
- before promoting a business component, scan source usage, build a
|
|
48
|
-
code-evidence state matrix, and
|
|
49
|
-
|
|
52
|
+
code-evidence state matrix, and define the public props boundary from that
|
|
53
|
+
evidence; after that, promote it directly into `packages/ui/system` and add
|
|
54
|
+
storyboard coverage for the accepted states
|
|
50
55
|
- business components should compose `base` primitives instead of recreating
|
|
51
56
|
buttons, fields, dialogs, cards, icons, or overlays
|
|
57
|
+
- promoted components and their storyboard examples must use UI-system semantic
|
|
58
|
+
tokens and approved shared CSS variables; do not leave raw `hex`,
|
|
59
|
+
`rgb(...)`, `rgba(...)`, ad hoc gradients, or app-local palette values in the
|
|
60
|
+
final UI-system implementation unless they already come from approved shared
|
|
61
|
+
tokens
|
|
62
|
+
- storyboard coverage must show the component's real promoted surface and
|
|
63
|
+
states; do not rely on surrounding docs chrome or wrapper panels to mask
|
|
64
|
+
component-level visual drift
|
|
65
|
+
- UI storyboard foundation content is JSON-driven. When changing documented
|
|
66
|
+
token, color, typography, spacing, radius, motion, or overview display data,
|
|
67
|
+
edit `apps/ui-storyboard/src/foundation/*.json` directly instead of
|
|
68
|
+
hardcoding those values in `apps/ui-storyboard/src/App.tsx`
|
|
69
|
+
- migrated consumers must end on the same UI-system visual implementation for
|
|
70
|
+
the promoted surface; temporary bridges are allowed only for wiring, not as a
|
|
71
|
+
separate long-lived token or styling system
|
|
52
72
|
- treat this package as the shared shadcn and Radix host package
|
|
53
73
|
- when a primitive exists in the shadcn registry, acquire it through shadcn CLI
|
|
54
74
|
targeted at this package instead of handwriting the component body
|
|
@@ -75,10 +95,12 @@ Rules:
|
|
|
75
95
|
`pnpm --filter @nextop-os/ui-storyboard typecheck`
|
|
76
96
|
- If a change affects desktop integration, also run
|
|
77
97
|
`pnpm --filter @nextop-os/desktop build`
|
|
98
|
+
- In the handoff, explicitly state whether tokens, primitives, storyboard
|
|
99
|
+
surface, and migrated consumer all comply with the UI-system standard; if any
|
|
100
|
+
of those are still divergent, the work is not complete
|
|
78
101
|
|
|
79
102
|
## Related Docs
|
|
80
103
|
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
-
|
|
84
|
-
- [docs/conventions/local-git-hooks.md](/Users/zhengweibin/Desktop/team-shell/nextop/docs/conventions/local-git-hooks.md)
|
|
104
|
+
- `ui-system.md`
|
|
105
|
+
- `docs/conventions/desktop-visual-language.md`
|
|
106
|
+
- `docs/conventions/local-git-hooks.md`
|
package/README.md
CHANGED
|
@@ -38,14 +38,9 @@ export default defineConfig({
|
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
When the dev server is reachable, the plugin mirrors the allowed UI-system
|
|
41
|
-
source files into `.nextop-ui-system-dev/` and aliases the
|
|
42
|
-
entrypoints to that cache. When the dev server is unavailable,
|
|
43
|
-
back to the installed package in `node_modules`.
|
|
44
|
-
|
|
45
|
-
Temporary agent previews should use this same dev-server path instead of
|
|
46
|
-
hardcoding local checkout paths. Generate the preview outside the repository,
|
|
47
|
-
configure its Vite app with `nextopUISystemDev({ serverUrl })`, and import
|
|
48
|
-
components, icons, styles, and utilities through the stable public entrypoints.
|
|
41
|
+
source and skill-support files into `.nextop-ui-system-dev/` and aliases the
|
|
42
|
+
stable package entrypoints to that cache. When the dev server is unavailable,
|
|
43
|
+
resolution falls back to the installed package in `node_modules`.
|
|
49
44
|
|
|
50
45
|
Add the generated cache to the external app's `.gitignore`:
|
|
51
46
|
|
|
@@ -71,14 +66,14 @@ import { uiSystemMetadata } from "@nextop-os/ui-system/metadata";
|
|
|
71
66
|
|
|
72
67
|
When promoting business UI into this package, use the bundled
|
|
73
68
|
`agent/nextop-ui-system/SKILL.md` skill when it is available. In the source
|
|
74
|
-
checkout, also read `AGENTS.md
|
|
75
|
-
are:
|
|
69
|
+
checkout, also read `AGENTS.md`, `ui-system.md`, and
|
|
70
|
+
`docs/conventions/desktop-visual-language.md`. The durable rules are:
|
|
76
71
|
|
|
77
72
|
1. prefer existing metadata entries before creating a component
|
|
78
73
|
2. classify the component as `base` or `business`
|
|
79
74
|
3. keep business components host-agnostic and side-effect-free
|
|
80
|
-
4. before promoting a business component, scan source usage and
|
|
81
|
-
|
|
75
|
+
4. before promoting a business component, scan source usage and define the
|
|
76
|
+
public props boundary from code evidence
|
|
82
77
|
5. compose business components from base primitives
|
|
83
78
|
6. add metadata, stable exports, and storyboard examples for public UI
|
|
84
79
|
7. run metadata and boundary validation before shipping
|
|
@@ -96,5 +91,7 @@ This copies the package skill into:
|
|
|
96
91
|
.codex/skills/nextop-ui-system/SKILL.md
|
|
97
92
|
```
|
|
98
93
|
|
|
99
|
-
|
|
100
|
-
|
|
94
|
+
When `.nextop-ui-system-dev/` is present, the installer prefers the synced
|
|
95
|
+
source checkout so the installed skill and bundled UI-system rules stay aligned
|
|
96
|
+
with the current local UI-system source. The installer does not overwrite a
|
|
97
|
+
locally modified skill unless `--force` is provided.
|
package/agent/install-skill.mjs
CHANGED
|
@@ -14,8 +14,9 @@ import { dirname, join, relative, resolve } from "node:path";
|
|
|
14
14
|
import { fileURLToPath } from "node:url";
|
|
15
15
|
|
|
16
16
|
const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
17
|
-
const sourceDirectory = join(packageRoot, "agent", "nextop-ui-system");
|
|
18
17
|
const skillName = "nextop-ui-system";
|
|
18
|
+
const devCacheDirectoryName = ".nextop-ui-system-dev";
|
|
19
|
+
const companionFiles = ["AGENTS.md", "ui-system.md"];
|
|
19
20
|
|
|
20
21
|
const options = parseArgs(process.argv.slice(2));
|
|
21
22
|
|
|
@@ -26,8 +27,15 @@ if (options.help) {
|
|
|
26
27
|
|
|
27
28
|
const targetRoot = resolve(options.cwd, ".codex", "skills");
|
|
28
29
|
const targetDirectory = join(targetRoot, skillName);
|
|
30
|
+
const sourceRoot = await resolveSourceRoot(options.cwd);
|
|
31
|
+
const sourceDirectory = join(sourceRoot, "agent", skillName);
|
|
29
32
|
|
|
30
33
|
await assertReadableDirectory(sourceDirectory);
|
|
34
|
+
await Promise.all(
|
|
35
|
+
companionFiles.map((fileName) =>
|
|
36
|
+
assertReadableFile(join(sourceRoot, fileName))
|
|
37
|
+
)
|
|
38
|
+
);
|
|
31
39
|
await mkdir(targetRoot, { recursive: true });
|
|
32
40
|
|
|
33
41
|
if (await pathExists(targetDirectory)) {
|
|
@@ -38,7 +46,7 @@ if (await pathExists(targetDirectory)) {
|
|
|
38
46
|
}
|
|
39
47
|
|
|
40
48
|
if (!options.force) {
|
|
41
|
-
if (await directoriesMatch(sourceDirectory, targetDirectory)) {
|
|
49
|
+
if (await directoriesMatch(sourceRoot, sourceDirectory, targetDirectory)) {
|
|
42
50
|
console.log(
|
|
43
51
|
`nextop-ui-system skill already configured at ${targetDirectory}`
|
|
44
52
|
);
|
|
@@ -59,6 +67,15 @@ await cp(sourceDirectory, targetDirectory, {
|
|
|
59
67
|
force: true,
|
|
60
68
|
recursive: true
|
|
61
69
|
});
|
|
70
|
+
await Promise.all(
|
|
71
|
+
companionFiles.map((fileName) =>
|
|
72
|
+
cp(join(sourceRoot, fileName), join(targetDirectory, fileName), {
|
|
73
|
+
errorOnExist: false,
|
|
74
|
+
force: true,
|
|
75
|
+
recursive: false
|
|
76
|
+
})
|
|
77
|
+
)
|
|
78
|
+
);
|
|
62
79
|
|
|
63
80
|
console.log(`Installed nextop-ui-system skill to ${targetDirectory}`);
|
|
64
81
|
console.log(
|
|
@@ -121,6 +138,15 @@ async function assertReadableDirectory(path) {
|
|
|
121
138
|
}
|
|
122
139
|
}
|
|
123
140
|
|
|
141
|
+
async function assertReadableFile(path) {
|
|
142
|
+
await access(path, constants.R_OK);
|
|
143
|
+
const pathStats = await stat(path);
|
|
144
|
+
|
|
145
|
+
if (!pathStats.isFile()) {
|
|
146
|
+
throw new Error(`Expected file: ${path}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
124
150
|
async function pathExists(path) {
|
|
125
151
|
try {
|
|
126
152
|
await access(path, constants.F_OK);
|
|
@@ -130,8 +156,24 @@ async function pathExists(path) {
|
|
|
130
156
|
}
|
|
131
157
|
}
|
|
132
158
|
|
|
133
|
-
async function
|
|
134
|
-
const
|
|
159
|
+
async function resolveSourceRoot(cwd) {
|
|
160
|
+
const devCacheRoot = resolve(cwd, devCacheDirectoryName);
|
|
161
|
+
const devCacheSkillDirectory = join(devCacheRoot, "agent", skillName);
|
|
162
|
+
|
|
163
|
+
if (
|
|
164
|
+
(await pathExists(devCacheSkillDirectory)) &&
|
|
165
|
+
(await pathExists(join(devCacheRoot, "AGENTS.md"))) &&
|
|
166
|
+
(await pathExists(join(devCacheRoot, "ui-system.md")))
|
|
167
|
+
) {
|
|
168
|
+
return devCacheRoot;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return packageRoot;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async function directoriesMatch(sourceRoot, sourceDirectory, rightDirectory) {
|
|
175
|
+
const sourceEntries = await listBundleFiles(sourceRoot, sourceDirectory);
|
|
176
|
+
const leftEntries = sourceEntries.map((entry) => entry.targetRelativePath);
|
|
135
177
|
const rightEntries = await listFiles(rightDirectory, rightDirectory);
|
|
136
178
|
|
|
137
179
|
if (leftEntries.length !== rightEntries.length) {
|
|
@@ -143,7 +185,7 @@ async function directoriesMatch(leftDirectory, rightDirectory) {
|
|
|
143
185
|
return false;
|
|
144
186
|
}
|
|
145
187
|
|
|
146
|
-
const leftFile =
|
|
188
|
+
const leftFile = sourceEntries[index].sourceAbsolutePath;
|
|
147
189
|
const rightFile = join(rightDirectory, rightEntries[index]);
|
|
148
190
|
|
|
149
191
|
const [leftContent, rightContent] = await Promise.all([
|
|
@@ -159,6 +201,24 @@ async function directoriesMatch(leftDirectory, rightDirectory) {
|
|
|
159
201
|
return true;
|
|
160
202
|
}
|
|
161
203
|
|
|
204
|
+
async function listBundleFiles(sourceRoot, sourceDirectory) {
|
|
205
|
+
const skillFiles = await listFiles(sourceDirectory, sourceDirectory);
|
|
206
|
+
const companionEntries = companionFiles.map((fileName) => ({
|
|
207
|
+
sourceAbsolutePath: join(sourceRoot, fileName),
|
|
208
|
+
targetRelativePath: fileName
|
|
209
|
+
}));
|
|
210
|
+
|
|
211
|
+
return skillFiles
|
|
212
|
+
.map((relativePath) => ({
|
|
213
|
+
sourceAbsolutePath: join(sourceDirectory, relativePath),
|
|
214
|
+
targetRelativePath: relativePath
|
|
215
|
+
}))
|
|
216
|
+
.concat(companionEntries)
|
|
217
|
+
.sort((left, right) =>
|
|
218
|
+
left.targetRelativePath.localeCompare(right.targetRelativePath)
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
162
222
|
async function listFiles(rootDirectory, directory) {
|
|
163
223
|
const entries = await readdir(directory, { withFileTypes: true });
|
|
164
224
|
const files = await Promise.all(
|
|
@@ -8,15 +8,39 @@ description: Use when working with @nextop-os/ui-system components, replacing lo
|
|
|
8
8
|
Use this skill as the single entrypoint for `@nextop-os/ui-system` component
|
|
9
9
|
reuse, extraction, promotion, metadata, and storyboard work.
|
|
10
10
|
|
|
11
|
+
## Non-Negotiable Standard
|
|
12
|
+
|
|
13
|
+
Any UI promoted into `@nextop-os/ui-system` must fully follow the UI-system
|
|
14
|
+
design standard before it can be reported as complete.
|
|
15
|
+
|
|
16
|
+
Treat these as hard requirements, not cleanup suggestions:
|
|
17
|
+
|
|
18
|
+
- use UI-system semantic tokens and existing shared CSS variables; do not leave
|
|
19
|
+
raw `hex`, `rgb(...)`, `rgba(...)`, ad hoc gradients, or app-local palette
|
|
20
|
+
values in promoted components or their storyboard examples unless the source
|
|
21
|
+
of truth already exposes them as approved tokens
|
|
22
|
+
- compose existing UI-system `base` primitives such as `Card`, `Button`,
|
|
23
|
+
`Tooltip`, `Dialog`, and related vocabulary before creating custom panel,
|
|
24
|
+
button, field, or overlay treatments
|
|
25
|
+
- make storyboard examples render the real component surface and states; do not
|
|
26
|
+
rely on surrounding docs chrome to hide component-level visual drift or to
|
|
27
|
+
fake the final panel/surface language
|
|
28
|
+
- when a consumer is migrated, its final rendered result must also follow the
|
|
29
|
+
same UI-system visual standard; a temporary bridge may help wiring, but it is
|
|
30
|
+
not acceptable as the final visual implementation if it keeps a second token
|
|
31
|
+
system or divergent component styling
|
|
32
|
+
|
|
33
|
+
If these conditions are not met, report the promotion as incomplete or blocked,
|
|
34
|
+
not complete.
|
|
35
|
+
|
|
11
36
|
## Source Of Truth
|
|
12
37
|
|
|
13
38
|
Read these before editing:
|
|
14
39
|
|
|
15
40
|
1. nearest `AGENTS.md` for the target code
|
|
16
|
-
2. `
|
|
17
|
-
3. `
|
|
18
|
-
4.
|
|
19
|
-
5. component metadata from the first available source:
|
|
41
|
+
2. local `AGENTS.md` bundled with this skill
|
|
42
|
+
3. local `ui-system.md` bundled with this skill
|
|
43
|
+
4. component metadata from the first available source:
|
|
20
44
|
- `GET http://127.0.0.1:4100/components`
|
|
21
45
|
- `packages/ui/system/src/metadata/components.json`
|
|
22
46
|
- `@nextop-os/ui-system/metadata` from the installed package
|
|
@@ -60,10 +84,90 @@ Keep these outside `@nextop-os/ui-system` components:
|
|
|
60
84
|
For any promoted public component, add stable exports, metadata, and storyboard
|
|
61
85
|
coverage that match the chosen reference workflow.
|
|
62
86
|
|
|
63
|
-
For
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
87
|
+
For promoted base components, storyboard coverage is not satisfied by metadata
|
|
88
|
+
alone. The promotion flow must also add or update a real renderable example in
|
|
89
|
+
`apps/ui-storyboard` so the component is visible in navigation and can be
|
|
90
|
+
visually reviewed in shared docs immediately after promotion.
|
|
91
|
+
|
|
92
|
+
For business component promotion, derive the promoted component directly from
|
|
93
|
+
the state matrix, proposed props boundary, and candidate source UI, then add
|
|
94
|
+
storyboard coverage for the accepted states in the same promotion pass. Treat
|
|
95
|
+
that evidence and boundary decision as the implementation blueprint for
|
|
96
|
+
`packages/ui/system`, and use review only to verify the finished implementation.
|
|
97
|
+
|
|
98
|
+
## Design Foundation Verification
|
|
99
|
+
|
|
100
|
+
Every promoted component must comply with
|
|
101
|
+
`ui-system.md`, especially the shared tokens,
|
|
102
|
+
theme variables, spacing, radius, typography, surface language, interactive
|
|
103
|
+
states, and existing `base` primitive vocabulary.
|
|
104
|
+
|
|
105
|
+
Explicitly check and report all of these before completion:
|
|
106
|
+
|
|
107
|
+
- color and surface styling come from UI-system semantic tokens rather than raw
|
|
108
|
+
palette values
|
|
109
|
+
- panels, rows, controls, and overlays compose existing base primitives where
|
|
110
|
+
applicable instead of recreating them locally
|
|
111
|
+
- storyboard shows the component's real promoted surface rather than only a
|
|
112
|
+
documentation wrapper
|
|
113
|
+
- migrated consumers no longer depend on a separate visual token system for the
|
|
114
|
+
promoted surface
|
|
115
|
+
|
|
116
|
+
Run the Nextop promotion review gate before reporting completion. The gate is
|
|
117
|
+
adapted from frontend design review practice but constrained to Nextop's dense
|
|
118
|
+
workbench product language:
|
|
119
|
+
|
|
120
|
+
- Frictionless: the migrated consumer preserves the original task path, keeps a
|
|
121
|
+
clear action hierarchy, and does not bury primary or recovery actions.
|
|
122
|
+
- Quality craft: visual parity evidence is captured for selected states, shared
|
|
123
|
+
tokens and primitives are used, light/dark and interactive states work, and no
|
|
124
|
+
unapproved raw palette, spacing, radius, typography, or motion drift remains.
|
|
125
|
+
- Trustworthy: empty, loading, disabled, error-like, permission-limited, and
|
|
126
|
+
AI-generated-content states keep clear labels, actionable recovery, and
|
|
127
|
+
host-owned policy or provenance outside the shared component.
|
|
128
|
+
|
|
129
|
+
After promoting a base or business component, start an independent subagent to
|
|
130
|
+
review design-foundation compliance before reporting completion. Provide the
|
|
131
|
+
subagent with the promoted files, source usage, selected states, storyboard and
|
|
132
|
+
metadata entries, and the UI-system guidelines. If subagents are unavailable,
|
|
133
|
+
state that design-foundation verification is blocked and do not claim full
|
|
134
|
+
compliance.
|
|
135
|
+
|
|
136
|
+
Report the gate result with:
|
|
137
|
+
|
|
138
|
+
- context: source usage, promoted component id/layer, user task, selected states
|
|
139
|
+
- status: pass, needs work, or blocked
|
|
140
|
+
- pillar assessment: Frictionless, Quality craft, Trustworthy
|
|
141
|
+
- issues grouped as blocking, major, and minor
|
|
142
|
+
- validation commands and exact results
|
|
143
|
+
- remaining risks, uncovered states, or approved visual deltas
|
|
144
|
+
|
|
145
|
+
## API Composition Review
|
|
146
|
+
|
|
147
|
+
When converting source states into public props, review the API shape before
|
|
148
|
+
writing the promoted component:
|
|
149
|
+
|
|
150
|
+
- avoid boolean prop proliferation for rendering modes; mode axes such as
|
|
151
|
+
`isFoo`, `showBar`, or `withBaz` must come from code evidence and usually
|
|
152
|
+
become a finite variant, discriminated union, explicit component variant,
|
|
153
|
+
slot, or composed child
|
|
154
|
+
- keep standard UI booleans such as `disabled`, `loading`, `selected`, `open`,
|
|
155
|
+
`required`, and `invalid` only when they represent real component state and
|
|
156
|
+
cannot create impossible combinations
|
|
157
|
+
- prefer `children` or named slots for caller-owned visual regions; use render
|
|
158
|
+
props only when the shared component must pass data back to the caller
|
|
159
|
+
- use compound components and context only for genuinely complex reusable
|
|
160
|
+
structures where consumers need to compose subparts without prop drilling
|
|
161
|
+
- if shared state is needed, define a narrow context value as `state`,
|
|
162
|
+
`actions`, and `meta`; providers may inject state but must not own daemon,
|
|
163
|
+
Electron, router, store, query, persistence, or workflow side effects
|
|
164
|
+
- for new React components in this React 19 codebase, prefer the React 19 API
|
|
165
|
+
shape such as `ref` as a prop; do not churn shadcn or Radix-acquired code only
|
|
166
|
+
to normalize style when behavior and public API are already sound
|
|
167
|
+
|
|
168
|
+
Report the API composition decision with the state matrix: which differences
|
|
169
|
+
became props, variants, slots, children, explicit variants, provider state, or
|
|
170
|
+
stayed host-owned.
|
|
67
171
|
|
|
68
172
|
## Validation Commands
|
|
69
173
|
|
|
@@ -77,3 +181,10 @@ pnpm --filter @nextop-os/ui-storyboard typecheck
|
|
|
77
181
|
|
|
78
182
|
If runtime component code changed, also run the relevant package typecheck or
|
|
79
183
|
consumer build.
|
|
184
|
+
|
|
185
|
+
When a base component is promoted, verify both of these conditions before
|
|
186
|
+
reporting completion:
|
|
187
|
+
|
|
188
|
+
- the component metadata opts into storyboard visibility when appropriate
|
|
189
|
+
- `apps/ui-storyboard` contains a concrete rendered example for the promoted
|
|
190
|
+
component states, not just inventory wiring
|
|
@@ -19,15 +19,45 @@ instead.
|
|
|
19
19
|
## Workflow
|
|
20
20
|
|
|
21
21
|
1. Check metadata and existing exports first.
|
|
22
|
-
2.
|
|
22
|
+
2. Read the bundled `ui-system.md` before implementation and
|
|
23
|
+
treat it as a hard gate for the extraction. The component must follow the
|
|
24
|
+
shared token, theme variable, spacing, radius, typography, surface,
|
|
25
|
+
interactive-state, accessibility, and reduced-motion rules from
|
|
26
|
+
`@nextop-os/ui-system`; do not preserve or introduce caller-local styling
|
|
27
|
+
when it conflicts with those guidelines.
|
|
28
|
+
3. If the primitive exists in the shadcn registry, acquire it through shadcn CLI
|
|
23
29
|
targeted at `packages/ui/system`.
|
|
24
|
-
|
|
30
|
+
4. Decide the primitive API before editing:
|
|
31
|
+
- use finite variants or discriminated unions for mutually exclusive visual
|
|
32
|
+
modes
|
|
33
|
+
- keep standard UI booleans such as `disabled`, `loading`, `selected`,
|
|
34
|
+
`open`, `required`, and `invalid` only when they represent real states
|
|
35
|
+
- prefer `children`, slots, refs, and class names for composition instead
|
|
36
|
+
of broad render props
|
|
37
|
+
- use compound components or context only when consumers need to assemble
|
|
38
|
+
reusable subparts that share primitive state
|
|
39
|
+
- follow the React 19 baseline for new hand-authored components, but do not
|
|
40
|
+
rewrite shadcn or Radix internals only for API-style churn
|
|
41
|
+
5. Adapt only package aliases, icon routing, tokens, stable exports, metadata,
|
|
25
42
|
storyboard examples, and boundary-check issues.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
43
|
+
6. Keep helper exports minimal and directly tied to primitive support.
|
|
44
|
+
7. Add metadata with `layer: "base"`.
|
|
45
|
+
8. Add storyboard coverage for the public states and variants exposed by the
|
|
29
46
|
primitive.
|
|
30
|
-
|
|
47
|
+
- This is mandatory for base-component promotion.
|
|
48
|
+
- Do not treat `storyboard: true` in metadata as sufficient by itself.
|
|
49
|
+
- Add or update a real renderable example in `apps/ui-storyboard` so the
|
|
50
|
+
component appears in navigation and can be visually reviewed immediately.
|
|
51
|
+
9. Replace duplicated local UI only after the shared primitive exists.
|
|
52
|
+
10. Run the promotion review gate from
|
|
53
|
+
`ui-system.md`: verify Frictionless task
|
|
54
|
+
preservation, Quality Craft visual/token/state parity, and Trustworthy
|
|
55
|
+
status/error/accessibility behavior for the migrated consumer.
|
|
56
|
+
11. Start an independent design-foundation review subagent after promotion. The
|
|
57
|
+
review must check the promoted files against
|
|
58
|
+
`ui-system.md`, existing tokens, primitives,
|
|
59
|
+
API shape, storyboard coverage, and metadata. Resolve any reported design
|
|
60
|
+
drift before completion.
|
|
31
61
|
|
|
32
62
|
## Validation
|
|
33
63
|
|
|
@@ -41,3 +71,17 @@ pnpm --filter @nextop-os/ui-system typecheck
|
|
|
41
71
|
```
|
|
42
72
|
|
|
43
73
|
If a consumer was migrated, also run that consumer's typecheck or build.
|
|
74
|
+
|
|
75
|
+
Before reporting completion, confirm storyboard delivery at two levels:
|
|
76
|
+
|
|
77
|
+
- inventory: the component is discoverable from storyboard navigation
|
|
78
|
+
- rendering: the component has a concrete example that renders its public
|
|
79
|
+
states or variants inside `apps/ui-storyboard`
|
|
80
|
+
|
|
81
|
+
Do not report full design-foundation compliance unless the subagent review ran
|
|
82
|
+
and found no unresolved drift. If subagents are unavailable, report the
|
|
83
|
+
verification as blocked.
|
|
84
|
+
|
|
85
|
+
Report the promotion review result with the component id, selected states,
|
|
86
|
+
Frictionless / Quality Craft / Trustworthy pillar status, blocking/major/minor
|
|
87
|
+
issues, validation commands, and remaining risks or approved visual deltas.
|
|
@@ -26,6 +26,11 @@ Keep storyboard grouped by:
|
|
|
26
26
|
|
|
27
27
|
Visible component stories should support copying the component id.
|
|
28
28
|
|
|
29
|
+
When a base component is newly promoted into `@nextop-os/ui-system`, updating
|
|
30
|
+
inventory alone is not enough. The same change must also add or refresh a real
|
|
31
|
+
renderable example in `apps/ui-storyboard` so the promoted component is
|
|
32
|
+
immediately reviewable from the shared storyboard.
|
|
33
|
+
|
|
29
34
|
When changing metadata or storyboard inventory, keep ids stable unless the
|
|
30
35
|
rename is intentional and callers or docs are updated together.
|
|
31
36
|
|