@imfusion/web-ui 0.6.1-dev.6.g4adc5c3e → 0.6.1
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/LICENSE.txt +30 -0
- package/README.md +104 -171
- package/THIRD_PARTY_NOTICES.md +34 -0
- package/bin/install.js +28 -10
- package/dist/code-BFMQnmu9.js +147 -0
- package/dist/codegen/gen-code-highlight-theme.d.ts +1 -0
- package/dist/components/code/code.d.ts +5 -4
- package/dist/components/stack/stack.d.ts +1 -1
- package/dist/components/toast/index.d.ts +2 -0
- package/dist/components/toast/toast.d.ts +200 -0
- package/dist/components/toast/toast.meta.d.ts +2 -0
- package/dist/components/typo/typo.d.ts +23 -22
- package/dist/icons/icon-config.d.ts +12 -0
- package/dist/{icons-wBmF0U2x.js → icons-Cy1HAosO.js} +1 -1
- package/dist/icons.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1278 -1069
- package/dist/integrations/code-highlight/highlighter.d.ts +24 -0
- package/dist/integrations/code-highlight.js +80 -47
- 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-CMKvMF4E.js → tabs-DIe1Utiy.js} +2 -0
- package/docs/assets/imfusion-banner.svg +16 -0
- package/package.json +15 -8
- package/src/docgen/doc.gen.json +515 -1
- package/src/llms/install-templates/AGENTS.md +15 -18
- package/src/llms/llms.gen.txt +39 -33
- package/src/llms/skills/imf-web-ui/SKILL.md +30 -39
- package/src/llms/skills/imf-web-ui-audit/SKILL.md +50 -102
- package/src/llms/skills/imf-web-ui-components/SKILL.md +47 -104
- package/src/llms/skills/imf-web-ui-conventions/SKILL.md +44 -52
- package/src/llms/skills/imf-web-ui-conventions/templates/AUDIT_CHECKLIST.md +1 -0
- package/src/llms/skills/imf-web-ui-conventions/topics/agent-tooling.md +40 -62
- package/src/llms/skills/imf-web-ui-conventions/topics/assets.md +11 -12
- package/src/llms/skills/imf-web-ui-conventions/topics/authentication.md +31 -46
- package/src/llms/skills/imf-web-ui-conventions/topics/class-names.md +18 -23
- package/src/llms/skills/imf-web-ui-conventions/topics/components.md +20 -69
- package/src/llms/skills/imf-web-ui-conventions/topics/data.md +50 -146
- package/src/llms/skills/imf-web-ui-conventions/topics/docs-structure.md +17 -23
- package/src/llms/skills/imf-web-ui-conventions/topics/git.md +15 -20
- package/src/llms/skills/imf-web-ui-conventions/topics/library-boundary.md +28 -19
- package/src/llms/skills/imf-web-ui-conventions/topics/library-setup.md +20 -16
- package/src/llms/skills/imf-web-ui-conventions/topics/npm-project.md +28 -42
- package/src/llms/skills/imf-web-ui-conventions/topics/project-structure.md +28 -30
- package/src/llms/skills/imf-web-ui-conventions/topics/react.md +28 -74
- package/src/llms/skills/imf-web-ui-conventions/topics/styling.md +65 -62
- package/src/llms/skills/imf-web-ui-conventions/topics/testing.md +12 -14
- package/src/llms/skills/imf-web-ui-conventions/topics/tokens.md +9 -4
- package/src/llms/skills/imf-web-ui-conventions/topics/tooling.md +40 -68
- package/src/llms/skills/imf-web-ui-conventions/topics/typescript.md +26 -50
- package/src/llms/skills/imf-web-ui-conventions/topics/validation.md +19 -25
- package/src/llms/skills/imf-web-ui-setup/SKILL.md +45 -64
- package/src/llms/skills/imf-web-ui-update/SKILL.md +48 -114
- package/src/llms/skills/imf-web-ui-ux/SKILL.md +64 -92
- package/src/llms/skills/imf-web-ui-ux/references/forms.md +16 -36
- package/src/llms/skills/imf-web-ui-ux/references/usability-heuristics.md +14 -27
- package/src/llms/skills/imf-web-ui-ux/references/visual-design.md +22 -38
- package/src/llms/tokens.gen.json +5 -5
- package/bin/install.test.ts +0 -329
- package/dist/code-Blo48PGr.js +0 -136
- package/dist/icons/icon-config-provider.d.ts +0 -8
- package/dist/icons/icon-context.d.ts +0 -4
|
@@ -1,157 +1,91 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: imf-web-ui-update
|
|
3
3
|
description:
|
|
4
|
-
"Update @imfusion/web-ui in a consumer repository
|
|
5
|
-
|
|
4
|
+
"Update @imfusion/web-ui in a consumer repository. Use this whenever a consumer needs a newer package, installed skills, or
|
|
5
|
+
lifecycle hooks. Refresh the base first, verify it, then audit any consumer migration separately. Preserve user work and
|
|
6
|
+
get approval before each commit."
|
|
6
7
|
argument-hint: "[--dry-run] [optional version or reason]"
|
|
7
8
|
allowed-tools: Bash Read Grep
|
|
8
9
|
---
|
|
9
10
|
|
|
10
|
-
#
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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.
|
|
11
|
+
# Update Web UI
|
|
12
|
+
|
|
13
|
+
This workflow has two possible commits: the package/tooling update, then an optional consumer migration. Keep them separate.
|
|
14
|
+
Never overwrite user changes or commit without fresh approval.
|
|
33
15
|
|
|
34
16
|
## Preflight
|
|
35
17
|
|
|
36
|
-
1.
|
|
37
|
-
2.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
18
|
+
1. Work from the frontend package root. In a monorepo, find the package that owns the Web UI dependency.
|
|
19
|
+
2. Read its `package.json`, lockfile, and repository instructions. npm with `package-lock.json` is the expected setup; stop
|
|
20
|
+
if another lockfile is the active one.
|
|
21
|
+
3. Record `git status --short`, the installed Web UI version, the installed skill targets, hooks, registrations, and
|
|
22
|
+
`AGENTS.md` fence.
|
|
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.
|
|
41
27
|
|
|
42
|
-
##
|
|
28
|
+
## Update the base
|
|
43
29
|
|
|
44
|
-
|
|
30
|
+
Run from the consumer package root:
|
|
45
31
|
|
|
46
32
|
```sh
|
|
47
33
|
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
|
|
56
34
|
npx web-ui-install
|
|
57
35
|
npx web-ui-install --hooks
|
|
58
36
|
```
|
|
59
37
|
|
|
60
|
-
|
|
61
|
-
|
|
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.
|
|
38
|
+
Use `npm install @imfusion/web-ui@<version>` when the user supplied an explicit version. Stop on install failure. Preserve
|
|
39
|
+
the installer's existing target. Do not use `--force` or `--legacy-peer-deps`.
|
|
73
40
|
|
|
74
|
-
|
|
41
|
+
The installer owns the vendored skills, its `AGENTS.md` fence, and hook scripts. Run both installer commands after the
|
|
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.
|
|
75
45
|
|
|
76
|
-
|
|
77
|
-
- **Held back:** pre-existing user changes, excluded from the commit.
|
|
78
|
-
- **Conflict:** an overlapping pre-existing change, ambiguous target, or unexpected changed path.
|
|
46
|
+
## Verify the base update
|
|
79
47
|
|
|
80
|
-
|
|
48
|
+
After every mutating command, compare the status with the preflight snapshot. Stop on an unexpected path or overlapping
|
|
49
|
+
change.
|
|
81
50
|
|
|
82
|
-
Run the
|
|
83
|
-
|
|
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.
|
|
51
|
+
Run the consumer's documented full verification. Read its scripts first; prefer an aggregate check, otherwise run the
|
|
52
|
+
non-watch format, lint, typecheck, test, and build commands that exist.
|
|
87
53
|
|
|
88
|
-
|
|
89
|
-
dry-run mode, say that mutation-dependent checks were skipped.
|
|
54
|
+
Check the dependency and lockfile, skill markers, `AGENTS.md` fence, hook registrations, and final update-owned path list.
|
|
90
55
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
Before the base commit, show this concise report:
|
|
56
|
+
Report before the first commit:
|
|
94
57
|
|
|
95
58
|
```text
|
|
96
59
|
@imfusion/web-ui update report
|
|
97
|
-
Package : <old> -> <new>
|
|
60
|
+
Package : <old> -> <new>
|
|
98
61
|
Skills : <status>
|
|
99
62
|
Hooks : <status>
|
|
100
63
|
Verification : <status>
|
|
101
64
|
Update files : <paths>
|
|
102
65
|
Held back : <paths or none>
|
|
103
66
|
Conflicts : <paths or none>
|
|
104
|
-
Commit : <
|
|
67
|
+
Commit : <message or not proposed>
|
|
105
68
|
```
|
|
106
69
|
|
|
107
|
-
|
|
108
|
-
|
|
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.
|
|
70
|
+
Ask: **Approve these update-owned changes and commit them?** Stage only approved update paths and follow the repository's
|
|
71
|
+
commit workflow.
|
|
136
72
|
|
|
137
|
-
|
|
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.
|
|
73
|
+
## Audit the consumer migration
|
|
140
74
|
|
|
141
|
-
|
|
75
|
+
Start this phase only after the base update commit exists. Use the pre-update package metadata as the comparison baseline;
|
|
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.
|
|
142
78
|
|
|
143
|
-
|
|
144
|
-
answer. The migration approval is not implied by approval of the base update.
|
|
79
|
+
Report separately:
|
|
145
80
|
|
|
146
|
-
|
|
81
|
+
- compatibility fixes required by changed imports or types;
|
|
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.
|
|
147
84
|
|
|
148
|
-
|
|
85
|
+
Do not infer a replacement from a name. Inspect the implementation, styles, and call sites. If there are no findings, say so
|
|
86
|
+
and do not make an empty migration commit.
|
|
149
87
|
|
|
150
|
-
|
|
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.
|
|
88
|
+
Ask whether to run `imf-web-ui-audit full`. Run it only after an explicit yes.
|
|
155
89
|
|
|
156
|
-
For
|
|
157
|
-
|
|
90
|
+
For approved migration work, ask: **Approve these consumer migration changes and commit them separately?** Then stage only
|
|
91
|
+
the approved paths, verify again, and use a separate imperative commit message.
|
|
@@ -1,103 +1,75 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: imf-web-ui-ux
|
|
3
3
|
description:
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
flow, or feature UI — not for prop lookups (that's imf-web-ui-components)."
|
|
4
|
+
"Help shape screens and flows with @imfusion/web-ui. Use this whenever a task chooses between components, defines layout,
|
|
5
|
+
or needs empty/loading/error states, even when the user asks only for an implementation. Do not use it for a prop lookup."
|
|
7
6
|
---
|
|
8
7
|
|
|
9
|
-
#
|
|
10
|
-
|
|
11
|
-
|
|
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
|
|
8
|
+
# Shape the screen
|
|
9
|
+
|
|
10
|
+
Use this skill for screen-level decisions. Verify component APIs with `imf-web-ui-components`; put code and styling rules in
|
|
85
11
|
`imf-web-ui-conventions`.
|
|
86
12
|
|
|
87
|
-
|
|
13
|
+
The identity index marks components as stable or experimental. Experimental components are usable, but prefer wrapping one
|
|
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:
|
|
88
63
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
64
|
+
- **Empty**: say what belongs here and what the user can do next.
|
|
65
|
+
- **Loading**: use `Spinner` or a stable skeleton; keep the frame from jumping.
|
|
66
|
+
- **Error**: explain what failed and the next action in a `Callout` near the problem.
|
|
67
|
+
- **Loaded**: the normal view.
|
|
92
68
|
|
|
93
|
-
##
|
|
69
|
+
## Keep custom UI native
|
|
94
70
|
|
|
95
|
-
|
|
96
|
-
|
|
71
|
+
When the library does not cover a piece, compose its primitives and use `--imf-ui-*` tokens. The implementation details are
|
|
72
|
+
in `imf-web-ui-conventions`.
|
|
97
73
|
|
|
98
|
-
|
|
99
|
-
|
|
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.
|
|
74
|
+
For a screen review, read the relevant reference under `references/`: `usability-heuristics.md`, `visual-design.md`, or
|
|
75
|
+
`forms.md`.
|
|
@@ -1,50 +1,30 @@
|
|
|
1
1
|
# Form UX
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
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.
|
|
3
|
+
Read this before building a form with more than two fields. The library supplies controls; the form library owns state and
|
|
4
|
+
validation. These rules cover structure and feedback.
|
|
13
5
|
|
|
14
6
|
## Structure
|
|
15
7
|
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
|
|
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.
|
|
8
|
+
- Remove fields that can be derived or asked later.
|
|
9
|
+
- Use one column by default. Put short, inseparable values such as city and postal code in a `Row`.
|
|
10
|
+
- Group related fields in a `Stack` and separate groups with more space.
|
|
11
|
+
- Use a labeled `Fieldset` or heading for each group.
|
|
12
|
+
- Match a field's size to the value it expects.
|
|
25
13
|
|
|
26
14
|
## Labels
|
|
27
15
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
errors. Persistent hints (format examples) go outside the field, stated _before_ the user types, not revealed by the error
|
|
31
|
-
afterward.
|
|
16
|
+
Use a visible `<label>` close to the control, usually above it. Do not use placeholder text as the only label. Put format
|
|
17
|
+
hints near the field before the user starts typing.
|
|
32
18
|
|
|
33
19
|
## Validation and errors
|
|
34
20
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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.
|
|
21
|
+
Validate when the user finishes a field, except where live feedback genuinely helps, such as password requirements. Keep the
|
|
22
|
+
error next to the field and use more than color to show it.
|
|
23
|
+
|
|
24
|
+
An error says what is wrong and how to fix it. Keep the user's input. A server or form-level failure belongs in a `Callout`
|
|
25
|
+
near the actions; field-level failures stay with their fields.
|
|
45
26
|
|
|
46
27
|
## Submission
|
|
47
28
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
form (see also heuristic 9 in [usability-heuristics.md](usability-heuristics.md)).
|
|
29
|
+
Use one primary `Button` whose label names the result, such as `Create project`. While submitting, keep the form visible and
|
|
30
|
+
show progress. A failed submission must leave the user's input on screen.
|
|
@@ -1,29 +1,16 @@
|
|
|
1
|
-
# Usability heuristics
|
|
1
|
+
# Usability heuristics
|
|
2
2
|
|
|
3
|
-
Nielsen's ten
|
|
4
|
-
|
|
5
|
-
when reviewing or reworking a flow. Each entry: the rule, then what it means in a web-ui app.
|
|
3
|
+
Use this checklist when reviewing a screen or flow. It is an application of Nielsen's ten heuristics, not a replacement for
|
|
4
|
+
user research.
|
|
6
5
|
|
|
7
|
-
1. **
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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.
|
|
6
|
+
1. **Show system status.** Give async actions visible progress and confirmation.
|
|
7
|
+
2. **Use the user's language.** Labels and ordering should match the domain, not an API's private names.
|
|
8
|
+
3. **Provide an exit.** Drawers and popovers need clear dismissal; destructive actions need confirmation or undo.
|
|
9
|
+
4. **Be consistent.** Reuse the library's established components and semantics.
|
|
10
|
+
5. **Prevent errors.** Constrain known choices and disable actions that cannot work.
|
|
11
|
+
6. **Support recognition.** Keep relevant options and context visible instead of making users remember them.
|
|
12
|
+
7. **Support frequent users.** Add keyboard shortcuts or dense layouts when the task is frequent and data-heavy.
|
|
13
|
+
8. **Remove decoration without a job.** Every element should support the action or the data.
|
|
14
|
+
9. **Make errors recoverable.** Say what failed and what to do next, near the problem.
|
|
15
|
+
10. **Keep help contextual.** Prefer a short hint beside a control to essential information hidden in a tooltip or separate
|
|
16
|
+
page.
|
|
@@ -1,38 +1,22 @@
|
|
|
1
|
-
# Visual design
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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.
|
|
1
|
+
# Visual design
|
|
2
|
+
|
|
3
|
+
Use this when a screen works but still looks wrong. Decide the hierarchy before choosing styles.
|
|
4
|
+
|
|
5
|
+
## Hierarchy
|
|
6
|
+
|
|
7
|
+
Write the intended order of attention: title, primary action, content, and supporting details. Use contrast and scale to make
|
|
8
|
+
that order visible. Keep variation limited; if everything is loud, nothing leads.
|
|
9
|
+
|
|
10
|
+
Reserve saturated status colors for meaning. The primary `Button` should be the strongest action treatment on the screen.
|
|
11
|
+
|
|
12
|
+
## Grouping
|
|
13
|
+
|
|
14
|
+
Use proximity first: tight gaps inside a group, larger gaps between groups. `Stack` gap values encode this relationship. Use
|
|
15
|
+
a shared `Card` or bordered region only when spacing alone does not make the relationship clear.
|
|
16
|
+
|
|
17
|
+
Similarity helps related elements stay recognisable across a layout. It supports proximity; it does not replace it.
|
|
18
|
+
|
|
19
|
+
## Whitespace
|
|
20
|
+
|
|
21
|
+
Space around an element gives it attention. Shrink or blur a screenshot as a quick check: the title and primary action should
|
|
22
|
+
still stand out. If the screen becomes one grey mass, its contrast and spacing are too even.
|
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.04) var(--imf-ui-color-surface-chroma) var(--imf-ui-color-surface-minor-hue) ), oklch( calc(var(--imf-ui-color-surface-bg-luma-dark) + 0.04) 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.02) var(--imf-ui-color-surface-chroma) var(--imf-ui-color-surface-support-hue) ), oklch( calc(var(--imf-ui-color-surface-bg-luma-dark) + 0.02) 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.225"
|
|
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.205"
|
|
317
317
|
},
|
|
318
318
|
{
|
|
319
319
|
"name": "--imf-ui-color-surface-bg-luma-light",
|
|
320
|
-
"value": "0.
|
|
320
|
+
"value": "0.995"
|
|
321
321
|
},
|
|
322
322
|
{
|
|
323
323
|
"name": "--imf-ui-color-surface-chroma",
|