@flipdish/ui-library 0.21.0 → 0.23.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 (244) hide show
  1. package/dist/components/__internal__/statusIcon/statusIcon.types.d.ts +12 -0
  2. package/dist/components/__internal__/statusIcon/statusIcon.types.d.ts.map +1 -0
  3. package/dist/components/__internal__/statusIcon/statusIcon.utils.cjs +21 -0
  4. package/dist/components/__internal__/statusIcon/statusIcon.utils.cjs.map +1 -0
  5. package/dist/components/__internal__/statusIcon/statusIcon.utils.d.ts +5 -0
  6. package/dist/components/__internal__/statusIcon/statusIcon.utils.d.ts.map +1 -0
  7. package/dist/components/__internal__/statusIcon/statusIcon.utils.js +19 -0
  8. package/dist/components/__internal__/statusIcon/statusIcon.utils.js.map +1 -0
  9. package/dist/components/atoms/BackgroundPattern/components/grid-check.cjs +14 -7
  10. package/dist/components/atoms/BackgroundPattern/components/grid-check.cjs.map +1 -1
  11. package/dist/components/atoms/BackgroundPattern/components/grid-check.d.ts.map +1 -1
  12. package/dist/components/atoms/BackgroundPattern/components/grid-check.js +14 -7
  13. package/dist/components/atoms/BackgroundPattern/components/grid-check.js.map +1 -1
  14. package/dist/components/atoms/BackgroundPattern/index.d.ts.map +1 -1
  15. package/dist/components/atoms/Badge/index.cjs +16 -3
  16. package/dist/components/atoms/Badge/index.cjs.map +1 -1
  17. package/dist/components/atoms/Badge/index.d.ts +13 -24
  18. package/dist/components/atoms/Badge/index.d.ts.map +1 -1
  19. package/dist/components/atoms/Badge/index.js +16 -3
  20. package/dist/components/atoms/Badge/index.js.map +1 -1
  21. package/dist/components/atoms/Dot/Dot.styles.cjs +51 -0
  22. package/dist/components/atoms/Dot/Dot.styles.cjs.map +1 -0
  23. package/dist/components/atoms/Dot/Dot.styles.d.ts +109 -0
  24. package/dist/components/atoms/Dot/Dot.styles.d.ts.map +1 -0
  25. package/dist/components/atoms/Dot/Dot.styles.js +49 -0
  26. package/dist/components/atoms/Dot/Dot.styles.js.map +1 -0
  27. package/dist/components/atoms/Dot/index.cjs +5 -14
  28. package/dist/components/atoms/Dot/index.cjs.map +1 -1
  29. package/dist/components/atoms/Dot/index.d.ts +11 -3
  30. package/dist/components/atoms/Dot/index.d.ts.map +1 -1
  31. package/dist/components/atoms/Dot/index.js +5 -14
  32. package/dist/components/atoms/Dot/index.js.map +1 -1
  33. package/dist/components/molecules/Alert/index.cjs +3 -11
  34. package/dist/components/molecules/Alert/index.cjs.map +1 -1
  35. package/dist/components/molecules/Alert/index.d.ts +3 -2
  36. package/dist/components/molecules/Alert/index.d.ts.map +1 -1
  37. package/dist/components/molecules/Alert/index.js +3 -11
  38. package/dist/components/molecules/Alert/index.js.map +1 -1
  39. package/dist/components/molecules/Carousel/index.cjs +1 -1
  40. package/dist/components/molecules/Carousel/index.cjs.map +1 -1
  41. package/dist/components/molecules/Carousel/index.js +1 -1
  42. package/dist/components/molecules/Carousel/index.js.map +1 -1
  43. package/dist/components/molecules/Notification/index.cjs +3 -10
  44. package/dist/components/molecules/Notification/index.cjs.map +1 -1
  45. package/dist/components/molecules/Notification/index.d.ts +2 -1
  46. package/dist/components/molecules/Notification/index.d.ts.map +1 -1
  47. package/dist/components/molecules/Notification/index.js +3 -10
  48. package/dist/components/molecules/Notification/index.js.map +1 -1
  49. package/dist/components/molecules/Pagination/index.cjs +4 -4
  50. package/dist/components/molecules/Pagination/index.cjs.map +1 -1
  51. package/dist/components/molecules/Pagination/index.js +5 -5
  52. package/dist/components/molecules/Pagination/index.js.map +1 -1
  53. package/dist/components/molecules/Tags/index.cjs +1 -1
  54. package/dist/components/molecules/Tags/index.cjs.map +1 -1
  55. package/dist/components/molecules/Tags/index.js +1 -1
  56. package/dist/components/molecules/Tags/index.js.map +1 -1
  57. package/dist/components/organisms/ActivityFeed/index.cjs +1 -1
  58. package/dist/components/organisms/ActivityFeed/index.cjs.map +1 -1
  59. package/dist/components/organisms/ActivityFeed/index.js +1 -1
  60. package/dist/components/organisms/ActivityFeed/index.js.map +1 -1
  61. package/dist/components/organisms/Calendar/calendar.utils.cjs +41 -0
  62. package/dist/components/organisms/Calendar/calendar.utils.cjs.map +1 -1
  63. package/dist/components/organisms/Calendar/calendar.utils.d.ts +20 -0
  64. package/dist/components/organisms/Calendar/calendar.utils.d.ts.map +1 -1
  65. package/dist/components/organisms/Calendar/calendar.utils.js +37 -1
  66. package/dist/components/organisms/Calendar/calendar.utils.js.map +1 -1
  67. package/dist/components/organisms/Calendar/components/calendar-day-view.cjs +86 -0
  68. package/dist/components/organisms/Calendar/components/calendar-day-view.cjs.map +1 -0
  69. package/dist/components/organisms/Calendar/components/calendar-day-view.d.ts +20 -0
  70. package/dist/components/organisms/Calendar/components/calendar-day-view.d.ts.map +1 -0
  71. package/dist/components/organisms/Calendar/components/calendar-day-view.js +84 -0
  72. package/dist/components/organisms/Calendar/components/calendar-day-view.js.map +1 -0
  73. package/dist/components/organisms/Calendar/components/calendar-mobile-day-grid.cjs +21 -0
  74. package/dist/components/organisms/Calendar/components/calendar-mobile-day-grid.cjs.map +1 -0
  75. package/dist/components/organisms/Calendar/components/calendar-mobile-day-grid.d.ts +16 -0
  76. package/dist/components/organisms/Calendar/components/calendar-mobile-day-grid.d.ts.map +1 -0
  77. package/dist/components/organisms/Calendar/components/calendar-mobile-day-grid.js +19 -0
  78. package/dist/components/organisms/Calendar/components/calendar-mobile-day-grid.js.map +1 -0
  79. package/dist/components/organisms/Calendar/components/calendar-month-view.cjs +265 -0
  80. package/dist/components/organisms/Calendar/components/calendar-month-view.cjs.map +1 -0
  81. package/dist/components/organisms/Calendar/components/calendar-month-view.d.ts +18 -0
  82. package/dist/components/organisms/Calendar/components/calendar-month-view.d.ts.map +1 -0
  83. package/dist/components/organisms/Calendar/components/calendar-month-view.js +263 -0
  84. package/dist/components/organisms/Calendar/components/calendar-month-view.js.map +1 -0
  85. package/dist/components/organisms/Calendar/components/calendar-positioned-event.cjs +41 -0
  86. package/dist/components/organisms/Calendar/components/calendar-positioned-event.cjs.map +1 -0
  87. package/dist/components/organisms/Calendar/components/calendar-positioned-event.d.ts +15 -0
  88. package/dist/components/organisms/Calendar/components/calendar-positioned-event.d.ts.map +1 -0
  89. package/dist/components/organisms/Calendar/components/calendar-positioned-event.js +39 -0
  90. package/dist/components/organisms/Calendar/components/calendar-positioned-event.js.map +1 -0
  91. package/dist/components/organisms/Calendar/components/calendar-week-view-day.cjs +23 -0
  92. package/dist/components/organisms/Calendar/components/calendar-week-view-day.cjs.map +1 -0
  93. package/dist/components/organisms/Calendar/components/calendar-week-view-day.d.ts +15 -0
  94. package/dist/components/organisms/Calendar/components/calendar-week-view-day.d.ts.map +1 -0
  95. package/dist/components/organisms/Calendar/components/calendar-week-view-day.js +21 -0
  96. package/dist/components/organisms/Calendar/components/calendar-week-view-day.js.map +1 -0
  97. package/dist/components/organisms/Calendar/components/calendar-week-view.cjs +77 -0
  98. package/dist/components/organisms/Calendar/components/calendar-week-view.cjs.map +1 -0
  99. package/dist/components/organisms/Calendar/components/calendar-week-view.d.ts +20 -0
  100. package/dist/components/organisms/Calendar/components/calendar-week-view.d.ts.map +1 -0
  101. package/dist/components/organisms/Calendar/components/calendar-week-view.js +75 -0
  102. package/dist/components/organisms/Calendar/components/calendar-week-view.js.map +1 -0
  103. package/dist/components/organisms/Calendar/index.cjs +4 -504
  104. package/dist/components/organisms/Calendar/index.cjs.map +1 -1
  105. package/dist/components/organisms/Calendar/index.d.ts +1 -1
  106. package/dist/components/organisms/Calendar/index.d.ts.map +1 -1
  107. package/dist/components/organisms/Calendar/index.js +6 -506
  108. package/dist/components/organisms/Calendar/index.js.map +1 -1
  109. package/dist/components/organisms/Charts/components/activity-gauge.cjs +4 -0
  110. package/dist/components/organisms/Charts/components/activity-gauge.cjs.map +1 -1
  111. package/dist/components/organisms/Charts/components/activity-gauge.d.ts +4 -0
  112. package/dist/components/organisms/Charts/components/activity-gauge.d.ts.map +1 -1
  113. package/dist/components/organisms/Charts/components/activity-gauge.js +4 -0
  114. package/dist/components/organisms/Charts/components/activity-gauge.js.map +1 -1
  115. package/dist/components/organisms/Charts/components/bar-chart.cjs +1 -1
  116. package/dist/components/organisms/Charts/components/bar-chart.cjs.map +1 -1
  117. package/dist/components/organisms/Charts/components/bar-chart.d.ts +1 -2
  118. package/dist/components/organisms/Charts/components/bar-chart.d.ts.map +1 -1
  119. package/dist/components/organisms/Charts/components/bar-chart.js +2 -2
  120. package/dist/components/organisms/Charts/components/bar-chart.js.map +1 -1
  121. package/dist/components/organisms/Charts/components/charts-base.cjs +1 -2
  122. package/dist/components/organisms/Charts/components/charts-base.cjs.map +1 -1
  123. package/dist/components/organisms/Charts/components/charts-base.d.ts +13 -2
  124. package/dist/components/organisms/Charts/components/charts-base.d.ts.map +1 -1
  125. package/dist/components/organisms/Charts/components/charts-base.js +1 -2
  126. package/dist/components/organisms/Charts/components/charts-base.js.map +1 -1
  127. package/dist/components/organisms/Charts/components/line-chart.cjs +1 -1
  128. package/dist/components/organisms/Charts/components/line-chart.cjs.map +1 -1
  129. package/dist/components/organisms/Charts/components/line-chart.d.ts +1 -2
  130. package/dist/components/organisms/Charts/components/line-chart.d.ts.map +1 -1
  131. package/dist/components/organisms/Charts/components/line-chart.js +2 -2
  132. package/dist/components/organisms/Charts/components/line-chart.js.map +1 -1
  133. package/dist/components/organisms/Charts/components/pie-chart.cjs +5 -0
  134. package/dist/components/organisms/Charts/components/pie-chart.cjs.map +1 -1
  135. package/dist/components/organisms/Charts/components/pie-chart.d.ts +6 -2
  136. package/dist/components/organisms/Charts/components/pie-chart.d.ts.map +1 -1
  137. package/dist/components/organisms/Charts/components/pie-chart.js +5 -0
  138. package/dist/components/organisms/Charts/components/pie-chart.js.map +1 -1
  139. package/dist/components/organisms/Charts/components/radar-chart.cjs +3 -4
  140. package/dist/components/organisms/Charts/components/radar-chart.cjs.map +1 -1
  141. package/dist/components/organisms/Charts/components/radar-chart.d.ts.map +1 -1
  142. package/dist/components/organisms/Charts/components/radar-chart.js +3 -4
  143. package/dist/components/organisms/Charts/components/radar-chart.js.map +1 -1
  144. package/dist/components/organisms/DatePicker/components/range-calendar.cjs +1 -1
  145. package/dist/components/organisms/DatePicker/components/range-calendar.cjs.map +1 -1
  146. package/dist/components/organisms/DatePicker/components/range-calendar.js +2 -2
  147. package/dist/components/organisms/DatePicker/components/range-calendar.js.map +1 -1
  148. package/dist/components/organisms/GradientPicker/components/gradient-area.cjs +157 -0
  149. package/dist/components/organisms/GradientPicker/components/gradient-area.cjs.map +1 -0
  150. package/dist/components/organisms/GradientPicker/components/gradient-area.d.ts +17 -0
  151. package/dist/components/organisms/GradientPicker/components/gradient-area.d.ts.map +1 -0
  152. package/dist/components/organisms/GradientPicker/components/gradient-area.js +155 -0
  153. package/dist/components/organisms/GradientPicker/components/gradient-area.js.map +1 -0
  154. package/dist/components/organisms/GradientPicker/components/gradient-reverse-button.cjs +17 -0
  155. package/dist/components/organisms/GradientPicker/components/gradient-reverse-button.cjs.map +1 -0
  156. package/dist/components/organisms/GradientPicker/components/gradient-reverse-button.d.ts +3 -0
  157. package/dist/components/organisms/GradientPicker/components/gradient-reverse-button.d.ts.map +1 -0
  158. package/dist/components/organisms/GradientPicker/components/gradient-reverse-button.js +15 -0
  159. package/dist/components/organisms/GradientPicker/components/gradient-reverse-button.js.map +1 -0
  160. package/dist/components/organisms/GradientPicker/components/gradient-slider.cjs +71 -0
  161. package/dist/components/organisms/GradientPicker/components/gradient-slider.cjs.map +1 -0
  162. package/dist/components/organisms/GradientPicker/components/gradient-slider.d.ts +7 -0
  163. package/dist/components/organisms/GradientPicker/components/gradient-slider.d.ts.map +1 -0
  164. package/dist/components/organisms/GradientPicker/components/gradient-slider.js +69 -0
  165. package/dist/components/organisms/GradientPicker/components/gradient-slider.js.map +1 -0
  166. package/dist/components/organisms/GradientPicker/components/gradient-stop-list.cjs +18 -0
  167. package/dist/components/organisms/GradientPicker/components/gradient-stop-list.cjs.map +1 -0
  168. package/dist/components/organisms/GradientPicker/components/gradient-stop-list.d.ts +4 -0
  169. package/dist/components/organisms/GradientPicker/components/gradient-stop-list.d.ts.map +1 -0
  170. package/dist/components/organisms/GradientPicker/components/gradient-stop-list.js +16 -0
  171. package/dist/components/organisms/GradientPicker/components/gradient-stop-list.js.map +1 -0
  172. package/dist/components/organisms/GradientPicker/components/gradient-stop-row.cjs +49 -0
  173. package/dist/components/organisms/GradientPicker/components/gradient-stop-row.cjs.map +1 -0
  174. package/dist/components/organisms/GradientPicker/components/gradient-stop-row.d.ts +6 -0
  175. package/dist/components/organisms/GradientPicker/components/gradient-stop-row.d.ts.map +1 -0
  176. package/dist/components/organisms/GradientPicker/components/gradient-stop-row.js +47 -0
  177. package/dist/components/organisms/GradientPicker/components/gradient-stop-row.js.map +1 -0
  178. package/dist/components/organisms/GradientPicker/components/gradient-type-select.cjs +28 -0
  179. package/dist/components/organisms/GradientPicker/components/gradient-type-select.cjs.map +1 -0
  180. package/dist/components/organisms/GradientPicker/components/gradient-type-select.d.ts +3 -0
  181. package/dist/components/organisms/GradientPicker/components/gradient-type-select.d.ts.map +1 -0
  182. package/dist/components/organisms/GradientPicker/components/gradient-type-select.js +26 -0
  183. package/dist/components/organisms/GradientPicker/components/gradient-type-select.js.map +1 -0
  184. package/dist/components/organisms/GradientPicker/components/position-input.cjs +43 -0
  185. package/dist/components/organisms/GradientPicker/components/position-input.cjs.map +1 -0
  186. package/dist/components/organisms/GradientPicker/components/position-input.d.ts +6 -0
  187. package/dist/components/organisms/GradientPicker/components/position-input.d.ts.map +1 -0
  188. package/dist/components/organisms/GradientPicker/components/position-input.js +41 -0
  189. package/dist/components/organisms/GradientPicker/components/position-input.js.map +1 -0
  190. package/dist/components/organisms/GradientPicker/index.cjs +11 -327
  191. package/dist/components/organisms/GradientPicker/index.cjs.map +1 -1
  192. package/dist/components/organisms/GradientPicker/index.d.ts +7 -8
  193. package/dist/components/organisms/GradientPicker/index.d.ts.map +1 -1
  194. package/dist/components/organisms/GradientPicker/index.js +7 -323
  195. package/dist/components/organisms/GradientPicker/index.js.map +1 -1
  196. package/dist/components/organisms/HeaderNavigation/components/nav-account-card.cjs +1 -1
  197. package/dist/components/organisms/HeaderNavigation/components/nav-account-card.cjs.map +1 -1
  198. package/dist/components/organisms/HeaderNavigation/components/nav-account-card.js +2 -2
  199. package/dist/components/organisms/HeaderNavigation/components/nav-account-card.js.map +1 -1
  200. package/dist/components/organisms/HeaderNavigation/components/nav-button.cjs +1 -1
  201. package/dist/components/organisms/HeaderNavigation/components/nav-button.cjs.map +1 -1
  202. package/dist/components/organisms/HeaderNavigation/components/nav-button.d.ts.map +1 -1
  203. package/dist/components/organisms/HeaderNavigation/components/nav-button.js +1 -1
  204. package/dist/components/organisms/HeaderNavigation/components/nav-button.js.map +1 -1
  205. package/dist/components/organisms/SidebarNavigation/components/nav-account-card.cjs +1 -1
  206. package/dist/components/organisms/SidebarNavigation/components/nav-account-card.cjs.map +1 -1
  207. package/dist/components/organisms/SidebarNavigation/components/nav-account-card.js +2 -2
  208. package/dist/components/organisms/SidebarNavigation/components/nav-account-card.js.map +1 -1
  209. package/dist/components/organisms/SidebarNavigation/index.cjs +1 -1
  210. package/dist/components/organisms/SidebarNavigation/index.cjs.map +1 -1
  211. package/dist/components/organisms/SidebarNavigation/index.js +2 -2
  212. package/dist/components/organisms/SidebarNavigation/index.js.map +1 -1
  213. package/dist/components/organisms/VideoPlayer/hooks/useVideoPlayback.cjs +169 -0
  214. package/dist/components/organisms/VideoPlayer/hooks/useVideoPlayback.cjs.map +1 -0
  215. package/dist/components/organisms/VideoPlayer/hooks/useVideoPlayback.d.ts +34 -0
  216. package/dist/components/organisms/VideoPlayer/hooks/useVideoPlayback.d.ts.map +1 -0
  217. package/dist/components/organisms/VideoPlayer/hooks/useVideoPlayback.js +167 -0
  218. package/dist/components/organisms/VideoPlayer/hooks/useVideoPlayback.js.map +1 -0
  219. package/dist/components/organisms/VideoPlayer/hooks/useVideoVolume.cjs +75 -0
  220. package/dist/components/organisms/VideoPlayer/hooks/useVideoVolume.cjs.map +1 -0
  221. package/dist/components/organisms/VideoPlayer/hooks/useVideoVolume.d.ts +16 -0
  222. package/dist/components/organisms/VideoPlayer/hooks/useVideoVolume.d.ts.map +1 -0
  223. package/dist/components/organisms/VideoPlayer/hooks/useVideoVolume.js +73 -0
  224. package/dist/components/organisms/VideoPlayer/hooks/useVideoVolume.js.map +1 -0
  225. package/dist/components/organisms/VideoPlayer/index.cjs +9 -182
  226. package/dist/components/organisms/VideoPlayer/index.cjs.map +1 -1
  227. package/dist/components/organisms/VideoPlayer/index.d.ts.map +1 -1
  228. package/dist/components/organisms/VideoPlayer/index.js +10 -183
  229. package/dist/components/organisms/VideoPlayer/index.js.map +1 -1
  230. package/dist/hooks/useBreakpoints/index.cjs +4 -1
  231. package/dist/hooks/useBreakpoints/index.cjs.map +1 -1
  232. package/dist/hooks/useBreakpoints/index.d.ts +2 -0
  233. package/dist/hooks/useBreakpoints/index.d.ts.map +1 -1
  234. package/dist/hooks/useBreakpoints/index.js +4 -2
  235. package/dist/hooks/useBreakpoints/index.js.map +1 -1
  236. package/dist/native/components/atoms/Dot/Dot.styles.d.ts +109 -0
  237. package/dist/native/components/atoms/Dot/Dot.styles.d.ts.map +1 -0
  238. package/dist/native/components/atoms/Dot/Dot.styles.js +49 -0
  239. package/dist/native/components/atoms/Dot/Dot.styles.js.map +1 -0
  240. package/dist/native/components/atoms/Dot/index.d.ts +24 -8
  241. package/dist/native/components/atoms/Dot/index.d.ts.map +1 -0
  242. package/dist/native/components/atoms/Dot/index.js +25 -0
  243. package/dist/native/components/atoms/Dot/index.js.map +1 -0
  244. package/package.json +1 -1
