@crisp-ui-kit/crisp 0.54.6 → 0.54.7

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.
@@ -17,6 +17,14 @@ const tokens_1 = require("../../tokens");
17
17
  // block, and those depend on following `.menu` in source order. Keeping the
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
+ //
21
+ // `.menu--op` (#594 follow-up) is the filter condition's own operator list —
22
+ // measured live against Attio's own popover at 135px (rounds to 134px), not
23
+ // the default 232px every other menu here uses. `.menu-item` also picked up
24
+ // `line-height: 20px` and `font-weight: medium` from the same measurement
25
+ // (its 8 rows read 14px/20px/500) — shared by every menu that renders one,
26
+ // not just the operator list, since crisp's menu-item typography was
27
+ // previously unset rather than wrong.
20
28
  const toolbarChromeHead = (p) => ` & .${namespace_1.CLASS_PREFIX}${p}-toolbar { display: flex; align-items: center; gap: ${tokens_1.contract.space["2"]}; padding: 0 ${tokens_1.contract.space["3"]} ${tokens_1.contract.space["2"]}; }
21
29
  & .${namespace_1.CLASS_PREFIX}${p}-toolbar[data-inline] { padding-bottom: 0; }
22
30
  & .${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}; }
@@ -56,7 +64,7 @@ const toolbarChromeBody = (p) => ` & .${namespace_1.CLASS_PREFIX}${p}-menu-he
56
64
  & .${namespace_1.CLASS_PREFIX}${p}-sort-learn { display: inline-flex; align-items: center; gap: ${tokens_1.contract.space["1.5"]}; font-size: ${tokens_1.contract.text.lg}; color: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 63%, transparent); text-decoration: none; }
57
65
  & .${namespace_1.CLASS_PREFIX}${p}-sort-learn svg { flex-shrink: 0; }
58
66
  & .${namespace_1.CLASS_PREFIX}${p}-sort-learn:hover { color: ${tokens_1.contract.fgPrimary}; }
59
- & .${namespace_1.CLASS_PREFIX}${p}-menu-item { display: flex; align-items: center; gap: ${tokens_1.contract.space["1.5"]}; width: 100%; height: ${tokens_1.contract.size.menuRow}; margin: 0; padding: 0 ${tokens_1.contract.space["2"]}; border: none; background: none; border-radius: ${tokens_1.contract.radius.md}; font-family: inherit; font-size: ${tokens_1.contract.text.lg}; color: ${tokens_1.contract.fgPrimary}; text-align: left; cursor: pointer; }
67
+ & .${namespace_1.CLASS_PREFIX}${p}-menu-item { display: flex; align-items: center; gap: ${tokens_1.contract.space["1.5"]}; width: 100%; height: ${tokens_1.contract.size.menuRow}; margin: 0; padding: 0 ${tokens_1.contract.space["2"]}; border: none; background: none; border-radius: ${tokens_1.contract.radius.md}; font-family: inherit; font-size: ${tokens_1.contract.text.lg}; line-height: 20px; font-weight: ${tokens_1.contract.weight.medium}; color: ${tokens_1.contract.fgPrimary}; text-align: left; cursor: pointer; }
60
68
  & .${namespace_1.CLASS_PREFIX}${p}-menu-item:hover { background: ${tokens_1.contract.bgRaised}; }
61
69
  & .${namespace_1.CLASS_PREFIX}${p}-menu-item:disabled { opacity: 0.4; cursor: default; }
62
70
  & .${namespace_1.CLASS_PREFIX}${p}-menu-item:disabled:hover { background: none; }
