@crisp-ui-kit/crisp 0.54.7 → 0.54.8

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.
Files changed (113) hide show
  1. package/dist/authshell.css +5 -1
  2. package/dist/authshell.layered.css +5 -1
  3. package/dist/badge.css +5 -5
  4. package/dist/badge.layered.css +5 -5
  5. package/dist/board.css +13 -9
  6. package/dist/board.layered.css +13 -9
  7. package/dist/button.css +3 -1
  8. package/dist/button.layered.css +3 -1
  9. package/dist/cjs/components/badge/badge.recipe.js +28 -5
  10. package/dist/cjs/components/button/button.js +33 -2
  11. package/dist/cjs/components/button/button.recipe.js +31 -5
  12. package/dist/cjs/components/datatable/datatable.js +66 -7
  13. package/dist/cjs/components/datatable/datatable.recipe.js +57 -2
  14. package/dist/cjs/components/dialog/dialog.js +8 -5
  15. package/dist/cjs/components/dialog/dialog.recipe.js +15 -1
  16. package/dist/cjs/components/tabletoolbar/tabletoolbar.chrome.js +12 -3
  17. package/dist/cjs/components/tabletoolbar/tabletoolbar.js +231 -48
  18. package/dist/cjs/components/tabletoolbar/tabletoolbar.recipe.js +44 -0
  19. package/dist/cjs/components/tabs/tabs.recipe.js +11 -2
  20. package/dist/cjs/components/tooltip/tooltip.js +23 -9
  21. package/dist/cjs/components/tooltip/tooltip.recipe.js +10 -9
  22. package/dist/cjs/product/authshell/authshell.js +14 -1
  23. package/dist/cjs/product/authshell/authshell.recipe.js +13 -1
  24. package/dist/cjs/product/board/board.js +122 -27
  25. package/dist/cjs/product/board/board.recipe.js +14 -2
  26. package/dist/cjs/product/comments/comments.js +23 -10
  27. package/dist/cjs/product/comments/comments.recipe.js +17 -3
  28. package/dist/cjs/product/formdialog/formdialog.js +10 -4
  29. package/dist/cjs/product/navitem/navitem.js +7 -2
  30. package/dist/cjs/product/navitem/navitem.recipe.js +16 -0
  31. package/dist/cjs/product/objectsettings/index.js +1 -2
  32. package/dist/cjs/product/objectsettings/objectsettings.js +3 -13
  33. package/dist/cjs/product/richtext/richtext.js +76 -1
  34. package/dist/cjs/product/sidebar/sidebar.js +68 -15
  35. package/dist/cjs/product/sidebar/sidebar.recipe.js +6 -1
  36. package/dist/cjs/tokens/palette.js +32 -1
  37. package/dist/cjs/tokens/semantic.js +11 -0
  38. package/dist/comments.css +36 -10
  39. package/dist/comments.layered.css +36 -10
  40. package/dist/datatable.css +47 -9
  41. package/dist/datatable.layered.css +47 -9
  42. package/dist/dialog.css +13 -1
  43. package/dist/dialog.layered.css +13 -1
  44. package/dist/esm/components/badge/badge.recipe.js +28 -5
  45. package/dist/esm/components/button/button.js +34 -3
  46. package/dist/esm/components/button/button.recipe.js +31 -5
  47. package/dist/esm/components/datatable/datatable.js +67 -8
  48. package/dist/esm/components/datatable/datatable.recipe.js +57 -2
  49. package/dist/esm/components/dialog/dialog.js +8 -5
  50. package/dist/esm/components/dialog/dialog.recipe.js +15 -1
  51. package/dist/esm/components/tabletoolbar/tabletoolbar.chrome.js +12 -3
  52. package/dist/esm/components/tabletoolbar/tabletoolbar.js +231 -48
  53. package/dist/esm/components/tabletoolbar/tabletoolbar.recipe.js +44 -0
  54. package/dist/esm/components/tabs/tabs.recipe.js +11 -2
  55. package/dist/esm/components/tooltip/tooltip.js +23 -9
  56. package/dist/esm/components/tooltip/tooltip.recipe.js +10 -9
  57. package/dist/esm/product/authshell/authshell.js +15 -2
  58. package/dist/esm/product/authshell/authshell.recipe.js +13 -1
  59. package/dist/esm/product/authshell/index.js +1 -1
  60. package/dist/esm/product/board/board.js +122 -27
  61. package/dist/esm/product/board/board.recipe.js +14 -2
  62. package/dist/esm/product/comments/comments.js +23 -10
  63. package/dist/esm/product/comments/comments.recipe.js +17 -3
  64. package/dist/esm/product/formdialog/formdialog.js +10 -4
  65. package/dist/esm/product/navitem/index.js +1 -1
  66. package/dist/esm/product/navitem/navitem.js +7 -2
  67. package/dist/esm/product/navitem/navitem.recipe.js +16 -0
  68. package/dist/esm/product/objectsettings/index.js +1 -1
  69. package/dist/esm/product/objectsettings/objectsettings.js +2 -12
  70. package/dist/esm/product/richtext/richtext.js +76 -1
  71. package/dist/esm/product/sidebar/sidebar.js +69 -16
  72. package/dist/esm/product/sidebar/sidebar.recipe.js +6 -1
  73. package/dist/esm/tokens/palette.js +32 -1
  74. package/dist/esm/tokens/semantic.js +11 -0
  75. package/dist/native/tokens.d.ts +1 -1
  76. package/dist/native/tokens.js +16 -2
  77. package/dist/navitem.css +7 -0
  78. package/dist/navitem.layered.css +7 -0
  79. package/dist/recordstable.css +1 -1
  80. package/dist/recordstable.layered.css +1 -1
  81. package/dist/sidebar.css +6 -1
  82. package/dist/sidebar.layered.css +6 -1
  83. package/dist/styles.css +163 -42
  84. package/dist/styles.layered.css +163 -42
  85. package/dist/tabletoolbar.css +16 -1
  86. package/dist/tabletoolbar.layered.css +16 -1
  87. package/dist/tabs.css +1 -1
  88. package/dist/tabs.layered.css +1 -1
  89. package/dist/tokens.css +9 -1
  90. package/dist/tokens.json +16 -2
  91. package/dist/tooltip.css +1 -1
  92. package/dist/tooltip.layered.css +1 -1
  93. package/dist/types/components/badge/badge.recipe.d.ts +5 -1
  94. package/dist/types/components/button/button.recipe.d.ts +18 -5
  95. package/dist/types/components/datatable/datatable.d.ts +9 -0
  96. package/dist/types/components/dialog/dialog.d.ts +25 -2
  97. package/dist/types/components/tabletoolbar/tabletoolbar.d.ts +43 -3
  98. package/dist/types/components/tooltip/tooltip.d.ts +12 -4
  99. package/dist/types/components/tooltip/tooltip.recipe.d.ts +1 -1
  100. package/dist/types/product/authshell/authshell.d.ts +26 -2
  101. package/dist/types/product/authshell/index.d.ts +1 -1
  102. package/dist/types/product/board/board.d.ts +5 -4
  103. package/dist/types/product/comments/comments.d.ts +10 -2
  104. package/dist/types/product/formdialog/formdialog.d.ts +2 -1
  105. package/dist/types/product/navitem/index.d.ts +1 -1
  106. package/dist/types/product/navitem/navitem.d.ts +23 -0
  107. package/dist/types/product/objectsettings/index.d.ts +1 -1
  108. package/dist/types/product/objectsettings/objectsettings.d.ts +0 -10
  109. package/dist/types/product/sidebar/sidebar.d.ts +33 -5
  110. package/dist/types/tokens/contract.d.ts +4 -0
  111. package/dist/types/tokens/palette.d.ts +13 -1
  112. package/dist/types/tokens/semantic.d.ts +11 -0
  113. package/package.json +1 -1
