@viraui/react 2026.9.0 → 2026.10.0-next.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/dist/catalog.json +9 -3
- package/dist/components/index.d.ts +1 -0
- package/dist/components/prose/prose.css +1 -1
- package/dist/components/prose/prose.d.ts +8 -0
- package/dist/components/prose/prose.js +2 -1
- package/dist/components/tabs/tabs-list.js +29 -23
- package/dist/components/tabs/tabs-size-context.d.ts +4 -0
- package/dist/components/tabs/tabs-size-context.js +7 -0
- package/dist/components/tabs/tabs-tab.js +21 -16
- package/dist/components/tabs/tabs.d.ts +7 -0
- package/dist/components/tabs/tabs.js +12 -8
- package/dist/components/text/text.css +2 -2
- package/dist/components/text/text.d.ts +9 -6
- package/dist/components/text/text.js +2 -2
- package/dist/components/title/title.css +2 -2
- package/dist/components/title/title.d.ts +9 -6
- package/dist/components/title/title.js +2 -2
- package/dist/components/toggle-group/toggle-group.d.ts +3 -1
- package/dist/components/toggle-text-button/index.d.ts +2 -0
- package/dist/components/toggle-text-button/toggle-text-button.d.ts +27 -0
- package/dist/components/toggle-text-button/toggle-text-button.js +24 -0
- package/dist/index.js +2 -1
- package/dist/specs/components/icon-button/props.xml +2 -1
- package/dist/specs/components/icon-button/usage.xml +2 -1
- package/dist/specs/components/prose/meta.xml +1 -1
- package/dist/specs/components/prose/patterns.xml +1 -1
- package/dist/specs/components/prose/props.xml +8 -2
- package/dist/specs/components/prose/usage.xml +2 -1
- package/dist/specs/components/tabs/props.xml +3 -0
- package/dist/specs/components/tabs/usage.xml +1 -0
- package/dist/specs/components/text/meta.xml +1 -1
- package/dist/specs/components/text/patterns.xml +11 -11
- package/dist/specs/components/text/props.xml +10 -7
- package/dist/specs/components/text/usage.xml +2 -2
- package/dist/specs/components/title/meta.xml +1 -1
- package/dist/specs/components/title/patterns.xml +8 -8
- package/dist/specs/components/title/props.xml +10 -7
- package/dist/specs/components/title/usage.xml +3 -3
- package/dist/specs/components/toggle-button/props.xml +2 -0
- package/dist/specs/components/toggle-button/usage.xml +2 -0
- package/dist/specs/components/toggle-group/patterns.xml +2 -1
- package/dist/specs/components/toggle-group/usage.xml +5 -5
- package/dist/specs/components/toggle-text-button/a11y.xml +8 -0
- package/dist/specs/components/toggle-text-button/meta.xml +19 -0
- package/dist/specs/components/toggle-text-button/patterns.xml +44 -0
- package/dist/specs/components/toggle-text-button/props.xml +58 -0
- package/dist/specs/components/toggle-text-button/usage.xml +13 -0
- package/dist/specs/index.xml +14 -4
- package/package.json +2 -2
package/dist/catalog.json
CHANGED
|
@@ -185,7 +185,7 @@
|
|
|
185
185
|
{
|
|
186
186
|
"id": "prose",
|
|
187
187
|
"name": "Prose",
|
|
188
|
-
"summary": "Text-wall grouping region (articles, docs, privacy) with heading-aware em rhythm
|
|
188
|
+
"summary": "Text-wall grouping region (articles, docs, privacy) with heading-aware em rhythm, region `wrap` (default `pretty`), and reading column via parent Stack `maxWidth` sized for body Text `size`.",
|
|
189
189
|
"agentDocs": "./specs/components/prose/meta.xml"
|
|
190
190
|
},
|
|
191
191
|
{
|
|
@@ -263,7 +263,7 @@
|
|
|
263
263
|
{
|
|
264
264
|
"id": "text",
|
|
265
265
|
"name": "Text",
|
|
266
|
-
"summary": "Theme-aware body-copy primitive with tone, family, sizing, and readable-measure props (`maxWidth` / `lineHeight` / `
|
|
266
|
+
"summary": "Theme-aware body-copy primitive with tone, family, sizing, and readable-measure props (`maxWidth` / `lineHeight` / `wrap`).",
|
|
267
267
|
"agentDocs": "./specs/components/text/meta.xml"
|
|
268
268
|
},
|
|
269
269
|
{
|
|
@@ -281,7 +281,7 @@
|
|
|
281
281
|
{
|
|
282
282
|
"id": "title",
|
|
283
283
|
"name": "Title",
|
|
284
|
-
"summary": "Theme-aware heading and display typography with readable-measure props (`maxWidth` / `lineHeight` / `
|
|
284
|
+
"summary": "Theme-aware heading and display typography with readable-measure props (`maxWidth` / `lineHeight` / `wrap`).",
|
|
285
285
|
"agentDocs": "./specs/components/title/meta.xml"
|
|
286
286
|
},
|
|
287
287
|
{
|
|
@@ -302,6 +302,12 @@
|
|
|
302
302
|
"summary": "Toolbar toggle set with shared selection state; Stack direction follows orientation with zero default gap.",
|
|
303
303
|
"agentDocs": "./specs/components/toggle-group/meta.xml"
|
|
304
304
|
},
|
|
305
|
+
{
|
|
306
|
+
"id": "toggle-text-button",
|
|
307
|
+
"name": "ToggleTextButton",
|
|
308
|
+
"summary": "Labeled two-state toggle on Base UI Toggle with Button chrome; visible text children, optional addon / pressedVariant; no resting/pressed icon pair.",
|
|
309
|
+
"agentDocs": "./specs/components/toggle-text-button/meta.xml"
|
|
310
|
+
},
|
|
305
311
|
{
|
|
306
312
|
"id": "typewriter",
|
|
307
313
|
"name": "Typewriter",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-prose-align{syntax:"*";inherits:false;initial-value:start}@property --vui-prose-gap-blocks{syntax:"<length>";inherits:true;initial-value:2em}@property --vui-prose-gap-heading-start{syntax:"<length>";inherits:true;initial-value:1.3em}@property --vui-prose-gap-heading-end{syntax:"<length>";inherits:true;initial-value:.8em}.viraui__prose-module__Prose_8yO9h{--vui-prose-gap-blocks:2em;--vui-prose-gap-heading-start:1.3em;--vui-prose-gap-heading-end:0.8em;&[data-prose-gap=s]{--vui-prose-gap-blocks:1em;--vui-prose-gap-heading-start:0.7em;--vui-prose-gap-heading-end:0.3em}&[data-prose-gap=m]{--vui-prose-gap-blocks:1.5em;--vui-prose-gap-heading-start:1em;--vui-prose-gap-heading-end:0.6em}
|
|
1
|
+
@layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-prose-align{syntax:"*";inherits:false;initial-value:start}@property --vui-prose-wrap{syntax:"*";inherits:true;initial-value:pretty}@property --vui-prose-gap-blocks{syntax:"<length>";inherits:true;initial-value:2em}@property --vui-prose-gap-heading-start{syntax:"<length>";inherits:true;initial-value:1.3em}@property --vui-prose-gap-heading-end{syntax:"<length>";inherits:true;initial-value:.8em}.viraui__prose-module__Prose_8yO9h{--vui-prose-gap-blocks:2em;--vui-prose-gap-heading-start:1.3em;--vui-prose-gap-heading-end:0.8em;&[data-prose-gap=s]{--vui-prose-gap-blocks:1em;--vui-prose-gap-heading-start:0.7em;--vui-prose-gap-heading-end:0.3em}&[data-prose-gap=m]{--vui-prose-gap-blocks:1.5em;--vui-prose-gap-heading-start:1em;--vui-prose-gap-heading-end:0.6em}text-wrap:var(--vui-prose-wrap);&[data-prose-has-align=true]{text-align:var(--vui-prose-align)}&>:is(h1,h2,h3,h4,h5,h6,hgroup,ul,ol,dd,p,figure,img,pre,table,fieldset,blockquote,picture,div):where(:not(:first-child)){margin-block:var(--vui-prose-gap-blocks)}&>:is(h1,h2,h3,h4,h5,h6)+*{margin-block-start:var(--vui-prose-gap-heading-start)}&>:is(h1,h2,h3,h4,h5,h6){margin-block-end:var(--vui-prose-gap-heading-end);text-box:trim-both cap alphabetic}}}
|
|
@@ -25,6 +25,14 @@ export type ProseProps = React.ComponentPropsWithoutRef<'div'> & {
|
|
|
25
25
|
* @defaultValue Inherits parent `text-align`.
|
|
26
26
|
*/
|
|
27
27
|
align?: React.CSSProperties['textAlign'];
|
|
28
|
+
/**
|
|
29
|
+
* Controls CSS `text-wrap` on the Prose root (inherits to descendants unless a child overrides).
|
|
30
|
+
* Default `pretty` for orphan-aware article walls. Prefer `balance` only on short multi-line
|
|
31
|
+
* blocks that need even line lengths. Single-line metrics stay on child Text/Title `whiteSpace`.
|
|
32
|
+
*
|
|
33
|
+
* @defaultValue 'pretty'
|
|
34
|
+
*/
|
|
35
|
+
wrap?: React.CSSProperties['textWrap'];
|
|
28
36
|
/**
|
|
29
37
|
* Replaces the default `div` root using Base UI render semantics.
|
|
30
38
|
*
|
|
@@ -4,10 +4,11 @@ import { clsx } from "../../core/clsx.js";
|
|
|
4
4
|
import prose_module_default from "./prose.module.js";
|
|
5
5
|
import { useRender } from "@base-ui/react/use-render";
|
|
6
6
|
//#region src/components/prose/prose.tsx
|
|
7
|
-
var Prose = ({ align, className, gap = "l", ref, render, style, ...otherProps }) => {
|
|
7
|
+
var Prose = ({ align, className, gap = "l", ref, render, style, wrap = "pretty", ...otherProps }) => {
|
|
8
8
|
const hasAlign = align !== void 0;
|
|
9
9
|
const dynamicStyle = {
|
|
10
10
|
...hasAlign && { "--vui-prose-align": align },
|
|
11
|
+
"--vui-prose-wrap": wrap,
|
|
11
12
|
...style
|
|
12
13
|
};
|
|
13
14
|
return useRender({
|
|
@@ -3,31 +3,37 @@ import { Stack } from "../stack/stack.js";
|
|
|
3
3
|
import { Surface } from "../surface/surface.js";
|
|
4
4
|
import tabs_module_default from "./tabs.module.js";
|
|
5
5
|
import { TabsIndicator } from "./tabs-indicator.js";
|
|
6
|
+
import { useTabsSize } from "./tabs-size-context.js";
|
|
6
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
8
|
import { Tabs } from "@base-ui/react/tabs";
|
|
8
9
|
//#region src/components/tabs/tabs-list.tsx
|
|
9
|
-
var TabsList = ({ children, className, activateOnFocus = true, ref, ...otherProps }) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
10
|
+
var TabsList = ({ children, className, activateOnFocus = true, ref, ...otherProps }) => {
|
|
11
|
+
const size = useTabsSize();
|
|
12
|
+
const listRadius = size === "s" ? "s" : "m";
|
|
13
|
+
return /* @__PURE__ */ jsxs(Tabs.List, {
|
|
14
|
+
className: clsx(tabs_module_default.List, className),
|
|
15
|
+
activateOnFocus,
|
|
16
|
+
"data-size": size,
|
|
17
|
+
render: /* @__PURE__ */ jsx(Surface, {
|
|
18
|
+
color: 1,
|
|
19
|
+
border: "all",
|
|
20
|
+
radius: listRadius,
|
|
21
|
+
vPadding: "2xs"
|
|
22
|
+
}),
|
|
23
|
+
ref,
|
|
24
|
+
...otherProps,
|
|
25
|
+
children: [/* @__PURE__ */ jsx(TabsIndicator, {}), /* @__PURE__ */ jsx("div", {
|
|
26
|
+
className: tabs_module_default.Track,
|
|
27
|
+
children: /* @__PURE__ */ jsx(Stack, {
|
|
28
|
+
expandChildren: true,
|
|
29
|
+
fullWidth: true,
|
|
30
|
+
direction: "row",
|
|
31
|
+
hAlign: "start",
|
|
32
|
+
vAlign: "center",
|
|
33
|
+
children
|
|
34
|
+
})
|
|
35
|
+
})]
|
|
36
|
+
});
|
|
37
|
+
};
|
|
32
38
|
//#endregion
|
|
33
39
|
export { TabsList };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
//#region src/components/tabs/tabs-size-context.ts
|
|
4
|
+
var TabsSizeContext = createContext("m");
|
|
5
|
+
var useTabsSize = () => useContext(TabsSizeContext);
|
|
6
|
+
//#endregion
|
|
7
|
+
export { TabsSizeContext, useTabsSize };
|
|
@@ -2,24 +2,29 @@ import { clsx } from "../../core/clsx.js";
|
|
|
2
2
|
import { Text } from "../text/text.js";
|
|
3
3
|
import { Button } from "../button/button.js";
|
|
4
4
|
import tabs_module_default from "./tabs.module.js";
|
|
5
|
+
import { useTabsSize } from "./tabs-size-context.js";
|
|
5
6
|
import { jsx } from "react/jsx-runtime";
|
|
6
7
|
import { Tabs } from "@base-ui/react/tabs";
|
|
7
8
|
//#region src/components/tabs/tabs-tab.tsx
|
|
8
|
-
var TabsTab = ({ addon, addonPosition = "start", children, className, ...otherProps }) =>
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
9
|
+
var TabsTab = ({ addon, addonPosition = "start", children, className, ...otherProps }) => {
|
|
10
|
+
const size = useTabsSize();
|
|
11
|
+
return /* @__PURE__ */ jsx(Tabs.Tab, {
|
|
12
|
+
render: /* @__PURE__ */ jsx(Button, {
|
|
13
|
+
variant: "flat",
|
|
14
|
+
size,
|
|
15
|
+
addon,
|
|
16
|
+
addonPosition,
|
|
17
|
+
className: clsx(tabs_module_default.Item, className)
|
|
18
|
+
}),
|
|
19
|
+
...otherProps,
|
|
20
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
21
|
+
fluid: false,
|
|
22
|
+
tone: "muted",
|
|
23
|
+
whiteSpace: "nowrap",
|
|
24
|
+
className: tabs_module_default.Label,
|
|
25
|
+
children
|
|
26
|
+
})
|
|
27
|
+
});
|
|
28
|
+
};
|
|
24
29
|
//#endregion
|
|
25
30
|
export { TabsTab };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { TabsRoot } from '@base-ui/react/tabs';
|
|
2
2
|
import { StackProps } from '..';
|
|
3
|
+
import { ButtonProps } from '../button/button';
|
|
3
4
|
import { TabsListProps } from './tabs-list';
|
|
4
5
|
import { TabsPanelProps } from './tabs-panel';
|
|
5
6
|
import { TabsTabProps } from './tabs-tab';
|
|
@@ -20,6 +21,12 @@ export type TabsProps = TabsRoot.Props & {
|
|
|
20
21
|
* @defaultValue 'start'
|
|
21
22
|
*/
|
|
22
23
|
listAlignment?: Extract<StackProps['hAlign'], 'start' | 'center' | 'end' | 'stretch'>;
|
|
24
|
+
/**
|
|
25
|
+
* Shared visual size for tab items (`Button`) and the active indicator footprint.
|
|
26
|
+
*
|
|
27
|
+
* @defaultValue 'm'
|
|
28
|
+
*/
|
|
29
|
+
size?: ButtonProps['size'];
|
|
23
30
|
};
|
|
24
31
|
type TabsComponent = React.FC<TabsProps> & {
|
|
25
32
|
List: React.FC<TabsListProps>;
|
|
@@ -2,6 +2,7 @@ import './tabs.css';
|
|
|
2
2
|
import { clsx } from "../../core/clsx.js";
|
|
3
3
|
import { Stack } from "../stack/stack.js";
|
|
4
4
|
import tabs_module_default from "./tabs.module.js";
|
|
5
|
+
import { TabsSizeContext } from "./tabs-size-context.js";
|
|
5
6
|
import { TabsList } from "./tabs-list.js";
|
|
6
7
|
import { TabsPanel } from "./tabs-panel.js";
|
|
7
8
|
import { TabsTab } from "./tabs-tab.js";
|
|
@@ -10,14 +11,17 @@ import { jsx } from "react/jsx-runtime";
|
|
|
10
11
|
import "react";
|
|
11
12
|
import { Tabs } from "@base-ui/react/tabs";
|
|
12
13
|
//#region src/components/tabs/tabs.tsx
|
|
13
|
-
var TabsRootComponent = ({ children, className, listAlignment = "start", ...otherProps }) => /* @__PURE__ */ jsx(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
var TabsRootComponent = ({ children, className, listAlignment = "start", size = "m", ...otherProps }) => /* @__PURE__ */ jsx(TabsSizeContext.Provider, {
|
|
15
|
+
value: size,
|
|
16
|
+
children: /* @__PURE__ */ jsx(Tabs.Root, {
|
|
17
|
+
render: /* @__PURE__ */ jsx(Stack, {
|
|
18
|
+
hAlign: listAlignment,
|
|
19
|
+
vAlign: "start",
|
|
20
|
+
className: clsx(tabs_module_default.Tabs, className)
|
|
21
|
+
}),
|
|
22
|
+
...otherProps,
|
|
23
|
+
children
|
|
24
|
+
})
|
|
21
25
|
});
|
|
22
26
|
var Tabs$1 = Object.assign(TabsRootComponent, {
|
|
23
27
|
List: TabsList,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
@layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-text-align{syntax:"*";inherits:false;initial-value:start}@property --vui-text-max-width{syntax:"*";inherits:false;initial-value:none}@property --vui-text-literal-color{syntax:"<color>";inherits:false;initial-value:#0000}@property --vui-text-white-space{syntax:"*";inherits:false;initial-value:normal}@property --vui-text-letter-spacing{syntax:"normal | <length>";inherits:false;initial-value:normal}@property --vui-text-text-transform{syntax:"none | capitalize | uppercase | lowercase";inherits:false;initial-value:none}@property --vui-text-font-weight{syntax:"<number>";inherits:false;initial-value:400}@property --vui-text-font-width{syntax:"<number>";inherits:false;initial-value:100}@property --vui-text-font-opsz{syntax:"<number>";inherits:false;initial-value:16}@property --vui-text-trim{syntax:"*";inherits:false;initial-value:trim-both}@property --vui-text-trim-type{syntax:"*";inherits:false;initial-value:cap alphabetic}@property --vui-text-padding-inline-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-text-padding-inline-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-text-padding-block-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-text-padding-block-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-text-font-size{syntax:"<length>";inherits:false;initial-value:1rem}@property --vui-text-font-family{syntax:"*";inherits:false;initial-value:sans-serif}@property --vui-text-line-height{syntax:"normal | <number> | <length-percentage>";inherits:false;initial-value:normal}@property --__text-fluid{syntax:"<number>";inherits:false;initial-value:0}@property --__text-size-min{syntax:"<length>";inherits:false;initial-value:1rem}@property --__text-size-max{syntax:"<length>";inherits:false;initial-value:1rem}.viraui__text-module__Text_bS8kv{--__text-fluid:calc((100vi - 320px) / 1125px);--__text-size-min:var(--font-scale-body-s);--__text-size-max:var(--font-scale-body-m);--vui-text-font-size:clamp(
|
|
1
|
+
@layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-text-align{syntax:"*";inherits:false;initial-value:start}@property --vui-text-max-width{syntax:"*";inherits:false;initial-value:none}@property --vui-text-literal-color{syntax:"<color>";inherits:false;initial-value:#0000}@property --vui-text-white-space{syntax:"*";inherits:false;initial-value:normal}@property --vui-text-wrap{syntax:"*";inherits:false;initial-value:pretty}@property --vui-text-letter-spacing{syntax:"normal | <length>";inherits:false;initial-value:normal}@property --vui-text-text-transform{syntax:"none | capitalize | uppercase | lowercase";inherits:false;initial-value:none}@property --vui-text-font-weight{syntax:"<number>";inherits:false;initial-value:400}@property --vui-text-font-width{syntax:"<number>";inherits:false;initial-value:100}@property --vui-text-font-opsz{syntax:"<number>";inherits:false;initial-value:16}@property --vui-text-trim{syntax:"*";inherits:false;initial-value:trim-both}@property --vui-text-trim-type{syntax:"*";inherits:false;initial-value:cap alphabetic}@property --vui-text-padding-inline-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-text-padding-inline-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-text-padding-block-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-text-padding-block-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-text-font-size{syntax:"<length>";inherits:false;initial-value:1rem}@property --vui-text-font-family{syntax:"*";inherits:false;initial-value:sans-serif}@property --vui-text-line-height{syntax:"normal | <number> | <length-percentage>";inherits:false;initial-value:normal}@property --__text-fluid{syntax:"<number>";inherits:false;initial-value:0}@property --__text-size-min{syntax:"<length>";inherits:false;initial-value:1rem}@property --__text-size-max{syntax:"<length>";inherits:false;initial-value:1rem}.viraui__text-module__Text_bS8kv{--__text-fluid:calc((100vi - 320px) / 1125px);--__text-size-min:var(--font-scale-body-s);--__text-size-max:var(--font-scale-body-m);--vui-text-font-size:clamp(
|
|
2
2
|
var(--__text-size-min),
|
|
3
3
|
calc(var(--__text-size-min) + (var(--__text-size-max) - var(--__text-size-min)) * var(--__text-fluid)),
|
|
4
4
|
var(--__text-size-max)
|
|
5
|
-
);--vui-text-font-family:var(--font-family-body);--vui-text-line-height:var(--font-leading-m);margin:0;max-inline-size:var(--vui-text-max-width);font-family:var(--vui-text-font-family);font-size:var(--vui-text-font-size);line-height:var(--vui-text-line-height);letter-spacing:var(--vui-text-letter-spacing);text-transform:var(--vui-text-text-transform);white-space:var(--vui-text-white-space);word-break:break-word;font-weight:var(--vui-text-font-weight);font-stretch:calc(var(--vui-text-font-width) * 1%);font-optical-sizing:auto;font-variation-settings:"wght" var(--vui-text-font-weight),"wdth" var(--vui-text-font-width),"opsz" var(--vui-text-font-opsz);text-box:var(--vui-text-trim) var(--vui-text-trim-type);&[data-text-
|
|
5
|
+
);--vui-text-font-family:var(--font-family-body);--vui-text-line-height:var(--font-leading-m);margin:0;max-inline-size:var(--vui-text-max-width);font-family:var(--vui-text-font-family);font-size:var(--vui-text-font-size);line-height:var(--vui-text-line-height);letter-spacing:var(--vui-text-letter-spacing);text-transform:var(--vui-text-text-transform);text-wrap:var(--vui-text-wrap);white-space:var(--vui-text-white-space);word-break:break-word;font-weight:var(--vui-text-font-weight);font-stretch:calc(var(--vui-text-font-width) * 1%);font-optical-sizing:auto;font-variation-settings:"wght" var(--vui-text-font-weight),"wdth" var(--vui-text-font-width),"opsz" var(--vui-text-font-opsz);text-box:var(--vui-text-trim) var(--vui-text-trim-type);&[data-text-selection=false]{-webkit-user-select:none;user-select:none}&[data-text-has-align=true]{text-align:var(--vui-text-align)}&[data-text-has-padding=true]{padding:var(--vui-text-padding-block-start) var(--vui-text-padding-inline-end) var(--vui-text-padding-block-end) var(--vui-text-padding-inline-start)}&[data-text-family=mono]{--vui-text-font-family:var(--font-family-mono)}&[data-text-size="4xl"]{--__text-size-min:var(--font-scale-body-3xl);--__text-size-max:var(--font-scale-body-4xl)}&[data-text-size="3xl"]{--__text-size-min:var(--font-scale-body-2xl);--__text-size-max:var(--font-scale-body-3xl)}&[data-text-size="2xl"]{--__text-size-min:var(--font-scale-body-xl);--__text-size-max:var(--font-scale-body-2xl)}&[data-text-size=xl]{--__text-size-min:var(--font-scale-body-l);--__text-size-max:var(--font-scale-body-xl)}&[data-text-size=l]{--__text-size-min:var(--font-scale-body-m);--__text-size-max:var(--font-scale-body-l)}&[data-text-size=s]{--__text-size-min:var(--font-scale-body-s);--__text-size-max:var(--font-scale-body-s)}&[data-text-size=xs]{--__text-size-min:var(--font-scale-body-xs);--__text-size-max:var(--font-scale-body-xs)}& .viraui__text-module__Text_bS8kv:not([data-text-size]){font-size:inherit}& .viraui__text-module__Text_bS8kv:not([data-text-line-height]){line-height:inherit}&[data-text-fluid=false]{--vui-text-font-size:var(--__text-size-max)}@container root style(--effect-fluid-typography: initial){--vui-text-font-size:var(--__text-size-max)}&[data-text-weight=light]{--vui-text-font-weight:200}&[data-text-weight=semibold]{--vui-text-font-weight:600}&[data-text-weight=bold]{--vui-text-font-weight:800}&[data-text-tone=primary]{color:var(--global-primary)}&[data-text-tone=muted]{color:var(--global-muted)}&[data-text-tone=interactive]{color:var(--global-interactive-text)}&[data-text-tone=positive]{color:var(--highlight-green)}&[data-text-tone=informative]{color:var(--highlight-blue)}&[data-text-tone=danger]{color:var(--highlight-red)}&[data-text-tone=warning]{color:var(--highlight-yellow)}&[data-text-has-literal-color=true]{color:var(--vui-text-literal-color)}&[data-text-line-height=none]{--vui-text-line-height:0}&[data-text-line-height=xs]{--vui-text-line-height:var(--font-leading-xs)}&[data-text-line-height=s]{--vui-text-line-height:var(--font-leading-s)}&[data-text-line-height=m]{--vui-text-line-height:var(--font-leading-m)}&[data-text-line-height=l]{--vui-text-line-height:var(--font-leading-l)}}}
|
|
@@ -85,7 +85,9 @@ export type TextProps = React.ComponentPropsWithoutRef<'span'> & {
|
|
|
85
85
|
*/
|
|
86
86
|
maxWidth?: string;
|
|
87
87
|
/**
|
|
88
|
-
* Controls white-space
|
|
88
|
+
* Controls white-space collapse/preserve (`white-space`).
|
|
89
|
+
* Prefer `whiteSpace="nowrap"` for single-line metrics/chrome (also collapses spaces).
|
|
90
|
+
* For wrapping algorithm / even line lengths use `wrap` (`text-wrap`) — not this prop.
|
|
89
91
|
*
|
|
90
92
|
* @defaultValue 'normal'
|
|
91
93
|
*/
|
|
@@ -105,13 +107,14 @@ export type TextProps = React.ComponentPropsWithoutRef<'span'> & {
|
|
|
105
107
|
*/
|
|
106
108
|
transform?: React.CSSProperties['textTransform'];
|
|
107
109
|
/**
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
110
|
+
* Controls CSS `text-wrap` (wrapping algorithm / wrap on-off).
|
|
111
|
+
* Default `pretty` for orphan-aware UI copy. Prefer `balance` on short multi-line
|
|
112
|
+
* heads/blurbs that need even line lengths. Use `wrap="nowrap"` only when you need
|
|
113
|
+
* no wrap without changing white-space collapse; prefer `whiteSpace="nowrap"` for metrics.
|
|
111
114
|
*
|
|
112
|
-
* @defaultValue
|
|
115
|
+
* @defaultValue 'pretty'
|
|
113
116
|
*/
|
|
114
|
-
|
|
117
|
+
wrap?: React.CSSProperties['textWrap'];
|
|
115
118
|
/**
|
|
116
119
|
* Enables text selection on the rendered copy.
|
|
117
120
|
*
|
|
@@ -4,7 +4,7 @@ import { resolveAxisPadding } from "../../core/styles/resolve-axis-padding.js";
|
|
|
4
4
|
import text_module_default from "./text.module.js";
|
|
5
5
|
import { useRender } from "@base-ui/react/use-render";
|
|
6
6
|
//#region src/components/text/text.tsx
|
|
7
|
-
var Text = ({ align,
|
|
7
|
+
var Text = ({ align, selection = true, className, color, family = "body", fluid = false, fontWidth, hPadding, lineHeight, maxWidth, opticalSize, ref, render, size, style, tone, tracking, transform, trim = "both", trimType = "cap alphabetic", vPadding, weight = "regular", whiteSpace = "normal", wrap = "pretty", ...otherProps }) => {
|
|
8
8
|
const hasAlign = align !== void 0;
|
|
9
9
|
const hasPadding = Boolean(hPadding || vPadding);
|
|
10
10
|
const dynamicStyle = {
|
|
@@ -12,6 +12,7 @@ var Text = ({ align, balanced = false, selection = true, className, color, famil
|
|
|
12
12
|
"--vui-text-max-width": maxWidth ?? "none",
|
|
13
13
|
"--vui-text-literal-color": color,
|
|
14
14
|
"--vui-text-white-space": whiteSpace,
|
|
15
|
+
"--vui-text-wrap": wrap,
|
|
15
16
|
"--vui-text-letter-spacing": tracking,
|
|
16
17
|
"--vui-text-text-transform": transform,
|
|
17
18
|
"--vui-text-trim": trim ? `trim-${trim}` : "none",
|
|
@@ -34,7 +35,6 @@ var Text = ({ align, balanced = false, selection = true, className, color, famil
|
|
|
34
35
|
"data-text-weight": typeof weight === "string" ? weight : "custom",
|
|
35
36
|
"data-text-tone": tone,
|
|
36
37
|
"data-text-line-height": lineHeight,
|
|
37
|
-
"data-text-balanced": balanced ? "true" : "false",
|
|
38
38
|
"data-text-selection": selection ? "true" : "false",
|
|
39
39
|
"data-text-fluid": fluid ? "true" : "false",
|
|
40
40
|
"data-text-has-align": hasAlign ? "true" : "false",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
@layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-title-align{syntax:"*";inherits:false;initial-value:start}@property --vui-title-max-width{syntax:"*";inherits:false;initial-value:none}@property --vui-title-literal-color{syntax:"<color>";inherits:false;initial-value:#0000}@property --vui-title-white-space{syntax:"*";inherits:false;initial-value:normal}@property --vui-title-font-weight{syntax:"<number>";inherits:false;initial-value:500}@property --vui-title-font-width{syntax:"<number>";inherits:false;initial-value:100}@property --vui-title-font-opsz{syntax:"<number>";inherits:false;initial-value:16}@property --vui-title-trim{syntax:"*";inherits:false;initial-value:trim-both}@property --vui-title-trim-type{syntax:"*";inherits:false;initial-value:cap alphabetic}@property --vui-title-padding-inline-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-title-padding-inline-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-title-padding-block-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-title-padding-block-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-title-font-size{syntax:"<length>";inherits:false;initial-value:1rem}@property --vui-title-line-height{syntax:"normal | <number> | <length-percentage>";inherits:false;initial-value:normal}@property --vui-title-letter-spacing{syntax:"normal | <length>";inherits:false;initial-value:normal}@property --__title-letter-spacing{syntax:"normal | <length>";inherits:false;initial-value:normal}@property --vui-title-text-transform{syntax:"none | capitalize | uppercase | lowercase";inherits:false;initial-value:none}@property --vui-title-font-family{syntax:"*";inherits:false;initial-value:sans-serif}@property --__title-fluid{syntax:"<number>";inherits:false;initial-value:0}@property --__title-size-min{syntax:"<length>";inherits:false;initial-value:1rem}@property --__title-size-max{syntax:"<length>";inherits:false;initial-value:1rem}.viraui__title-module__Title_CXMUX{--__title-fluid:calc((100vi - 320px) / 1125px);--__title-size-min:var(--font-scale-h2);--__title-size-max:var(--font-scale-h1);--vui-title-font-size:clamp(
|
|
1
|
+
@layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-title-align{syntax:"*";inherits:false;initial-value:start}@property --vui-title-max-width{syntax:"*";inherits:false;initial-value:none}@property --vui-title-literal-color{syntax:"<color>";inherits:false;initial-value:#0000}@property --vui-title-white-space{syntax:"*";inherits:false;initial-value:normal}@property --vui-title-wrap{syntax:"*";inherits:false;initial-value:pretty}@property --vui-title-font-weight{syntax:"<number>";inherits:false;initial-value:500}@property --vui-title-font-width{syntax:"<number>";inherits:false;initial-value:100}@property --vui-title-font-opsz{syntax:"<number>";inherits:false;initial-value:16}@property --vui-title-trim{syntax:"*";inherits:false;initial-value:trim-both}@property --vui-title-trim-type{syntax:"*";inherits:false;initial-value:cap alphabetic}@property --vui-title-padding-inline-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-title-padding-inline-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-title-padding-block-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-title-padding-block-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-title-font-size{syntax:"<length>";inherits:false;initial-value:1rem}@property --vui-title-line-height{syntax:"normal | <number> | <length-percentage>";inherits:false;initial-value:normal}@property --vui-title-letter-spacing{syntax:"normal | <length>";inherits:false;initial-value:normal}@property --__title-letter-spacing{syntax:"normal | <length>";inherits:false;initial-value:normal}@property --vui-title-text-transform{syntax:"none | capitalize | uppercase | lowercase";inherits:false;initial-value:none}@property --vui-title-font-family{syntax:"*";inherits:false;initial-value:sans-serif}@property --__title-fluid{syntax:"<number>";inherits:false;initial-value:0}@property --__title-size-min{syntax:"<length>";inherits:false;initial-value:1rem}@property --__title-size-max{syntax:"<length>";inherits:false;initial-value:1rem}.viraui__title-module__Title_CXMUX{--__title-fluid:calc((100vi - 320px) / 1125px);--__title-size-min:var(--font-scale-h2);--__title-size-max:var(--font-scale-h1);--vui-title-font-size:clamp(
|
|
2
2
|
var(--__title-size-min),
|
|
3
3
|
calc(var(--__title-size-min) + (var(--__title-size-max) - var(--__title-size-min)) * var(--__title-fluid)),
|
|
4
4
|
var(--__title-size-max)
|
|
5
|
-
);--vui-title-font-family:var(--font-family-heading);--vui-title-line-height:var(--font-leading-m);--__title-letter-spacing:-0.03em;margin:0;max-inline-size:var(--vui-title-max-width);font-family:var(--vui-title-font-family);font-size:var(--vui-title-font-size);line-height:var(--vui-title-line-height);letter-spacing:var(--__title-letter-spacing);text-transform:var(--vui-title-text-transform);white-space:var(--vui-title-white-space);word-break:break-word;font-weight:var(--vui-title-font-weight);font-stretch:calc(var(--vui-title-font-width) * 1%);font-optical-sizing:auto;font-variation-settings:"wght" var(--vui-title-font-weight),"wdth" var(--vui-title-font-width),"opsz" var(--vui-title-font-opsz);text-box:var(--vui-title-trim) var(--vui-title-trim-type);display:inline-flex;&[data-title-has-align=true]{text-align:var(--vui-title-align)}&[data-title-has-tracking=true]{letter-spacing:var(--vui-title-letter-spacing)}&[data-title-
|
|
5
|
+
);--vui-title-font-family:var(--font-family-heading);--vui-title-line-height:var(--font-leading-m);--__title-letter-spacing:-0.03em;margin:0;max-inline-size:var(--vui-title-max-width);font-family:var(--vui-title-font-family);font-size:var(--vui-title-font-size);line-height:var(--vui-title-line-height);letter-spacing:var(--__title-letter-spacing);text-transform:var(--vui-title-text-transform);text-wrap:var(--vui-title-wrap);white-space:var(--vui-title-white-space);word-break:break-word;font-weight:var(--vui-title-font-weight);font-stretch:calc(var(--vui-title-font-width) * 1%);font-optical-sizing:auto;font-variation-settings:"wght" var(--vui-title-font-weight),"wdth" var(--vui-title-font-width),"opsz" var(--vui-title-font-opsz);text-box:var(--vui-title-trim) var(--vui-title-trim-type);display:inline-flex;&[data-title-has-align=true]{text-align:var(--vui-title-align)}&[data-title-has-tracking=true]{letter-spacing:var(--vui-title-letter-spacing)}&[data-title-selection=false]{-webkit-user-select:none;user-select:none}&[data-title-has-padding=true]{padding:var(--vui-title-padding-block-start) var(--vui-title-padding-inline-end) var(--vui-title-padding-block-end) var(--vui-title-padding-inline-start)}&[data-title-size=display]{--__title-size-min:var(--font-scale-h1);--__title-size-max:var(--font-scale-display)}&[data-title-size="2"]{--__title-size-min:var(--font-scale-h3);--__title-size-max:var(--font-scale-h2)}&[data-title-size="3"]{--__title-size-min:var(--font-scale-h4);--__title-size-max:var(--font-scale-h3)}&[data-title-size="4"]{--__title-size-min:var(--font-scale-h5);--__title-size-max:var(--font-scale-h4)}&[data-title-size="5"]{--__title-size-min:var(--font-scale-h6);--__title-size-max:var(--font-scale-h5);--__title-letter-spacing:-0.02em}&[data-title-size="6"]{--__title-size-min:var(--font-scale-body-m);--__title-size-max:var(--font-scale-h6);--__title-letter-spacing:-0.02em}&[data-title-fluid=false]{--vui-title-font-size:var(--__title-size-max)}@container root style(--effect-fluid-typography: initial){--vui-title-font-size:var(--__title-size-max)}&[data-title-has-literal-color=true]{color:var(--vui-title-literal-color)}&[data-title-line-height=none]{--vui-title-line-height:0}&[data-title-line-height=xs]{--vui-title-line-height:var(--font-leading-xs)}&[data-title-line-height=s]{--vui-title-line-height:var(--font-leading-s)}&[data-title-line-height=m]{--vui-title-line-height:var(--font-leading-m)}&[data-title-line-height=l]{--vui-title-line-height:var(--font-leading-l)}}}
|
|
@@ -72,7 +72,9 @@ export type TitleProps = React.ComponentPropsWithoutRef<'span'> & {
|
|
|
72
72
|
*/
|
|
73
73
|
maxWidth?: string;
|
|
74
74
|
/**
|
|
75
|
-
* Controls white-space
|
|
75
|
+
* Controls white-space collapse/preserve (`white-space`).
|
|
76
|
+
* Prefer `whiteSpace="nowrap"` for single-line metrics/chrome (also collapses spaces).
|
|
77
|
+
* For wrapping algorithm / even line lengths use `wrap` (`text-wrap`) — not this prop.
|
|
76
78
|
*
|
|
77
79
|
* @defaultValue 'normal'
|
|
78
80
|
*/
|
|
@@ -94,13 +96,14 @@ export type TitleProps = React.ComponentPropsWithoutRef<'span'> & {
|
|
|
94
96
|
*/
|
|
95
97
|
transform?: React.CSSProperties['textTransform'];
|
|
96
98
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
99
|
+
* Controls CSS `text-wrap` (wrapping algorithm / wrap on-off).
|
|
100
|
+
* Default `pretty` for orphan-aware titles. Prefer `balance` on short multi-line
|
|
101
|
+
* heads that need even line lengths. Use `wrap="nowrap"` only when you need no wrap
|
|
102
|
+
* without changing white-space collapse; prefer `whiteSpace="nowrap"` for metrics.
|
|
100
103
|
*
|
|
101
|
-
* @defaultValue
|
|
104
|
+
* @defaultValue 'pretty'
|
|
102
105
|
*/
|
|
103
|
-
|
|
106
|
+
wrap?: React.CSSProperties['textWrap'];
|
|
104
107
|
/**
|
|
105
108
|
* Enables text selection on the rendered copy.
|
|
106
109
|
*
|
|
@@ -4,7 +4,7 @@ import { resolveAxisPadding } from "../../core/styles/resolve-axis-padding.js";
|
|
|
4
4
|
import title_module_default from "./title.module.js";
|
|
5
5
|
import { useRender } from "@base-ui/react/use-render";
|
|
6
6
|
//#region src/components/title/title.tsx
|
|
7
|
-
var Title = ({ align,
|
|
7
|
+
var Title = ({ align, selection = true, className, color, fluid = true, fontWidth, hPadding, size = "1", lineHeight = "m", maxWidth, opticalSize, ref, render, style, tracking, transform, trim = "both", trimType = "cap alphabetic", vPadding, weight, whiteSpace = "normal", wrap = "pretty", ...otherProps }) => {
|
|
8
8
|
const hasAlign = align !== void 0;
|
|
9
9
|
const hasPadding = Boolean(hPadding || vPadding);
|
|
10
10
|
const hasTracking = tracking !== void 0;
|
|
@@ -13,6 +13,7 @@ var Title = ({ align, balanced = false, selection = true, className, color, flui
|
|
|
13
13
|
"--vui-title-max-width": maxWidth ?? "none",
|
|
14
14
|
"--vui-title-literal-color": color,
|
|
15
15
|
"--vui-title-white-space": whiteSpace,
|
|
16
|
+
"--vui-title-wrap": wrap,
|
|
16
17
|
...hasTracking && { "--vui-title-letter-spacing": tracking },
|
|
17
18
|
"--vui-title-text-transform": transform,
|
|
18
19
|
"--vui-title-trim": trim ? `trim-${trim}` : "none",
|
|
@@ -32,7 +33,6 @@ var Title = ({ align, balanced = false, selection = true, className, color, flui
|
|
|
32
33
|
...otherProps,
|
|
33
34
|
"data-title-size": size,
|
|
34
35
|
"data-title-line-height": lineHeight,
|
|
35
|
-
"data-title-balanced": balanced ? "true" : "false",
|
|
36
36
|
"data-title-selection": selection ? "true" : "false",
|
|
37
37
|
"data-title-fluid": fluid ? "true" : "false",
|
|
38
38
|
"data-title-has-align": hasAlign ? "true" : "false",
|
|
@@ -4,7 +4,9 @@ import { ToggleGroup as ToggleGroupPrimitive } from '@base-ui/react/toggle-group
|
|
|
4
4
|
*
|
|
5
5
|
* Thin wrapper around Base UI `ToggleGroup` with default `Stack` direction
|
|
6
6
|
* (`row` / `column` from `orientation`) and zero gap — consumers own spacing.
|
|
7
|
-
* Compose `ToggleButton` children each with `value`
|
|
7
|
+
* Compose `ToggleButton` and/or `ToggleTextButton` children each with `value`
|
|
8
|
+
* (icon-only children also need an accessible name).
|
|
9
|
+
|
|
8
10
|
*
|
|
9
11
|
* @defaultValue Base UI pass-through props keep upstream defaults.
|
|
10
12
|
*/
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Toggle as TogglePrimitive } from '@base-ui/react/toggle';
|
|
2
|
+
import { ButtonProps } from '../button/button';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
/**
|
|
5
|
+
* Public ToggleTextButton props.
|
|
6
|
+
*
|
|
7
|
+
* Labeled two-state control built on Base UI `Toggle` and `Button`.
|
|
8
|
+
* Prefer a visible text `children` label; supply `aria-label` or `aria-labelledby`
|
|
9
|
+
* when children are empty or whitespace-only.
|
|
10
|
+
*
|
|
11
|
+
* @defaultValue Base UI toggle pass-through props keep upstream defaults.
|
|
12
|
+
*/
|
|
13
|
+
export type ToggleTextButtonProps = Omit<ButtonProps, 'render' | 'variant'> & Omit<TogglePrimitive.Props, 'render' | 'children'> & {
|
|
14
|
+
/**
|
|
15
|
+
* Visual variant while the toggle is not pressed.
|
|
16
|
+
*
|
|
17
|
+
* @defaultValue 'flat'
|
|
18
|
+
*/
|
|
19
|
+
variant?: ButtonProps['variant'];
|
|
20
|
+
/**
|
|
21
|
+
* Visual variant while the toggle is pressed.
|
|
22
|
+
*
|
|
23
|
+
* @defaultValue When omitted, `variant` is used in both states.
|
|
24
|
+
*/
|
|
25
|
+
pressedVariant?: ButtonProps['variant'];
|
|
26
|
+
};
|
|
27
|
+
export declare const ToggleTextButton: React.FC<ToggleTextButtonProps>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Button } from "../button/button.js";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import "react";
|
|
4
|
+
import { mergeProps } from "@base-ui/react/merge-props";
|
|
5
|
+
import { Toggle } from "@base-ui/react/toggle";
|
|
6
|
+
//#region src/components/toggle-text-button/toggle-text-button.tsx
|
|
7
|
+
var ToggleTextButton = ({ variant = "flat", pressedVariant, pressed, defaultPressed, onPressedChange, value, disabled, ref, ...otherProps }) => /* @__PURE__ */ jsx(Toggle, {
|
|
8
|
+
ref,
|
|
9
|
+
value,
|
|
10
|
+
pressed,
|
|
11
|
+
defaultPressed,
|
|
12
|
+
onPressedChange,
|
|
13
|
+
disabled,
|
|
14
|
+
render: (toggleProps, state) => {
|
|
15
|
+
const { "aria-label": _toggleAriaLabel, "aria-labelledby": _toggleAriaLabelledBy, ...restToggleProps } = toggleProps;
|
|
16
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
17
|
+
...mergeProps(restToggleProps, otherProps),
|
|
18
|
+
disabled,
|
|
19
|
+
variant: state.pressed ? pressedVariant ?? variant : variant
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
//#endregion
|
|
24
|
+
export { ToggleTextButton };
|
package/dist/index.js
CHANGED
|
@@ -70,7 +70,8 @@ import { Title } from "./components/title/title.js";
|
|
|
70
70
|
import { Toast } from "./components/toast/toast.js";
|
|
71
71
|
import { ToggleButton } from "./components/toggle-button/toggle-button.js";
|
|
72
72
|
import { ToggleGroup } from "./components/toggle-group/toggle-group.js";
|
|
73
|
+
import { ToggleTextButton } from "./components/toggle-text-button/toggle-text-button.js";
|
|
73
74
|
import { Typewriter } from "./components/typewriter/typewriter.js";
|
|
74
75
|
import { TooltipContent } from "./components/tooltip/tooltip-content.js";
|
|
75
76
|
import { Tooltip, TooltipProvider, TooltipTrigger } from "./components/tooltip/tooltip.js";
|
|
76
|
-
export { Accordion, Annotate, Autocomplete, Avatar, AvatarGroup, Badge, Beam, Bleed, BreakpointsProvider, Button, ButtonLink, Checkbox, CheckboxGroup, Chip, ClampText, Dialog, DialogClose, DialogIndent, DialogIndentBackground, DialogSheet, DialogTrigger, DirectionProvider, Disclosure, ELEVATION_DEFAULTS, Elevator, Fieldset, FitText, Glow, Grid, IconButton, IconButtonLink, LinearProgress, Masonry, Menu, MenuCheckboxItem, MenuGroup, MenuItem, MenuLinkItem, MenuPopup, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuSubmenu, MenuSubmenuTrigger, MenuTrigger, Meter, NumberField, OTPField, Popover, PopoverClose, PopoverDescription, PopoverSheet, PopoverTitle, PopoverTrigger, ProgressiveBlur, Prose, Radio, RadioGroup, Select, Separator, Shimmer, Skeleton, Slider, Spinner, Stack, StaticNoise, Surface, Switch, Tabs, Text, Textarea, Textfield, Title, Toast, ToggleButton, ToggleGroup, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Typewriter, getElevationProps, useBreakpoints, useDirection };
|
|
77
|
+
export { Accordion, Annotate, Autocomplete, Avatar, AvatarGroup, Badge, Beam, Bleed, BreakpointsProvider, Button, ButtonLink, Checkbox, CheckboxGroup, Chip, ClampText, Dialog, DialogClose, DialogIndent, DialogIndentBackground, DialogSheet, DialogTrigger, DirectionProvider, Disclosure, ELEVATION_DEFAULTS, Elevator, Fieldset, FitText, Glow, Grid, IconButton, IconButtonLink, LinearProgress, Masonry, Menu, MenuCheckboxItem, MenuGroup, MenuItem, MenuLinkItem, MenuPopup, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuSubmenu, MenuSubmenuTrigger, MenuTrigger, Meter, NumberField, OTPField, Popover, PopoverClose, PopoverDescription, PopoverSheet, PopoverTitle, PopoverTrigger, ProgressiveBlur, Prose, Radio, RadioGroup, Select, Separator, Shimmer, Skeleton, Slider, Spinner, Stack, StaticNoise, Surface, Switch, Tabs, Text, Textarea, Textfield, Title, Toast, ToggleButton, ToggleGroup, ToggleTextButton, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Typewriter, getElevationProps, useBreakpoints, useDirection };
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
<item>Actions that need visible text — use Button</item>
|
|
10
10
|
<item>Missing both aria-label and aria-labelledby</item>
|
|
11
11
|
<item>Navigation or non-button semantics — use IconButtonLink</item>
|
|
12
|
-
<item>Temporally swap icons after user interactions with temporal pressed state, like copy feedback. Use ToggleButton
|
|
12
|
+
<item>Temporally swap icons after user interactions with temporal pressed state, like copy feedback. Use ToggleButton (icon-only) or ToggleTextButton (labeled)</item>
|
|
13
|
+
|
|
13
14
|
</when_not_to_use>
|
|
14
15
|
<prop name="icon" kind="react">
|
|
15
16
|
<description>Icon rendered as the sole visible control content. Omit glyph `size` / width / height — host CSS sizes SVG via `--vui-button-icon-size`.</description>
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
<do>Icon-only navigation — use IconButtonLink (framework Link via `render`)</do>
|
|
11
11
|
<dont>Passing `children`, `addon`, or `addonPosition` — not part of the public API; use `icon`</dont>
|
|
12
12
|
<dont>Using icon-only Button instead of IconButton</dont>
|
|
13
|
-
<dont>Using IconButton for persistent or temporal pressed state — use ToggleButton</dont>
|
|
13
|
+
<dont>Using IconButton for persistent or temporal pressed state — use ToggleButton (icon-only) or ToggleTextButton (labeled)</dont>
|
|
14
|
+
|
|
14
15
|
<dont>Using IconButton with `render={<a />}` for links — use IconButtonLink</dont>
|
|
15
16
|
<dont>Omitting both `aria-label` and `aria-labelledby`</dont>
|
|
16
17
|
<dont>Passing `size={16}` / `size="1rem"` (or width/height) on the `icon` glyph — IconButton CSS sizes SVG descendants</dont>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<meta id="prose" title="Prose" category="typography" shared_contract="prose">
|
|
3
|
-
<summary>Text-wall grouping region (articles, docs, privacy) with heading-aware em rhythm
|
|
3
|
+
<summary>Text-wall grouping region (articles, docs, privacy) with heading-aware em rhythm, region `wrap` (default `pretty`), and reading column via parent Stack `maxWidth` sized for body Text `size`.</summary>
|
|
4
4
|
<exports>
|
|
5
5
|
<export name="Prose" />
|
|
6
6
|
</exports>
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
</Prose>
|
|
37
37
|
</Stack>
|
|
38
38
|
]]></tsx>
|
|
39
|
-
<notes>Text-wall path: Prose for rhythm + Stack measure sized for body `size` (here `s` → narrower than `m`). Not for short card blurbs — those stay Text/Title props (`maxWidth` / `
|
|
39
|
+
<notes>Text-wall path: Prose for rhythm + Stack measure sized for body `size` (here `s` → narrower than `m`). Not for short card blurbs — those stay Text/Title props (`maxWidth` / `wrap`).</notes>
|
|
40
40
|
</example>
|
|
41
41
|
|
|
42
42
|
<example title="Density and region align">
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
<when_to_use>
|
|
4
4
|
<item>Text walls — articles, docs, privacy/terms, long editorial — whose direct children are headings and blocks that need heading-aware vertical rhythm</item>
|
|
5
5
|
<item>Article, docs, or changelog regions where Stack `rowGap` would make heading→body and body→body the same</item>
|
|
6
|
-
<item>Optional `gap` density (`s` / `m` / `l`)
|
|
6
|
+
<item>Optional `gap` density (`s` / `m` / `l`), region `align` (Title/Text that omit `align` inherit it), and region `wrap` (default `pretty`; inherits to descendants)</item>
|
|
7
7
|
<item>Reading column via parent Stack `maxWidth` sized for the body Text `size` (smaller → narrower; not one fixed `65ch`–`75ch`); edge-to-edge wall of text is not OK</item>
|
|
8
8
|
</when_to_use>
|
|
9
9
|
<when_not_to_use>
|
|
10
10
|
<item>UI chrome spacing (cards, toolbars, form rows) — use Stack `rowGap` / `columnGap`</item>
|
|
11
|
-
<item>Short card/hero blurbs “for leading” — use Text/Title `lineHeight` / `maxWidth` / `
|
|
11
|
+
<item>Short card/hero blurbs “for leading” — use Text/Title `lineHeight` / `maxWidth` / `wrap` instead</item>
|
|
12
12
|
<item>Restyling type, lists, links, or tables — stay on Title / Text / consumer CSS</item>
|
|
13
13
|
<item>Markdown parse or sanitize — Prose only spaces matching direct children</item>
|
|
14
14
|
</when_not_to_use>
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
<prop name="gap" kind="react">
|
|
19
19
|
<description>Em density for heading-aware vertical rhythm (`s` < `m` < `l`).</description>
|
|
20
20
|
</prop>
|
|
21
|
+
<prop name="wrap" kind="react">
|
|
22
|
+
<description>Controls CSS `text-wrap` on the Prose root (inherits to descendants unless a child overrides). Default `pretty` for orphan-aware article walls. Prefer `balance` only on short multi-line blocks that need even line lengths. Single-line metrics stay on child Text/Title `whiteSpace`.</description>
|
|
23
|
+
</prop>
|
|
21
24
|
<prop name="ref" kind="react">
|
|
22
25
|
<description>Ref forwarded to the rendered prose root element.</description>
|
|
23
26
|
</prop>
|
|
@@ -36,4 +39,7 @@
|
|
|
36
39
|
<prop name="gap-heading-start" kind="css">
|
|
37
40
|
<description>Gap after a heading onto the next sibling (`--vui-prose-gap-heading-start`). Default `1.3em` (`l`).</description>
|
|
38
41
|
</prop>
|
|
42
|
+
<prop name="wrap" kind="css">
|
|
43
|
+
<description>Text-wrap on the Prose root (`--vui-prose-wrap`; inherits). Prefer the `wrap` React prop; default `pretty`.</description>
|
|
44
|
+
</prop>
|
|
39
45
|
</props>
|