@imfusion/web-ui 0.6.4-dev.45.gbaffa741 → 0.6.4-dev.48.g1cf34297

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -50,12 +50,12 @@ npx web-ui-install
50
50
  Run the command again after updating the package. It refreshes the skills already installed in the project. Use
51
51
  `--reconfigure` to choose a different target. Add `--hooks` to install the lifecycle hooks for Claude Code and Codex.
52
52
 
53
- Start with `/imf-web-ui`. It routes a task to the companion skills it needs, or tells the agent to work without extra
54
- guidance.
53
+ Start with `/imf-web-ui`. It routes library questions to the packaged user guides and UI work to the companion skills it
54
+ needs. Agents read the guides from `node_modules/@imfusion/web-ui/docs/user-guide/` without a running Storybook.
55
55
 
56
56
  | Skill | Use it for |
57
57
  | ------------------------- | ------------------------------------------------------------ |
58
- | `/imf-web-ui` | Route UI work to the right companion. |
58
+ | `/imf-web-ui` | Route UI work and library questions to skills and guides. |
59
59
  | `/imf-web-ui-setup` | Plan library wiring, project setup, or tooling changes. |
60
60
  | `/imf-web-ui-components` | Look up component and icon APIs. |
61
61
  | `/imf-web-ui-ux` | Choose components and shape screens and flows. |
