@imfusion/web-ui 0.5.0
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 +60 -0
- package/bin/install-skill.js +180 -0
- package/dist/assets/vendors/base-ui.d.ts +8 -0
- package/dist/breakpoints/index.d.ts +3 -0
- package/dist/breakpoints/min-width.d.ts +9 -0
- package/dist/breakpoints/registry.d.ts +19 -0
- package/dist/code-qBbqAHK-.js +190 -0
- package/dist/codegen/gen-breakpoints-css.d.ts +6 -0
- package/dist/codegen/gen-css-types.d.ts +1 -0
- package/dist/codegen/gen-token-css.d.ts +6 -0
- package/dist/codegen/run.d.ts +1 -0
- package/dist/components/app-shell/app-shell.d.ts +66 -0
- package/dist/components/app-shell/app-shell.meta.d.ts +2 -0
- package/dist/components/app-shell/index.d.ts +2 -0
- package/dist/components/button/button.d.ts +30 -0
- package/dist/components/button/button.meta.d.ts +2 -0
- package/dist/components/button/index.d.ts +2 -0
- package/dist/components/callout/callout.d.ts +42 -0
- package/dist/components/callout/callout.meta.d.ts +2 -0
- package/dist/components/callout/index.d.ts +2 -0
- package/dist/components/card/card.d.ts +64 -0
- package/dist/components/card/card.meta.d.ts +2 -0
- package/dist/components/card/index.d.ts +2 -0
- package/dist/components/checkbox/checkbox.d.ts +56 -0
- package/dist/components/checkbox/checkbox.meta.d.ts +2 -0
- package/dist/components/checkbox/index.d.ts +2 -0
- package/dist/components/chip/chip.cva.d.ts +12 -0
- package/dist/components/chip/chip.d.ts +11 -0
- package/dist/components/chip/chip.meta.d.ts +2 -0
- package/dist/components/chip/index.d.ts +2 -0
- package/dist/components/chip-link/chip-link.d.ts +17 -0
- package/dist/components/chip-link/chip-link.meta.d.ts +2 -0
- package/dist/components/chip-link/index.d.ts +2 -0
- package/dist/components/code/code.d.ts +60 -0
- package/dist/components/code/code.meta.d.ts +2 -0
- package/dist/components/code/index.d.ts +2 -0
- package/dist/components/collapsible/collapsible.d.ts +57 -0
- package/dist/components/collapsible/collapsible.meta.d.ts +2 -0
- package/dist/components/collapsible/index.d.ts +2 -0
- package/dist/components/copy-button/copy-button.d.ts +21 -0
- package/dist/components/copy-button/copy-button.meta.d.ts +2 -0
- package/dist/components/copy-button/index.d.ts +2 -0
- package/dist/components/drawer/drawer.d.ts +191 -0
- package/dist/components/drawer/drawer.meta.d.ts +2 -0
- package/dist/components/drawer/index.d.ts +2 -0
- package/dist/components/input/index.d.ts +2 -0
- package/dist/components/input/input.d.ts +25 -0
- package/dist/components/input/input.meta.d.ts +2 -0
- package/dist/components/logo/imfusion/imfusion.d.ts +16 -0
- package/dist/components/logo/imfusion/index.d.ts +1 -0
- package/dist/components/logo/index.d.ts +3 -0
- package/dist/components/logo/logo.d.ts +15 -0
- package/dist/components/logo/logo.meta.d.ts +2 -0
- package/dist/components/navigation-menu/index.d.ts +2 -0
- package/dist/components/navigation-menu/navigation-menu.d.ts +20 -0
- package/dist/components/navigation-menu/navigation-menu.meta.d.ts +2 -0
- package/dist/components/navigation-menu/subs/flyout-link.d.ts +24 -0
- package/dist/components/navigation-menu/subs/inline-submenu.d.ts +41 -0
- package/dist/components/navigation-menu/subs/link.d.ts +64 -0
- package/dist/components/navigation-menu/subs/overlay.d.ts +75 -0
- package/dist/components/navigation-menu/subs/shared.d.ts +20 -0
- package/dist/components/navigation-menu/subs/structure.d.ts +64 -0
- package/dist/components/navigation-menu/subs/trigger.d.ts +47 -0
- package/dist/components/popover/index.d.ts +2 -0
- package/dist/components/popover/popover.d.ts +181 -0
- package/dist/components/popover/popover.meta.d.ts +2 -0
- package/dist/components/row/index.d.ts +2 -0
- package/dist/components/row/row.d.ts +28 -0
- package/dist/components/row/row.meta.d.ts +2 -0
- package/dist/components/select/index.d.ts +2 -0
- package/dist/components/select/select.d.ts +278 -0
- package/dist/components/select/select.meta.d.ts +2 -0
- package/dist/components/separator/index.d.ts +2 -0
- package/dist/components/separator/separator.d.ts +15 -0
- package/dist/components/separator/separator.meta.d.ts +2 -0
- package/dist/components/slider/index.d.ts +2 -0
- package/dist/components/slider/slider.d.ts +111 -0
- package/dist/components/slider/slider.meta.d.ts +2 -0
- package/dist/components/spinner/index.d.ts +2 -0
- package/dist/components/spinner/spinner.d.ts +19 -0
- package/dist/components/spinner/spinner.geometry.d.ts +37 -0
- package/dist/components/spinner/spinner.meta.d.ts +2 -0
- package/dist/components/stack/index.d.ts +2 -0
- package/dist/components/stack/stack.d.ts +18 -0
- package/dist/components/stack/stack.meta.d.ts +2 -0
- package/dist/components/switch/index.d.ts +2 -0
- package/dist/components/switch/switch.d.ts +45 -0
- package/dist/components/switch/switch.meta.d.ts +2 -0
- package/dist/components/table/index.d.ts +2 -0
- package/dist/components/table/table.d.ts +66 -0
- package/dist/components/table/table.meta.d.ts +2 -0
- package/dist/components/tabs/index.d.ts +2 -0
- package/dist/components/tabs/tabs.d.ts +91 -0
- package/dist/components/tabs/tabs.meta.d.ts +2 -0
- package/dist/components/toggle/index.d.ts +2 -0
- package/dist/components/toggle/toggle.d.ts +31 -0
- package/dist/components/toggle/toggle.meta.d.ts +2 -0
- package/dist/components/toggle-group/index.d.ts +2 -0
- package/dist/components/toggle-group/toggle-group.d.ts +30 -0
- package/dist/components/toggle-group/toggle-group.meta.d.ts +2 -0
- package/dist/components/tooltip/index.d.ts +2 -0
- package/dist/components/tooltip/tooltip.d.ts +164 -0
- package/dist/components/tooltip/tooltip.meta.d.ts +2 -0
- package/dist/components/typo/index.d.ts +2 -0
- package/dist/components/typo/typo.d.ts +100 -0
- package/dist/components/typo/typo.meta.d.ts +2 -0
- package/dist/config.d.ts +8 -0
- package/dist/docgen/gen-docgen.d.ts +1 -0
- package/dist/docgen/gen-docgen.utils.d.ts +13 -0
- package/dist/hooks/index.d.ts +5 -0
- package/dist/hooks/use-clipboard.d.ts +12 -0
- package/dist/hooks/use-color-scheme.d.ts +31 -0
- package/dist/hooks/use-media-query.d.ts +13 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +13103 -0
- package/dist/integrations/code-highlight/code-highlight.d.ts +21 -0
- package/dist/integrations/code-highlight/code-highlight.meta.d.ts +2 -0
- package/dist/integrations/code-highlight/highlighter.d.ts +6 -0
- package/dist/integrations/code-highlight/index.d.ts +3 -0
- package/dist/integrations/code-highlight.js +97 -0
- package/dist/integrations/image-display-options/image-display-options-view.d.ts +22 -0
- package/dist/integrations/image-display-options/image-display-options-view.utils.d.ts +40 -0
- package/dist/integrations/image-display-options/image-display-options.d.ts +29 -0
- package/dist/integrations/image-display-options/image-display-options.meta.d.ts +2 -0
- package/dist/integrations/image-display-options/index.d.ts +2 -0
- package/dist/integrations/image-display-options.js +319 -0
- package/dist/llms/gen-llms.d.ts +1 -0
- package/dist/meta-B8C51eyL.js +74 -0
- package/dist/provider/index.d.ts +1 -0
- package/dist/provider/web-ui-provider.d.ts +6 -0
- package/dist/style.css +2 -0
- package/dist/tabs-DqBFSqq6.js +3789 -0
- package/dist/tokens/apply.d.ts +55 -0
- package/dist/tokens/control-registry.d.ts +10 -0
- package/dist/tokens/token-registry.d.ts +13 -0
- package/dist/tokens/types.d.ts +71 -0
- package/dist/tokens/use-token-controls.d.ts +36 -0
- package/dist/types/docgen.d.ts +17 -0
- package/dist/types/meta.d.ts +108 -0
- package/dist/types/theme.d.ts +3 -0
- package/package.json +139 -0
- package/src/docgen/doc.gen.json +4695 -0
- package/src/llms/llms.gen.txt +176 -0
- package/src/llms/skills/imf-web-ui/SKILL.md +46 -0
- package/src/llms/skills/imf-web-ui-components/SKILL.md +100 -0
- package/src/llms/skills/imf-web-ui-frontend-patterns/SKILL.md +67 -0
- package/src/llms/skills/imf-web-ui-frontend-patterns/references/react-patterns.md +94 -0
- package/src/llms/skills/imf-web-ui-setup/SKILL.md +30 -0
- package/src/llms/skills/imf-web-ui-ux/SKILL.md +103 -0
- package/src/llms/skills/imf-web-ui-ux/references/forms.md +48 -0
- package/src/llms/skills/imf-web-ui-ux/references/usability-heuristics.md +29 -0
- package/src/llms/skills/imf-web-ui-ux/references/visual-design.md +38 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ColorScheme } from '../types/theme';
|
|
2
|
+
import { Token, TokenControl, TokenId } from './token-registry';
|
|
3
|
+
import { TokenOverrides } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Pure token-application layer — no React, no router, no DOM ownership beyond the one imperative
|
|
6
|
+
* writer ({@link applyTokenOverrides}). The stateful, persistence-agnostic hook is `useTokenControls`.
|
|
7
|
+
*/
|
|
8
|
+
/** Flatten a possibly scheme-keyed numeric value to the active scheme. */
|
|
9
|
+
export declare function resolveScheme(field: number | Record<ColorScheme, number>, scheme: ColorScheme): number;
|
|
10
|
+
/**
|
|
11
|
+
* A control resolved to the active scheme — the panel-facing view. Slider controls carry numeric
|
|
12
|
+
* bounds; select controls carry options.
|
|
13
|
+
*/
|
|
14
|
+
export type ResolvedControl = {
|
|
15
|
+
id: TokenId;
|
|
16
|
+
cssVar: string;
|
|
17
|
+
group: Token["group"];
|
|
18
|
+
label: string;
|
|
19
|
+
description: string;
|
|
20
|
+
} & ({
|
|
21
|
+
kind: "slider";
|
|
22
|
+
type: "single" | "shared";
|
|
23
|
+
value: number;
|
|
24
|
+
defaultValue: number;
|
|
25
|
+
min: number;
|
|
26
|
+
max: number;
|
|
27
|
+
step: number;
|
|
28
|
+
derivedFrom?: TokenId;
|
|
29
|
+
} | {
|
|
30
|
+
kind: "select";
|
|
31
|
+
value: string;
|
|
32
|
+
defaultValue: string;
|
|
33
|
+
options: readonly {
|
|
34
|
+
label: string;
|
|
35
|
+
value: string;
|
|
36
|
+
}[];
|
|
37
|
+
});
|
|
38
|
+
/**
|
|
39
|
+
* Resolve a control to the active scheme, flattening its scheme-keyed fields to plain numbers.
|
|
40
|
+
* `value` starts at the resolved default; callers overlay effective overrides.
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolve(control: TokenControl, scheme: ColorScheme): ResolvedControl;
|
|
43
|
+
/**
|
|
44
|
+
* Registry-driven effective overrides — any slider control with `derivedFrom` tracks its source token
|
|
45
|
+
* until explicitly touched. Mirrors the CSS `var(--src, fallback)` chain so slider display stays
|
|
46
|
+
* correct. Select controls have no derivation.
|
|
47
|
+
*/
|
|
48
|
+
export declare function deriveAll(live: TokenOverrides): TokenOverrides;
|
|
49
|
+
/**
|
|
50
|
+
* Imperative core — reconcile `documentElement`'s inline custom properties to `overrides`. Sets
|
|
51
|
+
* present vars, removes every registry var absent from `overrides` (both `-light`/`-dark`), so reset
|
|
52
|
+
* and scheme switches leave nothing stale. This is the one DOM writer; `useTokenControls` calls it in
|
|
53
|
+
* a layout effect, and hosts (Storybook, consumers) can call it directly.
|
|
54
|
+
*/
|
|
55
|
+
export declare function applyTokenOverrides(overrides: TokenOverrides, root?: HTMLElement): void;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { TokenControl } from './token-registry';
|
|
2
|
+
/**
|
|
3
|
+
* The control registry — every {@link TokenControl}, i.e. every token that has a live adjuster. Each
|
|
4
|
+
* entry spreads its token's data (including `label`/`description`) from `TOKEN_REGISTRY` and adds
|
|
5
|
+
* only the control-specific metadata its UI needs.
|
|
6
|
+
*
|
|
7
|
+
* Not every token appears here: the semantic font aliases (`font-family-heading` / `-body` / `-ui`
|
|
8
|
+
* / `-code`) are `var()` indirections with no direct control, so they have no entry.
|
|
9
|
+
*/
|
|
10
|
+
export declare const TOKEN_CONTROLS: readonly TokenControl[];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Token, TokenId, TokenValue } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Derive the CSS custom property for a token. Scheme-aware tokens (numeric `Record<ColorScheme>`
|
|
4
|
+
* default) get a `-${scheme}` suffix; every other token has a single var.
|
|
5
|
+
*/
|
|
6
|
+
export declare function toTokenCssVar(token: {
|
|
7
|
+
id: string;
|
|
8
|
+
default: TokenValue;
|
|
9
|
+
}, scheme: "light" | "dark"): string;
|
|
10
|
+
export declare const TOKEN_REGISTRY: Record<TokenId, Token>;
|
|
11
|
+
export type { Token, TokenControl, TokenGroup, TokenId } from './types';
|
|
12
|
+
/** Runtime lookup: token by id. Always present — `TokenId` is exactly `TOKEN_REGISTRY`'s key set. */
|
|
13
|
+
export declare function tokenById(id: TokenId): Token;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { ColorScheme } from '../types/theme';
|
|
2
|
+
/**
|
|
3
|
+
* A **token** is a CSS custom property under `--imf-ui-` carrying a design value; every token lives
|
|
4
|
+
* in `TOKEN_REGISTRY`. A **TokenControl** is a live adjuster *bound to* a token, not a kind of token —
|
|
5
|
+
* it carries the token's own fields plus the control's `id`. Not every token has a control.
|
|
6
|
+
*
|
|
7
|
+
* The shapes below are generic over the id type to avoid an import cycle with the registry that
|
|
8
|
+
* defines the concrete `TokenId` union. Import `Token` / `TokenControl` from `./token-registry` (bound
|
|
9
|
+
* to the concrete id), not from here directly.
|
|
10
|
+
*/
|
|
11
|
+
/** A continuous or per-scheme numeric value (slider tokens) or a fixed string (select tokens). */
|
|
12
|
+
export type TokenValue = number | string | Record<ColorScheme, number>;
|
|
13
|
+
/** A numeric value that may be resolved per color scheme (min / max / default on slider controls). */
|
|
14
|
+
export type NumericTokenValue = number | Record<ColorScheme, number>;
|
|
15
|
+
/** Grouping for panel layout. */
|
|
16
|
+
export type TokenGroup = "brand" | "surface" | "primary" | "status" | "accent" | "shadow" | "shape" | "font";
|
|
17
|
+
/**
|
|
18
|
+
* The canonical token id vocabulary — **hand-authored** (not derived from the registry). This is the
|
|
19
|
+
* source of truth for what a `--imf-ui-*` token may be called, so:
|
|
20
|
+
* - the registry definition site gets autocomplete and rejects typos (`TOKEN_REGISTRY` is a
|
|
21
|
+
* `Record<TokenId, Token>`, so every key and every `id` is checked against it);
|
|
22
|
+
* - every `id` / `derivedFrom` on a control is checked against it.
|
|
23
|
+
*
|
|
24
|
+
* Adding or renaming a token is a deliberate two-step edit: this union **and** `TOKEN_REGISTRY`. The
|
|
25
|
+
* `token-registry.test.ts` "union ↔ registry agree" test fails loudly if the two drift.
|
|
26
|
+
*/
|
|
27
|
+
export type TokenId = "color-brand-luma" | "color-brand-chroma" | "color-brand-hue" | "color-surface-bg-luma" | "color-surface-fg-luma" | "color-surface-chroma" | "color-surface-main-hue" | "color-surface-support-hue" | "color-surface-minor-hue" | "color-primary-bg-luma" | "color-primary-fg-luma" | "color-primary-chroma" | "color-primary-hue" | "color-status-bg-luma" | "color-status-fg-luma" | "color-status-chroma" | "color-status-positive-hue" | "color-status-negative-hue" | "color-status-warning-hue" | "color-status-info-hue" | "color-accent-1-bg-luma" | "color-accent-1-fg-luma" | "color-accent-1-chroma" | "color-accent-1-hue" | "color-accent-2-bg-luma" | "color-accent-2-fg-luma" | "color-accent-2-chroma" | "color-accent-2-hue" | "color-accent-3-bg-luma" | "color-accent-3-fg-luma" | "color-accent-3-chroma" | "color-accent-3-hue" | "shadow-angle" | "shadow-hardness" | "shadow-spread" | "shadow-intensity" | "corner-radius" | "font-family-sans" | "font-family-mono" | "font-family-heading" | "font-family-body" | "font-family-ui" | "font-family-code";
|
|
28
|
+
/**
|
|
29
|
+
* A pure design token — one CSS custom property, its default, and its display copy. Carries **no**
|
|
30
|
+
* control metadata; whether it's adjustable is expressed by a separate {@link TokenControl} in
|
|
31
|
+
* `TOKEN_CONTROLS`. Every token has a `label`/`description` — including the semantic font aliases,
|
|
32
|
+
* which have no control — so consumers (the token drawer, the reference page) never need a fallback.
|
|
33
|
+
*/
|
|
34
|
+
export interface Token {
|
|
35
|
+
id: TokenId;
|
|
36
|
+
/** The `--imf-ui-*` custom property this token writes. Derived from `id` via `toTokenCssVar`. */
|
|
37
|
+
cssVar: string;
|
|
38
|
+
default: TokenValue;
|
|
39
|
+
/** CSS unit appended to numeric values when this token is emitted or applied (for example, `px`). */
|
|
40
|
+
unit?: string;
|
|
41
|
+
group: TokenGroup;
|
|
42
|
+
label: string;
|
|
43
|
+
description: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* A live adjuster bound to a token — the token's own fields plus kind-specific control metadata.
|
|
47
|
+
* Discriminated on `kind`:
|
|
48
|
+
* - `slider` — a continuous numeric control (min/max/step); may derive from another token.
|
|
49
|
+
* - `select` — a discrete choice from an enumerated option list (e.g. font stacks).
|
|
50
|
+
*
|
|
51
|
+
* The finer constraint — slider ↔ numeric token, select ↔ string token — is a runtime/test guard, not
|
|
52
|
+
* encoded here (encoding it would add cryptic type machinery for little gain).
|
|
53
|
+
*/
|
|
54
|
+
export type TokenControl = Token & ({
|
|
55
|
+
kind: "slider";
|
|
56
|
+
step: number;
|
|
57
|
+
min: NumericTokenValue;
|
|
58
|
+
max: NumericTokenValue;
|
|
59
|
+
/** When set, the target token inherits this source token's value until explicitly touched. */
|
|
60
|
+
derivedFrom?: TokenId;
|
|
61
|
+
/** `single` = one control; `shared` = an envelope control tuning a whole category. */
|
|
62
|
+
type: "single" | "shared";
|
|
63
|
+
} | {
|
|
64
|
+
kind: "select";
|
|
65
|
+
options: readonly {
|
|
66
|
+
label: string;
|
|
67
|
+
value: string;
|
|
68
|
+
}[];
|
|
69
|
+
});
|
|
70
|
+
/** A map of token overrides keyed by full CSS custom property name (e.g. `--imf-ui-color-primary-hue`). */
|
|
71
|
+
export type TokenOverrides = Record<string, number | string>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ColorScheme } from '../types/theme';
|
|
2
|
+
import { ResolvedControl } from './apply';
|
|
3
|
+
import { TokenId } from './token-registry';
|
|
4
|
+
import { TokenOverrides } from './types';
|
|
5
|
+
export interface UseTokenControlsResult {
|
|
6
|
+
/** Every control joined to its token and resolved to the active scheme, carrying its effective value. */
|
|
7
|
+
controls: readonly ResolvedControl[];
|
|
8
|
+
setControl: (id: TokenId, value: number | string) => void;
|
|
9
|
+
setControls: (updates: readonly {
|
|
10
|
+
id: TokenId;
|
|
11
|
+
value: number | string;
|
|
12
|
+
}[]) => void;
|
|
13
|
+
resetControl: (id: TokenId) => void;
|
|
14
|
+
reset: () => void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The persistence-agnostic token editor. It derives effective values, resolves each control for the
|
|
18
|
+
* active `scheme`, mirrors the effective map onto `documentElement`, and exposes mutators that
|
|
19
|
+
* commit through the injected `overrides`/`onChange` pair.
|
|
20
|
+
*
|
|
21
|
+
* `useTokenControls` owns *no* persistence — the host decides where `overrides` lives and how writes
|
|
22
|
+
* are debounced, then passes the current map and a commit callback in on every render.
|
|
23
|
+
*
|
|
24
|
+
* **Contract — synchronous read-back:** each mutator builds its next map by spreading the current
|
|
25
|
+
* `overrides`. If the host debounces persistence, it must still surface each committed map as
|
|
26
|
+
* `overrides` *synchronously* (e.g. a `useState` working copy) so back-to-back `setControl` calls in
|
|
27
|
+
* one tick don't clobber each other. A host that only reflects the committed map after an async
|
|
28
|
+
* round trip will drop rapid successive edits.
|
|
29
|
+
*/
|
|
30
|
+
export declare function useTokenControls({ overrides, onChange, scheme }: {
|
|
31
|
+
/** Current overrides, keyed by full CSS custom property name. Must update synchronously on commit. */
|
|
32
|
+
overrides: TokenOverrides;
|
|
33
|
+
/** Commit the next override map. The host persists it and re-supplies it as `overrides`. */
|
|
34
|
+
onChange: (next: TokenOverrides) => void;
|
|
35
|
+
scheme: ColorScheme;
|
|
36
|
+
}): UseTokenControlsResult;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface DocgenPropEntry {
|
|
2
|
+
name: string;
|
|
3
|
+
required: boolean;
|
|
4
|
+
type: string;
|
|
5
|
+
defaultValue: string | null;
|
|
6
|
+
description: string;
|
|
7
|
+
}
|
|
8
|
+
export interface DocgenComponentEntry {
|
|
9
|
+
name: string;
|
|
10
|
+
description: string;
|
|
11
|
+
props: DocgenPropEntry[];
|
|
12
|
+
}
|
|
13
|
+
export interface DocgenComponentGroup {
|
|
14
|
+
root: DocgenComponentEntry;
|
|
15
|
+
subComponents: DocgenComponentEntry[];
|
|
16
|
+
}
|
|
17
|
+
export type DocgenOutput = Record<string, DocgenComponentGroup>;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
export type ComponentCategoryId = "buttons" | "inputs" | "layout" | "display";
|
|
2
|
+
export type ComponentStatus = "stable" | "experimental" | "deprecated";
|
|
3
|
+
/**
|
|
4
|
+
* Provenance of a component. `"adapted"` wraps an upstream behavioral package —
|
|
5
|
+
* Base UI by default, or another best-in-class library (e.g. TanStack Table);
|
|
6
|
+
* `"native"` is built by us with no upstream runtime dependency, regardless of
|
|
7
|
+
* whether the design took inspiration from elsewhere. Surfaces as the origin
|
|
8
|
+
* badge in the docs UI and on consumer-side surfaces that disambiguate the
|
|
9
|
+
* implementation source.
|
|
10
|
+
*/
|
|
11
|
+
export type ComponentOrigin = "adapted" | "native";
|
|
12
|
+
/**
|
|
13
|
+
* Upstream a component is adapted from. Required when `origin === "adapted"`,
|
|
14
|
+
* absent when `origin === "native"`. Carries the human-readable upstream name
|
|
15
|
+
* (e.g. "Base UI") and the doc URLs the docs UI's link chips point at.
|
|
16
|
+
*/
|
|
17
|
+
export interface ComponentUpstream {
|
|
18
|
+
/** Display name of the upstream package, e.g. "Base UI". */
|
|
19
|
+
name: string;
|
|
20
|
+
/** Upstream brand / project home page — the URL the origin badge links to when clicked. */
|
|
21
|
+
websiteLink?: string;
|
|
22
|
+
/** Upstream documentation URL for the human reader. */
|
|
23
|
+
docLink?: string;
|
|
24
|
+
/** LLM-friendly documentation URL — typically the `.md` companion of `docLink`. */
|
|
25
|
+
llmDocLink?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Package specifiers a consumer must install to use this primitive, when
|
|
28
|
+
* adapting from an upstream OTHER than the house dependency (Base UI) — e.g.
|
|
29
|
+
* `["@tanstack/react-table"]` for Table. Omitted for Base-UI-adapted
|
|
30
|
+
* primitives, which are already present transitively; an absent field and an
|
|
31
|
+
* empty array both mean "no extra install". An array (not a single string)
|
|
32
|
+
* because one adapt may require several independently-installable peers (a
|
|
33
|
+
* lib plus a required companion package). Docs read this to render an install
|
|
34
|
+
* hint; `name` remains the human-readable display name.
|
|
35
|
+
*/
|
|
36
|
+
runtimeDependencies?: string[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A taxonomic category as it appears on a component's meta. Carries both the
|
|
40
|
+
* stable `id` (slug used for grouping/sorting) and a human-readable `label`.
|
|
41
|
+
* Default labels are English; i18n is out of scope for v0 — a later evolution
|
|
42
|
+
* can swap `ComponentCategories` for locale-aware sources without changing the
|
|
43
|
+
* `ComponentCategory` shape consumers read.
|
|
44
|
+
*/
|
|
45
|
+
export interface ComponentCategory {
|
|
46
|
+
id: ComponentCategoryId;
|
|
47
|
+
label: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Canonical category objects. Every `*.meta.ts` should reference one of these
|
|
51
|
+
* (e.g. `category: ComponentCategories.inputs`) rather than inlining a literal
|
|
52
|
+
* — a literal allows ID/label drift and duplicates the label string per meta.
|
|
53
|
+
*/
|
|
54
|
+
export declare const ComponentCategories: {
|
|
55
|
+
readonly buttons: {
|
|
56
|
+
readonly id: "buttons";
|
|
57
|
+
readonly label: "Buttons";
|
|
58
|
+
};
|
|
59
|
+
readonly inputs: {
|
|
60
|
+
readonly id: "inputs";
|
|
61
|
+
readonly label: "Inputs";
|
|
62
|
+
};
|
|
63
|
+
readonly layout: {
|
|
64
|
+
readonly id: "layout";
|
|
65
|
+
readonly label: "Layout";
|
|
66
|
+
};
|
|
67
|
+
readonly display: {
|
|
68
|
+
readonly id: "display";
|
|
69
|
+
readonly label: "Display";
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Self-descriptive metadata for an exported component. Describes *what the
|
|
74
|
+
* component is* — name, taxonomy, lifecycle, a one-sentence identity line, and
|
|
75
|
+
* provenance (adapted from an upstream vs. native). NOT documentation prose,
|
|
76
|
+
* usage examples, props, or part enumerations. Props are derived from the
|
|
77
|
+
* component's TypeScript Props interface at build time; longer-form
|
|
78
|
+
* documentation lives in MDX; named sub-exports are the source of truth for
|
|
79
|
+
* compound-component parts.
|
|
80
|
+
*/
|
|
81
|
+
export interface ComponentMeta {
|
|
82
|
+
/** PascalCase component name as exported from `@imfusion/web-ui`. Matches the `data-imf-ui-component` attribute. */
|
|
83
|
+
name: string;
|
|
84
|
+
/** Taxonomic category. Use a `ComponentCategories.*` constant. */
|
|
85
|
+
category: ComponentCategory;
|
|
86
|
+
/** Lifecycle marker. Required and explicit on every meta. */
|
|
87
|
+
status: ComponentStatus;
|
|
88
|
+
/**
|
|
89
|
+
* Set to `true` for pure-namespace components (e.g. Typo) that intentionally
|
|
90
|
+
* have no `Root` export — every export is a named sub-component. Suppresses
|
|
91
|
+
* the docgen "no root component found" warning for this folder.
|
|
92
|
+
*/
|
|
93
|
+
namespace?: true;
|
|
94
|
+
/** One-sentence identity line. Rendered in the docs UI page header and reusable on consumer-side surfaces (nav tooltips, search). Not a paragraph; not example prose. */
|
|
95
|
+
description: string;
|
|
96
|
+
/** Provenance — `"adapted"` wraps an upstream package, `"native"` is built by us. */
|
|
97
|
+
origin: ComponentOrigin;
|
|
98
|
+
/** Upstream descriptor — required when `origin === "adapted"`, absent when `origin === "native"`. */
|
|
99
|
+
upstream?: ComponentUpstream;
|
|
100
|
+
/**
|
|
101
|
+
* PascalCase names of other `@imfusion/web-ui` components this component
|
|
102
|
+
* composes internally (e.g. CopyButton renders through Button).
|
|
103
|
+
* The in-library counterpart to `upstream.runtimeDependencies`: no install
|
|
104
|
+
* implication — purely discovery/documentation, surfaced by doc tooling
|
|
105
|
+
* (DocHeader "Uses" row). Omit when the component composes nothing.
|
|
106
|
+
*/
|
|
107
|
+
internalDependencies?: string[];
|
|
108
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@imfusion/web-ui",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "The official Web UI component library for ImFusion web apps",
|
|
5
|
+
"author": "ImFusion GmbH",
|
|
6
|
+
"license": "UNLICENSED",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"registry": "https://registry.npmjs.org",
|
|
9
|
+
"access": "restricted"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"module": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"bin": {
|
|
15
|
+
"web-ui-install-skills": "./bin/install-skill.js"
|
|
16
|
+
},
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./integrations/*": {
|
|
23
|
+
"types": "./dist/integrations/*/index.d.ts",
|
|
24
|
+
"import": "./dist/integrations/*.js"
|
|
25
|
+
},
|
|
26
|
+
"./styles.css": "./dist/style.css",
|
|
27
|
+
"./docgen.json": "./src/docgen/doc.gen.json",
|
|
28
|
+
"./llms.txt": "./src/llms/llms.gen.txt",
|
|
29
|
+
"./*": null
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"src/docgen/doc.gen.json",
|
|
34
|
+
"src/llms/llms.gen.txt",
|
|
35
|
+
"src/llms/skills",
|
|
36
|
+
"bin"
|
|
37
|
+
],
|
|
38
|
+
"scripts": {
|
|
39
|
+
"codegen:docgen": "tsx src/docgen/gen-docgen.ts",
|
|
40
|
+
"codegen:llms": "tsx src/llms/gen-llms.ts",
|
|
41
|
+
"codegen:watch": "tsx watch src/codegen/run.ts",
|
|
42
|
+
"codegen:storybook": "tsx src/codegen/run.ts --storybook",
|
|
43
|
+
"codegen": "tsx src/codegen/run.ts",
|
|
44
|
+
"build": "npm run codegen && rm -rf dist && vite build && npm run codegen:docgen && npm run codegen:llms",
|
|
45
|
+
"dev": "tsx scripts/dev.ts",
|
|
46
|
+
"dev:host": "tsx scripts/dev.ts --host",
|
|
47
|
+
"dev:lib": "concurrently -n codegen,lib -c yellow,blue \"npm run codegen:watch\" \"vite build --watch\"",
|
|
48
|
+
"typecheck": "npm run codegen && tsc -p tsconfig.lib.json --noEmit && tsc -p .storybook/tsconfig.json --noEmit",
|
|
49
|
+
"format": "prettier --write .",
|
|
50
|
+
"format:check": "prettier --check .",
|
|
51
|
+
"lint": "eslint . --cache --max-warnings=0",
|
|
52
|
+
"lint:fix": "eslint . --cache --fix",
|
|
53
|
+
"lint:inspect": "npx @eslint/config-inspector@latest",
|
|
54
|
+
"skills:eval": "node src/llms/evals/run.mjs",
|
|
55
|
+
"skills:eval:dev": "WEB_UI_SKILL_EVAL_ROOT=/private/tmp/web-ui-dev-skill-evals WEB_UI_SKILL_EVAL_RESULTS_DIR=.agents/evals/results WEB_UI_SKILL_EVAL_REPORT_PATH=.agents/evals/REPORT.md WEB_UI_SKILL_EVAL_SKILL_FAMILY=web-ui-dev WEB_UI_SKILL_EVAL_WORKSPACE_LABEL='development repository' node src/llms/evals/run.mjs --scenarios-dir .agents/evals/scenarios --setup .agents/evals/setup-env.sh",
|
|
56
|
+
"skills:eval:compare": "node src/llms/evals/compare.mjs",
|
|
57
|
+
"skills:eval:report": "node src/llms/evals/report.mjs",
|
|
58
|
+
"storybook": "npm run codegen:storybook && storybook dev -p 6006 --no-open",
|
|
59
|
+
"storybook:free-ports": "tsx scripts/free-storybook-ports.ts",
|
|
60
|
+
"build:storybook": "npm run codegen:storybook && storybook build",
|
|
61
|
+
"test": "vitest run",
|
|
62
|
+
"test:unit": "vitest run --project unit",
|
|
63
|
+
"test:stories": "vitest run --project storybook",
|
|
64
|
+
"test:watch": "vitest",
|
|
65
|
+
"verify:preflight": "tsx scripts/verify/full.ts",
|
|
66
|
+
"verify:full": "npm run verify:preflight && npm run test",
|
|
67
|
+
"worktree:create": "tsx scripts/worktrees.ts create",
|
|
68
|
+
"worktree:close": "tsx scripts/worktrees.ts close",
|
|
69
|
+
"worktree:discard": "tsx scripts/worktrees.ts discard",
|
|
70
|
+
"knip": "knip",
|
|
71
|
+
"prepare": "git config core.hooksPath .githooks && git config pull.rebase true && git config merge.ff only"
|
|
72
|
+
},
|
|
73
|
+
"peerDependencies": {
|
|
74
|
+
"@imfusion/sdk": "^1.0.0",
|
|
75
|
+
"@imfusion/sdk-react": "^1.0.0",
|
|
76
|
+
"@tanstack/highlight": "^0.0.9",
|
|
77
|
+
"react": "^19.0.0",
|
|
78
|
+
"react-dom": "^19.0.0"
|
|
79
|
+
},
|
|
80
|
+
"peerDependenciesMeta": {
|
|
81
|
+
"@imfusion/sdk": {
|
|
82
|
+
"optional": true
|
|
83
|
+
},
|
|
84
|
+
"@imfusion/sdk-react": {
|
|
85
|
+
"optional": true
|
|
86
|
+
},
|
|
87
|
+
"@tanstack/highlight": {
|
|
88
|
+
"optional": true
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"dependencies": {
|
|
92
|
+
"@base-ui/react": "1.6.0",
|
|
93
|
+
"@clack/prompts": "1.7.0",
|
|
94
|
+
"class-variance-authority": "0.7.1",
|
|
95
|
+
"lucide-react": "1.16.0"
|
|
96
|
+
},
|
|
97
|
+
"devDependencies": {
|
|
98
|
+
"@eslint/compat": "1.4.1",
|
|
99
|
+
"@eslint/js": "9.39.4",
|
|
100
|
+
"@imfusion/sdk": "1.0.0",
|
|
101
|
+
"@imfusion/sdk-react": "1.0.0",
|
|
102
|
+
"@storybook/addon-a11y": "10.4.3",
|
|
103
|
+
"@storybook/addon-docs": "10.4.3",
|
|
104
|
+
"@storybook/addon-mcp": "0.6.0",
|
|
105
|
+
"@storybook/addon-vitest": "10.4.3",
|
|
106
|
+
"@storybook/react-vite": "10.4.3",
|
|
107
|
+
"@tanstack/highlight": "0.0.9",
|
|
108
|
+
"@tanstack/react-pacer": "0.22.1",
|
|
109
|
+
"@types/culori": "4.0.1",
|
|
110
|
+
"@types/mdx": "2.0.13",
|
|
111
|
+
"@types/node": "25.6.0",
|
|
112
|
+
"@types/react": "19.2.14",
|
|
113
|
+
"@types/react-dom": "19.2.3",
|
|
114
|
+
"@vitejs/plugin-react": "6.0.1",
|
|
115
|
+
"@vitest/browser-playwright": "4.1.6",
|
|
116
|
+
"concurrently": "9.2.1",
|
|
117
|
+
"culori": "4.0.2",
|
|
118
|
+
"eslint": "9.39.4",
|
|
119
|
+
"eslint-plugin-jsx-a11y": "6.10.2",
|
|
120
|
+
"eslint-plugin-mdx": "3.7.0",
|
|
121
|
+
"eslint-plugin-react": "7.37.5",
|
|
122
|
+
"eslint-plugin-react-hooks": "5.2.0",
|
|
123
|
+
"eslint-plugin-react-refresh": "0.4.26",
|
|
124
|
+
"globals": "15.15.0",
|
|
125
|
+
"jiti": "2.7.0",
|
|
126
|
+
"knip": "6.14.2",
|
|
127
|
+
"nano-staged": "1.0.2",
|
|
128
|
+
"playwright": "1.60.0",
|
|
129
|
+
"prettier": "3.8.3",
|
|
130
|
+
"react-docgen-typescript": "2.4.0",
|
|
131
|
+
"storybook": "10.4.3",
|
|
132
|
+
"tsx": "4.21.0",
|
|
133
|
+
"typescript": "6.0.3",
|
|
134
|
+
"typescript-eslint": "8.59.3",
|
|
135
|
+
"vite": "8.0.10",
|
|
136
|
+
"vite-plugin-dts": "5.0.0",
|
|
137
|
+
"vitest": "4.1.6"
|
|
138
|
+
}
|
|
139
|
+
}
|