@crisp-ui-kit/crisp 0.57.2 → 0.57.4

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 (200) hide show
  1. package/dist/assigneepicker.css +13 -0
  2. package/dist/assigneepicker.d.ts +7 -0
  3. package/dist/assigneepicker.layered.css +15 -0
  4. package/dist/button.css +3 -0
  5. package/dist/button.d.ts +2 -2
  6. package/dist/button.layered.css +3 -0
  7. package/dist/chip.css +1 -1
  8. package/dist/chip.layered.css +1 -1
  9. package/dist/cjs/components/breadcrumb/breadcrumb.js +1 -1
  10. package/dist/cjs/components/button/button.recipe.js +33 -0
  11. package/dist/cjs/components/chip/chip.recipe.js +3 -1
  12. package/dist/cjs/components/datatable/datatable.js +6 -3
  13. package/dist/cjs/components/datatable/datatable.recipe.js +45 -6
  14. package/dist/cjs/components/datepickerfield/datepickerfield.js +2 -2
  15. package/dist/cjs/components/datepickerfield/datepickerfield.recipe.js +16 -3
  16. package/dist/cjs/components/menu/menu.js +65 -9
  17. package/dist/cjs/components/multiselect/multiselect.js +3 -0
  18. package/dist/cjs/components/multiselect/multiselect.recipe.js +18 -0
  19. package/dist/cjs/components/select/select.js +2 -2
  20. package/dist/cjs/components/select/select.recipe.js +19 -0
  21. package/dist/cjs/components/table/table.recipe.js +7 -1
  22. package/dist/cjs/core/floating-portal.js +7 -4
  23. package/dist/cjs/core/index.js +2 -1
  24. package/dist/cjs/core/place-floating.js +38 -0
  25. package/dist/cjs/index.js +8 -0
  26. package/dist/cjs/product/assigneepicker/assigneepicker.js +127 -0
  27. package/dist/cjs/product/assigneepicker/assigneepicker.recipe.js +36 -0
  28. package/dist/cjs/product/assigneepicker/index.js +7 -0
  29. package/dist/cjs/product/inbox/inbox.js +11 -3
  30. package/dist/cjs/product/notesgallery/index.js +7 -0
  31. package/dist/cjs/product/notesgallery/notesgallery.js +80 -0
  32. package/dist/cjs/product/notesgallery/notesgallery.recipe.js +46 -0
  33. package/dist/cjs/product/objectpagemenu/index.js +17 -0
  34. package/dist/cjs/product/objectpagemenu/objectpagemenu.js +26 -0
  35. package/dist/cjs/product/objectpagemenu/objectpagemenu.recipe.js +30 -0
  36. package/dist/cjs/product/objectsettings/objectsettings.js +107 -14
  37. package/dist/cjs/product/recordpage/index.js +2 -1
  38. package/dist/cjs/product/recordpage/recordpage.js +112 -7
  39. package/dist/cjs/product/recordpage/recordpage.recipe.js +63 -0
  40. package/dist/cjs/product/recordpicker/index.js +7 -0
  41. package/dist/cjs/product/recordpicker/recordpicker.js +100 -0
  42. package/dist/cjs/product/recordpicker/recordpicker.recipe.js +36 -0
  43. package/dist/cjs/product/savedviews/index.js +2 -1
  44. package/dist/cjs/product/savedviews/savedviews.js +22 -0
  45. package/dist/cjs/product/savedviews/savedviews.recipe.js +47 -0
  46. package/dist/cjs/product/share/index.js +7 -0
  47. package/dist/cjs/product/share/share.js +179 -0
  48. package/dist/cjs/product/share/share.recipe.js +114 -0
  49. package/dist/cjs/product/shortcutssheet/index.js +17 -0
  50. package/dist/cjs/product/shortcutssheet/shortcutssheet.js +125 -0
  51. package/dist/cjs/product/shortcutssheet/shortcutssheet.recipe.js +50 -0
  52. package/dist/cjs/product/taskeditpopover/index.js +7 -0
  53. package/dist/cjs/product/taskeditpopover/taskeditpopover.js +159 -0
  54. package/dist/cjs/product/taskeditpopover/taskeditpopover.recipe.js +68 -0
  55. package/dist/cjs/product/workspaceswitchermenu/index.js +17 -0
  56. package/dist/cjs/product/workspaceswitchermenu/workspaceswitchermenu.js +38 -0
  57. package/dist/cjs/product/workspaceswitchermenu/workspaceswitchermenu.recipe.js +34 -0
  58. package/dist/cjs/tokens/palette.js +27 -0
  59. package/dist/cjs/tokens/semantic.js +20 -0
  60. package/dist/datatable.css +50 -11
  61. package/dist/datatable.layered.css +50 -11
  62. package/dist/datepickerfield.css +8 -2
  63. package/dist/datepickerfield.d.ts +2 -2
  64. package/dist/datepickerfield.layered.css +8 -2
  65. package/dist/esm/components/breadcrumb/breadcrumb.js +1 -1
  66. package/dist/esm/components/button/button.recipe.js +33 -0
  67. package/dist/esm/components/chip/chip.recipe.js +3 -1
  68. package/dist/esm/components/datatable/datatable.js +6 -3
  69. package/dist/esm/components/datatable/datatable.recipe.js +45 -6
  70. package/dist/esm/components/datepickerfield/datepickerfield.js +2 -2
  71. package/dist/esm/components/datepickerfield/datepickerfield.recipe.js +16 -3
  72. package/dist/esm/components/menu/menu.js +64 -8
  73. package/dist/esm/components/multiselect/multiselect.js +3 -0
  74. package/dist/esm/components/multiselect/multiselect.recipe.js +18 -0
  75. package/dist/esm/components/select/select.js +2 -2
  76. package/dist/esm/components/select/select.recipe.js +19 -0
  77. package/dist/esm/components/table/table.recipe.js +7 -1
  78. package/dist/esm/core/floating-portal.js +7 -4
  79. package/dist/esm/core/index.js +1 -1
  80. package/dist/esm/core/place-floating.js +37 -0
  81. package/dist/esm/index.js +8 -0
  82. package/dist/esm/product/assigneepicker/assigneepicker.js +91 -0
  83. package/dist/esm/product/assigneepicker/assigneepicker.recipe.js +33 -0
  84. package/dist/esm/product/assigneepicker/index.js +2 -0
  85. package/dist/esm/product/inbox/inbox.js +11 -3
  86. package/dist/esm/product/notesgallery/index.js +2 -0
  87. package/dist/esm/product/notesgallery/notesgallery.js +44 -0
  88. package/dist/esm/product/notesgallery/notesgallery.recipe.js +43 -0
  89. package/dist/esm/product/objectpagemenu/index.js +1 -0
  90. package/dist/esm/product/objectpagemenu/objectpagemenu.js +23 -0
  91. package/dist/esm/product/objectpagemenu/objectpagemenu.recipe.js +27 -0
  92. package/dist/esm/product/objectsettings/objectsettings.js +106 -13
  93. package/dist/esm/product/recordpage/index.js +1 -1
  94. package/dist/esm/product/recordpage/recordpage.js +112 -8
  95. package/dist/esm/product/recordpage/recordpage.recipe.js +63 -0
  96. package/dist/esm/product/recordpicker/index.js +2 -0
  97. package/dist/esm/product/recordpicker/recordpicker.js +64 -0
  98. package/dist/esm/product/recordpicker/recordpicker.recipe.js +33 -0
  99. package/dist/esm/product/savedviews/index.js +1 -1
  100. package/dist/esm/product/savedviews/savedviews.js +22 -1
  101. package/dist/esm/product/savedviews/savedviews.recipe.js +47 -0
  102. package/dist/esm/product/share/index.js +2 -0
  103. package/dist/esm/product/share/share.js +143 -0
  104. package/dist/esm/product/share/share.recipe.js +111 -0
  105. package/dist/esm/product/shortcutssheet/index.js +1 -0
  106. package/dist/esm/product/shortcutssheet/shortcutssheet.js +88 -0
  107. package/dist/esm/product/shortcutssheet/shortcutssheet.recipe.js +47 -0
  108. package/dist/esm/product/taskeditpopover/index.js +2 -0
  109. package/dist/esm/product/taskeditpopover/taskeditpopover.js +123 -0
  110. package/dist/esm/product/taskeditpopover/taskeditpopover.recipe.js +65 -0
  111. package/dist/esm/product/workspaceswitchermenu/index.js +1 -0
  112. package/dist/esm/product/workspaceswitchermenu/workspaceswitchermenu.js +35 -0
  113. package/dist/esm/product/workspaceswitchermenu/workspaceswitchermenu.recipe.js +31 -0
  114. package/dist/esm/tokens/palette.js +27 -0
  115. package/dist/esm/tokens/semantic.js +20 -0
  116. package/dist/multiselect.css +18 -0
  117. package/dist/multiselect.layered.css +18 -0
  118. package/dist/native/tokens.d.ts +1 -1
  119. package/dist/native/tokens.js +56 -4
  120. package/dist/notesgallery.css +15 -0
  121. package/dist/notesgallery.d.ts +7 -0
  122. package/dist/notesgallery.layered.css +17 -0
  123. package/dist/objectpagemenu.css +3 -0
  124. package/dist/objectpagemenu.d.ts +7 -0
  125. package/dist/objectpagemenu.layered.css +5 -0
  126. package/dist/recordpage.css +59 -0
  127. package/dist/recordpage.layered.css +59 -0
  128. package/dist/recordpicker.css +13 -0
  129. package/dist/recordpicker.d.ts +7 -0
  130. package/dist/recordpicker.layered.css +15 -0
  131. package/dist/savedviews.css +47 -0
  132. package/dist/savedviews.layered.css +47 -0
  133. package/dist/select.css +19 -0
  134. package/dist/select.layered.css +19 -0
  135. package/dist/share.css +84 -0
  136. package/dist/share.d.ts +7 -0
  137. package/dist/share.layered.css +86 -0
  138. package/dist/shortcutssheet.css +24 -0
  139. package/dist/shortcutssheet.d.ts +7 -0
  140. package/dist/shortcutssheet.layered.css +26 -0
  141. package/dist/styles.css +438 -16
  142. package/dist/styles.layered.css +438 -16
  143. package/dist/table.css +7 -2
  144. package/dist/table.layered.css +7 -2
  145. package/dist/taskeditpopover.css +36 -0
  146. package/dist/taskeditpopover.d.ts +7 -0
  147. package/dist/taskeditpopover.layered.css +38 -0
  148. package/dist/tokens.css +26 -0
  149. package/dist/tokens.json +56 -4
  150. package/dist/types/components/breadcrumb/breadcrumb.d.ts +9 -1
  151. package/dist/types/components/button/button.d.ts +2 -0
  152. package/dist/types/components/button/button.recipe.d.ts +12 -0
  153. package/dist/types/components/chip/chip.recipe.d.ts +1 -1
  154. package/dist/types/components/datatable/datatable.d.ts +8 -0
  155. package/dist/types/components/datepickerfield/datepickerfield.d.ts +4 -1
  156. package/dist/types/components/datepickerfield/datepickerfield.recipe.d.ts +18 -3
  157. package/dist/types/components/menu/menu.d.ts +50 -7
  158. package/dist/types/components/multiselect/multiselect.d.ts +9 -0
  159. package/dist/types/components/select/select.d.ts +10 -0
  160. package/dist/types/core/floating-portal.d.ts +6 -5
  161. package/dist/types/core/index.d.ts +1 -1
  162. package/dist/types/core/place-floating.d.ts +37 -0
  163. package/dist/types/index.d.ts +8 -0
  164. package/dist/types/product/assigneepicker/assigneepicker.d.ts +36 -0
  165. package/dist/types/product/assigneepicker/assigneepicker.recipe.d.ts +3 -0
  166. package/dist/types/product/assigneepicker/index.d.ts +2 -0
  167. package/dist/types/product/inbox/inbox.d.ts +13 -1
  168. package/dist/types/product/notesgallery/index.d.ts +2 -0
  169. package/dist/types/product/notesgallery/notesgallery.d.ts +54 -0
  170. package/dist/types/product/notesgallery/notesgallery.recipe.d.ts +3 -0
  171. package/dist/types/product/objectpagemenu/index.d.ts +1 -0
  172. package/dist/types/product/objectpagemenu/objectpagemenu.d.ts +40 -0
  173. package/dist/types/product/objectpagemenu/objectpagemenu.recipe.d.ts +17 -0
  174. package/dist/types/product/objectsettings/objectsettings.d.ts +71 -15
  175. package/dist/types/product/recordpage/index.d.ts +1 -1
  176. package/dist/types/product/recordpage/recordpage.d.ts +142 -1
  177. package/dist/types/product/recordpicker/index.d.ts +2 -0
  178. package/dist/types/product/recordpicker/recordpicker.d.ts +38 -0
  179. package/dist/types/product/recordpicker/recordpicker.recipe.d.ts +3 -0
  180. package/dist/types/product/savedviews/index.d.ts +1 -1
  181. package/dist/types/product/savedviews/savedviews.d.ts +36 -0
  182. package/dist/types/product/share/index.d.ts +2 -0
  183. package/dist/types/product/share/share.d.ts +85 -0
  184. package/dist/types/product/share/share.recipe.d.ts +3 -0
  185. package/dist/types/product/shortcutssheet/index.d.ts +1 -0
  186. package/dist/types/product/shortcutssheet/shortcutssheet.d.ts +49 -0
  187. package/dist/types/product/shortcutssheet/shortcutssheet.recipe.d.ts +3 -0
  188. package/dist/types/product/taskeditpopover/index.d.ts +2 -0
  189. package/dist/types/product/taskeditpopover/taskeditpopover.d.ts +67 -0
  190. package/dist/types/product/taskeditpopover/taskeditpopover.recipe.d.ts +3 -0
  191. package/dist/types/product/workspaceswitchermenu/index.d.ts +1 -0
  192. package/dist/types/product/workspaceswitchermenu/workspaceswitchermenu.d.ts +54 -0
  193. package/dist/types/product/workspaceswitchermenu/workspaceswitchermenu.recipe.d.ts +19 -0
  194. package/dist/types/tokens/contract.d.ts +13 -0
  195. package/dist/types/tokens/palette.d.ts +52 -0
  196. package/dist/types/tokens/semantic.d.ts +20 -0
  197. package/dist/workspaceswitchermenu.css +4 -0
  198. package/dist/workspaceswitchermenu.d.ts +7 -0
  199. package/dist/workspaceswitchermenu.layered.css +6 -0
  200. package/package.json +41 -1
