@vertz/ui-primitives 0.2.41 → 0.2.42

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 (232) hide show
  1. package/dist/shared/chunk-06m8prfg.js +52 -0
  2. package/dist/shared/chunk-0n9jj8xr.js +24 -0
  3. package/dist/shared/chunk-1ben27xq.js +317 -0
  4. package/dist/shared/chunk-1j2mj0sa.js +45 -0
  5. package/dist/shared/chunk-250hj18f.js +243 -0
  6. package/dist/shared/chunk-2h4m9c71.js +38 -0
  7. package/dist/shared/chunk-2sbx20hv.js +128 -0
  8. package/dist/shared/chunk-2ye674gr.js +70 -0
  9. package/dist/shared/chunk-34d8385y.js +15 -0
  10. package/dist/shared/chunk-4d7bm8h0.js +113 -0
  11. package/dist/shared/chunk-4zjgxr7x.js +157 -0
  12. package/dist/shared/chunk-5c150wvr.js +140 -0
  13. package/dist/shared/chunk-5gycdypd.js +58 -0
  14. package/dist/shared/chunk-6mm7fhp8.js +105 -0
  15. package/dist/shared/chunk-6zmnqvh6.js +109 -0
  16. package/dist/shared/{chunk-yy3ft5mb.js → chunk-7amn5d71.js} +2 -2
  17. package/dist/shared/chunk-7pbff2hg.js +118 -0
  18. package/dist/shared/chunk-7zpjshwz.js +194 -0
  19. package/dist/shared/chunk-993ff51d.js +155 -0
  20. package/dist/shared/chunk-9pdt5aw7.js +24 -0
  21. package/dist/shared/chunk-a71m4xkv.js +106 -0
  22. package/dist/shared/chunk-aj8m39pk.js +127 -0
  23. package/dist/shared/chunk-ajawpc05.js +305 -0
  24. package/dist/shared/chunk-b7mzwqhj.js +125 -0
  25. package/dist/shared/chunk-bb887de4.js +200 -0
  26. package/dist/shared/chunk-bfsmbrxc.js +111 -0
  27. package/dist/shared/chunk-c2f63m5n.js +56 -0
  28. package/dist/shared/chunk-c5r3s5km.js +263 -0
  29. package/dist/shared/chunk-caba5bhd.js +427 -0
  30. package/dist/shared/chunk-crym07yc.js +264 -0
  31. package/dist/shared/{chunk-5964gmv0.js → chunk-csjtyvam.js} +62 -88
  32. package/dist/shared/chunk-d6rtejz3.js +128 -0
  33. package/dist/shared/chunk-dvaf0bmq.js +140 -0
  34. package/dist/shared/chunk-dwkv9ya6.js +22 -0
  35. package/dist/shared/chunk-e0ckxrjg.js +41 -0
  36. package/dist/shared/chunk-ennxcymj.js +225 -0
  37. package/dist/shared/{chunk-1jd1n0dt.js → chunk-ey38de46.js} +19 -47
  38. package/dist/shared/chunk-f0v1gs5e.js +52 -0
  39. package/dist/shared/chunk-f86rsf84.js +231 -0
  40. package/dist/shared/{chunk-3sahbk4d.js → chunk-fdse46x5.js} +6 -1
  41. package/dist/shared/chunk-gj4hrssn.js +135 -0
  42. package/dist/shared/chunk-gyvq4gk9.js +24 -0
  43. package/dist/shared/chunk-hbnps9sq.js +229 -0
  44. package/dist/shared/{chunk-fhss32ya.js → chunk-hdmpyeq9.js} +43 -132
  45. package/dist/shared/chunk-hgnkd4he.js +256 -0
  46. package/dist/shared/chunk-hpcyffm7.js +185 -0
  47. package/dist/shared/chunk-hpmvwx0h.js +99 -0
  48. package/dist/shared/chunk-hz0e504p.js +69 -0
  49. package/dist/shared/chunk-hzk4wfq9.js +43 -0
  50. package/dist/shared/chunk-j7znzkpa.js +48 -0
  51. package/dist/shared/chunk-j9kxgrnn.js +167 -0
  52. package/dist/shared/chunk-jetwnv0w.js +130 -0
  53. package/dist/shared/chunk-jjdg26c1.js +155 -0
  54. package/dist/shared/chunk-k0m4yh86.js +123 -0
  55. package/dist/shared/chunk-k43q9cjr.js +82 -0
  56. package/dist/shared/chunk-k9k8tbr5.js +119 -0
  57. package/dist/shared/chunk-meaj7br1.js +232 -0
  58. package/dist/shared/chunk-mgj0n08k.js +34 -0
  59. package/dist/shared/chunk-mjz4rp6c.js +46 -0
  60. package/dist/shared/chunk-n4rr5gme.js +239 -0
  61. package/dist/shared/chunk-nk55etpp.js +65 -0
  62. package/dist/shared/chunk-nkh1ks3k.js +264 -0
  63. package/dist/shared/chunk-pgvpvbpe.js +26 -0
  64. package/dist/shared/chunk-pma8gnv7.js +178 -0
  65. package/dist/shared/chunk-q7xv6xze.js +131 -0
  66. package/dist/shared/chunk-qey801nq.js +22 -0
  67. package/dist/shared/chunk-s6b4c3tj.js +58 -0
  68. package/dist/shared/chunk-sq27a4h0.js +36 -0
  69. package/dist/shared/chunk-taa5pj15.js +103 -0
  70. package/dist/shared/chunk-tc5rpvyx.js +127 -0
  71. package/dist/shared/chunk-tescm0b3.js +192 -0
  72. package/dist/shared/chunk-tkftdwnq.js +71 -0
  73. package/dist/shared/chunk-tqhnjcfp.js +116 -0
  74. package/dist/shared/chunk-vfknb5ht.js +183 -0
  75. package/dist/shared/chunk-vsc369w3.js +185 -0
  76. package/dist/shared/chunk-whq9s8v5.js +301 -0
  77. package/dist/shared/{chunk-hze1f32t.js → chunk-wrqddgaj.js} +1 -1
  78. package/dist/shared/chunk-yzbmkx4r.js +155 -0
  79. package/dist/shared/chunk-zaen0ajc.js +347 -0
  80. package/dist/src/accordion/accordion-composed.js +1 -1
  81. package/dist/src/accordion/accordion.js +1 -1
  82. package/dist/src/alert/alert-composed.js +1 -1
  83. package/dist/src/alert-dialog/alert-dialog-composed.js +1 -1
  84. package/dist/src/alert-dialog/alert-dialog.js +1 -1
  85. package/dist/src/avatar/avatar-composed.js +1 -1
  86. package/dist/src/badge/badge-composed.js +1 -1
  87. package/dist/src/badge/badge.js +1 -1
  88. package/dist/src/breadcrumb/breadcrumb-composed.js +1 -1
  89. package/dist/src/button/button-composed.js +1 -1
  90. package/dist/src/button/button.js +1 -1
  91. package/dist/src/calendar/calendar-composed.js +1 -1
  92. package/dist/src/calendar/calendar.js +1 -1
  93. package/dist/src/card/card-composed.js +1 -1
  94. package/dist/src/carousel/carousel-composed.js +1 -1
  95. package/dist/src/carousel/carousel.js +1 -1
  96. package/dist/src/checkbox/checkbox-composed.js +1 -1
  97. package/dist/src/checkbox/checkbox.js +1 -1
  98. package/dist/src/collapsible/collapsible-composed.js +1 -1
  99. package/dist/src/collapsible/collapsible.js +1 -1
  100. package/dist/src/combobox/combobox-composed.js +1 -1
  101. package/dist/src/combobox/combobox.js +1 -1
  102. package/dist/src/command/command-composed.js +1 -1
  103. package/dist/src/command/command.js +1 -1
  104. package/dist/src/composed/with-styles.js +1 -1
  105. package/dist/src/context-menu/context-menu-composed.js +1 -1
  106. package/dist/src/context-menu/context-menu.js +1 -1
  107. package/dist/src/date-picker/date-picker-composed.js +1 -1
  108. package/dist/src/date-picker/date-picker.js +1 -1
  109. package/dist/src/dialog/dialog-composed.js +1 -1
  110. package/dist/src/dialog/dialog-stack-parts.js +1 -1
  111. package/dist/src/dialog/dialog.js +1 -1
  112. package/dist/src/dropdown-menu/dropdown-menu-composed.js +1 -1
  113. package/dist/src/dropdown-menu/dropdown-menu.js +1 -1
  114. package/dist/src/empty-state/empty-state-composed.js +1 -1
  115. package/dist/src/form-group/form-group-composed.js +1 -1
  116. package/dist/src/hover-card/hover-card-composed.js +1 -1
  117. package/dist/src/hover-card/hover-card.js +1 -1
  118. package/dist/src/input/input-composed.js +1 -1
  119. package/dist/src/label/label-composed.js +1 -1
  120. package/dist/src/list/list-composed.js +1 -1
  121. package/dist/src/menu/menu-composed.js +1 -1
  122. package/dist/src/menu/menu.js +1 -1
  123. package/dist/src/menubar/menubar-composed.js +1 -1
  124. package/dist/src/menubar/menubar.js +1 -1
  125. package/dist/src/navigation-menu/navigation-menu-composed.js +1 -1
  126. package/dist/src/navigation-menu/navigation-menu.js +1 -1
  127. package/dist/src/pagination/pagination-composed.js +1 -1
  128. package/dist/src/popover/popover-composed.js +1 -1
  129. package/dist/src/popover/popover.js +1 -1
  130. package/dist/src/progress/progress-composed.js +1 -1
  131. package/dist/src/progress/progress.js +1 -1
  132. package/dist/src/radio/radio-composed.js +1 -1
  133. package/dist/src/radio/radio.js +1 -1
  134. package/dist/src/resizable-panel/resizable-panel-composed.js +1 -1
  135. package/dist/src/resizable-panel/resizable-panel.js +1 -1
  136. package/dist/src/scroll-area/scroll-area-composed.js +1 -1
  137. package/dist/src/scroll-area/scroll-area.js +1 -1
  138. package/dist/src/select/select-composed.js +1 -1
  139. package/dist/src/select/select.js +1 -1
  140. package/dist/src/separator/separator-composed.js +1 -1
  141. package/dist/src/sheet/sheet-composed.js +1 -1
  142. package/dist/src/sheet/sheet.js +1 -1
  143. package/dist/src/skeleton/skeleton-composed.js +1 -1
  144. package/dist/src/slider/slider-composed.js +1 -1
  145. package/dist/src/slider/slider.js +1 -1
  146. package/dist/src/switch/switch-composed.js +1 -1
  147. package/dist/src/switch/switch.js +1 -1
  148. package/dist/src/table/table-composed.js +1 -1
  149. package/dist/src/tabs/tabs-composed.js +1 -1
  150. package/dist/src/tabs/tabs.js +1 -1
  151. package/dist/src/textarea/textarea-composed.js +1 -1
  152. package/dist/src/toast/toast.js +1 -1
  153. package/dist/src/toggle/toggle-composed.js +1 -1
  154. package/dist/src/toggle/toggle.js +1 -1
  155. package/dist/src/toggle-group/toggle-group-composed.js +1 -1
  156. package/dist/src/toggle-group/toggle-group.js +1 -1
  157. package/dist/src/tooltip/tooltip-composed.js +1 -1
  158. package/dist/src/tooltip/tooltip.js +1 -1
  159. package/package.json +3 -3
  160. package/dist/shared/chunk-144kbnmx.js +0 -95
  161. package/dist/shared/chunk-1ewxfgsa.js +0 -167
  162. package/dist/shared/chunk-1hm0mbke.js +0 -258
  163. package/dist/shared/chunk-22rt6ws9.js +0 -69
  164. package/dist/shared/chunk-2ssqz188.js +0 -162
  165. package/dist/shared/chunk-33he7ay9.js +0 -218
  166. package/dist/shared/chunk-3jack97k.js +0 -509
  167. package/dist/shared/chunk-75pegjs7.js +0 -26
  168. package/dist/shared/chunk-862x7dja.js +0 -398
  169. package/dist/shared/chunk-8pk1pn5h.js +0 -215
  170. package/dist/shared/chunk-8t0nm721.js +0 -152
  171. package/dist/shared/chunk-94twh4s4.js +0 -28
  172. package/dist/shared/chunk-9yb26c0w.js +0 -232
  173. package/dist/shared/chunk-a82r2pnq.js +0 -67
  174. package/dist/shared/chunk-axpbdpgx.js +0 -177
  175. package/dist/shared/chunk-b3j6mym6.js +0 -203
  176. package/dist/shared/chunk-b4zzg457.js +0 -410
  177. package/dist/shared/chunk-b9qxfcsy.js +0 -60
  178. package/dist/shared/chunk-bc2qqkhr.js +0 -194
  179. package/dist/shared/chunk-bv12nkdm.js +0 -149
  180. package/dist/shared/chunk-bvxc1ww4.js +0 -164
  181. package/dist/shared/chunk-czv0kqj4.js +0 -107
  182. package/dist/shared/chunk-d83ag07h.js +0 -189
  183. package/dist/shared/chunk-de18ashk.js +0 -134
  184. package/dist/shared/chunk-dvk4h36t.js +0 -140
  185. package/dist/shared/chunk-dxvnerw2.js +0 -353
  186. package/dist/shared/chunk-e399pzdq.js +0 -241
  187. package/dist/shared/chunk-e4qha9as.js +0 -180
  188. package/dist/shared/chunk-eb2d9v6k.js +0 -68
  189. package/dist/shared/chunk-ect26sp5.js +0 -353
  190. package/dist/shared/chunk-ev367pq3.js +0 -102
  191. package/dist/shared/chunk-fjykbv0v.js +0 -214
  192. package/dist/shared/chunk-gdddk6nh.js +0 -96
  193. package/dist/shared/chunk-ghkw5bjq.js +0 -55
  194. package/dist/shared/chunk-hfjtkytb.js +0 -310
  195. package/dist/shared/chunk-hpvjfj0j.js +0 -31
  196. package/dist/shared/chunk-jpyjk616.js +0 -52
  197. package/dist/shared/chunk-k6d53tne.js +0 -206
  198. package/dist/shared/chunk-knzg86am.js +0 -168
  199. package/dist/shared/chunk-ktbf6xrt.js +0 -179
  200. package/dist/shared/chunk-m8y2p66x.js +0 -252
  201. package/dist/shared/chunk-metxdt5x.js +0 -28
  202. package/dist/shared/chunk-mgae1d93.js +0 -157
  203. package/dist/shared/chunk-mtx2cfbx.js +0 -175
  204. package/dist/shared/chunk-n436p5cb.js +0 -260
  205. package/dist/shared/chunk-nj420k31.js +0 -54
  206. package/dist/shared/chunk-nsmvdxgp.js +0 -213
  207. package/dist/shared/chunk-pcms04vq.js +0 -162
  208. package/dist/shared/chunk-pqskzq8t.js +0 -79
  209. package/dist/shared/chunk-pwr60kyd.js +0 -321
  210. package/dist/shared/chunk-pzknpa1y.js +0 -327
  211. package/dist/shared/chunk-q77y3rg4.js +0 -189
  212. package/dist/shared/chunk-qhnany7w.js +0 -179
  213. package/dist/shared/chunk-rdr0rtpr.js +0 -131
  214. package/dist/shared/chunk-rj52ty6r.js +0 -147
  215. package/dist/shared/chunk-rnqc7735.js +0 -125
  216. package/dist/shared/chunk-rtk30950.js +0 -202
  217. package/dist/shared/chunk-s0xgd8vg.js +0 -266
  218. package/dist/shared/chunk-s415735j.js +0 -357
  219. package/dist/shared/chunk-s62e7jf4.js +0 -30
  220. package/dist/shared/chunk-snd8e6r8.js +0 -418
  221. package/dist/shared/chunk-spng4yb9.js +0 -73
  222. package/dist/shared/chunk-t887wwjc.js +0 -168
  223. package/dist/shared/chunk-tn0m98j8.js +0 -42
  224. package/dist/shared/chunk-v0b5pkcq.js +0 -30
  225. package/dist/shared/chunk-v5tj7veh.js +0 -284
  226. package/dist/shared/chunk-vkscwzpr.js +0 -294
  227. package/dist/shared/chunk-vv187snj.js +0 -112
  228. package/dist/shared/chunk-xv4wd0kf.js +0 -293
  229. package/dist/shared/chunk-y1hpsqzy.js +0 -185
  230. package/dist/shared/chunk-yfzddvxc.js +0 -71
  231. package/dist/shared/chunk-yzgzx2dh.js +0 -311
  232. package/dist/shared/chunk-z5j7ztf2.js +0 -467