@@ -24,8 +24,20 @@ const config = (0, core_1.defineRecipe)({
24
24
  }
25
25
  /* The header cell has no padding of its own -- the button owns the
26
26
  full cell so the whole header is clickable (its own inset is 12px).
27
- Mirrors the summary-row fix. */
28
- & th { padding: 0; }
27
+ Mirrors the summary-row fix.
28
+ \`& .crisp-table th\`, not bare \`& th\` (found while re-checking #691's
29
+ own fix live): DataTable's root nests \`Table\`'s own wrapper, whose
30
+ \`table.recipe.ts\` carries \`& th, & td { padding: 0 12px }\` at the
31
+ SAME specificity (.crisp-table th vs .crisp-datatable th, both one
32
+ class + one element) -- a bare \`& th\` here only won by source
33
+ order, which flipped the moment table.recipe.ts's own CSS file
34
+ happened to land after datatable's in the build (alphabetical:
35
+ datatable < table), silently reinstating 12px on every header cell
36
+ in the whole product and making every interactive column's button
37
+ double it to 24px. Scoping through \`.crisp-table\` adds a second
38
+ class to the selector (0,2,1 beats 0,1,1) so this can never lose a
39
+ specificity tie to source order again. */
40
+ & .crisp-table th { padding: 0; }
29
41
  /* Same wrapper trap as AUTHORING.md Lesson 40 (ColumnCalc's summary trigger):
30
42
  Menu wraps its trigger in a flex div that sizes to its content, so a
31
43
  long header grew past the column instead of filling it -- with nothing
@@ -36,6 +48,20 @@ const config = (0, core_1.defineRecipe)({
36
48
  & th .crisp-menu { width: 100%; height: 100%; }
37
49
  & .crisp-datatable-th-inner { display: inline-flex; align-items: center; gap: ${tokens_1.contract.space["1.5"]}; width: 100%; min-width: 0; height: 100%; }
38
50
  & .crisp-datatable-th-inner > svg { flex-shrink: 0; color: ${tokens_1.contract.fgMuted}; }
51
+ /* crisp/#605 follow-up: a header with neither a Menu nor a sort button
52
+ (the primary/entity column's now-inert path, or any column with no
53
+ columnMenu/sortable at all) renders .crisp-datatable-th-inner as a
54
+ DIRECT child of th instead of nested inside a button -- and loses
55
+ the button's own 12px inset, drifting left of the td's 12px base
56
+ inset. Measured live on Attio's own Companies grid: the header label
57
+ and the cell's own text land at the exact same x (335px from the
58
+ viewport, both 40px from the column's left edge) via two different
59
+ padding+icon+gap combinations -- Attio does not leave the inert
60
+ primary header flush left either. The \`>\` combinator targets only
61
+ the button-less case: Menu's own wrapper (\`.crisp-menu\`) and the
62
+ plain sort \`button\` both put >=1 more level between \`th\` and this
63
+ span, so their own 12px (already on the button) isn't doubled. */
64
+ & th > .crisp-datatable-th-inner { box-sizing: border-box; padding: 0 ${tokens_1.contract.space["3"]}; }
39
65
  /* The summary cell has NO padding of its own -- the calculation trigger
40
66
  owns the whole 246x37 area so a click anywhere in the cell opens the
41
67
  menu. Zero the cell's inset and let ColumnCalc supply the 12px. */
@@ -119,8 +145,37 @@ const config = (0, core_1.defineRecipe)({
119
145
  & .crisp-datatable-refoption-avatar { flex-shrink: 0; }
120
146
  & .crisp-datatable-refoption--create { color: ${tokens_1.contract.fgMuted}; }
121
147
  & .crisp-datatable-empty { padding: ${tokens_1.contract.space["8"]} ${tokens_1.contract.space["3"]}; text-align: center; color: ${tokens_1.contract.fgMuted}; font-size: ${tokens_1.contract.text.lg}; }
148
+ /* #579: click-to-expand overlay for a truncated cell -- a read-only,
149
+ full-value card, settled live as click (not Attio's usual
150
+ hover-expand) and measured position: absolute, unlike this file's
151
+ floating chrome (Menu/Select popovers) which portals and escapes the
152
+ scroll container. Deliberately NOT the edit-error pattern above
153
+ (grow the row, block-level, never clipped): a virtualized grid
154
+ assumes a fixed row height for its scroll math (owned by the grid
155
+ core, not this cell), so growing a row here would fight it. Anchored
156
+ to the SAME column width the cell itself renders at (measured:
157
+ Attio's own overlay came out only slightly wider than the
158
+ triggering cell's clientWidth -- the overshoot is this padding),
159
+ wrapping onto as many lines as the value needs; it CAN be clipped by
160
+ \`.crisp-table-scroll\`'s own \`overflow: auto\` if it grows past the
161
+ visible viewport, same as the edit-error comment above already
162
+ notes for any position:absolute escape -- unmeasured against Attio
163
+ for this exact case, flagged rather than guessed. */
164
+ & td[data-cell-expanded] { overflow: visible; z-index: 7; }
165
+ & .crisp-datatable-cell-overlay {
166
+ position: absolute; inset-inline-start: 0; top: 0; width: 100%; box-sizing: border-box;
167
+ padding: ${tokens_1.contract.space["2"]} ${tokens_1.contract.space["3"]}; background: ${tokens_1.contract.bgSurface};
168
+ border: 1px solid ${tokens_1.contract.bgBrandSolid}; border-radius: 4px;
169
+ font-family: ${tokens_1.contract.font.sans}; font-size: ${tokens_1.contract.text.lg}; line-height: 20px; font-weight: ${tokens_1.contract.weight.medium};
170
+ color: ${tokens_1.contract.fgPrimary}; white-space: normal; word-break: break-word; cursor: default;
171
+ }
122
172
  /* fixed layout so column widths (and resize) are exact — like RecordsTable */
123
173
  & table { table-layout: fixed; }
174
+ /* read-only/computed column marker (#596) -- sits just inside the
175
+ resize handle, same absolute-positioned-against-the-th approach the
176
+ handle itself uses, since th has zero padding and the button/inner
177
+ row fills the whole cell with no room left for a trailing sibling. */
178
+ & .crisp-datatable-readonly { position: absolute; top: 50%; inset-inline-end: 11px; transform: translateY(-50%); color: ${tokens_1.contract.fgMuted}; pointer-events: none; z-index: 5; }
124
179
  /* column resize grip */
125
180
  & .crisp-datatable-resize { position: absolute; top: 0; inset-inline-end: -3px; width: 9px; height: 100%; cursor: col-resize; z-index: 6; touch-action: none; }
126
181
  & .crisp-datatable-resize::after { content: ""; position: absolute; top: 0; inset-inline-start: 3px; width: 2px; height: 100%; background: ${tokens_1.contract.bgBrandSolid}; opacity: 0; transition: opacity .12s; }
@@ -60,12 +60,13 @@ function useDialogInstanceId() {
60
60
  * Escape / outside-click dismissal) with the measured modal surface.
61
61
  * Compose the body with `DialogBody` and actions with `DialogFooter`.
62
62
  */
63
- function Dialog({ open, onOpenChange, title, icon, width = 640, "aria-label": ariaLabel, closeLabel: closeLabelProp, children, className, style, "aria-describedby": describedBy, ...rest }) {
63
+ function Dialog({ open, onOpenChange, title, icon, width = 640, variant = "panel", description, "aria-label": ariaLabel, closeLabel: closeLabelProp, children, className, style, "aria-describedby": describedBy, ...rest }) {
64
64
  const closeLabel = (0, core_1.useCrispMessage)(closeLabelProp, "Close");
65
65
  const id = useDialogInstanceId();
66
66
  const service = (0, react_1.useMachine)(dialog.machine, {
67
67
  id,
68
68
  open,
69
+ role: variant === "alert" ? "alertdialog" : "dialog",
69
70
  onOpenChange(details) {
70
71
  onOpenChange(details.open);
71
72
  },
@@ -89,15 +90,17 @@ function Dialog({ open, onOpenChange, title, icon, width = 640, "aria-label": ar
89
90
  const api = dialog.connect(service, react_1.normalizeProps);
90
91
  if (!api.open)
91
92
  return null;
92
- return ((0, jsx_runtime_1.jsx)(react_1.Portal, { children: (0, jsx_runtime_1.jsxs)("div", { className: (0, dialog_recipe_1.dialogRecipe)(), children: [(0, jsx_runtime_1.jsx)("div", { ...api.getBackdropProps(), className: "crisp-dialog-backdrop" }), (0, jsx_runtime_1.jsx)("div", { ...api.getPositionerProps(), className: "crisp-dialog-positioner", children: (0, jsx_runtime_1.jsx)("div", { ...rest, ...(0, core_1.withDescribedBy)(api.getContentProps(), describedBy), className: (0, core_1.cx)("crisp-dialog-content", className), "data-crisp-dialog": id,
93
+ return ((0, jsx_runtime_1.jsx)(react_1.Portal, { children: (0, jsx_runtime_1.jsxs)("div", { className: (0, dialog_recipe_1.dialogRecipe)(), children: [(0, jsx_runtime_1.jsx)("div", { ...api.getBackdropProps(), className: "crisp-dialog-backdrop" }), (0, jsx_runtime_1.jsx)("div", { ...api.getPositionerProps(), className: "crisp-dialog-positioner", "data-variant": variant, children: (0, jsx_runtime_1.jsx)("div", { ...rest, ...(0, core_1.withDescribedBy)(api.getContentProps(), describedBy), className: (0, core_1.cx)("crisp-dialog-content", className), "data-crisp-dialog": id, "data-variant": variant,
93
94
  // `width` is the component's own knob, so it wins over a passed
94
95
  // maxWidth; everything else a consumer sets survives
95
- style: { ...style, maxWidth: `min(${width}px, 90vw)` }, children: (0, jsx_runtime_1.jsxs)("div", { className: "crisp-dialog-card", children: [title != null && ((0, jsx_runtime_1.jsxs)("div", { className: "crisp-dialog-header", children: [icon, (0, jsx_runtime_1.jsx)("h2", { ...api.getTitleProps(), className: "crisp-dialog-title", children: title }), (0, jsx_runtime_1.jsx)("button", { type: "button", ...api.getCloseTriggerProps(), className: "crisp-dialog-close", "aria-label": closeLabel, children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 16, strokeWidth: 2, "aria-hidden": "true" }) })] })), children] }) }) })] }) }));
96
+ style: { ...style, maxWidth: `min(${width}px, 90vw)` }, children: (0, jsx_runtime_1.jsxs)("div", { className: "crisp-dialog-card", children: [variant === "alert"
97
+ ? (title != null || description != null) && ((0, jsx_runtime_1.jsxs)("div", { className: "crisp-dialog-alert-header", children: [title != null && ((0, jsx_runtime_1.jsx)("h2", { ...api.getTitleProps(), className: "crisp-dialog-alert-title", children: title })), description != null && ((0, jsx_runtime_1.jsx)("p", { ...api.getDescriptionProps(), className: "crisp-dialog-alert-description", children: description }))] }))
98
+ : title != null && ((0, jsx_runtime_1.jsxs)("div", { className: "crisp-dialog-header", children: [icon, (0, jsx_runtime_1.jsx)("h2", { ...api.getTitleProps(), className: "crisp-dialog-title", children: title }), (0, jsx_runtime_1.jsx)("button", { type: "button", ...api.getCloseTriggerProps(), className: "crisp-dialog-close", "aria-label": closeLabel, children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 16, strokeWidth: 2, "aria-hidden": "true" }) })] })), children] }) }) })] }) }));
96
99
  }
97
100
  Dialog.displayName = "Dialog";
98
101
  function DialogBody({ children, className, }) {
99
102
  return ((0, jsx_runtime_1.jsx)("div", { className: className ? `crisp-dialog-body ${className}` : "crisp-dialog-body", children: children }));
100
103
  }
101
- function DialogFooter({ children }) {
102
- return (0, jsx_runtime_1.jsx)("div", { className: "crisp-dialog-footer", children: children });
104
+ function DialogFooter({ children, variant = "panel", }) {
105
+ return ((0, jsx_runtime_1.jsx)("div", { className: "crisp-dialog-footer", "data-variant": variant, children: children }));
103
106
  }
@@ -18,17 +18,31 @@ const tokens_1 = require("../../tokens");
18
18
  const config = (0, core_1.defineRecipe)({
19
19
  name: "dialog",
20
20
  base: `display: contents; font-family: ${tokens_1.contract.font.sans};
21
- & .crisp-dialog-backdrop { position: fixed; inset: 0; z-index: 60; background: transparent; }
21
+ & .crisp-dialog-backdrop { position: fixed; inset: 0; z-index: 60; background: ${tokens_1.contract.bgScrim}; }
22
22
  & .crisp-dialog-positioner { position: fixed; inset: 0; z-index: 61; display: flex; align-items: flex-start; justify-content: center; padding: 15vh ${tokens_1.contract.space["4"]} ${tokens_1.contract.space["4"]}; }
23
+ & .crisp-dialog-positioner[data-variant="alert"] { align-items: center; padding: ${tokens_1.contract.space["4"]}; }
23
24
  & .crisp-dialog-content { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; position: relative; display: flex; flex-direction: column; box-sizing: border-box; width: 90vw; max-height: 74vh; padding: ${tokens_1.contract.space["1"]}; border-radius: ${tokens_1.contract.radius["2xl"]}; background: color-mix(in srgb, ${tokens_1.contract.bgOverlayFrost} 60%, transparent); backdrop-filter: blur(15px); -webkit-backdrop-filter: blur(15px); box-shadow: ${tokens_1.elevation.modal}; opacity: 1; transform: scale(1); transition: opacity 0.2s ease, transform 0.2s ease; @starting-style { opacity: 0; transform: scale(0.97); } }
25
+ & .crisp-dialog-content[data-variant="alert"] { padding: 0; background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: none; }
24
26
  & .crisp-dialog-card { display: flex; flex-direction: column; flex: 1; min-height: 0; box-sizing: border-box; border-radius: ${tokens_1.contract.radius.xl}; background: ${tokens_1.contract.bgSurface}; box-shadow: 0 0 0 1px color-mix(in srgb, ${tokens_1.contract.fgPrimary} 8%, transparent); overflow: hidden; }
27
+ & .crisp-dialog-content[data-variant="alert"] .crisp-dialog-card { border-radius: ${tokens_1.contract.radius.xl}; background: ${tokens_1.contract.bgPopover}; box-shadow: ${tokens_1.elevation.floating}; }
25
28
  & .crisp-dialog-header { display: flex; align-items: center; gap: ${tokens_1.contract.space["2"]}; flex-shrink: 0; height: 52px; padding: 0 ${tokens_1.contract.space["2"]} 0 ${tokens_1.contract.space["4"]}; border-bottom: 1px solid ${tokens_1.contract.borderSubtle}; }
26
29
  & .crisp-dialog-header svg { flex-shrink: 0; color: ${tokens_1.contract.fgMuted}; }
27
30
  & .crisp-dialog-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.medium}; color: ${tokens_1.contract.fgPrimary}; margin: 0; }