@@ -69,6 +77,7 @@ const toolbarChromeBody = (p) => ` & .${namespace_1.CLASS_PREFIX}${p}-menu-he
69
77
  & .${namespace_1.CLASS_PREFIX}${p}-menu--right { left: auto; right: 0; }
70
78
  & .${namespace_1.CLASS_PREFIX}${p}-menu--fixed { position: fixed; top: auto; left: auto; z-index: 40; }
71
79
  & .${namespace_1.CLASS_PREFIX}${p}-menu--hdr { min-width: 200px; }
80
+ & .${namespace_1.CLASS_PREFIX}${p}-menu--op { min-width: 134px; }
72
81
  & .${namespace_1.CLASS_PREFIX}${p}-menu-item--danger { color: ${tokens_1.contract.bgDanger}; }
73
82
  & .${namespace_1.CLASS_PREFIX}${p}-menu-item--danger svg { color: ${tokens_1.contract.bgDanger}; }
74
83
  & .${namespace_1.CLASS_PREFIX}${p}-menu-item--danger:hover { background: color-mix(in srgb, ${tokens_1.contract.bgDanger} 10%, transparent); }
@@ -52,8 +52,14 @@ const OP_LABELS = {
52
52
  is: "is",
53
53
  isnot: "is not",
54
54
  isanyof: "is any of",
55
- empty: "is empty",
56
- notempty: "is not empty",
55
+ // Attio's own text says "empty"/"not empty", not "is empty"/"is not empty"
56
+ // -- #619's own issue body quotes it verbatim this way, and #593's number/
57
+ // date operator sets ("is / is not / less than / greater than / empty /
58
+ // not empty") repeat it. #619 ported the 3 new ops but left these two
59
+ // untouched from the pre-existing 5-op set, which had drifted; caught in
60
+ // review.
61
+ empty: "empty",
62
+ notempty: "not empty",
57
63
  };
58
64
  // #619: order and label set match Attio's own text-filter operator picker
59
65
  // verbatim (measured live, per RecordsTable's own #578 port of the same
@@ -407,7 +413,7 @@ function TableToolbar({ columns, sortColumns: sortColumnsProp, filterColumns: fi
407
413
  const hasValue = (!opNeedsValue(cond.op) || cond.value.trim()) &&
408
414
  (!opNeedsValues(cond.op) || (cond.values?.length ?? 0) > 0);
409
415
  return ((0, jsx_runtime_1.jsxs)("span", { className: "crisp-tabletoolbar-toolgroup", children: [(0, jsx_runtime_1.jsxs)("span", { className: "crisp-tabletoolbar-fchip", children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", className: "crisp-tabletoolbar-fchip-main", "data-menu-trigger": true, "aria-haspopup": "dialog", onClick: () => setOpenMenu(open ? null : `fcond:${cond.id}`), children: [(0, jsx_runtime_1.jsx)("span", { className: "crisp-tabletoolbar-fchip-field", children: col?.label }), hasValue ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: "crisp-tabletoolbar-fchip-op", children: crispMessages[OP_LABELS[cond.op]] ??
410
- OP_LABELS[cond.op] }), opNeedsValue(cond.op) && ((0, jsx_runtime_1.jsx)("span", { className: "crisp-tabletoolbar-fchip-val", children: cond.value })), cond.op === "isanyof" && cond.values && ((0, jsx_runtime_1.jsx)("span", { className: "crisp-tabletoolbar-fchip-val", children: isAnyOfSummary(cond.values) }))] })) : ((0, jsx_runtime_1.jsx)("span", { className: "crisp-tabletoolbar-fchip-op", children: selectConditionLabel }))] }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-tabletoolbar-fchip-x", "data-menu-trigger": true, "aria-haspopup": "menu", "aria-expanded": kebabOpen, "aria-label": `${col?.label} ${filterOptionsLabel}`, onClick: () => setOpenMenu(kebabOpen ? null : `fkebab:${cond.id}`), children: (0, jsx_runtime_1.jsx)(lucide_react_1.MoreVertical, { size: 13, strokeWidth: 2 }) })] }), kebabOpen && ((0, jsx_runtime_1.jsx)("div", { ref: kebabMenuRef, className: "crisp-tabletoolbar-menu crisp-tabletoolbar-menu--right crisp-tabletoolbar-menu--hdr", role: "menu", "aria-label": `${col?.label} ${filterOptionsLabel}`, onKeyDown: onKebabKeyDown, children: (0, jsx_runtime_1.jsx)("button", { type: "button", role: "menuitem", className: "crisp-tabletoolbar-menu-item", onClick: () => removeFilter(cond.id), children: deleteFilterLabel }) })), open && ((0, jsx_runtime_1.jsxs)("div", { className: "crisp-tabletoolbar-menu", role: "dialog", "aria-label": `${col?.label} ${crispMessages.condition ?? "condition"}`, children: [(0, jsx_runtime_1.jsxs)("div", { className: "crisp-tabletoolbar-menu-head", children: [col?.label, " ", crispMessages.condition ?? "condition"] }), opsFor(col).map((op) => ((0, jsx_runtime_1.jsxs)("button", { type: "button", className: "crisp-tabletoolbar-menu-item", "data-on": cond.op === op ? "" : undefined, onClick: () => patchFilter(cond.id, { op }), children: [crispMessages[OP_LABELS[op]] ?? OP_LABELS[op], cond.op === op ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Check, { className: "crisp-tabletoolbar-menu-check", size: 15, strokeWidth: 1.75 })) : null] }, op))), opNeedsValue(cond.op) && ((0, jsx_runtime_1.jsx)("input", { className: "crisp-tabletoolbar-menu-input", placeholder: filterValuePlaceholder, "aria-label": `${col?.label} filter value`,
416
+ OP_LABELS[cond.op] }), opNeedsValue(cond.op) && ((0, jsx_runtime_1.jsx)("span", { className: "crisp-tabletoolbar-fchip-val", children: cond.value })), cond.op === "isanyof" && cond.values && ((0, jsx_runtime_1.jsx)("span", { className: "crisp-tabletoolbar-fchip-val", children: isAnyOfSummary(cond.values) }))] })) : ((0, jsx_runtime_1.jsx)("span", { className: "crisp-tabletoolbar-fchip-op", children: selectConditionLabel }))] }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-tabletoolbar-fchip-x", "data-menu-trigger": true, "aria-haspopup": "menu", "aria-expanded": kebabOpen, "aria-label": `${col?.label} ${filterOptionsLabel}`, onClick: () => setOpenMenu(kebabOpen ? null : `fkebab:${cond.id}`), children: (0, jsx_runtime_1.jsx)(lucide_react_1.MoreVertical, { size: 13, strokeWidth: 2 }) })] }), kebabOpen && ((0, jsx_runtime_1.jsx)("div", { ref: kebabMenuRef, className: "crisp-tabletoolbar-menu crisp-tabletoolbar-menu--right crisp-tabletoolbar-menu--hdr", role: "menu", "aria-label": `${col?.label} ${filterOptionsLabel}`, onKeyDown: onKebabKeyDown, children: (0, jsx_runtime_1.jsxs)("button", { type: "button", role: "menuitem", className: "crisp-tabletoolbar-menu-item crisp-tabletoolbar-menu-item--danger", onClick: () => removeFilter(cond.id), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Trash2, { size: 16, strokeWidth: 1.75 }), deleteFilterLabel] }) })), open && ((0, jsx_runtime_1.jsxs)("div", { className: "crisp-tabletoolbar-menu crisp-tabletoolbar-menu--op", role: "dialog", "aria-label": `${col?.label} ${crispMessages.condition ?? "condition"}`, children: [(0, jsx_runtime_1.jsxs)("div", { className: "crisp-tabletoolbar-menu-head", children: [col?.label, " ", crispMessages.condition ?? "condition"] }), opsFor(col).map((op) => ((0, jsx_runtime_1.jsxs)("button", { type: "button", className: "crisp-tabletoolbar-menu-item", "data-on": cond.op === op ? "" : undefined, onClick: () => patchFilter(cond.id, { op }), children: [crispMessages[OP_LABELS[op]] ?? OP_LABELS[op], cond.op === op ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Check, { className: "crisp-tabletoolbar-menu-check", size: 15, strokeWidth: 1.75 })) : null] }, op))), opNeedsValue(cond.op) && ((0, jsx_runtime_1.jsx)("input", { className: "crisp-tabletoolbar-menu-input", placeholder: filterValuePlaceholder, "aria-label": `${col?.label} filter value`,
411
417
  // biome-ignore lint/a11y/noAutofocus: focus the value field
412
418
  autoFocus: true, value: cond.value, onChange: (e) => patchFilter(cond.id, { value: e.target.value }) })), cond.op === "isanyof" && col?.values && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("input", { className: "crisp-tabletoolbar-menu-input", placeholder: filterValuePlaceholder, "aria-label": `${col?.label} filter values`,
413
419
  // biome-ignore lint/a11y/noAutofocus: focus the search field
@@ -14,6 +14,14 @@ import { contract as c, elevation as e } from "../../tokens/index.js";
14
14
  // block, and those depend on following `.menu` in source order. Keeping the
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
+ //
18
+ // `.menu--op` (#594 follow-up) is the filter condition's own operator list —
19
+ // measured live against Attio's own popover at 135px (rounds to 134px), not
20
+ // the default 232px every other menu here uses. `.menu-item` also picked up
21
+ // `line-height: 20px` and `font-weight: medium` from the same measurement
22
+ // (its 8 rows read 14px/20px/500) — shared by every menu that renders one,
23
+ // not just the operator list, since crisp's menu-item typography was
24
+ // previously unset rather than wrong.
17
25
  export const toolbarChromeHead = (p) => ` & .${CLASS_PREFIX}${p}-toolbar { display: flex; align-items: center; gap: ${c.space["2"]}; padding: 0 ${c.space["3"]} ${c.space["2"]}; }