@@ -0,0 +1,3 @@
1
+ import { Plugin } from 'vite';
2
+ /** Serves and emits the complete ImFusion favicon set at stable root URLs. */
3
+ export declare function imfusionBrandAssets(): Plugin;
@@ -0,0 +1,2 @@
1
+ export { imfusionBrandAssets } from './brand-assets.ts';
2
+ export { readableCssModuleNames, type ReadableCssModuleNamesOptions } from './readable-css-module-names.ts';
package/dist/vite.js ADDED
@@ -0,0 +1,55 @@
1
+ import { readFileSync as e, readdirSync as t } from "node:fs";
2
+ import { dirname as n, join as r } from "node:path";
3
+ import { fileURLToPath as i } from "node:url";
4
+ //#region src/vite/brand-assets.ts
5
+ var a = n(i(import.meta.resolve("@imfusion/web-ui/assets/favicon/favicon.svg"))), o = t(a).map((t) => ({
6
+ name: t,
7
+ source: e(r(a, t))
8
+ })), s = {
9
+ ".ico": "image/x-icon",
10
+ ".png": "image/png",
11
+ ".svg": "image/svg+xml"
12
+ };
13
+ function c(e) {
14
+ return s[e.slice(e.lastIndexOf("."))] ?? "application/octet-stream";
15
+ }
16
+ function l() {
17
+ return {
18
+ name: "imf-ui:brand-assets",
19
+ configureServer(e) {
20
+ e.middlewares.use((e, t, n) => {
21
+ let r = o.find(({ name: t }) => e.url?.split("?")[0] === `/${t}`);
22
+ if (!r) {
23
+ n();
24
+ return;
25
+ }
26
+ t.setHeader("Content-Type", c(r.name)), t.end(r.source);
27
+ });
28
+ },
29
+ generateBundle() {
30
+ for (let e of o) this.emitFile({
31
+ fileName: e.name,
32
+ source: e.source,
33
+ type: "asset"
34
+ });
35
+ }
36
+ };
37
+ }
38
+ //#endregion
39
+ //#region src/vite/readable-css-module-names.ts
40
+ function u(e, t) {
41
+ let { lightningcss: n, modules: r, transformer: i } = e.css ?? {}, a = n?.cssModules;
42
+ if (!(typeof a == "boolean" || r === !1) && !a?.pattern && !(typeof r == "object" && r.generateScopedName)) return i === "postcss" ? { css: { modules: { generateScopedName: t } } } : { css: {
43
+ transformer: "lightningcss",
44
+ lightningcss: { cssModules: { pattern: t } }
45
+ } };
46
+ }
47
+ function d({ prefix: e }) {
48
+ let t = `${e}-[name]-[local]`;
49
+ return {
50
+ name: "imf-ui:readable-css-module-names",
51
+ config: (e) => u(e, t)
52
+ };
53
+ }
54
+ //#endregion
55
+ export { l as imfusionBrandAssets, d as readableCssModuleNames };
@@ -0,0 +1,51 @@
1
+ import { Meta } from "@storybook/addon-docs/blocks";
2
+ import { Typo } from "#/components/typo";
3
+
4
+ <Meta title="User Guide/AI Agents" />
5
+
6
+ # AI agents
7
+
8
+ The package includes optional skills for agents working in a project that uses `@imfusion/web-ui`.
9
+
10
+ ## Install the skills
11
+
12
+ Install the package first, then run this in the consumer project:
13
+
14
+ ```sh
15
+ npx web-ui-install
16
+ ```
17
+
18
+ The installer asks whether to use Claude Code's `.claude/skills/`, the shared `.agents/skills/` directory, or both. Use
19
+ `--target claude` or `--target agents` to choose without the prompt. Run it again after a package update; use
20
+ `--reconfigure` to choose again.
21
+
22
+ Add `--hooks` when the project should install the optional lifecycle hooks for Claude Code and Codex:
23
+
24
+ ```sh
25
+ npx web-ui-install --hooks
26
+ ```
27
+
28
+ Read the [agent-tooling topic](../../src/llms/skills/imf-web-ui-conventions/topics/agent-tooling.md) before adapting hook
29
+ registrations. Codex also requires project trust and a review of `/hooks`.
30
+
31
+ ## Start with the router
32
+
33
+ Use <Typo.InlineCode>/imf-web-ui</Typo.InlineCode> for UI work and library questions. It routes usage questions to the
34
+ packaged user guides and development tasks to the matching companions:
35
+
36
+ | Skill | Use it for |
37
+ | --- | --- |
38
+ | `/imf-web-ui-components` | Component props, parts, defaults, and icons. |
39
+ | `/imf-web-ui-ux` | Choosing components and shaping screens or flows. |
40
+ | `/imf-web-ui-conventions` | Code, styling, data, validation, and project conventions. |
41
+ | `/imf-web-ui-setup` | First-time wiring and approved project setup. |
42
+ | `/imf-web-ui-audit` | A read-only check of an existing project. |
43
+ | `/imf-web-ui-update` | Updating the package and its installed tooling. |
44
+
45
+ The router keeps small tasks small. It does not load every reference just because the package is installed.
46
+
47
+ ## Where the files come from
48
+
49
+ The skills are shipped inside the package under `src/llms/skills/`. `web-ui-install` copies them into the consumer project.
50
+ The package also exposes generated component, token, and icon indexes for the lookup skill. User guides ship as readable
51
+ MDX under `docs/user-guide/`; agents read them from the installed package without a running Storybook.
@@ -0,0 +1,105 @@
1
+ import { Meta } from "@storybook/addon-docs/blocks";
2
+ import faviconUrl from "#/assets/public/favicon/favicon.svg";
3
+ import ogUrl from "#/assets/public/favicon/og-image.png";
4
+
5
+ <Meta title="User Guide/Brand Assets" />
6
+
7
+ # Brand assets
8
+
9
+ The package ships the ImFusion favicon set and a social sharing image as plain files. Import them through the `assets`
10
+ subpath:
11
+
12
+ ```
13
+ @imfusion/web-ui/assets/<folder>/<file>
14
+ ```
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.
18
+
19
+ ## Files
20
+
21
+ | File | Size | Use |
22
+ | ------------------------------ | ---------- | --------------------------------------------------------- |
23
+ | `favicon/favicon.ico` | 16, 32, 48 | The fallback every browser understands |
24
+ | `favicon/favicon.svg` | any | Preferred by current browsers; stays sharp on any display |
25
+ | `favicon/favicon-16.png` | 16 | Explicit small PNG |
26
+ | `favicon/favicon-32.png` | 32 | Explicit standard PNG |
27
+ | `favicon/apple-touch-icon.png` | 180 | iOS home screen |
28
+ | `favicon/icon-192.png` | 192 | Web app manifest |
29
+ | `favicon/icon-512.png` | 512 | Web app manifest, splash screens |
30
+ | `favicon/og-image.png` | 1200×630 | Link previews in chat and social apps |
31
+
32
+ The mark sits on a square brand-blue tile. The white ImFusion glyph is scaled proportionally within it with a small inset at
33
+ the sides.
34
+
35
+ <div style={{ display: "flex", gap: "1.5rem", alignItems: "flex-end", margin: "1.5rem 0" }}>
36
+ {[16, 32, 64, 128].map(size => (
37
+ <div key={size} style={{ textAlign: "center" }}>
38
+ <img src={faviconUrl} width={size} height={size} alt="" style={{ display: "block", marginBottom: "0.5rem" }} />
39
+ <code style={{ fontSize: "0.75rem" }}>{size}</code>
40
+ </div>
41
+ ))}
42
+ </div>
43
+
44
+ <img src={ogUrl} alt="" width="480" style={{ display: "block", borderRadius: "0.5rem", margin: "1.5rem 0" }} />
45
+
46
+ ## Regenerate the favicon files
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:
50
+
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
57
+
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.
62
+
63
+ ## Add the favicon to a Vite application
64
+
65
+ Register the Vite plugin, then reference the stable root URLs from the document head:
66
+
67
+ ```ts
68
+ import { defineConfig } from "vite";
69
+ import { imfusionBrandAssets } from "@imfusion/web-ui/vite";
70
+
71
+ export default defineConfig({
72
+ plugins: [imfusionBrandAssets()]
73
+ });
74
+ ```
75
+
76
+ ```html
77
+ <link rel="icon" href="/favicon.ico" sizes="48x48" />
78
+ <link rel="icon" href="/favicon.svg" type="image/svg+xml" />
79
+ <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
80
+ <meta property="og:image" content="https://example.com/og-image.png" />
81
+ ```
82
+
83
+ The plugin serves the complete favicon set during development and emits it at the root of the build output. Give `og:image`
84
+ an absolute URL. Chat and social applications fetch it from their own servers, so a relative path does not resolve.
85
+
86
+ ### Other build systems
87
+
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`.
90
+
91
+ ## Import a single file in application code
92
+
93
+ A bundler can also take one file directly, which is useful for a manifest or an `<img>`:
94
+
95
+ ```ts
96
+ import iconUrl from "@imfusion/web-ui/assets/favicon/icon-512.png";
97
+ ```
98
+
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
103
+
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.
@@ -0,0 +1,55 @@
1
+ import { Meta } from "@storybook/addon-docs/blocks";
2
+
3
+ <Meta title="User Guide/Getting Started" />
4
+
5
+ # Getting started
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ npm install @imfusion/web-ui
11
+ ```
12
+
13
+ To try a local checkout instead:
14
+
15
+ ```sh
16
+ # from the web-ui repository
17
+ npm pack
18
+
19
+ # from your application
20
+ npm install /path/to/web-ui-0.0.0.tgz
21
+ ```
22
+
23
+ The package requires React and React DOM 19 or newer. Integrations have their own optional peer dependencies; their pages
24
+ list them.
25
+
26
+ ## Add the provider
27
+
28
+ Import the stylesheet and mount `WebUIProvider` once, near the application root:
29
+
30
+ ```tsx
31
+ import "@imfusion/web-ui/styles.css";
32
+ import { Button, WebUIProvider } from "@imfusion/web-ui";
33
+
34
+ export function App() {
35
+ return (
36
+ <WebUIProvider>
37
+ <Button>Save</Button>
38
+ </WebUIProvider>
39
+ );
40
+ }
41
+ ```
42
+
43
+ Import primitives from `@imfusion/web-ui`. Do not import Base UI components or styles directly.
44
+
45
+ ## Add the favicon
46
+
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.
49
+
50
+ ## Explore token controls
51
+
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.
@@ -0,0 +1,33 @@
1
+ import { Meta } from "@storybook/addon-docs/blocks";
2
+
3
+ <Meta title="User Guide/How It's Built" />
4
+
5
+ # How it's built
6
+
7
+ You can use the library without knowing its implementation. This explains the boundary.
8
+
9
+ ## Behavior comes from an implementation library
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.
13
+
14
+ This split lets the implementation change without forcing a consumer migration.
15
+
16
+ ## Web UI is the styled middle layer
17
+
18
+ Every primitive adds:
19
+
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.
23
+
24
+ The wrapper keeps the upstream surface complete. If an upstream part or prop is useful, Web UI exposes it instead of making an
25
+ app reach around the library.
26
+
27
+ ## Compose parts
28
+
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.
31
+
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).
@@ -0,0 +1,21 @@
1
+ import { Meta } from "@storybook/addon-docs/blocks";
2
+
3
+ <Meta title="User Guide/Introduction" />
4
+
5
+ # ImFusion Web UI
6
+
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
+ ## Find your way
11
+
12
+ - **Getting Started** installs the package and mounts it in an app.
13
+ - **Usage Patterns** covers composition, overrides, state, and color schemes.
14
+ - **Tokens** explains the theming surface.
15
+ - **AI Agents** explains the optional skills shipped with the package.
16
+ - **How It's Built** explains the boundary between Web UI and its implementation libraries.
17
+ - **Primitives** lists the components in the main package entry.
18
+ - **Integrations** lists components that need an optional package.
19
+ - **Development** is for contributors to this repository.
20
+
21
+ The [repository README](https://bitbucket.imfusion.com/projects/WEBSDK/repos/web-ui) covers local development and releases.
@@ -0,0 +1,85 @@
1
+ import { Meta } from "@storybook/addon-docs/blocks";
2
+ import { Typo } from "#/components/typo";
3
+
4
+ <Meta title="User Guide/Tokens" />
5
+
6
+ # Tokens
7
+
8
+ The library's theme is a set of CSS custom properties under `--imf-ui-*`.
9
+
10
+ ## Change a family
11
+
12
+ Most customization uses a control token. Controls feed the semantic tokens consumed by components:
13
+
14
+ ```css
15
+ :root {
16
+ --imf-ui-color-brand-hue: 210;
17
+ }
18
+ ```
19
+
20
+ Brand and primary are related. Primary hue and chroma follow brand until their own controls are changed; primary luma is
21
+ independent. Surface controls work the same way: `main`, `support`, and `minor` start as one ladder and can be split when
22
+ needed.
23
+
24
+ Use a semantic token for a one-off role. That changes one result without changing the rest of its family.
25
+
26
+ ## Families
27
+
28
+ | Family | Use |
29
+ | --- | --- |
30
+ | Brand | Identity color. |
31
+ | Surfaces | Canvas and panels: `main`, `support`, `minor`. |
32
+ | Primary | Actions and calls to action. |
33
+ | Status | `negative`, `warning`, `positive`, and `info`. |
34
+ | Accents | Three independent accent slots. |
35
+ | Fonts | Shared font stacks and text roles. |
36
+ | Shape | Radius and corner controls. |
37
+ | Shadow | The shared elevation model. |
38
+
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>.
41
+
42
+ ## Use semantic tokens in CSS
43
+
44
+ Components and consumer CSS should use semantic roles:
45
+
46
+ ```css
47
+ .panel {
48
+ background: var(--imf-ui-color-bg-support);
49
+ color: var(--imf-ui-color-fg-main);
50
+ }
51
+ ```
52
+
53
+ Foreground tokens are for text, icons, borders, and focus rings. Background tokens are for fills. `fg-oncolor` is for text on
54
+ saturated fills.
55
+
56
+ ## Color schemes
57
+
58
+ The provider sets the active scheme on the document element:
59
+
60
+ ```html
61
+ <html data-imf-ui-color-scheme="light">
62
+ ```
63
+
64
+ Scheme-aware controls have light and dark values. Application CSS can select the attribute when a rule itself must change.
65
+
66
+ ## Fonts, shape, and shadow
67
+
68
+ The font controls define the editorial and utility type roles. Radius controls plain rounded corners; chamfer is a separate
69
+ brand shape axis. Shadow controls share one lighting model across components:
70
+
71
+ - `--imf-ui-shadow-angle` sets the sun direction; the default `315deg` makes shadows fall down and right.
72
+ - `--imf-ui-shadow-hardness` moves from diffuse (`0`) to crisp (`1`) edges without changing the elevation level.
73
+ - `--imf-ui-shadow-spread` adds pixel spread to every shadow.
74
+ - `--imf-ui-shadow-intensity` sets the lowest-level opacity; higher levels add one point each.
75
+ - `--imf-ui-shadow-color` sets the cast color per scheme.
76
+
77
+ Components consume these values through tokens. The package's `src/llms/tokens.gen.json` lists the shipped token names and
78
+ authored defaults.
79
+
80
+ ## Explore
81
+
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.
@@ -0,0 +1,79 @@
1
+ import { Meta } from "@storybook/addon-docs/blocks";
2
+
3
+ <Meta title="User Guide/Usage Patterns" />
4
+
5
+ # Usage patterns
6
+
7
+ ## Keep imports behind Web UI
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.
11
+
12
+ ## Compose parts
13
+
14
+ Multi-part primitives are namespaces. Render the parts you need:
15
+
16
+ ```tsx
17
+ <Drawer.Root>
18
+ <Drawer.Trigger>Open</Drawer.Trigger>
19
+ <Drawer.Content>…</Drawer.Content>
20
+ </Drawer.Root>
21
+ ```
22
+
23
+ All parts come from `@imfusion/web-ui`, including less common ones such as `Indent`, `SwipeArea`, and `Description`.
24
+
25
+
26
+ ## Change the look with tokens
27
+
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:
29
+
30
+ ```css
31
+ :root {
32
+ --imf-ui-color-primary-hue: 30;
33
+ }
34
+ ```
35
+
36
+ Use a semantic token for a local role. Consumer CSS outside `@layer imf-ui.components` overrides the library without `!important`:
37
+
38
+ ```css
39
+ .my-button {
40
+ border-radius: 0;
41
+ }
42
+ ```
43
+
44
+ Components carry `data-imf-ui-component` on their roots, so it is a stable selector. CSS Module class names are internal.
45
+
46
+ ## Style state with data attributes
47
+
48
+ Components expose runtime state through attributes such as `data-checked`, `data-disabled`, and `data-popup-open`:
49
+
50
+ ```css
51
+ [data-imf-ui-component="Switch"][data-checked] {
52
+ outline: var(--imf-ui-border-size-2) solid var(--imf-ui-color-fg-positive);
53
+ }
54
+ ```
55
+
56
+ Use the attribute instead of maintaining a second state class.
57
+
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
64
+
65
+ `WebUIProvider` sets `data-imf-ui-color-scheme="light"` or `"dark"` on `<html>`. Select it when an application rule needs to
66
+ change with the scheme:
67
+
68
+ ```css
69
+ [data-imf-ui-color-scheme="dark"] .hero {
70
+ background-image: url("/hero-dark.png");
71
+ }
72
+ ```
73
+
74
+ The provider follows the OS by default. An application whose own surfaces are a fixed palette pins the scheme instead, so
75
+ component colors cannot disagree with them:
76
+
77
+ ```tsx
78
+ <WebUIProvider colorScheme="dark">{children}</WebUIProvider>
79
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imfusion/web-ui",
3
- "version": "0.6.4-dev.45.gbaffa741",
3
+ "version": "0.6.4-dev.48.g1cf34297",
4
4
  "description": "The official Web UI component library for ImFusion web apps",
5
5
  "author": "ImFusion GmbH",
6
6
  "homepage": "https://imfusion.com",
@@ -31,9 +31,9 @@
31
31
  "types": "./dist/integrations/*/index.d.ts",
32
32
  "import": "./dist/integrations/*.js"
33
33
  },
34
- "./build/*": {
35
- "types": "./dist/build/*/index.d.ts",
36
- "import": "./dist/build/*.js"
34
+ "./vite": {
35
+ "types": "./dist/vite/index.d.ts",
36
+ "import": "./dist/vite.js"
37
37
  },
38
38
  "./icons": {
39
39
  "types": "./dist/icons/index.d.ts",
@@ -49,6 +49,7 @@
49
49
  "dist",
50
50
  "src/assets/public",
51
51
  "docs/assets/imfusion-banner.svg",
52
+ "docs/user-guide",
52
53
  "THIRD_PARTY_NOTICES.md",
53
54
  "src/llms/install-templates",
54
55
  "src/docgen/doc.gen.json",
@@ -1,14 +1,15 @@
1
1
  ---
2
2
  name: imf-web-ui
3
3
  description:
4
- "Route UI work in a project that uses @imfusion/web-ui. Use this skill whenever a user adds, edits, styles, or reviews UI
5
- in a consumer project, even if they do not mention the library. Decide whether guidance is needed, then open only the
6
- companion skills that match the task."
4
+ "Route UI work and library questions in a project that uses @imfusion/web-ui. Use this skill whenever a user adds, edits,
5
+ styles, or reviews UI, or asks about library setup, brand assets, favicons, theming, or usage in a consumer project, even
6
+ if they do not mention the library. Open only the matching packaged guide or companion skill."
7
7
  ---
8
8
 
9
9
  # Route Web UI work
10
10
 
11
- Start here for UI work in a project that uses `@imfusion/web-ui`. This skill is a map, not a second copy of every convention.
11
+ Start here for UI work and library questions in a project that uses `@imfusion/web-ui`. This skill is a map, not a second
12
+ copy of every convention.
12
13
 
13
14
  ## 1. Decide whether guidance is needed
14
15
 
@@ -22,6 +23,7 @@ not already have.
22
23
 
23
24
  | Task | Open |
24
25
  | ----------------------------------------------------------------- | ------------------------------------------------------ |
26
+ | Understand library setup, brand assets, theming, or usage | Packaged user guides below |
25
27
  | Look up a component, part, prop, default, or icon | `imf-web-ui-components` |
26
28
  | Choose components or shape a screen or flow | `imf-web-ui-ux` |
27
29
  | Write or update documentation | `/documentation-writer`, then `imf-web-ui-conventions` |
@@ -33,6 +35,24 @@ not already have.
33
35
  A screen often needs both `imf-web-ui-ux` and `imf-web-ui-components`, in that order. Setup and audit are for project-wide
34
36
  questions, not every one-file edit.
35
37
 
38
+ ### Read a packaged user guide
39
+
40
+ Read only the matching page under `node_modules/@imfusion/web-ui/docs/user-guide/` in the consumer project:
41
+
42
+ | Question | Page |
43
+ | --------------------------------------------------------------- | -------------------- |
44
+ | What the library provides | `Introduction.mdx` |
45
+ | Installation, stylesheet, and provider wiring | `GettingStarted.mdx` |
46
+ | Favicons, social sharing images, and static brand files | `BrandAssets.mdx` |
47
+ | Composition, CSS overrides, state attributes, and color schemes | `UsagePatterns.mdx` |
48
+ | Token families and customization | `Tokens.mdx` |
49
+ | Agent skills and their installation | `AiAgents.mdx` |
50
+ | Library boundaries and implementation choices | `HowItsBuilt.mdx` |
51
+
52
+ Read MDX as text. Its imports, JSX previews, and Storybook navigation are presentation, not instructions to install or run
53
+ Storybook in the consumer. Cite the packaged page when answering a library question. Use `imf-web-ui-components` for exact
54
+ props and the conventions `tokens` topic for exact token names and defaults.
55
+
36
56
  ## 3. Keep project choices
37
57
 
38
58
  The host project's existing conventions win. The companion skills fill gaps; they do not justify refactoring a working
@@ -2,8 +2,11 @@
2
2
 
3
3
  ## Importing
4
4
 
5
- Import files from `src/assets/` so the bundler fingerprints and includes them. Do not reference an asset through a
6
- public-path string.
5
+ Import application images from `src/assets/` so the bundler fingerprints and includes them. Use public URLs for files
6
+ consumed by document metadata or manifests, with a build step that serves the files at those URLs.
7
+
8
+ For the library's favicon set and social sharing image, read `BrandAssets.mdx` through the packaged user-guide route in
9
+ `imf-web-ui`.
7
10
 
8
11
  ## Photographs: WebP
9
12
 
@@ -17,8 +20,8 @@ Keep the long edge at 2000px or less. WebP is supported by the browser floor.
17
20
 
18
21
  ## Other formats
19
22
 
20
- Use PNG when the image needs alpha or exact pixels. Use an inline SVG component for icons, logos, and line art so it inherits
21
- `currentColor` and follows the theme.
23
+ Use PNG when the image needs alpha or exact pixels. Use an inline SVG component for in-app icons, logos, and line art so it
24
+ inherits `currentColor` and follows the theme.
22
25
 
23
26
  ## Scope
24
27
 
@@ -71,19 +71,20 @@ The pre-commit hook checks the whole repository with ESLint and Prettier, then r
71
71
  affect generated files, types, dependencies, or TeamCity configuration. It does not rewrite files during a commit; use
72
72
  `npm run format` to apply Prettier changes explicitly.
73
73
 
74
- ## CSS class names
74
+ ## Vite plugins
75
75
 
76
- Register Web UI's `readableCssModuleNames` plugin in every compiler that processes the app's CSS, including development,
77
- Storybook, and production:
76
+ Register Web UI's Vite plugins in the application configuration:
78
77
 
79
78
  ```ts
80
79
  import { defineConfig } from "vite";
81
80
  import react from "@vitejs/plugin-react";
82
- import { readableCssModuleNames } from "@imfusion/web-ui/build/vite-css-module-names";
81
+ import { imfusionBrandAssets, readableCssModuleNames } from "@imfusion/web-ui/vite";
83
82
 
84
83
  export default defineConfig({
85
- plugins: [react(), readableCssModuleNames({ prefix: "app" })]
84
+ plugins: [react(), imfusionBrandAssets(), readableCssModuleNames({ prefix: "app" })]
86
85
  });
87
86
  ```
88
87
 
89
- A compiler left out of the plugin produces different class names and styles that appear to work only in some environments.
88
+ `imfusionBrandAssets` serves the complete favicon set during development and emits it at stable root URLs during builds.
89
+ Register `readableCssModuleNames` in every compiler that processes the app's CSS, including development, Storybook, and
90
+ production. A compiler left out produces different class names and styles that appear to work only in some environments.
@@ -1,17 +0,0 @@
1
- //#region src/build/vite-css-module-names/index.ts
2
- function e(e, t) {
3
- let { lightningcss: n, modules: r, transformer: i } = e.css ?? {}, a = n?.cssModules;
4
- if (!(typeof a == "boolean" || r === !1) && !a?.pattern && !(typeof r == "object" && r.generateScopedName)) return i === "postcss" ? { css: { modules: { generateScopedName: t } } } : { css: {
5
- transformer: "lightningcss",
6
- lightningcss: { cssModules: { pattern: t } }
7
- } };
8
- }
9
- function t({ prefix: t }) {
10
- let n = `${t}-[name]-[local]`;
11
- return {
12
- name: "imf-ui:readable-css-module-names",
13
- config: (t) => e(t, n)
14
- };
15
- }
16
- //#endregion
17
- export { t as readableCssModuleNames };