@imfusion/web-ui 0.11.1-dev.31.gb80c710e → 0.11.1-dev.35.g0028b4dd

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 CHANGED
@@ -4,6 +4,12 @@
4
4
 
5
5
  ### Added
6
6
 
7
+ - `TabNav` is a new row of links to routes with a bar under the current one, in the underline look of `Tabs`. `TabNav.Item`
8
+ renders an `<a>`, takes a router link as `render`, and sets `aria-current="page"` from `current`.
9
+ [TabNav](src/components/tab-nav/tab-nav.stories.tsx#InAProjectHeader) — Nikolaus Brunner <brunner@imfusion.com>
10
+ - `Tabs.Root` takes `appearance`: `"boxed"` (the default, unchanged) or `"underline"`, with mono labels, a 2px bar under the
11
+ active tab on a hairline rule, and an unframed panel. Underline is horizontal only; a vertical Tabs stays boxed.
12
+ [Tabs](src/components/tabs/tabs.stories.tsx#Underline) — Nikolaus Brunner <brunner@imfusion.com>
7
13
  - `Textarea` is a new multi-line input adapted from Base UI, with the `Input` variants and sizes, a drag-to-resize corner, and
8
14
  validation state from `Field`. [Textarea](src/components/textarea/textarea.mdx)
9
15
  ([WEBSDK-244](https://imfusion.atlassian.net/browse/WEBSDK-244)) — Nikolaus Brunner <brunner@imfusion.com>
@@ -22,6 +28,9 @@
22
28
  — Stephan Wenninger <wenninger@imfusion.com>
23
29
  - `Typo.UnorderedList` takes `markerVariant` to colour its dash apart from the text, such as the brand dash on main text.
24
30
  [Typo](src/components/typo/typo.stories.tsx#MarkerVariant) — Nikolaus Brunner <brunner@imfusion.com>
31
+ - Focus ring tokens: `--imf-ui-focus-ring-width`, `--imf-ui-focus-ring-color`, and two offsets for a ring outside the
32
+ element or inside it (`-offset`, `-offset-inset`).
33
+ ([WEBSDK-274](https://imfusion.atlassian.net/browse/WEBSDK-274)) — Nikolaus Brunner <brunner@imfusion.com>
25
34
 
26
35
  ### Changed
27
36
 
@@ -29,6 +38,21 @@
29
38
  primary, with no outline. [Input](src/components/input/input.mdx) — Nikolaus Brunner <brunner@imfusion.com>
30
39
  - `Drawer` draws no border by default; `borderColor` adds one, such as `borderColor="primary"` for the previous look.
31
40
  [Drawer](src/components/drawer/drawer.mdx) — Nikolaus Brunner <brunner@imfusion.com>
41
+ - Focus ring ([WEBSDK-274](https://imfusion.atlassian.net/browse/WEBSDK-274)) — Nikolaus Brunner <brunner@imfusion.com>
42
+ - Every component draws the same focus ring from the focus ring tokens, and popups draw none.
43
+ - Navigation items and toasts draw the ring fully inside the item.
44
+ - A focused `Toggle` draws no box: its icon turns bolder and its label underlined, in primary unless pressed.
45
+ - An open `Select` trigger keeps its surface and turns its border primary instead of filling with primary.
46
+ - A focused `Tabs.Tab` underlines its label instead of drawing a box that looks like the active indicator. A focused
47
+ `Tabs.Panel` tints together with the active tab instead of drawing a second line inside its border.
48
+ - The branded `AppShell` header and navbar draw a light ring. A focused `AppShell.NavItem` shows its active underline at
49
+ double thickness instead of an outline.
50
+ - A light ring shows on blue fills: an active or open `NavigationMenu` link or trigger, and the `oncolor` context of
51
+ `Button`, `AccountCard`, and `Typo`.
52
+ - `AppShell.Burger` draws the primary ring on default surfaces, where it used the text colour.
53
+ - A focused chamfered `Button` shows its hover state, and `Code.Block`'s copy button colours its icon; a ring cannot
54
+ show through their clip-path.
55
+ - `Code`'s inline copy button shows the ring in place of the browser default.
32
56
  - `Typo.UnorderedList` draws its dash in the text colour by default; `markerVariant="primary"` gives the brand dash.
33
57
  — Nikolaus Brunner <brunner@imfusion.com>
34
58
  - `Callout.Root` defaults to `maxWidth="lg"`, keeps a minimum width of 15rem, and spaces its title, description, and list
@@ -66,6 +90,7 @@
66
90
  as `docs/story-conventions.md` describes.
67
91
  - Combobox and Autocomplete stories start at the same top-left corner, so clicking through them does not shift the
68
92
  layout. A story resizes its frame with `parameters.frame`, which `withFrame` reads.
93
+ - The Autocomplete interaction test reads the popup's height after it reopens, so it passes on every run.
69
94
 
70
95
  ### Fixed
71
96
 
@@ -0,0 +1,2 @@
1
+ export * as TabNav from './tab-nav';
2
+ export { tabNavMeta } from './tab-nav.meta';
@@ -0,0 +1,26 @@
1
+ import { useRender } from '@base-ui/react/use-render';
2
+ interface RootProps extends React.ComponentProps<"nav"> {
3
+ /** Names the navigation for screen readers, such as "Project". */
4
+ "aria-label": string;
5
+ }
6
+ /**
7
+ * TabNav.Root — a `<nav>` of links that draws the hairline under its items. Give it an `aria-label` that names the
8
+ * navigation, such as "Project".
9
+ * Not based on any upstream component.
10
+ */
11
+ export declare function Root(props: RootProps): import("react/jsx-runtime").JSX.Element;
12
+ export declare namespace Root {
13
+ var displayName: string;
14
+ }
15
+ type ItemProps = useRender.ComponentProps<"a"> & {
16
+ /** Marks the item as the page the user is on: sets `aria-current="page"` and `data-current`, and draws the bar. */
17
+ current?: boolean;
18
+ };
19
+ /**
20
+ * TabNav.Item — a link in the row. Renders an `<a>`; pass a router link as `render` to navigate without a page load.
21
+ */
22
+ export declare function Item({ current, render, ...props }: ItemProps): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
23
+ export declare namespace Item {
24
+ var displayName: string;
25
+ }
26
+ export {};
@@ -0,0 +1,2 @@
1
+ import { ComponentMeta } from '../../types/meta';
2
+ export declare const tabNavMeta: ComponentMeta;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * The underline look shared by `Tabs` (appearance `"underline"`) and `TabNav`, which renders it on links. Keeping it here
3
+ * avoids cross-component imports between the two.
4
+ */
5
+ export declare const tabsUnderlineRule: (props?: import('class-variance-authority/types').ClassProp | undefined) => string;
6
+ export declare const tabsUnderlineItem: (props?: import('class-variance-authority/types').ClassProp | undefined) => string;
@@ -2,18 +2,27 @@ import { Tabs as TabsPrimitive } from '@base-ui/react/tabs';
2
2
  import { VariantProps } from 'class-variance-authority';
3
3
  declare const tabsList: (props?: ({
4
4
  fill?: boolean | null | undefined;
5
+ appearance?: "underline" | "boxed" | null | undefined;
5
6
  } & import('class-variance-authority/types').ClassProp) | undefined) => string;
7
+ type TabsAppearance = "boxed" | "underline";
8
+ interface RootProps extends React.ComponentProps<typeof TabsPrimitive.Root> {
9
+ /**
10
+ * `"boxed"` outlines the active tab in a box that fuses into a framed panel. `"underline"` marks it with a bar under
11
+ * its label on a hairline rule, with an unframed panel. Underline is horizontal only: a vertical Tabs stays boxed.
12
+ */
13
+ appearance?: TabsAppearance;
14
+ }
6
15
  /**
7
16
  * Tabs.Root — container that manages the active tab value and orientation context.
8
17
  *
9
18
  * @see https://base-ui.com/react/components/tabs
10
19
  * @llm https://base-ui.com/react/components/tabs.md
11
20
  */
12
- export declare function Root(props: React.ComponentProps<typeof TabsPrimitive.Root>): import("react/jsx-runtime").JSX.Element;
21
+ export declare function Root({ appearance, ...props }: RootProps): import("react/jsx-runtime").JSX.Element;
13
22
  export declare namespace Root {
14
23
  var displayName: string;
15
24
  }
16
- interface ListProps extends React.ComponentProps<typeof TabsPrimitive.List>, VariantProps<typeof tabsList> {
25
+ interface ListProps extends React.ComponentProps<typeof TabsPrimitive.List>, Pick<VariantProps<typeof tabsList>, "fill"> {
17
26
  /**
18
27
  * Give every tab an equal share of the list's length (equal width when
19
28
  * horizontal). When vertical, this only takes effect if the list is stretched
@@ -32,7 +41,7 @@ export declare namespace Tab {
32
41
  var displayName: string;
33
42
  }
34
43
  /**
35
- * Tabs.Indicator — the bordered box marking the active tab, positioned via
44
+ * Tabs.Indicator — the bordered box (boxed) or bar (underline) marking the active tab, positioned via
36
45
  * the `--active-tab-*` CSS custom properties Base UI writes onto it. Render
37
46
  * once per Tabs.List, after the Tabs.Tab list.
38
47
  */
@@ -43,7 +52,7 @@ export declare namespace Indicator {
43
52
  /**
44
53
  * Tabs.PanelViewport — the shared frame Tabs.Panel elements render inside.
45
54
  * No Base UI equivalent exists; it's surfaced as a named part since its
46
- * hairline border is what Tabs.Indicator visually fuses into.
55
+ * hairline border is what the boxed Tabs.Indicator visually fuses into. The underline appearance draws no frame.
47
56
  */
48
57
  export declare function PanelViewport(props: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
49
58
  export declare namespace PanelViewport {
package/dist/index.d.ts CHANGED
@@ -41,6 +41,7 @@ export { NavigationMenu, navigationMenuMeta } from './components/navigation-menu
41
41
  export { Skeleton, skeletonMeta } from './components/skeleton';
42
42
  export { Spinner, spinnerMeta } from './components/spinner';
43
43
  export { Table, tableMeta } from './components/table';
44
+ export { TabNav, tabNavMeta } from './components/tab-nav';
44
45
  export { Tabs, tabsMeta } from './components/tabs';
45
46
  export { Toast, toastMeta } from './components/toast';
46
47
  export { Tooltip, tooltipMeta } from './components/tooltip';