@rinzai/zen 0.10.3 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. package/README.md +38 -8
  2. package/dist/accordion/index.d.ts +41 -0
  3. package/dist/accordion/index.d.ts.map +1 -0
  4. package/dist/accordion/index.js +81 -0
  5. package/dist/animated-number/index.d.ts +3 -2
  6. package/dist/animated-number/index.d.ts.map +1 -1
  7. package/dist/animated-number/index.js +40 -38
  8. package/dist/avatar/index.d.ts +8 -3
  9. package/dist/avatar/index.d.ts.map +1 -1
  10. package/dist/avatar/index.js +29 -21
  11. package/dist/backdrop/index.d.ts +4 -4
  12. package/dist/backdrop/index.d.ts.map +1 -1
  13. package/dist/backdrop/index.js +41 -39
  14. package/dist/badge/index.d.ts +4 -2
  15. package/dist/badge/index.d.ts.map +1 -1
  16. package/dist/badge/index.js +20 -11
  17. package/dist/base.css +4 -0
  18. package/dist/breadcrumbs/index.d.ts +1 -1
  19. package/dist/breadcrumbs/index.d.ts.map +1 -1
  20. package/dist/breadcrumbs/index.js +25 -24
  21. package/dist/button/index.d.ts +3 -3
  22. package/dist/button/index.d.ts.map +1 -1
  23. package/dist/button/index.js +16 -11
  24. package/dist/button-group/index.d.ts +13 -0
  25. package/dist/button-group/index.d.ts.map +1 -0
  26. package/dist/button-group/index.js +14 -0
  27. package/dist/calendar/index.d.ts +15 -8
  28. package/dist/calendar/index.d.ts.map +1 -1
  29. package/dist/calendar/index.js +97 -91
  30. package/dist/calendar-heatmap/index.d.ts +7 -5
  31. package/dist/calendar-heatmap/index.d.ts.map +1 -1
  32. package/dist/calendar-heatmap/index.js +32 -30
  33. package/dist/canvas/geometry.d.ts +51 -0
  34. package/dist/canvas/geometry.d.ts.map +1 -0
  35. package/dist/canvas/geometry.js +90 -0
  36. package/dist/canvas/index.d.ts +59 -0
  37. package/dist/canvas/index.d.ts.map +1 -0
  38. package/dist/canvas/index.js +305 -0
  39. package/dist/carousel/index.d.ts +27 -0
  40. package/dist/carousel/index.d.ts.map +1 -0
  41. package/dist/carousel/index.js +162 -0
  42. package/dist/chart/index.d.ts +5 -4
  43. package/dist/chart/index.d.ts.map +1 -1
  44. package/dist/chart/index.js +137 -135
  45. package/dist/chart/palette.js +0 -1
  46. package/dist/checkbox/index.d.ts +3 -3
  47. package/dist/checkbox/index.d.ts.map +1 -1
  48. package/dist/checkbox/index.js +33 -30
  49. package/dist/chip/index.js +1 -1
  50. package/dist/code-block/index.d.ts.map +1 -1
  51. package/dist/code-block/index.js +27 -32
  52. package/dist/code-input/index.d.ts.map +1 -1
  53. package/dist/code-input/index.js +30 -24
  54. package/dist/collapse/index.d.ts +4 -3
  55. package/dist/collapse/index.d.ts.map +1 -1
  56. package/dist/collapse/index.js +42 -39
  57. package/dist/color-picker/index.d.ts +43 -0
  58. package/dist/color-picker/index.d.ts.map +1 -0
  59. package/dist/color-picker/index.js +221 -0
  60. package/dist/combobox/index.d.ts +14 -6
  61. package/dist/combobox/index.d.ts.map +1 -1
  62. package/dist/combobox/index.js +151 -139
  63. package/dist/command-palette/index.d.ts +4 -3
  64. package/dist/command-palette/index.d.ts.map +1 -1
  65. package/dist/command-palette/index.js +60 -57
  66. package/dist/confirm-dialog/index.d.ts +6 -7
  67. package/dist/confirm-dialog/index.d.ts.map +1 -1
  68. package/dist/confirm-dialog/index.js +20 -16
  69. package/dist/date-picker/index.d.ts +23 -14
  70. package/dist/date-picker/index.d.ts.map +1 -1
  71. package/dist/date-picker/index.js +109 -93
  72. package/dist/dialog/index.d.ts +3 -4
  73. package/dist/dialog/index.d.ts.map +1 -1
  74. package/dist/dialog/index.js +58 -55
  75. package/dist/disclosure/index.d.ts +8 -0
  76. package/dist/disclosure/index.d.ts.map +1 -1
  77. package/dist/disclosure/index.js +31 -32
  78. package/dist/editable-cell/index.d.ts +4 -5
  79. package/dist/editable-cell/index.d.ts.map +1 -1
  80. package/dist/editable-cell/index.js +23 -22
  81. package/dist/field/index.d.ts +8 -8
  82. package/dist/field/index.d.ts.map +1 -1
  83. package/dist/field/index.js +20 -18
  84. package/dist/filter-bar/index.d.ts +2 -2
  85. package/dist/filter-bar/index.d.ts.map +1 -1
  86. package/dist/filter-bar/index.js +38 -36
  87. package/dist/header/index.d.ts +1 -1
  88. package/dist/header/index.d.ts.map +1 -1
  89. package/dist/header/index.js +13 -11
  90. package/dist/hover-card/index.d.ts +32 -0
  91. package/dist/hover-card/index.d.ts.map +1 -0
  92. package/dist/hover-card/index.js +84 -0
  93. package/dist/icon-picker/index.d.ts +16 -5
  94. package/dist/icon-picker/index.d.ts.map +1 -1
  95. package/dist/icon-picker/index.js +42 -47
  96. package/dist/icons/micro/plus.d.ts +3 -0
  97. package/dist/icons/micro/plus.d.ts.map +1 -0
  98. package/dist/icons/micro/plus.js +17 -0
  99. package/dist/index.d.ts +41 -24
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/input/index.d.ts +5 -1
  102. package/dist/input/index.d.ts.map +1 -1
  103. package/dist/input/index.js +10 -10
  104. package/dist/input-group/index.d.ts +4 -1
  105. package/dist/input-group/index.d.ts.map +1 -1
  106. package/dist/input-group/index.js +17 -17
  107. package/dist/keypad/index.d.ts +9 -7
  108. package/dist/keypad/index.d.ts.map +1 -1
  109. package/dist/keypad/index.js +22 -19
  110. package/dist/lib.js +112 -93
  111. package/dist/load-more/index.d.ts +4 -2
  112. package/dist/load-more/index.d.ts.map +1 -1
  113. package/dist/load-more/index.js +26 -23
  114. package/dist/locale-provider/index.d.ts +23 -0
  115. package/dist/locale-provider/index.d.ts.map +1 -0
  116. package/dist/locale-provider/index.js +35 -0
  117. package/dist/menu/index.d.ts +62 -9
  118. package/dist/menu/index.d.ts.map +1 -1
  119. package/dist/menu/index.js +371 -128
  120. package/dist/meter/index.d.ts +2 -2
  121. package/dist/meter/index.d.ts.map +1 -1
  122. package/dist/meter/index.js +4 -4
  123. package/dist/money-input/index.d.ts +20 -10
  124. package/dist/money-input/index.d.ts.map +1 -1
  125. package/dist/money-input/index.js +199 -190
  126. package/dist/month-picker/index.d.ts +17 -10
  127. package/dist/month-picker/index.d.ts.map +1 -1
  128. package/dist/month-picker/index.js +97 -86
  129. package/dist/navigation-menu/index.d.ts +42 -0
  130. package/dist/navigation-menu/index.d.ts.map +1 -0
  131. package/dist/navigation-menu/index.js +144 -0
  132. package/dist/number-field/index.d.ts +34 -0
  133. package/dist/number-field/index.d.ts.map +1 -0
  134. package/dist/number-field/index.js +119 -0
  135. package/dist/page-header/index.d.ts +4 -3
  136. package/dist/page-header/index.d.ts.map +1 -1
  137. package/dist/page-header/index.js +2 -1
  138. package/dist/pagination/index.d.ts +1 -1
  139. package/dist/pagination/index.d.ts.map +1 -1
  140. package/dist/pagination/index.js +35 -33
  141. package/dist/progress-ring/index.d.ts +4 -3
  142. package/dist/progress-ring/index.d.ts.map +1 -1
  143. package/dist/progress-ring/index.js +11 -10
  144. package/dist/radio-cards/index.d.ts +9 -5
  145. package/dist/radio-cards/index.d.ts.map +1 -1
  146. package/dist/radio-cards/index.js +26 -24
  147. package/dist/radio-group/index.d.ts +9 -8
  148. package/dist/radio-group/index.d.ts.map +1 -1
  149. package/dist/radio-group/index.js +35 -34
  150. package/dist/range-slider/index.d.ts +10 -4
  151. package/dist/range-slider/index.d.ts.map +1 -1
  152. package/dist/range-slider/index.js +43 -31
  153. package/dist/repeat-picker/index.d.ts +13 -6
  154. package/dist/repeat-picker/index.d.ts.map +1 -1
  155. package/dist/repeat-picker/index.js +74 -62
  156. package/dist/resizable/index.d.ts +29 -0
  157. package/dist/resizable/index.d.ts.map +1 -0
  158. package/dist/resizable/index.js +135 -0
  159. package/dist/segmented/index.d.ts +8 -5
  160. package/dist/segmented/index.d.ts.map +1 -1
  161. package/dist/segmented/index.js +36 -34
  162. package/dist/select/index.d.ts +9 -3
  163. package/dist/select/index.d.ts.map +1 -1
  164. package/dist/select/index.js +94 -91
  165. package/dist/separator/index.d.ts +14 -0
  166. package/dist/separator/index.d.ts.map +1 -0
  167. package/dist/separator/index.js +15 -0
  168. package/dist/side-nav/index.js +1 -1
  169. package/dist/skeleton/index.d.ts +4 -4
  170. package/dist/skeleton/index.d.ts.map +1 -1
  171. package/dist/skeleton/index.js +4 -3
  172. package/dist/slider/index.d.ts +6 -3
  173. package/dist/slider/index.d.ts.map +1 -1
  174. package/dist/slider/index.js +29 -23
  175. package/dist/sortable/index.d.ts +10 -20
  176. package/dist/sortable/index.d.ts.map +1 -1
  177. package/dist/sortable/index.js +72 -134
  178. package/dist/sortable/shared.d.ts +56 -0
  179. package/dist/sortable/shared.d.ts.map +1 -0
  180. package/dist/sortable/shared.js +104 -0
  181. package/dist/sortable/tree-model.d.ts +46 -0
  182. package/dist/sortable/tree-model.d.ts.map +1 -0
  183. package/dist/sortable/tree-model.js +87 -0
  184. package/dist/sortable/tree.d.ts +31 -0
  185. package/dist/sortable/tree.d.ts.map +1 -0
  186. package/dist/sortable/tree.js +150 -0
  187. package/dist/sparkline/index.d.ts +1 -1
  188. package/dist/sparkline/index.d.ts.map +1 -1
  189. package/dist/sparkline/index.js +26 -25
  190. package/dist/spinner/index.d.ts +4 -3
  191. package/dist/spinner/index.d.ts.map +1 -1
  192. package/dist/spinner/index.js +2 -1
  193. package/dist/status-pill/index.d.ts.map +1 -1
  194. package/dist/status-pill/index.js +1 -1
  195. package/dist/stepper/index.d.ts +1 -1
  196. package/dist/stepper/index.d.ts.map +1 -1
  197. package/dist/stepper/index.js +31 -30
  198. package/dist/tab-bar/index.js +1 -1
  199. package/dist/table/index.d.ts +5 -5
  200. package/dist/table/index.d.ts.map +1 -1
  201. package/dist/table/index.js +66 -64
  202. package/dist/table/selection.d.ts +2 -2
  203. package/dist/table/selection.d.ts.map +1 -1
  204. package/dist/table/selection.js +41 -38
  205. package/dist/table/swipe.d.ts +1 -1
  206. package/dist/table/swipe.d.ts.map +1 -1
  207. package/dist/table/swipe.js +1 -1
  208. package/dist/table-of-contents/index.d.ts +4 -2
  209. package/dist/table-of-contents/index.d.ts.map +1 -1
  210. package/dist/table-of-contents/index.js +27 -25
  211. package/dist/tabs/index.d.ts.map +1 -1
  212. package/dist/tabs/index.js +90 -88
  213. package/dist/tag-input/index.d.ts +3 -1
  214. package/dist/tag-input/index.d.ts.map +1 -1
  215. package/dist/tag-input/index.js +61 -52
  216. package/dist/textarea/index.js +4 -4
  217. package/dist/theme-toggle/index.d.ts +9 -8
  218. package/dist/theme-toggle/index.d.ts.map +1 -1
  219. package/dist/theme-toggle/index.js +30 -28
  220. package/dist/theme.css +90 -12
  221. package/dist/time-field/index.d.ts +31 -0
  222. package/dist/time-field/index.d.ts.map +1 -0
  223. package/dist/time-field/index.js +175 -0
  224. package/dist/timeline/index.js +1 -1
  225. package/dist/toast/index.d.ts +1 -1
  226. package/dist/toast/index.d.ts.map +1 -1
  227. package/dist/toast/index.js +127 -125
  228. package/dist/toggle/index.d.ts +2 -2
  229. package/dist/toggle/index.d.ts.map +1 -1
  230. package/dist/toggle/index.js +8 -6
  231. package/dist/toggle-group/index.d.ts +35 -0
  232. package/dist/toggle-group/index.d.ts.map +1 -0
  233. package/dist/toggle-group/index.js +53 -0
  234. package/dist/toolbar/index.d.ts +19 -0
  235. package/dist/toolbar/index.d.ts.map +1 -0
  236. package/dist/toolbar/index.js +36 -0
  237. package/dist/tooltip/index.d.ts.map +1 -1
  238. package/dist/tooltip/index.js +40 -74
  239. package/dist/tree/index.d.ts.map +1 -1
  240. package/dist/tree/index.js +105 -102
  241. package/dist/trend/index.d.ts +2 -2
  242. package/dist/trend/index.d.ts.map +1 -1
  243. package/dist/trend/index.js +20 -19
  244. package/dist/utils/color.d.ts +35 -0
  245. package/dist/utils/color.d.ts.map +1 -0
  246. package/dist/utils/color.js +65 -0
  247. package/dist/utils/cva.js +0 -1
  248. package/dist/utils/cx.js +0 -1
  249. package/dist/utils/date.d.ts +6 -0
  250. package/dist/utils/date.d.ts.map +1 -1
  251. package/dist/utils/date.js +1 -2
  252. package/dist/utils/direction.d.ts +7 -0
  253. package/dist/utils/direction.d.ts.map +1 -0
  254. package/dist/utils/direction.js +6 -0
  255. package/dist/utils/form-value.d.ts +15 -0
  256. package/dist/utils/form-value.d.ts.map +1 -0
  257. package/dist/utils/form-value.js +29 -0
  258. package/dist/utils/fx.js +0 -1
  259. package/dist/utils/merge.js +0 -1
  260. package/dist/utils/messages.d.ts +137 -0
  261. package/dist/utils/messages.d.ts.map +1 -0
  262. package/dist/utils/messages.js +133 -0
  263. package/dist/utils/money.js +0 -1
  264. package/dist/utils/month.js +0 -1
  265. package/dist/utils/motion.js +0 -1
  266. package/dist/utils/refs.d.ts +6 -0
  267. package/dist/utils/refs.d.ts.map +1 -0
  268. package/dist/utils/refs.js +13 -0
  269. package/dist/utils/repeat.d.ts +3 -1
  270. package/dist/utils/repeat.d.ts.map +1 -1
  271. package/dist/utils/repeat.js +28 -25
  272. package/dist/utils/roving.d.ts +17 -0
  273. package/dist/utils/roving.d.ts.map +1 -0
  274. package/dist/utils/roving.js +35 -0
  275. package/dist/utils/section-link.js +0 -1
  276. package/dist/utils/slot.d.ts.map +1 -1
  277. package/dist/utils/slot.js +7 -11
  278. package/dist/utils/status-icons.js +7 -7
  279. package/dist/utils/styles.d.ts +9 -2
  280. package/dist/utils/styles.d.ts.map +1 -1
  281. package/dist/utils/styles.js +6 -3
  282. package/dist/utils/theme-wave.d.ts.map +1 -1
  283. package/dist/utils/theme-wave.js +70 -70
  284. package/dist/utils/theme.d.ts.map +1 -1
  285. package/dist/utils/theme.js +56 -60
  286. package/dist/utils/useAnchoredPopup.d.ts +7 -4
  287. package/dist/utils/useAnchoredPopup.d.ts.map +1 -1
  288. package/dist/utils/useAnchoredPopup.js +18 -11
  289. package/dist/utils/useControllable.d.ts +9 -0
  290. package/dist/utils/useControllable.d.ts.map +1 -0
  291. package/dist/utils/useControllable.js +15 -0
  292. package/dist/utils/useCopyToClipboard.d.ts +13 -0
  293. package/dist/utils/useCopyToClipboard.d.ts.map +1 -0
  294. package/dist/utils/useCopyToClipboard.js +26 -0
  295. package/dist/utils/useHoverPopup.d.ts +39 -0
  296. package/dist/utils/useHoverPopup.d.ts.map +1 -0
  297. package/dist/utils/useHoverPopup.js +64 -0
  298. package/dist/zen.css +1 -1
  299. package/package.json +1 -1
