@crisp-ui-kit/crisp 0.57.1 → 0.57.3

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 (277) hide show
  1. package/dist/authshell.css +9 -4
  2. package/dist/authshell.layered.css +9 -4
  3. package/dist/badge.css +3 -3
  4. package/dist/badge.layered.css +3 -3
  5. package/dist/board.css +28 -8
  6. package/dist/board.layered.css +28 -8
  7. package/dist/bottomsheet.css +26 -0
  8. package/dist/bottomsheet.d.ts +7 -0
  9. package/dist/bottomsheet.layered.css +28 -0
  10. package/dist/button.css +10 -6
  11. package/dist/button.d.ts +2 -2
  12. package/dist/button.layered.css +10 -6
  13. package/dist/checkbox.css +7 -3
  14. package/dist/checkbox.layered.css +7 -3
  15. package/dist/chip.css +16 -1
  16. package/dist/chip.d.ts +3 -1
  17. package/dist/chip.layered.css +16 -1
  18. package/dist/chipgroup.css +5 -0
  19. package/dist/chipgroup.d.ts +7 -0
  20. package/dist/chipgroup.layered.css +7 -0
  21. package/dist/cjs/components/badge/badge.recipe.js +22 -8
  22. package/dist/cjs/components/bottomsheet/bottomsheet.js +90 -0
  23. package/dist/cjs/components/bottomsheet/bottomsheet.recipe.js +77 -0
  24. package/dist/cjs/components/bottomsheet/index.js +9 -0
  25. package/dist/cjs/components/breadcrumb/breadcrumb.js +1 -1
  26. package/dist/cjs/components/button/button.recipe.js +67 -15
  27. package/dist/cjs/components/checkbox/checkbox.recipe.js +61 -9
  28. package/dist/cjs/components/chip/chip.js +14 -2
  29. package/dist/cjs/components/chip/chip.recipe.js +72 -2
  30. package/dist/cjs/components/chipgroup/chipgroup.js +51 -0
  31. package/dist/cjs/components/chipgroup/chipgroup.recipe.js +36 -0
  32. package/dist/cjs/components/chipgroup/index.js +7 -0
  33. package/dist/cjs/components/datatable/datatable.js +5 -1
  34. package/dist/cjs/components/datatable/datatable.recipe.js +21 -6
  35. package/dist/cjs/components/datepickerfield/datepickerfield.js +2 -2
  36. package/dist/cjs/components/datepickerfield/datepickerfield.recipe.js +16 -3
  37. package/dist/cjs/components/dialog/dialog.recipe.js +21 -10
  38. package/dist/cjs/components/emptystate/emptystate.recipe.js +7 -2
  39. package/dist/cjs/components/fileupload/fileupload.js +21 -4
  40. package/dist/cjs/components/input/index.js +2 -1
  41. package/dist/cjs/components/input/input.js +31 -1
  42. package/dist/cjs/components/input/input.recipe.js +16 -9
  43. package/dist/cjs/components/menu/menu.js +18 -2
  44. package/dist/cjs/components/menu/menu.recipe.js +21 -7
  45. package/dist/cjs/components/menusheet/index.js +9 -0
  46. package/dist/cjs/components/menusheet/menusheet.js +133 -0
  47. package/dist/cjs/components/menusheet/menusheet.recipe.js +103 -0
  48. package/dist/cjs/components/multiselect/multiselect.js +1 -1
  49. package/dist/cjs/components/multiselect/multiselect.recipe.js +33 -9
  50. package/dist/cjs/components/select/select.js +1 -1
  51. package/dist/cjs/components/select/select.recipe.js +38 -12
  52. package/dist/cjs/components/snackbar/index.js +8 -0
  53. package/dist/cjs/components/snackbar/snackbar.js +121 -0
  54. package/dist/cjs/components/snackbar/snackbar.recipe.js +71 -0
  55. package/dist/cjs/components/table/table.recipe.js +7 -1
  56. package/dist/cjs/components/tabletoolbar/tabletoolbar.chrome.js +7 -2
  57. package/dist/cjs/components/tabletoolbar/tabletoolbar.js +37 -12
  58. package/dist/cjs/components/tabs/tabs.js +10 -4
  59. package/dist/cjs/components/tabs/tabs.recipe.js +23 -6
  60. package/dist/cjs/components/textarea/textarea.recipe.js +11 -8
  61. package/dist/cjs/core/floating-portal.js +7 -4
  62. package/dist/cjs/index.js +7 -0
  63. package/dist/cjs/product/authshell/authshell.recipe.js +5 -1
  64. package/dist/cjs/product/command/command.recipe.js +4 -1
  65. package/dist/cjs/product/comments/comments.js +7 -2
  66. package/dist/cjs/product/comments/comments.recipe.js +25 -7
  67. package/dist/cjs/product/inbox/inbox.js +11 -3
  68. package/dist/cjs/product/memberssettings/index.js +6 -0
  69. package/dist/cjs/product/memberssettings/memberssettings.js +99 -0
  70. package/dist/cjs/product/memberssettings/memberssettings.recipe.js +83 -0
  71. package/dist/cjs/product/notificationssettings/index.js +5 -0
  72. package/dist/cjs/product/notificationssettings/notificationssettings.js +19 -0
  73. package/dist/cjs/product/notificationssettings/notificationssettings.recipe.js +44 -0
  74. package/dist/cjs/product/recordpage/index.js +2 -1
  75. package/dist/cjs/product/recordpage/recordpage.js +106 -9
  76. package/dist/cjs/product/recordpage/recordpage.recipe.js +68 -6
  77. package/dist/cjs/product/workspacegeneralsettings/index.js +5 -0
  78. package/dist/cjs/product/workspacegeneralsettings/workspacegeneralsettings.js +21 -0
  79. package/dist/cjs/product/workspacegeneralsettings/workspacegeneralsettings.recipe.js +51 -0
  80. package/dist/cjs/tokens/contract.js +1 -0
  81. package/dist/cjs/tokens/elevation.js +8 -5
  82. package/dist/cjs/tokens/palette.js +28 -8
  83. package/dist/cjs/tokens/scale.js +44 -2
  84. package/dist/cjs/tokens/semantic.js +2 -0
  85. package/dist/columncalc.css +15 -7
  86. package/dist/columncalc.layered.css +15 -7
  87. package/dist/command.css +23 -19
  88. package/dist/command.layered.css +23 -19
  89. package/dist/comments.css +28 -19
  90. package/dist/comments.d.ts +2 -2
  91. package/dist/comments.layered.css +28 -19
  92. package/dist/datatable.css +171 -71
  93. package/dist/datatable.layered.css +171 -71
  94. package/dist/datepicker.css +13 -41
  95. package/dist/datepicker.layered.css +13 -41
  96. package/dist/datepickerfield.css +12 -3
  97. package/dist/datepickerfield.d.ts +2 -2
  98. package/dist/datepickerfield.layered.css +12 -3
  99. package/dist/dialog.css +12 -7
  100. package/dist/dialog.layered.css +12 -7
  101. package/dist/emptystate.css +5 -3
  102. package/dist/emptystate.layered.css +5 -3
  103. package/dist/esm/components/badge/badge.recipe.js +22 -8
  104. package/dist/esm/components/bottomsheet/bottomsheet.js +52 -0
  105. package/dist/esm/components/bottomsheet/bottomsheet.recipe.js +74 -0
  106. package/dist/esm/components/bottomsheet/index.js +2 -0
  107. package/dist/esm/components/breadcrumb/breadcrumb.js +1 -1
  108. package/dist/esm/components/button/button.recipe.js +68 -16
  109. package/dist/esm/components/checkbox/checkbox.recipe.js +61 -9
  110. package/dist/esm/components/chip/chip.js +14 -2
  111. package/dist/esm/components/chip/chip.recipe.js +72 -2
  112. package/dist/esm/components/chipgroup/chipgroup.js +15 -0
  113. package/dist/esm/components/chipgroup/chipgroup.recipe.js +33 -0
  114. package/dist/esm/components/chipgroup/index.js +2 -0
  115. package/dist/esm/components/datatable/datatable.js +5 -1
  116. package/dist/esm/components/datatable/datatable.recipe.js +21 -6
  117. package/dist/esm/components/datepickerfield/datepickerfield.js +2 -2
  118. package/dist/esm/components/datepickerfield/datepickerfield.recipe.js +16 -3
  119. package/dist/esm/components/dialog/dialog.recipe.js +22 -11
  120. package/dist/esm/components/emptystate/emptystate.recipe.js +7 -2
  121. package/dist/esm/components/fileupload/fileupload.js +20 -5
  122. package/dist/esm/components/input/index.js +1 -1
  123. package/dist/esm/components/input/input.js +30 -0
  124. package/dist/esm/components/input/input.recipe.js +17 -10
  125. package/dist/esm/components/menu/menu.js +18 -2
  126. package/dist/esm/components/menu/menu.recipe.js +21 -7
  127. package/dist/esm/components/menusheet/index.js +2 -0
  128. package/dist/esm/components/menusheet/menusheet.js +95 -0
  129. package/dist/esm/components/menusheet/menusheet.recipe.js +100 -0
  130. package/dist/esm/components/multiselect/multiselect.js +1 -1
  131. package/dist/esm/components/multiselect/multiselect.recipe.js +33 -9
  132. package/dist/esm/components/select/select.js +1 -1
  133. package/dist/esm/components/select/select.recipe.js +38 -12
  134. package/dist/esm/components/snackbar/index.js +2 -0
  135. package/dist/esm/components/snackbar/snackbar.js +84 -0
  136. package/dist/esm/components/snackbar/snackbar.recipe.js +68 -0
  137. package/dist/esm/components/table/table.recipe.js +7 -1
  138. package/dist/esm/components/tabletoolbar/tabletoolbar.chrome.js +7 -2
  139. package/dist/esm/components/tabletoolbar/tabletoolbar.js +37 -12
  140. package/dist/esm/components/tabs/tabs.js +10 -4
  141. package/dist/esm/components/tabs/tabs.recipe.js +23 -6
  142. package/dist/esm/components/textarea/textarea.recipe.js +12 -9
  143. package/dist/esm/core/floating-portal.js +7 -4
  144. package/dist/esm/index.js +7 -0
  145. package/dist/esm/product/authshell/authshell.recipe.js +5 -1
  146. package/dist/esm/product/command/command.recipe.js +4 -1
  147. package/dist/esm/product/comments/comments.js +7 -2
  148. package/dist/esm/product/comments/comments.recipe.js +25 -7
  149. package/dist/esm/product/inbox/inbox.js +11 -3
  150. package/dist/esm/product/memberssettings/index.js +1 -0
  151. package/dist/esm/product/memberssettings/memberssettings.js +62 -0
  152. package/dist/esm/product/memberssettings/memberssettings.recipe.js +80 -0
  153. package/dist/esm/product/notificationssettings/index.js +1 -0
  154. package/dist/esm/product/notificationssettings/notificationssettings.js +16 -0
  155. package/dist/esm/product/notificationssettings/notificationssettings.recipe.js +41 -0
  156. package/dist/esm/product/recordpage/index.js +1 -1
  157. package/dist/esm/product/recordpage/recordpage.js +106 -10
  158. package/dist/esm/product/recordpage/recordpage.recipe.js +68 -6
  159. package/dist/esm/product/workspacegeneralsettings/index.js +1 -0
  160. package/dist/esm/product/workspacegeneralsettings/workspacegeneralsettings.js +18 -0
  161. package/dist/esm/product/workspacegeneralsettings/workspacegeneralsettings.recipe.js +48 -0
  162. package/dist/esm/tokens/contract.js +2 -1
  163. package/dist/esm/tokens/elevation.js +8 -5
  164. package/dist/esm/tokens/palette.js +28 -8
  165. package/dist/esm/tokens/scale.js +43 -1
  166. package/dist/esm/tokens/semantic.js +2 -0
  167. package/dist/fileupload.css +3 -1
  168. package/dist/fileupload.layered.css +3 -1
  169. package/dist/input.css +6 -4
  170. package/dist/input.layered.css +6 -4
  171. package/dist/listpage.css +3 -1
  172. package/dist/listpage.layered.css +3 -1
  173. package/dist/memberssettings.css +67 -0
  174. package/dist/memberssettings.d.ts +7 -0
  175. package/dist/memberssettings.layered.css +69 -0
  176. package/dist/menu.css +2 -2
  177. package/dist/menu.layered.css +2 -2
  178. package/dist/menusheet.css +36 -0
  179. package/dist/menusheet.d.ts +7 -0
  180. package/dist/menusheet.layered.css +38 -0
  181. package/dist/multiselect.css +13 -6
  182. package/dist/multiselect.layered.css +13 -6
  183. package/dist/native/tokens.d.ts +2 -1
  184. package/dist/native/tokens.js +20 -3
  185. package/dist/notificationssettings.css +22 -0
  186. package/dist/notificationssettings.d.ts +7 -0
  187. package/dist/notificationssettings.layered.css +24 -0
  188. package/dist/objectsettings.css +4 -4
  189. package/dist/objectsettings.layered.css +4 -4
  190. package/dist/recordpage.css +90 -23
  191. package/dist/recordpage.layered.css +90 -23
  192. package/dist/recordpanel.css +35 -16
  193. package/dist/recordpanel.layered.css +35 -16
  194. package/dist/resizablepanel.css +8 -5
  195. package/dist/resizablepanel.layered.css +8 -5
  196. package/dist/richtext.css +24 -8
  197. package/dist/richtext.layered.css +24 -8
  198. package/dist/savedviews.css +9 -2
  199. package/dist/savedviews.layered.css +9 -2
  200. package/dist/select.css +25 -5
  201. package/dist/select.layered.css +25 -5
  202. package/dist/settingsshell.css +2 -3
  203. package/dist/settingsshell.layered.css +2 -3
  204. package/dist/slider.css +6 -27
  205. package/dist/slider.layered.css +6 -27
  206. package/dist/snackbar.css +24 -0
  207. package/dist/snackbar.d.ts +7 -0
  208. package/dist/snackbar.layered.css +26 -0
  209. package/dist/statcard.css +3 -1
  210. package/dist/statcard.layered.css +3 -1
  211. package/dist/styles.css +911 -354
  212. package/dist/styles.layered.css +911 -354
  213. package/dist/table.css +35 -12
  214. package/dist/table.layered.css +35 -12
  215. package/dist/tabletoolbar.css +35 -24
  216. package/dist/tabletoolbar.layered.css +35 -24
  217. package/dist/tabs.css +18 -4
  218. package/dist/tabs.layered.css +18 -4
  219. package/dist/textarea.css +2 -6
  220. package/dist/textarea.layered.css +2 -6
  221. package/dist/themepicker.css +2 -1
  222. package/dist/themepicker.layered.css +2 -1
  223. package/dist/tokens.css +13 -2
  224. package/dist/tokens.json +20 -3
  225. package/dist/types/components/bottomsheet/bottomsheet.d.ts +35 -0
  226. package/dist/types/components/bottomsheet/bottomsheet.recipe.d.ts +3 -0
  227. package/dist/types/components/bottomsheet/index.d.ts +2 -0
  228. package/dist/types/components/breadcrumb/breadcrumb.d.ts +9 -1
  229. package/dist/types/components/button/button.d.ts +2 -0
  230. package/dist/types/components/button/button.recipe.d.ts +24 -6
  231. package/dist/types/components/checkbox/checkbox.recipe.d.ts +28 -5
  232. package/dist/types/components/chip/chip.d.ts +22 -0
  233. package/dist/types/components/chip/chip.recipe.d.ts +49 -1
  234. package/dist/types/components/chipgroup/chipgroup.d.ts +14 -0
  235. package/dist/types/components/chipgroup/chipgroup.recipe.d.ts +5 -0
  236. package/dist/types/components/chipgroup/index.d.ts +2 -0
  237. package/dist/types/components/datatable/datatable.d.ts +19 -0
  238. package/dist/types/components/datepickerfield/datepickerfield.d.ts +4 -1
  239. package/dist/types/components/datepickerfield/datepickerfield.recipe.d.ts +18 -3
  240. package/dist/types/components/fileupload/fileupload.d.ts +26 -0
  241. package/dist/types/components/input/index.d.ts +1 -1
  242. package/dist/types/components/input/input.d.ts +72 -0
  243. package/dist/types/components/menusheet/index.d.ts +2 -0
  244. package/dist/types/components/menusheet/menusheet.d.ts +42 -0
  245. package/dist/types/components/menusheet/menusheet.recipe.d.ts +3 -0
  246. package/dist/types/components/snackbar/index.d.ts +2 -0
  247. package/dist/types/components/snackbar/snackbar.d.ts +36 -0
  248. package/dist/types/components/snackbar/snackbar.recipe.d.ts +5 -0
  249. package/dist/types/components/tabletoolbar/tabletoolbar.d.ts +28 -1
  250. package/dist/types/components/tabs/tabs.d.ts +11 -1
  251. package/dist/types/core/floating-portal.d.ts +6 -5
  252. package/dist/types/index.d.ts +7 -0
  253. package/dist/types/product/comments/comments.d.ts +9 -3
  254. package/dist/types/product/comments/comments.recipe.d.ts +12 -2
  255. package/dist/types/product/inbox/inbox.d.ts +13 -1
  256. package/dist/types/product/memberssettings/index.d.ts +1 -0
  257. package/dist/types/product/memberssettings/memberssettings.d.ts +85 -0
  258. package/dist/types/product/memberssettings/memberssettings.recipe.d.ts +3 -0
  259. package/dist/types/product/notificationssettings/index.d.ts +1 -0
  260. package/dist/types/product/notificationssettings/notificationssettings.d.ts +37 -0
  261. package/dist/types/product/notificationssettings/notificationssettings.recipe.d.ts +3 -0
  262. package/dist/types/product/recordpage/index.d.ts +1 -1
  263. package/dist/types/product/recordpage/recordpage.d.ts +99 -2
  264. package/dist/types/product/workspacegeneralsettings/index.d.ts +1 -0
  265. package/dist/types/product/workspacegeneralsettings/workspacegeneralsettings.d.ts +48 -0
  266. package/dist/types/product/workspacegeneralsettings/workspacegeneralsettings.recipe.d.ts +3 -0
  267. package/dist/types/tokens/contract.d.ts +4 -1
  268. package/dist/types/tokens/elevation.d.ts +8 -5
  269. package/dist/types/tokens/palette.d.ts +9 -1
  270. package/dist/types/tokens/scale.d.ts +11 -1
  271. package/dist/types/tokens/semantic.d.ts +2 -0
  272. package/dist/wheelpicker.css +4 -2
  273. package/dist/wheelpicker.layered.css +4 -2
  274. package/dist/workspacegeneralsettings.css +30 -0
  275. package/dist/workspacegeneralsettings.d.ts +7 -0
  276. package/dist/workspacegeneralsettings.layered.css +32 -0
  277. package/package.json +36 -1