18
26
  & .${CLASS_PREFIX}${p}-toolbar[data-inline] { padding-bottom: 0; }
19
27
  & .${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}; }
@@ -52,7 +60,7 @@ export const toolbarChromeBody = (p) => ` & .${CLASS_PREFIX}${p}-menu-head {
52
60
  & .${CLASS_PREFIX}${p}-sort-learn { display: inline-flex; align-items: center; gap: ${c.space["1.5"]}; font-size: ${c.text.lg}; color: color-mix(in srgb, ${c.fgPrimary} 63%, transparent); text-decoration: none; }
53
61
  & .${CLASS_PREFIX}${p}-sort-learn svg { flex-shrink: 0; }
54
62
  & .${CLASS_PREFIX}${p}-sort-learn:hover { color: ${c.fgPrimary}; }
55
- & .${CLASS_PREFIX}${p}-menu-item { display: flex; align-items: center; gap: ${c.space["1.5"]}; width: 100%; height: ${c.size.menuRow}; margin: 0; padding: 0 ${c.space["2"]}; border: none; background: none; border-radius: ${c.radius.md}; font-family: inherit; font-size: ${c.text.lg}; color: ${c.fgPrimary}; text-align: left; cursor: pointer; }
63
+ & .${CLASS_PREFIX}${p}-menu-item { display: flex; align-items: center; gap: ${c.space["1.5"]}; width: 100%; height: ${c.size.menuRow}; margin: 0; padding: 0 ${c.space["2"]}; border: none; background: none; border-radius: ${c.radius.md}; font-family: inherit; font-size: ${c.text.lg}; line-height: 20px; font-weight: ${c.weight.medium}; color: ${c.fgPrimary}; text-align: left; cursor: pointer; }
56
64
  & .${CLASS_PREFIX}${p}-menu-item:hover { background: ${c.bgRaised}; }
57
65
  & .${CLASS_PREFIX}${p}-menu-item:disabled { opacity: 0.4; cursor: default; }
58
66
  & .${CLASS_PREFIX}${p}-menu-item:disabled:hover { background: none; }
@@ -65,6 +73,7 @@ export const toolbarChromeBody = (p) => ` & .${CLASS_PREFIX}${p}-menu-head {
65
73
  & .${CLASS_PREFIX}${p}-menu--right { left: auto; right: 0; }
66
74
  & .${CLASS_PREFIX}${p}-menu--fixed { position: fixed; top: auto; left: auto; z-index: 40; }
67
75
  & .${CLASS_PREFIX}${p}-menu--hdr { min-width: 200px; }
76
+ & .${CLASS_PREFIX}${p}-menu--op { min-width: 134px; }
68
77
  & .${CLASS_PREFIX}${p}-menu-item--danger { color: ${c.bgDanger}; }
69
78
  & .${CLASS_PREFIX}${p}-menu-item--danger svg { color: ${c.bgDanger}; }
70
79
  & .${CLASS_PREFIX}${p}-menu-item--danger:hover { background: color-mix(in srgb, ${c.bgDanger} 10%, transparent); }
@@ -1,5 +1,5 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { ArrowDownWideNarrow, ArrowUpDown, ArrowUpNarrowWide, Check, CircleHelp, GripVertical, ListFilter, MoreVertical, Plus, SlidersHorizontal, X, } from "lucide-react";
2
+ import { ArrowDownWideNarrow, ArrowUpDown, ArrowUpNarrowWide, Check, CircleHelp, GripVertical, ListFilter, MoreVertical, Plus, SlidersHorizontal, Trash2, X, } from "lucide-react";
3
3
  import * as React from "react";
4
4
  import { isInsideLaterFloatingLayer, useCrispMessage, useCrispMessages, useFocusAfterRemoval, } from "../../core/index.js";
5
5
  import { MenuCheckboxItem, useMenuKeyboard } from "../menu/index.js";
@@ -13,8 +13,14 @@ const OP_LABELS = {
13
13
  is: "is",
14
14
  isnot: "is not",
15
15
  isanyof: "is any of",
16
- empty: "is empty",
17
- notempty: "is not empty",
16
+ // Attio's own text says "empty"/"not empty", not "is empty"/"is not empty"
17
+ // -- #619's own issue body quotes it verbatim this way, and #593's number/
18
+ // date operator sets ("is / is not / less than / greater than / empty /
19
+ // not empty") repeat it. #619 ported the 3 new ops but left these two
20
+ // untouched from the pre-existing 5-op set, which had drifted; caught in
21
+ // review.
22
+ empty: "empty",
23
+ notempty: "not empty",
18
24
  };
19
25
  // #619: order and label set match Attio's own text-filter operator picker
20
26
  // verbatim (measured live, per RecordsTable's own #578 port of the same
@@ -368,7 +374,7 @@ export function TableToolbar({ columns, sortColumns: sortColumnsProp, filterColu
368
374
  const hasValue = (!opNeedsValue(cond.op) || cond.value.trim()) &&
369
375
  (!opNeedsValues(cond.op) || (cond.values?.length ?? 0) > 0);
370
376
  return (_jsxs("span", { className: "crisp-tabletoolbar-toolgroup", children: [_jsxs("span", { className: "crisp-tabletoolbar-fchip", children: [_jsxs("button", { type: "button", className: "crisp-tabletoolbar-fchip-main", "data-menu-trigger": true, "aria-haspopup": "dialog", onClick: () => setOpenMenu(open ? null : `fcond:${cond.id}`), children: [_jsx("span", { className: "crisp-tabletoolbar-fchip-field", children: col?.label }), hasValue ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "crisp-tabletoolbar-fchip-op", children: crispMessages[OP_LABELS[cond.op]] ??
371
- OP_LABELS[cond.op] }), opNeedsValue(cond.op) && (_jsx("span", { className: "crisp-tabletoolbar-fchip-val", children: cond.value })), cond.op === "isanyof" && cond.values && (_jsx("span", { className: "crisp-tabletoolbar-fchip-val", children: isAnyOfSummary(cond.values) }))] })) : (_jsx("span", { className: "crisp-tabletoolbar-fchip-op", children: selectConditionLabel }))] }), _jsx("button", { type: "button", className: "crisp-tabletoolbar-fchip-x", "data-menu-trigger": true, "aria-haspopup": "menu", "aria-expanded": kebabOpen, "aria-label": `${col?.label} ${filterOptionsLabel}`, onClick: () => setOpenMenu(kebabOpen ? null : `fkebab:${cond.id}`), children: _jsx(MoreVertical, { size: 13, strokeWidth: 2 }) })] }), kebabOpen && (_jsx("div", { ref: kebabMenuRef, className: "crisp-tabletoolbar-menu crisp-tabletoolbar-menu--right crisp-tabletoolbar-menu--hdr", role: "menu", "aria-label": `${col?.label} ${filterOptionsLabel}`, onKeyDown: onKebabKeyDown, children: _jsx("button", { type: "button", role: "menuitem", className: "crisp-tabletoolbar-menu-item", onClick: () => removeFilter(cond.id), children: deleteFilterLabel }) })), open && (_jsxs("div", { className: "crisp-tabletoolbar-menu", role: "dialog", "aria-label": `${col?.label} ${crispMessages.condition ?? "condition"}`, children: [_jsxs("div", { className: "crisp-tabletoolbar-menu-head", children: [col?.label, " ", crispMessages.condition ?? "condition"] }), opsFor(col).map((op) => (_jsxs("button", { type: "button", className: "crisp-tabletoolbar-menu-item", "data-on": cond.op === op ? "" : undefined, onClick: () => patchFilter(cond.id, { op }), children: [crispMessages[OP_LABELS[op]] ?? OP_LABELS[op], cond.op === op ? (_jsx(Check, { className: "crisp-tabletoolbar-menu-check", size: 15, strokeWidth: 1.75 })) : null] }, op))), opNeedsValue(cond.op) && (_jsx("input", { className: "crisp-tabletoolbar-menu-input", placeholder: filterValuePlaceholder, "aria-label": `${col?.label} filter value`,
377
+ OP_LABELS[cond.op] }), opNeedsValue(cond.op) && (_jsx("span", { className: "crisp-tabletoolbar-fchip-val", children: cond.value })), cond.op === "isanyof" && cond.values && (_jsx("span", { className: "crisp-tabletoolbar-fchip-val", children: isAnyOfSummary(cond.values) }))] })) : (_jsx("span", { className: "crisp-tabletoolbar-fchip-op", children: selectConditionLabel }))] }), _jsx("button", { type: "button", className: "crisp-tabletoolbar-fchip-x", "data-menu-trigger": true, "aria-haspopup": "menu", "aria-expanded": kebabOpen, "aria-label": `${col?.label} ${filterOptionsLabel}`, onClick: () => setOpenMenu(kebabOpen ? null : `fkebab:${cond.id}`), children: _jsx(MoreVertical, { size: 13, strokeWidth: 2 }) })] }), kebabOpen && (_jsx("div", { ref: kebabMenuRef, className: "crisp-tabletoolbar-menu crisp-tabletoolbar-menu--right crisp-tabletoolbar-menu--hdr", role: "menu", "aria-label": `${col?.label} ${filterOptionsLabel}`, onKeyDown: onKebabKeyDown, children: _jsxs("button", { type: "button", role: "menuitem", className: "crisp-tabletoolbar-menu-item crisp-tabletoolbar-menu-item--danger", onClick: () => removeFilter(cond.id), children: [_jsx(Trash2, { size: 16, strokeWidth: 1.75 }), deleteFilterLabel] }) })), open && (_jsxs("div", { className: "crisp-tabletoolbar-menu crisp-tabletoolbar-menu--op", role: "dialog", "aria-label": `${col?.label} ${crispMessages.condition ?? "condition"}`, children: [_jsxs("div", { className: "crisp-tabletoolbar-menu-head", children: [col?.label, " ", crispMessages.condition ?? "condition"] }), opsFor(col).map((op) => (_jsxs("button", { type: "button", className: "crisp-tabletoolbar-menu-item", "data-on": cond.op === op ? "" : undefined, onClick: () => patchFilter(cond.id, { op }), children: [crispMessages[OP_LABELS[op]] ?? OP_LABELS[op], cond.op === op ? (_jsx(Check, { className: "crisp-tabletoolbar-menu-check", size: 15, strokeWidth: 1.75 })) : null] }, op))), opNeedsValue(cond.op) && (_jsx("input", { className: "crisp-tabletoolbar-menu-input", placeholder: filterValuePlaceholder, "aria-label": `${col?.label} filter value`,
372
378
  // biome-ignore lint/a11y/noAutofocus: focus the value field
373
379
  autoFocus: true, value: cond.value, onChange: (e) => patchFilter(cond.id, { value: e.target.value }) })), cond.op === "isanyof" && col?.values && (_jsxs(_Fragment, { children: [_jsx("input", { className: "crisp-tabletoolbar-menu-input", placeholder: filterValuePlaceholder, "aria-label": `${col?.label} filter values`,
374
380
  // biome-ignore lint/a11y/noAutofocus: focus the search field
@@ -43,7 +43,7 @@
43
43
  & .crisp-recordstable-sort-learn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); font-size: var(--crisp-text-lg); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); text-decoration: none; }
44
44
  & .crisp-recordstable-sort-learn svg { flex-shrink: 0; }
45
45
  & .crisp-recordstable-sort-learn:hover { color: var(--crisp-fg-primary); }
46
- & .crisp-recordstable-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
46
+ & .crisp-recordstable-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
47
47
  & .crisp-recordstable-menu-item:hover { background: var(--crisp-bg-raised); }
48
48
  & .crisp-recordstable-menu-item:disabled { opacity: 0.4; cursor: default; }
49
49
  & .crisp-recordstable-menu-item:disabled:hover { background: none; }
@@ -56,6 +56,7 @@
56
56
  & .crisp-recordstable-menu--right { left: auto; right: 0; }
57
57
  & .crisp-recordstable-menu--fixed { position: fixed; top: auto; left: auto; z-index: 40; }
58
58
  & .crisp-recordstable-menu--hdr { min-width: 200px; }
59
+ & .crisp-recordstable-menu--op { min-width: 134px; }
59
60
  & .crisp-recordstable-menu-item--danger { color: var(--crisp-bg-danger); }
60
61
  & .crisp-recordstable-menu-item--danger svg { color: var(--crisp-bg-danger); }
61
62
  & .crisp-recordstable-menu-item--danger:hover { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
@@ -44,7 +44,7 @@
44
44
  & .crisp-recordstable-sort-learn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); font-size: var(--crisp-text-lg); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); text-decoration: none; }
45
45
  & .crisp-recordstable-sort-learn svg { flex-shrink: 0; }
46
46
  & .crisp-recordstable-sort-learn:hover { color: var(--crisp-fg-primary); }
47
- & .crisp-recordstable-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
47
+ & .crisp-recordstable-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
48
48
  & .crisp-recordstable-menu-item:hover { background: var(--crisp-bg-raised); }
49
49
  & .crisp-recordstable-menu-item:disabled { opacity: 0.4; cursor: default; }
50
50
  & .crisp-recordstable-menu-item:disabled:hover { background: none; }
@@ -57,6 +57,7 @@
57
57
  & .crisp-recordstable-menu--right { left: auto; right: 0; }
58
58
  & .crisp-recordstable-menu--fixed { position: fixed; top: auto; left: auto; z-index: 40; }
59
59
  & .crisp-recordstable-menu--hdr { min-width: 200px; }
60
+ & .crisp-recordstable-menu--op { min-width: 134px; }
60
61
  & .crisp-recordstable-menu-item--danger { color: var(--crisp-bg-danger); }
61
62
  & .crisp-recordstable-menu-item--danger svg { color: var(--crisp-bg-danger); }
62
63
  & .crisp-recordstable-menu-item--danger:hover { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
package/dist/styles.css CHANGED
@@ -1746,7 +1746,7 @@
1746
1746
  & .crisp-tabletoolbar-sort-learn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); font-size: var(--crisp-text-lg); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); text-decoration: none; }
1747
1747
  & .crisp-tabletoolbar-sort-learn svg { flex-shrink: 0; }
1748
1748
  & .crisp-tabletoolbar-sort-learn:hover { color: var(--crisp-fg-primary); }
1749
- & .crisp-tabletoolbar-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
1749
+ & .crisp-tabletoolbar-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
1750
1750
  & .crisp-tabletoolbar-menu-item:hover { background: var(--crisp-bg-raised); }
1751
1751
  & .crisp-tabletoolbar-menu-item:disabled { opacity: 0.4; cursor: default; }
1752
1752
  & .crisp-tabletoolbar-menu-item:disabled:hover { background: none; }
@@ -1759,6 +1759,7 @@
1759
1759
  & .crisp-tabletoolbar-menu--right { left: auto; right: 0; }
1760
1760
  & .crisp-tabletoolbar-menu--fixed { position: fixed; top: auto; left: auto; z-index: 40; }
1761
1761
  & .crisp-tabletoolbar-menu--hdr { min-width: 200px; }
1762
+ & .crisp-tabletoolbar-menu--op { min-width: 134px; }
1762
1763
  & .crisp-tabletoolbar-menu-item--danger { color: var(--crisp-bg-danger); }
1763
1764
  & .crisp-tabletoolbar-menu-item--danger svg { color: var(--crisp-bg-danger); }
1764
1765
  & .crisp-tabletoolbar-menu-item--danger:hover { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
@@ -2753,7 +2754,7 @@
2753
2754
  & .crisp-recordstable-sort-learn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); font-size: var(--crisp-text-lg); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); text-decoration: none; }
2754
2755
  & .crisp-recordstable-sort-learn svg { flex-shrink: 0; }
2755
2756
  & .crisp-recordstable-sort-learn:hover { color: var(--crisp-fg-primary); }
2756
- & .crisp-recordstable-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
2757
+ & .crisp-recordstable-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
2757
2758
  & .crisp-recordstable-menu-item:hover { background: var(--crisp-bg-raised); }
2758
2759
  & .crisp-recordstable-menu-item:disabled { opacity: 0.4; cursor: default; }
2759
2760
  & .crisp-recordstable-menu-item:disabled:hover { background: none; }
@@ -2766,6 +2767,7 @@
2766
2767
  & .crisp-recordstable-menu--right { left: auto; right: 0; }
2767
2768
  & .crisp-recordstable-menu--fixed { position: fixed; top: auto; left: auto; z-index: 40; }
2768
2769
  & .crisp-recordstable-menu--hdr { min-width: 200px; }
2770
+ & .crisp-recordstable-menu--op { min-width: 134px; }
2769
2771
  & .crisp-recordstable-menu-item--danger { color: var(--crisp-bg-danger); }
2770
2772
  & .crisp-recordstable-menu-item--danger svg { color: var(--crisp-bg-danger); }
2771
2773
  & .crisp-recordstable-menu-item--danger:hover { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
@@ -1747,7 +1747,7 @@
1747
1747
  & .crisp-tabletoolbar-sort-learn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); font-size: var(--crisp-text-lg); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); text-decoration: none; }
