@vitavision/ui 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md 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
package/dist/index.d.ts CHANGED
@@ -998,6 +998,34 @@ export declare function Slider({ value, onValueChange, onValueCommit, min, max,
998
998
  className?: string | undefined;
999
999
  }): import("react").JSX.Element;
1000
1000
  //#endregion
1001
+ //#region src/components/ui/tableSort.d.ts
1002
+ /** Which way a column is sorted. Named as `aria-sort` names them: `"ascending"` puts the smallest first. */
1003
+ type SortDirection = "ascending" | "descending";
1004
+ /** The column a table is sorted by, and which way. Where a sort is expected, `null` means the rows' own order. */
1005
+ interface TableSort {
1006
+ /** The sorted column's `key`. */
1007
+ key: string;
1008
+ /** Which way. */
1009
+ direction: SortDirection;
1010
+ }
1011
+ /**
1012
+ * The rows in the order a `Table` with these columns shows them under `sort`.
1013
+ *
1014
+ * The sort is stable in both directions: rows that compare equal keep their order in `rows`.
1015
+ * With the column's `compare`, that function decides (reversed for `"descending"`). With its
1016
+ * `sortValue`, numbers compare by value and strings by a fixed English collation that reads
1017
+ * digit runs as numbers ("frame 9" before "frame 10"), the same on a server as in any
1018
+ * browser; numbers come before strings; and `null`, `undefined` and `NaN` go last in both
1019
+ * directions. A `null` sort, a `key` that names no column, and a column that is not sortable or
1020
+ * has neither function leave the order as given.
1021
+ *
1022
+ * @param rows - The rows, in their own order. Not modified.
1023
+ * @param columns - The table's columns; only `key`, `sortable`, `sortValue` and `compare` are read.
1024
+ * @param sort - The column and direction, or `null` for the rows' own order.
1025
+ * @returns A new array of the same rows, sorted.
1026
+ */
1027
+ export declare function sortRows<Row>(rows: readonly Row[], columns: readonly Pick<Column<Row>, "key" | "sortable" | "sortValue" | "compare">[], sort: TableSort | null | undefined): Row[];
1028
+ //#endregion
1001
1029
  //#region src/components/ui/Table.d.ts
1002
1030
  /** One column of a `Table`: its header and how to render a row's cell. */