@@ -17,36 +17,22 @@
17
17
  measurement -- accessibility wins over the seed reference.
18
18
  neutralMuted clears it, 6.62:1 light / 14.71:1 dark (dark was
19
19
  already fine at 9.43:1). */
20
- & .crisp-datepicker-weekday {
21
- display: flex; align-items: center; justify-content: center;
22
- height: var(--crisp-size-calendarCell); color: var(--crisp-fg-neutral-muted);
23
- font-size: var(--crisp-text-sm); line-height: 16px; font-weight: var(--crisp-weight-medium);
24
- }
25
-
20
+ & .crisp-datepicker-weekday { display: flex; align-items: center; justify-content: center; height: var(--crisp-size-calendarCell); color: var(--crisp-fg-neutral-muted); font-size: var(--crisp-text-sm); line-height: 16px; font-weight: var(--crisp-weight-medium); }
26
21
  & .crisp-datepicker-months { display: grid; grid-template-columns: minmax(0, 1fr); align-items: start; min-width: 0; }
27
22
  & .crisp-datepicker-months[data-wheel-open] { visibility: hidden; }
28
23
  & .crisp-datepicker-month { min-width: 0; }
29
- & .crisp-datepicker-month-label {
30
- display: flex; align-items: center; height: 24px;
31
- color: var(--crisp-fg-primary); font-size: var(--crisp-text-lg); line-height: 20px;
32
- font-weight: var(--crisp-weight-medium);
33
- }
34
-
24
+ & .crisp-datepicker-month-label { display: flex; align-items: center; height: 24px; color: var(--crisp-fg-primary); font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); }
35
25
  & .crisp-datepicker-grid { display: grid; min-width: 0; }