1748
1748
  & .crisp-tabletoolbar-sort-learn svg { flex-shrink: 0; }
1749
1749
  & .crisp-tabletoolbar-sort-learn:hover { color: var(--crisp-fg-primary); }
1750
- & .crisp-tabletoolbar-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
1750
+ & .crisp-tabletoolbar-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
1751
1751
  & .crisp-tabletoolbar-menu-item:hover { background: var(--crisp-bg-raised); }
1752
1752
  & .crisp-tabletoolbar-menu-item:disabled { opacity: 0.4; cursor: default; }
1753
1753
  & .crisp-tabletoolbar-menu-item:disabled:hover { background: none; }
@@ -1760,6 +1760,7 @@
1760
1760
  & .crisp-tabletoolbar-menu--right { left: auto; right: 0; }
1761
1761
  & .crisp-tabletoolbar-menu--fixed { position: fixed; top: auto; left: auto; z-index: 40; }
1762
1762
  & .crisp-tabletoolbar-menu--hdr { min-width: 200px; }
1763
+ & .crisp-tabletoolbar-menu--op { min-width: 134px; }
1763
1764
  & .crisp-tabletoolbar-menu-item--danger { color: var(--crisp-bg-danger); }
1764
1765
  & .crisp-tabletoolbar-menu-item--danger svg { color: var(--crisp-bg-danger); }