@@ -1,521 +1,21 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
- var uiIcons = require('@flipdish/ui-icons');
5
- var Avatar = require('@flipdish/ui-library/components/atoms/Avatar');
6
- var Button = require('@flipdish/ui-library/components/atoms/Button');
7
- var UtilityButton = require('@flipdish/ui-library/components/atoms/UtilityButton');
8
4
  var cx = require('@flipdish/ui-library/utilities/cx');
9
5
  var testIdUtils = require('@flipdish/ui-library/utilities/testIdUtils');
10
6
  var date = require('@internationalized/date');
11
7
  var i18n = require('@react-aria/i18n');
12
8
  var React = require('react');
13
- var reactAriaComponents = require('react-aria-components');
14
- var cell = require('../DatePicker/components/cell.cjs');
15
- var calendarColumnHeader = require('./components/calendar-column-header.cjs');
16
- var calendarDwViewCell = require('./components/calendar-dw-view-cell.cjs');
17
- var calendarDwViewEvent = require('./components/calendar-dw-view-event.cjs');
9
+ var calendarDayView = require('./components/calendar-day-view.cjs');
18
10
  var calendarHeader = require('./components/calendar-header.cjs');
19
- var calendarMonthViewCell = require('./components/calendar-month-view-cell.cjs');
20
- var calendarMonthViewEvent = require('./components/calendar-month-view-event.cjs');
21
- var calendarRowLabel = require('./components/calendar-row-label.cjs');
22
- var calendarTimeMarker = require('./components/calendar-time-marker.cjs');
11
+ var calendarMonthView = require('./components/calendar-month-view.cjs');
12
+ var calendarWeekView = require('./components/calendar-week-view.cjs');
23
13
 