36
26
  & .crisp-datepicker-week-row { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
37
-
38
- & .crisp-datepicker-cell {
39
- position: relative; min-width: 0; min-height: var(--crisp-size-calendarCell);
40
- isolation: isolate;
41
- }
27
+ & .crisp-datepicker-cell { position: relative; min-width: 0; min-height: var(--crisp-size-calendarCell); isolation: isolate; }
42
28
  & .crisp-datepicker-empty-cell { min-height: var(--crisp-size-calendarCell); }
43
-
44
29
  /* The bridge joining days inside a completed range.
45
30
  The endpoints do NOT carry data-in-range -- only the interior days do --
46
31
  so these are three independent rules, not a base plus two modifiers. A
47
32
  modifier that sets only inset-inline-start never generates a pseudo
48
33
  element on an endpoint, which leaves a half-cell of white between the
49
- endpoint's pill and the run of grey beside it. Each rule declares its own content. */
34
+ endpoint's pill and the run of grey beside it. Each rule declares its
35
+ own content. */
50
36
  & .crisp-datepicker-cell[data-range-complete][data-in-range]::before { content: ""; position: absolute; z-index: -1; inset-inline: 0; top: calc((var(--crisp-size-calendarCell) - var(--crisp-size-calendarPill)) / 2); height: var(--crisp-size-calendarPill); background: var(--crisp-bg-neutral-weak); }
51
37
  & .crisp-datepicker-cell[data-range-complete][data-range-start]:not([data-range-end])::before { content: ""; position: absolute; z-index: -1; inset-inline-start: 50%; inset-inline-end: 0; top: calc((var(--crisp-size-calendarCell) - var(--crisp-size-calendarPill)) / 2); height: var(--crisp-size-calendarPill); background: var(--crisp-bg-neutral-weak); }
52
38
  & .crisp-datepicker-cell[data-range-complete][data-range-end]:not([data-range-start])::before { content: ""; position: absolute; z-index: -1; inset-inline-start: 0; inset-inline-end: 50%; top: calc((var(--crisp-size-calendarCell) - var(--crisp-size-calendarPill)) / 2); height: var(--crisp-size-calendarPill); background: var(--crisp-bg-neutral-weak); }
@@ -62,33 +48,19 @@
62
48
  & .crisp-datepicker-date:disabled { color: var(--crisp-fg-disabled); cursor: not-allowed; }
63
49
  & .crisp-datepicker-date:focus-visible::after { content: ""; position: absolute; top: calc((var(--crisp-size-calendarCell) - var(--crisp-size-calendarPill)) / 2); left: 50%; width: var(--crisp-size-calendarPill); height: var(--crisp-size-calendarPill); transform: translateX(-50%); border-radius: var(--crisp-radius-md); outline: 2px solid var(--crisp-stroke-focus-ring); outline-offset: -2px; }
64
50
  & .crisp-datepicker-date-content { position: relative; z-index: 1; display: flex; width: 100%; min-height: var(--crisp-size-calendarCell); min-width: 0; box-sizing: border-box; flex-direction: column; align-items: center; gap: 3px; padding-top: calc((var(--crisp-size-calendarCell) - var(--crisp-size-calendarPill)) / 2); color: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); font-variant-numeric: tabular-nums; }