1765
1766
  & .crisp-tabletoolbar-menu-item--danger:hover { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
@@ -2754,7 +2755,7 @@
2754
2755
  & .crisp-recordstable-sort-learn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); font-size: var(--crisp-text-lg); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); text-decoration: none; }
2755
2756
  & .crisp-recordstable-sort-learn svg { flex-shrink: 0; }
2756
2757
  & .crisp-recordstable-sort-learn:hover { color: var(--crisp-fg-primary); }
2757
- & .crisp-recordstable-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
2758
+ & .crisp-recordstable-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
2758
2759
  & .crisp-recordstable-menu-item:hover { background: var(--crisp-bg-raised); }
2759
2760
  & .crisp-recordstable-menu-item:disabled { opacity: 0.4; cursor: default; }
2760
2761
  & .crisp-recordstable-menu-item:disabled:hover { background: none; }
@@ -2767,6 +2768,7 @@
2767
2768
  & .crisp-recordstable-menu--right { left: auto; right: 0; }
2768
2769
  & .crisp-recordstable-menu--fixed { position: fixed; top: auto; left: auto; z-index: 40; }
2769
2770
  & .crisp-recordstable-menu--hdr { min-width: 200px; }
2771
+ & .crisp-recordstable-menu--op { min-width: 134px; }
2770
2772
  & .crisp-recordstable-menu-item--danger { color: var(--crisp-bg-danger); }
