@imfusion/web-ui 0.6.1-dev.3.g8b2855c3 → 0.6.1-dev.33.g665111df

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.
Files changed (60) hide show
  1. package/README.md +102 -169
  2. package/bin/install.js +28 -10
  3. package/bin/install.test.ts +19 -0
  4. package/dist/code-BFMQnmu9.js +147 -0
  5. package/dist/codegen/gen-code-highlight-theme.d.ts +1 -0
  6. package/dist/components/code/code.d.ts +5 -4
  7. package/dist/components/stack/stack.d.ts +1 -1
  8. package/dist/components/toast/index.d.ts +2 -0
  9. package/dist/components/toast/toast.d.ts +200 -0
  10. package/dist/components/toast/toast.meta.d.ts +2 -0
  11. package/dist/components/typo/typo.d.ts +23 -22
  12. package/dist/icons/icon-config.d.ts +12 -0
  13. package/dist/{icons-wBmF0U2x.js → icons-Cy1HAosO.js} +1 -1
  14. package/dist/icons.js +1 -1
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.js +1278 -1069
  17. package/dist/integrations/code-highlight/highlighter.d.ts +24 -0
  18. package/dist/integrations/code-highlight.js +80 -47
  19. package/dist/integrations/image-display-options.js +2 -2
  20. package/dist/provider/web-ui-provider.d.ts +3 -3
  21. package/dist/style.css +1 -1
  22. package/dist/{tabs-CMKvMF4E.js → tabs-DIe1Utiy.js} +2 -0
  23. package/package.json +5 -4
  24. package/src/docgen/doc.gen.json +515 -1
  25. package/src/llms/install-templates/AGENTS.md +15 -18
  26. package/src/llms/llms.gen.txt +39 -33
  27. package/src/llms/skills/imf-web-ui/SKILL.md +30 -39
  28. package/src/llms/skills/imf-web-ui-audit/SKILL.md +50 -102
  29. package/src/llms/skills/imf-web-ui-components/SKILL.md +47 -104
  30. package/src/llms/skills/imf-web-ui-conventions/SKILL.md +44 -52
  31. package/src/llms/skills/imf-web-ui-conventions/templates/AUDIT_CHECKLIST.md +1 -0
  32. package/src/llms/skills/imf-web-ui-conventions/topics/agent-tooling.md +40 -62
  33. package/src/llms/skills/imf-web-ui-conventions/topics/assets.md +11 -12
  34. package/src/llms/skills/imf-web-ui-conventions/topics/authentication.md +31 -46
  35. package/src/llms/skills/imf-web-ui-conventions/topics/class-names.md +18 -23
  36. package/src/llms/skills/imf-web-ui-conventions/topics/components.md +20 -69
  37. package/src/llms/skills/imf-web-ui-conventions/topics/data.md +50 -146
  38. package/src/llms/skills/imf-web-ui-conventions/topics/docs-structure.md +17 -23
  39. package/src/llms/skills/imf-web-ui-conventions/topics/git.md +15 -20
  40. package/src/llms/skills/imf-web-ui-conventions/topics/library-boundary.md +28 -19
  41. package/src/llms/skills/imf-web-ui-conventions/topics/library-setup.md +20 -16
  42. package/src/llms/skills/imf-web-ui-conventions/topics/npm-project.md +28 -42
  43. package/src/llms/skills/imf-web-ui-conventions/topics/project-structure.md +28 -30
  44. package/src/llms/skills/imf-web-ui-conventions/topics/react.md +28 -74
  45. package/src/llms/skills/imf-web-ui-conventions/topics/styling.md +65 -62
  46. package/src/llms/skills/imf-web-ui-conventions/topics/testing.md +12 -14
  47. package/src/llms/skills/imf-web-ui-conventions/topics/tokens.md +9 -4
  48. package/src/llms/skills/imf-web-ui-conventions/topics/tooling.md +40 -68
  49. package/src/llms/skills/imf-web-ui-conventions/topics/typescript.md +26 -50
  50. package/src/llms/skills/imf-web-ui-conventions/topics/validation.md +19 -25
  51. package/src/llms/skills/imf-web-ui-setup/SKILL.md +45 -64
  52. package/src/llms/skills/imf-web-ui-update/SKILL.md +48 -114
  53. package/src/llms/skills/imf-web-ui-ux/SKILL.md +64 -92
  54. package/src/llms/skills/imf-web-ui-ux/references/forms.md +16 -36
  55. package/src/llms/skills/imf-web-ui-ux/references/usability-heuristics.md +14 -27
  56. package/src/llms/skills/imf-web-ui-ux/references/visual-design.md +22 -38
  57. package/src/llms/tokens.gen.json +5 -5
  58. package/dist/code-Blo48PGr.js +0 -136
  59. package/dist/icons/icon-config-provider.d.ts +0 -8
  60. 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: 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."
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
- # 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.
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. 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.
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
- ## Base update
28
+ ## Update the base
43
29
 
44
- In a non-dry run, update the dependency:
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
- 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.
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
- Classify paths as:
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
- - **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.
46
+ ## Verify the base update
79
47
 
80
- On conflict, stop. Never use `git restore`, `git reset`, `git clean`, or broad staging to hide it.
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 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.
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
- 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.
54
+ Check the dependency and lockfile, skill markers, `AGENTS.md` fence, hook registrations, and final update-owned path list.
90
55
 
91
- ## Base update report and approval
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> / would update
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 : <imperative message or not proposed>
67
+ Commit : <message or not proposed>
105
68
  ```
106
69
 
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.
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
- 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.
73
+ ## Audit the consumer migration
140
74
 
141
- ## Migration approval
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
- 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.
79
+ Report separately:
145
80
 
146
- ## Commit
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
- For the base update, after approval:
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
- 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.
88
+ Ask whether to run `imf-web-ui-audit full`. Run it only after an explicit yes.
155
89
 
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.
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
- "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)."
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
- # 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
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
- ## Experimental components
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
- 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.
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
- ## Deep dives
69
+ ## Keep custom UI native
94
70
 
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:
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
- - [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.
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
- 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.
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
- - **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.
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
- - **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.
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
- - **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.
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
- - 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)).
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, applied
1
+ # Usability heuristics
2
2
 
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.
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. **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.
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 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.
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.
@@ -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.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) ) )"
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.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) ) )"
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.265"
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.27"
316
+ "value": "0.205"
317
317
  },
318
318
  {
319
319
  "name": "--imf-ui-color-surface-bg-luma-light",
320
- "value": "0.97"
320
+ "value": "0.995"
321
321
  },
322
322
  {
323
323
  "name": "--imf-ui-color-surface-chroma",