65
- /* The numeral is its own 42px flex box so it centres on the 42px pill. Without this the content column top-aligns the glyph and the pill reads as offset — the cell is 48px, the pill 42px inset 3px, and only a 42px-tall numeral box shares the pill's centre line. */
66
- & .crisp-datepicker-date-content > [data-date-picker-day] {
67
- display: flex; min-height: var(--crisp-size-calendarPill); flex-shrink: 0;
68
- align-items: center; justify-content: center;
69
- }
70
-
51
+ /* The numeral is its own 42px flex box so it centres on the 42px pill.
52
+ Without this the content column top-aligns the glyph and the pill reads
53
+ as offset — the cell is 48px, the pill 42px inset 3px, and only a
54
+ 42px-tall numeral box shares the pill's centre line. */
55
+ & .crisp-datepicker-date-content > [data-date-picker-day] { display: flex; min-height: var(--crisp-size-calendarPill); flex-shrink: 0; align-items: center; justify-content: center; }
71
56
  /* the year/month wheel, laid over the grid it replaces */
72
- & .crisp-datepicker-wheel-container {
73
- position: absolute; z-index: 1; inset-inline: 0;
74
- top: var(--crisp-size-menuRow); bottom: 0;
75
- display: flex; align-items: center; overflow: hidden;
76
- background: var(--crisp-bg-surface);
77
- }
57
+ & .crisp-datepicker-wheel-container { position: absolute; z-index: 1; inset-inline: 0; top: var(--crisp-size-menuRow); bottom: 0; display: flex; align-items: center; overflow: hidden; background: var(--crisp-bg-surface); }
78
58
  & .crisp-datepicker-wheel { width: 100%; }
79
-
80
- & .crisp-datepicker-continuous-scroll {
81
- height: 100%; min-height: 0; overflow-y: auto;
82
- overscroll-behavior: contain; scrollbar-width: none;
83
- }
59
+ & .crisp-datepicker-continuous-scroll { height: 100%; min-height: 0; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; }
84
60
  & .crisp-datepicker-continuous-scroll::-webkit-scrollbar { display: none; }
85
61
  & .crisp-datepicker-continuous-content { display: flex; flex-direction: column; }
86
-
87
62
  /* announced, never drawn */
88
- & .crisp-datepicker-live-region {
89
- position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
90
- overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
91
- }
63
+ & .crisp-datepicker-live-region { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
92
64
  }
93
65
  .crisp-datepicker--visibleRange_month {
94
66
 
@@ -1,13 +1,16 @@
1
1
  .crisp-datepickerfield {
2
2
  display: inline-flex; font-family: var(--crisp-font-sans);
3
- & .crisp-datepickerfield-box { display: inline-flex; align-items: center; box-sizing: border-box; height: 32px; margin: 0; border-radius: var(--crisp-radius-md); background: transparent; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 7%, transparent); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-lg); }
3
+ & .crisp-datepickerfield-box { display: inline-flex; align-items: center; width: 100%; box-sizing: border-box; height: 32px; margin: 0; border-radius: var(--crisp-radius-md); background: transparent; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 7%, transparent); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-lg); }
4
4
  & .crisp-datepickerfield-box[data-ghost] { background: transparent; box-shadow: none; }
5
5
  & .crisp-datepickerfield-box[data-ghost]:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
6
- & .crisp-datepickerfield-trigger { display: inline-flex; align-items: center; gap: var(--crisp-space-2); height: 100%; padding: 0 var(--crisp-space-2-5); margin: 0; border: none; background: none; color: inherit; font-family: inherit; font-size: inherit; white-space: nowrap; cursor: pointer; }
6
+ & .crisp-datepickerfield-trigger { flex: 1; min-width: 0; display: inline-flex; align-items: center; gap: var(--crisp-space-2); height: 100%; padding: 0 var(--crisp-space-2-5); margin: 0; border: none; background: none; color: inherit; font-family: inherit; font-size: inherit; white-space: nowrap; cursor: pointer; }
7
7
  & .crisp-datepickerfield-box[data-placeholder] .crisp-datepickerfield-trigger { color: var(--crisp-fg-muted); }
8
8
  & .crisp-datepickerfield-trigger svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
9
9
  /* Reuses TableToolbar's measured filter-chip remove button
10
- (tabletoolbar.chrome.ts's .crisp-tabletoolbar-fchip-x) -- the same small inline "clear this value" affordance, not a freshly-measured one: no live Attio composition for a DatePickerField-equivalent clear was reachable this round (#394). */
10
+ (tabletoolbar.chrome.ts's .crisp-tabletoolbar-fchip-x) -- the same
11
+ small inline "clear this value" affordance, not a freshly-measured
12
+ one: no live Attio composition for a DatePickerField-equivalent
13
+ clear was reachable this round (#394). */
11
14
  & .crisp-datepickerfield-clear { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; margin-inline-end: var(--crisp-space-1); padding: 0; border: none; border-radius: var(--crisp-radius-sm); background: none; color: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; }
12
15
  & .crisp-datepickerfield-clear:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 10%, transparent); color: var(--crisp-fg-primary); }
13
16
  & .crisp-datepickerfield-panel { padding: var(--crisp-space-2); width: 300px; }
@@ -15,3 +18,9 @@
15
18
  & .crisp-datepickerfield-preset { height: var(--crisp-size-chip); padding: 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-chip); background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-sm); cursor: pointer; }
16
19
  & .crisp-datepickerfield-preset:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 8%, transparent); }
17
20
  }
21
+ .crisp-datepickerfield--width_full {
22
+ width: 100%;
23
+ }
24
+ .crisp-datepickerfield--width_auto {
25
+ width: auto;
26
+ }
@@ -1,7 +1,7 @@
1
1
  import type { RecipeFn } from "../core/types";
2
2
 
3
3
  export interface DatepickerfieldVariants {
4
-
4
+ width?: "full" | "auto";
5
5
  }
6
6
 
7
- export declare const datepickerfieldRecipe: RecipeFn<{ }>;
7
+ export declare const datepickerfieldRecipe: RecipeFn<{ width: { full: string; auto: string } }>;
@@ -1,14 +1,17 @@
1
1
  @layer crisp-components {
2
2
  .crisp-datepickerfield {
3
3
  display: inline-flex; font-family: var(--crisp-font-sans);
4
- & .crisp-datepickerfield-box { display: inline-flex; align-items: center; box-sizing: border-box; height: 32px; margin: 0; border-radius: var(--crisp-radius-md); background: transparent; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 7%, transparent); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-lg); }
4
+ & .crisp-datepickerfield-box { display: inline-flex; align-items: center; width: 100%; box-sizing: border-box; height: 32px; margin: 0; border-radius: var(--crisp-radius-md); background: transparent; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 7%, transparent); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-lg); }
5
5
  & .crisp-datepickerfield-box[data-ghost] { background: transparent; box-shadow: none; }
6
6
  & .crisp-datepickerfield-box[data-ghost]:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
7
- & .crisp-datepickerfield-trigger { display: inline-flex; align-items: center; gap: var(--crisp-space-2); height: 100%; padding: 0 var(--crisp-space-2-5); margin: 0; border: none; background: none; color: inherit; font-family: inherit; font-size: inherit; white-space: nowrap; cursor: pointer; }
7
+ & .crisp-datepickerfield-trigger { flex: 1; min-width: 0; display: inline-flex; align-items: center; gap: var(--crisp-space-2); height: 100%; padding: 0 var(--crisp-space-2-5); margin: 0; border: none; background: none; color: inherit; font-family: inherit; font-size: inherit; white-space: nowrap; cursor: pointer; }
8
8
  & .crisp-datepickerfield-box[data-placeholder] .crisp-datepickerfield-trigger { color: var(--crisp-fg-muted); }
9
9
  & .crisp-datepickerfield-trigger svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