2771
2773
  & .crisp-recordstable-menu-item--danger svg { color: var(--crisp-bg-danger); }
2772
2774
  & .crisp-recordstable-menu-item--danger:hover { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
@@ -39,7 +39,7 @@
39
39
  & .crisp-tabletoolbar-sort-learn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); font-size: var(--crisp-text-lg); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); text-decoration: none; }
40
40
  & .crisp-tabletoolbar-sort-learn svg { flex-shrink: 0; }
41
41
  & .crisp-tabletoolbar-sort-learn:hover { color: var(--crisp-fg-primary); }
42
- & .crisp-tabletoolbar-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
42
+ & .crisp-tabletoolbar-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
43
43
  & .crisp-tabletoolbar-menu-item:hover { background: var(--crisp-bg-raised); }
44
44
  & .crisp-tabletoolbar-menu-item:disabled { opacity: 0.4; cursor: default; }
45
45
  & .crisp-tabletoolbar-menu-item:disabled:hover { background: none; }
@@ -52,6 +52,7 @@
52
52
  & .crisp-tabletoolbar-menu--right { left: auto; right: 0; }
53
53
  & .crisp-tabletoolbar-menu--fixed { position: fixed; top: auto; left: auto; z-index: 40; }
54
54
  & .crisp-tabletoolbar-menu--hdr { min-width: 200px; }