package/dist/table.css CHANGED
@@ -11,8 +11,13 @@
11
11
  /* #465: 12px, not crisp's old 8px -- measured on a live header cell
12
12
  (padding: 0 12px) and independently on a body cell's text inset
13
13
  (getBoundingClientRect delta from the cell edge). Matches
14
- ColumnCalc's own already-correct 12px trigger inset. */
15
- & th, & td { position: relative; height: var(--crisp-size-tableRow); padding: 0 var(--crisp-space-3); border-bottom: 1px solid var(--crisp-border-subtle); border-inline-end: 1px solid var(--crisp-border-subtle); text-align: start; vertical-align: middle; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
14
+ ColumnCalc's own already-correct 12px trigger inset. */ /* #719: overflow: clip, not hidden -- both render the ellipsis
15
+ identically, but hidden still honours a programmatic scrollLeft
16
+ assignment (a screenshot tool, a browser extension) even though it
17
+ already blocks user-driven wheel/scrollbar input; clip leaves no
18
+ scroll position for anything to move, so the truncated text can
19
+ never be panned out of view. */
20
+ & th, & td { position: relative; height: var(--crisp-size-tableRow); padding: 0 var(--crisp-space-3); border-bottom: 1px solid var(--crisp-border-subtle); border-inline-end: 1px solid var(--crisp-border-subtle); text-align: start; vertical-align: middle; white-space: nowrap; overflow: clip; text-overflow: ellipsis; }
16
21
  /* #554: sticky on the vertical axis, mirroring RecordsTable's own
17
22
  `.crisp-recordstable-th`. z-index 2 sits above a plain body cell (auto)
18
23
  and below a sticky-column corner cell (DataTable's `th[data-sticky]`,
@@ -12,8 +12,13 @@
12
12
  /* #465: 12px, not crisp's old 8px -- measured on a live header cell
13
13
  (padding: 0 12px) and independently on a body cell's text inset
14
14
  (getBoundingClientRect delta from the cell edge). Matches
15
- ColumnCalc's own already-correct 12px trigger inset. */
16
- & th, & td { position: relative; height: var(--crisp-size-tableRow); padding: 0 var(--crisp-space-3); border-bottom: 1px solid var(--crisp-border-subtle); border-inline-end: 1px solid var(--crisp-border-subtle); text-align: start; vertical-align: middle; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
15
+ ColumnCalc's own already-correct 12px trigger inset. */ /* #719: overflow: clip, not hidden -- both render the ellipsis
16
+ identically, but hidden still honours a programmatic scrollLeft
17
+ assignment (a screenshot tool, a browser extension) even though it
18
+ already blocks user-driven wheel/scrollbar input; clip leaves no
19
+ scroll position for anything to move, so the truncated text can
20
+ never be panned out of view. */
21
+ & th, & td { position: relative; height: var(--crisp-size-tableRow); padding: 0 var(--crisp-space-3); border-bottom: 1px solid var(--crisp-border-subtle); border-inline-end: 1px solid var(--crisp-border-subtle); text-align: start; vertical-align: middle; white-space: nowrap; overflow: clip; text-overflow: ellipsis; }
17
22
  /* #554: sticky on the vertical axis, mirroring RecordsTable's own
18
23
  `.crisp-recordstable-th`. z-index 2 sits above a plain body cell (auto)
19
24
  and below a sticky-column corner cell (DataTable's `th[data-sticky]`,
@@ -0,0 +1,36 @@
1
+ .crisp-taskeditpopover { position: fixed; z-index: 70; pointer-events: auto; opacity: 1; transform: scale(1); transition: opacity 0.08s ease, transform 0.08s ease; @starting-style { opacity: 0; transform: scale(0.97) translateY(-4px); } }
2
+ .crisp-taskeditpopover {
3
+ display: flex; flex-direction: column; box-sizing: border-box; width: 800px; max-width: 92vw; border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.07); font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
4
+ & .crisp-taskeditpopover-header { display: flex; align-items: center; justify-content: space-between; gap: var(--crisp-space-2); height: 44px; box-sizing: border-box; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-3); border-bottom: 1px solid var(--crisp-border-subtle); }
5
+ & .crisp-taskeditpopover-heading { display: flex; align-items: center; gap: var(--crisp-space-1); font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
6
+ & .crisp-taskeditpopover-heading svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
7
+ & .crisp-taskeditpopover-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: var(--crisp-radius-md); background: none; color: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; }
8
+ & .crisp-taskeditpopover-close:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
9
+ & .crisp-taskeditpopover-body { display: flex; align-items: center; gap: var(--crisp-space-2-5); min-height: 52px; box-sizing: border-box; padding: var(--crisp-space-3); }
10
+ & .crisp-taskeditpopover-check { appearance: none; -webkit-appearance: none; box-sizing: border-box; flex-shrink: 0; margin: 0; width: 16px; height: 16px; border: none; border-radius: var(--crisp-radius-full); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 9%, transparent); cursor: pointer; }
11
+ & .crisp-taskeditpopover-check:hover { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 30%, transparent); }
12
+ & .crisp-taskeditpopover-check:checked { background: var(--crisp-bg-brand-solid) center / 10px no-repeat; box-shadow: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 6.5 5 9l4.5-5'/%3E%3C/svg%3E"); }
13
+ & .crisp-taskeditpopover-title { flex: 1; min-width: 0; border: none; border-radius: var(--crisp-radius-sm); outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
14
+ & .crisp-taskeditpopover-title:focus-visible { outline: 2px solid var(--crisp-stroke-focus-ring); outline-offset: 2px; }
15
+ & .crisp-taskeditpopover-footer { display: flex; align-items: center; justify-content: space-between; gap: var(--crisp-space-2); height: 44px; box-sizing: border-box; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-3); }
16
+ & .crisp-taskeditpopover-chips { display: flex; align-items: center; gap: var(--crisp-space-1); min-width: 0; }
17
+ & .crisp-taskeditpopover-chip { display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0; height: 28px; box-sizing: border-box; padding: 4px 8px 4px 6px; border: none; border-radius: var(--crisp-radius-md); background: none; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); font-family: inherit; font-size: 10px; white-space: nowrap; cursor: pointer; }
18
+ & .crisp-taskeditpopover-chip svg { flex-shrink: 0; }
19
+ & .crisp-taskeditpopover-chip:hover { background: var(--crisp-bg-raised); }
20
+ & .crisp-taskeditpopover-actions { display: flex; align-items: center; gap: var(--crisp-space-2); flex-shrink: 0; }
21
+ & .crisp-taskeditpopover-kebab { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; margin: 0; padding: 6px; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-primary); font-family: inherit; cursor: pointer; }
22
+ & .crisp-taskeditpopover-kebab:hover { background: var(--crisp-bg-raised); }
23
+ & .crisp-taskeditpopover-cancel { display: inline-flex; align-items: center; gap: 6px; height: 28px; box-sizing: border-box; padding: 4px 6px 4px 8px; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-primary); font-family: inherit; font-size: 10px; cursor: pointer; }
24
+ & .crisp-taskeditpopover-cancel:hover { background: var(--crisp-bg-raised); }
25
+ & .crisp-taskeditpopover-save { display: inline-flex; align-items: center; gap: 6px; height: 28px; box-sizing: border-box; padding: 4px 6px 4px 8px; border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-brand-solid); color: var(--crisp-fg-on-brand); font-family: inherit; font-size: 10px; cursor: pointer; }
26
+ & .crisp-taskeditpopover-save:hover { background: var(--crisp-bg-brand-solid-pressed); }
27
+ & .crisp-taskeditpopover-key { color: color-mix(in srgb, currentColor 55%, transparent); font-size: 10px; }
28
+ }
29
+
30
+ @media (prefers-reduced-motion: reduce) {
31
+ .crisp-taskeditpopover, .crisp-taskeditpopover * {
32
+ animation-duration: 0.01ms !important;
33
+ animation-iteration-count: 1 !important;
34
+ transition-duration: 0.01ms !important;
35
+ }
36
+ }
@@ -0,0 +1,7 @@
1
+ import type { RecipeFn } from "../core/types";
2
+
3
+ export interface TaskeditpopoverVariants {
4
+
5
+ }
6
+
7
+ export declare const taskeditpopoverRecipe: RecipeFn<{ }>;
@@ -0,0 +1,38 @@
1
+ @layer crisp-components {
2
+ .crisp-taskeditpopover { position: fixed; z-index: 70; pointer-events: auto; opacity: 1; transform: scale(1); transition: opacity 0.08s ease, transform 0.08s ease; @starting-style { opacity: 0; transform: scale(0.97) translateY(-4px); } }
3
+ .crisp-taskeditpopover {
4
+ display: flex; flex-direction: column; box-sizing: border-box; width: 800px; max-width: 92vw; border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.07); font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
5
+ & .crisp-taskeditpopover-header { display: flex; align-items: center; justify-content: space-between; gap: var(--crisp-space-2); height: 44px; box-sizing: border-box; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-3); border-bottom: 1px solid var(--crisp-border-subtle); }
6
+ & .crisp-taskeditpopover-heading { display: flex; align-items: center; gap: var(--crisp-space-1); font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
7
+ & .crisp-taskeditpopover-heading svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
8
+ & .crisp-taskeditpopover-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: var(--crisp-radius-md); background: none; color: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; }
9
+ & .crisp-taskeditpopover-close:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
10
+ & .crisp-taskeditpopover-body { display: flex; align-items: center; gap: var(--crisp-space-2-5); min-height: 52px; box-sizing: border-box; padding: var(--crisp-space-3); }
11
+ & .crisp-taskeditpopover-check { appearance: none; -webkit-appearance: none; box-sizing: border-box; flex-shrink: 0; margin: 0; width: 16px; height: 16px; border: none; border-radius: var(--crisp-radius-full); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 9%, transparent); cursor: pointer; }
12
+ & .crisp-taskeditpopover-check:hover { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 30%, transparent); }
13
+ & .crisp-taskeditpopover-check:checked { background: var(--crisp-bg-brand-solid) center / 10px no-repeat; box-shadow: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 6.5 5 9l4.5-5'/%3E%3C/svg%3E"); }
14
+ & .crisp-taskeditpopover-title { flex: 1; min-width: 0; border: none; border-radius: var(--crisp-radius-sm); outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
15
+ & .crisp-taskeditpopover-title:focus-visible { outline: 2px solid var(--crisp-stroke-focus-ring); outline-offset: 2px; }
16
+ & .crisp-taskeditpopover-footer { display: flex; align-items: center; justify-content: space-between; gap: var(--crisp-space-2); height: 44px; box-sizing: border-box; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-3); }
17
+ & .crisp-taskeditpopover-chips { display: flex; align-items: center; gap: var(--crisp-space-1); min-width: 0; }
18
+ & .crisp-taskeditpopover-chip { display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0; height: 28px; box-sizing: border-box; padding: 4px 8px 4px 6px; border: none; border-radius: var(--crisp-radius-md); background: none; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); font-family: inherit; font-size: 10px; white-space: nowrap; cursor: pointer; }
19
+ & .crisp-taskeditpopover-chip svg { flex-shrink: 0; }
20
+ & .crisp-taskeditpopover-chip:hover { background: var(--crisp-bg-raised); }
21
+ & .crisp-taskeditpopover-actions { display: flex; align-items: center; gap: var(--crisp-space-2); flex-shrink: 0; }
22
+ & .crisp-taskeditpopover-kebab { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; margin: 0; padding: 6px; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-primary); font-family: inherit; cursor: pointer; }
23
+ & .crisp-taskeditpopover-kebab:hover { background: var(--crisp-bg-raised); }
24
+ & .crisp-taskeditpopover-cancel { display: inline-flex; align-items: center; gap: 6px; height: 28px; box-sizing: border-box; padding: 4px 6px 4px 8px; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-primary); font-family: inherit; font-size: 10px; cursor: pointer; }
25
+ & .crisp-taskeditpopover-cancel:hover { background: var(--crisp-bg-raised); }
26
+ & .crisp-taskeditpopover-save { display: inline-flex; align-items: center; gap: 6px; height: 28px; box-sizing: border-box; padding: 4px 6px 4px 8px; border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-brand-solid); color: var(--crisp-fg-on-brand); font-family: inherit; font-size: 10px; cursor: pointer; }
27
+ & .crisp-taskeditpopover-save:hover { background: var(--crisp-bg-brand-solid-pressed); }
28
+ & .crisp-taskeditpopover-key { color: color-mix(in srgb, currentColor 55%, transparent); font-size: 10px; }
29
+ }
30
+
31
+ @media (prefers-reduced-motion: reduce) {
32
+ .crisp-taskeditpopover, .crisp-taskeditpopover * {
33
+ animation-duration: 0.01ms !important;
34
+ animation-iteration-count: 1 !important;
35
+ transition-duration: 0.01ms !important;
36
+ }
37
+ }
38
+ }
package/dist/tokens.css CHANGED
@@ -97,6 +97,19 @@
97
97
  --crisp-stroke-select-divider: #00000010;
98
98
  --crisp-fg-select-placeholder: #b0b3ba;
99
99
  --crisp-shadow-select: #0000001f;
100
+ --crisp-bg-tag-swatch1: #fff3cc;
101
+ --crisp-bg-tag-swatch2: #f4fbcb;
102
+ --crisp-bg-tag-swatch3: #fdf7c4;
103
+ --crisp-bg-tag-swatch4: #feecf3;
104
+ --crisp-bg-tag-swatch5: #e0fced;
105
+ --crisp-bg-tag-swatch6: #ddf7ff;
106
+ --crisp-bg-tag-swatch7: #f6f7f7;
107
+ --crisp-bg-tag-swatch8: #ffebeb;
108
+ --crisp-bg-tag-swatch9: #feeee1;
109
+ --crisp-bg-tag-swatch10: #e5eeff;
110
+ --crisp-bg-tag-swatch11: #f5f0ff;
111
+ --crisp-bg-tag-swatch12: #fdedff;
112
+ --crisp-fg-tag-swatch: #000000;
100
113
  }
101
114
 
102
115
  [data-theme="dark"] {
@@ -170,6 +183,19 @@
170
183
  --crisp-stroke-select-divider: #ffffff17;
171
184
  --crisp-fg-select-placeholder: #868b94;
172
185
  --crisp-shadow-select: #000000cc;
186
+ --crisp-bg-tag-swatch1: #fff3cc;
187
+ --crisp-bg-tag-swatch2: #f4fbcb;
188
+ --crisp-bg-tag-swatch3: #fdf7c4;
189
+ --crisp-bg-tag-swatch4: #feecf3;
190
+ --crisp-bg-tag-swatch5: #e0fced;
191
+ --crisp-bg-tag-swatch6: #ddf7ff;
192
+ --crisp-bg-tag-swatch7: #f6f7f7;
193
+ --crisp-bg-tag-swatch8: #ffebeb;
194
+ --crisp-bg-tag-swatch9: #feeee1;
195
+ --crisp-bg-tag-swatch10: #e5eeff;
196
+ --crisp-bg-tag-swatch11: #f5f0ff;
197
+ --crisp-bg-tag-swatch12: #fdedff;
198
+ --crisp-fg-tag-swatch: #000000;
173
199
  }
174
200
 
175
201
  :root {
package/dist/tokens.json CHANGED
@@ -70,7 +70,20 @@
70
70
  "strokeSelectInvalid": "#fa342c",
71
71
  "strokeSelectDivider": "#00000010",
72
72
  "fgSelectPlaceholder": "#b0b3ba",
73
- "shadowSelect": "#0000001f"
73
+ "shadowSelect": "#0000001f",
74
+ "bgTagSwatch1": "#fff3cc",
75
+ "bgTagSwatch2": "#f4fbcb",
76
+ "bgTagSwatch3": "#fdf7c4",
77
+ "bgTagSwatch4": "#feecf3",
78
+ "bgTagSwatch5": "#e0fced",
79
+ "bgTagSwatch6": "#ddf7ff",
80
+ "bgTagSwatch7": "#f6f7f7",
81
+ "bgTagSwatch8": "#ffebeb",
82
+ "bgTagSwatch9": "#feeee1",
83
+ "bgTagSwatch10": "#e5eeff",
84
+ "bgTagSwatch11": "#f5f0ff",
85
+ "bgTagSwatch12": "#fdedff",
86
+ "fgTagSwatch": "#000000"
74
87
  },
75
88
  "dark": {
76
89
  "bgBrandSolid": "#0298d9",
@@ -142,7 +155,20 @@
142
155
  "strokeSelectInvalid": "#ff6e60",
143
156
  "strokeSelectDivider": "#ffffff17",
144
157
  "fgSelectPlaceholder": "#868b94",
145
- "shadowSelect": "#000000cc"
158
+ "shadowSelect": "#000000cc",
159
+ "bgTagSwatch1": "#fff3cc",
160
+ "bgTagSwatch2": "#f4fbcb",
161
+ "bgTagSwatch3": "#fdf7c4",
162
+ "bgTagSwatch4": "#feecf3",
163
+ "bgTagSwatch5": "#e0fced",
164
+ "bgTagSwatch6": "#ddf7ff",
165
+ "bgTagSwatch7": "#f6f7f7",
166
+ "bgTagSwatch8": "#ffebeb",
167
+ "bgTagSwatch9": "#feeee1",
168
+ "bgTagSwatch10": "#e5eeff",
169
+ "bgTagSwatch11": "#f5f0ff",
170
+ "bgTagSwatch12": "#fdedff",
171
+ "fgTagSwatch": "#000000"
146
172
  }
147
173
  },
148
174
  "palette": {
@@ -212,7 +238,20 @@
212
238
  "selectInvalidStroke": "#fa342c",
213
239
  "selectDivider": "#00000010",
214
240
  "selectPlaceholder": "#b0b3ba",
215
- "selectShadow": "#0000001f"
241
+ "selectShadow": "#0000001f",
242
+ "tagSwatch1": "#fff3cc",
243
+ "tagSwatch2": "#f4fbcb",
244
+ "tagSwatch3": "#fdf7c4",
245
+ "tagSwatch4": "#feecf3",
246
+ "tagSwatch5": "#e0fced",
247
+ "tagSwatch6": "#ddf7ff",
248
+ "tagSwatch7": "#f6f7f7",
249
+ "tagSwatch8": "#ffebeb",
250
+ "tagSwatch9": "#feeee1",
251
+ "tagSwatch10": "#e5eeff",
252
+ "tagSwatch11": "#f5f0ff",
253
+ "tagSwatch12": "#fdedff",
254
+ "tagSwatchInk": "#000000"
216
255
  },
217
256
  "dark": {
218
257
  "gray00": "#0a0a0a",
@@ -280,7 +319,20 @@
280
319
  "selectInvalidStroke": "#ff6e60",
281
320
  "selectDivider": "#ffffff17",
282
321
  "selectPlaceholder": "#868b94",
283
- "selectShadow": "#000000cc"
322
+ "selectShadow": "#000000cc",
323
+ "tagSwatch1": "#fff3cc",
324
+ "tagSwatch2": "#f4fbcb",
325
+ "tagSwatch3": "#fdf7c4",
326
+ "tagSwatch4": "#feecf3",
327
+ "tagSwatch5": "#e0fced",
328
+ "tagSwatch6": "#ddf7ff",
329
+ "tagSwatch7": "#f6f7f7",
330
+ "tagSwatch8": "#ffebeb",
331
+ "tagSwatch9": "#feeee1",
332
+ "tagSwatch10": "#e5eeff",
333
+ "tagSwatch11": "#f5f0ff",
334
+ "tagSwatch12": "#fdedff",
335
+ "tagSwatchInk": "#000000"
284
336
  }
285
337
  },
286
338
  "space": {
@@ -3,7 +3,15 @@ export type BreadcrumbItem = {
3
3
  label: React.ReactNode;
4
4
  href?: string;
5
5
  icon?: React.ReactNode;
6
- onClick?: () => void;
6
+ /** Called on a plain left click. With `href` also set, this fires on the
7
+ * real `<a>` rather than replacing it with a `<button>` -- call
8
+ * `event.preventDefault()` yourself for client-side routing (e.g.
9
+ * react-router's `navigate()`), the same division of labour `StatList`'s
10
+ * own `href`+`onClick` pair already uses. Right-click, middle-click,
11
+ * ctrl/cmd-click and the status-bar hover keep working since the
12
+ * element stays a real anchor. Without `href`, this renders a plain
13
+ * button (unchanged). */
14
+ onClick?: (event: React.MouseEvent<HTMLAnchorElement | HTMLButtonElement>) => void;
7
15
  };
8
16
  export type BreadcrumbProps = React.ComponentPropsWithoutRef<"nav"> & {
9
17
  items: BreadcrumbItem[];
@@ -15,6 +15,7 @@ export declare const Button: React.ForwardRefExoticComponent<Omit<React.Detailed
15
15
  };
16
16
  readonly size: {
17
17
  readonly sm: string;
18
+ readonly xs: string;
18
19
  readonly md: string;
19
20
  readonly lg: string;
20
21
  };
@@ -36,6 +37,7 @@ export declare const Button: React.ForwardRefExoticComponent<Omit<React.Detailed
36
37
  };