10
10
  /* Reuses TableToolbar's measured filter-chip remove button
11
- (tabletoolbar.chrome.ts's .crisp-tabletoolbar-fchip-x) -- the same small inline "clear this value" affordance, not a freshly-measured one: no live Attio composition for a DatePickerField-equivalent clear was reachable this round (#394). */
11
+ (tabletoolbar.chrome.ts's .crisp-tabletoolbar-fchip-x) -- the same
12
+ small inline "clear this value" affordance, not a freshly-measured
13
+ one: no live Attio composition for a DatePickerField-equivalent
14
+ clear was reachable this round (#394). */
12
15
  & .crisp-datepickerfield-clear { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; margin-inline-end: var(--crisp-space-1); padding: 0; border: none; border-radius: var(--crisp-radius-sm); background: none; color: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; }
13
16
  & .crisp-datepickerfield-clear:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 10%, transparent); color: var(--crisp-fg-primary); }
14
17
  & .crisp-datepickerfield-panel { padding: var(--crisp-space-2); width: 300px; }
@@ -16,4 +19,10 @@
16
19
  & .crisp-datepickerfield-preset { height: var(--crisp-size-chip); padding: 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-chip); background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-sm); cursor: pointer; }
17
20
  & .crisp-datepickerfield-preset:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 8%, transparent); }
18
21
  }
22
+ .crisp-datepickerfield--width_full {
23
+ width: 100%;
24
+ }
25
+ .crisp-datepickerfield--width_auto {
26
+ width: auto;
27
+ }
19
28
  }
package/dist/dialog.css CHANGED
@@ -3,10 +3,8 @@
3
3
  & .crisp-dialog-backdrop { position: fixed; inset: 0; z-index: 60; background: var(--crisp-bg-scrim); }
4
4
  & .crisp-dialog-positioner { position: fixed; inset: 0; z-index: 61; display: flex; align-items: flex-start; justify-content: center; padding: 15vh var(--crisp-space-4) var(--crisp-space-4); }
5
5
  & .crisp-dialog-positioner[data-variant="alert"] { align-items: center; padding: var(--crisp-space-4); }
6
- & .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: var(--crisp-space-1); border-radius: var(--crisp-radius-2xl); background: color-mix(in srgb, var(--crisp-bg-overlay-frost) 60%, transparent); backdrop-filter: blur(15px); -webkit-backdrop-filter: blur(15px); box-shadow: 0 8px 28px -6px var(--crisp-shadow-overlay1), 0 18px 88px -4px var(--crisp-shadow-overlay2), 0 0 1px var(--crisp-shadow-overlay3); opacity: 1; transform: scale(1); transition: opacity 0.2s ease, transform 0.2s ease; @starting-style { opacity: 0; transform: scale(0.97); } }
7
- & .crisp-dialog-content[data-variant="alert"] { padding: 0; background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: none; }
8
- & .crisp-dialog-card { display: flex; flex-direction: column; flex: 1; min-height: 0; box-sizing: border-box; border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 8%, transparent); overflow: hidden; }
9
- & .crisp-dialog-content[data-variant="alert"] .crisp-dialog-card { border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); }
6
+ & .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; opacity: 1; transform: scale(1); transition: opacity 0.2s ease, transform 0.2s ease; @starting-style { opacity: 0; transform: scale(0.97); } }
7
+ & .crisp-dialog-card { display: flex; flex-direction: column; flex: 1; min-height: 0; box-sizing: border-box; border-radius: var(--crisp-radius-3xl); background: var(--crisp-bg-surface); overflow: hidden; }
10
8
  & .crisp-dialog-header { display: flex; align-items: center; gap: var(--crisp-space-2); flex-shrink: 0; height: 52px; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-4); border-bottom: 1px solid var(--crisp-border-subtle); }
11
9
  & .crisp-dialog-header svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
12
10
  & .crisp-dialog-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); margin: 0; }
@@ -15,8 +13,10 @@
15
13
  /* The discard-confirm's own stacked title + sentence (crisp#677) — no
16
14
  border, no close button, unlike the panel header above: measured
17
15
  live, both themes, 18px/24px 600-weight title (no scale token
18
- reaches 18px — the scale tops out at text.xl's 16px, so this is raw px per Golden Rule 3's "genuinely intrinsic size" exception, same as
19
- this file's own submit-key glyphs) then a 14px/20px 500-weight sentence 4px below it. */
16
+ reaches 18px — the scale tops out at text.xl's 16px, so this is raw
17
+ px per Golden Rule 3's "genuinely intrinsic size" exception, same as
18
+ this file's own submit-key glyphs) then a 14px/20px 500-weight
19
+ sentence 4px below it. */
20
20
  & .crisp-dialog-alert-header { display: flex; flex-direction: column; gap: var(--crisp-space-1); padding: var(--crisp-space-4) var(--crisp-space-4) 0; }
21
21
  & .crisp-dialog-alert-title { margin: 0; font-size: 18px; line-height: 24px; font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); }
22
22
  & .crisp-dialog-alert-description { margin: 0; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-alert-description); }
@@ -26,7 +26,12 @@
26
26
  & .crisp-dialog-field { display: flex; flex-direction: column; gap: var(--crisp-space-1-5); }
27
27
  & .crisp-dialog-field-label { font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent); }
28
28
  & .crisp-dialog-more { display: inline-flex; align-items: center; gap: var(--crisp-space-2); margin-inline-end: auto; border: none; background: none; padding: 0; font-family: inherit; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); cursor: pointer; }
29
- & .crisp-dialog-submit { display: inline-flex; align-items: center; gap: var(--crisp-space-2); height: 28px; padding: 0 var(--crisp-space-1) 0 var(--crisp-space-2-5); 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: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; }
29
+ /* your-moon/crisp#953: bgBrandContrast, not bgBrandSolid --
30
+ the accent (#0298d9) only clears 3.23:1 with white; the darker
31
+ sibling clears 4.5:1+, same fix already applied to Button/Badge/
32
+ Avatar (#897). Scoped to this one fill only -- Dialog's own frosted-
33
+ surface identity (#934) is untouched here. */
34
+ & .crisp-dialog-submit { display: inline-flex; align-items: center; gap: var(--crisp-space-2); height: 28px; padding: 0 var(--crisp-space-1) 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-brand-contrast); color: var(--crisp-fg-on-brand); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; }
30
35
  & .crisp-dialog-submit-key { display: inline-flex; align-items: center; gap: var(--crisp-space-1); }
31
36
  & .crisp-dialog-submit-key kbd { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; padding: 0 3px; border-radius: 4px; background: transparent; color: var(--crisp-fg-on-brand); font-family: inherit; font-style: normal; font-size: 10px; }
32
37
  }
@@ -4,10 +4,8 @@
4
4
  & .crisp-dialog-backdrop { position: fixed; inset: 0; z-index: 60; background: var(--crisp-bg-scrim); }
5
5
  & .crisp-dialog-positioner { position: fixed; inset: 0; z-index: 61; display: flex; align-items: flex-start; justify-content: center; padding: 15vh var(--crisp-space-4) var(--crisp-space-4); }
6
6
  & .crisp-dialog-positioner[data-variant="alert"] { align-items: center; padding: var(--crisp-space-4); }
7
- & .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: var(--crisp-space-1); border-radius: var(--crisp-radius-2xl); background: color-mix(in srgb, var(--crisp-bg-overlay-frost) 60%, transparent); backdrop-filter: blur(15px); -webkit-backdrop-filter: blur(15px); box-shadow: 0 8px 28px -6px var(--crisp-shadow-overlay1), 0 18px 88px -4px var(--crisp-shadow-overlay2), 0 0 1px var(--crisp-shadow-overlay3); opacity: 1; transform: scale(1); transition: opacity 0.2s ease, transform 0.2s ease; @starting-style { opacity: 0; transform: scale(0.97); } }
8
- & .crisp-dialog-content[data-variant="alert"] { padding: 0; background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: none; }
9
- & .crisp-dialog-card { display: flex; flex-direction: column; flex: 1; min-height: 0; box-sizing: border-box; border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 8%, transparent); overflow: hidden; }
10
- & .crisp-dialog-content[data-variant="alert"] .crisp-dialog-card { border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); }
7
+ & .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; opacity: 1; transform: scale(1); transition: opacity 0.2s ease, transform 0.2s ease; @starting-style { opacity: 0; transform: scale(0.97); } }
8
+ & .crisp-dialog-card { display: flex; flex-direction: column; flex: 1; min-height: 0; box-sizing: border-box; border-radius: var(--crisp-radius-3xl); background: var(--crisp-bg-surface); overflow: hidden; }
11
9
  & .crisp-dialog-header { display: flex; align-items: center; gap: var(--crisp-space-2); flex-shrink: 0; height: 52px; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-4); border-bottom: 1px solid var(--crisp-border-subtle); }
