@imfusion/web-ui 0.6.4-dev.55.g47fb2f84 → 0.6.4-dev.58.g88c8fcaa

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 (58) hide show
  1. package/README.md +19 -54
  2. package/dist/assets/vendors/base-ui.d.ts +2 -3
  3. package/dist/breakpoints/min-width.d.ts +3 -7
  4. package/dist/breakpoints/registry.d.ts +3 -9
  5. package/dist/codegen/gen-breakpoints-css.d.ts +0 -4
  6. package/dist/codegen/gen-token-css.d.ts +0 -2
  7. package/dist/components/button/button.d.ts +1 -1
  8. package/dist/components/callout/callout.d.ts +7 -10
  9. package/dist/components/card/card.d.ts +2 -4
  10. package/dist/components/chip/chip.cva.d.ts +2 -4
  11. package/dist/components/code/code.d.ts +1 -1
  12. package/dist/components/logo/imfusion/imfusion.d.ts +1 -4
  13. package/dist/components/logo/logo.d.ts +1 -1
  14. package/dist/components/navigation-menu/subs/flyout-link.d.ts +3 -5
  15. package/dist/components/navigation-menu/subs/inline-submenu.d.ts +2 -4
  16. package/dist/components/navigation-menu/subs/trigger.d.ts +5 -7
  17. package/dist/components/number-field/number-field.d.ts +2 -3
  18. package/dist/components/select/select.d.ts +3 -3
  19. package/dist/components/stack/stack.d.ts +2 -3
  20. package/dist/components/table/table.d.ts +3 -5
  21. package/dist/components/tabs/tabs.d.ts +5 -8
  22. package/dist/components/tooltip/tooltip.d.ts +5 -8
  23. package/dist/components/typo/typo.d.ts +1 -3
  24. package/dist/docgen/gen-docgen.utils.d.ts +3 -4
  25. package/dist/hooks/use-color-scheme.d.ts +5 -11
  26. package/dist/hooks/use-media-query.d.ts +2 -7
  27. package/dist/integrations/image-display-options/image-display-options-view.utils.d.ts +0 -1
  28. package/dist/style.css +1 -1
  29. package/dist/tokens/apply.d.ts +4 -9
  30. package/dist/tokens/control-registry.d.ts +3 -6
  31. package/dist/tokens/types.d.ts +7 -24
  32. package/dist/tokens/use-token-controls.d.ts +3 -12
  33. package/dist/types/meta.d.ts +15 -32
  34. package/dist/vite/readable-css-module-names.d.ts +3 -12
  35. package/dist/web-ui-cli.js +322 -0
  36. package/docs/user-guide/AgentTooling.mdx +127 -0
  37. package/docs/user-guide/BrandAssets.mdx +25 -28
  38. package/docs/user-guide/GettingStarted.mdx +34 -19
  39. package/docs/user-guide/HowItsBuilt.mdx +92 -12
  40. package/docs/user-guide/Tokens.mdx +12 -10
  41. package/docs/user-guide/UsagePatterns.mdx +64 -21
  42. package/package.json +6 -5
  43. package/src/docgen/doc.gen.json +20 -20
  44. package/src/llms/install-templates/AGENTS.md +4 -4
  45. package/src/llms/install-templates/hooks/baseline-staleness.sh +9 -2
  46. package/src/llms/skills/imf-web-ui/SKILL.md +8 -9
  47. package/src/llms/skills/imf-web-ui-audit/SKILL.md +4 -4
  48. package/src/llms/skills/imf-web-ui-components/SKILL.md +3 -0
  49. package/src/llms/skills/imf-web-ui-conventions/templates/AUDIT_CHECKLIST.md +0 -1
  50. package/src/llms/skills/imf-web-ui-conventions/topics/agent-tooling.md +15 -10
  51. package/src/llms/skills/imf-web-ui-conventions/topics/git.md +2 -1
  52. package/src/llms/skills/imf-web-ui-conventions/topics/styling.md +1 -1
  53. package/src/llms/skills/imf-web-ui-conventions/topics/tooling.md +1 -1
  54. package/src/llms/skills/imf-web-ui-setup/SKILL.md +1 -1
  55. package/src/llms/skills/imf-web-ui-update/SKILL.md +15 -13
  56. package/bin/install.js +0 -446
  57. package/docs/user-guide/AiAgents.mdx +0 -51
  58. package/docs/user-guide/Introduction.mdx +0 -21