1003
1031
  type Column<Row> = {
@@ -1011,6 +1039,30 @@ type Column<Row> = {
1011
1039
  width?: string;
1012
1040
  /** The cell's content for a row. */
1013
1041
  cell: (row: Row) => ReactNode;
1042
+ /**
1043
+ * Whether the header sorts the table. Defaults to `true` when the column has a `sortValue`
1044
+ * or a `compare`. Set it `true` with neither for a column the app sorts itself (see the
1045
+ * table's `manualSort`), or `false` to keep a column with a `sortValue` unsortable.
1046
+ */
1047
+ sortable?: boolean | undefined;
1048
+ /**
1049
+ * The value the column sorts by. Numbers compare by value; strings by a fixed English
1050
+ * collation that reads digit runs as numbers ("frame 9" before "frame 10"), so a server
1051
+ * render and the browser agree; numbers come before strings. `null`, `undefined` and `NaN`
1052
+ * go last in both directions.
1053
+ */
1054
+ sortValue?: ((row: Row) => number | string | null | undefined) | undefined;
1055
+ /**
1056
+ * A full ascending comparison, for an order one value cannot express (two fields, a rank):
1057
+ * negative when `a` comes first. Takes precedence over `sortValue`. Reversed for
1058
+ * `"descending"`; rows that compare equal keep their order in `rows` either way.
1059
+ */
1060
+ compare?: ((a: Row, b: Row) => number) | undefined;
1061
+ /**
1062
+ * The direction of the first click on the header. Defaults to `"ascending"`; `"descending"`
1063
+ * suits a score, where the best comes first.
1064
+ */
1065
+ firstSort?: SortDirection | undefined;
1014
1066
  };
1015
1067
  /**
1016
1068
  * A table of rows, with numeric columns set in mono and right-aligned.
@@ -1018,13 +1070,21 @@ type Column<Row> = {
1018
1070
  * With `onRowClick` the rows are keyboard-reachable (Tab, then Enter or Space) while keeping
1019
1071
  * their table semantics. The active row carries `aria-current` and `data-state="active"`;
1020
1072
  * padding follows the density in force. With no rows it renders the `empty` message instead.
1021
- */
1022
- export declare function Table<Row>({ columns, rows, rowKey, empty, caption, className, onRowClick, isRowActive, onRowHover }: {
1073
+ *
1074
+ * A column with a `sortValue` or a `compare` gets a header button: each click moves its sort
1075
+ * from the column's `firstSort` direction to the other one, then back to the rows' own order.
1076
+ * The sorted header carries `aria-sort` and `data-sort` (`"ascending"` or `"descending"`);
1077
+ * other sortable headers carry `data-sort="none"`. The sort is kept by the table (from
1078
+ * `defaultSort`) or controlled (`sort` with `onSortChange`); with `manualSort` the headers
1079
+ * show it and the rows render as given. Row callbacks always receive a row's index in `rows`,
1080
+ * whatever the order on screen.
1081
+ */
1082
+ export declare function Table<Row>({ columns, rows, rowKey, empty, caption, className, onRowClick, isRowActive, onRowHover, sort: controlledSort, defaultSort, onSortChange, manualSort }: {
1023
1083
  /** The columns, in order. */
1024
1084
  columns: Column<Row>[];
1025
- /** The rows, in order. */
1085
+ /** The rows, in their own order: the order shown while the table is not sorted. */
1026
1086
  rows: Row[];
1027
- /** A stable key per row. */
1087
+ /** A stable key per row. `index` is the row's position in `rows`, whatever the sort. */
1028
1088
  rowKey: (row: Row, index: number) => string | number;
1029
1089
  /** Shown instead of the table when there are no rows. Defaults to "Nothing here.". */
1030
1090
  empty?: ReactNode;
@@ -1035,14 +1095,33 @@ export declare function Table<Row>({ columns, rows, rowKey, empty, caption, clas
1035
1095
  /** Makes rows activatable. Keyboard-reachable, so a table used as a list of
1036
1096
  * destinations is not a mouse-only control. The event is passed so a caller can read
1037
1097
  * modifiers — a list kept in step with a canvas needs shift-range and meta-toggle to mean
1038
- * the same thing in both places. */
1098
+ * the same thing in both places. `index` is the row's position in `rows`, whatever the
1099
+ * sort. */
1039
1100
  onRowClick?: (row: Row, index: number, event: MouseEvent<HTMLTableRowElement> | KeyboardEvent<HTMLTableRowElement>) => void;
1040
1101
  /** 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. */
1102
+ * `aria-current`, so it is announced rather than only tinted. `index` is the row's
1103
+ * position in `rows`, whatever the sort. */
1042
1104
  isRowActive?: (row: Row, index: number) => boolean;
1043
1105
  /** Pointer enter/leave, for tables kept in step with a canvas overlay.
1044
- * `null` on leave. */
1106
+ * `null` on leave. `index` is the row's position in `rows`, whatever the sort. */
1045
1107
  onRowHover?: (row: Row | null, index: number | null) => void;
1108
+ /**
1109
+ * The sort, controlled: a column `key` and a direction, or `null` for the rows' own order.
1110
+ * Leave it undefined and the table keeps the sort itself, starting from `defaultSort`.
1111
+ */
1112
+ sort?: TableSort | null | undefined;
1113
+ /** The sort the table starts with when `sort` is not given. Defaults to `null`, the rows' own order. */
1114
+ defaultSort?: TableSort | null | undefined;
1115
+ /**
1116
+ * Called on a header click with the new sort: the column's `firstSort` direction, then the
1117
+ * other, then `null`. A click on another column starts that column at its `firstSort`.
1118
+ */
1119
+ onSortChange?: ((sort: TableSort | null) => void) | undefined;
1120
+ /**
1121
+ * The app orders the rows (on a server, say): the headers show the sort and report clicks,
1122
+ * and the rows render exactly as given. Mark the columns it can sort `sortable: true`.
1123
+ */
1124
+ manualSort?: boolean | undefined;
1046
1125
  }): import("react").JSX.Element;
1047
1126
  //#endregion
1048
1127
  //#region src/components/ui/Toggle.d.ts
@@ -1343,5 +1422,5 @@ export declare function Tabs<Id extends string>({ items, active, onSelect, label
1343
1422
  className?: string | undefined;
1344
1423
  }): import("react").JSX.Element;
1345
1424
  //#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 };
1425
+ export type { BackLink, ButtonSize, ButtonVariant, CalloutTone, Column, Density, DropdownMenuProps, ListboxOption, ListboxOptionState, ListboxProps, MeasureTone, MenuCheckboxItemProps, MenuItemProps, NumberInputProps, PopoverProps, PoseInputProps, PoseValue, Quaternion, ReadoutItem, RotationView, SelectOption, SortDirection, TabItem, TableSort, ThemeChoice, ToastOptions, ToastRecord, ToastStore, ToastTone, ToasterProps, Tone, Vec3, VectorInputProps };
1347
1426
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { AlertTriangle, Check, CheckCircle2, ChevronDown, ChevronRight, CircleCheck, CircleX, HelpCircle, Info, Loader2, Minus, Moon, Sun, SunMoon, TriangleAlert, X, XCircle } from "lucide-react";
1
+ import { AlertTriangle, ArrowDown, ArrowUp, ArrowUpDown, Check, CheckCircle2, ChevronDown, ChevronRight, CircleCheck, CircleX, HelpCircle, Info, Loader2, Minus, Moon, Sun, SunMoon, TriangleAlert, X, XCircle } from "lucide-react";
2
2
  import { createContext, isValidElement, use, useCallback, useEffect, useId, useMemo, useRef, useState, useSyncExternalStore } from "react";
3
3
  import * as RadixTooltip from "@radix-ui/react-tooltip";
4
4
  import { clsx } from "clsx";
@@ -1775,16 +1775,123 @@ function Slider({ value, onValueChange, onValueCommit, min = 0, max = 1, step =
1775
1775
  });
1776
1776
  }
1777
1777
  //#endregion
1778
+ //#region src/components/ui/tableSort.ts
1779
+ /** Strings by a fixed English collation that reads digit runs as numbers: "frame 9" before "frame 10". */
1780
+ const collator = new Intl.Collator("en", { numeric: true });
1781
+ /**
1782
+ * Whether a column's header sorts the table: `sortable` if given, otherwise whether the column
1783
+ * says how to order (`sortValue` or `compare`).
1784
+ */
1785
+ function isSortable(column) {
1786
+ return column.sortable ?? (column.sortValue !== void 0 || column.compare !== void 0);
1787
+ }
1788
+ /** The sort after a click on `column`'s header: its first direction, then the other, then none. */
1789
+ function nextSort(current, column) {
1790
+ const first = column.firstSort ?? "ascending";
1791
+ if (current?.key !== column.key) return {
1792
+ key: column.key,
1793
+ direction: first
1794
+ };
1795
+ if (current.direction !== first) return null;
1796
+ return {
1797
+ key: column.key,
1798
+ direction: first === "ascending" ? "descending" : "ascending"
1799
+ };
1800
+ }
1801
+ /** A value with no place in the order: `null`, `undefined` or `NaN`. */
1802
+ function missing(value) {
1803
+ return value === null || value === void 0 || Number.isNaN(value);
1804
+ }
1805
+ /**
1806
+ * Two present values in ascending order: numbers by value (compared, not subtracted, so two
1807
+ * infinities tie), strings by the collator, and every number before every string.
1808
+ */
1809
+ function compareValues(a, b) {
1810
+ if (typeof a === "number" && typeof b === "number") return a < b ? -1 : a > b ? 1 : 0;
1811
+ if (typeof a === "string" && typeof b === "string") return collator.compare(a, b);
1812
+ return typeof a === "number" ? -1 : 1;
1813
+ }
1814
+ /**
1815
+ * The display order of `rows` under `sort`, as indices into `rows`. `Table` renders through it
1816
+ * so each row keeps its original index for the row callbacks.
1817
+ */
1818
+ function sortOrder(rows, columns, sort) {
1819
+ const order = rows.map((_, index) => index);
1820
+ if (!sort) return order;
1821
+ const column = columns.find((candidate) => candidate.key === sort.key);
1822
+ if (!column || !isSortable(column)) return order;
1823
+ const sign = sort.direction === "descending" ? -1 : 1;
1824
+ const { compare, sortValue } = column;
1825
+ if (compare) return order.sort((a, b) => sign * compare(rows[a], rows[b]) || a - b);
1826
+ if (!sortValue) return order;
1827
+ const values = rows.map((row) => sortValue(row));
1828
+ return order.sort((a, b) => {
1829
+ const left = values[a];
1830
+ const right = values[b];
1831
+ const leftMissing = missing(left);
1832
+ const rightMissing = missing(right);
1833
+ if (leftMissing || rightMissing) return leftMissing === rightMissing ? a - b : leftMissing ? 1 : -1;
1834
+ return sign * compareValues(left, right) || a - b;
1835
+ });
1836
+ }
1837
+ /**
1838
+ * The rows in the order a `Table` with these columns shows them under `sort`.
1839
+ *
1840
+ * The sort is stable in both directions: rows that compare equal keep their order in `rows`.
1841
+ * With the column's `compare`, that function decides (reversed for `"descending"`). With its
1842
+ * `sortValue`, numbers compare by value and strings by a fixed English collation that reads
1843
+ * digit runs as numbers ("frame 9" before "frame 10"), the same on a server as in any
1844
+ * browser; numbers come before strings; and `null`, `undefined` and `NaN` go last in both
1845
+ * directions. A `null` sort, a `key` that names no column, and a column that is not sortable or
1846
+ * has neither function leave the order as given.
1847
+ *
1848
+ * @param rows - The rows, in their own order. Not modified.
1849
+ * @param columns - The table's columns; only `key`, `sortable`, `sortValue` and `compare` are read.
1850
+ * @param sort - The column and direction, or `null` for the rows' own order.
1851
+ * @returns A new array of the same rows, sorted.
1852
+ */
1853
+ function sortRows(rows, columns, sort) {
1854
+ return sortOrder(rows, columns, sort).map((index) => rows[index]);
1855
+ }
1856
+ //#endregion
1778
1857
  //#region src/components/ui/Table.tsx
1858
+ /** The header icon for a sort state: the direction when sorted, both arrows when only sortable. */
1859
+ const SORT_ICONS = {
1860
+ ascending: ArrowUp,
1861
+ descending: ArrowDown,
1862
+ none: ArrowUpDown
1863
+ };
1779
1864
  /**
1780
1865
  * A table of rows, with numeric columns set in mono and right-aligned.
1781
1866
  *
1782
1867
  * With `onRowClick` the rows are keyboard-reachable (Tab, then Enter or Space) while keeping
1783
1868
  * their table semantics. The active row carries `aria-current` and `data-state="active"`;
1784
1869
  * padding follows the density in force. With no rows it renders the `empty` message instead.
1785
- */
1786
- function Table({ columns, rows, rowKey, empty = "Nothing here.", caption, className, onRowClick, isRowActive, onRowHover }) {
1870
+ *
1871
+ * A column with a `sortValue` or a `compare` gets a header button: each click moves its sort
1872
+ * from the column's `firstSort` direction to the other one, then back to the rows' own order.
1873
+ * The sorted header carries `aria-sort` and `data-sort` (`"ascending"` or `"descending"`);
1874
+ * other sortable headers carry `data-sort="none"`. The sort is kept by the table (from
1875
+ * `defaultSort`) or controlled (`sort` with `onSortChange`); with `manualSort` the headers
1876
+ * show it and the rows render as given. Row callbacks always receive a row's index in `rows`,
1877
+ * whatever the order on screen.
1878
+ */
1879
+ function Table({ columns, rows, rowKey, empty = "Nothing here.", caption, className, onRowClick, isRowActive, onRowHover, sort: controlledSort, defaultSort = null, onSortChange, manualSort = false }) {
1787
1880
  const density = useDensity();
1881
+ const [ownSort, setOwnSort] = useState(defaultSort);
1882
+ const controlled = controlledSort !== void 0;
1883
+ const sort = controlled ? controlledSort : ownSort;
1884
+ const order = useMemo(() => manualSort ? rows.map((_, index) => index) : sortOrder(rows, columns, sort), [
1885
+ rows,
1886
+ columns,
1887
+ sort,
1888
+ manualSort
1889
+ ]);
1890
+ const changeSort = (column) => {
1891
+ const next = nextSort(sort, column);
1892
+ if (!controlled) setOwnSort(next);
1893
+ onSortChange?.(next);
1894
+ };
1788
1895
  if (rows.length === 0) return /* @__PURE__ */ jsx("p", {
1789
1896
  className: cn("text-center text-fg-muted", byDensity(density, "py-6 text-sm", "py-3 text-xs"), className),
1790
1897
  children: empty
@@ -1800,32 +1907,51 @@ function Table({ columns, rows, rowKey, empty = "Nothing here.", caption, classN
1800
1907
  }),
1801
1908
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", {
1802
1909
  className: "border-b border-line",
1803
- children: columns.map((column) => /* @__PURE__ */ jsx("th", {
1804
- scope: "col",
1805
- style: column.width ? { width: column.width } : void 0,
1806
- className: cn("font-medium text-fg-muted", byDensity(density, "pb-2 pr-3 text-xs", "pb-1 pr-2 text-[10px]"), column.numeric && "text-right"),
1807
- children: column.header
1808
- }, column.key))
1910
+ children: columns.map((column) => {
1911
+ const sortable = isSortable(column);
1912
+ const direction = sortable && sort?.key === column.key ? sort.direction : void 0;
1913
+ const SortIcon = SORT_ICONS[direction ?? "none"];
1914
+ return /* @__PURE__ */ jsx("th", {
1915
+ scope: "col",
1916
+ style: column.width ? { width: column.width } : void 0,
1917
+ "aria-sort": direction,
1918
+ "data-sort": sortable ? direction ?? "none" : void 0,
1919
+ className: cn("font-medium text-fg-muted last:pr-0", byDensity(density, "pb-2 pr-3 text-xs", "pb-1 pr-2 text-[10px]"), column.numeric && "text-right"),
1920
+ children: sortable ? /* @__PURE__ */ jsxs("button", {
1921
+ type: "button",
1922
+ onClick: () => changeSort(column),
1923
+ className: cn("-mx-1 flex w-fit max-w-full cursor-pointer items-center gap-1 rounded-control px-1", "font-medium transition-colors hover:text-fg", focusRing, column.numeric ? "ml-auto flex-row-reverse text-right" : "text-left", direction && "text-fg"),
1924
+ children: [column.header, /* @__PURE__ */ jsx(SortIcon, {
1925
+ "aria-hidden": true,
1926
+ className: cn("shrink-0", byDensity(density, "size-3", "size-2.5"), !direction && "text-fg-subtle")
1927
+ })]
1928
+ }) : column.header
1929
+ }, column.key);
1930
+ })
1809
1931
  }) }),
1810
- /* @__PURE__ */ jsx("tbody", { children: rows.map((row, index) => /* @__PURE__ */ jsx("tr", {
1811
- "data-state": isRowActive?.(row, index) ? "active" : void 0,
1812
- className: cn("border-b border-line/60 last:border-0", onRowClick && "cursor-pointer hover:bg-raised", isRowActive?.(row, index) && "bg-signal/10"),
1813
- tabIndex: onRowClick ? 0 : void 0,
1814
- "aria-current": isRowActive?.(row, index) ? true : void 0,
1815
- onClick: onRowClick ? (event) => onRowClick(row, index, event) : void 0,
1816
- onKeyDown: onRowClick ? (event) => {
1817
- if (event.key === "Enter" || event.key === " ") {
1818
- event.preventDefault();
1819
- onRowClick(row, index, event);
1820
- }
1821
- } : void 0,
1822
- onPointerEnter: onRowHover ? () => onRowHover(row, index) : void 0,
1823
- onPointerLeave: onRowHover ? () => onRowHover(null, null) : void 0,
1824
- children: columns.map((column) => /* @__PURE__ */ jsx("td", {
1825
- className: cn("align-middle text-fg last:pr-0", byDensity(density, "py-2 pr-3", "py-0.5 pr-2"), column.numeric && "text-right font-mono tabular-nums"),
1826
- children: column.cell(row)
1827
- }, column.key))
1828
- }, rowKey(row, index))) })
1932
+ /* @__PURE__ */ jsx("tbody", { children: order.map((index) => {
1933
+ const row = rows[index];
1934
+ const active = isRowActive?.(row, index) ?? false;
1935
+ return /* @__PURE__ */ jsx("tr", {
1936
+ "data-state": active ? "active" : void 0,
1937
+ className: cn("border-b border-line/60 last:border-0", onRowClick && "cursor-pointer hover:bg-raised", active && "bg-signal/10"),
1938
+ tabIndex: onRowClick ? 0 : void 0,
1939
+ "aria-current": active ? true : void 0,
1940
+ onClick: onRowClick ? (event) => onRowClick(row, index, event) : void 0,
1941
+ onKeyDown: onRowClick ? (event) => {
1942
+ if (event.key === "Enter" || event.key === " ") {
1943
+ event.preventDefault();
1944
+ onRowClick(row, index, event);
1945
+ }
1946
+ } : void 0,
1947
+ onPointerEnter: onRowHover ? () => onRowHover(row, index) : void 0,
1948
+ onPointerLeave: onRowHover ? () => onRowHover(null, null) : void 0,
1949
+ children: columns.map((column) => /* @__PURE__ */ jsx("td", {
1950
+ className: cn("align-middle text-fg last:pr-0", byDensity(density, "py-2 pr-3", "py-0.5 pr-2"), column.numeric && "text-right font-mono tabular-nums"),
1951
+ children: column.cell(row)
1952
+ }, column.key))
1953
+ }, rowKey(row, index));
1954
+ }) })
1829
1955
  ]
1830
1956
  })
1831
1957
  });