12
10
  & .crisp-dialog-header svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
13
11
  & .crisp-dialog-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); margin: 0; }
@@ -16,8 +14,10 @@
16
14
  /* The discard-confirm's own stacked title + sentence (crisp#677) — no
17
15
  border, no close button, unlike the panel header above: measured
18
16
  live, both themes, 18px/24px 600-weight title (no scale token
19
- reaches 18px — the scale tops out at text.xl's 16px, so this is raw px per Golden Rule 3's "genuinely intrinsic size" exception, same as
20
- this file's own submit-key glyphs) then a 14px/20px 500-weight sentence 4px below it. */
17
+ reaches 18px — the scale tops out at text.xl's 16px, so this is raw
18
+ px per Golden Rule 3's "genuinely intrinsic size" exception, same as
19
+ this file's own submit-key glyphs) then a 14px/20px 500-weight
20
+ sentence 4px below it. */
21
21
  & .crisp-dialog-alert-header { display: flex; flex-direction: column; gap: var(--crisp-space-1); padding: var(--crisp-space-4) var(--crisp-space-4) 0; }
22
22
  & .crisp-dialog-alert-title { margin: 0; font-size: 18px; line-height: 24px; font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); }
23
23
  & .crisp-dialog-alert-description { margin: 0; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-alert-description); }
@@ -27,7 +27,12 @@
27
27
  & .crisp-dialog-field { display: flex; flex-direction: column; gap: var(--crisp-space-1-5); }
28
28
  & .crisp-dialog-field-label { font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent); }
29
29
  & .crisp-dialog-more { display: inline-flex; align-items: center; gap: var(--crisp-space-2); margin-inline-end: auto; border: none; background: none; padding: 0; font-family: inherit; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); cursor: pointer; }
30
- & .crisp-dialog-submit { display: inline-flex; align-items: center; gap: var(--crisp-space-2); height: 28px; padding: 0 var(--crisp-space-1) 0 var(--crisp-space-2-5); 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: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; }
30
+ /* your-moon/crisp#953: bgBrandContrast, not bgBrandSolid --
31
+ the accent (#0298d9) only clears 3.23:1 with white; the darker
32
+ sibling clears 4.5:1+, same fix already applied to Button/Badge/
33
+ Avatar (#897). Scoped to this one fill only -- Dialog's own frosted-
34
+ surface identity (#934) is untouched here. */
35
+ & .crisp-dialog-submit { display: inline-flex; align-items: center; gap: var(--crisp-space-2); height: 28px; padding: 0 var(--crisp-space-1) 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-brand-contrast); color: var(--crisp-fg-on-brand); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; }
31
36
  & .crisp-dialog-submit-key { display: inline-flex; align-items: center; gap: var(--crisp-space-1); }
32
37
  & .crisp-dialog-submit-key kbd { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; padding: 0 3px; border-radius: 4px; background: transparent; color: var(--crisp-fg-on-brand); font-family: inherit; font-style: normal; font-size: 10px; }
33
38
  }
@@ -3,7 +3,9 @@
3
3
  & .crisp-emptystate-icon { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; margin-bottom: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: color-mix(in srgb, var(--crisp-fg-primary) 5%, transparent); color: var(--crisp-fg-muted); }
4
4
  & .crisp-emptystate-title { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); }
