@imfusion/web-ui 0.7.2-dev.5.g78bbaac3 → 0.8.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/CHANGELOG.md +97 -1
- package/README.md +32 -0
- package/dist/components/navigation-menu/subs/link.d.ts +1 -4
- package/dist/components/prose/index.d.ts +2 -0
- package/dist/components/prose/prose.d.ts +1 -0
- package/dist/components/prose/prose.meta.d.ts +2 -0
- package/dist/components/separator/separator.d.ts +1 -2
- package/dist/components/typo/typo.d.ts +12 -16
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1172 -1181
- package/dist/paths-Oi0v8x-w.js +26 -0
- package/dist/style.css +1 -1
- package/dist/vite/index.d.ts +1 -0
- package/dist/vite/local-web-ui-link.d.ts +8 -0
- package/dist/vite.js +32 -17
- package/dist/web-ui-cli.js +121 -146
- package/docs/user-guide/Changelog.mdx +1 -1
- package/package.json +1 -1
- package/src/docgen/doc.gen.json +9 -78
- package/src/llms/llms.gen.txt +5 -0
- package/src/llms/skills/imf-web-ui-conventions/SKILL.md +1 -1
- package/src/llms/skills/imf-web-ui-conventions/templates/AUDIT_CHECKLIST.md +5 -4
- package/src/llms/skills/imf-web-ui-conventions/topics/library-boundary.md +13 -0
- package/src/llms/skills/imf-web-ui-conventions/topics/react.md +1 -1
- package/src/llms/skills/imf-web-ui-conventions/topics/styling.md +25 -0
- package/src/llms/skills/imf-web-ui-conventions/topics/tooling.md +3 -0
- package/src/llms/skills/imf-web-ui-update/SKILL.md +2 -1
- package/src/llms/skills/imf-web-ui-ux/SKILL.md +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,89 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## `0.8.0` 2026.10.01
|
|
4
|
+
|
|
5
|
+
### Highlights
|
|
6
|
+
|
|
7
|
+
#### The layout owns spacing
|
|
8
|
+
|
|
9
|
+
Web UI components have no outer margin. The parent sets the space between them: `Stack` and `Row` gaps in UI, and the new
|
|
10
|
+
`Prose` for long-form text. A component now sits at the same distance from its neighbours in every layout, where a margin
|
|
11
|
+
used to add to the gap inside a `Stack`, a `Row`, or a card.
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { Callout, Prose, Stack, Typo } from "@imfusion/web-ui";
|
|
15
|
+
|
|
16
|
+
<Stack gap="3">
|
|
17
|
+
<Typo.P>Your study is ready.</Typo.P>
|
|
18
|
+
<Callout.Root>…</Callout.Root>
|
|
19
|
+
</Stack>
|
|
20
|
+
|
|
21
|
+
<Prose>
|
|
22
|
+
<Typo.H2>Export</Typo.H2>
|
|
23
|
+
<Typo.P>Pick a format, then a destination.</Typo.P>
|
|
24
|
+
</Prose>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`Prose` spaces headings, paragraphs, lists, `Code.Block`, `Table.Root`, `Callout.Root`, and `Separator` by their role, and
|
|
28
|
+
its first and last child sit flush with its edges. It is `experimental`. `imf-web-ui-conventions` has a Spacing section,
|
|
29
|
+
`imf-web-ui-audit` checks it, and `imf-web-ui-update` finds the call sites a style-only change touches.
|
|
30
|
+
|
|
31
|
+
#### New and updated components
|
|
32
|
+
|
|
33
|
+
- `Prose` is new. It spaces long-form text and the blocks inside it.
|
|
34
|
+
- Read-only `Input`, `NumberField`, and `Select` share a dashed border, muted text, and no fill, so a locked value reads
|
|
35
|
+
apart from an editable or a disabled one. A read-only search `Input` has no clear button.
|
|
36
|
+
- `NavigationMenu` flyout text and padding scale with the fluid body size, and `NavigationMenu.Link` has no hover arrow.
|
|
37
|
+
|
|
38
|
+
#### Link a local checkout
|
|
39
|
+
|
|
40
|
+
The `localWebUILink` Vite plugin dedupes the library's peer dependencies in an app that links a local Web UI checkout.
|
|
41
|
+
|
|
42
|
+
#### Important fixes
|
|
43
|
+
|
|
44
|
+
- `WebUIProvider` and `useColorScheme` render on the server and hydrate from the stored and OS color scheme.
|
|
45
|
+
|
|
46
|
+
#### Migrating from 0.7
|
|
47
|
+
|
|
48
|
+
Typo members have no margin and no `spacing` prop. Wrap long-form text in `Prose`:
|
|
49
|
+
|
|
50
|
+
```diff
|
|
51
|
+
- <div>
|
|
52
|
+
+ <Prose>
|
|
53
|
+
<Typo.H2>Export</Typo.H2>
|
|
54
|
+
<Typo.P>Pick a format, then a destination.</Typo.P>
|
|
55
|
+
- </div>
|
|
56
|
+
+ </Prose>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Delete `spacing="none"`, which is now the only behavior:
|
|
60
|
+
|
|
61
|
+
```diff
|
|
62
|
+
- <Typo.P spacing="none">Your study is ready.</Typo.P>
|
|
63
|
+
+ <Typo.P>Your study is ready.</Typo.P>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`Callout.Root`, `Table.Root`, `Code.Block`, and `Separator` have no margin either. Space them with a gap, or put them inside
|
|
67
|
+
`Prose`:
|
|
68
|
+
|
|
69
|
+
```diff
|
|
70
|
+
- <div>
|
|
71
|
+
+ <Stack gap="3">
|
|
72
|
+
<Callout.Root>…</Callout.Root>
|
|
73
|
+
- <Separator spacing="large" />
|
|
74
|
+
+ <Separator />
|
|
75
|
+
<Table.Root>…</Table.Root>
|
|
76
|
+
- </div>
|
|
77
|
+
+ </Stack>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Breaking
|
|
81
|
+
|
|
82
|
+
- **Breaking:** Web UI components have no outer margin. `Stack` and `Row` gaps space UI, and `Prose` spaces long-form text. — Nikolaus Brunner <brunner@imfusion.com>
|
|
83
|
+
- Block `Typo` members (`Hero`, `H1`–`H4`, `P`, `Lead`, `Blockquote`, and the lists) have no default margin and no
|
|
84
|
+
`spacing` prop.
|
|
85
|
+
- `Callout.Root`, `Table.Root`, and `Code.Block` have no bottom margin.
|
|
86
|
+
- `Separator` has no `spacing` prop.
|
|
4
87
|
|
|
5
88
|
### Added
|
|
6
89
|
|
|
@@ -11,16 +94,29 @@
|
|
|
11
94
|
|
|
12
95
|
- Components — Nikolaus Brunner <brunner@imfusion.com>
|
|
13
96
|
- `Drawer` draws its open-edge border at `--imf-ui-border-size-1`.
|
|
97
|
+
- `NavigationMenu.InlineSubmenu` spaces its rail and detail pane with one flyout padding.
|
|
14
98
|
- Agent skills — Nikolaus Brunner <brunner@imfusion.com>
|
|
99
|
+
- `imf-web-ui-conventions` says when a locked field uses `readOnly`, `disabled`, or plain text.
|
|
15
100
|
- `imf-web-ui-update` measures the delta from a prerelease baseline by diffing the old package's types and styles.
|
|
101
|
+
- The component and story dev skills name the Storybook CLI command for each lookup and check, and route only pixels, DOM,
|
|
102
|
+
focus, and console checks to Chrome DevTools.
|
|
103
|
+
- `web-ui-dev-new-component` checks existing primitives before any upstream lookup, for a URL or a description, and routes
|
|
104
|
+
a partial match to `web-ui-dev-update-component`.
|
|
16
105
|
|
|
17
106
|
### Fixed
|
|
18
107
|
|
|
19
108
|
- Storybook — Nikolaus Brunner <brunner@imfusion.com>
|
|
20
109
|
- Nested sidebar groups and components indent under their parent group.
|
|
110
|
+
- Sidebar components line up with the stories and docs beside them.
|
|
111
|
+
- The showcase keeps a gap between its content and the docked token drawer.
|
|
112
|
+
- The showcase docks the token drawer from the `xl` breakpoint, so its navigation strip fits beside it.
|
|
21
113
|
- Font choices in the token drawer persist in the URL.
|
|
114
|
+
- The sidebar and panes stay visible while the sidebar is resized.
|
|
115
|
+
- The sidebar keeps a minimum width that fits its section labels.
|
|
116
|
+
- The preview stays dark while a page loads in dark mode.
|
|
22
117
|
- Agent skills — Nikolaus Brunner <brunner@imfusion.com>
|
|
23
118
|
- `npx web-ui install skills` formats the skill version markers with the project's Prettier.
|
|
119
|
+
- `imf-web-ui-audit` has a checklist box for every tooling section, including Vite plugins.
|
|
24
120
|
|
|
25
121
|
---
|
|
26
122
|
|
package/README.md
CHANGED
|
@@ -87,3 +87,35 @@ The main development skills are:
|
|
|
87
87
|
| `/web-ui-dev-claude-design-sync` | Update the design system in Claude Design. |
|
|
88
88
|
| `/web-ui-dev-teardown-worktree` | Remove a finished worktree. |
|
|
89
89
|
| `/web-ui-dev-mcp` | Recover one optional MCP capability. |
|
|
90
|
+
|
|
91
|
+
### Work on it from a consumer app
|
|
92
|
+
|
|
93
|
+
To change the library while running an app that uses it, point the app's dependency at your checkout:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
"@imfusion/web-ui": "file:../web-ui"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Run `npm install` in the app, then keep `npm run dev:lib` running here. The package resolves to `dist/`, so the app resolves
|
|
100
|
+
nothing until the first watch build has finished, and sees each later change once the rebuild has written it.
|
|
101
|
+
|
|
102
|
+
npm links the checkout instead of copying it. Without help, the app then loads two copies of React, its own and the one in
|
|
103
|
+
this checkout's `node_modules`, and every hook fails with "Invalid hook call". Register `localWebUILink` in the app's Vite
|
|
104
|
+
config to prevent that:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
import { localWebUILink } from "@imfusion/web-ui/vite";
|
|
108
|
+
|
|
109
|
+
export default defineConfig({
|
|
110
|
+
plugins: [react(), localWebUILink()]
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
It dedupes every peer dependency of the library, including `@imfusion/sdk` and `@imfusion/sdk-react`. For an installed
|
|
115
|
+
package it does nothing, so it can stay in the config.
|
|
116
|
+
|
|
117
|
+
It covers the browser in development and in the build. Server rendering, including React Router prerendering, still loads
|
|
118
|
+
dependencies through Node, which picks the checkout's React. Base UI's `use-sync-external-store` dependency is CommonJS, so
|
|
119
|
+
Popover, Select, and other stateful parts can still fail on the server.
|
|
120
|
+
|
|
121
|
+
Change the dependency back before you commit the app.
|
|
@@ -4,11 +4,8 @@ import { UpstreamLink } from './shared';
|
|
|
4
4
|
* NavigationMenu.Link — a top-strip (rail) link: a peer of `Trigger` for a
|
|
5
5
|
* section that navigates directly instead of opening a flyout. Renders an `<a>`.
|
|
6
6
|
* For a link inside a flyout, use `NavigationMenu.FlyoutLink`.
|
|
7
|
-
*
|
|
8
|
-
* A trailing `ArrowRight` slides in on hover/focus. When a custom `render` is
|
|
9
|
-
* supplied the icon is omitted — the consumer's element owns its content.
|
|
10
7
|
*/
|
|
11
|
-
export declare function Link(
|
|
8
|
+
export declare function Link(props: React.ComponentProps<typeof NavigationMenuPrimitive.Link>): import("react/jsx-runtime").JSX.Element;
|
|
12
9
|
export declare namespace Link {
|
|
13
10
|
var displayName: string;
|
|
14
11
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function Prose(props: React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -2,7 +2,6 @@ import { Separator as SeparatorPrimitive } from '@base-ui/react/separator';
|
|
|
2
2
|
import { VariantProps } from 'class-variance-authority';
|
|
3
3
|
declare const separator: (props?: ({
|
|
4
4
|
variant?: "solid" | "dashed" | "dotted" | null | undefined;
|
|
5
|
-
spacing?: "none" | "small" | "medium" | "large" | "spacious" | null | undefined;
|
|
6
5
|
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
7
6
|
interface Props extends React.ComponentProps<typeof SeparatorPrimitive>, VariantProps<typeof separator> {
|
|
8
7
|
}
|
|
@@ -12,5 +11,5 @@ interface Props extends React.ComponentProps<typeof SeparatorPrimitive>, Variant
|
|
|
12
11
|
* @see https://base-ui.com/react/components/separator
|
|
13
12
|
* @llm https://base-ui.com/react/components/separator.md
|
|
14
13
|
*/
|
|
15
|
-
export declare function Separator({ orientation, variant,
|
|
14
|
+
export declare function Separator({ orientation, variant, ...props }: Props): import("react/jsx-runtime").JSX.Element;
|
|
16
15
|
export {};
|
|
@@ -4,54 +4,50 @@ import { Code } from '../code';
|
|
|
4
4
|
declare const typo: (props?: ({
|
|
5
5
|
variant?: "primary" | "positive" | "negative" | "oncolor" | "main" | "support" | "minor" | "brand" | "warning" | "info" | "accent-1" | "accent-2" | "accent-3" | null | undefined;
|
|
6
6
|
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
7
|
-
declare const spacingVariants: (props?: ({
|
|
8
|
-
spacing?: "none" | "default" | null | undefined;
|
|
9
|
-
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
10
7
|
type TypoProps = VariantProps<typeof typo>;
|
|
11
|
-
type
|
|
12
|
-
type HeadingProps = useRender.ComponentProps<"h1"> & TypoProps & SpacingProps;
|
|
8
|
+
type HeadingProps = useRender.ComponentProps<"h1"> & TypoProps;
|
|
13
9
|
type LongHeadingProps = HeadingProps & {
|
|
14
10
|
/** Whether lines after the first use a translucent text color. */
|
|
15
11
|
fadeAfterFirstLine?: boolean;
|
|
16
12
|
};
|
|
17
|
-
type ParagraphProps = useRender.ComponentProps<"p"> & TypoProps
|
|
13
|
+
type ParagraphProps = useRender.ComponentProps<"p"> & TypoProps;
|
|
18
14
|
export type TypoLinkKind = "external" | "internal";
|
|
19
15
|
type LinkProps = useRender.ComponentProps<"a"> & TypoProps & {
|
|
20
16
|
/** Link target scope. `"external"` (default) opens in a new tab; `"internal"` stays in the current tab. */
|
|
21
17
|
kind?: TypoLinkKind;
|
|
22
18
|
};
|
|
23
19
|
/** Typo.Hero — oversized page heading. */
|
|
24
|
-
export declare function Hero({ variant,
|
|
20
|
+
export declare function Hero({ variant, fadeAfterFirstLine, render, ...props }: LongHeadingProps): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
|
|
25
21
|
export declare namespace Hero {
|
|
26
22
|
var displayName: string;
|
|
27
23
|
}
|
|
28
24
|
/** Typo.H1 — top-level page heading. */
|
|
29
|
-
export declare function H1({ variant,
|
|
25
|
+
export declare function H1({ variant, fadeAfterFirstLine, render, ...props }: LongHeadingProps): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
|
|
30
26
|
export declare namespace H1 {
|
|
31
27
|
var displayName: string;
|
|
32
28
|
}
|
|
33
29
|
/** Typo.H2 — section heading. */
|
|
34
|
-
export declare function H2({ variant,
|
|
30
|
+
export declare function H2({ variant, fadeAfterFirstLine, render, ...props }: LongHeadingProps): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
|
|
35
31
|
export declare namespace H2 {
|
|
36
32
|
var displayName: string;
|
|
37
33
|
}
|
|
38
34
|
/** Typo.H3 — sub-section heading. */
|
|
39
|
-
export declare function H3({ variant,
|
|
35
|
+
export declare function H3({ variant, render, ...props }: HeadingProps): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
|
|
40
36
|
export declare namespace H3 {
|
|
41
37
|
var displayName: string;
|
|
42
38
|
}
|
|
43
39
|
/** Typo.H4 — minor heading. */
|
|
44
|
-
export declare function H4({ variant,
|
|
40
|
+
export declare function H4({ variant, render, ...props }: HeadingProps): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
|
|
45
41
|
export declare namespace H4 {
|
|
46
42
|
var displayName: string;
|
|
47
43
|
}
|
|
48
44
|
/** Typo.P — body paragraph. */
|
|
49
|
-
export declare function P({ variant,
|
|
45
|
+
export declare function P({ variant, render, ...props }: ParagraphProps): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
|
|
50
46
|
export declare namespace P {
|
|
51
47
|
var displayName: string;
|
|
52
48
|
}
|
|
53
49
|
/** Typo.Lead — emphasised intro paragraph. */
|
|
54
|
-
export declare function Lead({ variant,
|
|
50
|
+
export declare function Lead({ variant, render, ...props }: ParagraphProps): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
|
|
55
51
|
export declare namespace Lead {
|
|
56
52
|
var displayName: string;
|
|
57
53
|
}
|
|
@@ -66,7 +62,7 @@ export declare namespace Small {
|
|
|
66
62
|
var displayName: string;
|
|
67
63
|
}
|
|
68
64
|
/** Typo.Blockquote — pulled quotation. */
|
|
69
|
-
export declare function Blockquote({ variant,
|
|
65
|
+
export declare function Blockquote({ variant, render, ...props }: useRender.ComponentProps<"blockquote"> & TypoProps): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
|
|
70
66
|
export declare namespace Blockquote {
|
|
71
67
|
var displayName: string;
|
|
72
68
|
}
|
|
@@ -89,12 +85,12 @@ export declare namespace Link {
|
|
|
89
85
|
var displayName: string;
|
|
90
86
|
}
|
|
91
87
|
/** Typo.OrderedList — numbered list. */
|
|
92
|
-
export declare function OrderedList({ variant,
|
|
88
|
+
export declare function OrderedList({ variant, render, ...props }: useRender.ComponentProps<"ol"> & TypoProps): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
|
|
93
89
|
export declare namespace OrderedList {
|
|
94
90
|
var displayName: string;
|
|
95
91
|
}
|
|
96
92
|
/** Typo.UnorderedList — bulleted list. */
|
|
97
|
-
export declare function UnorderedList({ variant,
|
|
93
|
+
export declare function UnorderedList({ variant, render, ...props }: useRender.ComponentProps<"ul"> & TypoProps): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
|
|
98
94
|
export declare namespace UnorderedList {
|
|
99
95
|
var displayName: string;
|
|
100
96
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export { AppShell, appShellMeta } from './components/app-shell';
|
|
|
15
15
|
export { Card, cardMeta } from './components/card';
|
|
16
16
|
export { Drawer, drawerMeta } from './components/drawer';
|
|
17
17
|
export { Popover, popoverMeta } from './components/popover';
|
|
18
|
+
export { Prose, proseMeta } from './components/prose';
|
|
18
19
|
export { Row, rowMeta } from './components/row';
|
|
19
20
|
export { Separator, separatorMeta } from './components/separator';
|
|
20
21
|
export { Stack, stackMeta } from './components/stack';
|