@vitavision/ui 0.11.0 → 0.13.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.
Files changed (39) hide show
  1. package/README.md +8 -5
  2. package/dist/index.d.ts +255 -12
  3. package/dist/index.js +599 -44
  4. package/dist/index.js.map +1 -1
  5. package/package.json +1 -1
  6. package/src/components/Tabs.tsx +3 -10
  7. package/src/components/ThemeToggle.tsx +3 -8
  8. package/src/components/ui/Badge.tsx +1 -4
  9. package/src/components/ui/Button.tsx +3 -15
  10. package/src/components/ui/Dialog.tsx +4 -19
  11. package/src/components/ui/Disclosure.tsx +2 -7
  12. package/src/components/ui/DropdownMenu.tsx +2 -16
  13. package/src/components/ui/Feedback.tsx +5 -9
  14. package/src/components/ui/Field.tsx +4 -15
  15. package/src/components/ui/HighlightedText.tsx +84 -0
  16. package/src/components/ui/Input.tsx +5 -43
  17. package/src/components/ui/Panel.tsx +4 -16
  18. package/src/components/ui/PoseInput.tsx +7 -5
  19. package/src/components/ui/Progress.tsx +80 -0
  20. package/src/components/ui/SegmentedControl.tsx +1 -3
  21. package/src/components/ui/Select.tsx +2 -10
  22. package/src/components/ui/Slider.tsx +2 -7
  23. package/src/components/ui/Table.tsx +331 -85
  24. package/src/components/ui/Textarea.tsx +149 -0
  25. package/src/components/ui/Toaster.tsx +3 -19
  26. package/src/components/ui/Toggle.tsx +1 -5
  27. package/src/components/ui/ToggleChip.tsx +1 -3
  28. package/src/components/ui/Tooltip.tsx +1 -5
  29. package/src/components/ui/VectorInput.tsx +1 -1
  30. package/src/components/ui/cn.ts +1 -2
  31. package/src/components/ui/highlightSpans.ts +110 -0
  32. package/src/components/ui/index.ts +11 -41
  33. package/src/components/ui/listboxModel.ts +1 -6
  34. package/src/components/ui/tableSort.ts +114 -0
  35. package/src/components/ui/tableWindow.ts +96 -0
  36. package/src/fonts/fonts.css +1 -1
  37. package/src/index.ts +1 -8
  38. package/src/styles.css +17 -7
  39. package/src/theme.ts +2 -7
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  The vitavision *instrument* design system: true-neutral greys, one accent, and verdict colours
4
4
  reserved for verdicts. Tailwind v4 design tokens, a theme controller, and the React primitives
5
- every lab app shares. React 19, no CSS-in-JS, no runtime theme engine.
5
+ every vitavision app shares. React 19, no CSS-in-JS, no runtime theme engine.
6
6
 
7
7
  ## Install
8
8
 
@@ -31,7 +31,7 @@ Each stylesheet ships **unprocessed** — Tailwind v4 *source*, resolved by your
31
31
  declares its own `@source "./"`, which Tailwind resolves against that stylesheet: the package's
32
32
  class names are found without an `@source` line of yours.
33
33
 
34
- `fonts.css` serves the type pair, IBM Plex Sans and IBM Plex Mono (ADR-0003), from files in this
34
+ `fonts.css` serves the type pair, IBM Plex Sans and IBM Plex Mono, from files in this
35
35
  package (SIL Open Font License). Its Plex Mono is IBM's own build, which keeps the `zero` feature,
36
36
  so values get a slashed zero; `unicode-range` means a page fetches only the subsets its text
37
37
  uses (about 80 KB for Latin). Drop any fontsource or Google Fonts Plex you loaded before — their
@@ -125,11 +125,14 @@ keep independent preferences.
125
125
  **Primitives** — `Badge`, `CountRun`, `StatusDot` · `Button`, `ButtonLink` (a navigation styled as a button — never nest a `Button` in a link), `buttonClasses` · `Dialog`, `ConfirmDialog`,