55
+ & .crisp-tabletoolbar-menu--op { min-width: 134px; }
55
56
  & .crisp-tabletoolbar-menu-item--danger { color: var(--crisp-bg-danger); }
56
57
  & .crisp-tabletoolbar-menu-item--danger svg { color: var(--crisp-bg-danger); }
57
58
  & .crisp-tabletoolbar-menu-item--danger:hover { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
@@ -40,7 +40,7 @@
40
40
  & .crisp-tabletoolbar-sort-learn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); font-size: var(--crisp-text-lg); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); text-decoration: none; }
41
41
  & .crisp-tabletoolbar-sort-learn svg { flex-shrink: 0; }
42
42
  & .crisp-tabletoolbar-sort-learn:hover { color: var(--crisp-fg-primary); }
43
- & .crisp-tabletoolbar-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
43
+ & .crisp-tabletoolbar-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
44
44
  & .crisp-tabletoolbar-menu-item:hover { background: var(--crisp-bg-raised); }
45
45
  & .crisp-tabletoolbar-menu-item:disabled { opacity: 0.4; cursor: default; }
46
46
  & .crisp-tabletoolbar-menu-item:disabled:hover { background: none; }
@@ -53,6 +53,7 @@
53
53
  & .crisp-tabletoolbar-menu--right { left: auto; right: 0; }
