@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 +2 -2
- package/dist/index.d.ts +87 -8
- package/dist/index.js +155 -29
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ThemeToggle.tsx +2 -3
- package/src/components/ui/Table.tsx +188 -65
- package/src/components/ui/index.ts +1 -0
- package/src/components/ui/tableSort.ts +121 -0
- package/src/fonts/fonts.css +1 -1
- package/src/styles.css +3 -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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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) =>
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
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:
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
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
|