5
5
  & .crisp-emptystate-desc { max-width: 320px; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
6
- /* #603: measured 8px gap between "Import CSV"/"Connect data source" -- inline-flex so one action (the common case) or several lay out the same way, wrapping if the container is narrow. */
6
+ /* #603: measured 8px gap between "Import CSV"/"Connect data source" --
7
+ inline-flex so one action (the common case) or several lay out the
8
+ same way, wrapping if the container is narrow. */
7
9
  & .crisp-emptystate-action { display: inline-flex; align-items: center; flex-wrap: wrap; justify-content: center; gap: var(--crisp-space-2); margin-top: var(--crisp-space-2); }
8
10
  /* #603: Attio's zero-records "Learn more" card -- a label above a
9
11
  clickable icon+title tile. Left/start-aligned, unlike the rest of
@@ -23,12 +25,12 @@
23
25
  .crisp-emptystate--variant_page {
24
26
  gap: var(--crisp-space-2);
25
27
  & .crisp-emptystate-icon { width: 45px; height: 45px; margin-bottom: var(--crisp-space-2); border-radius: var(--crisp-radius-full); border: 1px solid var(--crisp-border-subtle); background: none; color: var(--crisp-fg-muted); }
26
- & .crisp-emptystate-title { font-size: 20px; line-height: 24px; }
28
+ & .crisp-emptystate-title { font-size: 20px; line-height: 24px; letter-spacing: var(--crisp-tracking-20); }
27
29
  & .crisp-emptystate-desc { max-width: 266px; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); line-height: 20px; }
28
30
  & .crisp-emptystate-action { margin-top: var(--crisp-space-2); }
29
31
  }
30
32
  .crisp-emptystate--variant_records {
31
33
  & .crisp-emptystate-icon { width: 138px; height: 138px; margin-bottom: var(--crisp-space-2); border-radius: 0; color: color-mix(in srgb, var(--crisp-fg-primary) 22%, transparent); background: radial-gradient(circle, color-mix(in srgb, var(--crisp-fg-primary) 12%, transparent) 1.2px, transparent 1.2px) 0 0 / 16px 16px; }
32
- & .crisp-emptystate-title { font-size: 20px; line-height: 24px; }
34
+ & .crisp-emptystate-title { font-size: 20px; line-height: 24px; letter-spacing: var(--crisp-tracking-20); }
33
35
  & .crisp-emptystate-desc { max-width: 266px; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); line-height: 20px; }
34
36
  }
@@ -4,7 +4,9 @@
4
4
  & .crisp-emptystate-icon { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; margin-bottom: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: color-mix(in srgb, var(--crisp-fg-primary) 5%, transparent); color: var(--crisp-fg-muted); }
5
5
  & .crisp-emptystate-title { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); }
6
6
  & .crisp-emptystate-desc { max-width: 320px; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
7
- /* #603: measured 8px gap between "Import CSV"/"Connect data source" -- inline-flex so one action (the common case) or several lay out the same way, wrapping if the container is narrow. */
7
+ /* #603: measured 8px gap between "Import CSV"/"Connect data source" --
8
+ inline-flex so one action (the common case) or several lay out the
9
+ same way, wrapping if the container is narrow. */
8
10
  & .crisp-emptystate-action { display: inline-flex; align-items: center; flex-wrap: wrap; justify-content: center; gap: var(--crisp-space-2); margin-top: var(--crisp-space-2); }
9
11
  /* #603: Attio's zero-records "Learn more" card -- a label above a
10
12
  clickable icon+title tile. Left/start-aligned, unlike the rest of
@@ -24,13 +26,13 @@
24
26
  .crisp-emptystate--variant_page {
25
27
  gap: var(--crisp-space-2);
26
28
  & .crisp-emptystate-icon { width: 45px; height: 45px; margin-bottom: var(--crisp-space-2); border-radius: var(--crisp-radius-full); border: 1px solid var(--crisp-border-subtle); background: none; color: var(--crisp-fg-muted); }
27
- & .crisp-emptystate-title { font-size: 20px; line-height: 24px; }
29
+ & .crisp-emptystate-title { font-size: 20px; line-height: 24px; letter-spacing: var(--crisp-tracking-20); }
28
30
  & .crisp-emptystate-desc { max-width: 266px; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); line-height: 20px; }
29
31
  & .crisp-emptystate-action { margin-top: var(--crisp-space-2); }
30
32
  }
31
33
  .crisp-emptystate--variant_records {
32
34
  & .crisp-emptystate-icon { width: 138px; height: 138px; margin-bottom: var(--crisp-space-2); border-radius: 0; color: color-mix(in srgb, var(--crisp-fg-primary) 22%, transparent); background: radial-gradient(circle, color-mix(in srgb, var(--crisp-fg-primary) 12%, transparent) 1.2px, transparent 1.2px) 0 0 / 16px 16px; }
33
- & .crisp-emptystate-title { font-size: 20px; line-height: 24px; }
35
+ & .crisp-emptystate-title { font-size: 20px; line-height: 24px; letter-spacing: var(--crisp-tracking-20); }
34
36
  & .crisp-emptystate-desc { max-width: 266px; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); line-height: 20px; }
35
37
  }
36
38
  }
@@ -89,7 +89,11 @@ const spec = defineSpec({
89
89
  paddingInline: c.space["1"],
90
90
  fontSize: c.text.sm,
91
91
  lineHeight: "16px",
92
- borderRadius: c.radius.sm,
92
+ // your-moon/crisp#919: seed-design's own Badge (`badge.yaml`)
93
+ // is a small rounded-rect at every size, never a pill -- its
94
+ // small/medium step is `$radius.r1` = 4px (`radius.xs`), not the 6px
95
+ // `radius.sm` this used to share with Chip's old rounded-rect shape.
96
+ borderRadius: c.radius.xs,
93
97
  },
94
98
  // crisp#696: Attio's tag pill (Standard/System/Enriched) measures
95
99
  // 20px h / 4px padding / 12px text / 16px line-height / 3px gap -- was
@@ -101,14 +105,24 @@ const spec = defineSpec({
101
105
  fontSize: c.text.sm,
102
106
  lineHeight: "16px",
103
107
  gap: "3px",
104
- borderRadius: c.radius.sm,
108
+ // your-moon/crisp#919: same seed radius step as `small`
109
+ // above -- seed's Badge treats small/medium as one radius step
110
+ // (`$radius.r1` = 4px), unlike Button/Input's per-size table.
111
+ borderRadius: c.radius.xs,
105
112
  },
106
113
  // crisp#805: measured live against Attio's real status/stage chip
107
- // (Deals "Deal stage" column, All Deals table view) -- radius 9px, not
108
- // `radius.chip`'s 7px, and asymmetric padding (room for a leading dot/
109
- // icon: 1px top/bottom, 6px trailing, 4px leading), not a symmetric
110
- // 9px. Height/font/tracking are unchanged (still not independently
111
- // re-measured this round, per #696's own note).
114
+ // (Deals "Deal stage" column, All Deals table view) -- asymmetric
115
+ // padding (room for a leading dot/icon: 1px top/bottom, 6px trailing,
116
+ // 4px leading), not a symmetric 9px. Height/font/tracking are
117
+ // unchanged (still not independently re-measured this round, per
118
+ // #696's own note).
119
+ // your-moon/crisp#919: radius was Attio's own measured 9px
120
+ // (`radius.lg`, deliberately not `radius.chip`'s then-7px) -- now
121
+ // `radius.sm` (6px), seed-design's own Badge large step
122
+ // (`$radius.r1_5`). Radius specifically is one of the values this
123
+ // migration takes from seed over an Attio measurement (colours/radii/
124
+ // control-styling/elevation all do); the padding/height facts above
125
+ // are unaffected and still Attio's.
112
126
  large: {
113
127
  height: c.size.chip,
114
128
  paddingBlock: c.space.px,
@@ -116,7 +130,7 @@ const spec = defineSpec({
116
130
  paddingInlineEnd: c.space["1.5"],
117
131
  fontSize: c.text.lg,
118
132
  letterSpacing: "-0.1px",
119
- borderRadius: c.radius.lg,
133
+ borderRadius: c.radius.sm,
120
134
  },
121
135
  },
122
136
  variant: { soft: {}, solid: {} },
@@ -0,0 +1,52 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as dialog from "@zag-js/dialog";
3
+ import { normalizeProps, Portal, useMachine } from "@zag-js/react";
4
+ import { X } from "lucide-react";
5
+ import * as React from "react";
6
+ import { cx, hasOpenFloatingLayer, useCrispMessage, withDescribedBy, } from "../../core/index.js";
7
+ import { bottomsheetRecipe } from "./bottomsheet.recipe.js";
8
+ let instanceCounter = 0;
9
+ function useBottomSheetInstanceId() {
10
+ const idRef = React.useRef(null);
11
+ if (idRef.current == null) {
12
+ instanceCounter += 1;
13
+ idRef.current = `crisp-bottomsheet-${instanceCounter}`;
14
+ }
15
+ return idRef.current;
16
+ }
17
+ /**
18
+ * A mobile bottom sheet — composes Zag's dialog machine (focus trap, scroll
19
+ * lock, Escape / outside-click dismissal) with a panel that slides up from
20
+ * the bottom edge. Compose the body with `BottomSheetBody` and actions with
21
+ * `BottomSheetFooter`.
22
+ */
23
+ export function BottomSheet({ open, onOpenChange, title, description, headerAlign = "left", showCloseButton, "aria-label": ariaLabel, closeLabel: closeLabelProp, children, className, "aria-describedby": describedBy, ...rest }) {
24
+ const closeLabel = useCrispMessage(closeLabelProp, "Close");
25
+ const id = useBottomSheetInstanceId();
26
+ const service = useMachine(dialog.machine, {
27
+ id,
28
+ open,
29
+ onOpenChange(details) {
30
+ onOpenChange(details.open);
31
+ },
32
+ "aria-label": typeof title === "string" ? title : ariaLabel,
33
+ // Defer to a nested Menu/Select/Popover/ContextMenu's own Escape
34
+ // handling (#361) -- same reasoning as Dialog/Drawer, same machine.
35
+ onEscapeKeyDown(event) {
36
+ if (hasOpenFloatingLayer())
37
+ event.preventDefault();
38
+ },
39
+ });
40
+ const api = dialog.connect(service, normalizeProps);
41
+ if (!api.open)
42
+ return null;
43
+ const hasClose = showCloseButton ?? title != null;
44
+ return (_jsx(Portal, { children: _jsxs("div", { className: bottomsheetRecipe(), children: [_jsx("div", { ...api.getBackdropProps(), className: "crisp-bottomsheet-backdrop" }), _jsx("div", { ...api.getPositionerProps(), className: "crisp-bottomsheet-positioner", children: _jsxs("div", { ...rest, ...withDescribedBy(api.getContentProps(), describedBy), className: cx("crisp-bottomsheet-content", className), "data-header-align": headerAlign, "data-has-close": hasClose ? "" : undefined, children: [(title != null || description != null) && (_jsxs("div", { className: "crisp-bottomsheet-header", children: [title != null && (_jsx("span", { ...api.getTitleProps(), className: "crisp-bottomsheet-title", children: title })), description != null && (_jsx("span", { className: "crisp-bottomsheet-description", children: description })), hasClose && (_jsx("button", { type: "button", ...api.getCloseTriggerProps(), className: "crisp-bottomsheet-close", "aria-label": closeLabel, children: _jsx(X, { size: 16, strokeWidth: 2, "aria-hidden": "true" }) }))] })), children] }) })] }) }));
45
+ }
46
+ BottomSheet.displayName = "BottomSheet";
47
+ export function BottomSheetBody({ children }) {
48
+ return _jsx("div", { className: "crisp-bottomsheet-body", children: children });
49
+ }
50
+ export function BottomSheetFooter({ children, }) {
51
+ return _jsx("div", { className: "crisp-bottomsheet-footer", children: children });
52
+ }
@@ -0,0 +1,74 @@
1
+ import { defineRecipe, resolveRecipe } from "../../core/index.js";
2
+ import { contract as c } from "../../tokens/index.js";
3
+ // A mobile bottom sheet — daangn/seed-design's
4
+ // packages/rootage/components/bottom-sheet.yaml (dev@e1c486b904297f7b6a8f17b8523f732c37015d60),
5
+ // not Attio (no such component there; crisp#911). Composes @zag-js/dialog, the
6
+ // same headless machine Dialog/Drawer already use, with a panel that slides
7
+ // up from the bottom edge over a scrim -- only the TOP corners round; the
8
+ // panel sits flush with the viewport's bottom edge, unlike Drawer's own
9
+ // 8px-gutter floating panel. Every numeric value below cites its yaml line.
10
+ const config = defineRecipe({
11
+ name: "bottomsheet",
12
+ base: `display: contents; font-family: ${c.font.sans};
13
+ & .crisp-bottomsheet-backdrop {
14
+ position: fixed; inset: 0; z-index: 60;
15
+ background: ${c.bgOverlayStrong}; /* bottom-sheet.yaml:99 backdrop.color = $color.bg.overlay -- a different, darker, theme-constant scrim than the Dialog bgScrim token, see its own comment */
16
+ opacity: 1; transition: opacity 300ms cubic-bezier(0,0,.15,1); /* bottom-sheet.yaml:100-102 enterDuration/enterTimingFunction */
17
+ @starting-style { opacity: 0; }
18
+ }
19
+ & .crisp-bottomsheet-positioner {
20
+ position: fixed; inset: 0; z-index: 61;
21
+ display: flex; align-items: flex-end; justify-content: center;
22
+ }
23
+ & .crisp-bottomsheet-content {
24
+ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
25
+ position: relative; box-sizing: border-box; display: flex; flex-direction: column;
26
+ overflow: hidden; width: 100%; max-width: 480px; /* bottom-sheet.yaml:110 content.maxWidth */
27
+ max-height: 85vh;
28
+ background: ${c.bgSurface}; /* bottom-sheet.yaml:109 content.color = $color.bg.layer-floating */
29
+ border-radius: ${c.radius["4xl"]} ${c.radius["4xl"]} 0 0; /* bottom-sheet.yaml:111 content.topCornerRadius = $radius.r6 (24px), bottom flush with the viewport */
30
+ transform: translateY(0);
31
+ transition: transform 300ms cubic-bezier(.03,.4,.1,1); /* bottom-sheet.yaml:112-113 content.enterDuration/enterTimingFunction (enter-expressive) */
32
+ @starting-style { transform: translateY(100%); }
33
+ }
34
+ & .crisp-bottomsheet-header {
35
+ position: relative; display: flex; flex-direction: column;
36
+ gap: ${c.space["2"]}; /* bottom-sheet.yaml:120 header.gap = $dimension.x2 (8px) */
37
+ padding-top: ${c.space["6"]}; padding-bottom: ${c.space["4"]}; /* bottom-sheet.yaml:121-122 header.paddingTop/paddingBottom = $dimension.x6/x4 (24px/16px) */
38
+ flex-shrink: 0;
39
+ }
40
+ & .crisp-bottomsheet-title {
41
+ color: ${c.fgPrimary}; /* bottom-sheet.yaml:130 title.color = $color.fg.neutral */
42
+ font-size: 22px; line-height: 30px; font-weight: ${c.weight.bold}; /* bottom-sheet.yaml:131-133 title.fontSize/lineHeight/fontWeight = $font-size.t8/$line-height.t8/bold */
43
+ padding-inline: ${c.space["4"]}; /* default (headerAlignment=left, no close button): bottom-sheet.yaml:150-152 */
44
+ }
45
+ &[data-header-align="left"][data-has-close] .crisp-bottomsheet-title { padding-inline-start: ${c.space["4"]}; padding-inline-end: 56px; } /* bottom-sheet.yaml:141-144 */
46
+ &[data-header-align="center"] .crisp-bottomsheet-title { text-align: center; }
47
+ &[data-header-align="center"][data-has-close] .crisp-bottomsheet-title { padding-inline: 56px; } /* bottom-sheet.yaml:154-157 */
48
+ & .crisp-bottomsheet-description {
49
+ color: ${c.fgMuted}; /* bottom-sheet.yaml:138 description.color = $color.fg.neutral-muted */
50
+ font-size: ${c.text.xl}; line-height: 22px; font-weight: ${c.weight.regular}; /* bottom-sheet.yaml:139-141 description.fontSize/lineHeight/fontWeight = $font-size.t5/$line-height.t5/regular */
51
+ padding-inline: ${c.space["4"]}; /* bottom-sheet.yaml:142 description.paddingX = global-gutter (16px) */
52
+ }
53
+ & .crisp-bottomsheet-close {
54
+ position: absolute; top: ${c.space["6"]}; inset-inline-end: ${c.space["4"]}; /* bottom-sheet.yaml:145-146 closeButton.fromTop/fromRight = $dimension.x6/x4 (24px/16px) */
55
+ display: inline-flex; align-items: center; justify-content: center;
56
+ width: 28px; height: 28px; margin: 0; padding: 0; border: none; border-radius: ${c.radius.md};
57
+ background: none; color: ${c.fgMuted}; font-family: inherit; cursor: pointer;
58
+ }
59
+ & .crisp-bottomsheet-close:hover { background: color-mix(in srgb, ${c.fgPrimary} 6%, transparent); color: ${c.fgPrimary}; }
60
+ & .crisp-bottomsheet-body {
61
+ flex: 1; min-height: 0; overflow-y: auto;
62
+ padding-inline: ${c.space["4"]}; /* bottom-sheet.yaml:126 body.paddingX = global-gutter (16px) -- no vertical padding in the spec */
63
+ }
64
+ & .crisp-bottomsheet-footer {
65
+ display: flex; align-items: center; justify-content: flex-end; gap: ${c.space["3"]};
66
+ flex-shrink: 0;
67
+ padding-inline: ${c.space["4"]}; padding-top: ${c.space["3"]}; padding-bottom: ${c.space["4"]}; /* bottom-sheet.yaml:127-129 footer.paddingX/paddingTop/paddingBottom = global-gutter/x3/x4 (16px/12px/16px) */
68
+ }`,
69
+ variants: {},
70
+ defaultVariants: {},
71
+ compoundVariants: [],
72
+ });
73
+ export const bottomsheetRecipe = resolveRecipe(config);
74
+ export default config;
@@ -0,0 +1,2 @@
1
+ export { BottomSheet, BottomSheetBody, BottomSheetFooter, } from "./bottomsheet.js";
2
+ export { bottomsheetRecipe } from "./bottomsheet.recipe.js";
@@ -19,7 +19,7 @@ export function Breadcrumb({ items, separator, "aria-label": ariaLabelProp, clas
19
19
  return (_jsx("nav", { "aria-label": ariaLabel, className: breadcrumbRecipe({ className }), ...rest, children: items.map((item, i) => {
20
20
  const last = i === items.length - 1;
21
21
  const content = (_jsxs(_Fragment, { children: [item.icon, item.label] }));
22
- return (_jsxs(React.Fragment, { children: [last ? (_jsx("span", { className: "crisp-breadcrumb-item", "aria-current": "page", children: content })) : item.href ? (_jsx("a", { className: "crisp-breadcrumb-item", href: item.href, children: content })) : (_jsx("button", { type: "button", className: "crisp-breadcrumb-item", onClick: item.onClick, children: content })), !last && _jsx("span", { className: "crisp-breadcrumb-sep", children: sep })] }, i));
22
+ return (_jsxs(React.Fragment, { children: [last ? (_jsx("span", { className: "crisp-breadcrumb-item", "aria-current": "page", children: content })) : item.href ? (_jsx("a", { className: "crisp-breadcrumb-item", href: item.href, onClick: item.onClick, children: content })) : (_jsx("button", { type: "button", className: "crisp-breadcrumb-item", onClick: item.onClick, children: content })), !last && _jsx("span", { className: "crisp-breadcrumb-sep", children: sep })] }, i));
23
23
  }) }));
24
24
  }
25
25
  Breadcrumb.displayName = "Breadcrumb";