28
31
  & .crisp-dialog-close { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 28px; height: 28px; margin: 0; padding: 0; border: none; border-radius: ${tokens_1.contract.radius.md}; background: none; color: ${tokens_1.contract.fgMuted}; font-family: inherit; cursor: pointer; }
29
32
  & .crisp-dialog-close:hover { background: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 6%, transparent); color: ${tokens_1.contract.fgPrimary}; }
33
+ /* The discard-confirm's own stacked title + sentence (crisp#677) — no
34
+ border, no close button, unlike the panel header above: measured
35
+ live, both themes, 18px/24px 600-weight title (no scale token
36
+ reaches 18px — the scale tops out at text.xl's 16px, so this is raw
37
+ px per Golden Rule 3's "genuinely intrinsic size" exception, same as
38
+ this file's own submit-key glyphs) then a 14px/20px 500-weight
39
+ sentence 4px below it. */
40
+ & .crisp-dialog-alert-header { display: flex; flex-direction: column; gap: ${tokens_1.contract.space["1"]}; padding: ${tokens_1.contract.space["4"]} ${tokens_1.contract.space["4"]} 0; }
41
+ & .crisp-dialog-alert-title { margin: 0; font-size: 18px; line-height: 24px; font-weight: ${tokens_1.contract.weight.semibold}; color: ${tokens_1.contract.fgPrimary}; }
42
+ & .crisp-dialog-alert-description { margin: 0; font-size: ${tokens_1.contract.text.lg}; line-height: 20px; font-weight: ${tokens_1.contract.weight.medium}; color: ${tokens_1.contract.fgAlertDescription}; }
30
43
  & .crisp-dialog-body { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: ${tokens_1.contract.space["4"]}; padding: ${tokens_1.contract.space["5"]} ${tokens_1.contract.space["4"]}; }