126
126
  `DialogClose` · `Disclosure` · `DropdownMenu`, `MenuItem`, `MenuCheckboxItem`, `MenuLabel`,
127
127
  `MenuSeparator` (a non-modal command and toggle menu) · `Callout`, `Empty`, `ErrorBox`,
128
- `ProgressBar`, `Skeleton`, `SkeletonRows` · `Field` · `Input`, `NumberInput` (with an optional
129
- `unit` written in the field; number-valued with `onValueChange`), `Textarea` · `VectorInput`,
128
+ `Skeleton`, `SkeletonRows` · `Progress` (a count out of a total, or indeterminate; `ProgressBar` is
129
+ deprecated) · `Field` · `Input`, `NumberInput` (with an optional
130
+ `unit` written in the field; number-valued with `onValueChange`), `Textarea` (optionally growing
131
+ with its content between `minRows` and `maxRows`) · `HighlightedText`, `findSpans` (a string
132
+ with its placeholders, tags and terms marked, never parsed as HTML) · `VectorInput`,
130
133
  `PoseInput` · `Kbd` · `Listbox` (single choice among options that render their own content) ·
131
134
  `PageHeader`, `Panel`, `ReadoutStrip`, `Section` · `Popover`, `PopoverClose` ·
132
- `SegmentedControl` · `Select` · `Slider` · `Table` ·
135
+ `SegmentedControl` · `Select` · `Slider` · `Table` (with `windowed` for thousands of rows) ·
133
136
  `Checkbox`, `Switch` · `ToggleChip` · `Toaster`, `toast()` (notifications from anywhere; mount one `<Toaster />` near the root) ·
134
137
  `InfoHint`, `Tooltip`, `TooltipProvider` ·
135
138
  `ThemeToggle` · plus `cn`, `focusRing`, `focusRingInset`, and `formatNumber` / `parseNumber`