54
54
  & .crisp-tabletoolbar-menu--fixed { position: fixed; top: auto; left: auto; z-index: 40; }
55
55
  & .crisp-tabletoolbar-menu--hdr { min-width: 200px; }
56
+ & .crisp-tabletoolbar-menu--op { min-width: 134px; }
56
57
  & .crisp-tabletoolbar-menu-item--danger { color: var(--crisp-bg-danger); }
57
58
  & .crisp-tabletoolbar-menu-item--danger svg { color: var(--crisp-bg-danger); }
58
59
  & .crisp-tabletoolbar-menu-item--danger:hover { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
@@ -95,8 +95,10 @@ export type TableToolbarProps = Omit<React.ComponentPropsWithoutRef<"div">, "chi
95
95
  /** aria-label on a filter chip's "⋮" kebab (default "Filter options"). */
96
96
  filterOptionsLabel?: string;
97
97
  /** Label on the filter chip kebab's "Delete filter" action (default
98
- * "Delete filter") — Attio's own chip kebab (#594) has exactly this one
99
- * item. */
98
+ * "Delete filter") — Attio's own chip kebab (#594) has exactly this
99
+ * one item, danger-styled with a leading trash icon. Renamed from
100
+ * "Delete filter" (this prop's original default) after a re-measurement
101
+ * caught the wrong word. */
100
102
  deleteFilterLabel?: string;
101
103
  /** Label on the "ascending" sort-direction option (default "Ascending"). */
102
104
  ascendingLabel?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crisp-ui-kit/crisp",
3
- "version": "0.54.6",
3
+ "version": "0.54.7",
4
4
  "description": "A lean React design system, measured pixel-for-pixel from Attio.",
5
5
  "license": "MIT",
6
6
  "type": "module",