@imfusion/web-ui 0.6.1-dev.27.gfc6e5abb → 0.6.1-dev.3.g8b2855c3
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/README.md +169 -102
- package/dist/{code-C_56u-Vk.js → code-Blo48PGr.js} +2 -2
- package/dist/components/stack/stack.d.ts +1 -1
- package/dist/icons/icon-config-provider.d.ts +8 -0
- package/dist/icons/icon-context.d.ts +4 -0
- package/dist/{icons-Cy1HAosO.js → icons-wBmF0U2x.js} +1 -1
- package/dist/icons.js +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +830 -1009
- package/dist/integrations/code-highlight/highlighter.d.ts +0 -24
- package/dist/integrations/code-highlight.js +47 -80
- package/dist/integrations/image-display-options.js +2 -2
- package/dist/provider/web-ui-provider.d.ts +3 -3
- package/dist/style.css +1 -1
- package/dist/{tabs-DIe1Utiy.js → tabs-CMKvMF4E.js} +0 -2
- package/package.json +4 -5
- package/src/docgen/doc.gen.json +1 -389
- package/src/llms/install-templates/AGENTS.md +18 -15
- package/src/llms/llms.gen.txt +33 -39
- package/src/llms/skills/imf-web-ui/SKILL.md +39 -30
- package/src/llms/skills/imf-web-ui-audit/SKILL.md +102 -50
- package/src/llms/skills/imf-web-ui-components/SKILL.md +104 -47
- package/src/llms/skills/imf-web-ui-conventions/SKILL.md +52 -44
- package/src/llms/skills/imf-web-ui-conventions/templates/AUDIT_CHECKLIST.md +0 -1
- package/src/llms/skills/imf-web-ui-conventions/topics/agent-tooling.md +62 -40
- package/src/llms/skills/imf-web-ui-conventions/topics/assets.md +12 -11
- package/src/llms/skills/imf-web-ui-conventions/topics/authentication.md +46 -31
- package/src/llms/skills/imf-web-ui-conventions/topics/class-names.md +23 -18
- package/src/llms/skills/imf-web-ui-conventions/topics/components.md +69 -20
- package/src/llms/skills/imf-web-ui-conventions/topics/data.md +146 -50
- package/src/llms/skills/imf-web-ui-conventions/topics/docs-structure.md +23 -17
- package/src/llms/skills/imf-web-ui-conventions/topics/git.md +20 -15
- package/src/llms/skills/imf-web-ui-conventions/topics/library-boundary.md +19 -28
- package/src/llms/skills/imf-web-ui-conventions/topics/library-setup.md +16 -20
- package/src/llms/skills/imf-web-ui-conventions/topics/npm-project.md +42 -28
- package/src/llms/skills/imf-web-ui-conventions/topics/project-structure.md +30 -28
- package/src/llms/skills/imf-web-ui-conventions/topics/react.md +74 -28
- package/src/llms/skills/imf-web-ui-conventions/topics/styling.md +62 -65
- package/src/llms/skills/imf-web-ui-conventions/topics/testing.md +14 -12
- package/src/llms/skills/imf-web-ui-conventions/topics/tokens.md +4 -9
- package/src/llms/skills/imf-web-ui-conventions/topics/tooling.md +68 -40
- package/src/llms/skills/imf-web-ui-conventions/topics/typescript.md +50 -26
- package/src/llms/skills/imf-web-ui-conventions/topics/validation.md +25 -19
- package/src/llms/skills/imf-web-ui-setup/SKILL.md +64 -45
- package/src/llms/skills/imf-web-ui-update/SKILL.md +114 -48
- package/src/llms/skills/imf-web-ui-ux/SKILL.md +92 -64
- package/src/llms/skills/imf-web-ui-ux/references/forms.md +36 -16
- package/src/llms/skills/imf-web-ui-ux/references/usability-heuristics.md +27 -14
- package/src/llms/skills/imf-web-ui-ux/references/visual-design.md +38 -22
- package/src/llms/tokens.gen.json +5 -5
- package/dist/codegen/gen-code-highlight-theme.d.ts +0 -1
- package/dist/components/toast/index.d.ts +0 -2
- package/dist/components/toast/toast.d.ts +0 -200
- package/dist/components/toast/toast.meta.d.ts +0 -2
- package/dist/icons/icon-config.d.ts +0 -12
|
@@ -1,91 +1,157 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: imf-web-ui-update
|
|
3
3
|
description:
|
|
4
|
-
"Update @imfusion/web-ui in a consumer repository
|
|
5
|
-
|
|
6
|
-
get approval before each commit."
|
|
4
|
+
"Update @imfusion/web-ui in a consumer repository: refresh the package, vendored skills, and lifecycle hooks, verify the
|
|
5
|
+
base update, then audit and optionally migrate affected or custom consumer components in a separate approved commit."
|
|
7
6
|
argument-hint: "[--dry-run] [optional version or reason]"
|
|
8
7
|
allowed-tools: Bash Read Grep
|
|
9
8
|
---
|
|
10
9
|
|
|
11
|
-
#
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
# imf-web-ui-update
|
|
11
|
+
|
|
12
|
+
Update a repository that consumes `@imfusion/web-ui`. Preserve existing project choices and user work. The workflow has two
|
|
13
|
+
commits: the dependency/tooling update first, then an optional consumer migration. Never commit without a fresh explicit
|
|
14
|
+
approval.
|
|
15
|
+
|
|
16
|
+
## Rules
|
|
17
|
+
|
|
18
|
+
- Work from the frontend package root. In a monorepo, inspect package manifests and `git worktree list` first, then choose
|
|
19
|
+
the frontend package in the active worktree that uses web-ui. Read repository and component instructions before changing
|
|
20
|
+
files.
|
|
21
|
+
- This workflow uses npm. `package-lock.json` is the expected lockfile. Another lockfile is a conflict: stop and ask.
|
|
22
|
+
- A dry run is read-only. Do not install, run the installer, format, stage, commit, reset, or clean. Report what would run.
|
|
23
|
+
- Record the initial `git status --short`. Existing changes are held back, never staged or overwritten.
|
|
24
|
+
- A dirty file that the workflow needs to modify is a conflict. Stop and report it. This includes package files, installed
|
|
25
|
+
skill directories, the `AGENTS.md` installer fence, hook files, and hook settings.
|
|
26
|
+
- Do not hand-edit installer-owned skills, the `AGENTS.md` fenced block, or installer-owned hook files.
|
|
27
|
+
- Keep the base update and consumer migration in separate commits. Do not begin the migration audit until the base update
|
|
28
|
+
commit is complete.
|
|
29
|
+
- Treat the installed package version before the update as the comparison baseline. There is no assumed changelog.
|
|
30
|
+
- A migration candidate is a custom consumer implementation whose behavior overlaps with a current web-ui component, or an
|
|
31
|
+
existing web-ui usage affected by changed types or documented API. Do not infer a replacement from a name alone; inspect
|
|
32
|
+
the implementation and the current component documentation/types.
|
|
15
33
|
|
|
16
34
|
## Preflight
|
|
17
35
|
|
|
18
|
-
1.
|
|
19
|
-
2.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
4. Check for another npm process and stop on a conflict. A dirty file this workflow needs is also a conflict. Do not reset,
|
|
24
|
-
clean, restore, or hide it.
|
|
25
|
-
5. With `--dry-run`, stop after reporting what would happen. Do not install, format, stage, commit, or ask for commit
|
|
26
|
-
approval.
|
|
36
|
+
1. Select the frontend package in the active worktree and read its instructions, `package.json`, and `package-lock.json`.
|
|
37
|
+
2. Check whether `@imfusion/web-ui` is already declared and record its installed/version-marker version.
|
|
38
|
+
3. Record the worktree status and identify files the update would touch.
|
|
39
|
+
4. Inspect `.agents/skills/`, `.claude/skills/`, the `AGENTS.md` fence, `.claude/settings.json`, and `.agents/hooks/`.
|
|
40
|
+
5. Check for another npm process. Stop on any conflict or ambiguous target.
|
|
27
41
|
|
|
28
|
-
##
|
|
42
|
+
## Base update
|
|
29
43
|
|
|
30
|
-
|
|
44
|
+
In a non-dry run, update the dependency:
|
|
31
45
|
|
|
32
46
|
```sh
|
|
33
47
|
npm install @imfusion/web-ui
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Pass an explicit version only when the user supplied one. Do not use `--force` or `--legacy-peer-deps` to make installation
|
|
51
|
+
pass. Stop on install failure.
|
|
52
|
+
|
|
53
|
+
Then refresh the existing web-ui skill target and lifecycle hooks:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
34
56
|
npx web-ui-install
|
|
35
57
|
npx web-ui-install --hooks
|
|
36
58
|
```
|
|
37
59
|
|
|
38
|
-
|
|
39
|
-
the
|
|
60
|
+
Run these from the consumer package root, the directory holding the `node_modules` that the dependency install just wrote.
|
|
61
|
+
`npx` resolves `web-ui-install` from the installed `@imfusion/web-ui` there; from any other directory it cannot find the
|
|
62
|
+
binary. Preserve the existing target (`.agents`, `.claude`, or both); do not silently choose a new one.
|
|
63
|
+
|
|
64
|
+
Always run both installer commands after the package update. Skills and installer-owned hook scripts may have changed even
|
|
65
|
+
when their existing registrations already cover session start, subagent start, prompt submit, and the stop gate. The hook
|
|
66
|
+
installer refreshes those scripts wholesale, prunes retired scripts and their registrations, and merges registrations
|
|
67
|
+
idempotently into both host files (`.claude/settings.json` and `.codex/hooks.json`). Stop on malformed settings or installer
|
|
68
|
+
conflicts.
|
|
69
|
+
|
|
70
|
+
## Verification
|
|
71
|
+
|
|
72
|
+
After each mutating command, compare `git status --short` with the preflight snapshot.
|
|
40
73
|
|
|
41
|
-
|
|
42
|
-
package update even when the existing registrations look complete: they refresh scripts, prune retired registrations, and
|
|
43
|
-
merge installer-owned entries idempotently into `.claude/settings.json` and `.codex/hooks.json`. Stop on malformed settings
|
|
44
|
-
or installer conflicts. Read existing host registrations first and do not stack an event the project already covers.
|
|
74
|
+
Classify paths as:
|
|
45
75
|
|
|
46
|
-
|
|
76
|
+
- **Update-owned:** package files and installer-owned files changed by this workflow.
|
|
77
|
+
- **Held back:** pre-existing user changes, excluded from the commit.
|
|
78
|
+
- **Conflict:** an overlapping pre-existing change, ambiguous target, or unexpected changed path.
|
|
47
79
|
|
|
48
|
-
|
|
49
|
-
change.
|
|
80
|
+
On conflict, stop. Never use `git restore`, `git reset`, `git clean`, or broad staging to hide it.
|
|
50
81
|
|
|
51
|
-
Run the
|
|
52
|
-
|
|
82
|
+
Run the frontend package's documented full verification after the base update. Read its `package.json` scripts and choose
|
|
83
|
+
commands that cover typechecking, linting, tests, and building. Prefer one documented aggregate `verify`/`check` script when
|
|
84
|
+
it covers those responsibilities; otherwise run the documented non-watch scripts for the responsibilities that exist. Do not
|
|
85
|
+
invent script names or run watch/dev scripts. A type or build failure is a base-update conflict to resolve before the base
|
|
86
|
+
commit, not a migration finding to defer.
|
|
53
87
|
|
|
54
|
-
|
|
88
|
+
Verify the dependency/lockfile, current skill markers, the `AGENTS.md` fence, hook coverage, and the final path list. In
|
|
89
|
+
dry-run mode, say that mutation-dependent checks were skipped.
|
|
55
90
|
|
|
56
|
-
|
|
91
|
+
## Base update report and approval
|
|
92
|
+
|
|
93
|
+
Before the base commit, show this concise report:
|
|
57
94
|
|
|
58
95
|
```text
|
|
59
96
|
@imfusion/web-ui update report
|
|
60
|
-
Package : <old> -> <new>
|
|
97
|
+
Package : <old> -> <new> / would update
|
|
61
98
|
Skills : <status>
|
|
62
99
|
Hooks : <status>
|
|
63
100
|
Verification : <status>
|
|
64
101
|
Update files : <paths>
|
|
65
102
|
Held back : <paths or none>
|
|
66
103
|
Conflicts : <paths or none>
|
|
67
|
-
Commit : <message or not proposed>
|
|
104
|
+
Commit : <imperative message or not proposed>
|
|
68
105
|
```
|
|
69
106
|
|
|
70
|
-
|
|
71
|
-
|
|
107
|
+
Normal mode: ask exactly, **“Approve these update-owned changes and commit them?”** Do not commit without an affirmative
|
|
108
|
+
answer. If denied, leave the changes uncommitted.
|
|
109
|
+
|
|
110
|
+
Dry-run mode: state **“Dry run complete; no changes or commit were made.”** Do not mutate or ask for commit approval.
|
|
111
|
+
|
|
112
|
+
## Consumer migration audit
|
|
113
|
+
|
|
114
|
+
Begin this phase only after the approved base update has been committed. Record the old and new package versions from the
|
|
115
|
+
pre-update and current manifests/lockfile. Use the current package's exported types, generated documentation, and component
|
|
116
|
+
examples as the source of truth. Use the old version's package metadata or repository history when available to identify what
|
|
117
|
+
changed; do not pretend a changelog exists.
|
|
118
|
+
|
|
119
|
+
Run the same documented full verification again after the base commit. Separate findings into:
|
|
120
|
+
|
|
121
|
+
- **Compatibility fixes:** existing web-ui imports, props, or usage patterns that no longer typecheck, build, lint, or pass
|
|
122
|
+
tests.
|
|
123
|
+
- **Changed component usages:** existing components whose current API, behavior, or documented contract changed between the
|
|
124
|
+
two versions and may need a consumer update, even when the typecheck passes.
|
|
125
|
+
- **Replacement candidates:** custom consumer components, wrappers, or field implementations that overlap with a component
|
|
126
|
+
now exported by `@imfusion/web-ui`. Inspect their code, styles, and call sites before suggesting a replacement. Include the
|
|
127
|
+
current custom implementation, the proposed web-ui component, the relevant API/type evidence, and any behavior or styling
|
|
128
|
+
that still needs to be preserved.
|
|
129
|
+
|
|
130
|
+
Report these findings separately from the base update. Ask whether to apply the proposed migration. If the user declines,
|
|
131
|
+
leave the consumer code unchanged. If accepted, make only the approved migration changes, run the documented full
|
|
132
|
+
verification again, and show a second report with the migration paths, held-back paths, conflicts, and verification result.
|
|
133
|
+
|
|
134
|
+
If no findings exist, report that the installed update has no detected compatibility fixes, changed usages, or replacement
|
|
135
|
+
candidates. Do not create an empty migration commit.
|
|
72
136
|
|
|
73
|
-
|
|
137
|
+
Whatever the migration outcome, close the phase by asking whether to run `imf-web-ui-audit full`: an update can shift the
|
|
138
|
+
baseline (new components, hooks, conventions), and the audit shows where the project now stands against it. Run it only on an
|
|
139
|
+
explicit yes.
|
|
74
140
|
|
|
75
|
-
|
|
76
|
-
don't assume a changelog exists. Compare the old and new package metadata, current generated docs, types, and examples. Run
|
|
77
|
-
the full verification again.
|
|
141
|
+
## Migration approval
|
|
78
142
|
|
|
79
|
-
|
|
143
|
+
Ask exactly, **“Approve these consumer migration changes and commit them separately?”** Do not commit without an affirmative
|
|
144
|
+
answer. The migration approval is not implied by approval of the base update.
|
|
80
145
|
|
|
81
|
-
|
|
82
|
-
- existing uses affected by a changed API or documented behavior;
|
|
83
|
-
- custom components that overlap with a current Web UI primitive, with evidence and any behavior to preserve.
|
|
146
|
+
## Commit
|
|
84
147
|
|
|
85
|
-
|
|
86
|
-
and do not make an empty migration commit.
|
|
148
|
+
For the base update, after approval:
|
|
87
149
|
|
|
88
|
-
|
|
150
|
+
1. Recheck status and exclude held-back paths.
|
|
151
|
+
2. Stage base update-owned paths selectively. Never use `git add .` or `git add -A`.
|
|
152
|
+
3. Run the repository's commit workflow if it has one, including its required verification and documentation audit. Otherwise
|
|
153
|
+
run documented verification and follow the repository's commit convention.
|
|
154
|
+
4. Commit with a concise imperative message and confirm the commit and final status.
|
|
89
155
|
|
|
90
|
-
For approved migration
|
|
91
|
-
|
|
156
|
+
For an approved migration, repeat the same selective staging and documented commit workflow with a separate imperative
|
|
157
|
+
message. Never bypass hooks or amend an unrelated commit after a hook failure.
|
|
@@ -1,75 +1,103 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: imf-web-ui-ux
|
|
3
3
|
description:
|
|
4
|
-
"
|
|
5
|
-
|
|
4
|
+
"UX guidance for building screens with @imfusion/web-ui when no designer is around: pick the right component for an
|
|
5
|
+
interaction, lay out common screen types, handle empty/loading/error states. Load when building or reshaping a screen,
|
|
6
|
+
flow, or feature UI — not for prop lookups (that's imf-web-ui-components)."
|
|
6
7
|
---
|
|
7
8
|
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
# imf-web-ui-ux
|
|
10
|
+
|
|
11
|
+
Most teams consuming `@imfusion/web-ui` don't have a designer on call. This skill stands in: it encodes the library authors'
|
|
12
|
+
UX experience — the whole experience of a screen, its visual design, and the usability where both meet. Follow it by default;
|
|
13
|
+
deviate when the product has a real reason to. Code-level patterns (tokens, layers, wrappers) live in
|
|
14
|
+
`imf-web-ui-conventions`; project wiring lives in the `library-setup` topic of `imf-web-ui-conventions`.
|
|
15
|
+
|
|
16
|
+
Component names below are real — verify any API against the docgen index (`imf-web-ui-components`) before use. Never invent a
|
|
17
|
+
component this library doesn't ship.
|
|
18
|
+
|
|
19
|
+
## Before recommending or building: the interview
|
|
20
|
+
|
|
21
|
+
If — and only if — the request is foggy and a human is available, ask what the conversation hasn't already answered, from
|
|
22
|
+
this list, and nothing more. This applies to recommendation questions, not just build tasks: when someone asks "which
|
|
23
|
+
component for X?" and the choice hinges on facts you don't have (how many controls, how often used, how much data), **ask
|
|
24
|
+
those questions first and recommend after** — don't recommend and then list caveats, because the caveats _are_ the interview,
|
|
25
|
+
inverted.
|
|
26
|
+
|
|
27
|
+
1. Who uses this screen, and how often? (daily power-user tool vs. occasional visit changes density and shortcuts)
|
|
28
|
+
2. What is the **one** primary action? (a screen with three primary buttons has zero)
|
|
29
|
+
3. What data does it show — shape and volume? (5 rows or 5,000 decides table vs. cards vs. search-first)
|
|
30
|
+
4. What happens when it's empty, loading, or failing?
|
|
31
|
+
5. Where does it live — full page, or a step inside another flow?
|
|
32
|
+
|
|
33
|
+
If no human is around: make the conservative choice, and state your assumptions in the handoff.
|
|
34
|
+
|
|
35
|
+
## Choosing the surface
|
|
36
|
+
|
|
37
|
+
- **Full page** — the default. Reach for an overlay only when context must be preserved behind the task.
|
|
38
|
+
- **`Drawer`** — a focused sub-task that interrupts the page: edit-details, multi-field create, confirm-with-context. This
|
|
39
|
+
library ships no modal `Dialog`; `Drawer` is the blocking surface. If a true centered dialog is genuinely required, raise
|
|
40
|
+
it upstream — don't hand-roll one.
|
|
41
|
+
- **`Popover`** — light, dismissable, contextual: a small form, a filter panel, extra actions. If it needs a heading and
|
|
42
|
+
three fields, it wanted to be a `Drawer`.
|
|
43
|
+
- **`Tooltip`** — hints only. Never essential information, never interactive content.
|
|
44
|
+
- **`Collapsible`** — progressive disclosure inside the page: advanced options, long secondary content.
|
|
45
|
+
- **`Tabs`** — parallel views of the same subject. If users must complete all of them, it's a flow, not tabs.
|
|
46
|
+
|
|
47
|
+
## Choosing between look-alikes
|
|
48
|
+
|
|
49
|
+
- **`Button` vs. `ChipLink` vs. `Chip`** — does it _do_ something (`Button`), _go_ somewhere (`ChipLink`), or _label_
|
|
50
|
+
something (`Chip`)?
|
|
51
|
+
- **`Table` alone vs. `Table` + a table library** — static, small data reads fine as bare `Table` parts; the moment sorting,
|
|
52
|
+
pagination, or column logic appears, drive the parts with a headless table library (TanStack Table recommended) you install
|
|
53
|
+
yourself, using `Table.SortableHeaderCell` for the sort glue.
|
|
54
|
+
- **`Callout` vs. transient feedback** — `Callout` is for persistent, in-place status (errors, warnings, empty-state hints).
|
|
55
|
+
The library ships no `Toast`; for fire-and-forget confirmations prefer inline feedback near the trigger, and raise the
|
|
56
|
+
toast need upstream rather than hand-rolling one.
|
|
57
|
+
- **`Input`/`Select`/`Checkbox`/`Switch`/`Slider`** — `Switch` for instant effect, `Checkbox` for submitted forms; `Select`
|
|
58
|
+
beyond ~5 options, radio-style choices below that; `Slider` only when the _relative_ position means more than the exact
|
|
59
|
+
number.
|
|
60
|
+
|
|
61
|
+
## Layout and hierarchy
|
|
62
|
+
|
|
63
|
+
- Frame the app with **`AppShell`**; inside it, compose **`Stack`** and **`Row`** with token-based gaps instead of
|
|
64
|
+
hand-written flex containers with magic-number margins. **`Separator`** over border hacks.
|
|
65
|
+
- Text hierarchy comes from **`Typo`** — pick levels by role (page title, section, body, caption), don't skip levels for
|
|
66
|
+
visual effect, don't style raw HTML headings next to it.
|
|
67
|
+
- **One primary action per view.** Everything else uses the quieter `Button` variants (see its docgen entry for the semantic
|
|
68
|
+
variant list). If two things compete for primary, decide which one the screen is _for_.
|
|
69
|
+
- Density follows the interview: power-user + high volume → compact tables, visible shortcuts; occasional use + low volume →
|
|
70
|
+
generous spacing, explanatory text.
|
|
71
|
+
|
|
72
|
+
## States are part of the screen
|
|
73
|
+
|
|
74
|
+
Every screen ships four states, not one:
|
|
75
|
+
|
|
76
|
+
- **Empty** — say what this screen _will_ show and what to do next; an empty `Table` with no explanation is a bug.
|
|
77
|
+
- **Loading** — `Spinner`, or skeletons for known layouts; keep the frame stable so content doesn't jump in.
|
|
78
|
+
- **Error** — `Callout` with what failed and what the user can do; never a blank region, never only a console log.
|
|
79
|
+
- **Loaded** — the one you were going to build anyway.
|
|
80
|
+
|
|
81
|
+
## Looking native
|
|
82
|
+
|
|
83
|
+
Custom UI the library doesn't cover should be indistinguishable from library UI: build it from `--imf-ui-*` tokens and
|
|
84
|
+
compose it with library primitives. The goal lives here; the mechanics (tokens, layers, wrappers) live in
|
|
11
85
|
`imf-web-ui-conventions`.
|
|
12
86
|
|
|
13
|
-
|
|
14
|
-
when it is used across many call sites so API movement stays local.
|
|
15
|
-
|
|
16
|
-
## Ask only what matters
|
|
17
|
-
|
|
18
|
-
If the request is vague and a human can answer, ask these questions one at a time and stop once the choice is clear:
|
|
19
|
-
|
|
20
|
-
1. Who uses the screen, and how often?
|
|
21
|
-
2. What is its one primary action?
|
|
22
|
-
3. What data does it show, and roughly how much?
|
|
23
|
-
4. What should users see when it is empty, loading, or failing?
|
|
24
|
-
5. Is it a full page or part of another flow?
|
|
25
|
-
|
|
26
|
-
If the prompt already answers a question, do not ask it again. If nobody can answer, make the conservative choice and state
|
|
27
|
-
the assumption.
|
|
28
|
-
|
|
29
|
-
## Choose a surface
|
|
30
|
-
|
|
31
|
-
- Use a full page by default.
|
|
32
|
-
- Use `Drawer` for a focused task that keeps the current page in context.
|
|
33
|
-
- Use `Popover` for small contextual content or a light form.
|
|
34
|
-
- Use `Tooltip` for a hint only. It must not contain required or interactive information.
|
|
35
|
-
- Use `Collapsible` for secondary content inside the page.
|
|
36
|
-
- Use `Tabs` for parallel views of one subject. If users must complete every section, use a flow instead.
|
|
37
|
-
|
|
38
|
-
The library has no modal `Dialog` or `Toast`. Raise those gaps rather than hand-rolling a replacement without a product
|
|
39
|
-
reason.
|
|
40
|
-
|
|
41
|
-
## Choose between similar controls
|
|
42
|
-
|
|
43
|
-
- `Button` performs an action, `ChipLink` goes somewhere, and `Chip` labels something.
|
|
44
|
-
- Use plain `Table` parts for static small data. Pair them with a headless table library for sorting, pagination, or column
|
|
45
|
-
logic. TanStack Table is the recommended choice.
|
|
46
|
-
- Use `Callout` for persistent in-place status. Put transient confirmation near the action until a toast pattern exists.
|
|
47
|
-
- Use `Switch` for an immediate setting and `Checkbox` for a submitted choice.
|
|
48
|
-
- Use `Select` for a known list, and consider a different control when the list is very short or very large.
|
|
49
|
-
- Use `Slider` when relative position matters more than typing an exact value.
|
|
50
|
-
|
|
51
|
-
## Build the hierarchy
|
|
52
|
-
|
|
53
|
-
- Frame an application with `AppShell`.
|
|
54
|
-
- Compose `Stack` and `Row` for spacing and arrangement. Use `Separator` for a real division.
|
|
55
|
-
- Use `Typo` for text hierarchy instead of styling raw headings beside it.
|
|
56
|
-
- Give a view one primary action. Make other actions quieter.
|
|
57
|
-
- Choose density from the user's frequency and data volume: frequent work and large data need compact layouts; occasional
|
|
58
|
-
work benefits from more explanation and space.
|
|
59
|
-
|
|
60
|
-
## Cover the states
|
|
61
|
-
|
|
62
|
-
Plan these states with the loaded view:
|
|
87
|
+
## Experimental components
|
|
63
88
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
- **Loaded**: the normal view.
|
|
89
|
+
The identity index marks each component `stable` or `experimental`. Experimental ones are fine to use, but expect API
|
|
90
|
+
movement across releases — prefer wrapping them once (see `imf-web-ui-conventions`) so a breaking change lands in one file,
|
|
91
|
+
not forty call sites.
|
|
68
92
|
|
|
69
|
-
##
|
|
93
|
+
## Deep dives
|
|
70
94
|
|
|
71
|
-
|
|
72
|
-
|
|
95
|
+
The 80/20 fundamentals behind this skill's advice, distilled from authoritative sources, live in child files. Read the one
|
|
96
|
+
that matches the work — they are for you, the agent, while designing; hand the source links to the human only on request:
|
|
73
97
|
|
|
74
|
-
|
|
75
|
-
|
|
98
|
+
- [references/usability-heuristics.md](references/usability-heuristics.md) — Nielsen's ten heuristics, applied to web-ui
|
|
99
|
+
screens. Read when reviewing or reworking an existing flow.
|
|
100
|
+
- [references/visual-design.md](references/visual-design.md) — hierarchy, grouping, alignment, whitespace. Read when a screen
|
|
101
|
+
is functionally complete but looks wrong and you can't say why.
|
|
102
|
+
- [references/forms.md](references/forms.md) — form layout, labels, validation timing, error wording. Read before building
|
|
103
|
+
any form beyond two fields.
|
|
@@ -1,30 +1,50 @@
|
|
|
1
1
|
# Form UX
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
The 80/20 of forms, distilled from NN/g's form-design and error-guidelines articles
|
|
4
|
+
([form design](https://www.nngroup.com/articles/web-form-design/),
|
|
5
|
+
[errors](https://www.nngroup.com/articles/errors-forms-design-guidelines/)). Forms are where inexperienced UI work loses the
|
|
6
|
+
most users — a cited CHI study found guideline-compliant forms hit 78% one-try error-free submission vs. 42% for
|
|
7
|
+
non-compliant ones. Read before building any form beyond two fields.
|
|
8
|
+
|
|
9
|
+
The library ships the controls (`Input`, `Select`, `Checkbox`, `Switch`, `Slider`) but no form or field wrapper, so labels,
|
|
10
|
+
grouping, and where errors appear are composed by you. That's exactly where these rules apply. Composing the markup is not
|
|
11
|
+
the same as owning the state: form state and validation belong to a form library (see `imf-web-ui-conventions`), and these
|
|
12
|
+
rules govern how its errors get presented.
|
|
5
13
|
|
|
6
14
|
## Structure
|
|
7
15
|
|
|
8
|
-
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
|
|
16
|
+
- **Cut every cuttable field.** Each field that can be derived, deferred, or omitted costs completions. Optional fields:
|
|
17
|
+
first try to eliminate them; keep at most 1–2 and mark _them_ explicitly with "(optional)" — don't asterisk the required
|
|
18
|
+
majority.
|
|
19
|
+
- **Single column.** Multiple columns break the vertical momentum of filling a form. The one exception: short, logically
|
|
20
|
+
inseparable fields (city / postal code) may share a `Row`.
|
|
21
|
+
- **Group by topic.** Related fields sit tight in a `Stack`; groups separate with larger whitespace (proximity is grouping —
|
|
22
|
+
see [visual-design.md](visual-design.md)). Keep groups accessible: a labeled `fieldset` or heading per group.
|
|
23
|
+
- **Match field size to expected input.** A two-letter field shouldn't be full-width; a free-text reason shouldn't be one
|
|
24
|
+
line.
|
|
13
25
|
|
|
14
26
|
## Labels
|
|
15
27
|
|
|
16
|
-
|
|
17
|
-
|
|
28
|
+
- **Real `<label>` elements, outside the field, close to it.** Above the field is the default (works on mobile, scans fast).
|
|
29
|
+
- **Never placeholder text as the label.** It vanishes on input, so users can't review what a filled field means or check
|
|
30
|
+
errors. Persistent hints (format examples) go outside the field, stated _before_ the user types, not revealed by the error
|
|
31
|
+
afterward.
|
|
18
32
|
|
|
19
33
|
## Validation and errors
|
|
20
34
|
|
|
21
|
-
Validate when the user finishes a field,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
35
|
+
- **Validate when the user finishes a field, not while typing.** Premature validation — flagging a field as wrong while it's
|
|
36
|
+
still being filled — reads as hostile. Live feedback is only for cases where it genuinely helps as the user types (e.g. a
|
|
37
|
+
password-requirements checklist).
|
|
38
|
+
- **Errors sit next to the offending field**, with multiple cues — outline plus message, never color alone. Never rely solely
|
|
39
|
+
on a summary at the top of the form.
|
|
40
|
+
- **Error text is precise, human, and constructive**: what's wrong, and what to do — "Date must be in the future", not
|
|
41
|
+
"Invalid input". A form-level failure (server rejected) gets a `Callout` above the actions; field-level problems stay at
|
|
42
|
+
their fields.
|
|
43
|
+
- **Preserve the user's input.** An error never empties the field, and there is no Reset/Clear button — its main use is being
|
|
44
|
+
clicked by accident.
|
|
26
45
|
|
|
27
46
|
## Submission
|
|
28
47
|
|
|
29
|
-
|
|
30
|
-
|
|
48
|
+
- One primary submit `Button`, labeled with the action's outcome ("Create project", not "Submit"). While submitting: the
|
|
49
|
+
button shows progress and the form stays visible — on failure the user must see their input plus the error, not a blank
|
|
50
|
+
form (see also heuristic 9 in [usability-heuristics.md](usability-heuristics.md)).
|
|
@@ -1,16 +1,29 @@
|
|
|
1
|
-
# Usability heuristics
|
|
1
|
+
# Usability heuristics, applied
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Nielsen's ten usability heuristics ([source](https://www.nngroup.com/articles/ten-usability-heuristics/)) are the highest
|
|
4
|
+
80/20 leverage in interaction design — most usability problems in a screen violate one of these. Walk them as a checklist
|
|
5
|
+
when reviewing or reworking a flow. Each entry: the rule, then what it means in a web-ui app.
|
|
5
6
|
|
|
6
|
-
1. **
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
1. **Visibility of system status** — always show what's happening via timely feedback. In practice: every async action gets a
|
|
8
|
+
`Spinner` or disabled-with-progress state; every mutation confirms visibly near its trigger; never leave a button that
|
|
9
|
+
"did nothing" for two seconds.
|
|
10
|
+
2. **Match the system to the real world** — use the users' words, not internal jargon; order information the way the domain
|
|
11
|
+
thinks. Label buttons and `Table` columns in the vocabulary of the people from the interview, not the API's field names.
|
|
12
|
+
3. **User control and freedom** — clearly marked exits. Every `Drawer` and `Popover` is dismissable (Esc, backdrop, visible
|
|
13
|
+
close); destructive actions get an undo or a confirm step — never both missing.
|
|
14
|
+
4. **Consistency and standards** — the same action looks the same everywhere; users' expectations come from every other
|
|
15
|
+
product they use (Jakob's Law). Using the library's components with their default semantics _is_ this heuristic; a second
|
|
16
|
+
hand-rolled pattern for something a component already does is a violation.
|
|
17
|
+
5. **Error prevention** — constraints and good defaults beat good error messages. Prefer `Select` over free text when options
|
|
18
|
+
are known; disable invalid actions instead of explaining them after the click; confirm before irreversible commitment.
|
|
19
|
+
6. **Recognition rather than recall** — keep options and context visible; don't force users to remember values across
|
|
20
|
+
screens. If step 2 needs a value from step 1, show it; that's what `Collapsible` summaries and persistent `Chip` labels
|
|
21
|
+
are for.
|
|
22
|
+
7. **Flexibility and efficiency of use** — accelerators for experts that novices never see. The interview's power-user answer
|
|
23
|
+
decides this: daily-use screens earn keyboard shortcuts and dense `Table` defaults.
|
|
24
|
+
8. **Aesthetic and minimalist design** — every extra element competes with the relevant ones. If a screen element doesn't
|
|
25
|
+
serve the primary action or the data, cut it — this is the design-side twin of "compose, don't configure."
|
|
26
|
+
9. **Help users recognize, diagnose, and recover from errors** — plain-language messages that state the problem precisely and
|
|
27
|
+
suggest the fix, in a `Callout` next to where it went wrong. "Something went wrong" is a violation, not a message.
|
|
28
|
+
10. **Help and documentation** — best if unneeded; when needed, contextual and task-focused. Prefer a one-line hint near the
|
|
29
|
+
control (not a `Tooltip` hiding essential information) over a help page.
|
|
@@ -1,22 +1,38 @@
|
|
|
1
|
-
# Visual design
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
1
|
+
# Visual design fundamentals
|
|
2
|
+
|
|
3
|
+
The 80/20 of making a functionally complete screen _look right_, distilled from NN/g's visual-hierarchy and Gestalt articles
|
|
4
|
+
([hierarchy](https://www.nngroup.com/articles/visual-hierarchy-ux-definition/),
|
|
5
|
+
[proximity](https://www.nngroup.com/articles/gestalt-proximity/),
|
|
6
|
+
[similarity](https://www.nngroup.com/articles/gestalt-similarity/)). Read when a screen works but looks wrong and you can't
|
|
7
|
+
say why — the answer is almost always in here.
|
|
8
|
+
|
|
9
|
+
## Hierarchy: decide the eye's order first
|
|
10
|
+
|
|
11
|
+
Visual hierarchy means the eye consumes elements in order of intended importance. Before styling anything, write down the
|
|
12
|
+
order: what should be seen first, second, third? Then make the styling agree. If you can't rank the elements, the screen has
|
|
13
|
+
an information-architecture problem, not a styling problem — go back to the interview's "one primary action."
|
|
14
|
+
|
|
15
|
+
- **Contrast creates hierarchy, not hue.** What advances is what contrasts with its context. The primary `Button` variant is
|
|
16
|
+
the contrast peak of the screen — which is why there's only one. Reserve warm, saturated signals (red) for errors/warnings,
|
|
17
|
+
never decoration.
|
|
18
|
+
- **Scale = importance.** The most important element is the biggest; keep at most two genuinely large elements per screen.
|
|
19
|
+
- **Limit variation, or nothing stands out.** At most ~3 contrast treatments and 3 type sizes per screen. `Typo`'s role
|
|
20
|
+
levels are this rule made concrete — if you're reaching past them, you're adding a fourth size that dilutes the other
|
|
21
|
+
three.
|
|
22
|
+
|
|
23
|
+
## Grouping: proximity beats everything
|
|
24
|
+
|
|
25
|
+
- **Proximity is grouping.** Elements close together read as one unit — this overpowers color and shape cues. Tight gap
|
|
26
|
+
between a label and its control, larger gap between one group and the next. Use `Stack` gap steps for exactly this: small
|
|
27
|
+
within groups, large between them. Never equidistant spacing — it says nothing.
|
|
28
|
+
- **Common region.** A shared container (`Card`, a bordered region) makes enclosed items read as related. Powerful, and
|
|
29
|
+
clutter when overused — if `Stack` spacing already groups it, the border adds nothing.
|
|
30
|
+
- **Similarity.** Shared color/shape/size signals relatedness across distance — all `Chip`s of one meaning look the same
|
|
31
|
+
everywhere. Weaker than proximity, but it survives layout changes.
|
|
32
|
+
|
|
33
|
+
## Whitespace and the squint test
|
|
34
|
+
|
|
35
|
+
More space around an element gives it more attention — whitespace is an active tool, not leftover room. Verify with the
|
|
36
|
+
squint test: blur your eyes (or downscale a screenshot); the primary action and the screen's title should still dominate. If
|
|
37
|
+
everything blurs into one gray mass, contrast and spacing are too uniform — pick the one thing that matters and make the
|
|
38
|
+
styling say so.
|
package/src/llms/tokens.gen.json
CHANGED
|
@@ -153,7 +153,7 @@
|
|
|
153
153
|
},
|
|
154
154
|
{
|
|
155
155
|
"name": "--imf-ui-color-bg-minor",
|
|
156
|
-
"value": "light-dark( oklch( calc(var(--imf-ui-color-surface-bg-luma-light) - 0.
|
|
156
|
+
"value": "light-dark( oklch( calc(var(--imf-ui-color-surface-bg-luma-light) - 0.075) var(--imf-ui-color-surface-chroma) var(--imf-ui-color-surface-minor-hue) ), oklch( calc(var(--imf-ui-color-surface-bg-luma-dark) + 0.075) var(--imf-ui-color-surface-chroma) var(--imf-ui-color-surface-minor-hue) ) )"
|
|
157
157
|
},
|
|
158
158
|
{
|
|
159
159
|
"name": "--imf-ui-color-bg-negative",
|
|
@@ -177,7 +177,7 @@
|
|
|
177
177
|
},
|
|
178
178
|
{
|
|
179
179
|
"name": "--imf-ui-color-bg-support",
|
|
180
|
-
"value": "light-dark( oklch( calc(var(--imf-ui-color-surface-bg-luma-light) - 0.
|
|
180
|
+
"value": "light-dark( oklch( calc(var(--imf-ui-color-surface-bg-luma-light) - 0.025) var(--imf-ui-color-surface-chroma) var(--imf-ui-color-surface-support-hue) ), oklch( calc(var(--imf-ui-color-surface-bg-luma-dark) + 0.025) var(--imf-ui-color-surface-chroma) var(--imf-ui-color-surface-support-hue) ) )"
|
|
181
181
|
},
|
|
182
182
|
{
|
|
183
183
|
"name": "--imf-ui-color-bg-warning",
|
|
@@ -285,7 +285,7 @@
|
|
|
285
285
|
},
|
|
286
286
|
{
|
|
287
287
|
"name": "--imf-ui-color-status-chroma",
|
|
288
|
-
"value": "0.
|
|
288
|
+
"value": "0.265"
|
|
289
289
|
},
|
|
290
290
|
{
|
|
291
291
|
"name": "--imf-ui-color-status-fg-luma-dark",
|
|
@@ -313,11 +313,11 @@
|
|
|
313
313
|
},
|
|
314
314
|
{
|
|
315
315
|
"name": "--imf-ui-color-surface-bg-luma-dark",
|
|
316
|
-
"value": "0.
|
|
316
|
+
"value": "0.27"
|
|
317
317
|
},
|
|
318
318
|
{
|
|
319
319
|
"name": "--imf-ui-color-surface-bg-luma-light",
|
|
320
|
-
"value": "0.
|
|
320
|
+
"value": "0.97"
|
|
321
321
|
},
|
|
322
322
|
{
|
|
323
323
|
"name": "--imf-ui-color-surface-chroma",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function writeCodeHighlightTheme(): void;
|