@@ -1,22 +1,24 @@
1
1
  import { DateString } from '../utils/date';
2
2
  import { Month } from '../utils/month';
3
+ import { ComponentProps } from 'react';
3
4
  /**
4
5
  * A month as a grid of days, each shaded by its value (e.g. what was spent
5
6
  * that day): busy days stand out at a glance. Hover a day for its figure;
6
- * with `onSelect`, days are buttons.
7
+ * with `onSelectedChange`, days are buttons.
7
8
  */
8
- export default function CalendarHeatmap({ month, values, locale, format, weekStartsOn, onSelect, selected, label, className, }: CalendarHeatmapProps): import('react').JSX.Element;
9
- export interface CalendarHeatmapProps {
9
+ export default function CalendarHeatmap({ month, values, locale: localeProp, format, weekStartsOn: weekStartsOnProp, onSelectedChange, selected, label, className, ...rest }: CalendarHeatmapProps): import('react').JSX.Element;
10
+ /** Other props (data-*, an id) go on the table. */
11
+ export interface CalendarHeatmapProps extends Omit<ComponentProps<'table'>, 'children'> {
10
12
  month: Month;
11
13
  /** Each day's value, by date ("2026-09-03"); days missing have none. */
12
14
  values: Partial<Record<DateString, number>>;
13
- locale: string;
15
+ locale?: string;
14
16
  /** Turns a value into text for its label, e.g. as money. */
15
17
  format?: (value: number) => string;
16
18
  /** 0 for Sunday … 6 for Saturday (default: the locale's). */
17
19
  weekStartsOn?: number;
18
20
  /** Makes the days buttons. */
19
- onSelect?: (day: DateString) => void;
21
+ onSelectedChange?: (day: DateString) => void;
20
22
  selected?: DateString | null;
21
23
  /** Accessible name (default: the month, e.g. "September 2026"). */
22
24
  label?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/calendar-heatmap/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAA+D,MAAM,iBAAiB,CAAC;AAC/G,OAAO,EAAe,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE3D;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EACpC,KAAK,EACL,MAAM,EACN,MAAM,EACN,MAAe,EACf,YAAgC,EAChC,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,SAAS,GACZ,EAAE,oBAAoB,+BAsFtB;AAED,MAAM,WAAW,oBAAoB;IACjC,KAAK,EAAE,KAAK,CAAC;IACb,wEAAwE;IACxE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/calendar-heatmap/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAA+D,MAAM,iBAAiB,CAAC;AAC/G,OAAO,EAAe,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAEvC;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EACpC,KAAK,EACL,MAAM,EACN,MAAM,EAAE,UAAU,EAClB,MAAe,EACf,YAAY,EAAE,gBAAgB,EAC9B,gBAAgB,EAChB,QAAQ,EACR,KAAK,EACL,SAAS,EACT,GAAG,IAAI,EACV,EAAE,oBAAoB,+BA0FtB;AAED,mDAAmD;AACnD,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC;IACnF,KAAK,EAAE,KAAK,CAAC;IACb,wEAAwE;IACxE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8BAA8B;IAC9B,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,QAAQ,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -1,48 +1,50 @@
1
1
  "use client";
2
2
  import { cx as e } from "../utils/cx.js";
3
- import { formatMonth as t } from "../utils/month.js";
4
- import { dayOfWeek as n, daysInMonth as r, formatDate as i, weekStart as a, weekdayNames as o } from "../utils/date.js";
5
- import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
3
+ import { useLocale as t } from "../locale-provider/index.js";
4
+ import { formatMonth as n } from "../utils/month.js";
5
+ import { dayOfWeek as r, daysInMonth as i, formatDate as a, weekStart as o, weekdayNames as s } from "../utils/date.js";
6
+ import { Fragment as c, jsx as l, jsxs as u } from "react/jsx-runtime";
6
7
  //#region packages/calendar-heatmap/index.tsx
7
- function u({ month: u, values: d, locale: f, format: p = String, weekStartsOn: m = a(f), onSelect: h, selected: g, label: _, className: v }) {
8
- let y = r(u), b = Array.from({ length: y }, (e, t) => `${u}-${String(t + 1).padStart(2, "0")}`), x = (n(b[0]) - m + 7) % 7, S = [...Array(x).fill(null), ...b];
9
- for (; S.length % 7;) S.push(null);
10
- let C = Array.from({ length: S.length / 7 }, (e, t) => S.slice(t * 7, t * 7 + 7)), w = o(f, "narrow"), T = o(f, "long"), E = Array.from({ length: 7 }, (e, t) => (m + t) % 7), D = Math.max(0, ...b.map((e) => d[e] ?? 0));
11
- return /* @__PURE__ */ l("table", {
12
- "aria-label": _ ?? t(u, f, "long"),
13
- className: e("zen__calendar-heatmap w-full table-fixed border-separate border-spacing-1", v),
14
- children: [/* @__PURE__ */ c("thead", { children: /* @__PURE__ */ c("tr", { children: E.map((e) => /* @__PURE__ */ c("th", {
8
+ function d({ month: d, values: f, locale: p, format: m = String, weekStartsOn: h, onSelectedChange: g, selected: _, label: v, className: y, ...b }) {
9
+ let x = t(p), S = new Intl.NumberFormat(x), C = h ?? o(x), w = i(d), T = Array.from({ length: w }, (e, t) => `${d}-${String(t + 1).padStart(2, "0")}`), E = (r(T[0]) - C + 7) % 7, D = [...Array(E).fill(null), ...T];
10
+ for (; D.length % 7;) D.push(null);
11
+ let O = Array.from({ length: D.length / 7 }, (e, t) => D.slice(t * 7, t * 7 + 7)), k = s(x, "narrow"), A = s(x, "long"), j = Array.from({ length: 7 }, (e, t) => (C + t) % 7), M = Math.max(0, ...T.map((e) => f[e] ?? 0));
12
+ return /* @__PURE__ */ u("table", {
13
+ "aria-label": v ?? n(d, x, "long"),
14
+ ...b,
15
+ className: e("zen__calendar-heatmap w-full table-fixed border-separate border-spacing-1", y),
16
+ children: [/* @__PURE__ */ l("thead", { children: /* @__PURE__ */ l("tr", { children: j.map((e) => /* @__PURE__ */ l("th", {
15
17
  scope: "col",
16
- abbr: T[e],
18
+ abbr: A[e],
17
19
  className: "text-muted-foreground pb-1 text-xs font-normal",
18
- children: w[e]
19
- }, e)) }) }), /* @__PURE__ */ c("tbody", { children: C.map((t, n) => /* @__PURE__ */ c("tr", { children: t.map((t, n) => {
20
- if (!t) return /* @__PURE__ */ c("td", {}, n);
21
- let r = d[t], a = D > 0 && r ? Math.sqrt(r / D) : 0, o = `${i(t, f, "day")}: ${p(r || 0)}`, u = e("relative grid aspect-square w-full place-items-center rounded-md text-[0.65rem] tabular-nums transition-[box-shadow]", a ? a > .6 ? "text-primary-foreground" : "text-foreground/80" : "bg-tint/[0.04] text-muted-foreground", t === g && "ring-ring ring-2"), m = a ? { background: `oklch(var(--primary) / ${+(.14 + .81 * a).toFixed(2)})` } : void 0, _ = /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c("span", {
20
+ children: k[e]
21
+ }, e)) }) }), /* @__PURE__ */ l("tbody", { children: O.map((t, n) => /* @__PURE__ */ l("tr", { children: t.map((t, n) => {
22
+ if (!t) return /* @__PURE__ */ l("td", {}, n);
23
+ let r = f[t], i = M > 0 && r ? Math.sqrt(r / M) : 0, o = `${a(t, x, "day")}: ${m(r || 0)}`, s = e("relative grid aspect-square w-full place-items-center rounded-md text-[0.65rem] tabular-nums transition-[box-shadow]", i ? i > .6 ? "text-primary-foreground" : "text-foreground/80" : "bg-tint/[0.04] text-muted-foreground", t === _ && "ring-ring ring-2"), d = i ? { background: `oklch(var(--primary) / ${+(.14 + .81 * i).toFixed(2)})` } : void 0, p = /* @__PURE__ */ u(c, { children: [/* @__PURE__ */ l("span", {
22
24
  "aria-hidden": !0,
23
- children: Number(t.slice(8))
24
- }), /* @__PURE__ */ c("span", {
25
+ children: S.format(Number(t.slice(8)))
26
+ }), /* @__PURE__ */ l("span", {
25
27
  className: "sr-only",
26
28
  children: o
27
29
  })] });
28
- return /* @__PURE__ */ c("td", {
30
+ return /* @__PURE__ */ l("td", {
29
31
  title: o,
30
32
  className: "p-0",
31
- children: h ? /* @__PURE__ */ c("button", {
33
+ children: g ? /* @__PURE__ */ l("button", {
32
34
  type: "button",
33
- "aria-pressed": t === g,
34
- onClick: () => h(t),
35
- className: e(u, "focus-visible:ring-ring/60 cursor-pointer outline-hidden hover:shadow-[0_0_0_1px_oklch(var(--tint)/0.3)] focus-visible:ring-2"),
36
- style: m,
37
- children: _
38
- }) : /* @__PURE__ */ c("span", {
39
- className: u,
40
- style: m,
41
- children: _
35
+ "aria-pressed": t === _,
36
+ onClick: () => g(t),
37
+ className: e(s, " cursor-pointer outline-hidden hover:shadow-[0_0_0_1px_oklch(var(--tint)/0.3)] focus-ring"),
38
+ style: d,
39
+ children: p
40
+ }) : /* @__PURE__ */ l("span", {
41
+ className: s,
42
+ style: d,
43
+ children: p
42
44
  })
43
45
  }, t);
44
46
  }) }, n)) })]
45
47
  });
46
48
  }
47
49
  //#endregion
48
- export { u as default };
50
+ export { d as default };
@@ -0,0 +1,51 @@
1
+ export interface CanvasRect {
2
+ x: number;
3
+ y: number;
4
+ w: number;
5
+ h: number;
6
+ }
7
+ /** A snap line: a vertical one at x, or a horizontal one at y. */
8
+ export interface CanvasGuide {
9
+ axis: 'x' | 'y';
10
+ at: number;
11
+ }
12
+ /** Which corner or edge a resize handle is on. */
13
+ export type CanvasHandle = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw';
14
+ export interface Bounds {
15
+ width: number;
16
+ height: number;
17
+ /** Smallest width and height. */
18
+ min: number;
19
+ }
20
+ export interface SnapOptions {
21
+ /** Rects to line up with, besides the surface. */
22
+ others?: readonly CanvasRect[];
23
+ /** How close counts for lines, in surface units; 0 or left out, no lines. */
24
+ threshold?: number;
25
+ /** Round to multiples of this when no line is in reach. */
26
+ grid?: number;
27
+ }
28
+ /** The box around several rects. */
29
+ export declare function boundsOf(rects: readonly CanvasRect[]): CanvasRect;
30
+ /** Whether two rects overlap. */
31
+ export declare function intersects(a: CanvasRect, b: CanvasRect): boolean;
32
+ /**
33
+ * `start` moved by dx, dy, then snapped: an edge or its centre onto a line in
34
+ * reach, otherwise its corner onto the grid. Kept on the surface, in whole units.
35
+ */
36
+ export declare function moveRect(start: CanvasRect, dx: number, dy: number, bounds: Bounds, snap?: SnapOptions): {
37
+ rect: CanvasRect;
38
+ guides: CanvasGuide[];
39
+ };
40
+ /**
41
+ * `start` resized by dragging `handle` by dx, dy: its moving edges snapped to a
42
+ * line or the grid, no smaller than `min`, kept on the surface, in whole units.
43
+ * With `keepRatio`, its shape stays the same (and it doesn't snap).
44
+ */
45
+ export declare function resizeRect(start: CanvasRect, handle: CanvasHandle, dx: number, dy: number, bounds: Bounds, { keepRatio, ...snap }?: SnapOptions & {
46
+ keepRatio?: boolean;
47
+ }): {
48
+ rect: CanvasRect;
49
+ guides: CanvasGuide[];
50
+ };
51
+ //# sourceMappingURL=geometry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../packages/canvas/geometry.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACvB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACb;AAED,kEAAkE;AAClE,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,GAAG,GAAG,GAAG,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACd;AAED,kDAAkD;AAClD,MAAM,MAAM,YAAY,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC;AAE7E,MAAM,WAAW,MAAM;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IACxB,kDAAkD;IAClD,MAAM,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/B,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,oCAAoC;AACpC,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,CASjE;AAED,iCAAiC;AACjC,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAEhE;AA2BD;;;GAGG;AACH,wBAAgB,QAAQ,CACpB,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,WAAgB,GACvB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,WAAW,EAAE,CAAA;CAAE,CAqB7C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACtB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,YAAY,EACpB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,EAAE,SAAiB,EAAE,GAAG,IAAI,EAAE,GAAE,WAAW,GAAG;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3E;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,WAAW,EAAE,CAAA;CAAE,CAqD7C"}
@@ -0,0 +1,90 @@
1
+ //#region packages/canvas/geometry.ts
2
+ function e(e) {
3
+ let t = Math.min(...e.map((e) => e.x)), n = Math.min(...e.map((e) => e.y));
4
+ return {
5
+ x: t,
6
+ y: n,
7
+ w: Math.max(...e.map((e) => e.x + e.w)) - t,
8
+ h: Math.max(...e.map((e) => e.y + e.h)) - n
9
+ };
10
+ }
11
+ function t(e, t) {
12
+ return e.x < t.x + t.w && t.x < e.x + e.w && e.y < t.y + t.h && t.y < e.y + e.h;
13
+ }
14
+ function n(e, t, n) {
15
+ let r = e === "x" ? t.width : t.height, i = [
16
+ 0,
17
+ r / 2,
18
+ r
19
+ ];
20
+ for (let t of n) {
21
+ let [n, r] = e === "x" ? [t.x, t.w] : [t.y, t.h];
22
+ i.push(n, n + r / 2, n + r);
23
+ }
24
+ return i;
25
+ }
26
+ function r(e, t, n) {
27
+ let r = null;
28
+ for (let i of e) for (let e of t) {
29
+ let t = e - i;
30
+ Math.abs(t) <= n && (!r || Math.abs(t) < Math.abs(r.by)) && (r = {
31
+ by: t,
32
+ at: e
33
+ });
34
+ }
35
+ return r;
36
+ }
37
+ var i = (e, t) => t ? Math.round(e / t) * t : e;
38
+ function a(e, t, a, o, s = {}) {
39
+ let c = [], l = (e, t, a) => {
40
+ let l = s.threshold && r([
41
+ t,
42
+ t + a / 2,
43
+ t + a
44
+ ], n(e, o, s.others ?? []), s.threshold);
45
+ return l ? (c.push({
46
+ axis: e,
47
+ at: l.at
48
+ }), t + l.by) : i(t, s.grid);
49
+ }, u = l("x", e.x + t, e.w), d = l("y", e.y + a, e.h);
50
+ return {
51
+ rect: {
52
+ x: Math.round(Math.min(Math.max(0, u), o.width - e.w)),
53
+ y: Math.round(Math.min(Math.max(0, d), o.height - e.h)),
54
+ w: e.w,
55
+ h: e.h
56
+ },
57
+ guides: c
58
+ };
59
+ }
60
+ function o(e, t, a, o, s, { keepRatio: c = !1, ...l } = {}) {
61
+ let u = t.includes("w"), d = t.includes("e"), f = t.includes("n"), p = t.includes("s"), m = e.x + e.w, h = e.y + e.h, g = e.x + (u ? a : 0), _ = m + (d ? a : 0), v = e.y + (f ? o : 0), y = h + (p ? o : 0), b = [];
62
+ if (!c) {
63
+ let e = (e, t) => {
64
+ let a = l.threshold && r([t], n(e, s, l.others ?? []), l.threshold);
65
+ return a ? (b.push({
66
+ axis: e,
67
+ at: a.at
68
+ }), a.at) : i(t, l.grid);
69
+ };
70
+ u && (g = e("x", g)), d && (_ = e("x", _)), f && (v = e("y", v)), p && (y = e("y", y));
71
+ }
72
+ let x = u ? m : s.width - e.x, S = f ? h : s.height - e.y, C = Math.min(x, Math.max(s.min, _ - g)), w = Math.min(S, Math.max(s.min, y - v));
73
+ if (c) {
74
+ let t = e.w / e.h;
75
+ (u || d) && (!(f || p) || Math.abs(C / e.w - 1) >= Math.abs(w / e.h - 1)) ? w = C / t : C = w * t;
76
+ let n = Math.min(1, x / C, S / w), r = Math.max(1, s.min / C, s.min / w), i = n < 1 ? n : r;
77
+ C *= i, w *= i;
78
+ }
79
+ return C = Math.round(C), w = Math.round(w), {
80
+ rect: {
81
+ x: u ? m - C : e.x,
82
+ y: f ? h - w : e.y,
83
+ w: C,
84
+ h: w
85
+ },
86
+ guides: b
87
+ };
88
+ }
89
+ //#endregion
90
+ export { e as boundsOf, t as intersects, a as moveRect, o as resizeRect };
@@ -0,0 +1,59 @@
1
+ import { ComponentProps } from 'react';
2
+ import { CanvasRect } from './geometry';
3
+ export type { CanvasRect } from './geometry';
4
+ /**
5
+ * A fixed-size surface where items sit anywhere, such as the cards of a
6
+ * stream overlay or a slide. Drag an item to move it, and the handles of the
7
+ * selected one to resize it (Shift keeps its shape); Escape mid-drag puts it
8
+ * back. Shift- or Cmd-click, or drag a box on empty space, to select several
9
+ * and move them together. From the keyboard, Tab reaches each item, the arrow
10
+ * keys move the selection (Shift by 10), Alt and the arrow keys resize, Cmd or
11
+ * Ctrl+A selects all, and Escape deselects; each change is announced.
12
+ *
13
+ * Items stay on the surface; with `snap` they line up with its edges and
14
+ * centre and with each other, and with `grid` they keep to a grid. `scale`
15
+ * shows the design larger or smaller, or `"fit"` fills the width it's given.
16
+ * `onItemsChange` gets the items with every step of a change; `onItemsChangeEnd`, once
17
+ * it's made, with the items before it, for undo or saving.
18
+ */
19
+ export declare function Canvas<T extends CanvasItemRect>({ width, height, scale, items, onItemsChange, onItemsChangeEnd, selected, onSelectedChange, minSize, snap, grid, className, style, children, onPointerDown, ref, ...rest }: CanvasProps<T>): import('react').JSX.Element;
20
+ /**
21
+ * One item on a Canvas, placed where the canvas's `items` say for its `id`;
22
+ * later items sit on top of earlier ones. `label` names it ("Title") in what's
23
+ * announced. Its content is yours: fields and buttons in it work as usual,
24
+ * and pressing them doesn't drag it (nor anything with data-canvas-no-drag).
25
+ */
26
+ export declare function CanvasItem({ id, label, className, style, children, ...rest }: CanvasItemProps): import('react').JSX.Element | null;
27
+ export interface CanvasItemRect extends CanvasRect {
28
+ id: string;
29
+ /** Not moved or resized, and presses go through it to the surface (Tab still reaches it): a background, say. */
30
+ locked?: boolean;
31
+ }
32
+ export interface CanvasProps<T extends CanvasItemRect = CanvasItemRect> extends ComponentProps<'div'> {
33
+ /** The surface's size, in your design's units (px at scale 1). */
34
+ width: number;
35
+ height: number;
36
+ /** How large to show it: 2 shows a 400×120 design 800×240; "fit" fills the width it's given. Positions stay in design units. */
37
+ scale?: number | 'fit';
38
+ /** Where each item is (other fields are kept); render a CanvasItem for each. */
39
+ items: readonly T[];
40
+ /** The items, with every step of a move or resize. */
41
+ onItemsChange: (items: T[]) => void;
42
+ /** The items once a change is made (a drag let go, a key pressed), and as they were before: for undo or saving. */
43
+ onItemsChangeEnd?: (items: T[], before: readonly T[]) => void;
44
+ /** The selected items' ids. */
45
+ selected?: readonly string[];
46
+ onSelectedChange?: (ids: string[]) => void;
47
+ /** Smallest width and height an item can be resized to. */
48
+ minSize?: number;
49
+ /** Line items up with the surface and each other: true, or how close counts, in screen px (true is 6). */
50
+ snap?: boolean | number;
51
+ /** Keep positions and sizes to multiples of this (design units) when no line is in reach. */
52
+ grid?: number;
53
+ }
54
+ export interface CanvasItemProps extends ComponentProps<'div'> {
55
+ id: string;
56
+ /** The item's name, e.g. "Title", for what's announced. */
57
+ label: string;
58
+ }
59
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/canvas/index.tsx"],"names":[],"mappings":"AAGA,OAAO,EACH,cAAc,EAWjB,MAAM,OAAO,CAAC;AAEf,OAAO,EAIH,KAAK,UAAU,EAKlB,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAyC7C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,cAAc,EAAE,EAC7C,KAAK,EACL,MAAM,EACN,KAAS,EACT,KAAK,EACL,aAAa,EACb,gBAAgB,EAChB,QAAa,EACb,gBAAgB,EAChB,OAAW,EACX,IAAY,EACZ,IAAI,EACJ,SAAS,EACT,KAAK,EACL,QAAQ,EACR,aAAa,EACb,GAAG,EACH,GAAG,IAAI,EACV,EAAE,WAAW,CAAC,CAAC,CAAC,+BAwUhB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,eAAe,sCA2D7F;AAED,MAAM,WAAW,cAAe,SAAQ,UAAU;IAC9C,EAAE,EAAE,MAAM,CAAC;IACX,gHAAgH;IAChH,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,cAAc,GAAG,cAAc,CAAE,SAAQ,cAAc,CAAC,KAAK,CAAC;IACjG,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,gIAAgI;IAChI,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACvB,gFAAgF;IAChF,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IACpB,sDAAsD;IACtD,aAAa,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;IACpC,mHAAmH;IACnH,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC;IAC9D,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC3C,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0GAA0G;IAC1G,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,6FAA6F;IAC7F,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAgB,SAAQ,cAAc,CAAC,KAAK,CAAC;IAC1D,EAAE,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1,305 @@
1
+ "use client";
2
+ import { cx as e } from "../utils/cx.js";
3
+ import { useMergedRefs as t } from "../utils/refs.js";
4
+ import { useMessages as n } from "../locale-provider/index.js";
5
+ import { boundsOf as r, intersects as i, moveRect as a, resizeRect as o } from "./geometry.js";
6
+ import { createContext as s, useContext as c, useEffect as l, useId as u, useLayoutEffect as d, useRef as f, useState as p } from "react";
7
+ import { jsx as m, jsxs as h } from "react/jsx-runtime";
8
+ //#region packages/canvas/index.tsx
9
+ var g = typeof window > "u" ? l : d, _ = 3, ee = "input, textarea, select, button, a[href], [contenteditable=\"\"], [contenteditable=\"true\"], [data-canvas-no-drag]", v = [
10
+ "nw",
11
+ "n",
12
+ "ne",
13
+ "e",
14
+ "se",
15
+ "s",
16
+ "sw",
17
+ "w"
18
+ ], y = {
19
+ nw: "left-0 top-0 cursor-nwse-resize",
20
+ n: "left-1/2 top-0 cursor-ns-resize",
21
+ ne: "left-full top-0 cursor-nesw-resize",
22
+ e: "left-full top-1/2 cursor-ew-resize",
23
+ se: "left-full top-full cursor-nwse-resize",
24
+ s: "left-1/2 top-full cursor-ns-resize",
25
+ sw: "left-0 top-full cursor-nesw-resize",
26
+ w: "left-0 top-1/2 cursor-ew-resize"
27
+ }, b = {
28
+ ArrowLeft: [-1, 0],
29
+ ArrowRight: [1, 0],
30
+ ArrowUp: [0, -1],
31
+ ArrowDown: [0, 1]
32
+ }, x = (e, t) => e.x === t.x && e.y === t.y && e.w === t.w && e.h === t.h, S = (e, t) => e.length === t.length && e.every((e, n) => e === t[n]), C = s(null);
33
+ function w({ width: s, height: c, scale: l = 1, items: d, onItemsChange: v, onItemsChangeEnd: y, selected: w = [], onSelectedChange: T, minSize: E = 8, snap: D = !1, grid: O, className: te, style: ne, children: re, onPointerDown: ie, ref: ae, ...k }) {
34
+ let A = n(), j = f(null), oe = t(j, ae), M = f(!1), [N, se] = p(null), [ce, P] = p([]), [F, I] = p(null), [L, R] = p(null), [le, z] = p(!1), [B, V] = p(""), H = u();
35
+ g(() => {
36
+ let e = j.current;
37
+ if (l !== "fit" || !e) return;
38
+ let t = () => e.clientWidth && se(e.clientWidth / s);
39
+ if (t(), typeof ResizeObserver > "u") return;
40
+ let n = new ResizeObserver(t);
41
+ return n.observe(e), () => n.disconnect();
42
+ }, [l, s]);
43
+ let U = l === "fit" ? N ?? 1 : l, W = new Map(d.map((e) => [e.id, e])), G = {
44
+ width: s,
45
+ height: c,
46
+ min: E
47
+ }, ue = D === !1 ? 0 : (D === !0 ? 6 : D) / U, K = (e) => ({
48
+ others: d.filter((t) => !e.has(t.id)),
49
+ threshold: ue,
50
+ grid: O
51
+ }), q = (e) => {
52
+ S(e, w) || T?.(e);
53
+ }, J = (e) => d.map((t) => {
54
+ let n = e.get(t.id);
55
+ return n ? {
56
+ ...t,
57
+ ...n
58
+ } : t;
59
+ }), Y = (e, t, n, i) => {
60
+ let o = r(e), s = a(o, t, n, G, i), [c, l] = [s.rect.x - o.x, s.rect.y - o.y];
61
+ return {
62
+ rects: new Map(e.map((e) => [e.id, {
63
+ x: e.x + c,
64
+ y: e.y + l,
65
+ w: e.w,
66
+ h: e.h
67
+ }])),
68
+ box: s.rect,
69
+ guides: s.guides
70
+ };
71
+ }, X = (e, t, n) => {
72
+ n.w !== t.w || n.h !== t.h ? V(A.resized(e, n.w, n.h)) : (n.x !== t.x || n.y !== t.y) && V(A.moved(e, n.x, n.y));
73
+ }, Z = (e, t, n) => e.length === 1 && e[0].id === t ? n : `${e.length} items`, de = (e, t, n, i) => {
74
+ let a = W.get(t);
75
+ if (e.button !== 0 || !a || a.locked && !i) return;
76
+ let s = e.target.closest(ee);
77
+ if (!i && s && s !== e.currentTarget && e.currentTarget.contains(s)) return;
78
+ e.preventDefault(), e.stopPropagation();
79
+ let c = e.shiftKey || e.metaKey || e.ctrlKey, l;
80
+ if (l = i ? [t] : c ? w.includes(t) ? w.filter((e) => e !== t) : [...w, t] : w.includes(t) ? [...w] : [t], q(l), M.current = !0, e.currentTarget.closest("[data-canvas-id]")?.focus({ preventScroll: !0 }), M.current = !1, !l.includes(t)) return;
81
+ let u = i ? [a] : l.flatMap((e) => W.get(e) ?? []).filter((e) => !e.locked);
82
+ if (!u.length) return;
83
+ let f = e.currentTarget;
84
+ f.setPointerCapture?.(e.pointerId);
85
+ let p = new Set(u.map((e) => e.id)), m = d, h = r(u), g = Z(u, t, n), b = !1, x = [...d], S = h, C = (n) => {
86
+ if (n.pointerId !== e.pointerId) return;
87
+ let [r, s] = [n.clientX - e.clientX, n.clientY - e.clientY];
88
+ if (!b) {
89
+ if (Math.hypot(r, s) < _) return;
90
+ b = !0, z(!0);
91
+ }
92
+ let [c, l] = [r / U, s / U], d;
93
+ if (i) {
94
+ let e = o(a, i, c, l, G, {
95
+ keepRatio: n.shiftKey,
96
+ ...K(p)
97
+ });
98
+ d = {
99
+ rects: /* @__PURE__ */ new Map([[t, e.rect]]),
100
+ box: e.rect,
101
+ guides: e.guides
102
+ };
103
+ } else d = Y(u, c, l, K(p));
104
+ S = d.box, x = J(d.rects), v(x), P(d.guides), R({
105
+ box: d.box,
106
+ text: i ? `${d.box.w} × ${d.box.h}` : `${d.box.x}, ${d.box.y}`
107
+ });
108
+ }, T = (t) => {
109
+ f.removeEventListener("pointermove", C), f.removeEventListener("pointerup", E), f.removeEventListener("pointercancel", D), window.removeEventListener("keydown", O, !0), f.hasPointerCapture?.(e.pointerId) && f.releasePointerCapture(e.pointerId), P([]), R(null), z(!1), b && (t ? (y?.(x, m), X(g, h, S)) : (v([...m]), V(A.putBack(g))));
110
+ }, E = (t) => t.pointerId === e.pointerId && T(!0), D = (t) => t.pointerId === e.pointerId && T(!1), O = (e) => {
111
+ e.key === "Escape" && (e.preventDefault(), e.stopPropagation(), T(!1));
112
+ };
113
+ f.addEventListener("pointermove", C), f.addEventListener("pointerup", E), f.addEventListener("pointercancel", D), window.addEventListener("keydown", O, !0);
114
+ }, fe = (e) => {
115
+ if (e.button !== 0 || e.target.closest("[data-canvas-id]:not([data-locked])")) return;
116
+ let t = e.currentTarget, n = t.getBoundingClientRect(), r = (e) => ({
117
+ x: Math.min(s, Math.max(0, (e.clientX - n.left) / U)),
118
+ y: Math.min(c, Math.max(0, (e.clientY - n.top) / U))
119
+ }), a = e.shiftKey || e.metaKey || e.ctrlKey ? [...w] : [], o = r(e), l = !1, u = w;
120
+ t.setPointerCapture?.(e.pointerId);
121
+ let f = (t) => {
122
+ if (t.pointerId !== e.pointerId || !l && Math.hypot(t.clientX - e.clientX, t.clientY - e.clientY) < _) return;
123
+ l = !0;
124
+ let n = r(t), s = {
125
+ x: Math.min(o.x, n.x),
126
+ y: Math.min(o.y, n.y),
127
+ w: Math.abs(n.x - o.x),
128
+ h: Math.abs(n.y - o.y)
129
+ };
130
+ I(s);
131
+ let c = d.filter((e) => !e.locked && i(e, s)).map((e) => e.id), f = [...a, ...c.filter((e) => !a.includes(e))];
132
+ S(f, u) || (u = f, T?.(f));
133
+ }, p = (n) => {
134
+ n.pointerId === e.pointerId && (t.removeEventListener("pointermove", f), t.removeEventListener("pointerup", p), t.removeEventListener("pointercancel", p), I(null), n.type !== "pointercancel" && (l ? V(A.selected(u.length)) : a.length || q([])));
135
+ };
136
+ t.addEventListener("pointermove", f), t.addEventListener("pointerup", p), t.addEventListener("pointercancel", p);
137
+ }, pe = (e, t, n) => {
138
+ let i = W.get(t);
139
+ if (!i || e.target !== e.currentTarget) return;
140
+ if (e.key === "Escape") {
141
+ if (!w.length) return;
142
+ e.preventDefault(), q([]);
143
+ return;
144
+ }
145
+ if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "a") {
146
+ e.preventDefault();
147
+ let t = d.filter((e) => !e.locked).map((e) => e.id);
148
+ q(t), V(A.selected(t.length));
149
+ return;
150
+ }
151
+ let a = b[e.key];
152
+ if (!a) return;
153
+ e.preventDefault();
154
+ let s = e.shiftKey ? 10 : 1, [c, l] = [a[0] * s, a[1] * s], u = (w.includes(t) ? w : [t]).flatMap((e) => W.get(e) ?? []).filter((e) => !e.locked), f = e.altKey ? u.filter((e) => e.id === t) : u;
155
+ if (!f.length) return;
156
+ let p = e.altKey ? /* @__PURE__ */ new Map([[t, o(i, "se", c, l, G).rect]]) : Y(f, c, l).rects;
157
+ if ([...p].every(([e, t]) => x(t, W.get(e)))) return;
158
+ let m = J(p);
159
+ v(m), y?.(m, d), X(Z(f, t, n), r(f), r([...p.values()]));
160
+ }, me = (e) => {
161
+ !M.current && !w.includes(e) && q([e]);
162
+ }, Q = L && {
163
+ left: Math.min(s * U - 28, Math.max(28, (L.box.x + L.box.w / 2) * U)),
164
+ top: (L.box.y + L.box.h) * U + 26 > c * U ? Math.max(4, L.box.y * U - 26) : (L.box.y + L.box.h) * U + 6
165
+ }, $ = le && O && O * U >= 6 ? O * U : 0;
166
+ return /* @__PURE__ */ h(C.Provider, {
167
+ value: {
168
+ item: (e) => W.get(e),
169
+ selected: w,
170
+ grab: de,
171
+ key: pe,
172
+ focus: me,
173
+ hintId: H
174
+ },
175
+ children: [
176
+ /* @__PURE__ */ h("div", {
177
+ role: "group",
178
+ ...k,
179
+ ref: oe,
180
+ onPointerDown: (e) => {
181
+ ie?.(e), e.defaultPrevented || fe(e);
182
+ },
183
+ style: {
184
+ ...ne,
185
+ ...l === "fit" ? {
186
+ width: "100%",
187
+ aspectRatio: `${s} / ${c}`
188
+ } : {
189
+ width: s * U,
190
+ height: c * U
191
+ }
192
+ },
193
+ className: e("zen__canvas bg-tint/[0.03] relative shrink-0 overflow-hidden rounded-lg shadow-[inset_0_0_0_1px_oklch(var(--tint)/0.08)] select-none", te),
194
+ children: [/* @__PURE__ */ m("div", {
195
+ style: {
196
+ width: s,
197
+ height: c,
198
+ scale: String(U),
199
+ "--canvas-scale": U
200
+ },
201
+ className: e("absolute top-0 left-0 origin-top-left", l === "fit" && N === null && "invisible"),
202
+ children: re
203
+ }), /* @__PURE__ */ h("div", {
204
+ "aria-hidden": !0,
205
+ className: "pointer-events-none absolute inset-0",
206
+ children: [
207
+ $ > 0 && /* @__PURE__ */ m("div", {
208
+ "data-canvas-grid": "",
209
+ className: "absolute inset-0",
210
+ style: {
211
+ backgroundImage: "radial-gradient(circle, oklch(var(--tint) / 0.22) 1px, transparent 1.5px)",
212
+ backgroundSize: `${$}px ${$}px`,
213
+ backgroundPosition: `${-$ / 2}px ${-$ / 2}px`
214
+ }
215
+ }),
216
+ ce.map((e) => /* @__PURE__ */ m("span", {
217
+ "data-canvas-guide": "",
218
+ className: "bg-primary absolute shadow-[0_0_6px_oklch(var(--glow)/0.8)]",
219
+ style: e.axis === "x" ? {
220
+ left: e.at * U,
221
+ top: 0,
222
+ bottom: 0,
223
+ width: 1
224
+ } : {
225
+ top: e.at * U,
226
+ left: 0,
227
+ right: 0,
228
+ height: 1
229
+ }
230
+ }, `${e.axis}${e.at}`)),
231
+ F && /* @__PURE__ */ m("span", {
232
+ "data-canvas-marquee": "",
233
+ className: "border-primary/60 bg-primary/10 absolute rounded-sm border",
234
+ style: {
235
+ left: F.x * U,
236
+ top: F.y * U,
237
+ width: F.w * U,
238
+ height: F.h * U
239
+ }
240
+ }),
241
+ Q && /* @__PURE__ */ m("span", {
242
+ "data-canvas-readout": "",
243
+ className: "bg-primary text-primary-foreground absolute -translate-x-1/2 rounded-md px-1.5 py-0.5 text-[11px] leading-4 font-medium whitespace-nowrap tabular-nums shadow-[0_4px_14px_-4px_oklch(var(--glow)/0.7)]",
244
+ style: Q,
245
+ children: L.text
246
+ })
247
+ ]
248
+ })]
249
+ }),
250
+ /* @__PURE__ */ m("span", {
251
+ id: H,
252
+ hidden: !0,
253
+ children: A.canvasHelp
254
+ }),
255
+ /* @__PURE__ */ m("span", {
256
+ "aria-live": "assertive",
257
+ className: "sr-only",
258
+ children: B
259
+ })
260
+ ]
261
+ });
262
+ }
263
+ function T({ id: t, label: n, className: r, style: i, children: a, ...o }) {
264
+ let s = c(C);
265
+ if (!s) throw Error("<CanvasItem> must be inside <Canvas>");
266
+ let l = s.item(t);
267
+ if (!l) return null;
268
+ let u = s.selected.includes(t), d = u && s.selected.length === 1;
269
+ return /* @__PURE__ */ h("div", {
270
+ role: "group",
271
+ "aria-roledescription": l.locked ? "locked item" : "movable item",
272
+ "aria-label": n,
273
+ "aria-describedby": l.locked ? void 0 : s.hintId,
274
+ tabIndex: 0,
275
+ "data-canvas-id": t,
276
+ "data-selected": u || void 0,
277
+ "data-locked": l.locked || void 0,
278
+ ...o,
279
+ onFocus: (e) => {
280
+ o.onFocus?.(e), e.target === e.currentTarget && s.focus(t);
281
+ },
282
+ onPointerDown: (e) => {
283
+ o.onPointerDown?.(e), s.grab(e, t, n);
284
+ },
285
+ onKeyDown: (e) => {
286
+ o.onKeyDown?.(e), s.key(e, t, n);
287
+ },
288
+ style: {
289
+ ...i,
290
+ left: l.x,
291
+ top: l.y,
292
+ width: l.w,
293
+ height: l.h
294
+ },
295
+ className: e("zen__canvas-item absolute cursor-move touch-none outline-hidden data-locked:cursor-default data-locked:touch-auto", "[outline-offset:calc(1px/var(--canvas-scale))]", "not-data-selected:hover:outline-solid not-data-selected:hover:outline-[length:calc(1px/var(--canvas-scale))] not-data-selected:hover:outline-[color:oklch(var(--tint)/0.35)]", "data-selected:outline-solid data-selected:outline-[length:calc(2px/var(--canvas-scale))] data-selected:outline-[color:oklch(var(--primary)/0.8)]", "focus-visible:outline-solid focus-visible:outline-[length:calc(2px/var(--canvas-scale))] focus-visible:outline-[color:oklch(var(--ring)/0.7)]", r),
296
+ children: [a, d && !l.locked && v.map((r) => /* @__PURE__ */ m("span", {
297
+ "aria-hidden": !0,
298
+ "data-handle": r,
299
+ onPointerDown: (e) => s.grab(e, t, n, r),
300
+ className: e("bg-foreground absolute z-10 size-[calc(10px/var(--canvas-scale))] -translate-1/2 rounded-full border-[length:calc(2px/var(--canvas-scale))] border-[color:oklch(var(--primary))] shadow-[0_0_8px_oklch(var(--glow)/0.6)]", "after:absolute after:-inset-[calc(6px/var(--canvas-scale))] pointer-coarse:after:-inset-[calc(14px/var(--canvas-scale))]", y[r])
301
+ }, r))]
302
+ });
303
+ }
304
+ //#endregion
305
+ export { w as Canvas, T as CanvasItem };