@imfusion/web-ui 0.8.1-dev.6.g254fcc45 → 0.8.1-dev.69.g7977f40a
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/CHANGELOG.md +259 -6
- package/README.md +29 -18
- package/THIRD_PARTY_NOTICES.md +34 -0
- package/dist/{code-D2lwxHgd.js → code-BYkr5k55.js} +13 -13
- package/dist/codegen/gen-icons.d.ts +29 -4
- package/dist/codegen/sharpen-icon.d.ts +11 -0
- package/dist/components/account-card/account-card.d.ts +9 -9
- package/dist/components/app-shell/app-shell.d.ts +59 -34
- package/dist/components/avatar/avatar.d.ts +1 -1
- package/dist/components/button/button.d.ts +14 -7
- package/dist/components/callout/callout.d.ts +4 -4
- package/dist/components/card/card.d.ts +21 -7
- package/dist/components/chip/chip.cva.d.ts +1 -1
- package/dist/components/chip/chip.d.ts +1 -1
- package/dist/components/chip-link/chip-link.d.ts +1 -1
- package/dist/components/code/code.d.ts +1 -1
- package/dist/components/field/field.d.ts +5 -2
- package/dist/components/icon/icon.d.ts +1 -1
- package/dist/components/icon-button/icon-button.d.ts +19 -0
- package/dist/components/icon-button/icon-button.meta.d.ts +2 -0
- package/dist/components/icon-button/index.d.ts +2 -0
- package/dist/components/kbd/aria-key-shortcuts.d.ts +5 -0
- package/dist/components/kbd/index.d.ts +2 -0
- package/dist/components/kbd/kbd.d.ts +14 -0
- package/dist/components/kbd/kbd.meta.d.ts +2 -0
- package/dist/components/logo/logo.d.ts +3 -3
- package/dist/components/meter/index.d.ts +2 -0
- package/dist/components/meter/meter.d.ts +33 -0
- package/dist/components/meter/meter.meta.d.ts +2 -0
- package/dist/components/navigation-menu/subs/link.d.ts +1 -1
- package/dist/components/popover/popover.d.ts +3 -3
- package/dist/components/prose/prose.d.ts +1 -1
- package/dist/components/row/row.d.ts +3 -3
- package/dist/components/skeleton/index.d.ts +2 -0
- package/dist/components/skeleton/skeleton.d.ts +47 -0
- package/dist/components/skeleton/skeleton.meta.d.ts +2 -0
- package/dist/components/slider/slider.d.ts +11 -1
- package/dist/components/spinner/spinner.d.ts +1 -1
- package/dist/components/stack/stack.d.ts +3 -3
- package/dist/components/table/table.d.ts +16 -7
- package/dist/components/tabs/tabs.d.ts +1 -1
- package/dist/components/toggle/toggle.d.ts +7 -1
- package/dist/components/tooltip/tooltip.d.ts +2 -2
- package/dist/components/typo/typo.d.ts +21 -12
- package/dist/icons/catalog.gen.d.ts +3804 -0
- package/dist/icons/create-icon.d.ts +3 -0
- package/dist/icons/icon-config-context.d.ts +3 -0
- package/dist/icons/icon-config.d.ts +2 -2
- package/dist/icons/icons.gen.d.ts +1737 -1672
- package/dist/icons-BsK_o-Cb.js +36358 -0
- package/dist/icons.js +2 -2
- package/dist/index.d.ts +5 -0
- package/dist/index.js +2080 -1607
- package/dist/integrations/code-highlight.js +6 -4
- package/dist/integrations/frame-selection/frame-selection-view.d.ts +24 -0
- package/dist/integrations/frame-selection/frame-selection.d.ts +21 -0
- package/dist/integrations/frame-selection/frame-selection.meta.d.ts +2 -0
- package/dist/integrations/frame-selection/index.d.ts +2 -0
- package/dist/integrations/frame-selection.js +121 -0
- package/dist/integrations/image-display-options/image-display-options-view.d.ts +1 -1
- package/dist/integrations/image-display-options/image-display-options.d.ts +1 -1
- package/dist/integrations/image-display-options.js +56 -55
- package/dist/llms/evals/runner/config.d.ts +1 -0
- package/dist/llms/gen-tokens.d.ts +1 -1
- package/dist/{paths-Oi0v8x-w.js → paths-B5Ht3ETc.js} +2 -2
- package/dist/separator-lzz4A3x_.js +26 -0
- package/dist/slider-Cqpreglu.js +116 -0
- package/dist/style.css +1 -1
- package/dist/tabs-DRyqtS04.js +358 -0
- package/dist/utils/email.d.ts +7 -0
- package/dist/utils/status-glyphs.d.ts +4 -0
- package/dist/vite.js +2 -2
- package/dist/web-ui-cli.js +1 -1
- package/docs/user-guide/AgentTooling.mdx +8 -3
- package/package.json +38 -38
- package/src/docgen/doc.gen.json +1377 -215
- package/src/llms/icon-catalog.gen.json +5541 -1671
- package/src/llms/llms.gen.txt +29 -2
- package/src/llms/skills/imf-web-ui/SKILL.md +3 -1
- package/src/llms/skills/imf-web-ui-audit/SKILL.md +18 -4
- package/src/llms/skills/imf-web-ui-components/SKILL.md +3 -1
- package/src/llms/skills/imf-web-ui-conventions/templates/AUDIT_CHECKLIST.md +3 -2
- package/src/llms/skills/imf-web-ui-conventions/topics/authentication.md +2 -1
- package/src/llms/skills/imf-web-ui-conventions/topics/data.md +5 -3
- package/src/llms/skills/imf-web-ui-conventions/topics/git.md +2 -3
- package/src/llms/skills/imf-web-ui-conventions/topics/npm-project.md +3 -4
- package/src/llms/skills/imf-web-ui-conventions/topics/styling.md +4 -2
- package/src/llms/skills/imf-web-ui-conventions/topics/tooling.md +83 -42
- package/src/llms/skills/imf-web-ui-setup/SKILL.md +2 -0
- package/src/llms/skills/imf-web-ui-update/SKILL.md +42 -7
- package/src/llms/skills/imf-web-ui-user-profile/SKILL.md +95 -0
- package/src/llms/skills/imf-web-ui-ux/SKILL.md +2 -0
- package/src/llms/tokens.gen.json +3 -3
- package/dist/icons-CaGCCwG-.js +0 -78
- package/dist/tabs-BS6rqrrA.js +0 -398
- /package/dist/{meta-j-7HGrWv.js → meta-V_KyLeGn.js} +0 -0
- /package/dist/{chunk-DmhlhrBa.js → rolldown-runtime-Dy4uBu1J.js} +0 -0
package/src/llms/llms.gen.txt
CHANGED
|
@@ -38,7 +38,7 @@ Persistent, in-place status message for information, success, warnings, and erro
|
|
|
38
38
|
|
|
39
39
|
## Card
|
|
40
40
|
- category: Layout, status: stable
|
|
41
|
-
Surface container for related content on a tonal background. Also called a panel or tile; compose it from optional image, header, content, and footer parts.
|
|
41
|
+
Surface container for related content on a tonal background. Also called a panel or tile; compose it from optional image, status, header, content, and footer parts.
|
|
42
42
|
- props: node_modules/@imfusion/web-ui/src/docgen/doc.gen.json -> .card (jq: jq '.card' node_modules/@imfusion/web-ui/src/docgen/doc.gen.json)
|
|
43
43
|
|
|
44
44
|
## Checkbox
|
|
@@ -96,11 +96,22 @@ Semantic group for related form controls with a shared legend. Also called a for
|
|
|
96
96
|
- props: node_modules/@imfusion/web-ui/src/docgen/doc.gen.json -> .fieldset (jq: jq '.fieldset' node_modules/@imfusion/web-ui/src/docgen/doc.gen.json)
|
|
97
97
|
- further reading (usage/anatomy, not props): https://base-ui.com/react/components/fieldset.md
|
|
98
98
|
|
|
99
|
+
## FrameSelection
|
|
100
|
+
- category: Inputs, status: experimental
|
|
101
|
+
Frame or slice picker bound to the focused frame of ImFusion image sets, with a focus and count readout. For a position picker not tied to the SDK, use Slider with variant="position".
|
|
102
|
+
- props: node_modules/@imfusion/web-ui/src/docgen/doc.gen.json -> .frame-selection (jq: jq '.frame-selection' node_modules/@imfusion/web-ui/src/docgen/doc.gen.json)
|
|
103
|
+
- further reading (usage/anatomy, not props): https://docs.imfusion.com/
|
|
104
|
+
|
|
99
105
|
## Icon
|
|
100
106
|
- category: Display, status: stable
|
|
101
107
|
Renders a Web UI icon with an optional semantic foreground color. The default inherits the surrounding currentColor.
|
|
102
108
|
- props: node_modules/@imfusion/web-ui/src/docgen/doc.gen.json -> .icon (jq: jq '.icon' node_modules/@imfusion/web-ui/src/docgen/doc.gen.json)
|
|
103
109
|
|
|
110
|
+
## IconButton
|
|
111
|
+
- category: Buttons, status: experimental
|
|
112
|
+
Square button that shows a single icon and no visible text, with its accessible name from `label`. Also called an icon-only or toolbar button. Use Button with `startIcon` or `endIcon` when a text label is visible.
|
|
113
|
+
- props: node_modules/@imfusion/web-ui/src/docgen/doc.gen.json -> .icon-button (jq: jq '.icon-button' node_modules/@imfusion/web-ui/src/docgen/doc.gen.json)
|
|
114
|
+
|
|
104
115
|
## ImageDisplayOptions
|
|
105
116
|
- category: Inputs, status: experimental
|
|
106
117
|
Panel and toolbar controls for an image dataset's display options, including window, level, gamma, and invert settings.
|
|
@@ -113,11 +124,22 @@ Single-line text input for form data entry. Also called a text field; it support
|
|
|
113
124
|
- props: node_modules/@imfusion/web-ui/src/docgen/doc.gen.json -> .input (jq: jq '.input' node_modules/@imfusion/web-ui/src/docgen/doc.gen.json)
|
|
114
125
|
- further reading (usage/anatomy, not props): https://base-ui.com/react/components/input.md
|
|
115
126
|
|
|
127
|
+
## Kbd
|
|
128
|
+
- category: Display, status: experimental
|
|
129
|
+
Shows a keyboard key or shortcut, such as the letter that activates a button. Also called a key hint; Button and Toggle render it through their `shortcut` prop.
|
|
130
|
+
- props: node_modules/@imfusion/web-ui/src/docgen/doc.gen.json -> .kbd (jq: jq '.kbd' node_modules/@imfusion/web-ui/src/docgen/doc.gen.json)
|
|
131
|
+
|
|
116
132
|
## Logo
|
|
117
133
|
- category: Display, status: stable
|
|
118
134
|
Renders a logo from a URL or inline React element with consistent sizing. Also called a wordmark or brand mark.
|
|
119
135
|
- props: node_modules/@imfusion/web-ui/src/docgen/doc.gen.json -> .logo (jq: jq '.logo' node_modules/@imfusion/web-ui/src/docgen/doc.gen.json)
|
|
120
136
|
|
|
137
|
+
## Meter
|
|
138
|
+
- category: Display, status: experimental
|
|
139
|
+
Read-only bar for a measured amount within a known range, such as seats in use or storage used. Also called a gauge or usage bar. Use Slider when the user sets the value.
|
|
140
|
+
- props: node_modules/@imfusion/web-ui/src/docgen/doc.gen.json -> .meter (jq: jq '.meter' node_modules/@imfusion/web-ui/src/docgen/doc.gen.json)
|
|
141
|
+
- further reading (usage/anatomy, not props): https://base-ui.com/react/components/meter.md
|
|
142
|
+
|
|
121
143
|
## NavigationMenu
|
|
122
144
|
- category: Display, status: experimental
|
|
123
145
|
Navigation menu with horizontal or vertical triggers and anchored flyout panels. Also called a menu bar or mega menu; it supports links, rich cards, and nested navigation.
|
|
@@ -158,9 +180,14 @@ Line that divides content horizontally or vertically. Also called a divider or r
|
|
|
158
180
|
- props: node_modules/@imfusion/web-ui/src/docgen/doc.gen.json -> .separator (jq: jq '.separator' node_modules/@imfusion/web-ui/src/docgen/doc.gen.json)
|
|
159
181
|
- further reading (usage/anatomy, not props): https://base-ui.com/react/components/separator.md
|
|
160
182
|
|
|
183
|
+
## Skeleton
|
|
184
|
+
- category: Display, status: experimental
|
|
185
|
+
Loading placeholder that stands in for data at the size it will take, so nothing shifts when it lands. Also called a skeleton loader or ghost. Use Spinner when the layout is unknown.
|
|
186
|
+
- props: node_modules/@imfusion/web-ui/src/docgen/doc.gen.json -> .skeleton (jq: jq '.skeleton' node_modules/@imfusion/web-ui/src/docgen/doc.gen.json)
|
|
187
|
+
|
|
161
188
|
## Slider
|
|
162
189
|
- category: Inputs, status: stable
|
|
163
|
-
Numeric input for choosing one value or a range by dragging a thumb. Also called a range input; use it when relative magnitude matters.
|
|
190
|
+
Numeric input for choosing one value or a range by dragging a thumb. Also called a range input; use it when relative magnitude matters. The position variant is a scrubber for picking one slice or frame.
|
|
164
191
|
- props: node_modules/@imfusion/web-ui/src/docgen/doc.gen.json -> .slider (jq: jq '.slider' node_modules/@imfusion/web-ui/src/docgen/doc.gen.json)
|
|
165
192
|
- further reading (usage/anatomy, not props): https://base-ui.com/react/components/slider.md
|
|
166
193
|
|
|
@@ -11,6 +11,8 @@ description:
|
|
|
11
11
|
Start here for UI work and library questions in a project that uses `@imfusion/web-ui`. This skill is a map, not a second
|
|
12
12
|
copy of every convention.
|
|
13
13
|
|
|
14
|
+
Invoke `imf-web-ui-user-profile` first and explain at its levels throughout.
|
|
15
|
+
|
|
14
16
|
## 1. Decide whether guidance is needed
|
|
15
17
|
|
|
16
18
|
Skip a companion when the task is explicit and small, an existing local pattern already solves it in the file being changed,
|
|
@@ -60,7 +62,7 @@ props and the conventions `tokens` topic for exact token names and defaults.
|
|
|
60
62
|
The host project's existing conventions win. The companion skills fill gaps; they do not justify refactoring a working
|
|
61
63
|
styling system, state library, or folder structure.
|
|
62
64
|
|
|
63
|
-
When a task needs TanStack Router, Query, Form, Table, or
|
|
65
|
+
When a task needs TanStack Router, Query, Form, Table, Store, or Hotkeys and the project has no incumbent, open
|
|
64
66
|
`imf-web-ui-conventions` for the house position on that layer, then read the library's current documentation with
|
|
65
67
|
`npx @tanstack/cli` before using it. The recommendation lives in the conventions topics, not here.
|
|
66
68
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: imf-web-ui-audit
|
|
3
3
|
description:
|
|
4
|
-
"Audit an existing ImFusion frontend against the @imfusion/web-ui conventions without changing files. Use this for
|
|
5
|
-
project health check, a pre-setup review, or one named topic. Report broken and missing pieces, working deviations,
|
|
4
|
+
"Audit an existing ImFusion frontend against the @imfusion/web-ui conventions without changing project files. Use this for
|
|
5
|
+
a project health check, a pre-setup review, or one named topic. Report broken and missing pieces, working deviations,
|
|
6
6
|
evidence, and an ordered plan."
|
|
7
7
|
argument-hint: "[full|<topic>]"
|
|
8
|
-
allowed-tools: Read Glob Grep
|
|
8
|
+
allowed-tools: Read Glob Grep Skill
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# Audit a consumer project
|
|
@@ -21,6 +21,8 @@ it low, and do not let it crowd the sections a consumer has to act on.
|
|
|
21
21
|
|
|
22
22
|
## Workflow
|
|
23
23
|
|
|
24
|
+
Invoke `imf-web-ui-user-profile` first and explain at its levels throughout.
|
|
25
|
+
|
|
24
26
|
1. Resolve the argument. Bare means `full`; an unknown topic is an error, not a reason to widen the scope.
|
|
25
27
|
2. Enter plan mode unless this audit is being called as verification by another skill or the host has no plan mode.
|
|
26
28
|
3. Read the report template and existing reviewer notes, then dispatch one investigator per in-scope topic. Tell each
|
|
@@ -28,7 +30,8 @@ it low, and do not let it crowd the sections a consumer has to act on.
|
|
|
28
30
|
section in that topic and writes nothing. Once dispatch starts, the host performs no repository inspection: the returned
|
|
29
31
|
reports are the evidence, and the host merges them without reading or searching the files again. Gathering the evidence
|
|
30
32
|
twice spends context on the second pass and reports what the host still remembers. Inspect a topic inline only after its
|
|
31
|
-
dispatch has been tried and refused, and say which attempt failed.
|
|
33
|
+
dispatch has been tried and refused, and say which attempt failed. A `full` audit also dispatches one marker investigator;
|
|
34
|
+
a named-topic audit gives that search to the topic's investigator. See [Deferred-work markers](#deferred-work-markers).
|
|
32
35
|
4. Merge the evidence into the shared report format in
|
|
33
36
|
[`templates/REPORT.md`](../imf-web-ui-conventions/templates/REPORT.md). Before presenting or writing it, check that every
|
|
34
37
|
Broken, Missing, Deviation, and Unverified entry has a severity, evidence, impact, and next action; do not compact
|
|
@@ -66,6 +69,17 @@ Read the corresponding topic and the matching block in
|
|
|
66
69
|
[`templates/AUDIT_CHECKLIST.md`](../imf-web-ui-conventions/templates/AUDIT_CHECKLIST.md). The audit is incomplete until every
|
|
67
70
|
in-scope box has evidence.
|
|
68
71
|
|
|
72
|
+
## Deferred-work markers
|
|
73
|
+
|
|
74
|
+
Comments that mark unfinished work are evidence the code itself admits. Search the frontend sources, styles, stories, tests,
|
|
75
|
+
and frontend config for `TODO`, `FIXME`, `HACK`, `XXX`, and phrases like "temporary", "workaround", "for now", or "remove
|
|
76
|
+
once". Skip `node_modules`, build output, generated files, and vendored code. A named-topic audit keeps only the markers that
|
|
77
|
+
bear on that topic.
|
|
78
|
+
|
|
79
|
+
Read each marker with its surrounding code. One that admits a convention gap, such as a hand-rolled control waiting for a Web
|
|
80
|
+
UI component or a hard-coded color waiting for a token, is evidence for that topic's finding. Every other marker goes under
|
|
81
|
+
`Suggestions` with its `path:line` and what it defers; group repeats of one cause into a single entry.
|
|
82
|
+
|
|
69
83
|
## Agent tooling checks
|
|
70
84
|
|
|
71
85
|
For `agent-tooling`, compare the declared version in `package.json`, the installed
|
|
@@ -4,13 +4,15 @@ description:
|
|
|
4
4
|
"Look up @imfusion/web-ui component APIs, compound parts, defaults, and icon glyphs without reading source. Use this
|
|
5
5
|
whenever a consumer task names a Web UI component or icon and you need to choose a prop, part, default, or glyph. Do not
|
|
6
6
|
use it to choose between components or bootstrap a project."
|
|
7
|
-
allowed-tools: Bash
|
|
7
|
+
allowed-tools: Bash Skill
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# Look up components
|
|
11
11
|
|
|
12
12
|
Use the generated package indexes. They are smaller and more reliable than reading the library source.
|
|
13
13
|
|
|
14
|
+
Invoke `imf-web-ui-user-profile` first and explain at its levels throughout.
|
|
15
|
+
|
|
14
16
|
## Component lookup
|
|
15
17
|
|
|
16
18
|
1. Read the identity index first, even when you already know the component's name: it gives the docgen key and the status.
|
|
@@ -103,8 +103,9 @@ sections one to one — change a topic's sections and this file follows in the s
|
|
|
103
103
|
- [ ] When a library owns a layer
|
|
104
104
|
- [ ] Devtools
|
|
105
105
|
- [ ] Docs over memory
|
|
106
|
-
- [ ]
|
|
107
|
-
- [ ]
|
|
106
|
+
- [ ] Vite+
|
|
107
|
+
- [ ] Oxfmt
|
|
108
|
+
- [ ] Oxlint and TypeScript
|
|
108
109
|
- [ ] Pre-commit checks
|
|
109
110
|
- [ ] Vite plugins
|
|
110
111
|
|
|
@@ -19,7 +19,8 @@ Use one server-backed current-user query as the identity source:
|
|
|
19
19
|
|
|
20
20
|
- Put it in `api/auth/queries.ts` and define its key and schema with the [data.md](data.md) pattern.
|
|
21
21
|
- Expose query options as `context.api.auth.getUser()`.
|
|
22
|
-
- Call `
|
|
22
|
+
- Call `queryClient.query({ ...options, staleTime: "static" })` in a loader (see [data.md](data.md)) or a query hook in a
|
|
23
|
+
component.
|
|
23
24
|
- Keep credentials and access tokens out of React state.
|
|
24
25
|
- Do not infer authentication from local storage, decoded tokens, route flags, or permission-gated UI.
|
|
25
26
|
|
|
@@ -85,9 +85,11 @@ export function getDetails(options?: QueryOptions<User>) {
|
|
|
85
85
|
}
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
Callers choose `
|
|
89
|
-
`
|
|
90
|
-
|
|
88
|
+
Callers choose `queryClient.query`, `useSuspenseQuery`, or another Query API. A router loader reads the cache with
|
|
89
|
+
`queryClient.query({ ...options, staleTime: "static" })`, not the deprecated `ensureQueryData` or `fetchQuery`. Keep
|
|
90
|
+
`"static"`: without it the factory's `staleTime` applies (default 0), so every loader run waits on the network and the page's
|
|
91
|
+
`useQuery` refetches on mount. Mutation factories likewise return `mutationOptions`, own their mutation key and parsing, and
|
|
92
|
+
are passed to `useMutation`; do not inline those options at the call site.
|
|
91
93
|
|
|
92
94
|
## Router context access
|
|
93
95
|
|
|
@@ -18,11 +18,10 @@ The hooks are tracked in `.githooks/`. Check both the Git setting and the direct
|
|
|
18
18
|
|
|
19
19
|
There are two scopes:
|
|
20
20
|
|
|
21
|
-
- **commit**:
|
|
22
|
-
for staged inputs.
|
|
21
|
+
- **commit**: the pre-commit hook, which runs `vp staged` as `tooling.md` describes under Pre-commit checks.
|
|
23
22
|
- **full**: `verify:full`, the build and complete verification used by CI.
|
|
24
23
|
|
|
25
|
-
The scripts under `scripts/verify/` own the step lists. Hooks and npm scripts only launch them.
|
|
24
|
+
The `staged` block and the scripts under `scripts/verify/` own the step lists. Hooks and npm scripts only launch them.
|
|
26
25
|
|
|
27
26
|
## Staleness at commit time
|
|
28
27
|
|
|
@@ -17,12 +17,11 @@ Use the same names for the same checks where the project supports them:
|
|
|
17
17
|
| ------------------ | --------------------------------------- |
|
|
18
18
|
| `dev` | Start local development. |
|
|
19
19
|
| `build` | Create a production build. |
|
|
20
|
-
| `verify:format` |
|
|
21
|
-
| `verify:lint` |
|
|
20
|
+
| `verify:format` | Run `vp fmt --check`. |
|
|
21
|
+
| `verify:lint` | Run `vp lint`. |
|
|
22
22
|
| `verify:typecheck` | Run TypeScript without emitting. |
|
|
23
|
-
| `verify:tests` | Run
|
|
23
|
+
| `verify:tests` | Run `vp test run`. |
|
|
24
24
|
| `verify:knip` | Check dead code and unused exports. |
|
|
25
|
-
| `verify:staged` | Run the pre-commit scope. |
|
|
26
25
|
| `verify:full` | Run the CI scope. |
|
|
27
26
|
| `format` | Rewrite formatting. |
|
|
28
27
|
| `lint` | Rewrite fixable lint issues. |
|
|
@@ -7,6 +7,8 @@ Use native CSS and Web UI's public seams. The library's CSS Modules and token na
|
|
|
7
7
|
- Use CSS Modules with native nesting. Do not add Sass, CSS-in-JS, or a utility-class framework for ordinary component
|
|
8
8
|
styles.
|
|
9
9
|
- Nest states, pseudo-elements, and child selectors under the root.
|
|
10
|
+
- Write declarations before nested rules; browsers before Chrome 130, Firefox 132, and Safari 18 move later ones above them.
|
|
11
|
+
- Do not nest under a selector list whose selectors differ in specificity. The nested rule takes the highest one.
|
|
10
12
|
- Lift repeated values into custom properties, especially when a state or variant changes several descendants.
|
|
11
13
|
- Keep structurally different rules explicit; not every repeated value needs an abstraction.
|
|
12
14
|
|
|
@@ -85,8 +87,8 @@ Foreground roles are for text, icons, borders, and focus rings. Background roles
|
|
|
85
87
|
|
|
86
88
|
## Browser floor
|
|
87
89
|
|
|
88
|
-
The library targets Safari
|
|
89
|
-
guarded fallback for older Safari:
|
|
90
|
+
The library targets Safari 17.5, Chrome 123, and Firefox 120 or newer, the first versions with native `light-dark()`.
|
|
91
|
+
`color-mix(in oklch, …)` is available at that floor. Relative color syntax needs a guarded fallback for older Safari:
|
|
90
92
|
|
|
91
93
|
```css
|
|
92
94
|
.subtle {
|
|
@@ -4,27 +4,28 @@ Use the tool's current documentation rather than memory.
|
|
|
4
4
|
|
|
5
5
|
## Topic-to-tool map
|
|
6
6
|
|
|
7
|
-
| Need | Default |
|
|
8
|
-
| --------------------- |
|
|
9
|
-
|
|
|
10
|
-
| Routing and URL state | TanStack Router
|
|
11
|
-
| Server state | TanStack Query
|
|
12
|
-
| Forms | TanStack Form
|
|
13
|
-
| Data grids | TanStack Table plus Web UI `Table` parts
|
|
14
|
-
| App-wide client state | TanStack Store, after URL/server/local state |
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
7
|
+
| Need | Default | Docs |
|
|
8
|
+
| --------------------- | -------------------------------------------------------------- | ----------------------------------------- |
|
|
9
|
+
| Toolchain | Vite+ (`vite-plus`), driven through `vp` | https://viteplus.dev/guide |
|
|
10
|
+
| Routing and URL state | TanStack Router | `npx @tanstack/cli`, library `router` |
|
|
11
|
+
| Server state | TanStack Query | `npx @tanstack/cli`, library `query` |
|
|
12
|
+
| Forms | TanStack Form | `npx @tanstack/cli`, library `form` |
|
|
13
|
+
| Data grids | TanStack Table plus Web UI `Table` parts | `npx @tanstack/cli`, library `table` |
|
|
14
|
+
| App-wide client state | TanStack Store, after URL/server/local state | `npx @tanstack/cli`, library `store` |
|
|
15
|
+
| Keyboard shortcuts | TanStack Hotkeys; show the key with Web UI `shortcut` or `Kbd` | `npx @tanstack/cli`, library `hotkeys` |
|
|
16
|
+
| Schema validation | Zod at the boundary | https://zod.dev |
|
|
17
|
+
| Tests | Vitest through `vp test` | https://vitest.dev |
|
|
18
|
+
| Format | Oxfmt through `vp fmt` | https://oxc.rs/docs/guide/usage/formatter |
|
|
19
|
+
| Lint | Oxlint through `vp lint`, type-aware | https://oxc.rs/docs/guide/usage/linter |
|
|
20
|
+
| Types | `tsc --noEmit` | https://www.typescriptlang.org/docs |
|
|
21
|
+
| Pre-commit checks | `vp staged` against the staged state | https://viteplus.dev/guide |
|
|
22
|
+
| Dead code | Knip via `verify:knip` | https://knip.dev |
|
|
22
23
|
|
|
23
24
|
## When a library owns a layer
|
|
24
25
|
|
|
25
26
|
Use the library that already owns the problem. Adopt Form for form rules, Query for caching and refetching, Router for URL
|
|
26
|
-
state,
|
|
27
|
-
works.
|
|
27
|
+
state, Table for sorting and pagination, and Hotkeys for keyboard shortcuts instead of rebuilding those layers. Web UI only
|
|
28
|
+
shows a key; the app binds it. Keep an existing project choice when it works.
|
|
28
29
|
|
|
29
30
|
## Devtools
|
|
30
31
|
|
|
@@ -33,50 +34,90 @@ devtools package whenever a new TanStack dependency is added.
|
|
|
33
34
|
|
|
34
35
|
## Docs over memory
|
|
35
36
|
|
|
36
|
-
Use `npx @tanstack/cli` for TanStack documentation
|
|
37
|
-
|
|
37
|
+
Use `npx @tanstack/cli` for TanStack documentation, with the library id from the map: `search-docs "<query>" --library <id>`
|
|
38
|
+
finds a page, and `doc <id> <path>` prints it, for example
|
|
39
|
+
`npx @tanstack/cli doc hotkeys framework/react/reference/functions/useHotkey`. If TanStack Intent is configured, use it for
|
|
40
|
+
the Agent Skills the TanStack package provides.
|
|
38
41
|
|
|
39
|
-
##
|
|
42
|
+
## Vite+
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
Vite+ runs development, build, tests, format, lint, and staged checks through one `vp` binary configured in `vite.config.ts`.
|
|
45
|
+
Pin `vite-plus` exactly, alias `vite` to `npm:@voidzero-dev/vite-plus-core@<vite-plus version>`, pin `vitest` to the version
|
|
46
|
+
`vp toolchain vitest` reports, and repeat both pins under `overrides`. Import `defineConfig` from `vite-plus` and Vitest APIs
|
|
47
|
+
from `vite-plus/test`. It needs Node `^22.22.1 || ^24.11 || >=26` and Git 2.32 or later.
|
|
48
|
+
|
|
49
|
+
`vp <command>` is a built-in; `vp run <script>` runs a package script.
|
|
50
|
+
|
|
51
|
+
Move an existing Vite, Vitest, ESLint, or Prettier project with `vp migrate --no-hooks` (`vp help migrate` lists its
|
|
52
|
+
options), then check the result against this topic. The hook lives in `.githooks/`, as `git.md` describes.
|
|
53
|
+
|
|
54
|
+
## Oxfmt
|
|
55
|
+
|
|
56
|
+
Configure formatting in the `fmt` block of `vite.config.ts`. The repo's values:
|
|
42
57
|
|
|
43
58
|
```ts
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export default config;
|
|
59
|
+
export default defineConfig({
|
|
60
|
+
fmt: {
|
|
61
|
+
printWidth: 125,
|
|
62
|
+
tabWidth: 2,
|
|
63
|
+
useTabs: false,
|
|
64
|
+
trailingComma: "none",
|
|
65
|
+
arrowParens: "avoid",
|
|
66
|
+
semi: true,
|
|
67
|
+
singleQuote: false,
|
|
68
|
+
proseWrap: "always",
|
|
69
|
+
sortPackageJson: false
|
|
70
|
+
}
|
|
71
|
+
});
|
|
58
72
|
```
|
|
59
73
|
|
|
60
|
-
##
|
|
74
|
+
## Oxlint and TypeScript
|
|
61
75
|
|
|
62
|
-
|
|
63
|
-
|
|
76
|
+
Configure linting in the `lint` block with type-aware rules on. The baseline bans `as` and non-null `!` outside tests and
|
|
77
|
+
requires the `#/` alias instead of parent-relative imports:
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
export default defineConfig({
|
|
81
|
+
lint: {
|
|
82
|
+
options: { typeAware: true },
|
|
83
|
+
overrides: [
|
|
84
|
+
{
|
|
85
|
+
files: ["src/**/*.{ts,tsx}"],
|
|
86
|
+
rules: {
|
|
87
|
+
"typescript/consistent-type-assertions": ["error", { assertionStyle: "never" }],
|
|
88
|
+
"typescript/no-non-null-assertion": "error",
|
|
89
|
+
"no-restricted-imports": [
|
|
90
|
+
"error",
|
|
91
|
+
{ patterns: [{ group: ["../*"], message: "Use the #/ alias for anything outside the current folder." }] }
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
files: ["**/*.test.{ts,tsx}"],
|
|
97
|
+
rules: { "typescript/consistent-type-assertions": "off", "typescript/no-non-null-assertion": "off" }
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
```
|
|
64
103
|
|
|
65
104
|
Use strict TypeScript with bundler module resolution, `verbatimModuleSyntax`, unused-value checks, and `#/` paths. Keep
|
|
66
105
|
`import type` for type-only imports.
|
|
67
106
|
|
|
68
107
|
## Pre-commit checks
|
|
69
108
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
109
|
+
`.githooks/pre-commit` runs `vp staged --hide-unstaged --fail-on-changes --revert --diff-filter=ACMRD` with `set -e`. Those
|
|
110
|
+
flags make the checks see only the staged state, include deletion-only commits, fail the commit when a check would change a
|
|
111
|
+
file, and restore the tree afterwards, so the hook never rewrites or stages files. The `staged` block in `vite.config.ts` is
|
|
112
|
+
a function returning path-free commands such as `npm run --silent verify:lint`, so each project-wide check runs once. Use
|
|
113
|
+
`npm run format` to apply formatting explicitly.
|
|
73
114
|
|
|
74
115
|
## Vite plugins
|
|
75
116
|
|
|
76
117
|
Register Web UI's Vite plugins in the application configuration:
|
|
77
118
|
|
|
78
119
|
```ts
|
|
79
|
-
import { defineConfig } from "vite";
|
|
120
|
+
import { defineConfig } from "vite-plus";
|
|
80
121
|
import react from "@vitejs/plugin-react";
|
|
81
122
|
import { imfusionBrandAssets, readableCssModuleNames } from "@imfusion/web-ui/vite";
|
|
82
123
|
|
|
@@ -15,6 +15,8 @@ working choices.
|
|
|
15
15
|
|
|
16
16
|
## Workflow
|
|
17
17
|
|
|
18
|
+
Invoke `imf-web-ui-user-profile` first and explain at its levels throughout.
|
|
19
|
+
|
|
18
20
|
1. Resolve the scope. A named topic limits the assessment to that topic. A bare invocation means `full`, unless the request
|
|
19
21
|
is about one topic, in which case that topic is the scope: answer what was asked and offer the wider sweep rather than
|
|
20
22
|
running it. If the argument is unknown, list the supported topics and point to `imf-web-ui-audit`.
|
|
@@ -5,7 +5,7 @@ description:
|
|
|
5
5
|
lifecycle hooks. Refresh the base first, verify it, then audit any consumer migration separately. Preserve user work and
|
|
6
6
|
get approval before each commit."
|
|
7
7
|
argument-hint: "[--dry-run] [optional version or reason]"
|
|
8
|
-
allowed-tools: Bash Read Grep
|
|
8
|
+
allowed-tools: Bash Read Grep Skill
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# Update Web UI
|
|
@@ -13,6 +13,22 @@ allowed-tools: Bash Read Grep
|
|
|
13
13
|
This workflow has two possible commits: the package/tooling update, then an optional consumer migration. Keep them separate.
|
|
14
14
|
Never overwrite user changes or commit without fresh approval.
|
|
15
15
|
|
|
16
|
+
## Before you start
|
|
17
|
+
|
|
18
|
+
Invoke `imf-web-ui-user-profile` first and explain at its levels throughout.
|
|
19
|
+
|
|
20
|
+
Open with a short orientation, before any command runs, so the person knows the route and when they will be asked:
|
|
21
|
+
|
|
22
|
+
1. **Preflight**: check the project and stop on uncommitted work.
|
|
23
|
+
2. **Base update**: install the new package, refresh the skills and hooks, verify, then ask to commit.
|
|
24
|
+
3. **Migration check**: read what the new releases changed and report what this project needs; changes and their separate
|
|
25
|
+
commit wait for approval.
|
|
26
|
+
4. **Full audit**: offer `imf-web-ui-audit full`, a read-only check of the whole project against the conventions, wider than
|
|
27
|
+
what this release changed.
|
|
28
|
+
|
|
29
|
+
Name the decision points up front: `latest` or `dev` when the installed version is a prerelease, the base commit, the
|
|
30
|
+
migration commit, and the audit offer. With `--dry-run`, say the run stops after preflight and changes nothing.
|
|
31
|
+
|
|
16
32
|
## Preflight
|
|
17
33
|
|
|
18
34
|
1. Work from the frontend package root. In a monorepo, find the package that owns the Web UI dependency.
|
|
@@ -20,9 +36,22 @@ Never overwrite user changes or commit without fresh approval.
|
|
|
20
36
|
if another lockfile is the active one.
|
|
21
37
|
3. Record `git status --short`, the installed Web UI version, the installed skill harness(es), hooks, registrations, and
|
|
22
38
|
`AGENTS.md` fence.
|
|
23
|
-
4. Check for another npm process and stop on a conflict
|
|
24
|
-
|
|
25
|
-
|
|
39
|
+
4. Check for another npm process in this package and stop on a conflict:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
pgrep npm # process IDs only
|
|
43
|
+
lsof -a -d cwd -p <pid> -Fn # the folder a process runs in
|
|
44
|
+
ps -o args= -p <pid> # its command, only when that folder is this package
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
A running install, update, or `ci` in this package is a conflict; a long-running `npm exec` server is not. Full process
|
|
48
|
+
listings such as `pgrep -fl` or `ps aux` print every program's arguments, secrets included, so keep them out of the
|
|
49
|
+
transcript.
|
|
50
|
+
|
|
51
|
+
Uncommitted work is also a conflict: report it and stop before the first mutating command, even if it looks unrelated to
|
|
52
|
+
this workflow: what the update touches is only known once it runs, and the person can commit, stash, or wave it through in
|
|
53
|
+
one reply. Never reset, clean, restore, or hide it.
|
|
54
|
+
|
|
26
55
|
5. With `--dry-run`, stop after reporting what would happen. Do not install, format, stage, commit, or ask for commit
|
|
27
56
|
approval.
|
|
28
57
|
|
|
@@ -87,12 +116,13 @@ Update files : <paths>
|
|
|
87
116
|
Held back : <paths or none>
|
|
88
117
|
Conflicts : <paths or none>
|
|
89
118
|
Commit : <message or not proposed>
|
|
119
|
+
Next : migration check, then the optional full audit
|
|
90
120
|
```
|
|
91
121
|
|
|
92
122
|
Ask: **Approve these update-owned changes and commit them?** Stage only approved update paths and follow the repository's
|
|
93
123
|
commit workflow.
|
|
94
124
|
|
|
95
|
-
##
|
|
125
|
+
## Check the consumer migration
|
|
96
126
|
|
|
97
127
|
Start this phase only after the base update commit exists. Read `node_modules/@imfusion/web-ui/CHANGELOG.md`: every release
|
|
98
128
|
section after the pre-update version, up to and including the new one. Each section's highlights, migration guide, and
|
|
@@ -114,12 +144,17 @@ releases read, then report separately:
|
|
|
114
144
|
- existing uses affected by a changed API or documented behavior;
|
|
115
145
|
- suggestions: new features from the highlights and `Added` entries that fit what the project already builds, each with the
|
|
116
146
|
project code it would serve; a suggestion stays a proposal until the person asks for it;
|
|
117
|
-
- custom components that overlap with a current Web UI primitive, with evidence and any behavior to preserve
|
|
147
|
+
- custom components that overlap with a current Web UI primitive, with evidence and any behavior to preserve;
|
|
148
|
+
- icons: project-local icons (inline SVGs, icon components, a third-party icon set) that a catalog icon now covers, above all
|
|
149
|
+
the ImFusion icons (`"origin": "imfusion"`). Search `node_modules/@imfusion/web-ui/src/llms/icon-catalog.gen.json` by
|
|
150
|
+
meaning, compare the drawing, and report each with the replacement export; a replacement stays a proposal until the person
|
|
151
|
+
asks for it.
|
|
118
152
|
|
|
119
153
|
Do not infer a replacement from a name. Inspect the implementation, styles, and call sites. If there are no findings, say so
|
|
120
154
|
and do not make an empty migration commit.
|
|
121
155
|
|
|
122
|
-
|
|
156
|
+
Offer `imf-web-ui-audit full` as the next step: the migration check covered what the releases changed, the audit checks the
|
|
157
|
+
whole project against the conventions and changes nothing. Run it only after an explicit yes.
|
|
123
158
|
|
|
124
159
|
For approved migration work, ask: **Approve these consumer migration changes and commit them separately?** Then stage only
|
|
125
160
|
the approved paths, verify again, and use a separate imperative commit message.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: imf-web-ui-user-profile
|
|
3
|
+
description:
|
|
4
|
+
"Read or create the person's profile: technical background, experience, how they want things explained, and how they like
|
|
5
|
+
to work. Invoke it first in every Web UI skill, and when the person asks to change their profile or how the agent explains
|
|
6
|
+
or paces work."
|
|
7
|
+
user-invocable: false
|
|
8
|
+
allowed-tools: Bash Read Write
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Fit the work to the person
|
|
12
|
+
|
|
13
|
+
The profile records who the person is and how they learn, so every Web UI workflow explains what they need and paces the work
|
|
14
|
+
the way they like. Read it once per session; later skills in the same session reuse what is already loaded.
|
|
15
|
+
|
|
16
|
+
## Read the profile
|
|
17
|
+
|
|
18
|
+
Resolve the profile path with the shell, then read that exact path:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
printf '%s\n' "${XDG_CONFIG_HOME:-$HOME/.config}/imfusion/web-ui/consumer-profile.md"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The profile sits outside the project: it belongs to the person, never to the repository, so read-only promises such as the
|
|
25
|
+
audit's still hold when this skill writes it.
|
|
26
|
+
|
|
27
|
+
When the file exists, apply it and return to the calling workflow without comment. When it is missing, run the interview
|
|
28
|
+
before the workflow starts. When the router skips companions for a small task, do the task first and offer the interview
|
|
29
|
+
afterwards.
|
|
30
|
+
|
|
31
|
+
## Interview
|
|
32
|
+
|
|
33
|
+
Open with one question: may you ask six short questions and save the answers to the profile path, so every later workflow
|
|
34
|
+
fits them and they are never asked again? Mention that they can decline any single question. On no, use the defaults below
|
|
35
|
+
for this session and do not offer the interview again in it.
|
|
36
|
+
|
|
37
|
+
On yes, ask one question per message, in plain prose, and wait for each answer:
|
|
38
|
+
|
|
39
|
+
1. What is your name?
|
|
40
|
+
2. What is your technical background: the languages and tools you work with?
|
|
41
|
+
3. How much have you built for the web, for example with React, HTML, and CSS?
|
|
42
|
+
4. Beyond Git, how comfortable are you with npm and the terminal?
|
|
43
|
+
5. How much explanation do you want: just the results, a short gloss for new terms, or the reasoning behind each step?
|
|
44
|
+
6. How do you like to work: pause after every step, pause after each finished piece, or work freely and stop only before a
|
|
45
|
+
commit?
|
|
46
|
+
|
|
47
|
+
Derive the levels from the answers; ask a short follow-up only when an answer fits no level. The person can decline any
|
|
48
|
+
question: its field stays out of the file, and its default applies: `some`, `comfortable`, `terms`, `slice`.
|
|
49
|
+
|
|
50
|
+
## The file
|
|
51
|
+
|
|
52
|
+
Show the profile below before writing it. The person can correct or remove any line, or reject the whole profile; on a
|
|
53
|
+
rejection, save nothing and use the defaults for this session. After they confirm, write it and name its path so they can
|
|
54
|
+
edit or delete it later:
|
|
55
|
+
|
|
56
|
+
```markdown
|
|
57
|
+
---
|
|
58
|
+
name: <their name>
|
|
59
|
+
frontend: none | some | seasoned
|
|
60
|
+
tooling: new | comfortable
|
|
61
|
+
explanation: results | terms | reasoning
|
|
62
|
+
pace: step | slice | commit
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Background
|
|
66
|
+
|
|
67
|
+
<their answer to question 2, in their words>
|
|
68
|
+
|
|
69
|
+
## Notes
|
|
70
|
+
|
|
71
|
+
- <lasting preferences learned later>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
When the write fails, keep the answers for this session. When the person later states a lasting preference about how to work
|
|
75
|
+
with them, such as a language, a term they want avoided, or a tool they already know, add it under `Notes` and tell them.
|
|
76
|
+
When they ask to change their profile, run the interview again with the current answers as defaults.
|
|
77
|
+
|
|
78
|
+
## Apply the profile
|
|
79
|
+
|
|
80
|
+
The fields apply independently.
|
|
81
|
+
|
|
82
|
+
- **Name**: address the person by name.
|
|
83
|
+
- **Background**: explain by analogy to what they already know, such as a component compared to a class for a Java developer.
|
|
84
|
+
- **Frontend `none` or `some`**: give a one-line gloss the first time a frontend term appears, such as component, prop,
|
|
85
|
+
design token, CSS layer, or Storybook. For `none`, also say what a finding means for the running app.
|
|
86
|
+
- **Tooling `new`**: gloss tooling terms on first use, such as lockfile, dist-tag, prerelease, hook, harness, or the
|
|
87
|
+
`AGENTS.md` fence; say in one plain sentence what each command does before it runs, read-only checks included; and before
|
|
88
|
+
an approval question, say what yes changes and how to undo it.
|
|
89
|
+
- **Explanation**: `results` adds nothing beyond what the experience levels call for; `terms` glosses every new term;
|
|
90
|
+
`reasoning` also says why each step happens, and after a report block, what happened and what comes next.
|
|
91
|
+
- **Pace**: `step` ends the reply after each step or phase of the calling workflow and waits for a go-ahead; `slice` pauses
|
|
92
|
+
after each working piece; `commit` runs freely between the workflow's own approval points.
|
|
93
|
+
|
|
94
|
+
Pace adds pauses on top of the calling workflow's approval gates and keeps every one of them. Put explanations around report
|
|
95
|
+
blocks and approval questions, never inside them.
|
|
@@ -10,6 +10,8 @@ description:
|
|
|
10
10
|
Use this skill for screen-level decisions. Verify component APIs with `imf-web-ui-components`; put code and styling rules in
|
|
11
11
|
`imf-web-ui-conventions`.
|
|
12
12
|
|
|
13
|
+
Invoke `imf-web-ui-user-profile` first and explain at its levels throughout.
|
|
14
|
+
|
|
13
15
|
The identity index marks components as stable or experimental. Experimental components are usable, but prefer wrapping one
|
|
14
16
|
when it is used across many call sites so API movement stays local.
|
|
15
17
|
|