@crisp-ui-kit/crisp 0.48.0 → 0.50.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/cjs/components/datatable/datatable.recipe.js +4 -3
- package/dist/cjs/components/tabletoolbar/tabletoolbar.chrome.js +1 -0
- package/dist/cjs/components/tabletoolbar/tabletoolbar.js +22 -2
- package/dist/datatable.css +4 -3
- package/dist/datatable.layered.css +4 -3
- package/dist/esm/components/datatable/datatable.recipe.js +4 -3
- package/dist/esm/components/tabletoolbar/tabletoolbar.chrome.js +1 -0
- package/dist/esm/components/tabletoolbar/tabletoolbar.js +21 -2
- package/dist/recordstable.css +1 -0
- package/dist/recordstable.layered.css +1 -0
- package/dist/styles.css +6 -3
- package/dist/styles.layered.css +6 -3
- package/dist/tabletoolbar.css +1 -0
- package/dist/tabletoolbar.layered.css +1 -0
- package/dist/types/components/tabletoolbar/tabletoolbar.d.ts +34 -1
- package/package.json +1 -1
|
@@ -10,7 +10,7 @@ const tokens_1 = require("../../tokens");
|
|
|
10
10
|
const config = (0, core_1.defineRecipe)({
|
|
11
11
|
name: "datatable",
|
|
12
12
|
base: `display: flex; flex-direction: column; gap: ${tokens_1.contract.space["2.5"]}; font-family: ${tokens_1.contract.font.sans};
|
|
13
|
-
& .crisp-datatable-toolbar { display: flex; align-items: center; gap: ${tokens_1.contract.space["2"]}; }
|
|
13
|
+
& .crisp-datatable-toolbar { display: flex; align-items: center; gap: ${tokens_1.contract.space["2"]}; min-height: 49px; border-top: 1px solid ${tokens_1.contract.borderSubtle}; }
|
|
14
14
|
& .crisp-datatable-search { position: relative; flex: 1; max-width: 280px; display: inline-flex; align-items: center; }
|
|
15
15
|
& .crisp-datatable-search svg { position: absolute; inset-inline-start: ${tokens_1.contract.space["2"]}; color: ${tokens_1.contract.fgMuted}; pointer-events: none; }
|
|
16
16
|
& .crisp-datatable-search input { width: 100%; height: 32px; padding: 0 ${tokens_1.contract.space["2"]} 0 ${tokens_1.contract.space["6"]}; border: none; border-radius: ${tokens_1.contract.radius.md}; background: ${tokens_1.contract.bgSurface}; box-shadow: ${tokens_1.elevation.field}; font-family: inherit; font-size: ${tokens_1.contract.text.lg}; color: ${tokens_1.contract.fgPrimary}; outline: none; transition: box-shadow .15s; }
|
|
@@ -51,9 +51,10 @@ const config = (0, core_1.defineRecipe)({
|
|
|
51
51
|
& .crisp-datatable-th-rename:focus { box-shadow: inset 0 0 0 1px ${tokens_1.contract.bgBrandSolid}; }
|
|
52
52
|
& .crisp-datatable-th-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
|
|
53
53
|
& .crisp-datatable-sort { display: flex; align-items: center; gap: ${tokens_1.contract.space["1.5"]}; width: 100%; min-width: 0; height: 100%; margin: 0; padding: 0 ${tokens_1.contract.space["2"]}; border: none; background: none; font: inherit; letter-spacing: inherit; color: inherit; text-align: start; cursor: pointer; }
|
|
54
|
-
& th[data-align="right"] .crisp-datatable-sort { justify-content: flex-end; }
|
|
54
|
+
& th[data-align="right"] .crisp-datatable-sort { justify-content: flex-end; padding-inline-end: 0; }
|
|
55
|
+
& th[data-align="right"] .crisp-datatable-th-inner { justify-content: flex-end; }
|
|
55
56
|
& .crisp-datatable-chevron { margin-inline-start: auto; flex-shrink: 0; color: ${tokens_1.contract.fgMuted}; opacity: 0; transition: opacity .12s; }
|
|
56
|
-
& th[data-align="right"] .crisp-datatable-chevron { margin-inline-start: 0; }
|
|
57
|
+
& th[data-align="right"] .crisp-datatable-chevron { margin-inline-start: 0; order: -1; }
|
|
57
58
|
& .crisp-datatable-sort:hover .crisp-datatable-chevron { opacity: 0.6; }
|
|
58
59
|
& .crisp-datatable-sort[data-sorted] .crisp-datatable-chevron { opacity: 1; color: ${tokens_1.contract.fgPrimary}; }
|
|
59
60
|
/* sticky first column(s) + horizontal scroll shadow — RecordsTable's feel */
|
|
@@ -18,6 +18,7 @@ const tokens_1 = require("../../tokens");
|
|
|
18
18
|
// split preserves that cascade exactly, which is what lets the generated CSS
|
|
19
19
|
// stay byte-for-byte identical to what shipped before the extraction.
|
|
20
20
|
const toolbarChromeHead = (p) => ` & .${namespace_1.CLASS_PREFIX}${p}-toolbar { display: flex; align-items: center; gap: ${tokens_1.contract.space["1.5"]}; padding: 0 ${tokens_1.contract.space["3"]} ${tokens_1.contract.space["2"]}; }
|
|
21
|
+
& .${namespace_1.CLASS_PREFIX}${p}-toolbar[data-inline] { padding-bottom: 0; }
|
|
21
22
|
& .${namespace_1.CLASS_PREFIX}${p}-search { display: flex; align-items: center; gap: ${tokens_1.contract.space["1.5"]}; height: ${tokens_1.contract.size.row}; padding: 0 ${tokens_1.contract.space["2.5"]}; border: none; border-radius: ${tokens_1.contract.radius.md}; background: ${tokens_1.contract.bgSurface}; box-shadow: inset 0 0 0 1px ${tokens_1.contract.borderSubtle}; color: ${tokens_1.contract.fgMuted}; }
|
|
22
23
|
& .${namespace_1.CLASS_PREFIX}${p}-search svg { flex-shrink: 0; }
|
|
23
24
|
& .${namespace_1.CLASS_PREFIX}${p}-search input { border: none; outline: none; background: transparent; font-family: inherit; font-size: ${tokens_1.contract.text.md}; color: ${tokens_1.contract.fgPrimary}; width: 180px; }
|
|
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ToolbarTool = void 0;
|
|
36
37
|
exports.applyFilters = applyFilters;
|
|
37
38
|
exports.applySorts = applySorts;
|
|
38
39
|
exports.TableToolbar = TableToolbar;
|
|
@@ -149,7 +150,7 @@ function applySorts(rows, sorts, get = (row, key) => row[key]) {
|
|
|
149
150
|
* composable version, to put above `DataTable` or any table of your own. Pair
|
|
150
151
|
* it with `applyFilters` / `applySorts` to turn its state into rows.
|
|
151
152
|
*/
|
|
152
|
-
function TableToolbar({ columns, sorts: sortsProp, defaultSorts, onSortsChange, filters: filtersProp, defaultFilters, onFiltersChange, count, children, helpHref, className, sortLabel = "Sort", reorderSortLabel = "Reorder sort", noSortsLabel = "No sorts applied to this view.", addSortLabel = "Add sort", learnSortingLabel = "Learn about sorting", selectConditionLabel = "Select condition", sortFieldLabel = "Sort field", sortDirectionLabel = "Sort direction", removeSortLabel = "Remove sort", filterFieldLabel = "Filter by field", filterFieldPlaceholder = "Filter by…", filterValuePlaceholder = "Value…", ascendingLabel = "Ascending", descendingLabel = "Descending", sortTriggerLabel, filterTriggerLabel, ...rest }) {
|
|
153
|
+
function TableToolbar({ columns, sorts: sortsProp, defaultSorts, onSortsChange, filters: filtersProp, defaultFilters, onFiltersChange, count, children, helpHref, className, sortLabel = "Sort", reorderSortLabel = "Reorder sort", noSortsLabel = "No sorts applied to this view.", addSortLabel = "Add sort", learnSortingLabel = "Learn about sorting", selectConditionLabel = "Select condition", sortFieldLabel = "Sort field", sortDirectionLabel = "Sort direction", removeSortLabel = "Remove sort", filterFieldLabel = "Filter by field", filterFieldPlaceholder = "Filter by…", filterValuePlaceholder = "Value…", ascendingLabel = "Ascending", descendingLabel = "Descending", sortTriggerLabel, filterTriggerLabel, inline, ...rest }) {
|
|
153
154
|
const [sortsState, setSortsState] = React.useState(defaultSorts ?? []);
|
|
154
155
|
const [filtersState, setFiltersState] = React.useState(defaultFilters ?? []);
|
|
155
156
|
const sorts = sortsProp ?? sortsState;
|
|
@@ -239,7 +240,7 @@ function TableToolbar({ columns, sorts: sortsProp, defaultSorts, onSortsChange,
|
|
|
239
240
|
: sorts.length
|
|
240
241
|
? `Sorted by ${columns.find((c) => c.key === sorts[0].key)?.label}${sorts.length > 1 ? ` +${sorts.length - 1}` : ""}`
|
|
241
242
|
: "Sort";
|
|
242
|
-
return ((0, jsx_runtime_1.jsx)("div", { className: (0, tabletoolbar_recipe_1.tabletoolbarRecipe)({ className }), ...rest, children: (0, jsx_runtime_1.jsxs)("div", { className: "crisp-tabletoolbar-toolbar", children: [(0, jsx_runtime_1.jsxs)("span", { className: "crisp-tabletoolbar-toolgroup", children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", className: `crisp-tabletoolbar-tool${sorts.length ? " crisp-tabletoolbar-tool--active" : ""}`, onClick: () => setOpenMenu(openMenu === "sort" ? null : "sort"), "aria-haspopup": "dialog", "aria-expanded": openMenu === "sort", "data-menu-trigger": true, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.ArrowUpDown, { size: 14, strokeWidth: 1.75, "aria-hidden": "true" }), sortedLabel] }), openMenu === "sort" && ((0, jsx_runtime_1.jsxs)("div", { ref: sortListRef, className: "crisp-tabletoolbar-menu crisp-tabletoolbar-sortpop", role: "dialog", "aria-label": sortLabel, children: [sorts.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "crisp-tabletoolbar-sort-empty", children: noSortsLabel })) : (sorts.map((s, i) => ((0, jsx_runtime_1.jsxs)("div", { className: "crisp-tabletoolbar-sort-row", onDragOver: (e) => {
|
|
243
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, tabletoolbar_recipe_1.tabletoolbarRecipe)({ className }), ...rest, children: (0, jsx_runtime_1.jsxs)("div", { className: "crisp-tabletoolbar-toolbar", "data-inline": inline ? "" : undefined, children: [(0, jsx_runtime_1.jsxs)("span", { className: "crisp-tabletoolbar-toolgroup", children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", className: `crisp-tabletoolbar-tool${sorts.length ? " crisp-tabletoolbar-tool--active" : ""}`, onClick: () => setOpenMenu(openMenu === "sort" ? null : "sort"), "aria-haspopup": "dialog", "aria-expanded": openMenu === "sort", "data-menu-trigger": true, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.ArrowUpDown, { size: 14, strokeWidth: 1.75, "aria-hidden": "true" }), sortedLabel] }), openMenu === "sort" && ((0, jsx_runtime_1.jsxs)("div", { ref: sortListRef, className: "crisp-tabletoolbar-menu crisp-tabletoolbar-sortpop", role: "dialog", "aria-label": sortLabel, children: [sorts.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "crisp-tabletoolbar-sort-empty", children: noSortsLabel })) : (sorts.map((s, i) => ((0, jsx_runtime_1.jsxs)("div", { className: "crisp-tabletoolbar-sort-row", onDragOver: (e) => {
|
|
243
244
|
if (dragSort !== null)
|
|
244
245
|
e.preventDefault();
|
|
245
246
|
}, onDrop: () => {
|
|
@@ -301,3 +302,22 @@ function TableToolbar({ columns, sorts: sortsProp, defaultSorts, onSortsChange,
|
|
|
301
302
|
})] }))] }))] }, cond.id));
|
|
302
303
|
}), (0, jsx_runtime_1.jsx)("span", { className: "crisp-tabletoolbar-spacer" }), count != null && ((0, jsx_runtime_1.jsx)("span", { className: "crisp-tabletoolbar-count", children: count })), children] }) }));
|
|
303
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* The Sort/Filter chip's own chrome (`.crisp-tabletoolbar-tool`), standalone
|
|
307
|
+
* (#399) — for a control drawn like Sort/Filter that isn't Sort or Filter (a
|
|
308
|
+
* screen's own quick filter, e.g.). `.crisp-tabletoolbar-tool` alone renders
|
|
309
|
+
* unstyled: the rule lives nested under `TableToolbar`'s own root class, the
|
|
310
|
+
* same way every other rule in its shared chrome does, so it only paints on
|
|
311
|
+
* a descendant of an actual `TableToolbar`. This wraps one in, `display:
|
|
312
|
+
* contents` so it contributes no box of its own — the same technique
|
|
313
|
+
* `TableToolbar`'s own root already uses to disappear from layout.
|
|
314
|
+
*/
|
|
315
|
+
exports.ToolbarTool = React.forwardRef(({ active, ghost, className, ...rest }, ref) => ((0, jsx_runtime_1.jsx)("span", { className: (0, tabletoolbar_recipe_1.tabletoolbarRecipe)(), children: (0, jsx_runtime_1.jsx)("button", { ref: ref, type: "button", className: [
|
|
316
|
+
"crisp-tabletoolbar-tool",
|
|
317
|
+
active && "crisp-tabletoolbar-tool--active",
|
|
318
|
+
ghost && "crisp-tabletoolbar-tool--ghost",
|
|
319
|
+
className,
|
|
320
|
+
]
|
|
321
|
+
.filter(Boolean)
|
|
322
|
+
.join(" "), ...rest }) })));
|
|
323
|
+
exports.ToolbarTool.displayName = "ToolbarTool";
|
package/dist/datatable.css
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
.crisp-datatable {
|
|
2
2
|
display: flex; flex-direction: column; gap: var(--crisp-space-2-5); font-family: var(--crisp-font-sans);
|
|
3
|
-
& .crisp-datatable-toolbar { display: flex; align-items: center; gap: var(--crisp-space-2); }
|
|
3
|
+
& .crisp-datatable-toolbar { display: flex; align-items: center; gap: var(--crisp-space-2); min-height: 49px; border-top: 1px solid var(--crisp-border-subtle); }
|
|
4
4
|
& .crisp-datatable-search { position: relative; flex: 1; max-width: 280px; display: inline-flex; align-items: center; }
|
|
5
5
|
& .crisp-datatable-search svg { position: absolute; inset-inline-start: var(--crisp-space-2); color: var(--crisp-fg-muted); pointer-events: none; }
|
|
6
6
|
& .crisp-datatable-search input { width: 100%; height: 32px; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-6); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-ring-neutral), 0 0 2px rgba(28,40,64,0.18), 0 1px 3px rgba(0,0,0,0.04); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); outline: none; transition: box-shadow .15s; }
|
|
@@ -32,9 +32,10 @@
|
|
|
32
32
|
& .crisp-datatable-th-rename:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
|
|
33
33
|
& .crisp-datatable-th-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
|
|
34
34
|
& .crisp-datatable-sort { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; min-width: 0; height: 100%; margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; font: inherit; letter-spacing: inherit; color: inherit; text-align: start; cursor: pointer; }
|
|
35
|
-
& th[data-align="right"] .crisp-datatable-sort { justify-content: flex-end; }
|
|
35
|
+
& th[data-align="right"] .crisp-datatable-sort { justify-content: flex-end; padding-inline-end: 0; }
|
|
36
|
+
& th[data-align="right"] .crisp-datatable-th-inner { justify-content: flex-end; }
|
|
36
37
|
& .crisp-datatable-chevron { margin-inline-start: auto; flex-shrink: 0; color: var(--crisp-fg-muted); opacity: 0; transition: opacity .12s; }
|
|
37
|
-
& th[data-align="right"] .crisp-datatable-chevron { margin-inline-start: 0; }
|
|
38
|
+
& th[data-align="right"] .crisp-datatable-chevron { margin-inline-start: 0; order: -1; }
|
|
38
39
|
& .crisp-datatable-sort:hover .crisp-datatable-chevron { opacity: 0.6; }
|
|
39
40
|
& .crisp-datatable-sort[data-sorted] .crisp-datatable-chevron { opacity: 1; color: var(--crisp-fg-primary); }
|
|
40
41
|
/* sticky first column(s) + horizontal scroll shadow — RecordsTable's feel */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
@layer crisp-components {
|
|
2
2
|
.crisp-datatable {
|
|
3
3
|
display: flex; flex-direction: column; gap: var(--crisp-space-2-5); font-family: var(--crisp-font-sans);
|
|
4
|
-
& .crisp-datatable-toolbar { display: flex; align-items: center; gap: var(--crisp-space-2); }
|
|
4
|
+
& .crisp-datatable-toolbar { display: flex; align-items: center; gap: var(--crisp-space-2); min-height: 49px; border-top: 1px solid var(--crisp-border-subtle); }
|
|
5
5
|
& .crisp-datatable-search { position: relative; flex: 1; max-width: 280px; display: inline-flex; align-items: center; }
|
|
6
6
|
& .crisp-datatable-search svg { position: absolute; inset-inline-start: var(--crisp-space-2); color: var(--crisp-fg-muted); pointer-events: none; }
|
|
7
7
|
& .crisp-datatable-search input { width: 100%; height: 32px; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-6); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-ring-neutral), 0 0 2px rgba(28,40,64,0.18), 0 1px 3px rgba(0,0,0,0.04); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); outline: none; transition: box-shadow .15s; }
|
|
@@ -33,9 +33,10 @@
|
|
|
33
33
|
& .crisp-datatable-th-rename:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
|
|
34
34
|
& .crisp-datatable-th-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
|
|
35
35
|
& .crisp-datatable-sort { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; min-width: 0; height: 100%; margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; font: inherit; letter-spacing: inherit; color: inherit; text-align: start; cursor: pointer; }
|
|
36
|
-
& th[data-align="right"] .crisp-datatable-sort { justify-content: flex-end; }
|
|
36
|
+
& th[data-align="right"] .crisp-datatable-sort { justify-content: flex-end; padding-inline-end: 0; }
|
|
37
|
+
& th[data-align="right"] .crisp-datatable-th-inner { justify-content: flex-end; }
|
|
37
38
|
& .crisp-datatable-chevron { margin-inline-start: auto; flex-shrink: 0; color: var(--crisp-fg-muted); opacity: 0; transition: opacity .12s; }
|
|
38
|
-
& th[data-align="right"] .crisp-datatable-chevron { margin-inline-start: 0; }
|
|
39
|
+
& th[data-align="right"] .crisp-datatable-chevron { margin-inline-start: 0; order: -1; }
|
|
39
40
|
& .crisp-datatable-sort:hover .crisp-datatable-chevron { opacity: 0.6; }
|
|
40
41
|
& .crisp-datatable-sort[data-sorted] .crisp-datatable-chevron { opacity: 1; color: var(--crisp-fg-primary); }
|
|
41
42
|
/* sticky first column(s) + horizontal scroll shadow — RecordsTable's feel */
|
|
@@ -7,7 +7,7 @@ import { contract as c, elevation as e } from "../../tokens/index.js";
|
|
|
7
7
|
const config = defineRecipe({
|
|
8
8
|
name: "datatable",
|
|
9
9
|
base: `display: flex; flex-direction: column; gap: ${c.space["2.5"]}; font-family: ${c.font.sans};
|
|
10
|
-
& .crisp-datatable-toolbar { display: flex; align-items: center; gap: ${c.space["2"]}; }
|
|
10
|
+
& .crisp-datatable-toolbar { display: flex; align-items: center; gap: ${c.space["2"]}; min-height: 49px; border-top: 1px solid ${c.borderSubtle}; }
|
|
11
11
|
& .crisp-datatable-search { position: relative; flex: 1; max-width: 280px; display: inline-flex; align-items: center; }
|
|
12
12
|
& .crisp-datatable-search svg { position: absolute; inset-inline-start: ${c.space["2"]}; color: ${c.fgMuted}; pointer-events: none; }
|
|
13
13
|
& .crisp-datatable-search input { width: 100%; height: 32px; padding: 0 ${c.space["2"]} 0 ${c.space["6"]}; border: none; border-radius: ${c.radius.md}; background: ${c.bgSurface}; box-shadow: ${e.field}; font-family: inherit; font-size: ${c.text.lg}; color: ${c.fgPrimary}; outline: none; transition: box-shadow .15s; }
|
|
@@ -48,9 +48,10 @@ const config = defineRecipe({
|
|
|
48
48
|
& .crisp-datatable-th-rename:focus { box-shadow: inset 0 0 0 1px ${c.bgBrandSolid}; }
|
|
49
49
|
& .crisp-datatable-th-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
|
|
50
50
|
& .crisp-datatable-sort { display: flex; align-items: center; gap: ${c.space["1.5"]}; width: 100%; min-width: 0; height: 100%; margin: 0; padding: 0 ${c.space["2"]}; border: none; background: none; font: inherit; letter-spacing: inherit; color: inherit; text-align: start; cursor: pointer; }
|
|
51
|
-
& th[data-align="right"] .crisp-datatable-sort { justify-content: flex-end; }
|
|
51
|
+
& th[data-align="right"] .crisp-datatable-sort { justify-content: flex-end; padding-inline-end: 0; }
|
|
52
|
+
& th[data-align="right"] .crisp-datatable-th-inner { justify-content: flex-end; }
|
|
52
53
|
& .crisp-datatable-chevron { margin-inline-start: auto; flex-shrink: 0; color: ${c.fgMuted}; opacity: 0; transition: opacity .12s; }
|
|
53
|
-
& th[data-align="right"] .crisp-datatable-chevron { margin-inline-start: 0; }
|
|
54
|
+
& th[data-align="right"] .crisp-datatable-chevron { margin-inline-start: 0; order: -1; }
|
|
54
55
|
& .crisp-datatable-sort:hover .crisp-datatable-chevron { opacity: 0.6; }
|
|
55
56
|
& .crisp-datatable-sort[data-sorted] .crisp-datatable-chevron { opacity: 1; color: ${c.fgPrimary}; }
|
|
56
57
|
/* sticky first column(s) + horizontal scroll shadow — RecordsTable's feel */
|
|
@@ -15,6 +15,7 @@ import { contract as c, elevation as e } from "../../tokens/index.js";
|
|
|
15
15
|
// split preserves that cascade exactly, which is what lets the generated CSS
|
|
16
16
|
// stay byte-for-byte identical to what shipped before the extraction.
|
|
17
17
|
export const toolbarChromeHead = (p) => ` & .${CLASS_PREFIX}${p}-toolbar { display: flex; align-items: center; gap: ${c.space["1.5"]}; padding: 0 ${c.space["3"]} ${c.space["2"]}; }
|
|
18
|
+
& .${CLASS_PREFIX}${p}-toolbar[data-inline] { padding-bottom: 0; }
|
|
18
19
|
& .${CLASS_PREFIX}${p}-search { display: flex; align-items: center; gap: ${c.space["1.5"]}; height: ${c.size.row}; padding: 0 ${c.space["2.5"]}; border: none; border-radius: ${c.radius.md}; background: ${c.bgSurface}; box-shadow: inset 0 0 0 1px ${c.borderSubtle}; color: ${c.fgMuted}; }
|
|
19
20
|
& .${CLASS_PREFIX}${p}-search svg { flex-shrink: 0; }
|
|
20
21
|
& .${CLASS_PREFIX}${p}-search input { border: none; outline: none; background: transparent; font-family: inherit; font-size: ${c.text.md}; color: ${c.fgPrimary}; width: 180px; }
|
|
@@ -111,7 +111,7 @@ export function applySorts(rows, sorts, get = (row, key) => row[key]) {
|
|
|
111
111
|
* composable version, to put above `DataTable` or any table of your own. Pair
|
|
112
112
|
* it with `applyFilters` / `applySorts` to turn its state into rows.
|
|
113
113
|
*/
|
|
114
|
-
export function TableToolbar({ columns, sorts: sortsProp, defaultSorts, onSortsChange, filters: filtersProp, defaultFilters, onFiltersChange, count, children, helpHref, className, sortLabel = "Sort", reorderSortLabel = "Reorder sort", noSortsLabel = "No sorts applied to this view.", addSortLabel = "Add sort", learnSortingLabel = "Learn about sorting", selectConditionLabel = "Select condition", sortFieldLabel = "Sort field", sortDirectionLabel = "Sort direction", removeSortLabel = "Remove sort", filterFieldLabel = "Filter by field", filterFieldPlaceholder = "Filter by…", filterValuePlaceholder = "Value…", ascendingLabel = "Ascending", descendingLabel = "Descending", sortTriggerLabel, filterTriggerLabel, ...rest }) {
|
|
114
|
+
export function TableToolbar({ columns, sorts: sortsProp, defaultSorts, onSortsChange, filters: filtersProp, defaultFilters, onFiltersChange, count, children, helpHref, className, sortLabel = "Sort", reorderSortLabel = "Reorder sort", noSortsLabel = "No sorts applied to this view.", addSortLabel = "Add sort", learnSortingLabel = "Learn about sorting", selectConditionLabel = "Select condition", sortFieldLabel = "Sort field", sortDirectionLabel = "Sort direction", removeSortLabel = "Remove sort", filterFieldLabel = "Filter by field", filterFieldPlaceholder = "Filter by…", filterValuePlaceholder = "Value…", ascendingLabel = "Ascending", descendingLabel = "Descending", sortTriggerLabel, filterTriggerLabel, inline, ...rest }) {
|
|
115
115
|
const [sortsState, setSortsState] = React.useState(defaultSorts ?? []);
|
|
116
116
|
const [filtersState, setFiltersState] = React.useState(defaultFilters ?? []);
|
|
117
117
|
const sorts = sortsProp ?? sortsState;
|
|
@@ -201,7 +201,7 @@ export function TableToolbar({ columns, sorts: sortsProp, defaultSorts, onSortsC
|
|
|
201
201
|
: sorts.length
|
|
202
202
|
? `Sorted by ${columns.find((c) => c.key === sorts[0].key)?.label}${sorts.length > 1 ? ` +${sorts.length - 1}` : ""}`
|
|
203
203
|
: "Sort";
|
|
204
|
-
return (_jsx("div", { className: tabletoolbarRecipe({ className }), ...rest, children: _jsxs("div", { className: "crisp-tabletoolbar-toolbar", children: [_jsxs("span", { className: "crisp-tabletoolbar-toolgroup", children: [_jsxs("button", { type: "button", className: `crisp-tabletoolbar-tool${sorts.length ? " crisp-tabletoolbar-tool--active" : ""}`, onClick: () => setOpenMenu(openMenu === "sort" ? null : "sort"), "aria-haspopup": "dialog", "aria-expanded": openMenu === "sort", "data-menu-trigger": true, children: [_jsx(ArrowUpDown, { size: 14, strokeWidth: 1.75, "aria-hidden": "true" }), sortedLabel] }), openMenu === "sort" && (_jsxs("div", { ref: sortListRef, className: "crisp-tabletoolbar-menu crisp-tabletoolbar-sortpop", role: "dialog", "aria-label": sortLabel, children: [sorts.length === 0 ? (_jsx("div", { className: "crisp-tabletoolbar-sort-empty", children: noSortsLabel })) : (sorts.map((s, i) => (_jsxs("div", { className: "crisp-tabletoolbar-sort-row", onDragOver: (e) => {
|
|
204
|
+
return (_jsx("div", { className: tabletoolbarRecipe({ className }), ...rest, children: _jsxs("div", { className: "crisp-tabletoolbar-toolbar", "data-inline": inline ? "" : undefined, children: [_jsxs("span", { className: "crisp-tabletoolbar-toolgroup", children: [_jsxs("button", { type: "button", className: `crisp-tabletoolbar-tool${sorts.length ? " crisp-tabletoolbar-tool--active" : ""}`, onClick: () => setOpenMenu(openMenu === "sort" ? null : "sort"), "aria-haspopup": "dialog", "aria-expanded": openMenu === "sort", "data-menu-trigger": true, children: [_jsx(ArrowUpDown, { size: 14, strokeWidth: 1.75, "aria-hidden": "true" }), sortedLabel] }), openMenu === "sort" && (_jsxs("div", { ref: sortListRef, className: "crisp-tabletoolbar-menu crisp-tabletoolbar-sortpop", role: "dialog", "aria-label": sortLabel, children: [sorts.length === 0 ? (_jsx("div", { className: "crisp-tabletoolbar-sort-empty", children: noSortsLabel })) : (sorts.map((s, i) => (_jsxs("div", { className: "crisp-tabletoolbar-sort-row", onDragOver: (e) => {
|
|
205
205
|
if (dragSort !== null)
|
|
206
206
|
e.preventDefault();
|
|
207
207
|
}, onDrop: () => {
|
|
@@ -263,3 +263,22 @@ export function TableToolbar({ columns, sorts: sortsProp, defaultSorts, onSortsC
|
|
|
263
263
|
})] }))] }))] }, cond.id));
|
|
264
264
|
}), _jsx("span", { className: "crisp-tabletoolbar-spacer" }), count != null && (_jsx("span", { className: "crisp-tabletoolbar-count", children: count })), children] }) }));
|
|
265
265
|
}
|
|
266
|
+
/**
|
|
267
|
+
* The Sort/Filter chip's own chrome (`.crisp-tabletoolbar-tool`), standalone
|
|
268
|
+
* (#399) — for a control drawn like Sort/Filter that isn't Sort or Filter (a
|
|
269
|
+
* screen's own quick filter, e.g.). `.crisp-tabletoolbar-tool` alone renders
|
|
270
|
+
* unstyled: the rule lives nested under `TableToolbar`'s own root class, the
|
|
271
|
+
* same way every other rule in its shared chrome does, so it only paints on
|
|
272
|
+
* a descendant of an actual `TableToolbar`. This wraps one in, `display:
|
|
273
|
+
* contents` so it contributes no box of its own — the same technique
|
|
274
|
+
* `TableToolbar`'s own root already uses to disappear from layout.
|
|
275
|
+
*/
|
|
276
|
+
export const ToolbarTool = React.forwardRef(({ active, ghost, className, ...rest }, ref) => (_jsx("span", { className: tabletoolbarRecipe(), children: _jsx("button", { ref: ref, type: "button", className: [
|
|
277
|
+
"crisp-tabletoolbar-tool",
|
|
278
|
+
active && "crisp-tabletoolbar-tool--active",
|
|
279
|
+
ghost && "crisp-tabletoolbar-tool--ghost",
|
|
280
|
+
className,
|
|
281
|
+
]
|
|
282
|
+
.filter(Boolean)
|
|
283
|
+
.join(" "), ...rest }) })));
|
|
284
|
+
ToolbarTool.displayName = "ToolbarTool";
|
package/dist/recordstable.css
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
& * { box-sizing: border-box; }
|
|
4
4
|
/* toolbar */
|
|
5
5
|
& .crisp-recordstable-toolbar { display: flex; align-items: center; gap: var(--crisp-space-1-5); padding: 0 var(--crisp-space-3) var(--crisp-space-2); }
|
|
6
|
+
& .crisp-recordstable-toolbar[data-inline] { padding-bottom: 0; }
|
|
6
7
|
& .crisp-recordstable-search { display: flex; align-items: center; gap: var(--crisp-space-1-5); height: var(--crisp-size-row); padding: 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
|
|
7
8
|
& .crisp-recordstable-search svg { flex-shrink: 0; }
|
|
8
9
|
& .crisp-recordstable-search input { border: none; outline: none; background: transparent; font-family: inherit; font-size: var(--crisp-text-md); color: var(--crisp-fg-primary); width: 180px; }
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
& * { box-sizing: border-box; }
|
|
5
5
|
/* toolbar */
|
|
6
6
|
& .crisp-recordstable-toolbar { display: flex; align-items: center; gap: var(--crisp-space-1-5); padding: 0 var(--crisp-space-3) var(--crisp-space-2); }
|
|
7
|
+
& .crisp-recordstable-toolbar[data-inline] { padding-bottom: 0; }
|
|
7
8
|
& .crisp-recordstable-search { display: flex; align-items: center; gap: var(--crisp-space-1-5); height: var(--crisp-size-row); padding: 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
|
|
8
9
|
& .crisp-recordstable-search svg { flex-shrink: 0; }
|
|
9
10
|
& .crisp-recordstable-search input { border: none; outline: none; background: transparent; font-family: inherit; font-size: var(--crisp-text-md); color: var(--crisp-fg-primary); width: 180px; }
|
package/dist/styles.css
CHANGED
|
@@ -516,7 +516,7 @@
|
|
|
516
516
|
|
|
517
517
|
.crisp-datatable {
|
|
518
518
|
display: flex; flex-direction: column; gap: var(--crisp-space-2-5); font-family: var(--crisp-font-sans);
|
|
519
|
-
& .crisp-datatable-toolbar { display: flex; align-items: center; gap: var(--crisp-space-2); }
|
|
519
|
+
& .crisp-datatable-toolbar { display: flex; align-items: center; gap: var(--crisp-space-2); min-height: 49px; border-top: 1px solid var(--crisp-border-subtle); }
|
|
520
520
|
& .crisp-datatable-search { position: relative; flex: 1; max-width: 280px; display: inline-flex; align-items: center; }
|
|
521
521
|
& .crisp-datatable-search svg { position: absolute; inset-inline-start: var(--crisp-space-2); color: var(--crisp-fg-muted); pointer-events: none; }
|
|
522
522
|
& .crisp-datatable-search input { width: 100%; height: 32px; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-6); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-ring-neutral), 0 0 2px rgba(28,40,64,0.18), 0 1px 3px rgba(0,0,0,0.04); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); outline: none; transition: box-shadow .15s; }
|
|
@@ -548,9 +548,10 @@
|
|
|
548
548
|
& .crisp-datatable-th-rename:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
|
|
549
549
|
& .crisp-datatable-th-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
|
|
550
550
|
& .crisp-datatable-sort { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; min-width: 0; height: 100%; margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; font: inherit; letter-spacing: inherit; color: inherit; text-align: start; cursor: pointer; }
|
|
551
|
-
& th[data-align="right"] .crisp-datatable-sort { justify-content: flex-end; }
|
|
551
|
+
& th[data-align="right"] .crisp-datatable-sort { justify-content: flex-end; padding-inline-end: 0; }
|
|
552
|
+
& th[data-align="right"] .crisp-datatable-th-inner { justify-content: flex-end; }
|
|
552
553
|
& .crisp-datatable-chevron { margin-inline-start: auto; flex-shrink: 0; color: var(--crisp-fg-muted); opacity: 0; transition: opacity .12s; }
|
|
553
|
-
& th[data-align="right"] .crisp-datatable-chevron { margin-inline-start: 0; }
|
|
554
|
+
& th[data-align="right"] .crisp-datatable-chevron { margin-inline-start: 0; order: -1; }
|
|
554
555
|
& .crisp-datatable-sort:hover .crisp-datatable-chevron { opacity: 0.6; }
|
|
555
556
|
& .crisp-datatable-sort[data-sorted] .crisp-datatable-chevron { opacity: 1; color: var(--crisp-fg-primary); }
|
|
556
557
|
/* sticky first column(s) + horizontal scroll shadow — RecordsTable's feel */
|
|
@@ -1550,6 +1551,7 @@
|
|
|
1550
1551
|
display: contents; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
|
|
1551
1552
|
& * { box-sizing: border-box; }
|
|
1552
1553
|
& .crisp-tabletoolbar-toolbar { display: flex; align-items: center; gap: var(--crisp-space-1-5); padding: 0 var(--crisp-space-3) var(--crisp-space-2); }
|
|
1554
|
+
& .crisp-tabletoolbar-toolbar[data-inline] { padding-bottom: 0; }
|
|
1553
1555
|
& .crisp-tabletoolbar-search { display: flex; align-items: center; gap: var(--crisp-space-1-5); height: var(--crisp-size-row); padding: 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
|
|
1554
1556
|
& .crisp-tabletoolbar-search svg { flex-shrink: 0; }
|
|
1555
1557
|
& .crisp-tabletoolbar-search input { border: none; outline: none; background: transparent; font-family: inherit; font-size: var(--crisp-text-md); color: var(--crisp-fg-primary); width: 180px; }
|
|
@@ -2216,6 +2218,7 @@
|
|
|
2216
2218
|
& * { box-sizing: border-box; }
|
|
2217
2219
|
/* toolbar */
|
|
2218
2220
|
& .crisp-recordstable-toolbar { display: flex; align-items: center; gap: var(--crisp-space-1-5); padding: 0 var(--crisp-space-3) var(--crisp-space-2); }
|
|
2221
|
+
& .crisp-recordstable-toolbar[data-inline] { padding-bottom: 0; }
|
|
2219
2222
|
& .crisp-recordstable-search { display: flex; align-items: center; gap: var(--crisp-space-1-5); height: var(--crisp-size-row); padding: 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
|
|
2220
2223
|
& .crisp-recordstable-search svg { flex-shrink: 0; }
|
|
2221
2224
|
& .crisp-recordstable-search input { border: none; outline: none; background: transparent; font-family: inherit; font-size: var(--crisp-text-md); color: var(--crisp-fg-primary); width: 180px; }
|
package/dist/styles.layered.css
CHANGED
|
@@ -517,7 +517,7 @@
|
|
|
517
517
|
|
|
518
518
|
.crisp-datatable {
|
|
519
519
|
display: flex; flex-direction: column; gap: var(--crisp-space-2-5); font-family: var(--crisp-font-sans);
|
|
520
|
-
& .crisp-datatable-toolbar { display: flex; align-items: center; gap: var(--crisp-space-2); }
|
|
520
|
+
& .crisp-datatable-toolbar { display: flex; align-items: center; gap: var(--crisp-space-2); min-height: 49px; border-top: 1px solid var(--crisp-border-subtle); }
|
|
521
521
|
& .crisp-datatable-search { position: relative; flex: 1; max-width: 280px; display: inline-flex; align-items: center; }
|
|
522
522
|
& .crisp-datatable-search svg { position: absolute; inset-inline-start: var(--crisp-space-2); color: var(--crisp-fg-muted); pointer-events: none; }
|
|
523
523
|
& .crisp-datatable-search input { width: 100%; height: 32px; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-6); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-ring-neutral), 0 0 2px rgba(28,40,64,0.18), 0 1px 3px rgba(0,0,0,0.04); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); outline: none; transition: box-shadow .15s; }
|
|
@@ -549,9 +549,10 @@
|
|
|
549
549
|
& .crisp-datatable-th-rename:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
|
|
550
550
|
& .crisp-datatable-th-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
|
|
551
551
|
& .crisp-datatable-sort { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; min-width: 0; height: 100%; margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; font: inherit; letter-spacing: inherit; color: inherit; text-align: start; cursor: pointer; }
|
|
552
|
-
& th[data-align="right"] .crisp-datatable-sort { justify-content: flex-end; }
|
|
552
|
+
& th[data-align="right"] .crisp-datatable-sort { justify-content: flex-end; padding-inline-end: 0; }
|
|
553
|
+
& th[data-align="right"] .crisp-datatable-th-inner { justify-content: flex-end; }
|
|
553
554
|
& .crisp-datatable-chevron { margin-inline-start: auto; flex-shrink: 0; color: var(--crisp-fg-muted); opacity: 0; transition: opacity .12s; }
|
|
554
|
-
& th[data-align="right"] .crisp-datatable-chevron { margin-inline-start: 0; }
|
|
555
|
+
& th[data-align="right"] .crisp-datatable-chevron { margin-inline-start: 0; order: -1; }
|
|
555
556
|
& .crisp-datatable-sort:hover .crisp-datatable-chevron { opacity: 0.6; }
|
|
556
557
|
& .crisp-datatable-sort[data-sorted] .crisp-datatable-chevron { opacity: 1; color: var(--crisp-fg-primary); }
|
|
557
558
|
/* sticky first column(s) + horizontal scroll shadow — RecordsTable's feel */
|
|
@@ -1551,6 +1552,7 @@
|
|
|
1551
1552
|
display: contents; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
|
|
1552
1553
|
& * { box-sizing: border-box; }
|
|
1553
1554
|
& .crisp-tabletoolbar-toolbar { display: flex; align-items: center; gap: var(--crisp-space-1-5); padding: 0 var(--crisp-space-3) var(--crisp-space-2); }
|
|
1555
|
+
& .crisp-tabletoolbar-toolbar[data-inline] { padding-bottom: 0; }
|
|
1554
1556
|
& .crisp-tabletoolbar-search { display: flex; align-items: center; gap: var(--crisp-space-1-5); height: var(--crisp-size-row); padding: 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
|
|
1555
1557
|
& .crisp-tabletoolbar-search svg { flex-shrink: 0; }
|
|
1556
1558
|
& .crisp-tabletoolbar-search input { border: none; outline: none; background: transparent; font-family: inherit; font-size: var(--crisp-text-md); color: var(--crisp-fg-primary); width: 180px; }
|
|
@@ -2217,6 +2219,7 @@
|
|
|
2217
2219
|
& * { box-sizing: border-box; }
|
|
2218
2220
|
/* toolbar */
|
|
2219
2221
|
& .crisp-recordstable-toolbar { display: flex; align-items: center; gap: var(--crisp-space-1-5); padding: 0 var(--crisp-space-3) var(--crisp-space-2); }
|
|
2222
|
+
& .crisp-recordstable-toolbar[data-inline] { padding-bottom: 0; }
|
|
2220
2223
|
& .crisp-recordstable-search { display: flex; align-items: center; gap: var(--crisp-space-1-5); height: var(--crisp-size-row); padding: 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
|
|
2221
2224
|
& .crisp-recordstable-search svg { flex-shrink: 0; }
|
|
2222
2225
|
& .crisp-recordstable-search input { border: none; outline: none; background: transparent; font-family: inherit; font-size: var(--crisp-text-md); color: var(--crisp-fg-primary); width: 180px; }
|
package/dist/tabletoolbar.css
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
display: contents; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
|
|
3
3
|
& * { box-sizing: border-box; }
|
|
4
4
|
& .crisp-tabletoolbar-toolbar { display: flex; align-items: center; gap: var(--crisp-space-1-5); padding: 0 var(--crisp-space-3) var(--crisp-space-2); }
|
|
5
|
+
& .crisp-tabletoolbar-toolbar[data-inline] { padding-bottom: 0; }
|
|
5
6
|
& .crisp-tabletoolbar-search { display: flex; align-items: center; gap: var(--crisp-space-1-5); height: var(--crisp-size-row); padding: 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
|
|
6
7
|
& .crisp-tabletoolbar-search svg { flex-shrink: 0; }
|
|
7
8
|
& .crisp-tabletoolbar-search input { border: none; outline: none; background: transparent; font-family: inherit; font-size: var(--crisp-text-md); color: var(--crisp-fg-primary); width: 180px; }
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
display: contents; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
|
|
4
4
|
& * { box-sizing: border-box; }
|
|
5
5
|
& .crisp-tabletoolbar-toolbar { display: flex; align-items: center; gap: var(--crisp-space-1-5); padding: 0 var(--crisp-space-3) var(--crisp-space-2); }
|
|
6
|
+
& .crisp-tabletoolbar-toolbar[data-inline] { padding-bottom: 0; }
|
|
6
7
|
& .crisp-tabletoolbar-search { display: flex; align-items: center; gap: var(--crisp-space-1-5); height: var(--crisp-size-row); padding: 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
|
|
7
8
|
& .crisp-tabletoolbar-search svg { flex-shrink: 0; }
|
|
8
9
|
& .crisp-tabletoolbar-search input { border: none; outline: none; background: transparent; font-family: inherit; font-size: var(--crisp-text-md); color: var(--crisp-fg-primary); width: 180px; }
|
|
@@ -81,6 +81,15 @@ export type TableToolbarProps = Omit<React.ComponentPropsWithoutRef<"div">, "chi
|
|
|
81
81
|
sortTriggerLabel?: (sorts: ToolbarSort[], columns: TableToolbarColumn[]) => React.ReactNode;
|
|
82
82
|
/** Text on the filter trigger. Receives the number of active filters. */
|
|
83
83
|
filterTriggerLabel?: (activeFilters: number) => React.ReactNode;
|
|
84
|
+
/**
|
|
85
|
+
* Set when nesting `TableToolbar` inside a consumer's own toolbar row
|
|
86
|
+
* (`DataTable`'s `toolbar` slot, e.g.) alongside other same-height
|
|
87
|
+
* controls. Drops the row's own bottom padding, which exists for when
|
|
88
|
+
* `TableToolbar` sits directly above a table with nothing else in its
|
|
89
|
+
* row — that gap isn't the row's to add when something else in the same
|
|
90
|
+
* row already centres on the same 28px line (#398).
|
|
91
|
+
*/
|
|
92
|
+
inline?: boolean;
|
|
84
93
|
className?: string;
|
|
85
94
|
};
|
|
86
95
|
/**
|
|
@@ -102,5 +111,29 @@ export declare function applySorts<T>(rows: T[], sorts: ToolbarSort[], get?: (ro
|
|
|
102
111
|
* composable version, to put above `DataTable` or any table of your own. Pair
|
|
103
112
|
* it with `applyFilters` / `applySorts` to turn its state into rows.
|
|
104
113
|
*/
|
|
105
|
-
export declare function TableToolbar({ columns, sorts: sortsProp, defaultSorts, onSortsChange, filters: filtersProp, defaultFilters, onFiltersChange, count, children, helpHref, className, sortLabel, reorderSortLabel, noSortsLabel, addSortLabel, learnSortingLabel, selectConditionLabel, sortFieldLabel, sortDirectionLabel, removeSortLabel, filterFieldLabel, filterFieldPlaceholder, filterValuePlaceholder, ascendingLabel, descendingLabel, sortTriggerLabel, filterTriggerLabel, ...rest }: TableToolbarProps): React.JSX.Element;
|
|
114
|
+
export declare function TableToolbar({ columns, sorts: sortsProp, defaultSorts, onSortsChange, filters: filtersProp, defaultFilters, onFiltersChange, count, children, helpHref, className, sortLabel, reorderSortLabel, noSortsLabel, addSortLabel, learnSortingLabel, selectConditionLabel, sortFieldLabel, sortDirectionLabel, removeSortLabel, filterFieldLabel, filterFieldPlaceholder, filterValuePlaceholder, ascendingLabel, descendingLabel, sortTriggerLabel, filterTriggerLabel, inline, ...rest }: TableToolbarProps): React.JSX.Element;
|
|
115
|
+
export type ToolbarToolProps = React.ComponentPropsWithoutRef<"button"> & {
|
|
116
|
+
/** Drawn the way Sort/Filter are once a condition is set (#399). */
|
|
117
|
+
active?: boolean;
|
|
118
|
+
/** The quieter, no-ring variant Sort/Filter never use themselves, for a
|
|
119
|
+
* chip whose "on" state should read as less committed than a real filter. */
|
|
120
|
+
ghost?: boolean;
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* The Sort/Filter chip's own chrome (`.crisp-tabletoolbar-tool`), standalone
|
|
124
|
+
* (#399) — for a control drawn like Sort/Filter that isn't Sort or Filter (a
|
|
125
|
+
* screen's own quick filter, e.g.). `.crisp-tabletoolbar-tool` alone renders
|
|
126
|
+
* unstyled: the rule lives nested under `TableToolbar`'s own root class, the
|
|
127
|
+
* same way every other rule in its shared chrome does, so it only paints on
|
|
128
|
+
* a descendant of an actual `TableToolbar`. This wraps one in, `display:
|
|
129
|
+
* contents` so it contributes no box of its own — the same technique
|
|
130
|
+
* `TableToolbar`'s own root already uses to disappear from layout.
|
|
131
|
+
*/
|
|
132
|
+
export declare const ToolbarTool: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
|
|
133
|
+
/** Drawn the way Sort/Filter are once a condition is set (#399). */
|
|
134
|
+
active?: boolean;
|
|
135
|
+
/** The quieter, no-ring variant Sort/Filter never use themselves, for a
|
|
136
|
+
* chip whose "on" state should read as less committed than a real filter. */
|
|
137
|
+
ghost?: boolean;
|
|
138
|
+
} & React.RefAttributes<HTMLButtonElement>>;
|
|
106
139
|
export {};
|