@@ -2199,6 +2325,6 @@ function Tabs({ items, active, onSelect, label, idPrefix, className }) {
2199
2325
  });
2200
2326
  }
2201
2327
  //#endregion
2202
- export { Badge, Button, ButtonLink, Callout, Checkbox, ConfirmDialog, CountRun, DEFAULT_THEME_STORAGE_KEY, DensityProvider, Dialog, DialogClose, Disclosure, DropdownMenu, Empty, ErrorBox, Field, InfoHint, Input, Kbd, Listbox, MenuCheckboxItem, MenuItem, MenuLabel, MenuSeparator, NumberInput, PageHeader, Panel, Popover, PopoverClose, PoseInput, ProgressBar, ReadoutStrip, Section, SegmentedControl, Select, Skeleton, SkeletonRows, Slider, StatusDot, Switch, Table, Tabs, Textarea, ThemeToggle, Toaster, ToggleChip, Tooltip, TooltipProvider, VectorInput, buttonClasses, byDensity, cn, controlClasses, createToastStore, defaultToastStore, focusRing, focusRingInset, formatNumber, initTheme, inputClasses, parseNumber, readThemeChoice, resolveTheme, setThemeChoice, toast, toneColor, useControlHeight, useDensity };
2328
+ export { Badge, Button, ButtonLink, Callout, Checkbox, ConfirmDialog, CountRun, DEFAULT_THEME_STORAGE_KEY, DensityProvider, Dialog, DialogClose, Disclosure, DropdownMenu, Empty, ErrorBox, Field, InfoHint, Input, Kbd, Listbox, MenuCheckboxItem, MenuItem, MenuLabel, MenuSeparator, NumberInput, PageHeader, Panel, Popover, PopoverClose, PoseInput, ProgressBar, ReadoutStrip, Section, SegmentedControl, Select, Skeleton, SkeletonRows, Slider, StatusDot, Switch, Table, Tabs, Textarea, ThemeToggle, Toaster, ToggleChip, Tooltip, TooltipProvider, VectorInput, buttonClasses, byDensity, cn, controlClasses, createToastStore, defaultToastStore, focusRing, focusRingInset, formatNumber, initTheme, inputClasses, parseNumber, readThemeChoice, resolveTheme, setThemeChoice, sortRows, toast, toneColor, useControlHeight, useDensity };
2203
2329
 
2204
2330
  //# sourceMappingURL=index.js.map