@@ -0,0 +1,127 @@
1
+ import { Meta } from "@storybook/addon-docs/blocks";
2
+
3
+ <Meta title="User Guide/Agent Tooling" />
4
+
5
+ # Agent tooling
6
+
7
+ The package ships skills and lifecycle hooks for coding agents working in a project that uses `@imfusion/web-ui`. Both are
8
+ optional, but highly recommended: the library is built to be set up and used through an agent.
9
+
10
+ ## Supported agents
11
+
12
+ The skills follow the [Agent Skills](https://agentskills.io/) standard and install into `.agents/skills/`. Project
13
+ instructions go into [`AGENTS.md`](https://agents.md/): when the project has one, the installer keeps a fenced Web UI block
14
+ in it up to date.
15
+
16
+ | Agent | Skills | `AGENTS.md` | Hooks |
17
+ | --- | --- | --- | --- |
18
+ | [Codex](https://developers.openai.com/codex/skills) | Reads `.agents/skills/` | [Reads it](https://developers.openai.com/codex/guides/agents-md) | [Supported](https://developers.openai.com/codex/hooks) |
19
+ | [Claude Code](https://code.claude.com/docs/en/skills) | Reads only `.claude/skills/`, so the installer links each skill there | [Reads it](https://code.claude.com/docs/en/changelog#2-1-277) when the project has no `CLAUDE.md`; otherwise add `@AGENTS.md` to `CLAUDE.md` | [Supported](https://code.claude.com/docs/en/hooks) |
20
+ | Other Agent Skills clients | Check the agent's docs for `.agents/skills/` | Check the agent's docs | Not installed |
21
+
22
+ The installer targets Codex and Claude Code. Other agents that implement the standard are listed on
23
+ [agentskills.io](https://agentskills.io/); one that reads `.agents/skills/` picks up the same skills, without the hooks.
24
+
25
+ ## Install
26
+
27
+ Install the package first, then run this in the project root:
28
+
29
+ ```sh
30
+ npx web-ui install skills --harness=all
31
+ npx web-ui install hooks --harness=all
32
+ ```
33
+
34
+ `--harness` picks the agent the tooling is installed for:
35
+
36
+ | Value | Installs for |
37
+ | --- | --- |
38
+ | `claude` | Claude Code |
39
+ | `codex` | Codex, and any agent that reads `.agents/skills/` |
40
+ | `all` | Both |
41
+
42
+ Without `--harness`, `install skills` prompts once and records the choice, and later runs reuse it. `install hooks` needs the
43
+ skills installed for the same harness first. Leave out the second command to install only the skills.
44
+
45
+ `npx web-ui --help` lists the commands, and `--help` on any subcommand lists its options.
46
+
47
+ ## Skills
48
+
49
+ `/imf-web-ui` is the router: the entry point for UI work and library questions. It routes usage questions to the packaged user
50
+ guides and development tasks to the matching companion skill, and it keeps small tasks small instead of loading every
51
+ reference just because the package is installed.
52
+
53
+ With the hooks installed, the agent is pointed at the router at the start of every session. Without them, the agent usually
54
+ picks it up from the skill's description; invoke it by name when it does not.
55
+
56
+ | Skill | Use it for |
57
+ | --- | --- |
58
+ | `/imf-web-ui` | The router: any UI task or library question. |
59
+ | `/imf-web-ui-components` | Component props, parts, defaults, and icons. |
60
+ | `/imf-web-ui-ux` | Choosing components and shaping screens or flows. |
61
+ | `/imf-web-ui-conventions` | Code, styling, data, validation, and project conventions. |
62
+ | `/imf-web-ui-setup` | First-time wiring and approved project setup. |
63
+ | `/imf-web-ui-audit` | A read-only check of an existing project. |
64
+ | `/imf-web-ui-update` | Updating the package and its installed tooling. |
65
+
66
+ ## Hooks
67
+
68
+ The hooks put the agent on the right skill at the right moment and ask it to verify the project after it edits source files:
69
+
70
+ | Event | What the hook does |
71
+ | --- | --- |
72
+ | `SessionStart` | Points the agent at the router once per session. |
73
+ | `SubagentStart` | Gives the same pointer to spawned agents. |
74
+ | `UserPromptSubmit` | Names the companion skills relevant to the prompt. |
75
+ | `Stop` | Asks for project verification after a turn edits source files. |
76
+
77
+ ## Keeping it current
78
+
79
+ Ask the agent to update the library, for example "Update @imfusion/web-ui". That runs `/imf-web-ui-update`, which installs
80
+ the newer package and refreshes the skills, hook scripts, and registrations to match it.
81
+
82
+ To do the same by hand, update the package, then run:
83
+
84
+ ```sh
85
+ npx web-ui install skills
86
+ npx web-ui install hooks
87
+ ```
88
+
89
+ Both reuse the recorded harness. Leave out the second command if the project skips hooks. Together they bring the installed
90
+ tooling in line with the package version and remove anything the package no longer ships.
91
+
92
+ ## Reference
93
+
94
+ ### Where the files go
95
+
96
+ - Skills: `.agents/skills/` for every harness. `claude` also links each skill from `.claude/skills/`.
97
+ - Hook scripts: `.agents/hooks/imf-web-ui/`.
98
+ - Hook registrations: `.claude/settings.json` for Claude Code, `.codex/hooks.json` for Codex.
99
+
100
+ ### Changing the harness
101
+
102
+ Pass a different `--harness`, or `--reconfigure` to get the prompt again. Dropping `claude` removes its `.claude/skills`
103
+ links. The next `install hooks` run removes the registrations from a harness that is no longer selected and adds them for the
104
+ newly selected one.
105
+
106
+ ### What the installer owns
107
+
108
+ The installer owns every skill directory named `imf-web-ui` or `imf-web-ui-*`. It overwrites and prunes those directories and
109
+ leaves every other skill alone, so a project must not put its own skills under that prefix.
110
+
111
+ Hook registrations merge into the chosen harness's file without touching unrelated entries. For each event, the installer
112
+ adds a shipped hook unless that same script is already registered there; other hooks on that event stay alongside it.
113
+
114
+ An agent reads the `agent-tooling` topic in the installed `imf-web-ui-conventions` skill before adapting a hook registration.
115
+
116
+ ### Codex trust
117
+
118
+ Codex only runs project hooks after the project is trusted and each script is approved through `/hooks`. Revisit that review
119
+ after a hook script changes. Claude Code has no equivalent trust gate.
120
+
121
+ ### Where the files come from
122
+
123
+ The skills ship inside the package under `src/llms/skills/`, and `web-ui install` copies them into the project. The package
124
+ also exposes generated component, token, and icon indexes for the lookup skill. User guides ship as readable MDX under
125
+ `docs/user-guide/`; agents read them from the installed package without a running Storybook.
126
+
127
+ <PageNav>Importing and composing components, then changing their look with tokens, CSS, and state attributes.</PageNav>
@@ -13,8 +13,8 @@ subpath:
13
13
  @imfusion/web-ui/assets/<folder>/<file>
14
14
  ```
15
15
 
16
- These are static files rather than components, so an application references them from its HTML head or copies them into its
17
- own output. Everything under the subpath is a real file on disk, which means a build step can resolve and copy it.
16
+ These are static files rather than components, so an application references them from its HTML head, copies them into its own
17
+ output, or resolves them on disk during its build.
18
18
 
19
19
  ## Files
20
20
 
@@ -43,26 +43,19 @@ the sides.
43
43
 
44
44
  <img src={ogUrl} alt="" width="480" style={{ display: "block", borderRadius: "0.5rem", margin: "1.5rem 0" }} />
45
45
 
46
- ## Regenerate the favicon files
46
+ ## Use the files
47
47
 
48
- `favicon.svg` is the source for every favicon variant. With [ImageMagick](https://imagemagick.org) installed, run this from
49
- `src/assets/public/favicon/` after changing the SVG:
48
+ Pick the method that matches how the application builds:
50
49
 
51
- ```sh
52
- for output in "favicon-16.png:16" "favicon-32.png:32" "apple-touch-icon.png:180" "icon-192.png:192" "icon-512.png:512"; do
53
- file=${output%%:*}
54
- size=${output##*:}
55
- magick -density 512 favicon.svg -resize "${size}x${size}" "png32:$file"
56
- done
50
+ | Method | Use it when | Public URLs |
51
+ | --- | --- | --- |
52
+ | [Vite plugin](#vite-plugin) | The application builds with Vite | Stable root paths such as `/favicon.ico` |
53
+ | [Copy step](#copy-step) | Another build system, or a static directory served as is | Whatever the copy target gives them |
54
+ | [Direct import](#direct-import) | One file used from application code, such as a manifest or an `<img>` | Hashed by the bundler |
57
55
 
58
- magick -density 512 favicon.svg -define icon:auto-resize=16,32,48 favicon.ico
59
- ```
60
-
61
- `og-image.png` is a separate 1200×630 social image.
56
+ ### Vite plugin
62
57
 
63
- ## Add the favicon to a Vite application
64
-
65
- Register the Vite plugin, then reference the stable root URLs from the document head:
58
+ Register the plugin, then reference the stable root URLs from the document head:
66
59
 
67
60
  ```ts
68
61
  import { defineConfig } from "vite";
@@ -83,23 +76,27 @@ export default defineConfig({
83
76
  The plugin serves the complete favicon set during development and emits it at the root of the build output. Give `og:image`
84
77
  an absolute URL. Chat and social applications fetch it from their own servers, so a relative path does not resolve.
85
78
 
86
- ### Other build systems
79
+ ### Copy step
80
+
81
+ Copy the files into the application's static-files directory during its build, then reference them from its HTML the same way
82
+ as above. Resolve the package path rather than hard-coding a path into `node_modules`:
87
83
 
88
- Copy the files into the application's static-files directory during its build. Resolve the package path rather than hard-coding
89
- a path into `node_modules`.
84
+ ```ts
85
+ import { dirname } from "node:path";
86
+ import { fileURLToPath } from "node:url";
87
+
88
+ const faviconDir = dirname(fileURLToPath(import.meta.resolve("@imfusion/web-ui/assets/favicon/favicon.svg")));
89
+ ```
90
90
 
91
- ## Import a single file in application code
91
+ ### Direct import
92
92
 
93
- A bundler can also take one file directly, which is useful for a manifest or an `<img>`:
93
+ A bundler can also take one file directly:
94
94
 
95
95
  ```ts
96
96
  import iconUrl from "@imfusion/web-ui/assets/favicon/icon-512.png";
97
97
  ```
98
98
 
99
99
  The bundler returns the asset's URL for use in application code. Vite also processes `index.html` and rewrites supported
100
- asset references there. Use the copy step above when the files need stable public filenames.
101
-
102
- ## Keycloak
100
+ asset references there. Use the plugin or the copy step when the files need stable public filenames.
103
101
 
104
- A Keycloak login theme reads its icons from its own `resources/` directory. Copy the favicon files in when building the theme
105
- and reference them from the theme's template, the same way as any other application.
102
+ <PageNav>Where behavior comes from, what Web UI adds on top, and why components are split into parts.</PageNav>
@@ -4,28 +4,43 @@ import { Meta } from "@storybook/addon-docs/blocks";
4
4
 
5
5
  # Getting started
6
6
 
7
- ## Install
7
+ `@imfusion/web-ui` is the shared React UI library for ImFusion web apps. It provides accessible primitives, ImFusion tokens,
8
+ and one public import surface.
9
+
10
+ The library is built to be set up and used through a coding agent. The recommended way to wire it up is to ask the agent,
11
+ rather than follow a manual walkthrough.
12
+
13
+ ## 1. Install the package
8
14
 
9
15
  ```sh
10
16
  npm install @imfusion/web-ui
11
17
  ```
12
18
 
13
- To try a local checkout instead:
19
+ The package requires React and React DOM 19 or newer.
14
20
 
15
- ```sh
16
- # from the web-ui repository
17
- npm pack
21
+ ## 2. Install the agent skills
18
22
 
19
- # from your application
20
- npm install /path/to/web-ui-0.0.0.tgz
23
+ ```sh
24
+ npx web-ui install skills --harness=all
25
+ npx web-ui install hooks --harness=all
21
26
  ```
22
27
 
23
- The package requires React and React DOM 19 or newer. Integrations have their own optional peer dependencies; their pages
24
- list them.
28
+ This installs the skills an agent uses to work with the library. The hooks point the agent at the right skill for each task
29
+ and ask it to verify the project after it edits source files. [Agent Tooling](./AgentTooling.mdx) covers the flags and what
30
+ each piece does.
31
+
32
+ ## 3. Ask the agent to set up the library
25
33
 
26
- ## Add the provider
34
+ Tell your agent, in plain language:
27
35
 
28
- Import the stylesheet and mount `WebUIProvider` once, near the application root:
36
+ > Set up @imfusion/web-ui in this project.
37
+
38
+ Behind the scenes this runs the setup skill, `/imf-web-ui-setup`. It proposes a plan and writes the wiring only after you
39
+ approve it.
40
+
41
+ ## 4. What the agent writes
42
+
43
+ For an existing project, the agent adds the stylesheet import and mounts `WebUIProvider` once, near the application root:
29
44
 
30
45
  ```tsx
31
46
  import "@imfusion/web-ui/styles.css";
@@ -42,14 +57,14 @@ export function App() {
42
57
 
43
58
  Import primitives from `@imfusion/web-ui`. Do not import Base UI components or styles directly.
44
59
 
45
- ## Add the favicon
60
+ An existing project that already has UI can also ask the agent for an audit. `/imf-web-ui-audit` checks the project against
61
+ the library's conventions and reports what it finds without changing any file.
62
+
63
+ For a new project, the same setup skill can also propose routing, an app shell, and other starter pieces. It writes only what
64
+ you approve.
46
65
 
47
- The package also ships the ImFusion favicon set and a social sharing image. See **Brand Assets** for the files and the
48
- `<link>` tags an application needs.
66
+ ## Without an agent
49
67
 
50
- ## Explore token controls
68
+ Make the same two changes yourself: install the package, then add the stylesheet import and `WebUIProvider` shown above.
51
69
 
52
- When exploring the library in Storybook, open `Tokens` in the top-right toolbar. The token showcase displays the controls in
53
- a sidebar on larger screens and a drawer on smaller screens, and changes update the preview live. The controls do not yet
54
- generate a copyable CSS override block. Apply the values you want in your application CSS, starting with `--imf-ui-*`
55
- variables.
70
+ <PageNav>Which agents the tooling supports, the skills it installs, and the hooks that point an agent at them.</PageNav>
@@ -4,30 +4,110 @@ import { Meta } from "@storybook/addon-docs/blocks";
4
4
 
5
5
  # How it's built
6
6
 
7
- You can use the library without knowing its implementation. This explains the boundary.
7
+ You can use the library without knowing its implementation. The snippets below are simplified from the library source.
8
8
 
9
9
  ## Behavior comes from an implementation library
10
10
 
11
- Adapted interactive primitives use Base UI for focus management, keyboard behavior, and accessibility details. Web UI owns the public
12
- props, defaults, tokens, styles, and exports.
11
+ Adapted interactive primitives use Base UI for focus management, keyboard behavior, and accessibility details. Web UI wraps
12
+ each part, takes its props from the upstream type, and adds its own class and identity:
13
13
 
14
- This split lets the implementation change without forcing a consumer migration.
14
+ ```tsx
15
+ import { Switch as Upstream } from "@base-ui/react/switch";
16
+
17
+ export function Root(props: React.ComponentProps<typeof Upstream.Root>) {
18
+ return <Upstream.Root {...props} data-imf-ui-component="Switch.Root" className={styles.root} />;
19
+ }
20
+ ```
21
+
22
+ Web UI owns the public props, defaults, tokens, styles, and exports. An application imports `Switch` from `@imfusion/web-ui`
23
+ and never sees `@base-ui/react`, so the implementation can change without forcing a consumer migration.
15
24
 
16
25
  ## Web UI is the styled middle layer
17
26
 
18
- Every primitive adds:
27
+ Between the implementation library and the application, Web UI adds the look. Styles are CSS Modules that read `--imf-ui-*`
28
+ tokens, and two mechanisms pick which rules apply: CVA for the props a consumer sets, and data attributes for the state a
29
+ component is in at runtime.
30
+
31
+ ### Variants with CVA
32
+
33
+ [class-variance-authority](https://cva.style/docs) (CVA) maps each variant prop to a CSS Module class. The defaults sit in
34
+ the component signature:
35
+
36
+ ```tsx
37
+ import { cva } from "class-variance-authority";
38
+ import classes from "./button.module.css";
39
+
40
+ const button = cva(classes.root, {
41
+ variants: {
42
+ variant: { primary: classes.variantPrimary, outline: classes.variantOutline },
43
+ size: { sm: classes.sizeSm, md: classes.sizeMd }
44
+ }
45
+ });
46
+
47
+ export function Button({ variant = "primary", size = "md", className, ...props }: Props) {
48
+ return <Upstream {...props} data-imf-ui-component="Button" className={button({ variant, size, className })} />;
49
+ }
50
+ ```
51
+
52
+ A consumer `className` joins the variant classes instead of replacing them.
53
+
54
+ ### Runtime state with data attributes
55
+
56
+ State that changes while the component runs, such as checked, open, or disabled, is not a prop to map. Base UI sets it as
57
+ [data attributes](https://base-ui.com/react/handbook/styling#style-hooks) on each part, like `data-checked` on
58
+ `Switch.Root`, and the stylesheet selects them:
19
59
 
20
- - `--imf-ui-*` tokens for the visual system.
21
- - `data-imf-ui-component` for a stable DOM identity.
22
- - CSS layers that let consumer styles override the defaults.
60
+ ```css
61
+ @layer imf-ui.components {
62
+ .root {
63
+ background: var(--imf-ui-color-bg-minor);
64
+ }
65
+
66
+ .root[data-checked] {
67
+ background: var(--imf-ui-color-bg-primary-main);
68
+ }
69
+ }
70
+ ```
71
+
72
+ Base UI's page for each component lists the attributes its parts expose.
73
+
74
+ ### Layers and tokens
75
+
76
+ Every rule sits in the `imf-ui.components` cascade layer. Unlayered CSS always beats layered CSS, so an application rule
77
+ wins without `!important`. The token changes the value everywhere; the rule changes one place:
78
+
79
+ ```css
80
+ :root {
81
+ --imf-ui-color-primary-hue: 30;
82
+ }
83
+
84
+ [data-imf-ui-component="Switch.Root"] {
85
+ border-radius: 0;
86
+ }
87
+ ```
23
88
 
24
89
  The wrapper keeps the upstream surface complete. If an upstream part or prop is useful, Web UI exposes it instead of making an
25
90
  app reach around the library.
26
91
 
27
92
  ## Compose parts
28
93
 
29
- Compound components use namespaces such as `Drawer.Root`, `Drawer.Trigger`, and `Drawer.Content`. This keeps behavior and
30
- layout composable without a component with a prop for every possible arrangement.
94
+ Compound components are namespaces of parts. Instead of one component with a prop for every arrangement, an application
95
+ renders the parts it needs, where it needs them:
96
+
97
+ ```tsx
98
+ // One component, one prop per arrangement:
99
+ <Field label="Study name" description="Shown in the reading queue." descriptionPosition="above" />
100
+
101
+ // Parts, arranged by the application:
102
+ <Field.Root>
103
+ <Field.Label>Study name</Field.Label>
104
+ <Field.Description>Shown in the reading queue.</Field.Description>
105
+ <Input name="study" />
106
+ </Field.Root>
107
+ ```
108
+
109
+ The first form is pseudo-code; Web UI ships only the second. The
110
+ [library-boundary topic](../../src/llms/skills/imf-web-ui-conventions/topics/library-boundary.md) has the consumer import and
111
+ composition rules.
31
112
 
32
- For consumer import and composition rules, read the packaged
33
- [library-boundary topic](../../src/llms/skills/imf-web-ui-conventions/topics/library-boundary.md).
113
+ <PageNav>The token families, the control tokens that change them, and how to try them live.</PageNav>
@@ -1,7 +1,6 @@
1
1
  import { Meta } from "@storybook/addon-docs/blocks";
2
- import { Typo } from "#/components/typo";
3
2
 
4
- <Meta title="User Guide/Tokens" />
3
+ <Meta title="Tokens/Overview" />
5
4
 
6
5
  # Tokens
7
6
 
@@ -36,8 +35,7 @@ Use a semantic token for a one-off role. That changes one result without changin
36
35
  | Shape | Radius and corner controls. |
37
36
  | Shadow | The shared elevation model. |
38
37
 
39
- The live token controls and exact names are on the
40
- <Typo.Link href="/?path=/story/user-guide-tokens-reference--reference" kind="internal" target="_top">token reference</Typo.Link>.
38
+ The live token controls and exact names are on the [token reference](../../src/tokens/token-reference.stories.tsx).
41
39
 
42
40
  ## Use semantic tokens in CSS
43
41
 
@@ -74,12 +72,16 @@ brand shape axis. Shadow controls share one lighting model across components:
74
72
  - `--imf-ui-shadow-intensity` sets the lowest-level opacity; higher levels add one point each.
75
73
  - `--imf-ui-shadow-color` sets the cast color per scheme.
76
74
 
77
- Components consume these values through tokens. The package's `src/llms/tokens.gen.json` lists the shipped token names and
78
- authored defaults.
75
+ Components consume these values through tokens. `node_modules/@imfusion/web-ui/src/llms/tokens.gen.json` lists the shipped
76
+ token names and authored defaults.
79
77
 
80
78
  ## Explore
81
79
 
82
- - <Typo.Link href="/?path=/story/user-guide-tokens-showcase--showcase" kind="internal" target="_top">Showcase</Typo.Link>
83
- applies the controls to real components.
84
- - <Typo.Link href="/?path=/story/user-guide-tokens-reference--reference" kind="internal" target="_top">Reference</Typo.Link>
85
- lists every generated token.
80
+ In Storybook, the Showcase and Reference pages show the token controls in a side panel on larger screens and behind the
81
+ `Tokens` button in the bottom-right corner on smaller ones. Other stories open the same drawer from that button. Changes
82
+ update the preview live; to keep a value, set that token in your application CSS.
83
+
84
+ - [Showcase](../../src/tokens/showcase.stories.tsx) applies the controls to real components.
85
+ - [Reference](../../src/tokens/token-reference.stories.tsx) lists every generated token.
86
+
87
+ <PageNav>What a primitive is, how compound parts compose, and what each component page shows.</PageNav>
@@ -4,28 +4,70 @@ import { Meta } from "@storybook/addon-docs/blocks";
4
4
 
5
5
  # Usage patterns
6
6
 
7
- ## Keep imports behind Web UI
7
+ ## Build with components
8
8
 
9
- Use the library's components, icons, styles, and provider. Do not import Base UI or another implementation package directly.
10
- That keeps the styling and public API consistent.
9
+ Import components and the provider from `@imfusion/web-ui`, and icons from `@imfusion/web-ui/icons`. Multi-part
10
+ primitives are namespaces: render the parts a screen needs, in the order the component documents.
11
11
 
12
- ## Compose parts
12
+ ```tsx
13
+ import { Field, Input } from "@imfusion/web-ui";
14
+
15
+ export function StudyName() {
16
+ return (
17
+ <Field.Root>
18
+ <Field.Label>Study name</Field.Label>
19
+ <Input name="study" />
20
+ <Field.Description>Shown in the reading queue.</Field.Description>
21
+ </Field.Root>
22
+ );
23
+ }
24
+ ```
13
25
 
14
- Multi-part primitives are namespaces. Render the parts you need:
26
+ The same pattern scales to an overlay. A drawer is a namespace too, and the field sits inside it unchanged:
15
27
 
16
28
  ```tsx
17
- <Drawer.Root>
18
- <Drawer.Trigger>Open</Drawer.Trigger>
19
- <Drawer.Content>…</Drawer.Content>
20
- </Drawer.Root>
29
+ import { Button, Drawer, Field, Input, Stack } from "@imfusion/web-ui";
30
+ import { Icon, Settings } from "@imfusion/web-ui/icons";
31
+
32
+ export function StudySettings() {
33
+ return (
34
+ <Drawer.Root>
35
+ <Drawer.Trigger render={<Button variant="secondary" startIcon={<Icon glyph={Settings} />}>Settings</Button>} />
36
+ <Drawer.Portal>
37
+ <Drawer.Backdrop />
38
+ <Drawer.Viewport>
39
+ <Drawer.Popup>
40
+ <Drawer.Content>
41
+ <Stack gap="4">
42
+ <Drawer.Title>Study settings</Drawer.Title>
43
+ <Field.Root>
44
+ <Field.Label>Study name</Field.Label>
45
+ <Input name="study" />
46
+ <Field.Description>Shown in the reading queue.</Field.Description>
47
+ </Field.Root>
48
+ <Drawer.Close render={<Button>Save</Button>} />
49
+ </Stack>
50
+ </Drawer.Content>
51
+ </Drawer.Popup>
52
+ </Drawer.Viewport>
53
+ </Drawer.Portal>
54
+ </Drawer.Root>
55
+ );
56
+ }
21
57
  ```
22
58
 
23
- All parts come from `@imfusion/web-ui`, including less common ones such as `Indent`, `SwipeArea`, and `Description`.
59
+ Every part comes from `@imfusion/web-ui`, including less common ones such as `Drawer.Indent`, `Drawer.SwipeArea`, and
60
+ `Field.Description`. Do not import Base UI or another implementation package directly; the library's parts carry the styles,
61
+ defaults, and stable identity that the rest of this page relies on.
62
+
63
+ ## Change the look
24
64
 
65
+ Start as broad as the change is, then narrow down: a token changes a whole family, a CSS rule changes one place, and a state
66
+ attribute changes one state.
25
67
 
26
- ## Change the look with tokens
68
+ ### With tokens
27
69
 
28
- When exploring the library in Storybook, use the `Tokens` controls in the top-right toolbar. On the token showcase, they appear as a sidebar on larger screens and a drawer on smaller screens, and changes update the preview live. The controls do not yet generate a copyable CSS override block. Apply the values you want in your application CSS, starting with `--imf-ui-*` variables. A control changes a related family of semantic tokens:
70
+ The theme is a set of `--imf-ui-*` custom properties. A control token changes a related family of semantic tokens at once:
29
71
 
30
72
  ```css
31
73
  :root {
@@ -33,7 +75,11 @@ When exploring the library in Storybook, use the `Tokens` controls in the top-ri
33
75
  }
34
76
  ```
35
77
 
36
- Use a semantic token for a local role. Consumer CSS outside `@layer imf-ui.components` overrides the library without `!important`:
78
+ [Tokens](./Tokens.mdx) lists the families, the controls, and how to try them live in Storybook.
79
+
80
+ ### With CSS
81
+
82
+ Consumer CSS outside `@layer imf-ui.components` overrides the library without `!important`:
37
83
 
38
84
  ```css
39
85
  .my-button {
@@ -43,24 +89,19 @@ Use a semantic token for a local role. Consumer CSS outside `@layer imf-ui.compo
43
89
 
44
90
  Components carry `data-imf-ui-component` on their roots, so it is a stable selector. CSS Module class names are internal.
45
91
 
46
- ## Style state with data attributes
92
+ ### By state
47
93
 
48
94
  Components expose runtime state through attributes such as `data-checked`, `data-disabled`, and `data-popup-open`:
49
95
 
50
96
  ```css
51
- [data-imf-ui-component="Switch"][data-checked] {
97
+ [data-imf-ui-component="Switch.Root"][data-checked] {
52
98
  outline: var(--imf-ui-border-size-2) solid var(--imf-ui-color-fg-positive);
53
99
  }
54
100
  ```
55
101
 
56
102
  Use the attribute instead of maintaining a second state class.
57
103
 
58
- ## Choose variants locally
59
-
60
- A `variant` prop belongs to the component that defines it. `brand` means identity color; `primary` means the action color.
61
- They may look related, but one component's variant list is not a global list.
62
-
63
- ## Color schemes
104
+ ### By color scheme
64
105
 
65
106
  `WebUIProvider` sets `data-imf-ui-color-scheme="light"` or `"dark"` on `<html>`. Select it when an application rule needs to
66
107
  change with the scheme:
@@ -77,3 +118,5 @@ component colors cannot disagree with them:
77
118
  ```tsx
78
119
  <WebUIProvider colorScheme="dark">{children}</WebUIProvider>
79
120
  ```
121
+
122
+ <PageNav>The favicon set and social sharing image the package ships, and three ways to put them in an application.</PageNav>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imfusion/web-ui",
3
- "version": "0.6.4-dev.55.g47fb2f84",
3
+ "version": "0.6.4-dev.58.g88c8fcaa",
4
4
  "description": "The official Web UI component library for ImFusion web apps",
5
5
  "author": "ImFusion GmbH",
6
6
  "homepage": "https://imfusion.com",
@@ -20,7 +20,7 @@
20
20
  "module": "./dist/index.js",
21
21
  "types": "./dist/index.d.ts",
22
22
  "bin": {
23
- "web-ui-install": "bin/install.js"
23
+ "web-ui": "dist/web-ui-cli.js"
24
24
  },
25
25
  "exports": {
26
26
  ".": {
@@ -56,14 +56,13 @@
56
56
  "src/llms/llms.gen.txt",
57
57
  "src/llms/icon-catalog.gen.json",
58
58
  "src/llms/tokens.gen.json",
59
- "src/llms/skills",
60
- "bin/install.js"
59
+ "src/llms/skills"
61
60
  ],
62
61
  "scripts": {
63
62
  "dev": "tsx scripts/dev.ts",
64
63
  "dev:host": "tsx scripts/dev.ts --host",
65
64
  "dev:lib": "concurrently -n codegen,lib -c yellow,blue \"npm run codegen:watch\" \"vite build --watch\"",
66
- "build": "npm run codegen && rm -rf dist && vite build && npm run codegen:docgen && npm run codegen:llms && npm run codegen:tokens",
65
+ "build": "npm run codegen && rm -rf dist && vite build && chmod +x dist/web-ui-cli.js && npm run codegen:docgen && npm run codegen:llms && npm run codegen:tokens",
67
66
  "build:storybook": "npm run codegen:storybook && storybook build",
68
67
  "ci:status": "teamcity run list --job WebSDK_WebUI_BuildTest --limit 3 --json=id,number,status,state,branchName,buildType.name,triggered.type,triggered.user.name,startDate,finishDate,webUrl | tsx scripts/ci-status.ts",
69
68
  "storybook": "npm run codegen:storybook && storybook dev -p 6006 --no-open --ci",
@@ -119,6 +118,7 @@
119
118
  "@base-ui/react": "1.6.0",
120
119
  "@clack/prompts": "1.7.0",
121
120
  "class-variance-authority": "0.7.1",
121
+ "commander": "15.0.0",
122
122
  "iconoir-react": "7.12.1"
123
123
  },
124
124
  "devDependencies": {
@@ -152,6 +152,7 @@
152
152
  "jiti": "2.7.0",
153
153
  "knip": "6.14.2",
154
154
  "lightningcss": "1.32.0",
155
+ "mermaid": "12.0.0",
155
156
  "playwright": "1.60.0",
156
157
  "prettier": "3.8.3",
157
158
  "react-docgen-typescript": "2.4.0",