31
44
  & .crisp-dialog-footer { display: flex; align-items: center; justify-content: flex-end; gap: ${tokens_1.contract.space["3"]}; flex-shrink: 0; min-height: 56px; padding: 0 ${tokens_1.contract.space["4"]}; border-top: 1px solid ${tokens_1.contract.borderSubtle}; }
45
+ & .crisp-dialog-footer[data-variant="alert"] { min-height: 45px; padding: ${tokens_1.contract.space["2"]}; }
32
46
  & .crisp-dialog-field { display: flex; flex-direction: column; gap: ${tokens_1.contract.space["1.5"]}; }
33
47
  & .crisp-dialog-field-label { font-size: ${tokens_1.contract.text.sm}; font-weight: ${tokens_1.contract.weight.medium}; color: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 50%, transparent); }
34
48
  & .crisp-dialog-more { display: inline-flex; align-items: center; gap: ${tokens_1.contract.space["2"]}; margin-inline-end: auto; border: none; background: none; padding: 0; font-family: inherit; font-size: ${tokens_1.contract.text.md}; color: ${tokens_1.contract.fgMuted}; cursor: pointer; }
@@ -19,12 +19,21 @@ const tokens_1 = require("../../tokens");
19
19
  // stay byte-for-byte identical to what shipped before the extraction.