package/dist/index.d.ts CHANGED
@@ -464,6 +464,9 @@ export declare function SkeletonRows({ rows, className }: {
464
464
  * A `role="progressbar"` with `aria-valuenow` in percent. Its accessible name is
465
465
  * `aria-label` if given, else `label`, else "Progress" — pass one that names the job when
466
466
  * a screen shows more than one bar.
467
+ *
468
+ * @deprecated Use `Progress`: a value out of a `max` with a "412 of 2,556" value text, an
469
+ * indeterminate state, and a track that follows the density.
467
470
  */
468
471
  export declare function ProgressBar({ fraction, label, "aria-label": ariaLabel, className }: {
469
472
  /** Done, from 0 to 1. Clamped. */
@@ -510,6 +513,75 @@ export declare function Field({ label, description, error, required, annotation,
510
513
  children: ReactNode;
511
514
  }): import("react").JSX.Element;
512
515
  //#endregion
516
+ //#region src/components/ui/highlightSpans.d.ts
517
+ /** What a highlighted span is. Each kind has its own shape on screen, not only its own colour. */
518
+ type HighlightKind = "placeholder" | "tag" | "protected-term" | "mismatch";
519
+ /** A highlighted range of the text: `[start, end)` in UTF-16 code units. */
520
+ interface HighlightSpan {
521
+ /** The offset of the span's first code unit. */
522
+ start: number;
523
+ /** The offset just past the span's last code unit. */
524
+ end: number;
525
+ /** What the span is; it decides the span's shape and its default label. */
526
+ kind: HighlightKind;
527
+ /**
528
+ * What a screen reader hears after the span, instead of the kind's default label: say
529
+ * *why* it is marked ("missing from the translation").
530
+ */
531
+ label?: string | undefined;
532
+ }
533
+ /** A pattern whose matches become spans of one kind. */
534
+ interface HighlightRule {
535
+ /** Matched against the whole text, every match (the `g` flag is added if missing). */
536
+ pattern: RegExp;
537
+ /** The kind every match gets. */
538
+ kind: HighlightKind;
539
+ /** The spans' `label`, if they need one. */
540
+ label?: string | undefined;
541
+ }
542
+ /**
543
+ * Spans for every match of every rule: `%1`, `<b>`, a glossary term. Empty matches are
544
+ * skipped. The result is sorted by start, then longest first.
545
+ *
546
+ * @param text - The string to search.
547
+ * @param rules - Each pattern and the kind its matches get.
548
+ * @returns The spans, ready for `HighlightedText`.
549
+ *
550
+ * @example
551
+ * ```ts
552
+ * findSpans("Open %1 in <b>ParamsManager</b>", [
553
+ * { pattern: /%\d+/, kind: "placeholder" },
554
+ * { pattern: /<\/?[a-z][^>]*>/i, kind: "tag" },
555
+ * { pattern: /\bParamsManager\b/, kind: "protected-term" },
556
+ * ]);
557
+ * ```
558
+ */
559
+ export declare function findSpans(text: string, rules: readonly HighlightRule[]): HighlightSpan[];
560
+ //#endregion
561
+ //#region src/components/ui/HighlightedText.d.ts
562
+ /** Props of `HighlightedText`: the text, its spans, and every `<span>` prop but `children`. */
563
+ type HighlightedTextProps = Omit<ComponentProps<"span">, "children"> & {
564
+ /** The string. Shown as text, whitespace and line breaks kept; markup in it is not interpreted. */
565
+ text: string;
566
+ /** The ranges to mark, in UTF-16 offsets, in any order; overlaps are allowed. `findSpans` builds them from patterns. */
567
+ spans?: readonly HighlightSpan[] | undefined;
568
+ /**
569
+ * What a screen reader hears after a span of each kind: "placeholder", "markup",
570
+ * "protected term" and "mismatch" by default. `null` silences a kind. A span's own `label` wins.
571
+ */
572
+ labels?: Partial<Record<HighlightKind, string | null>> | undefined;
573
+ };
574
+ /**
575
+ * A string with highlighted spans: placeholders (`%1`, `{count}`), markup tags (`<b>`),
576
+ * protected terms (`ParamsManager`) and mismatches, each drawn in its own shape. The caller
577
+ * supplies the spans, or finds them with `findSpans`.
578
+ *
579
+ * The text is rendered as text, never as HTML. Each span is a `<mark>` with `data-kind` (the
580
+ * kinds covering it, space-separated), followed by its label for screen readers ("%1,
581
+ * placeholder"), which a copy of the text leaves out.
582
+ */
583
+ export declare function HighlightedText({ text, spans, labels, className, ...rest }: HighlightedTextProps): import("react").JSX.Element;
584
+ //#endregion
513
585
  //#region src/components/ui/Input.d.ts
514
586
  /**
515
587
  * The shared look of a text-like control — border, palette, placeholder, hover, disabled and
@@ -598,11 +670,6 @@ type NumberInputProps = Omit<ComponentProps<"input">, "min" | "max" | "value"> &
598
670
  * is the native text-valued input.
599
671
  */
600
672
  export declare function NumberInput({ onValueChange, onClear, precision, ...props }: NumberInputProps): import("react").JSX.Element;
601
- /**
602
- * Multi-line text — set in mono, for JSON and lists. Takes every `<textarea>` prop, `ref`
603
- * included.
604
- */
605
- export declare function Textarea({ className, "aria-describedby": describedBy, ...rest }: ComponentProps<"textarea">): import("react").JSX.Element;
606
673
  //#endregion
607
674
  //#region src/components/ui/Kbd.d.ts
608
675
  /**
@@ -776,6 +843,39 @@ export declare function ReadoutStrip({ items, className }: {
776
843
  className?: string | undefined;
777
844
  }): import("react").JSX.Element | null;
778
845
  //#endregion
846
+ //#region src/components/ui/Progress.d.ts
847
+ /**
848
+ * The accessible value text of a progress: `"412 of 2,556"`, or `null` while indeterminate.
849
+ *
850
+ * @param value - Done so far; `null` or `undefined` for an unknown amount.
851
+ * @param max - The whole. Defaults to 100.
852
+ * @returns The text, with the value clamped to `[0, max]`.
853
+ */
854
+ export declare function progressText(value: number | null | undefined, max?: number): string | null;
855
+ /** Props of `Progress`: a value out of a `max`, or none for an unknown amount, plus the `<div>` props. */
856
+ type ProgressProps = Omit<ComponentProps<"div">, "children" | "role"> & {
857
+ /** Done so far, from 0 to `max`; clamped. `null` or left out: indeterminate, the amount unknown. */
858
+ value?: number | null | undefined;
859
+ /** The whole. Defaults to 100; a value ≤ 0 counts as 100. */
860
+ max?: number | undefined;
861
+ /**
862
+ * What a screen reader says for the value. Defaults to `"412 of 2,556"`; give your own when
863
+ * the unit matters ("412 of 2,556 strings").
864
+ */
865
+ valueText?: string | undefined;
866
+ };
867
+ /**
868
+ * A progress bar: determinate when it has a `value` (a `max`, 100 by default), indeterminate
869
+ * without one. Name it with `aria-label` or `aria-labelledby`.
870
+ *
871
+ * A `progressbar` with `aria-valuenow`, `aria-valuemax` and `aria-valuetext` ("412 of 2,556",
872
+ * or your `valueText`); indeterminate, it has none of them, as the ARIA pattern asks.
873
+ * The track follows the density in force. State is exposed as `data-state`
874
+ * (`"indeterminate"`, `"loading"` or `"complete"`). With reduced motion the indeterminate bar
875
+ * holds still.
876
+ */
877
+ export declare function Progress({ value, max, valueText, className, ...rest }: ProgressProps): import("react").JSX.Element;
878
+ //#endregion
779
879
  //#region src/components/ui/Popover.d.ts
780
880
  /** Props of `Popover`. */
781
881
  interface PopoverProps {
@@ -998,6 +1098,34 @@ export declare function Slider({ value, onValueChange, onValueCommit, min, max,
998
1098
  className?: string | undefined;
999
1099
  }): import("react").JSX.Element;
1000
1100
  //#endregion
1101
+ //#region src/components/ui/tableSort.d.ts
1102
+ /** Which way a column is sorted. Named as `aria-sort` names them: `"ascending"` puts the smallest first. */
1103
+ type SortDirection = "ascending" | "descending";
1104
+ /** The column a table is sorted by, and which way. Where a sort is expected, `null` means the rows' own order. */
1105
+ interface TableSort {
1106
+ /** The sorted column's `key`. */
1107
+ key: string;
1108
+ /** Which way. */
1109
+ direction: SortDirection;
1110
+ }
1111
+ /**
1112
+ * The rows in the order a `Table` with these columns shows them under `sort`.
1113
+ *
1114
+ * The sort is stable in both directions: rows that compare equal keep their order in `rows`.
1115
+ * With the column's `compare`, that function decides (reversed for `"descending"`). With its
1116
+ * `sortValue`, numbers compare by value and strings by a fixed English collation that reads
1117
+ * digit runs as numbers ("frame 9" before "frame 10"), the same on a server as in any
1118
+ * browser; numbers come before strings; and `null`, `undefined` and `NaN` go last in both
1119
+ * directions. A `null` sort, a `key` that names no column, and a column that is not sortable or
1120
+ * has neither function leave the order as given.
1121
+ *
1122
+ * @param rows - The rows, in their own order. Not modified.
1123
+ * @param columns - The table's columns; only `key`, `sortable`, `sortValue` and `compare` are read.
1124
+ * @param sort - The column and direction, or `null` for the rows' own order.
1125
+ * @returns A new array of the same rows, sorted.
1126
+ */
1127
+ export declare function sortRows<Row>(rows: readonly Row[], columns: readonly Pick<Column<Row>, "key" | "sortable" | "sortValue" | "compare">[], sort: TableSort | null | undefined): Row[];
1128
+ //#endregion
1001
1129
  //#region src/components/ui/Table.d.ts
1002
1130
  /** One column of a `Table`: its header and how to render a row's cell. */
1003
1131
  type Column<Row> = {
@@ -1011,20 +1139,75 @@ type Column<Row> = {
1011
1139
  width?: string;
1012
1140
  /** The cell's content for a row. */
1013
1141
  cell: (row: Row) => ReactNode;
1142
+ /**
1143
+ * Whether the header sorts the table. Defaults to `true` when the column has a `sortValue`
1144
+ * or a `compare`. Set it `true` with neither for a column the app sorts itself (see the
1145
+ * table's `manualSort`), or `false` to keep a column with a `sortValue` unsortable.
1146
+ */
1147
+ sortable?: boolean | undefined;
1148
+ /**
1149
+ * The value the column sorts by. Numbers compare by value; strings by a fixed English
1150
+ * collation that reads digit runs as numbers ("frame 9" before "frame 10"), so a server
1151
+ * render and the browser agree; numbers come before strings. `null`, `undefined` and `NaN`
1152
+ * go last in both directions.
1153
+ */
1154
+ sortValue?: ((row: Row) => number | string | null | undefined) | undefined;
1155
+ /**
1156
+ * A full ascending comparison, for an order one value cannot express (two fields, a rank):
1157
+ * negative when `a` comes first. Takes precedence over `sortValue`. Reversed for
1158
+ * `"descending"`; rows that compare equal keep their order in `rows` either way.
1159
+ */
1160
+ compare?: ((a: Row, b: Row) => number) | undefined;
1161
+ /**
1162
+ * The direction of the first click on the header. Defaults to `"ascending"`; `"descending"`
1163
+ * suits a score, where the best comes first.
1164
+ */
1165
+ firstSort?: SortDirection | undefined;
1014
1166
  };
1167
+ /**
1168
+ * Windowed rendering for a long table: only the rows in view, plus `overscan` on each side,
1169
+ * are in the DOM. The rows scroll under a sticky header drawn on `surface`, the panel colour.
1170
+ */
1171
+ interface TableWindowing {
1172
+ /**
1173
+ * Every body row's height in px. Rows are drawn exactly this tall and cells keep to one line
1174
+ * (longer content is cut with an ellipsis), so it must be at least the density's own row
1175
+ * height: 36 px comfortable, 22 px compact.
1176
+ */
1177
+ rowHeight: number;
1178
+ /**
1179
+ * The scroll area's height in px, header included. Leave it out to fill the height of the
1180
+ * container, which must then have one (a flex child with `min-h-0`, a fixed-height panel).
1181
+ */
1182
+ height?: number | undefined;
1183
+ /** Rows rendered beyond each edge of the view, so a fast scroll shows no gap. Defaults to 8. */
1184
+ overscan?: number | undefined;
1185
+ }
1015
1186
  /**
1016
1187
  * A table of rows, with numeric columns set in mono and right-aligned.
1017
1188
  *
1018
1189
  * With `onRowClick` the rows are keyboard-reachable (Tab, then Enter or Space) while keeping
1019
1190
  * their table semantics. The active row carries `aria-current` and `data-state="active"`;
1020
1191
  * padding follows the density in force. With no rows it renders the `empty` message instead.
1192
+ *
1193
+ * A column with a `sortValue` or a `compare` gets a header button: each click moves its sort
1194
+ * from the column's `firstSort` direction to the other one, then back to the rows' own order.
1195
+ * The sorted header carries `aria-sort` and `data-sort` (`"ascending"` or `"descending"`);
1196
+ * other sortable headers carry `data-sort="none"`. The sort is kept by the table (from
1197
+ * `defaultSort`) or controlled (`sort` with `onSortChange`); with `manualSort` the headers
1198
+ * show it and the rows render as given. Row callbacks always receive a row's index in `rows`,
1199
+ * whatever the order on screen.
1200
+ *
1201
+ * Activatable rows also move focus with the arrow keys, Page Up / Page Down and Home / End.
1202
+ * With `windowed` the table scrolls itself (vertically, under a sticky header), renders only the
1203
+ * rows in view, and uses a fixed layout: give columns a `width` where the content needs it.
1021
1204
  */
1022
- export declare function Table<Row>({ columns, rows, rowKey, empty, caption, className, onRowClick, isRowActive, onRowHover }: {
1205
+ export declare function Table<Row>({ columns, rows, rowKey, empty, caption, className, onRowClick, isRowActive, onRowHover, sort: controlledSort, defaultSort, onSortChange, manualSort, windowed }: {
1023
1206
  /** The columns, in order. */
1024
1207
  columns: Column<Row>[];
1025
- /** The rows, in order. */
1208
+ /** The rows, in their own order: the order shown while the table is not sorted. */
1026
1209
  rows: Row[];
1027
- /** A stable key per row. */
1210
+ /** A stable key per row. `index` is the row's position in `rows`, whatever the sort. */
1028
1211
  rowKey: (row: Row, index: number) => string | number;
1029
1212
  /** Shown instead of the table when there are no rows. Defaults to "Nothing here.". */
1030
1213
  empty?: ReactNode;
@@ -1035,16 +1218,76 @@ export declare function Table<Row>({ columns, rows, rowKey, empty, caption, clas
1035
1218
  /** Makes rows activatable. Keyboard-reachable, so a table used as a list of
1036
1219
  * destinations is not a mouse-only control. The event is passed so a caller can read
1037
1220
  * modifiers — a list kept in step with a canvas needs shift-range and meta-toggle to mean
1038
- * the same thing in both places. */
1221
+ * the same thing in both places. `index` is the row's position in `rows`, whatever the
1222
+ * sort. */
1039
1223
  onRowClick?: (row: Row, index: number, event: MouseEvent<HTMLTableRowElement> | KeyboardEvent<HTMLTableRowElement>) => void;
1040
1224
  /** Marks the row that is current — the selected match, the open frame. Rendered as
1041
- * `aria-current`, so it is announced rather than only tinted. */
1225
+ * `aria-current`, so it is announced rather than only tinted. `index` is the row's
1226
+ * position in `rows`, whatever the sort. */
1042
1227
  isRowActive?: (row: Row, index: number) => boolean;
1043
1228
  /** Pointer enter/leave, for tables kept in step with a canvas overlay.
1044
- * `null` on leave. */
1229
+ * `null` on leave. `index` is the row's position in `rows`, whatever the sort. */
1045
1230
  onRowHover?: (row: Row | null, index: number | null) => void;
1231
+ /**
1232
+ * The sort, controlled: a column `key` and a direction, or `null` for the rows' own order.
1233
+ * Leave it undefined and the table keeps the sort itself, starting from `defaultSort`.
1234
+ */
1235
+ sort?: TableSort | null | undefined;
1236
+ /** The sort the table starts with when `sort` is not given. Defaults to `null`, the rows' own order. */
1237
+ defaultSort?: TableSort | null | undefined;
1238
+ /**
1239
+ * Called on a header click with the new sort: the column's `firstSort` direction, then the
1240
+ * other, then `null`. A click on another column starts that column at its `firstSort`.
1241
+ */
1242
+ onSortChange?: ((sort: TableSort | null) => void) | undefined;
1243
+ /**
1244
+ * The app orders the rows (on a server, say): the headers show the sort and report clicks,
1245
+ * and the rows render exactly as given. Mark the columns it can sort `sortable: true`.
1246
+ */
1247
+ manualSort?: boolean | undefined;
1248
+ /**
1249
+ * Render only the rows in view, for a long table: every row `rowHeight` tall, in a scroll
1250
+ * area of `height` (or the container's height) under a sticky header. Sorting, row
1251
+ * callbacks and keyboard navigation work as without it.
1252
+ */
1253
+ windowed?: TableWindowing | undefined;
1046
1254
  }): import("react").JSX.Element;
1047
1255
  //#endregion
1256
+ //#region src/components/ui/Textarea.d.ts
1257
+ /**
1258
+ * Props of `Textarea`: every `<textarea>` prop, `ref` included, plus an invalid state, the
1259
+ * mono face, and growing with the content between `minRows` and `maxRows`.
1260
+ */
1261
+ type TextareaProps = ComponentProps<"textarea"> & {
1262
+ /** Called with the new text on every edit, alongside the native `onChange`. */
1263
+ onValueChange?: ((value: string) => void) | undefined;
1264
+ /**
1265
+ * Marks the value as wrong: `aria-invalid`, `data-invalid` and a border in the defect
1266
+ * colour. Inside a `Field` with an `error` it is on without this. Say what is wrong in
1267
+ * text too (the field's `error`): the border alone is a colour.
1268
+ */
1269
+ invalid?: boolean | undefined;
1270
+ /** Sets the text in IBM Plex Mono, for code, JSON, lists, or strings whose characters all matter. */
1271
+ mono?: boolean | undefined;
1272
+ /**
1273
+ * Grows with the content from this many lines. Set it or `maxRows` to turn growing on;
1274
+ * `rows` is then ignored.
1275
+ */
1276
+ minRows?: number | undefined;
1277
+ /** Stops growing at this many lines and scrolls beyond them. Set it or `minRows` to turn growing on. */
1278
+ maxRows?: number | undefined;
1279
+ };
1280
+ /**
1281
+ * Multi-line text, on the shared control palette. Takes every `<textarea>` prop, `ref`
1282
+ * included; inside a `Field` it is described by the field's description and error, and
1283
+ * shown invalid while the field has an error.
1284
+ *
1285
+ * With `minRows` or `maxRows` it grows with its content between the two (and scrolls past
1286
+ * `maxRows`); without them it is `rows` tall and the reader can resize it. State is exposed
1287
+ * as `data-invalid`.
1288
+ */
1289
+ export declare function Textarea({ className, "aria-describedby": describedBy, invalid, mono, minRows, maxRows, rows, value, onChange, onValueChange, ref, ...rest }: TextareaProps): import("react").JSX.Element;
1290
+ //#endregion
1048
1291
  //#region src/components/ui/Toggle.d.ts
1049
1292
  /**
1050
1293
  * A setting: changes how the thing behaves from now on, and reads as one ("show the mask").
@@ -1343,5 +1586,5 @@ export declare function Tabs<Id extends string>({ items, active, onSelect, label
1343
1586
  className?: string | undefined;
1344
1587
  }): import("react").JSX.Element;
1345
1588
  //#endregion
1346
- export type { BackLink, ButtonSize, ButtonVariant, CalloutTone, Column, Density, DropdownMenuProps, ListboxOption, ListboxOptionState, ListboxProps, MeasureTone, MenuCheckboxItemProps, MenuItemProps, NumberInputProps, PopoverProps, PoseInputProps, PoseValue, Quaternion, ReadoutItem, RotationView, SelectOption, TabItem, ThemeChoice, ToastOptions, ToastRecord, ToastStore, ToastTone, ToasterProps, Tone, Vec3, VectorInputProps };
1589
+ export type { BackLink, ButtonSize, ButtonVariant, CalloutTone, Column, Density, DropdownMenuProps, HighlightKind, HighlightRule, HighlightSpan, HighlightedTextProps, ListboxOption, ListboxOptionState, ListboxProps, MeasureTone, MenuCheckboxItemProps, MenuItemProps, NumberInputProps, PopoverProps, PoseInputProps, PoseValue, ProgressProps, Quaternion, ReadoutItem, RotationView, SelectOption, SortDirection, TabItem, TableSort, TableWindowing, TextareaProps, ThemeChoice, ToastOptions, ToastRecord, ToastStore, ToastTone, ToasterProps, Tone, Vec3, VectorInputProps };
1347
1590
  //# sourceMappingURL=index.d.ts.map