@@ -0,0 +1,427 @@
1
+ import {
2
+ cn
3
+ } from "./chunk-q7xbcj9q.js";
4
+
5
+ // src/calendar/calendar-composed.tsx
6
+ import { jsxDEV as jsxDEV_7x81h0kn, Fragment as Fragment_8vg9x3sq } from "@vertz/ui/jsx-dev-runtime";
7
+ var MONTH_NAMES = [
8
+ "January",
9
+ "February",
10
+ "March",
11
+ "April",
12
+ "May",
13
+ "June",
14
+ "July",
15
+ "August",
16
+ "September",
17
+ "October",
18
+ "November",
19
+ "December"
20
+ ];
21
+ var DAY_NAMES = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
22
+ var MONTH_OPTIONS = MONTH_NAMES.map((name, index) => ({ name, index }));
23
+ function getDaysInMonth(year, month) {
24
+ return new Date(year, month + 1, 0).getDate();
25
+ }
26
+ function isSameDay(a, b) {
27
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
28
+ }
29
+ function addDays(date, days) {
30
+ const result = new Date(date);
31
+ result.setDate(result.getDate() + days);
32
+ return result;
33
+ }
34
+ function addMonths(date, months) {
35
+ const result = new Date(date);
36
+ result.setMonth(result.getMonth() + months);
37
+ return result;
38
+ }
39
+ function formatDate(date) {
40
+ const y = date.getFullYear();
41
+ const m = String(date.getMonth() + 1).padStart(2, "0");
42
+ const d = String(date.getDate()).padStart(2, "0");
43
+ return `${y}-${m}-${d}`;
44
+ }
45
+ function isSelectedDate(date, val) {
46
+ if (val === null)
47
+ return false;
48
+ if (val instanceof Date)
49
+ return isSameDay(val, date);
50
+ if (Array.isArray(val))
51
+ return val.some((d) => isSameDay(d, date));
52
+ if ("from" in val && "to" in val) {
53
+ return isSameDay(val.from, date) || isSameDay(val.to, date);
54
+ }
55
+ return false;
56
+ }
57
+ function isInRangeDate(date, val) {
58
+ if (val === null || !("from" in val))
59
+ return false;
60
+ const range = val;
61
+ return date > range.from && date < range.to;
62
+ }
63
+ function isDateDisabledCheck(date, minDate, maxDate, disabled) {
64
+ if (disabled?.(date))
65
+ return true;
66
+ if (minDate && date < minDate && !isSameDay(date, minDate))
67
+ return true;
68
+ if (maxDate && date > maxDate && !isSameDay(date, maxDate))
69
+ return true;
70
+ return false;
71
+ }
72
+ function computeYearRange(now, minDate, maxDate) {
73
+ const minYear = minDate ? minDate.getFullYear() : now.getFullYear() - 100;
74
+ const maxYear = maxDate ? maxDate.getFullYear() : now.getFullYear() + 10;
75
+ const years = [];
76
+ for (let y = minYear;y <= maxYear; y++) {
77
+ years.push(y);
78
+ }
79
+ return years;
80
+ }
81
+ function isMonthDisabled(month, year, minDate, maxDate) {
82
+ if (minDate && year === minDate.getFullYear() && month < minDate.getMonth())
83
+ return true;
84
+ if (maxDate && year === maxDate.getFullYear() && month > maxDate.getMonth())
85
+ return true;
86
+ return false;
87
+ }
88
+ function computeGridRows(display, weekStartsOn) {
89
+ const year = display.getFullYear();
90
+ const month = display.getMonth();
91
+ const daysInMonth = getDaysInMonth(year, month);
92
+ const firstDay = new Date(year, month, 1);
93
+ const firstDayOfWeek = firstDay.getDay();
94
+ const offset = (firstDayOfWeek - weekStartsOn + 7) % 7;
95
+ const startDate = addDays(firstDay, -offset);
96
+ const totalCells = offset + daysInMonth;
97
+ const totalRows = Math.ceil(totalCells / 7);
98
+ const rows = [];
99
+ let current = startDate;
100
+ for (let row = 0;row < totalRows; row++) {
101
+ const rowDates = [];
102
+ for (let col = 0;col < 7; col++) {
103
+ rowDates.push(new Date(current));
104
+ current = addDays(current, 1);
105
+ }
106
+ rows.push(rowDates);
107
+ }
108
+ return rows;
109
+ }
110
+ function DayCell({
111
+ cellDate,
112
+ displayMonth,
113
+ now,
114
+ mode,
115
+ value,
116
+ minDate,
117
+ maxDate,
118
+ disabled,
119
+ classes,
120
+ onSelect
121
+ }) {
122
+ const dateStr = formatDate(cellDate);
123
+ const isOutside = cellDate.getMonth() !== displayMonth.getMonth();
124
+ const isToday = isSameDay(cellDate, now);
125
+ const isDisabled = isDateDisabledCheck(cellDate, minDate, maxDate, disabled);
126
+ const selected = isSelectedDate(cellDate, value);
127
+ const rangeVal = value;
128
+ const isRangeStart = mode === "range" && rangeVal && "from" in rangeVal && isSameDay(cellDate, rangeVal.from);
129
+ const isRangeEnd = mode === "range" && rangeVal && "to" in rangeVal && isSameDay(cellDate, rangeVal.to);
130
+ const inRange = mode === "range" && isInRangeDate(cellDate, value);
131
+ return jsxDEV_7x81h0kn("button", {
132
+ type: "button",
133
+ class: cn(classes?.dayButton),
134
+ "data-date": dateStr,
135
+ "data-outside-month": isOutside ? "true" : undefined,
136
+ "data-today": isToday ? "true" : undefined,
137
+ "aria-disabled": isDisabled ? "true" : undefined,
138
+ "aria-selected": selected ? "true" : undefined,
139
+ "data-range-start": isRangeStart ? "true" : undefined,
140
+ "data-range-end": isRangeEnd ? "true" : undefined,
141
+ "data-in-range": inRange ? "true" : undefined,
142
+ onClick: () => onSelect(cellDate),
143
+ children: cellDate.getDate()
144
+ }, undefined, false, undefined, this);
145
+ }
146
+ function ComposedCalendarRoot({
147
+ classes,
148
+ mode: modeProp = "single",
149
+ defaultValue,
150
+ defaultMonth: defaultMonthProp,
151
+ minDate,
152
+ maxDate,
153
+ disabled,
154
+ weekStartsOn = 0,
155
+ onValueChange,
156
+ onMonthChange,
157
+ captionLayout = "buttons"
158
+ }) {
159
+ const now = new Date;
160
+ const mode = modeProp;
161
+ let displayMonth = defaultMonthProp ?? now;
162
+ let value = defaultValue ?? null;
163
+ const dayHeaders = Array.from({ length: 7 }, (_, i) => DAY_NAMES[(weekStartsOn + i) % 7] ?? "");
164
+ function selectDate(date) {
165
+ if (isDateDisabledCheck(date, minDate, maxDate, disabled))
166
+ return;
167
+ if (mode === "single") {
168
+ value = date;
169
+ } else if (mode === "multiple") {
170
+ const current = value ?? [];
171
+ const existing = current.findIndex((d) => isSameDay(d, date));
172
+ if (existing >= 0) {
173
+ const next = [...current];
174
+ next.splice(existing, 1);
175
+ value = next;
176
+ } else {
177
+ value = [...current, date];
178
+ }
179
+ } else if (mode === "range") {
180
+ const current = value;
181
+ if (!current || "to" in current && current.to) {
182
+ value = { from: date, to: date };
183
+ } else {
184
+ if (date < current.from) {
185
+ value = { from: date, to: current.from };
186
+ } else {
187
+ value = { from: current.from, to: date };
188
+ }
189
+ }
190
+ }
191
+ onValueChange?.(value);
192
+ }
193
+ function navigateMonth(delta) {
194
+ displayMonth = addMonths(displayMonth, delta);
195
+ onMonthChange?.(displayMonth);
196
+ }
197
+ function handleGridKeydown(event) {
198
+ const gridEl = event.currentTarget;
199
+ const active = document.activeElement;
200
+ if (!active || active.tagName !== "BUTTON")
201
+ return;
202
+ const dateStr = active.getAttribute("data-date");
203
+ if (!dateStr)
204
+ return;
205
+ const focused = new Date(`${dateStr}T00:00:00`);
206
+ let next = null;
207
+ if (event.key === "ArrowLeft") {
208
+ event.preventDefault();
209
+ next = addDays(focused, -1);
210
+ } else if (event.key === "ArrowRight") {
211
+ event.preventDefault();
212
+ next = addDays(focused, 1);
213
+ } else if (event.key === "ArrowUp") {
214
+ event.preventDefault();
215
+ next = addDays(focused, -7);
216
+ } else if (event.key === "ArrowDown") {
217
+ event.preventDefault();
218
+ next = addDays(focused, 7);
219
+ } else if (event.key === "Home") {
220
+ event.preventDefault();
221
+ const dayOfWeek = (focused.getDay() - weekStartsOn + 7) % 7;
222
+ next = addDays(focused, -dayOfWeek);
223
+ } else if (event.key === "End") {
224
+ event.preventDefault();
225
+ const dayOfWeek = (focused.getDay() - weekStartsOn + 7) % 7;
226
+ next = addDays(focused, 6 - dayOfWeek);
227
+ } else if (event.key === "PageUp") {
228
+ event.preventDefault();
229
+ next = event.shiftKey ? addMonths(focused, -12) : addMonths(focused, -1);
230
+ } else if (event.key === "PageDown") {
231
+ event.preventDefault();
232
+ next = event.shiftKey ? addMonths(focused, 12) : addMonths(focused, 1);
233
+ } else if (event.key === "Enter" || event.key === " ") {
234
+ event.preventDefault();
235
+ selectDate(focused);
236
+ return;
237
+ }
238
+ if (next) {
239
+ if (showDropdowns) {
240
+ const minYear = yearRange[0] ?? now.getFullYear();
241
+ const maxYear = yearRange[yearRange.length - 1] ?? now.getFullYear();
242
+ const minMo = minDate && next.getFullYear() === minDate.getFullYear() ? minDate.getMonth() : 0;
243
+ const maxMo = maxDate && next.getFullYear() === maxDate.getFullYear() ? maxDate.getMonth() : 11;
244
+ if (next.getFullYear() < minYear || next.getFullYear() > maxYear || next.getFullYear() === minYear && next.getMonth() < minMo || next.getFullYear() === maxYear && next.getMonth() > maxMo) {
245
+ return;
246
+ }
247
+ }
248
+ const needsMonthChange = next.getMonth() !== displayMonth.getMonth() || next.getFullYear() !== displayMonth.getFullYear();
249
+ if (needsMonthChange) {
250
+ displayMonth = new Date(next.getFullYear(), next.getMonth(), 1);
251
+ onMonthChange?.(displayMonth);
252
+ }
253
+ const dateKey = formatDate(next);
254
+ const focusBtn = () => {
255
+ const btn = gridEl.querySelector(`button[data-date="${dateKey}"]`);
256
+ btn?.focus();
257
+ };
258
+ if (needsMonthChange) {
259
+ queueMicrotask(focusBtn);
260
+ } else {
261
+ focusBtn();
262
+ }
263
+ }
264
+ }
265
+ const titleText = `${MONTH_NAMES[displayMonth.getMonth()]} ${displayMonth.getFullYear()}`;
266
+ const showDropdowns = captionLayout === "dropdown" || captionLayout === "dropdown-buttons";
267
+ const showButtons = captionLayout === "buttons" || captionLayout === "dropdown-buttons";
268
+ const yearRange = showDropdowns ? computeYearRange(now, minDate, maxDate) : [];
269
+ function handleMonthSelect(event) {
270
+ const target = event.target;
271
+ const newMonth = Number(target.value);
272
+ if (isMonthDisabled(newMonth, displayMonth.getFullYear(), minDate, maxDate))
273
+ return;
274
+ displayMonth = new Date(displayMonth.getFullYear(), newMonth, 1);
275
+ onMonthChange?.(displayMonth);
276
+ }
277
+ function handleYearSelect(event) {
278
+ const target = event.target;
279
+ const newYear = Number(target.value);
280
+ let month = displayMonth.getMonth();
281
+ if (isMonthDisabled(month, newYear, minDate, maxDate)) {
282
+ if (minDate && newYear === minDate.getFullYear())
283
+ month = minDate.getMonth();
284
+ else if (maxDate && newYear === maxDate.getFullYear())
285
+ month = maxDate.getMonth();
286
+ }
287
+ displayMonth = new Date(newYear, month, 1);
288
+ onMonthChange?.(displayMonth);
289
+ }
290
+ const effectiveMinYear = showDropdowns ? yearRange[0] ?? now.getFullYear() : 0;
291
+ const effectiveMaxYear = showDropdowns ? yearRange[yearRange.length - 1] ?? now.getFullYear() : 9999;
292
+ const effectiveMinMonth = minDate && effectiveMinYear === minDate.getFullYear() ? minDate.getMonth() : 0;
293
+ const effectiveMaxMonth = maxDate && effectiveMaxYear === maxDate.getFullYear() ? maxDate.getMonth() : 11;
294
+ const isAtMinBoundary = showDropdowns && displayMonth.getFullYear() === effectiveMinYear && displayMonth.getMonth() === effectiveMinMonth;
295
+ const isAtMaxBoundary = showDropdowns && displayMonth.getFullYear() === effectiveMaxYear && displayMonth.getMonth() === effectiveMaxMonth;
296
+ const rows = computeGridRows(displayMonth, weekStartsOn);
297
+ const prevChevron = jsxDEV_7x81h0kn("svg", {
298
+ xmlns: "http://www.w3.org/2000/svg",
299
+ width: "16",
300
+ height: "16",
301
+ viewBox: "0 0 24 24",
302
+ fill: "none",
303
+ stroke: "currentColor",
304
+ "stroke-width": "2",
305
+ "stroke-linecap": "round",
306
+ "stroke-linejoin": "round",
307
+ "aria-hidden": "true",
308
+ children: jsxDEV_7x81h0kn("path", {
309
+ d: "m15 18-6-6 6-6"
310
+ }, undefined, false, undefined, this)
311
+ }, undefined, false, undefined, this);
312
+ const nextChevron = jsxDEV_7x81h0kn("svg", {
313
+ xmlns: "http://www.w3.org/2000/svg",
314
+ width: "16",
315
+ height: "16",
316
+ viewBox: "0 0 24 24",
317
+ fill: "none",
318
+ stroke: "currentColor",
319
+ "stroke-width": "2",
320
+ "stroke-linecap": "round",
321
+ "stroke-linejoin": "round",
322
+ "aria-hidden": "true",
323
+ children: jsxDEV_7x81h0kn("path", {
324
+ d: "m9 18 6-6-6-6"
325
+ }, undefined, false, undefined, this)
326
+ }, undefined, false, undefined, this);
327
+ return jsxDEV_7x81h0kn("div", {
328
+ class: cn(classes?.root),
329
+ children: [
330
+ jsxDEV_7x81h0kn("div", {
331
+ class: cn(classes?.header),
332
+ "data-caption-layout": captionLayout,
333
+ children: [
334
+ showButtons && jsxDEV_7x81h0kn("button", {
335
+ type: "button",
336
+ class: cn(classes?.navButton),
337
+ "aria-label": "Previous month",
338
+ "aria-disabled": isAtMinBoundary ? "true" : undefined,
339
+ onClick: () => {
340
+ if (!isAtMinBoundary)
341
+ navigateMonth(-1);
342
+ },
343
+ children: prevChevron
344
+ }, undefined, false, undefined, this),
345
+ showDropdowns ? jsxDEV_7x81h0kn(Fragment_8vg9x3sq, {
346
+ children: [
347
+ jsxDEV_7x81h0kn("select", {
348
+ "aria-label": "Select month",
349
+ class: cn(classes?.monthSelect),
350
+ value: String(displayMonth.getMonth()),
351
+ onChange: handleMonthSelect,
352
+ children: MONTH_OPTIONS.map((mo) => jsxDEV_7x81h0kn("option", {
353
+ value: String(mo.index),
354
+ disabled: isMonthDisabled(mo.index, displayMonth.getFullYear(), minDate, maxDate),
355
+ children: mo.name
356
+ }, undefined, false, undefined, this))
357
+ }, undefined, false, undefined, this),
358
+ jsxDEV_7x81h0kn("select", {
359
+ "aria-label": "Select year",
360
+ class: cn(classes?.yearSelect),
361
+ value: String(displayMonth.getFullYear()),
362
+ onChange: handleYearSelect,
363
+ children: yearRange.map((yr) => jsxDEV_7x81h0kn("option", {
364
+ value: String(yr),
365
+ children: yr
366
+ }, undefined, false, undefined, this))
367
+ }, undefined, false, undefined, this)
368
+ ]
369
+ }, undefined, true, undefined, this) : jsxDEV_7x81h0kn("div", {
370
+ class: cn(classes?.title),
371
+ children: titleText
372
+ }, undefined, false, undefined, this),
373
+ showButtons && jsxDEV_7x81h0kn("button", {
374
+ type: "button",
375
+ class: cn(classes?.navButton),
376
+ "aria-label": "Next month",
377
+ "aria-disabled": isAtMaxBoundary ? "true" : undefined,
378
+ onClick: () => {
379
+ if (!isAtMaxBoundary)
380
+ navigateMonth(1);
381
+ },
382
+ children: nextChevron
383
+ }, undefined, false, undefined, this)
384
+ ]
385
+ }, undefined, true, undefined, this),
386
+ jsxDEV_7x81h0kn("table", {
387
+ role: "grid",
388
+ class: cn(classes?.grid),
389
+ onKeydown: handleGridKeydown,
390
+ children: [
391
+ jsxDEV_7x81h0kn("thead", {
392
+ children: jsxDEV_7x81h0kn("tr", {
393
+ children: dayHeaders.map((day) => jsxDEV_7x81h0kn("th", {
394
+ scope: "col",
395
+ class: cn(classes?.headCell),
396
+ children: day
397
+ }, undefined, false, undefined, this))
398
+ }, undefined, false, undefined, this)
399
+ }, undefined, false, undefined, this),
400
+ jsxDEV_7x81h0kn("tbody", {
401
+ children: rows.map((rowDates) => jsxDEV_7x81h0kn("tr", {
402
+ children: rowDates.map((cellDate) => jsxDEV_7x81h0kn("td", {
403
+ role: "gridcell",
404
+ class: cn(classes?.cell),
405
+ children: jsxDEV_7x81h0kn(DayCell, {
406
+ cellDate,
407
+ displayMonth,
408
+ now,
409
+ mode,
410
+ value,
411
+ minDate,
412
+ maxDate,
413
+ disabled,
414
+ classes,
415
+ onSelect: selectDate
416
+ }, undefined, false, undefined, this)
417
+ }, undefined, false, undefined, this))
418
+ }, undefined, false, undefined, this))
419
+ }, undefined, false, undefined, this)
420
+ ]
421
+ }, undefined, true, undefined, this)
422
+ ]
423
+ }, undefined, true, undefined, this);
424
+ }
425
+ var ComposedCalendar = ComposedCalendarRoot;
426
+
427
+ export { ComposedCalendar };
@@ -0,0 +1,264 @@
1
+ import {
2
+ createDismiss
3
+ } from "./chunk-a6wp8c32.js";
4
+ import {
5
+ cn
6
+ } from "./chunk-q7xbcj9q.js";
7
+ import {
8
+ createFloatingPosition,
9
+ resolveLayoutElement
10
+ } from "./chunk-vef3sepw.js";
11
+ import {
12
+ linkedIds
13
+ } from "./chunk-8y1jf6xr.js";
14
+ import {
15
+ Keys,
16
+ handleListNavigation,
17
+ isKey
18
+ } from "./chunk-7867pr13.js";
19
+
20
+ // src/menu/menu-composed.tsx
21
+ import { jsxDEV as jsxDEV_7x81h0kn } from "@vertz/ui/jsx-dev-runtime";
22
+ import { createContext, ref, useContext } from "@vertz/ui";
23
+ var MenuContext = createContext(undefined, "@vertz/ui-primitives::MenuContext");
24
+ function useMenuContext(componentName) {
25
+ const ctx = useContext(MenuContext);
26
+ if (!ctx) {
27
+ throw new Error(`<Menu.${componentName}> must be used inside <Menu>. ` + "Ensure it is a direct or nested child of the Menu root component.");
28
+ }
29
+ return ctx;
30
+ }
31
+ function MenuTrigger({ children }) {
32
+ const ctx = useMenuContext("Trigger");
33
+ return jsxDEV_7x81h0kn("span", {
34
+ style: { display: "contents" },
35
+ "data-menu-trigger": "",
36
+ "aria-haspopup": "menu",
37
+ "aria-controls": ctx.contentId,
38
+ "aria-expanded": "false",
39
+ "data-state": "closed",
40
+ onClick: () => ctx.toggle(),
41
+ onKeydown: (event) => {
42
+ if (isKey(event, Keys.ArrowDown, Keys.Enter, Keys.Space)) {
43
+ event.preventDefault();
44
+ if (!ctx.isOpen())
45
+ ctx.open(true);
46
+ }
47
+ },
48
+ children
49
+ }, undefined, false, undefined, this);
50
+ }
51
+ function MenuContent({ children, className: cls, class: classProp }) {
52
+ const ctx = useMenuContext("Content");
53
+ const instanceIndex = ctx._contentCount.value++;
54
+ if (instanceIndex > 0) {
55
+ console.warn("Duplicate <Menu.Content> detected – only the first is used");
56
+ }
57
+ return jsxDEV_7x81h0kn("div", {
58
+ ref: ctx.contentRef,
59
+ role: "menu",
60
+ tabindex: "-1",
61
+ id: ctx.contentId,
62
+ "data-menu-content": "",
63
+ "aria-hidden": "true",
64
+ "data-state": "closed",
65
+ style: { display: "none" },
66
+ class: cn(ctx.classes?.content, cls ?? classProp),
67
+ onKeydown: (event) => {
68
+ if (isKey(event, Keys.Escape)) {
69
+ event.preventDefault();
70
+ ctx.close();
71
+ return;
72
+ }
73
+ const el = event.currentTarget ?? event.target;
74
+ const items = [...el.querySelectorAll('[role="menuitem"]')];
75
+ const focusedIdx = items.indexOf(document.activeElement);
76
+ if (isKey(event, Keys.Enter, Keys.Space)) {
77
+ event.preventDefault();
78
+ const active = items[focusedIdx];
79
+ if (active) {
80
+ const val = active.getAttribute("data-value");
81
+ if (val !== null) {
82
+ ctx.onSelect?.(val);
83
+ ctx.close();
84
+ }
85
+ }
86
+ return;
87
+ }
88
+ handleListNavigation(event, items, { orientation: "vertical" });
89
+ if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
90
+ const char = event.key.toLowerCase();
91
+ const match = items.find((item) => item.textContent?.toLowerCase().startsWith(char));
92
+ if (match)
93
+ match.focus();
94
+ }
95
+ },
96
+ onClick: (event) => {
97
+ const target = event.target.closest('[role="menuitem"]');
98
+ if (target)
99
+ ctx.close();
100
+ },
101
+ children
102
+ }, undefined, false, undefined, this);
103
+ }
104
+ function MenuItem({ value, children, className: cls, class: classProp }) {
105
+ const ctx = useMenuContext("Item");
106
+ return jsxDEV_7x81h0kn("div", {
107
+ role: "menuitem",
108
+ "data-value": value,
109
+ tabindex: "-1",
110
+ class: cn(ctx.classes?.item, cls ?? classProp),
111
+ onClick: () => {
112
+ ctx.onSelect?.(value);
113
+ ctx.close();
114
+ },
115
+ children
116
+ }, undefined, false, undefined, this);
117
+ }
118
+ function MenuGroup({ label, children, className: cls, class: classProp }) {
119
+ const ctx = useMenuContext("Group");
120
+ return jsxDEV_7x81h0kn("div", {
121
+ role: "group",
122
+ "aria-label": label,
123
+ class: cn(ctx.classes?.group, cls ?? classProp),
124
+ children
125
+ }, undefined, false, undefined, this);
126
+ }
127
+ function MenuLabel({ children, className: cls, class: classProp }) {
128
+ const { classes } = useMenuContext("Label");
129
+ return jsxDEV_7x81h0kn("div", {
130
+ role: "none",
131
+ class: cn(classes?.label, cls ?? classProp),
132
+ children
133
+ }, undefined, false, undefined, this);
134
+ }
135
+ function MenuSeparator({ className: cls, class: classProp }) {
136
+ const { classes } = useMenuContext("Separator");
137
+ return jsxDEV_7x81h0kn("hr", {
138
+ role: "separator",
139
+ class: cn(classes?.separator, cls ?? classProp)
140
+ }, undefined, false, undefined, this);
141
+ }
142
+ function ComposedMenuRoot({
143
+ children,
144
+ classes,
145
+ onSelect,
146
+ onOpenChange,
147
+ positioning
148
+ }) {
149
+ const ids = linkedIds("menu");
150
+ const contentRef = ref();
151
+ let isOpen = false;
152
+ const state = { activeIndex: -1, floatingCleanup: null, dismissCleanup: null };
153
+ function getContentEl() {
154
+ return contentRef.current ?? null;
155
+ }
156
+ function getItems() {
157
+ const content = getContentEl();
158
+ if (!content)
159
+ return [];
160
+ return [...content.querySelectorAll('[role="menuitem"]')];
161
+ }
162
+ function getTriggerEl() {
163
+ const content = getContentEl();
164
+ const triggerSpan = content?.parentElement?.querySelector("[data-menu-trigger]");
165
+ if (!triggerSpan)
166
+ return null;
167
+ return resolveLayoutElement(triggerSpan);
168
+ }
169
+ function updateActiveItem(items, index) {
170
+ items.forEach((item, i) => {
171
+ item.setAttribute("tabindex", i === index ? "0" : "-1");
172
+ });
173
+ }
174
+ function syncContentAttrs() {
175
+ const contentEl = getContentEl();
176
+ if (!contentEl)
177
+ return;
178
+ const open2 = isOpen;
179
+ contentEl.style.display = open2 ? "" : "none";
180
+ contentEl.setAttribute("aria-hidden", open2 ? "false" : "true");
181
+ contentEl.setAttribute("data-state", open2 ? "open" : "closed");
182
+ const triggerEl = getTriggerEl();
183
+ if (triggerEl) {
184
+ triggerEl.setAttribute("aria-expanded", open2 ? "true" : "false");
185
+ triggerEl.setAttribute("data-state", open2 ? "open" : "closed");
186
+ }
187
+ }
188
+ function open(activateFirst = false) {
189
+ isOpen = true;
190
+ state.activeIndex = -1;
191
+ syncContentAttrs();
192
+ onOpenChange?.(true);
193
+ const contentEl = getContentEl();
194
+ const triggerEl = getTriggerEl();
195
+ if (!contentEl)
196
+ return;
197
+ {
198
+ const floatingOpts = positioning ?? { placement: "bottom-start", offset: 4 };
199
+ const refEl = floatingOpts.referenceElement ?? triggerEl ?? contentEl;
200
+ contentEl.style.position = "fixed";
201
+ const result = createFloatingPosition(refEl, contentEl, floatingOpts);
202
+ state.floatingCleanup = result.cleanup;
203
+ state.dismissCleanup = createDismiss({
204
+ onDismiss: close,
205
+ insideElements: [refEl, contentEl, ...triggerEl ? [triggerEl] : []],
206
+ escapeKey: false
207
+ });
208
+ }
209
+ const items = getItems();
210
+ if (activateFirst && items.length > 0) {
211
+ state.activeIndex = 0;
212
+ updateActiveItem(items, 0);
213
+ items[0]?.focus();
214
+ } else {
215
+ updateActiveItem(items, -1);
216
+ contentEl.focus();
217
+ }
218
+ }
219
+ function close() {
220
+ isOpen = false;
221
+ syncContentAttrs();
222
+ state.floatingCleanup?.();
223
+ state.floatingCleanup = null;
224
+ state.dismissCleanup?.();
225
+ state.dismissCleanup = null;
226
+ onOpenChange?.(false);
227
+ getTriggerEl()?.focus();
228
+ }
229
+ function toggle() {
230
+ if (isOpen)
231
+ close();
232
+ else
233
+ open();
234
+ }
235
+ const ctx = {
236
+ isOpen: () => isOpen,
237
+ contentId: ids.contentId,
238
+ contentRef,
239
+ classes,
240
+ onSelect,
241
+ open,
242
+ close,
243
+ toggle,
244
+ _contentCount: { value: 0 }
245
+ };
246
+ return jsxDEV_7x81h0kn(MenuContext.Provider, {
247
+ value: ctx,
248
+ children: jsxDEV_7x81h0kn("span", {
249
+ style: { display: "contents" },
250
+ "data-menu-root": "",
251
+ children
252
+ }, undefined, false, undefined, this)
253
+ }, undefined, false, undefined, this);
254
+ }
255
+ var ComposedMenu = Object.assign(ComposedMenuRoot, {
256
+ Trigger: MenuTrigger,
257
+ Content: MenuContent,
258
+ Item: MenuItem,
259
+ Group: MenuGroup,
260
+ Label: MenuLabel,
261
+ Separator: MenuSeparator
262
+ });
263
+
264
+ export { ComposedMenu };