24
- const SLOT_HEIGHT = 48;
25
14
  const viewOptions = [
26
15
  { value: 'day', label: 'Day view', addon: '⌘D' },
27
16
  { value: 'week', label: 'Week view', addon: '⌘W' },
28
17
  { value: 'month', label: 'Month view', addon: '⌘M' },
29
18
  ];
30
- const getStartOfDay = (date$1, timeZone) => {
31
- const zoned = date$1 instanceof date.CalendarDate ? date.toZoned(date$1, timeZone) : date$1;
32
- return zoned.set({ hour: 0, minute: 0, second: 0, millisecond: 0 });
33
- };
34
- const getEndOfDay = (date$1, timeZone) => {
35
- const zoned = date$1 instanceof date.CalendarDate ? date.toZoned(date$1, timeZone) : date$1;
36
- return zoned.set({ hour: 23, minute: 59, second: 59, millisecond: 999 });
37
- };
38
- const getDaysInVisibleMonthGrid = (anchorDate, locale) => {
39
- const monthStart = date.startOfMonth(anchorDate);
40
- const monthEnd = date.endOfMonth(anchorDate);
41
- const weekStart = date.startOfWeek(monthStart, locale);
42
- const weekEnd = date.endOfWeek(monthEnd, locale);
43
- const days = [];
44
- let day = weekStart;
45
- while (day.compare(weekEnd) <= 0) {
46
- days.push(day);
47
- day = day.add({ days: 1 });
48
- }
49
- return days;
50
- };
51
- const getEventsForDay = (allEvents, targetDate, timeZone) => {
52
- const dayStart = getStartOfDay(targetDate, timeZone);
53
- const dayEnd = getEndOfDay(targetDate, timeZone);
54
- return allEvents
55
- .filter((event) => {
56
- // Check if event interval overlaps with the day interval
57
- return event.start.compare(dayEnd) < 0 && event.end.compare(dayStart) > 0;
58
- })
59
- .sort((a, b) => a.start.compare(b.start));
60
- };
61
- const PositionedEvent = ({ event, dayStart, timeZone, slotHeight, overlapIndex, setSelectedDate, timeFormatter }) => {
62
- const prefix = testIdUtils.useTestIdPrefix();
63
- const eventTestId = prefix ? testIdUtils.joinTestId(prefix, `event-${testIdUtils.slugifyTestId(event.id)}`) : undefined;
64
- const formatTime = (dateTime) => timeFormatter.format(dateTime.toDate());
65
- const startZoned = event.start;
66
- const endZoned = event.end;
67
- // Clamp event start/end times to the visible day boundaries for height calculation
68
- const dayEnd = getEndOfDay(dayStart, timeZone); // Calculate dayEnd based on dayStart
69
- const clampedStart = startZoned.compare(dayStart) < 0 ? dayStart : startZoned;
70
- const clampedEnd = endZoned.compare(dayEnd) > 0 ? dayEnd : endZoned;
71
- const startMinutes = clampedStart.hour * 60 + clampedStart.minute;
72
- const endMinutes = clampedEnd.hour * 60 + clampedEnd.minute;
73
- const durationMinutes = Math.max(15, endMinutes - startMinutes);
74
- // Position based on 30-min slots (slotHeight = 24px)
75
- const top = (startMinutes / 30) * slotHeight;
76
- const height = Math.max(slotHeight / 2, (durationMinutes / 30) * slotHeight); // Min height 15min
77
- // Basic overlap handling - simple horizontal offset
78
- // const horizontalOffset = overlapIndex * 10;
79
- const horizontalOffset = 0;
80
- const displayTime = durationMinutes > 30;
81
- const supportingText = displayTime ? formatTime(startZoned) : undefined;
82
- return (
83
- // biome-ignore lint/a11y/noStaticElementInteractions: This is a static element that is used to position the event
84
- // biome-ignore lint/a11y/useKeyWithClickEvents: This is a static element that is used to position the event
85
- jsxRuntime.jsx("div", { className: "absolute w-full px-1.5 py-1.5", style: {
86
- top: `${top}px`,
87
- height: `${height}px`,
88
- left: `${horizontalOffset}px`,
89
- zIndex: overlapIndex,
90
- }, onClick: () => setSelectedDate(date.toCalendarDate(startZoned)), children: jsxRuntime.jsx(calendarDwViewEvent.CalendarDwViewEvent, { label: event.title, supportingText: supportingText, color: event.color, withDot: event.dot, "data-testid": eventTestId }) }, event.id));
91
- };
92
- const MonthView = ({ currentMonthDate, selectedDate, zonedEvents, locale, timeZone, setSelectedDate, fullDateFormatter, shortWeekdayFormatter, timeFormatter, // Needed for formatTime inside
93
- className, }) => {
94
- const prefix = testIdUtils.useTestIdPrefix();
95
- const eventTestId = (eventId) => (prefix ? testIdUtils.joinTestId(prefix, `event-${testIdUtils.slugifyTestId(eventId)}`) : undefined);
96
- const monthStart = date.startOfMonth(currentMonthDate);
97
- const monthEnd = date.endOfMonth(currentMonthDate);
98
- const weekStart = date.startOfWeek(monthStart, locale);
99
- const weekEnd = date.endOfWeek(monthEnd, locale);
100
- const formatTimeForMonth = (dateTime) => timeFormatter.format(dateTime.toDate());
101
- const days = React.useMemo(() => getDaysInVisibleMonthGrid(currentMonthDate, locale), [currentMonthDate, locale]);
102
- const weekdays = React.useMemo(() => {
103
- const firstDay = date.startOfWeek(date.today(timeZone), locale);
104
- return Array.from({ length: 7 }).map((_, i) => shortWeekdayFormatter.format(firstDay.add({ days: i }).toDate(timeZone)));
105
- }, [locale, timeZone, shortWeekdayFormatter]); // Dependencies are passed in
106
- const visibleEvents = zonedEvents.filter((event) => {
107
- const eventStartDay = date.toCalendarDate(event.start);
108
- const eventEndDay = date.toCalendarDate(event.end);
109
- return eventStartDay.compare(weekEnd) <= 0 && eventEndDay.compare(weekStart) >= 0;
110
- });
111
- // Pre-calculate events for each day in the visible grid
112
- const eventsByDay = React.useMemo(() => {
113
- const map = new Map();
114
- days.forEach((day) => {
115
- const dateKey = day.toString();
116
- const dayEvents = getEventsForDay(visibleEvents, day, timeZone);
117
- map.set(dateKey, dayEvents);
118
- });
119
- return map;
120
- }, [days, visibleEvents, timeZone]); // Dependencies: days array, visible events, timezone
121
- const MAX_EVENTS_PER_CELL = 3;
122
- const todayCalDate = date.today(timeZone);
123
- const targetDateForFooter = selectedDate || (date.isSameMonth(currentMonthDate, todayCalDate) ? todayCalDate : null);
124
- let eventsForFooter = [];
125
- if (targetDateForFooter) {
126
- const targetZoned = date.toZoned(targetDateForFooter, timeZone);
127
- const targetZonedStart = getStartOfDay(targetZoned, timeZone);
128
- const targetZonedEnd = getEndOfDay(targetZoned, timeZone);
129
- eventsForFooter = zonedEvents
130
- .filter((event) => {
131
- const eventStartDay = date.toCalendarDate(event.start);
132
- const eventEndDay = date.toCalendarDate(event.end);
133
- return (date.isSameDay(eventStartDay, targetDateForFooter) ||
134
- date.isSameDay(eventEndDay, targetDateForFooter) ||
135
- (event.start.compare(targetZonedEnd) < 0 && event.end.compare(targetZonedStart) > 0));
136
- })
137
- .sort((a, b) => a.start.compare(b.start));
138
- }
139
- /**
140
- * Calculates how many days an event should visually span from a given start date.
141
- *
142
- * Multi-day events are rendered as a single element that spans multiple cells.
143
- * To avoid duplicate rendering:
144
- * - Events render only on their start day
145
- * - Multi-week events re-render at the start of each new week they span
146
- *
147
- * @returns Number of days to span, or null if event should not render on this day
148
- */
149
- const calculateEventSpan = React.useCallback((event, currentDate) => {
150
- const eventStartDay = date.toCalendarDate(event.start);
151
- const eventEndDay = date.toCalendarDate(event.end);
152
- const startsOnThisDay = date.isSameDay(currentDate, eventStartDay);
153
- // Determine if we should render this event on the current date
154
- if (!startsOnThisDay && eventStartDay.compare(currentDate) < 0) {
155
- // Event started on a previous day
156
- const currentDayIndex = days.findIndex((d) => date.isSameDay(d, currentDate));
157
- const weekStartIndex = Math.floor(currentDayIndex / 7) * 7;
158
- const weekStartDate = days[weekStartIndex];
159
- if (!weekStartDate)
160
- return null;
161
- const isFirstDayOfWeek = date.isSameDay(currentDate, weekStartDate);
162
- // Only render at week boundaries for multi-week events
163
- if (!isFirstDayOfWeek) {
164
- return null; // Already rendered earlier in this week
165
- }
166
- }
167
- // Calculate span: count days from current date until event ends or week ends
168
- const currentDayIndex = days.findIndex((d) => date.isSameDay(d, currentDate));
169
- const weekEndIndex = Math.floor(currentDayIndex / 7) * 7 + 6;
170
- let spanDays = 1;
171
- let checkDay = currentDate.add({ days: 1 });
172
- let checkDayIndex = currentDayIndex + 1;
173
- while (checkDayIndex <= weekEndIndex && checkDay.compare(eventEndDay) <= 0) {
174
- spanDays++;
175
- checkDay = checkDay.add({ days: 1 });
176
- checkDayIndex++;
177
- }
178
- return spanDays;
179
- }, [days]);
180
- /**
181
- * Creates an optimized layout for multi-day events using a row-packing algorithm.
182
- *
183
- * Key concepts:
184
- * 1. Each event is assigned to a "row" (vertical position within a day cell)
185
- * 2. Events spanning multiple days create invisible "placeholder" cells to reserve space
186
- * 3. Row assignment uses a greedy algorithm to minimize wasted vertical space
187
- * 4. Multi-week events can use different rows in each week for optimal packing
188
- *
189
- * Example: If Event A (Mon-Wed) is in row 0, Event B (Thu-Fri) can also use row 0
190
- * because they don't overlap, preventing wasted space.
191
- */
192
- const eventRenderMap = React.useMemo(() => {
193
- const renderMap = new Map();
194
- // Initialize empty arrays for each day
195
- // biome-ignore lint/suspicious/useIterableCallbackReturn: This is a side effect
196
- days.forEach((day) => renderMap.set(day.toString(), []));
197
- // Tracking state for the algorithm
198
- const eventRowAssignments = new Map(); // eventId -> row number
199
- const rowOccupancyByDay = new Map(); // dateKey -> [row0: Set<eventId>, row1: Set<eventId>, ...]
200
- // biome-ignore lint/suspicious/useIterableCallbackReturn: This is a side effect
201
- days.forEach((day) => rowOccupancyByDay.set(day.toString(), []));
202
- // Checks if an event is starting at a week boundary (for multi-week events)
203
- const isWeekBoundaryStart = (dayIndex, eventStartDay, currentDay) => {
204
- const startsOnCurrentDay = date.isSameDay(currentDay, eventStartDay);
205
- if (startsOnCurrentDay)
206
- return false;
207
- const weekStartIndex = Math.floor(dayIndex / 7) * 7;
208
- const weekStartDate = days[weekStartIndex];
209
- if (!weekStartDate)
210
- return false;
211
- return date.isSameDay(currentDay, weekStartDate);
212
- };
213
- // Finds the first available row for an event across all days it spans
214
- const findAvailableRow = (startDayIndex, span) => {
215
- let row = 0;
216
- while (true) {
217
- let isAvailable = true;
218
- // Check if this row is free for all days in the span
219
- for (let offset = 0; offset < span; offset++) {
220
- const dayIndex = startDayIndex + offset;
221
- const day = days[dayIndex];
222
- if (!day)
223
- break;
224
- const dayKey = day.toString();
225
- const occupancy = rowOccupancyByDay.get(dayKey);
226
- if ((occupancy?.[row]?.size ?? 0) > 0) {
227
- isAvailable = false;
228
- break;
229
- }
230
- }
231
- if (isAvailable)
232
- return row;
233
- row++;
234
- }
235
- };
236
- // Marks a row as occupied for all days an event spans
237
- const markRowAsOccupied = (startDayIndex, span, row, eventId) => {
238
- for (let offset = 0; offset < span; offset++) {
239
- const dayIndex = startDayIndex + offset;
240
- const day = days[dayIndex];
241
- if (!day)
242
- break;
243
- const dayKey = day.toString();
244
- const occupancy = rowOccupancyByDay.get(dayKey);
245
- if (!occupancy)
246
- break;
247
- let cell = occupancy[row];
248
- if (!cell) {
249
- cell = new Set();
250
- occupancy[row] = cell;
251
- }
252
- cell.add(eventId);
253
- }
254
- };
255
- // Main logic: Process each day and assign rows to events
256
- days.forEach((day, dayIndex) => {
257
- const dateKey = day.toString();
258
- const eventsOnThisDay = eventsByDay.get(dateKey) || [];
259
- eventsOnThisDay.forEach((event) => {
260
- const span = calculateEventSpan(event, day);
261
- if (span === null)
262
- return; // Event doesn't render on this day
263
- const eventStartDay = date.toCalendarDate(event.start);
264
- const isNewWeekSegment = isWeekBoundaryStart(dayIndex, eventStartDay, day);
265
- const hasExistingRow = eventRowAssignments.has(event.id);
266
- // Determine row: reuse existing row within same week, or find new row for new week segments
267
- let row;
268
- if (hasExistingRow && !isNewWeekSegment) {
269
- // biome-ignore lint/style/noNonNullAssertion: guarded by hasExistingRow (eventRowAssignments.has(event.id)) above
270
- row = eventRowAssignments.get(event.id);
271
- }
272
- else {
273
- row = findAvailableRow(dayIndex, span);
274
- eventRowAssignments.set(event.id, row);
275
- }
276
- // Mark occupancy and add event cell
277
- markRowAsOccupied(dayIndex, span, row, event.id);
278
- renderMap.get(dateKey)?.push({ event, span, isPlaceholder: false, row });
279
- // Add invisible placeholder cells for subsequent days
280
- for (let offset = 1; offset < span; offset++) {
281
- const nextDayIndex = dayIndex + offset;
282
- const nextDay = days[nextDayIndex];
283
- if (!nextDay)
284
- break;
285
- const nextDayKey = nextDay.toString();
286
- renderMap.get(nextDayKey)?.push({ event, span: 0, isPlaceholder: true, row });
287
- }
288
- });
289
- });
290
- // Sort events by row for consistent rendering order
291
- // biome-ignore lint/suspicious/useIterableCallbackReturn: This is a side effect
292
- renderMap.forEach((events) => events.sort((a, b) => a.row - b.row));
293
- return renderMap;
294
- }, [calculateEventSpan, days, eventsByDay]);
295
- return (jsxRuntime.jsxs("div", { className: cx.cx('flex flex-1 flex-col', className), children: [jsxRuntime.jsx("div", { className: "grid grid-cols-7", children: weekdays.map((weekday, index) => (
296
- // biome-ignore lint/suspicious/noArrayIndexKey: This is a key for the column header
297
- jsxRuntime.jsx(calendarColumnHeader.CalendarColumnHeader, { weekDay: weekday, className: "before:border-b" }, index))) }), jsxRuntime.jsx("div", { className: cx.cx('grid flex-1 grid-cols-7',
298
- // 6 rows for >35 days (6 weeks), 5 rows for >28 days (5 weeks), 4 rows for <=28 days (4 weeks)
299
- days.length > 35 ? 'grid-rows-6' : days.length > 28 ? 'grid-rows-5' : 'grid-rows-4'), children: days.map((date$1, index) => {
300
- const dateKey = date$1.toString();
301
- const isCurrentMonthFlag = date.isSameMonth(date$1, currentMonthDate);
302
- const isTodayFlag = date.isToday(date$1, timeZone);
303
- const isSelectedFlag = selectedDate ? date.isSameDay(date$1, selectedDate) : false;
304
- // Determine if it's the last row based on the number of weeks
305
- const isLastRow = days.length > 35 ? index >= 35 : days.length > 28 ? index >= 28 : index >= 21;
306
- const isLastColumn = (index + 1) % 7 === 0;
307
- // Retrieve events to render for this day
308
- const eventsToRender = eventRenderMap.get(dateKey) || [];
309
- const dayEvents = eventsByDay.get(dateKey) || [];
310
- const eventsToShow = eventsToRender.slice(0, MAX_EVENTS_PER_CELL);
311
- const remainingEventsCount = Math.max(0, dayEvents.length - MAX_EVENTS_PER_CELL);
312
- return (jsxRuntime.jsxs(calendarMonthViewCell.CalendarMonthViewCell, { day: date$1.day, isDisabled: !isCurrentMonthFlag, state: isSelectedFlag ? 'selected' : isTodayFlag ? 'current' : 'default', className: cx.cx(isLastRow && 'before:border-b-0', isLastColumn && 'before:border-r-0'), onClick: () => isCurrentMonthFlag && setSelectedDate(date$1), "data-testid": prefix ? testIdUtils.joinTestId(prefix, `cell-${testIdUtils.slugifyTestId(dateKey)}`) : undefined, children: [jsxRuntime.jsx("div", { className: "flex gap-1 max-md:pl-1 md:flex-col", children: eventsToShow.map(({ event, span, isPlaceholder }) => {
313
- // If this is a placeholder, render an invisible element to take up space
314
- if (isPlaceholder) {
315
- return (jsxRuntime.jsx("div", { className: "pointer-events-none opacity-0", children: jsxRuntime.jsx(calendarMonthViewEvent.CalendarMonthViewEvent, { label: event.title, collapseOnMobile: true, color: event.color, withDot: event.dot }) }, `${event.id}-placeholder`));
316
- }
317
- // Regular event rendering
318
- const eventStartDay = date.toCalendarDate(event.start);
319
- const eventEndDay = date.toCalendarDate(event.end);
320
- const startsToday = date.isSameDay(date$1, eventStartDay);
321
- const endsToday = date.isSameDay(date$1, eventEndDay);
322
- const continuesPrior = eventStartDay.compare(date$1) < 0;
323
- const continuesAfter = eventEndDay.compare(date$1) > 0;
324
- // Boundary checks compare times, not calendar days: an event starts "at day start"
325
- // only when it begins at midnight, and ends "at day end" when it ends at midnight
326
- // (exclusive-end convention) or at 23:59:59.999 (inclusive-end convention).
327
- const eventStartsAtDayStart = event.start.compare(getStartOfDay(event.start, timeZone)) === 0;
328
- const eventEndsAtDayEnd = event.end.compare(getStartOfDay(event.end, timeZone)) === 0 || event.end.compare(getEndOfDay(event.end, timeZone)) >= 0;
329
- const isAllDayForCell = (continuesPrior && continuesAfter) ||
330
- (startsToday && continuesAfter && eventStartsAtDayStart) ||
331
- (continuesPrior && endsToday && eventEndsAtDayEnd) ||
332
- (startsToday && endsToday && eventStartsAtDayStart && eventEndsAtDayEnd);
333
- const supportingText = isAllDayForCell ? undefined : formatTimeForMonth(event.start);
334
- // Apply custom width style for multi-day events
335
- const spanStyle = span > 1
336
- ? {
337
- zIndex: 1,
338
- width: `calc(${span * 100}% + ${(span - 1) * 16}px)`,
339
- }
340
- : undefined;
341
- return (jsxRuntime.jsx("div", { style: spanStyle, className: cx.cx(!isCurrentMonthFlag && 'opacity-50'), children: jsxRuntime.jsx(calendarMonthViewEvent.CalendarMonthViewEvent, { label: event.title, collapseOnMobile: true, supportingText: supportingText, color: event.color, withDot: event.dot, "data-testid": eventTestId(event.id) }) }, event.id));
342
- }) }), remainingEventsCount > 0 && (jsxRuntime.jsx("div", { className: "truncate text-xs font-semibold text-utility-neutral-500 max-md:pl-1", children: `${remainingEventsCount} more...` }))] }, dateKey));
343
- }) }), targetDateForFooter && (jsxRuntime.jsxs("div", { className: "border-t border-secondary px-4 py-5 md:hidden", children: [jsxRuntime.jsx("h3", { className: "text-sm font-semibold text-primary", children: fullDateFormatter.format(targetDateForFooter.toDate(timeZone)) }), eventsForFooter.length > 0 && (jsxRuntime.jsx("div", { className: "mt-4 flex flex-col gap-1.5", children: eventsForFooter.slice(0, 3).map((event) => {
344
- // "All day" when the event covers the entire displayed day. Comparing against the
345
- // footer's target day (not the event's own end day) handles exclusive-end events
346
- // (end = next midnight) and multi-day events spanning this day.
347
- const dayStart = getStartOfDay(targetDateForFooter, timeZone);
348
- const dayEnd = getEndOfDay(targetDateForFooter, timeZone);
349
- const isAllDay = event.start.compare(dayStart) <= 0 && event.end.compare(dayEnd) >= 0;
350
- const supportingText = isAllDay ? 'All day' : formatTimeForMonth(event.start);
351
- return (jsxRuntime.jsx(calendarMonthViewEvent.CalendarMonthViewEvent, { label: event.title, supportingText: supportingText, color: event.color, withDot: event.dot, "data-testid": eventTestId(event.id) }, `footer-${event.id}`));
352
- }) })), eventsForFooter.length === 0 && jsxRuntime.jsx("p", { className: "mt-4 text-xs font-semibold text-quaternary", children: "No events for this day." }), eventsForFooter.length > 3 && jsxRuntime.jsx("p", { className: "mt-4 text-xs font-semibold text-quaternary", children: `${eventsForFooter.length - 3} more...` })] }))] }));
353
- };
354
- const MobileSingleDayGrid = ({ dayToDisplay, dayEvents, timeZone, setSelectedDate, timeFormatter, className }) => {
355
- const dayStart = React.useMemo(() => getStartOfDay(dayToDisplay, timeZone), [dayToDisplay, timeZone]); // Calculate once
356
- return (jsxRuntime.jsxs("div", { className: cx.cx('relative flex-1', className), children: [Array.from({ length: 48 }).map((_, slotIndex) => (jsxRuntime.jsx(calendarDwViewCell.CalendarDwViewCell
357
- // biome-ignore lint/suspicious/noArrayIndexKey: This is a key for the slot
358
- , { className: cx.cx('before:border-r-0', slotIndex === 47 && 'before:border-b-0') }, `mobile-slot-${dayToDisplay.toString()}-${slotIndex}`))), dayEvents.map((event, index) => {
359
- const overlapIndex = dayEvents.filter((e, i) => i < index && event.start.compare(e.end) < 0 && event.end.compare(e.start) > 0).length;
360
- const totalOverlapping = dayEvents.filter((e) => event.start.compare(e.end) < 0 && event.end.compare(e.start) > 0).length;
361
- return (jsxRuntime.jsx(PositionedEvent, { event: event, dayStart: dayStart, timeZone: timeZone, slotHeight: SLOT_HEIGHT, overlapIndex: overlapIndex, totalOverlapping: totalOverlapping, setSelectedDate: setSelectedDate, timeFormatter: timeFormatter }, event.id));
362
- })] }));
363
- };
364
- const WeekViewDay = ({ day, isLastDay, visibleEvents, timeZone, slotHeight, setSelectedDate, timeFormatter }) => {
365
- const dateKey = day.toString();
366
- const dayEvents = React.useMemo(() => getEventsForDay(visibleEvents, day, timeZone), [visibleEvents, day, timeZone]);
367
- const dayStart = React.useMemo(() => getStartOfDay(day, timeZone), [day, timeZone]);
368
- return (jsxRuntime.jsx("div", { className: "flex flex-col border-secondary", children: jsxRuntime.jsxs("div", { className: "relative flex-1 bg-primary", style: { minHeight: `${48 * slotHeight}px` }, children: [Array.from({ length: 48 }).map((_, slotIndex) => (jsxRuntime.jsx(calendarDwViewCell.CalendarDwViewCell
369
- // biome-ignore lint/suspicious/noArrayIndexKey: fixed 48 half-hour slots — the index is a stable slot position
370
- , { className: cx.cx('last:before:border-b-0', isLastDay && 'before:border-r-0') }, `slot-${dateKey}-${slotIndex}`))), dayEvents.map((event, index) => {
371
- const overlapIndex = dayEvents.filter((e, i) => i < index && event.start.compare(e.end) < 0 && event.end.compare(e.start) > 0).length;
372
- const totalOverlapping = dayEvents.filter((e) => event.start.compare(e.end) < 0 && event.end.compare(e.start) > 0).length;
373
- return (jsxRuntime.jsx(PositionedEvent, { event: event, dayStart: dayStart, timeZone: timeZone, slotHeight: slotHeight, overlapIndex: overlapIndex, totalOverlapping: totalOverlapping, setSelectedDate: setSelectedDate, timeFormatter: timeFormatter }, event.id));
374
- })] }) }));
375
- };
376
- const WeekView = ({ currentMonthDate, selectedDate, zonedEvents, locale, timeZone, currentTime, setSelectedDate, shortWeekdayFormatter, timeFormatter, hourOnlyFormatter, className, view, }) => {
377
- const currentWeekStart = date.startOfWeek(currentMonthDate, locale);
378
- const currentWeekEnd = date.endOfWeek(currentMonthDate, locale);
379
- const localCurrentTime = currentTime;
380
- const scrollContainerRef = React.useRef(null);
381
- const formatTime = (dateTime) => timeFormatter.format(dateTime.toDate());
382
- const showTimeMarker = localCurrentTime.compare(date.toZoned(currentWeekStart, timeZone)) >= 0 &&
383
- localCurrentTime.compare(date.toZoned(currentWeekEnd, timeZone).add({ days: 1 })) < 0;
384
- const days = [];
385
- let dayIterator = currentWeekStart;
386
- while (dayIterator.compare(currentWeekEnd) <= 0) {
387
- days.push(dayIterator);
388
- dayIterator = dayIterator.add({ days: 1 });
389
- }
390
- const hours = Array.from({ length: 24 }, (_, i) => i);
391
- let timeMarkerTop = 0;
392
- if (showTimeMarker) {
393
- const startOfVisibleDay = getStartOfDay(localCurrentTime, timeZone);
394
- const minutesFromTop = localCurrentTime.hour * 60 + localCurrentTime.minute - (startOfVisibleDay.hour * 60 + startOfVisibleDay.minute);
395
- timeMarkerTop = (minutesFromTop / 30) * SLOT_HEIGHT;
396
- }
397
- const visibleEvents = zonedEvents.filter((event) => {
398
- const eventStartDay = date.toCalendarDate(event.start);
399
- const eventEndDay = date.toCalendarDate(event.end);
400
- return eventStartDay.compare(currentWeekEnd) <= 0 && eventEndDay.compare(currentWeekStart) >= 0;
401
- });
402
- // Calculate earliest event time for the entire week or default to 8 AM
403
- const earliestEventTimeInWeek = React.useMemo(() => {
404
- if (visibleEvents.length === 0) {
405
- // Default scroll target: 8 AM of the week start day
406
- return date.toZoned(currentWeekStart, timeZone).set({ hour: 8 });
407
- }
408
- // Find the earliest start time across all visible events in the week
409
- return visibleEvents.reduce((earliest, current) => {
410
- return current.start.compare(earliest.start) < 0 ? current : earliest;
411
- }).start;
412
- }, [visibleEvents, currentWeekStart, timeZone]);
413
- // Effect to scroll to the earliest event - Use useLayoutEffect
414
- // biome-ignore lint/correctness/useExhaustiveDependencies: We need to include currentMonthDate in the dependency array to recalculate the earliest event time when the week changes
415
- React.useLayoutEffect(() => {
416
- // Only scroll if the view is 'week' and the ref is attached
417
- if (view === 'week' && scrollContainerRef.current && earliestEventTimeInWeek) {
418
- const startMinutes = earliestEventTimeInWeek.hour * 60 + earliestEventTimeInWeek.minute;
419
- // Calculate target scroll, ensuring it's not negative
420
- let targetScrollTop = Math.max(0, (startMinutes / 30) * SLOT_HEIGHT);
421
- // Optional: Add an offset
422
- targetScrollTop = Math.max(0, targetScrollTop - SLOT_HEIGHT);
423
- // No need for setTimeout with useLayoutEffect for initial scroll
424
- if (scrollContainerRef.current) {
425
- scrollContainerRef.current.scrollTop = targetScrollTop;
426
- }
427
- }
428
- // Dependency array includes view and earliestEventTimeInWeek
429
- // currentMonthDate determines the week, which affects earliestEventTimeInWeek calculation
430
- }, [view, earliestEventTimeInWeek, currentMonthDate]);
431
- return (jsxRuntime.jsxs("div", { className: cx.cx('flex flex-1 flex-col overflow-auto', className), children: [jsxRuntime.jsx("div", { className: "sticky top-0 z-10 grid grid-cols-7 bg-primary pl-18 shadow-sm dark:border-b dark:border-secondary", children: days.map((day) => {
432
- const isTodayFlag = date.isToday(day, timeZone);
433
- const dayToHighlight = selectedDate && day.compare(currentWeekStart) >= 0 && day.compare(currentWeekEnd) <= 0 ? selectedDate : currentWeekStart;
434
- const isSelectedFlag = date.isSameDay(day, dayToHighlight);
435
- const weekDayShort = shortWeekdayFormatter.format(day.toDate(timeZone));
436
- return (jsxRuntime.jsx(calendarColumnHeader.CalendarColumnHeader, { onClick: () => setSelectedDate(day), weekDay: weekDayShort, day: day.day, state: isSelectedFlag ? 'selected' : isTodayFlag ? 'current' : 'default', className: "cursor-pointer first:before:-left-px first:before:border-l" }, `mobile-header-${day.toString()}`));
437
- }) }), jsxRuntime.jsxs("div", { ref: scrollContainerRef, tabIndex: 0, className: "relative flex flex-1 overflow-y-auto", children: [jsxRuntime.jsx("div", { className: "flex h-max w-18 flex-col border-r border-secondary", children: hours.map((hour) => {
438
- const time = new date.CalendarDateTime(currentWeekStart.year, currentWeekStart.month, currentWeekStart.day, hour);
439
- const timeString = hourOnlyFormatter.format(date.toZoned(time, timeZone).toDate());
440
- return jsxRuntime.jsx(calendarRowLabel.CalendarRowLabel, { children: timeString }, `time-${hour}`);
441
- }) }), jsxRuntime.jsx("div", { className: "grid flex-1 grid-cols-7", children: days.map((day, index) => {
442
- const isLastDay = index === days.length - 1;
443
- return (jsxRuntime.jsx(WeekViewDay, { day: day, isLastDay: isLastDay, visibleEvents: visibleEvents, timeZone: timeZone, slotHeight: SLOT_HEIGHT, setSelectedDate: setSelectedDate, timeFormatter: timeFormatter }, day.toString()));
444
- }) }), showTimeMarker && jsxRuntime.jsx(calendarTimeMarker.CalendarTimeMarker, { style: { top: `${timeMarkerTop}px` }, children: formatTime(localCurrentTime) })] })] }));
445
- };
446
- const DayView = ({ dayToDisplay, zonedEvents, locale, timeZone, currentTime, setSelectedDate, shortWeekdayFormatter, timeFormatter, hourOnlyFormatter, selectedDate, className, view, }) => {
447
- const currentWeekStart = date.startOfWeek(dayToDisplay, locale);
448
- const currentWeekEnd = date.endOfWeek(dayToDisplay, locale);
449
- const localCurrentTime = currentTime;
450
- const formatTime = (dateTime) => timeFormatter.format(dateTime.toDate());
451
- const showTimeMarker = date.isSameDay(date.toCalendarDate(localCurrentTime), dayToDisplay);
452
- const hours = Array.from({ length: 24 }, (_, i) => i);
453
- let timeMarkerTop = 0;
454
- if (showTimeMarker) {
455
- const minutesFromDayStart = localCurrentTime.hour * 60 + localCurrentTime.minute;
456
- timeMarkerTop = (minutesFromDayStart / 30) * SLOT_HEIGHT;
457
- }
458
- const visibleEvents = React.useMemo(() => getEventsForDay(zonedEvents, dayToDisplay, timeZone), [zonedEvents, dayToDisplay, timeZone]);
459
- const highlightedDates = React.useMemo(() => {
460
- const datesWithEvents = new Set();
461
- zonedEvents.forEach((event) => {
462
- let currentDate = date.toCalendarDate(event.start);
463
- const endDate = date.toCalendarDate(event.end);
464
- // Iterate through each day the event spans
465
- while (currentDate.compare(endDate) <= 0) {
466
- datesWithEvents.add(currentDate.toString());
467
- currentDate = currentDate.add({ days: 1 });
468
- }
469
- });
470
- return datesWithEvents;
471
- }, [zonedEvents]);
472
- const days = [];
473
- let dayIterator = currentWeekStart;
474
- while (dayIterator.compare(currentWeekEnd) <= 0) {
475
- days.push(dayIterator);
476
- dayIterator = dayIterator.add({ days: 1 });
477
- }
478
- const scrollContainerRef = React.useRef(null);
479
- // Calculate earliest event time or default to 8 AM
480
- const earliestEventTime = React.useMemo(() => {
481
- if (visibleEvents.length === 0) {
482
- // Default scroll target: 8 AM of the displayed day
483
- return date.toZoned(dayToDisplay, timeZone).set({ hour: 8 });
484
- }
485
- // Find the earliest start time among visible events
486
- return visibleEvents.reduce((earliest, current) => {
487
- return current.start.compare(earliest.start) < 0 ? current : earliest;
488
- }).start;
489
- }, [visibleEvents, dayToDisplay, timeZone]);
490
- // Effect to scroll to the earliest event - Use useLayoutEffect
491
- // biome-ignore lint/correctness/useExhaustiveDependencies: We need to include view, earliestEventTime, and dayToDisplay in the dependency array to re-trigger on changes
492
- React.useLayoutEffect(() => {
493
- // Only scroll if the view is 'day' and the ref is attached
494
- if (view === 'day' && scrollContainerRef.current && earliestEventTime) {
495
- const startMinutes = earliestEventTime.hour * 60 + earliestEventTime.minute;
496
- // Calculate target scroll, ensuring it's not negative
497
- let targetScrollTop = Math.max(0, (startMinutes / 30) * SLOT_HEIGHT);
498
- // Optional: Add an offset to show some context before the first event (e.g., scroll up by one slot height)
499
- targetScrollTop = Math.max(0, targetScrollTop - SLOT_HEIGHT);
500
- // No need for setTimeout with useLayoutEffect for initial scroll
501
- if (scrollContainerRef.current) {
502
- scrollContainerRef.current.scrollTop = targetScrollTop;
503
- }
504
- }
505
- // Dependency array includes view, earliestEventTime, and dayToDisplay to re-trigger on changes
506
- }, [view, earliestEventTime, dayToDisplay]);
507
- return (jsxRuntime.jsxs("div", { className: cx.cx('flex flex-1 flex-col overflow-auto', className), children: [jsxRuntime.jsx("div", { className: "sticky top-0 z-20 grid grid-cols-7 bg-primary shadow-sm lg:hidden dark:border-b dark:border-secondary", children: days.map((day) => {
508
- const isTodayFlag = date.isToday(day, timeZone);
509
- const dayToHighlight = selectedDate && day.compare(currentWeekStart) >= 0 && day.compare(currentWeekEnd) <= 0 ? selectedDate : currentWeekStart;
510
- const isSelectedFlag = date.isSameDay(day, dayToHighlight);
511
- const weekDayShort = shortWeekdayFormatter.format(day.toDate(timeZone));
512
- return (jsxRuntime.jsx(calendarColumnHeader.CalendarColumnHeader, { onClick: () => setSelectedDate(day), weekDay: weekDayShort, day: day.day, state: isSelectedFlag ? 'selected' : isTodayFlag ? 'current' : 'default', className: "cursor-pointer" }, `mobile-header-${day.toString()}`));
513
- }) }), jsxRuntime.jsxs("div", { className: "flex h-full flex-1", children: [jsxRuntime.jsxs("div", { ref: scrollContainerRef, tabIndex: 0, className: "relative flex h-full flex-1 overflow-auto", children: [jsxRuntime.jsx("div", { className: "flex h-max w-14 flex-col border-r border-secondary md:w-18", children: hours.map((hour) => {
514
- const time = new date.CalendarDateTime(dayToDisplay.year, dayToDisplay.month, dayToDisplay.day, hour);
515
- const timeString = hourOnlyFormatter.format(date.toZoned(time, timeZone).toDate());
516
- return jsxRuntime.jsx(calendarRowLabel.CalendarRowLabel, { children: timeString }, `time-${hour}`);
517
- }) }), jsxRuntime.jsx(MobileSingleDayGrid, { dayToDisplay: dayToDisplay, dayEvents: visibleEvents, timeZone: timeZone, locale: locale, currentTime: currentTime, setSelectedDate: setSelectedDate, timeFormatter: timeFormatter }), showTimeMarker && jsxRuntime.jsx(calendarTimeMarker.CalendarTimeMarker, { style: { top: `${timeMarkerTop}px` }, children: formatTime(localCurrentTime) })] }), jsxRuntime.jsxs("div", { className: "sticky top-0 hidden h-full w-82 flex-col overflow-auto border-l border-secondary mask-b-from-94% lg:flex", children: [jsxRuntime.jsxs(reactAriaComponents.Calendar, { "aria-label": "Calendar", className: "px-6 py-5", value: selectedDate, onChange: (value) => setSelectedDate(value), children: [jsxRuntime.jsxs("div", { className: "mb-3 flex items-center justify-between", children: [jsxRuntime.jsx(Button.Button, { slot: "previous", iconLeading: uiIcons.ChevronLeft, size: "sm", color: "tertiary", className: "size-8" }), jsxRuntime.jsx(reactAriaComponents.Heading, { className: "text-sm font-semibold text-fg-secondary" }), jsxRuntime.jsx(Button.Button, { slot: "next", iconLeading: uiIcons.ChevronRight, size: "sm", color: "tertiary", className: "size-8" })] }), jsxRuntime.jsxs(reactAriaComponents.CalendarGrid, { weekdayStyle: "short", className: "w-max", children: [jsxRuntime.jsx(reactAriaComponents.CalendarGridHeader, { className: "border-b-4 border-transparent", children: (day) => (jsxRuntime.jsx(reactAriaComponents.CalendarHeaderCell, { className: "p-0", children: jsxRuntime.jsx("div", { className: "flex size-10 items-center justify-center text-sm font-medium text-secondary", children: day.slice(0, 2) }) })) }), jsxRuntime.jsx(reactAriaComponents.CalendarGridBody, { className: "[&_td]:p-0 [&_tr]:border-b-4 [&_tr]:border-transparent [&_tr:last-of-type]:border-none", children: (date) => jsxRuntime.jsx(cell.CalendarCell, { date: date, isHighlighted: highlightedDates.has(date.toString()) }) })] })] }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-5 border-t border-secondary px-6 py-5", children: [jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntime.jsxs("section", { className: "flex w-full justify-between", children: [jsxRuntime.jsx("p", { className: "text-md font-semibold text-primary", children: "Product demo" }), jsxRuntime.jsxs("div", { className: "-mt-2 -mr-2 flex gap-0.5", children: [jsxRuntime.jsx(UtilityButton.ButtonUtility, { size: "xs", color: "tertiary", tooltip: "Copy link", icon: uiIcons.Copy01 }), jsxRuntime.jsx(UtilityButton.ButtonUtility, { size: "xs", color: "tertiary", tooltip: "Delete", icon: uiIcons.Trash01 }), jsxRuntime.jsx(UtilityButton.ButtonUtility, { size: "xs", color: "tertiary", tooltip: "Edit", icon: uiIcons.Edit01 })] })] }), jsxRuntime.jsxs("section", { className: "flex flex-col gap-1.5", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [jsxRuntime.jsx(uiIcons.Calendar, { className: "size-4 stroke-[2.25px] text-fg-quaternary" }), jsxRuntime.jsx("p", { className: "text-sm text-tertiary", children: "Friday, Jan 10, 2027" })] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [jsxRuntime.jsx(uiIcons.Clock, { className: "size-4 stroke-[2.25px] text-fg-quaternary" }), jsxRuntime.jsx("p", { className: "text-sm text-tertiary", children: "1:30 PM - 3:30 PM" })] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [jsxRuntime.jsx(uiIcons.BellRinging01, { className: "size-4 stroke-[2.25px] text-fg-quaternary" }), jsxRuntime.jsx("p", { className: "text-sm text-tertiary", children: "10 min before" })] })] })] }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [jsxRuntime.jsxs("section", { className: "flex gap-2", children: [jsxRuntime.jsxs("section", { className: "flex flex-row -space-x-2", children: [jsxRuntime.jsx(Avatar.Avatar, { className: "ring-[1.5px] ring-bg-primary", src: "https://www.untitledui.com/images/avatars/sienna-hewitt?fm=webp&q=80", alt: "Sienna Hewitt", size: "sm" }), jsxRuntime.jsx(Avatar.Avatar, { className: "ring-[1.5px] ring-bg-primary", src: "https://www.untitledui.com/images/avatars/ammar-foley?fm=webp&q=80", alt: "Ammar Foley", size: "sm" }), jsxRuntime.jsx(Avatar.Avatar, { className: "ring-[1.5px] ring-bg-primary", src: "https://www.untitledui.com/images/avatars/pippa-wilkinson?fm=webp&q=80", alt: "Pippa Wilkinson", size: "sm" }), jsxRuntime.jsx(Avatar.Avatar, { className: "ring-[1.5px] ring-bg-primary", src: "https://www.untitledui.com/images/avatars/olly-schroeder?fm=webp&q=80", alt: "Olly Schroeder", size: "sm" }), jsxRuntime.jsx(Avatar.Avatar, { className: "ring-[1.5px] ring-bg-primary", src: "https://www.untitledui.com/images/avatars/mathilde-lewis?fm=webp&q=80", alt: "Mathilde Lewis", size: "sm" }), jsxRuntime.jsx(Avatar.Avatar, { className: "ring-[1.5px] ring-bg-primary", initials: "OR", size: "sm" })] }), jsxRuntime.jsx(Avatar.AvatarAddButton, { size: "sm" })] }), jsxRuntime.jsxs("section", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("p", { className: "text-sm font-semibold text-primary", children: "6 guests" }), jsxRuntime.jsx("span", { className: "h-[13px] border-l border-primary" }), jsxRuntime.jsx("p", { className: "text-sm text-tertiary", children: "5 yes" }), jsxRuntime.jsx("span", { className: "h-[13px] border-l border-primary" }), jsxRuntime.jsx("p", { className: "text-sm text-tertiary", children: "1 awaiting" })] })] }), jsxRuntime.jsxs("section", { className: "flex flex-col gap-2", children: [jsxRuntime.jsx("p", { className: "text-sm font-semibold text-primary", children: "About this event" }), jsxRuntime.jsxs("div", { className: "text-sm text-tertiary", children: [jsxRuntime.jsx("p", { children: "Sienna is inviting you to a scheduled Zoom meeting." }), jsxRuntime.jsx("br", {}), jsxRuntime.jsx("p", { children: "Topic: Product demo for the new dashboard and Q&A session." }), jsxRuntime.jsx("br", {}), jsxRuntime.jsxs("p", { className: "wrap-break-word whitespace-normal", children: ["Join Zoom Meeting:\u00A0", jsxRuntime.jsx("span", { className: "break-all underline", children: "https://us02web.zoom.us/j/86341969512" }), "\u00A0"] }), jsxRuntime.jsx("br", {}), jsxRuntime.jsx("p", { children: "Meeting ID: 863 4196 9512" })] })] })] })] })] })] }));
518
- };
519
19
  /**
520
20
  * A scheduling calendar that renders a list of events across month, week, and
521
21
  * day views, with built-in navigation, a current-time marker, and a responsive
@@ -588,7 +88,7 @@ const Calendar = ({ events, view: defaultView = 'month', className, 'data-testid
588
88
  const dayToDisplay = selectedDate || currentMonthDate;
589
89
  if (!isMounted)
590
90
  return null;
591
- return (jsxRuntime.jsx(testIdUtils.TestIdProvider, { value: rootTestId, children: jsxRuntime.jsxs("div", { role: "application", "aria-label": "Calendar", "data-testid": rootTestId, className: cx.cx('flex flex-col overflow-hidden rounded-xl bg-primary shadow-xs ring ring-secondary', view === 'month' ? 'h-full md:min-h-[912px]' : 'h-[912px]', className), children: [jsxRuntime.jsx(calendarHeader.CalendarHeader, { date: headerDate, selectedView: view, onSelectionChange: setView, viewOptions: viewOptions, onClickPrev: () => handleNavigate('PREV'), onClickNext: () => handleNavigate('NEXT'), onClickToday: () => handleNavigate('TODAY') }), jsxRuntime.jsxs("div", { className: "flex flex-1 overflow-hidden", children: [view === 'month' && (jsxRuntime.jsx(MonthView, { currentMonthDate: currentMonthDate, selectedDate: selectedDate, zonedEvents: zonedEvents, locale: locale, timeZone: timeZone, setSelectedDate: setSelectedDate, fullDateFormatter: fullDateFormatter, shortWeekdayFormatter: shortWeekdayFormatter, timeFormatter: timeFormatter })), view === 'week' && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(DayView, { dayToDisplay: dayToDisplay, selectedDate: selectedDate, zonedEvents: zonedEvents, locale: locale, timeZone: timeZone, currentTime: currentTime, setSelectedDate: setSelectedDate, shortWeekdayFormatter: shortWeekdayFormatter, timeFormatter: timeFormatter, hourOnlyFormatter: hourOnlyFormatter, view: view, className: "md:hidden" }), jsxRuntime.jsx(WeekView, { currentMonthDate: currentMonthDate, selectedDate: selectedDate, zonedEvents: zonedEvents, locale: locale, timeZone: timeZone, currentTime: currentTime, setSelectedDate: setSelectedDate, shortWeekdayFormatter: shortWeekdayFormatter, timeFormatter: timeFormatter, hourOnlyFormatter: hourOnlyFormatter, view: view, className: "max-md:hidden" })] })), view === 'day' && (jsxRuntime.jsx(DayView, { dayToDisplay: dayToDisplay, selectedDate: selectedDate, zonedEvents: zonedEvents, locale: locale, timeZone: timeZone, currentTime: currentTime, setSelectedDate: setSelectedDate, shortWeekdayFormatter: shortWeekdayFormatter, timeFormatter: timeFormatter, hourOnlyFormatter: hourOnlyFormatter, view: view }))] })] }) }));
91
+ return (jsxRuntime.jsx(testIdUtils.TestIdProvider, { value: rootTestId, children: jsxRuntime.jsxs("div", { role: "application", "aria-label": "Calendar", "data-testid": rootTestId, className: cx.cx('flex flex-col overflow-hidden rounded-xl bg-primary shadow-xs ring ring-secondary', view === 'month' ? 'h-full md:min-h-[912px]' : 'h-[912px]', className), children: [jsxRuntime.jsx(calendarHeader.CalendarHeader, { date: headerDate, selectedView: view, onSelectionChange: setView, viewOptions: viewOptions, onClickPrev: () => handleNavigate('PREV'), onClickNext: () => handleNavigate('NEXT'), onClickToday: () => handleNavigate('TODAY') }), jsxRuntime.jsxs("div", { className: "flex flex-1 overflow-hidden", children: [view === 'month' && (jsxRuntime.jsx(calendarMonthView.MonthView, { currentMonthDate: currentMonthDate, selectedDate: selectedDate, zonedEvents: zonedEvents, locale: locale, timeZone: timeZone, setSelectedDate: setSelectedDate, fullDateFormatter: fullDateFormatter, shortWeekdayFormatter: shortWeekdayFormatter, timeFormatter: timeFormatter })), view === 'week' && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(calendarDayView.DayView, { dayToDisplay: dayToDisplay, selectedDate: selectedDate, zonedEvents: zonedEvents, locale: locale, timeZone: timeZone, currentTime: currentTime, setSelectedDate: setSelectedDate, shortWeekdayFormatter: shortWeekdayFormatter, timeFormatter: timeFormatter, hourOnlyFormatter: hourOnlyFormatter, view: view, className: "md:hidden" }), jsxRuntime.jsx(calendarWeekView.WeekView, { currentMonthDate: currentMonthDate, selectedDate: selectedDate, zonedEvents: zonedEvents, locale: locale, timeZone: timeZone, currentTime: currentTime, setSelectedDate: setSelectedDate, shortWeekdayFormatter: shortWeekdayFormatter, timeFormatter: timeFormatter, hourOnlyFormatter: hourOnlyFormatter, view: view, className: "max-md:hidden" })] })), view === 'day' && (jsxRuntime.jsx(calendarDayView.DayView, { dayToDisplay: dayToDisplay, selectedDate: selectedDate, zonedEvents: zonedEvents, locale: locale, timeZone: timeZone, currentTime: currentTime, setSelectedDate: setSelectedDate, shortWeekdayFormatter: shortWeekdayFormatter, timeFormatter: timeFormatter, hourOnlyFormatter: hourOnlyFormatter, view: view }))] })] }) }));
592
92
  };
593
93
 
594
94
  exports.Calendar = Calendar;