@milktop/react-ui 0.2.4 → 0.2.6
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/table/Table.d.ts +4 -2
- package/dist/table/Table.js +12 -5
- package/dist/table/table.css +2 -0
- package/package.json +1 -1
package/dist/table/Table.d.ts
CHANGED
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
* - `selectable`: a checkbox per row and a select-all; `selected`,
|
|
24
24
|
* `defaultSelected`: the selected rows' keys; `onSelectedChange`. Shift-click
|
|
25
25
|
* a row's checkbox to tick (or clear) the rows between it and the last one
|
|
26
|
-
* clicked
|
|
26
|
+
* clicked. Once a row is ticked, clicking a row ticks (or clears) it too,
|
|
27
|
+
* Shift a run, rather than calling `onRowClick`
|
|
27
28
|
* - `loading`: skeleton rows while there are none yet (`loadingRows`, 5),
|
|
28
29
|
* else dims the rows
|
|
29
30
|
* - `emptyText`, or `empty` (markup), for no rows
|
|
@@ -31,7 +32,8 @@
|
|
|
31
32
|
* - `label`: a caption for assistive tech
|
|
32
33
|
* - `size`: 'sm', 'md' (default) or 'lg' (roomier rows)
|
|
33
34
|
* - `flush`: no border or rounding, to sit edge to edge in a card
|
|
34
|
-
* - `onRowClick`: called with the row when a row is clicked (outside its
|
|
35
|
+
* - `onRowClick`: called with the row when a row is clicked (outside its
|
|
36
|
+
* controls), unless rows are ticked; rows then show the pointer
|
|
35
37
|
*
|
|
36
38
|
* Or write the <table> yourself as its content, for the look alone (no
|
|
37
39
|
* sorting, selection or loading states); `data-align` on cells works too.
|
package/dist/table/Table.js
CHANGED
|
@@ -24,7 +24,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
24
24
|
* - `selectable`: a checkbox per row and a select-all; `selected`,
|
|
25
25
|
* `defaultSelected`: the selected rows' keys; `onSelectedChange`. Shift-click
|
|
26
26
|
* a row's checkbox to tick (or clear) the rows between it and the last one
|
|
27
|
-
* clicked
|
|
27
|
+
* clicked. Once a row is ticked, clicking a row ticks (or clears) it too,
|
|
28
|
+
* Shift a run, rather than calling `onRowClick`
|
|
28
29
|
* - `loading`: skeleton rows while there are none yet (`loadingRows`, 5),
|
|
29
30
|
* else dims the rows
|
|
30
31
|
* - `emptyText`, or `empty` (markup), for no rows
|
|
@@ -32,7 +33,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
32
33
|
* - `label`: a caption for assistive tech
|
|
33
34
|
* - `size`: 'sm', 'md' (default) or 'lg' (roomier rows)
|
|
34
35
|
* - `flush`: no border or rounding, to sit edge to edge in a card
|
|
35
|
-
* - `onRowClick`: called with the row when a row is clicked (outside its
|
|
36
|
+
* - `onRowClick`: called with the row when a row is clicked (outside its
|
|
37
|
+
* controls), unless rows are ticked; rows then show the pointer
|
|
36
38
|
*
|
|
37
39
|
* Or write the <table> yourself as its content, for the look alone (no
|
|
38
40
|
* sorting, selection or loading states); `data-align` on cells works too.
|
|
@@ -97,6 +99,8 @@ export function Table({ columns = [], rows = [], rowKey = 'id', selectable = fal
|
|
|
97
99
|
const isSelected = (row) => selected.includes(keyOf(row));
|
|
98
100
|
const selectedCount = rows.filter(isSelected).length;
|
|
99
101
|
const allState = selectedCount === 0 ? false : selectedCount === rows.length ? true : 'indeterminate';
|
|
102
|
+
// Once a row is ticked, a click on a row ticks it rather than opening it.
|
|
103
|
+
const selecting = selectable && selected.length > 0;
|
|
100
104
|
// Change events don't carry the Shift key, so it's noted on the way in;
|
|
101
105
|
// Shift+mousedown would also select the text between.
|
|
102
106
|
const shift = useRef(false);
|
|
@@ -104,7 +108,7 @@ export function Table({ columns = [], rows = [], rowKey = 'id', selectable = fal
|
|
|
104
108
|
function noteShift(e) {
|
|
105
109
|
const event = e.nativeEvent;
|
|
106
110
|
shift.current = event.shiftKey;
|
|
107
|
-
if (event.shiftKey && e.type === 'mousedown' && e.target.closest('[data-part=select-cell]'))
|
|
111
|
+
if (event.shiftKey && e.type === 'mousedown' && (selecting || e.target.closest('[data-part=select-cell]')))
|
|
108
112
|
e.preventDefault();
|
|
109
113
|
}
|
|
110
114
|
function toggleRow(row, on) {
|
|
@@ -131,10 +135,13 @@ export function Table({ columns = [], rows = [], rowKey = 'id', selectable = fal
|
|
|
131
135
|
const control = e.target.closest('a, button, input, label, select, textarea, [data-scope]:not([data-scope=table])');
|
|
132
136
|
if (control && e.currentTarget.contains(control))
|
|
133
137
|
return;
|
|
134
|
-
|
|
138
|
+
if (selecting)
|
|
139
|
+
toggleRow(row, !isSelected(row));
|
|
140
|
+
else
|
|
141
|
+
onRowClick?.(row);
|
|
135
142
|
}
|
|
136
143
|
const columnCount = columns.length + (selectable ? 1 : 0);
|
|
137
|
-
return (_jsx("div", { ...rest, ...part('root'), className: cx(className, classes?.root), "data-size": size, "data-flush": flush || undefined, "data-loading": (loading && rows.length > 0) || undefined, children: _jsx("div", { ...part('scroll'), "data-sticky": maxHeight ? '' : undefined, style: maxHeight ? { maxHeight } : undefined, children: !columns.length ? children : (_jsxs("table", { ...part('table'), "aria-busy": loading, children: [label && _jsx("caption", { ...part('caption'), children: label }), _jsx("thead", { children: _jsxs("tr", { children: [selectable && (_jsx("th", { ...part('select-cell'), scope: "col", children: _jsx(Checkbox, { label: t.table.selectAll, labelHidden: true, disabled: !rows.length, checked: allState, onCheckedChange: (on) => toggleAll(on) }) })), columns.map((column) => (_jsx("th", { scope: "col", "data-align": column.align ?? 'start', "aria-sort": ariaSort(column), style: column.width ? { width: column.width } : undefined, children: column.sortable
|
|
144
|
+
return (_jsx("div", { ...rest, ...part('root'), className: cx(className, classes?.root), "data-size": size, "data-flush": flush || undefined, "data-clickable": onRowClick ? '' : undefined, "data-selecting": selecting || undefined, "data-loading": (loading && rows.length > 0) || undefined, children: _jsx("div", { ...part('scroll'), "data-sticky": maxHeight ? '' : undefined, style: maxHeight ? { maxHeight } : undefined, children: !columns.length ? children : (_jsxs("table", { ...part('table'), "aria-busy": loading, children: [label && _jsx("caption", { ...part('caption'), children: label }), _jsx("thead", { children: _jsxs("tr", { children: [selectable && (_jsx("th", { ...part('select-cell'), scope: "col", children: _jsx(Checkbox, { label: t.table.selectAll, labelHidden: true, disabled: !rows.length, checked: allState, onCheckedChange: (on) => toggleAll(on) }) })), columns.map((column) => (_jsx("th", { scope: "col", "data-align": column.align ?? 'start', "aria-sort": ariaSort(column), style: column.width ? { width: column.width } : undefined, children: column.sortable
|
|
138
145
|
? _jsxs("button", { ...part('sort'), type: "button", "data-dir": sortDir(column) ?? undefined, onClick: () => toggleSort(column), children: [_jsx("span", { children: column.label }), _jsx("span", { ...part('sort-icon'), children: _jsx("iconify-icon", { icon: sortDir(column) === 'asc' ? 'lucide:chevron-up'
|
|
139
146
|
: sortDir(column) === 'desc' ? 'lucide:chevron-down' : 'lucide:chevrons-up-down' }) })] })
|
|
140
147
|
: column.label }, column.key)))] }) }), _jsx("tbody", { onPointerDownCapture: noteShift, onMouseDownCapture: noteShift, onKeyDownCapture: noteShift, children: loading && !rows.length
|
package/dist/table/table.css
CHANGED
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
& tbody tr:last-child td { border-bottom: none; }
|
|
24
24
|
& tbody tr:hover { background: color-mix(in srgb, var(--ui-hover) 60%, transparent); }
|
|
25
25
|
& tbody tr[data-selected] { background: color-mix(in srgb, var(--ui-accent-soft) 45%, transparent); }
|
|
26
|
+
/* A click on a row opens it (`onRowClick`) or, while rows are ticked, ticks it. */
|
|
27
|
+
:is([data-clickable], [data-selecting]) > & tbody tr { cursor: pointer; }
|
|
26
28
|
/* Outer cells line up with a card's padding. */
|
|
27
29
|
[data-flush] > & :is(th, td):first-child { padding-left: 1.25rem; }
|
|
28
30
|
[data-flush] > & :is(th, td):last-child { padding-right: 1.25rem; } }
|