20
20
  //
21
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
22
+ // no fixed min-width of its own (#593 correction below), unlike the default
23
+ // 232px every other menu here uses. `.menu-item` also picked up
24
24
  // `line-height: 20px` and `font-weight: medium` from the same measurement
25
25
  // (its 8 rows read 14px/20px/500) — shared by every menu that renders one,
26
26
  // not just the operator list, since crisp's menu-item typography was
27
27
  // previously unset rather than wrong.
28
+ //
29
+ // #593 correction: `.menu--op` originally carried a fixed `min-width: 134px`
30
+ // (rounded from one live measurement, the 8-op text set at 135px). Adding
31
+ // number/date columns' own shorter operator sets and re-measuring them live
32
+ // (104.86px for 6 number ops, 91.16px for 6 date ops — both narrower than
33
+ // 134px) showed that number wasn't a real Attio constant, just one set's own
34
+ // content width: a floor sized for the text set overshoots the other two.
35
+ // Dropped to `min-width: 0` so every op set sizes to its own content, the
36
+ // same as any other menu here without an explicit floor.
28
37
  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"]}; }
29
38
  & .${namespace_1.CLASS_PREFIX}${p}-toolbar[data-inline] { padding-bottom: 0; }
30
39
  & .${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}; }
@@ -77,7 +86,7 @@ const toolbarChromeBody = (p) => ` & .${namespace_1.CLASS_PREFIX}${p}-menu-he
77
86
  & .${namespace_1.CLASS_PREFIX}${p}-menu--right { left: auto; right: 0; }
78
87
  & .${namespace_1.CLASS_PREFIX}${p}-menu--fixed { position: fixed; top: auto; left: auto; z-index: 40; }
79
88
  & .${namespace_1.CLASS_PREFIX}${p}-menu--hdr { min-width: 200px; }
80
- & .${namespace_1.CLASS_PREFIX}${p}-menu--op { min-width: 134px; }
89
+ & .${namespace_1.CLASS_PREFIX}${p}-menu--op { min-width: 0; }
81
90
  & .${namespace_1.CLASS_PREFIX}${p}-menu-item--danger { color: ${tokens_1.contract.bgDanger}; }
82
91
  & .${namespace_1.CLASS_PREFIX}${p}-menu-item--danger svg { color: ${tokens_1.contract.bgDanger}; }
83
92
  & .${namespace_1.CLASS_PREFIX}${p}-menu-item--danger:hover { background: color-mix(in srgb, ${tokens_1.contract.bgDanger} 10%, transparent); }