37
38
  readonly size: {
38
39
  readonly sm: string;
40
+ readonly xs: string;
39
41
  readonly md: string;
40
42
  readonly lg: string;
41
43
  };
@@ -99,6 +99,15 @@ declare const spec: {
99
99
  readonly fontSize: `var(--${string})`;
100
100
  readonly borderRadius: `var(--${string})`;
101
101
  };
102
+ readonly xs: {
103
+ readonly height: "20px";
104
+ readonly paddingInline: `var(--${string})`;
105
+ readonly fontSize: `var(--${string})`;
106
+ readonly lineHeight: "16px";
107
+ readonly letterSpacing: "normal";
108
+ readonly borderRadius: `var(--${string})`;
109
+ readonly gap: `var(--${string})`;
110
+ };
102
111
  readonly md: {
103
112
  readonly decls: {
104
113
  readonly height: "28px";
@@ -172,6 +181,7 @@ declare const config: import("../..").RecipeConfig<{
172
181
  };
173
182
  readonly size: {
174
183
  readonly sm: string;
184
+ readonly xs: string;
175
185
  readonly md: string;
176
186
  readonly lg: string;
177
187
  };
@@ -193,6 +203,7 @@ export declare const buttonRecipe: import("../..").RecipeFn<{
193
203
  };
194
204
  readonly size: {
195
205
  readonly sm: string;
206
+ readonly xs: string;
196
207
  readonly md: string;
197
208
  readonly lg: string;
198
209
  };
@@ -214,6 +225,7 @@ export declare const buttonRecipe: import("../..").RecipeFn<{
214
225
  };
215
226
  readonly size: {
216
227
  readonly sm: string;
228
+ readonly xs: string;
217
229
  readonly md: string;
218
230
  readonly lg: string;
219
231
  };
@@ -22,7 +22,7 @@ declare const spec: {
22
22
  readonly selector: "& .crisp-chip-label";
23
23
  readonly decls: {
24
24
  readonly minWidth: 0;
25
- readonly overflow: "hidden";
25
+ readonly overflow: "clip";
26
26
  readonly textOverflow: "ellipsis";
27
27
  readonly whiteSpace: "nowrap";
28
28
  readonly display: "block";
@@ -87,6 +87,14 @@ export type DataTableColumn<T> = {
87
87
  resizable?: boolean;
88
88
  /** Tone overrides for `status`/`tags` values (else a stable colour per value). */
89
89
  tones?: Record<string, string>;
90
+ /**
91
+ * One of Attio's 12 fixed tag/option colours (your-moon/crisp#998), 1-12,
92
+ * per `status`/`tags` value -- renders that value's chip as a filled
93
+ * pill from Attio's own enumerable palette (measured: flat black text,
94
+ * no ring) instead of `tones`'/`toneFor`'s semantic 7-tone family. Wins
95
+ * over `tones` for a value present in both.
96
+ */
97
+ swatches?: Record<string, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12>;
90
98
  /** `type: "date"`/`"datetime"` only: render this cell in Attio's own
91
99
  * measured overdue/danger red (`fgDanger`, `#eb3b3b` — the same token
92
100
  * `TasksTable`'s own overdue due-date already uses, crisp#462) when the
@@ -29,6 +29,9 @@ export type DatePickerFieldProps = Omit<React.ComponentPropsWithoutRef<"div">, "
29
29
  placeholder?: string;
30
30
  /** `default` = outlined trigger; `ghost` = transparent (for table cells). */
31
31
  variant?: "default" | "ghost";
32
+ /** `full` (default) fills its container, like `Select`'s own default.
33
+ * `auto` sizes to content, the field's only behaviour before crisp#980. */
34
+ width?: "full" | "auto";
32
35
  /** Formats the trigger label (default: e.g. "Jun 3, 2026"). */
33
36
  format?: (date: Date) => string;
34
37
  /**
@@ -51,7 +54,7 @@ export type DatePickerFieldProps = Omit<React.ComponentPropsWithoutRef<"div">, "
51
54
  * popover. This is what `DatePicker` used to be; `DatePicker` is now
52
55
  * seed-design's bare calendar, and this composes it.
53
56
  */
54
- export declare function DatePickerField({ value, defaultValue, onValueChange, onChange, placeholder: placeholderProp, variant, format, clearable, clearLabel: clearLabelProp, presets, calendarProps, "aria-label": ariaLabel, className, ...rest }: DatePickerFieldProps): React.JSX.Element;
57
+ export declare function DatePickerField({ value, defaultValue, onValueChange, onChange, placeholder: placeholderProp, variant, width, format, clearable, clearLabel: clearLabelProp, presets, calendarProps, "aria-label": ariaLabel, className, ...rest }: DatePickerFieldProps): React.JSX.Element;
55
58
  export declare namespace DatePickerField {
56
59
  var displayName: string;
57
60
  }
@@ -1,5 +1,20 @@
1
- declare const config: import("../..").RecipeConfig<{}>;
2
- export declare const datepickerfieldRecipe: import("../..").RecipeFn<{}> & {
3
- config: import("../..").RecipeConfig<{}>;
1
+ declare const config: import("../..").RecipeConfig<{
2
+ width: {
3
+ full: string;
4
+ auto: string;
5
+ };
6
+ }>;
7
+ export declare const datepickerfieldRecipe: import("../..").RecipeFn<{
8
+ width: {
9
+ full: string;
10
+ auto: string;
11
+ };
12
+ }> & {
13
+ config: import("../..").RecipeConfig<{
14
+ width: {
15
+ full: string;
16
+ auto: string;
17
+ };
18
+ }>;
4
19
  };
5
20
  export default config;
@@ -4,8 +4,19 @@ export type MenuProps = {
4
4
  trigger: React.ReactElement;
5
5
  children: React.ReactNode;
6
6
  /** Align the menu to the trigger's inline `start` or `end` edge — the left
7
- * edge in an LTR document, the right one in RTL. */
7
+ * edge in an LTR document, the right one in RTL. Ignored when
8
+ * `placement="submenu"`, which decides its own side (see there). */
8
9
  align?: "start" | "end";
10
+ /**
11
+ * `"menu"` (default): a dropdown below/above the trigger, `placeFloating`'s
12
+ * own placement. `"submenu"` (crisp#616): a cascade BESIDE the trigger —
13
+ * give it a `MenuItem` (with a `trailingIcon` chevron) as `trigger`, nested
14
+ * inside an outer `Menu`'s children, the way Attio's own "Notifications ›"
15
+ * row opens "Connect Slack workspace". Reuses the same outside-click/Escape
16
+ * machinery below (registered as its own floating layer), so it composes
17
+ * with the outer Menu for free.
18
+ */
19
+ placement?: "menu" | "submenu";
9
20
  /** Controlled open state. Omit to let Menu manage it (see defaultOpen). */
10
21
  open?: boolean;
11
22
  /** Initially open, when uncontrolled. */
@@ -31,11 +42,11 @@ export type MenuProps = {
31
42
  * typeahead, Enter/Space select, Esc closes and returns focus to the trigger);
32
43
  * closes on outside click. Flips up / right-aligns when space is tight.
33
44
  */
34
- export declare function Menu({ trigger, children, align, open: openProp, defaultOpen, onOpenChange, className, contentClassName, "aria-label": ariaLabel, }: MenuProps): React.JSX.Element;
45
+ export declare function Menu({ trigger, children, align, placement, open: openProp, defaultOpen, onOpenChange, className, contentClassName, "aria-label": ariaLabel, }: MenuProps): React.JSX.Element;
35
46
  export declare namespace Menu {
36
47
  var displayName: string;
37
48
  }
38
- export type MenuItemProps = {
49
+ export type MenuItemProps = Omit<React.ComponentPropsWithoutRef<"button">, "children" | "disabled" | "onSelect"> & {
39
50
  children: React.ReactNode;
40
51
  icon?: React.ReactNode;
41
52
  shortcut?: string;
@@ -45,16 +56,48 @@ export type MenuItemProps = {
45
56
  * `count` prop uses, not bare text.
46
57
  */
47
58
  count?: React.ReactNode;
59
+ /**
60
+ * A trailing indicator after everything else — a submenu chevron
61
+ * (crisp#616: give this item a nested `<Menu placement="submenu">` as its
62
+ * `trigger`, with a `ChevronRight` here). Plain content, not a second
63
+ * `icon` slot — nothing else currently needs two.
64
+ */
65
+ trailingIcon?: React.ReactNode;
48
66
  danger?: boolean;
49
67
  disabled?: boolean;
50
68
  onSelect?: () => void;
51
69
  /** Keep the menu open after selecting (default closes). */
52
70
  closeOnSelect?: boolean;
53
71
  };
54
- export declare function MenuItem({ children, icon, shortcut, count, danger, disabled, onSelect, closeOnSelect, }: MenuItemProps): React.JSX.Element;
55
- export declare namespace MenuItem {
56
- var displayName: string;
57
- }
72
+ /**
73
+ * A row inside a `Menu`. Forwards its ref and spreads unrecognised button
74
+ * props (crisp#616) so it can double as another `Menu`'s own `trigger` —
75
+ * `Menu` clones its trigger with `ref`/`onClick`/`aria-*`, which a plain
76
+ * function component would silently drop.
77
+ */
78
+ export declare const MenuItem: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref">, "children" | "disabled" | "onSelect"> & {
79
+ children: React.ReactNode;
80
+ icon?: React.ReactNode;
81
+ shortcut?: string;
82
+ /**
83
+ * A trailing count badge (crisp#875) — e.g. a saved-filter item showing
84
+ * how many rows match. Same measured neutral chip `ToolbarTool`'s own
85
+ * `count` prop uses, not bare text.
86
+ */
87
+ count?: React.ReactNode;
88
+ /**
89
+ * A trailing indicator after everything else — a submenu chevron
90
+ * (crisp#616: give this item a nested `<Menu placement="submenu">` as its
91
+ * `trigger`, with a `ChevronRight` here). Plain content, not a second
92
+ * `icon` slot — nothing else currently needs two.
93
+ */
94
+ trailingIcon?: React.ReactNode;
95
+ danger?: boolean;
96
+ disabled?: boolean;
97
+ onSelect?: () => void;
98
+ /** Keep the menu open after selecting (default closes). */
99
+ closeOnSelect?: boolean;
100
+ } & React.RefAttributes<HTMLButtonElement>>;
58
101
  export type MenuCheckboxItemProps = {
59
102
  children: React.ReactNode;
60
103
  checked?: boolean;
@@ -4,6 +4,15 @@ export type MultiSelectOption = {
4
4
  label: string;
5
5
  /** Chip colour tone; falls back to a deterministic pastel per value. */
6
6
  tone?: string;
7
+ /**
8
+ * One of Attio's 12 fixed tag/option colours (your-moon/crisp#998), 1-12
9
+ * -- measured off Attio's own multi-select field option pills (flat
10
+ * black text, no ring, 7px radius). Wins over `tone` when both are set:
11
+ * `tone` is crisp's own semantic 7-tone chip family (with a ring), this
12
+ * is Attio's separate, workspace-admin-assigned enumerable palette,
13
+ * reproduced verbatim rather than mapped onto the existing tones.
14
+ */
15
+ swatch?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
7
16
  /**
8
17
  * Group heading, rendered above this option (#343). A header renders once
9
18
  * per run of consecutive options sharing the same `group` — like native
@@ -11,6 +11,16 @@ export type SelectOption = {
11
11
  keywords?: string;
12
12
  /** A status colour dot shown before the label (status/select fields). */
13
13
  color?: string;
14
+ /**
15
+ * One of Attio's 12 fixed tag/option colours (your-moon/crisp#998),
16
+ * 1-12 -- renders the label itself as a filled pill (measured: 22px,
17
+ * 7px radius, flat black text) rather than the small `color` dot beside
18
+ * it. The two are mutually exclusive; `swatch` wins if both are set.
19
+ * Distinct from `color`: that one is an arbitrary CSS value for a
20
+ * status-style dot, this is Attio's own enumerable, workspace-admin-
21
+ * assigned palette, reproduced verbatim.
22
+ */
23
+ swatch?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
14
24
  disabled?: boolean;
15
25
  /**
16
26
  * Group heading, rendered above this option (#343). A header renders once
@@ -15,10 +15,11 @@ import * as React from "react";
15
15
  * `Dialog` was rendering offset by the dialog's own box instead of anchored
16
16
  * to its trigger.
17
17
  *
18
- * Every caller renders this conditionally on its own `open` state, which
19
- * starts `false` and is driven only by client interaction — never a prop a
20
- * fixture sets true at mount (unlike Dialog/Drawer/Command) — so this never
21
- * touches `document` during SSR, the same safety Tooltip already had.
18
+ * Every caller renders this conditionally on its own `open` state. A fixture
19
+ * CAN set that true at mount (crisp#964 needs exactly that, to give Menu's
20
+ * roving-tabindex guard something to inspect), so this checks for `window`
21
+ * itself rather than assuming the caller never does — the same guard
22
+ * `@zag-js/react`'s own `Portal` uses for the identical reason.
22
23
  *
23
24
  * `sourceRef` is the caller's own root — still in its original DOM position,
24
25
  * never portaled — used to carry a `data-theme` set on some ancestor of it
@@ -36,4 +37,4 @@ import * as React from "react";
36
37
  export declare function FloatingPortal({ children, sourceRef, }: {
37
38
  children: React.ReactElement;
38
39
  sourceRef: React.RefObject<HTMLElement | null>;
39
- }): React.ReactPortal;
40
+ }): React.ReactElement;
@@ -9,7 +9,7 @@ export { hasNestedFloatingLayer, hasOpenFloatingLayer, isInsideLaterFloatingLaye
9
9
  export { formValueStyle } from "./form-value";
10
10
  export { type CrispComponentDefaults, type CrispMessages, CrispMessagesProvider, useCrispComponentDefaults, useCrispMessage, useCrispMessages, } from "./i18n";
11
11
  export { type MentionAnchor, type MentionMatch, matchMentionTrigger, } from "./mention";
12
- export { type FloatingAlign, type PlaceFloatingOptions, placeFloating, } from "./place-floating";
12
+ export { type FloatingAlign, type PlacedSubmenu, type PlaceFloatingOptions, type PlaceSubmenuOptions, placeFloating, placeSubmenu, } from "./place-floating";
13
13
  export { Primitive } from "./primitive";
14
14
  export { resolveRecipe } from "./resolve";
15
15
  export * from "./rtl";
@@ -38,3 +38,40 @@ export type PlacedFloating = {
38
38
  * against would still be physical.
39
39
  */
40
40
  export declare function placeFloating({ rect, align, gap, flipBelow, anchor, }: PlaceFloatingOptions): PlacedFloating;
41
+ export type PlaceSubmenuOptions = {
42
+ /** The item's own box that opens the submenu (already shifted up by the
43
+ * surface's own top padding, so the FIRST row of the submenu lines up
44
+ * with the item rather than the submenu's outer edge). */
45
+ rect: DOMRect;
46
+ /** The submenu surface's own rendered size (it's already in the DOM,
47
+ * just not yet positioned, when `Menu` calls this — a real measurement,
48
+ * not a guessed threshold). */
49
+ size: {
50
+ width: number;
51
+ height: number;
52
+ };
53
+ /** Gap between the item and the submenu. */
54
+ gap: number;
55
+ anchor?: Element | null;
56
+ };
57
+ export type PlacedSubmenu = {
58
+ style: React.CSSProperties;
59
+ /** Which side it opened on, in logical terms — for the caller's own
60
+ * animation-origin hint (reuses the same vocabulary `align` does). */
61
+ align: FloatingAlign;
62
+ /** True when it flipped to a bottom anchor instead of the item's top. */
63
+ up: boolean;
64
+ };
65
+ /**
66
+ * Where a cascading submenu goes, BESIDE the item that opens it — not below
67
+ * it, the way `placeFloating`'s own dropdown does. Opens toward the inline
68
+ * end by default (further into the reading direction) and flips to the
69
+ * inline start when the surface's measured width doesn't fit there.
70
+ *
71
+ * Live-measured on Attio's own object-page "…" menu (crisp#616): the
72
+ * Notifications submenu sits with NO gap against the item's opposite edge
73
+ * (its own edge lines up exactly with the item's), so callers pass `gap: 0`
74
+ * for this specific cascade rather than the 4px a dropdown uses against its
75
+ * trigger.
76
+ */
77
+ export declare function placeSubmenu({ rect, size, gap, anchor, }: PlaceSubmenuOptions): PlacedSubmenu;
@@ -68,6 +68,7 @@ export * from "./components/wheelpicker";
68
68
  export * from "./core";
69
69
  export * from "./product/activityfeed";
70
70
  export * from "./product/appshell";
71
+ export * from "./product/assigneepicker";
71
72
  export * from "./product/authshell";
72
73
  export * from "./product/board";
73
74
  export * from "./product/command";
@@ -81,20 +82,27 @@ export * from "./product/inbox";
81
82
  export * from "./product/listpage";
82
83
  export * from "./product/memberssettings";
83
84
  export * from "./product/navitem";
85
+ export * from "./product/notesgallery";
84
86
  export * from "./product/notificationssettings";
87
+ export * from "./product/objectpagemenu";
85
88
  export * from "./product/objectsettings";
86
89
  export * from "./product/onboarding";
87
90
  export * from "./product/recordpage";
88
91
  export * from "./product/recordpanel";
92
+ export * from "./product/recordpicker";
89
93
  export * from "./product/richtext";
90
94
  export * from "./product/savedviews";
91
95
  export * from "./product/settingssection";
92
96
  export * from "./product/settingsshell";
97
+ export * from "./product/share";
98
+ export * from "./product/shortcutssheet";
93
99
  export * from "./product/sidebar";
94
100
  export * from "./product/statlist";
101
+ export * from "./product/taskeditpopover";
95
102
  export * from "./product/tasklist";
96
103
  export * from "./product/themepicker";
97
104
  export * from "./product/trialbanner";
98
105
  export * from "./product/viewtoggle";
99
106
  export * from "./product/workspacegeneralsettings";
107
+ export * from "./product/workspaceswitchermenu";
100
108
  export * from "./tokens";