@kodffe/ui 0.0.0-stage → 0.10.1

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 (304) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +11 -0
  2. package/dist/accordion/accordion.d.ts +44 -0
  3. package/dist/accordion/accordion.js +84 -0
  4. package/dist/accordion/accordion.js.map +1 -0
  5. package/dist/alert/alert.d.ts +17 -0
  6. package/dist/alert/alert.js +59 -0
  7. package/dist/alert/alert.js.map +1 -0
  8. package/dist/app-shell/app-footer.d.ts +29 -0
  9. package/dist/app-shell/app-footer.js +39 -0
  10. package/dist/app-shell/app-footer.js.map +1 -0
  11. package/dist/app-shell/app-shell-context.d.ts +10 -0
  12. package/dist/app-shell/app-shell-context.js +12 -0
  13. package/dist/app-shell/app-shell-context.js.map +1 -0
  14. package/dist/app-shell/app-shell.d.ts +42 -0
  15. package/dist/app-shell/app-shell.js +191 -0
  16. package/dist/app-shell/app-shell.js.map +1 -0
  17. package/dist/app-shell/floating-actions.d.ts +19 -0
  18. package/dist/app-shell/floating-actions.js +59 -0
  19. package/dist/app-shell/floating-actions.js.map +1 -0
  20. package/dist/app-shell/workspace-switcher.d.ts +25 -0
  21. package/dist/app-shell/workspace-switcher.js +82 -0
  22. package/dist/app-shell/workspace-switcher.js.map +1 -0
  23. package/dist/badge/badge.d.ts +19 -0
  24. package/dist/badge/badge.js +59 -0
  25. package/dist/badge/badge.js.map +1 -0
  26. package/dist/banner/banner.d.ts +22 -0
  27. package/dist/banner/banner.js +80 -0
  28. package/dist/banner/banner.js.map +1 -0
  29. package/dist/breadcrumbs/breadcrumbs.d.ts +18 -0
  30. package/dist/breadcrumbs/breadcrumbs.js +45 -0
  31. package/dist/breadcrumbs/breadcrumbs.js.map +1 -0
  32. package/dist/button/button.d.ts +38 -0
  33. package/dist/button/button.js +83 -0
  34. package/dist/button/button.js.map +1 -0
  35. package/dist/card/card.d.ts +159 -0
  36. package/dist/card/card.js +390 -0
  37. package/dist/card/card.js.map +1 -0
  38. package/dist/card/insight-card.d.ts +19 -0
  39. package/dist/card/insight-card.js +51 -0
  40. package/dist/card/insight-card.js.map +1 -0
  41. package/dist/card/integration-card.d.ts +19 -0
  42. package/dist/card/integration-card.js +70 -0
  43. package/dist/card/integration-card.js.map +1 -0
  44. package/dist/charts/charts.d.ts +75 -0
  45. package/dist/charts/charts.js +453 -0
  46. package/dist/charts/charts.js.map +1 -0
  47. package/dist/choice/choice.d.ts +39 -0
  48. package/dist/choice/choice.js +143 -0
  49. package/dist/choice/choice.js.map +1 -0
  50. package/dist/combobox/combobox.d.ts +46 -0
  51. package/dist/combobox/combobox.js +196 -0
  52. package/dist/combobox/combobox.js.map +1 -0
  53. package/dist/command-palette/command-palette.d.ts +35 -0
  54. package/dist/command-palette/command-palette.js +164 -0
  55. package/dist/command-palette/command-palette.js.map +1 -0
  56. package/dist/confirm-dialog/confirm-dialog.d.ts +37 -0
  57. package/dist/confirm-dialog/confirm-dialog.js +106 -0
  58. package/dist/confirm-dialog/confirm-dialog.js.map +1 -0
  59. package/dist/content/assistant.d.ts +86 -0
  60. package/dist/content/assistant.js +213 -0
  61. package/dist/content/assistant.js.map +1 -0
  62. package/dist/content/content.d.ts +45 -0
  63. package/dist/content/content.js +136 -0
  64. package/dist/content/content.js.map +1 -0
  65. package/dist/data-display/avatar-sizes.d.ts +8 -0
  66. package/dist/data-display/avatar-sizes.js +12 -0
  67. package/dist/data-display/avatar-sizes.js.map +1 -0
  68. package/dist/data-display/avatar.d.ts +21 -0
  69. package/dist/data-display/avatar.js +53 -0
  70. package/dist/data-display/avatar.js.map +1 -0
  71. package/dist/data-display/chip.d.ts +20 -0
  72. package/dist/data-display/chip.js +64 -0
  73. package/dist/data-display/chip.js.map +1 -0
  74. package/dist/data-display/code-block.d.ts +14 -0
  75. package/dist/data-display/code-block.js +50 -0
  76. package/dist/data-display/code-block.js.map +1 -0
  77. package/dist/data-display/data-display.d.ts +73 -0
  78. package/dist/data-display/data-display.js +227 -0
  79. package/dist/data-display/data-display.js.map +1 -0
  80. package/dist/data-display/insights.d.ts +120 -0
  81. package/dist/data-display/insights.js +220 -0
  82. package/dist/data-display/insights.js.map +1 -0
  83. package/dist/data-table/cells.d.ts +86 -0
  84. package/dist/data-table/cells.js +163 -0
  85. package/dist/data-table/cells.js.map +1 -0
  86. package/dist/data-table/data-table.d.ts +112 -0
  87. package/dist/data-table/data-table.js +558 -0
  88. package/dist/data-table/data-table.js.map +1 -0
  89. package/dist/date-picker/date-picker.d.ts +61 -0
  90. package/dist/date-picker/date-picker.js +309 -0
  91. package/dist/date-picker/date-picker.js.map +1 -0
  92. package/dist/drawer/drawer.d.ts +32 -0
  93. package/dist/drawer/drawer.js +72 -0
  94. package/dist/drawer/drawer.js.map +1 -0
  95. package/dist/empty-state/empty-state.d.ts +25 -0
  96. package/dist/empty-state/empty-state.js +78 -0
  97. package/dist/empty-state/empty-state.js.map +1 -0
  98. package/dist/error-state/error-state.d.ts +19 -0
  99. package/dist/error-state/error-state.js +56 -0
  100. package/dist/error-state/error-state.js.map +1 -0
  101. package/dist/event-calendar/calendar-logic.test.d.ts +1 -0
  102. package/dist/event-calendar/dates.d.ts +35 -0
  103. package/dist/event-calendar/dates.js +55 -0
  104. package/dist/event-calendar/dates.js.map +1 -0
  105. package/dist/event-calendar/event-calendar.d.ts +125 -0
  106. package/dist/event-calendar/event-calendar.js +795 -0
  107. package/dist/event-calendar/event-calendar.js.map +1 -0
  108. package/dist/event-calendar/event-details.d.ts +50 -0
  109. package/dist/event-calendar/event-details.js +124 -0
  110. package/dist/event-calendar/event-details.js.map +1 -0
  111. package/dist/event-calendar/layout.d.ts +48 -0
  112. package/dist/event-calendar/layout.js +55 -0
  113. package/dist/event-calendar/layout.js.map +1 -0
  114. package/dist/file-upload/file-upload.d.ts +70 -0
  115. package/dist/file-upload/file-upload.js +307 -0
  116. package/dist/file-upload/file-upload.js.map +1 -0
  117. package/dist/filters/filters.d.ts +48 -0
  118. package/dist/filters/filters.js +103 -0
  119. package/dist/filters/filters.js.map +1 -0
  120. package/dist/form-field/form-field.d.ts +39 -0
  121. package/dist/form-field/form-field.js +88 -0
  122. package/dist/form-field/form-field.js.map +1 -0
  123. package/dist/hover-card/hover-card.d.ts +15 -0
  124. package/dist/hover-card/hover-card.js +27 -0
  125. package/dist/hover-card/hover-card.js.map +1 -0
  126. package/dist/hover-card/person-hover-card.d.ts +26 -0
  127. package/dist/hover-card/person-hover-card.js +85 -0
  128. package/dist/hover-card/person-hover-card.js.map +1 -0
  129. package/dist/icon/icon-tile.d.ts +20 -0
  130. package/dist/icon/icon-tile.js +55 -0
  131. package/dist/icon/icon-tile.js.map +1 -0
  132. package/dist/icon/icon.d.ts +14 -0
  133. package/dist/icon/icon.js +28 -0
  134. package/dist/icon/icon.js.map +1 -0
  135. package/dist/icon/icons.generated.d.ts +358 -0
  136. package/dist/icon/icons.generated.js +362 -0
  137. package/dist/icon/icons.generated.js.map +1 -0
  138. package/dist/index.d.ts +90 -0
  139. package/dist/index.js +88 -0
  140. package/dist/input/extra-inputs.d.ts +122 -0
  141. package/dist/input/extra-inputs.js +351 -0
  142. package/dist/input/extra-inputs.js.map +1 -0
  143. package/dist/input/field-styles.d.ts +5 -0
  144. package/dist/input/field-styles.js +14 -0
  145. package/dist/input/field-styles.js.map +1 -0
  146. package/dist/input/input.d.ts +50 -0
  147. package/dist/input/input.js +107 -0
  148. package/dist/input/input.js.map +1 -0
  149. package/dist/layout/layout.d.ts +41 -0
  150. package/dist/layout/layout.js +90 -0
  151. package/dist/layout/layout.js.map +1 -0
  152. package/dist/lib/control-styles.d.ts +9 -0
  153. package/dist/lib/control-styles.js +16 -0
  154. package/dist/lib/control-styles.js.map +1 -0
  155. package/dist/lib/cx.d.ts +2 -0
  156. package/dist/lib/cx.js +8 -0
  157. package/dist/lib/cx.js.map +1 -0
  158. package/dist/lib/glyphs.d.ts +13 -0
  159. package/dist/lib/glyphs.js +67 -0
  160. package/dist/lib/glyphs.js.map +1 -0
  161. package/dist/lib/segmented-styles.d.ts +8 -0
  162. package/dist/lib/segmented-styles.js +12 -0
  163. package/dist/lib/segmented-styles.js.map +1 -0
  164. package/dist/lib/select-on-arrow.d.ts +7 -0
  165. package/dist/lib/select-on-arrow.js +21 -0
  166. package/dist/lib/select-on-arrow.js.map +1 -0
  167. package/dist/lib/skip-link.d.ts +5 -0
  168. package/dist/lib/skip-link.js +13 -0
  169. package/dist/lib/skip-link.js.map +1 -0
  170. package/dist/lib/use-media-query.d.ts +4 -0
  171. package/dist/lib/use-media-query.js +15 -0
  172. package/dist/lib/use-media-query.js.map +1 -0
  173. package/dist/lists/lists.d.ts +76 -0
  174. package/dist/lists/lists.js +133 -0
  175. package/dist/lists/lists.js.map +1 -0
  176. package/dist/locale-switch/locale-switch.d.ts +29 -0
  177. package/dist/locale-switch/locale-switch.js +62 -0
  178. package/dist/locale-switch/locale-switch.js.map +1 -0
  179. package/dist/logo/logo.d.ts +31 -0
  180. package/dist/logo/logo.js +157 -0
  181. package/dist/logo/logo.js.map +1 -0
  182. package/dist/logo/product-logo.d.ts +19 -0
  183. package/dist/logo/product-logo.js +46 -0
  184. package/dist/logo/product-logo.js.map +1 -0
  185. package/dist/marketing/marketing.d.ts +176 -0
  186. package/dist/marketing/marketing.js +451 -0
  187. package/dist/marketing/marketing.js.map +1 -0
  188. package/dist/marketing/newsletter-form.d.ts +21 -0
  189. package/dist/marketing/newsletter-form.js +100 -0
  190. package/dist/marketing/newsletter-form.js.map +1 -0
  191. package/dist/mascot/mascot.d.ts +28 -0
  192. package/dist/mascot/mascot.js +28 -0
  193. package/dist/mascot/mascot.js.map +1 -0
  194. package/dist/mascot/mascots.generated.d.ts +284 -0
  195. package/dist/mascot/mascots.generated.js +287 -0
  196. package/dist/mascot/mascots.generated.js.map +1 -0
  197. package/dist/master-detail/master-detail.d.ts +30 -0
  198. package/dist/master-detail/master-detail.js +71 -0
  199. package/dist/master-detail/master-detail.js.map +1 -0
  200. package/dist/menu/account-menu.d.ts +44 -0
  201. package/dist/menu/account-menu.js +78 -0
  202. package/dist/menu/account-menu.js.map +1 -0
  203. package/dist/menu/context-menu.d.ts +31 -0
  204. package/dist/menu/context-menu.js +111 -0
  205. package/dist/menu/context-menu.js.map +1 -0
  206. package/dist/menu/dropdown-menu.d.ts +49 -0
  207. package/dist/menu/dropdown-menu.js +152 -0
  208. package/dist/menu/dropdown-menu.js.map +1 -0
  209. package/dist/menu/menu-styles.d.ts +8 -0
  210. package/dist/menu/menu-styles.js +6 -0
  211. package/dist/menu/menu-styles.js.map +1 -0
  212. package/dist/menu/menubar.d.ts +31 -0
  213. package/dist/menu/menubar.js +125 -0
  214. package/dist/menu/menubar.js.map +1 -0
  215. package/dist/modal/modal.d.ts +34 -0
  216. package/dist/modal/modal.js +58 -0
  217. package/dist/modal/modal.js.map +1 -0
  218. package/dist/notification-center/notification-center.d.ts +51 -0
  219. package/dist/notification-center/notification-center.js +244 -0
  220. package/dist/notification-center/notification-center.js.map +1 -0
  221. package/dist/otp-input/otp-input.d.ts +23 -0
  222. package/dist/otp-input/otp-input.js +61 -0
  223. package/dist/otp-input/otp-input.js.map +1 -0
  224. package/dist/overlay/overlay.d.ts +53 -0
  225. package/dist/overlay/overlay.js +103 -0
  226. package/dist/overlay/overlay.js.map +1 -0
  227. package/dist/page-header/page-header.d.ts +55 -0
  228. package/dist/page-header/page-header.js +114 -0
  229. package/dist/page-header/page-header.js.map +1 -0
  230. package/dist/page-header/record-headers.d.ts +51 -0
  231. package/dist/page-header/record-headers.js +134 -0
  232. package/dist/page-header/record-headers.js.map +1 -0
  233. package/dist/page-header/section-header.d.ts +21 -0
  234. package/dist/page-header/section-header.js +44 -0
  235. package/dist/page-header/section-header.js.map +1 -0
  236. package/dist/page-navigation/page-navigation.d.ts +59 -0
  237. package/dist/page-navigation/page-navigation.js +136 -0
  238. package/dist/page-navigation/page-navigation.js.map +1 -0
  239. package/dist/pagination/pagination.d.ts +28 -0
  240. package/dist/pagination/pagination.js +102 -0
  241. package/dist/pagination/pagination.js.map +1 -0
  242. package/dist/phone-input/phone-input.d.ts +34 -0
  243. package/dist/phone-input/phone-input.js +171 -0
  244. package/dist/phone-input/phone-input.js.map +1 -0
  245. package/dist/popover/popover.d.ts +23 -0
  246. package/dist/popover/popover.js +40 -0
  247. package/dist/popover/popover.js.map +1 -0
  248. package/dist/progress/progress.d.ts +21 -0
  249. package/dist/progress/progress.js +49 -0
  250. package/dist/progress/progress.js.map +1 -0
  251. package/dist/segmented-control/segmented-control.d.ts +32 -0
  252. package/dist/segmented-control/segmented-control.js +29 -0
  253. package/dist/segmented-control/segmented-control.js.map +1 -0
  254. package/dist/select/select.d.ts +48 -0
  255. package/dist/select/select.js +136 -0
  256. package/dist/select/select.js.map +1 -0
  257. package/dist/settings/permission-matrix.d.ts +29 -0
  258. package/dist/settings/permission-matrix.js +101 -0
  259. package/dist/settings/permission-matrix.js.map +1 -0
  260. package/dist/settings/settings-row.d.ts +32 -0
  261. package/dist/settings/settings-row.js +63 -0
  262. package/dist/settings/settings-row.js.map +1 -0
  263. package/dist/side-nav/side-nav.d.ts +36 -0
  264. package/dist/side-nav/side-nav.js +123 -0
  265. package/dist/side-nav/side-nav.js.map +1 -0
  266. package/dist/site-header/site-header.d.ts +32 -0
  267. package/dist/site-header/site-header.js +99 -0
  268. package/dist/site-header/site-header.js.map +1 -0
  269. package/dist/skeleton/skeleton.d.ts +16 -0
  270. package/dist/skeleton/skeleton.js +19 -0
  271. package/dist/skeleton/skeleton.js.map +1 -0
  272. package/dist/slider/slider.d.ts +15 -0
  273. package/dist/slider/slider.js +48 -0
  274. package/dist/slider/slider.js.map +1 -0
  275. package/dist/spinner/spinner.d.ts +15 -0
  276. package/dist/spinner/spinner.js +42 -0
  277. package/dist/spinner/spinner.js.map +1 -0
  278. package/dist/stepper/step-dots.d.ts +16 -0
  279. package/dist/stepper/step-dots.js +26 -0
  280. package/dist/stepper/step-dots.js.map +1 -0
  281. package/dist/stepper/stepper.d.ts +26 -0
  282. package/dist/stepper/stepper.js +113 -0
  283. package/dist/stepper/stepper.js.map +1 -0
  284. package/dist/tabs/tabs.d.ts +31 -0
  285. package/dist/tabs/tabs.js +66 -0
  286. package/dist/tabs/tabs.js.map +1 -0
  287. package/dist/templates/app-templates.d.ts +126 -0
  288. package/dist/templates/app-templates.js +153 -0
  289. package/dist/templates/app-templates.js.map +1 -0
  290. package/dist/templates/site-templates.d.ts +49 -0
  291. package/dist/templates/site-templates.js +110 -0
  292. package/dist/templates/site-templates.js.map +1 -0
  293. package/dist/toast/toast-store.d.ts +54 -0
  294. package/dist/toast/toast-store.js +49 -0
  295. package/dist/toast/toast-store.js.map +1 -0
  296. package/dist/toast/toaster.d.ts +15 -0
  297. package/dist/toast/toaster.js +124 -0
  298. package/dist/toast/toaster.js.map +1 -0
  299. package/dist/tooltip/tooltip.d.ts +29 -0
  300. package/dist/tooltip/tooltip.js +54 -0
  301. package/dist/tooltip/tooltip.js.map +1 -0
  302. package/package.json +88 -3
  303. package/styles.css +521 -0
  304. package/README.md +0 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-calendar.js","names":["RadixPopover","DEFAULT_CALENDAR_LABELS","n","LANE","HOUR","SLOT","itemColor","item","chipStyle","c","pending","alpha","timeText","isAllDay","StatusText","parts","labels","inRange","r","day","ordered","a","b","pointRect","x","y","useControlled","inner","setInner","useState","initial","value","v","onChange","GlyphButton","label","pressed","cx","Glyph","glyph","ItemChip","time","onOpen","className","style","Icon","DayRows","allDayItems","useMemo","showNumbers","items","ariaLabel","onGridKeyDown","weeks","bars","packRow","week","used","shown","lanes","hidden","col","height","minHeight","top","isToday","today","outside","month","selected","highlight","off","workDays","weekday","focusDay","onFocusDay","onCellPointerDown","onCellPointerEnter","onCellDoubleClick","toDate","dayLabel","locale","Bar","onOpenItem","onOpenDay","span","bar","slotRange","from","s","to","timeOf","HourGrid","scroller","useRef","drag","setDrag","key","days","startHour","slotAt","nowMin","now","minutesOf","i","placed","placeDay","sel","moved","onSelect","p","start","end","CalendarAgenda","labelsProp","rows","sortItems","touches","onSelectRange","weekdayName","list","isTyping","el","EventCalendar","nowProp","viewProp","anchorProp","asideOpenProp","view","setView","defaultView","onViewChange","anchor","setAnchor","onAnchorChange","asideOpen","setAsideOpen","defaultAsideOpen","onAsideOpenChange","wide","useMediaQuery","panelRoom","visibleDays","weekStartsOn","clock","setClock","tick","d","id","floating","setFloating","keySel","setKeySel","setFocusDay","moveFocus","root","gridDay","selection","select","range","actions","quickActions","openItem","renderItemPopover","up","cancel","go","next","changeView","onRootKeyDown","shortcuts","k","shiftAnchor","step","addDays","cell","dayRowHandlers","e","closeFloating","restoreFocus","target","titleDay","Heading","headingLevel","board","monthLanes","rect","showAside","aside","Button","SegmentedControl","toolbarEnd","loading","showHelp","o","PopoverContent","it","DropdownMenu","DropdownMenuTrigger","DropdownMenuContent","DropdownMenuLabel","rangeLabel","DropdownMenuItem"],"sources":["../../src/event-calendar/event-calendar.tsx"],"sourcesContent":["'use client';\n\nimport * as RadixPopover from '@radix-ui/react-popover';\nimport {\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type PointerEvent,\n type ReactNode,\n} from 'react';\nimport { cx } from '../lib/cx';\nimport { Glyph, type GlyphName } from '../lib/glyphs';\nimport { useMediaQuery } from '../lib/use-media-query';\nimport { Icon, type IconName } from '../icon/icon';\nimport { Button } from '../button/button';\nimport { SegmentedControl } from '../segmented-control/segmented-control';\nimport { PopoverContent } from '../popover/popover';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuTrigger,\n} from '../menu/dropdown-menu';\nimport {\n addDays,\n dayLabel,\n minutesOf,\n rangeLabel,\n shiftAnchor,\n timeOf,\n toDate,\n visibleDays,\n weekday,\n weekdayName,\n type CalendarView,\n type IsoDate,\n type Weekday,\n} from './dates';\nimport { isAllDay, packRow, placeDay, sortItems, touches, type LayoutItem, type PackedBar } from './layout';\n\nexport type { CalendarView, IsoDate, Weekday };\n\n/* ---------------- Types ---------------- */\n\nexport interface CalendarItem<M = unknown> extends LayoutItem {\n /** Category color 1–12 (`--kf-category-N`). Defaults to the brand color. */\n color?: number;\n icon?: IconName;\n /** `pending` is drawn with a dashed edge, in italics, and named \"Pending\". */\n status?: 'confirmed' | 'pending';\n /** Someone else's event shown only as busy time: neutral color and a lock. */\n busy?: boolean;\n location?: string;\n /** Product data, passed back untouched in callbacks. */\n meta?: M;\n}\n\n/** A selection: days (inclusive) and, from the hour grid, times. */\nexport interface CalendarRange {\n start: IsoDate;\n end: IsoDate;\n startTime?: string;\n endTime?: string;\n}\n\nexport interface CalendarQuickAction {\n key: string;\n label: string;\n icon?: IconName;\n /** Grey second line (\"09:00 – 10:00\", \"Opens the form with this day\"). */\n hint?: string;\n onSelect: () => void;\n}\n\nexport interface EventCalendarLabels {\n today: string;\n previous: string;\n next: string;\n views: Record<CalendarView, string>;\n viewsLabel: string;\n allDay: string;\n pending: string;\n busy: string;\n /** Visible text of the \"+N more\" button. */\n more: (count: number) => string;\n togglePanel: string;\n /** Accessible name of the day grid. */\n grid: string;\n help: string;\n helpTouch: string;\n empty: string;\n todaySuffix: string;\n}\n\nexport const DEFAULT_CALENDAR_LABELS: EventCalendarLabels = {\n today: 'Today',\n previous: 'Previous',\n next: 'Next',\n views: { day: 'Day', week: 'Week', month: 'Month' },\n viewsLabel: 'Calendar view',\n allDay: 'All day',\n pending: 'Pending',\n busy: 'Busy',\n more: (n) => `+${n} more`,\n togglePanel: 'Side panel',\n grid: 'Days',\n help: 'Double-click a day or drag across days to add something. Shortcuts: T today, D / W / M views, ← → move.',\n helpTouch: 'Double-tap a day to add something.',\n empty: 'Nothing on these dates',\n todaySuffix: 'today',\n};\n\n/* ---------------- Shared helpers ---------------- */\n\nconst LANE = 22;\nconst HOUR = 44;\nconst SLOT = 30;\n\nexport function itemColor(item: Pick<CalendarItem, 'busy' | 'color'>) {\n if (item.busy) return 'var(--kf-fg-muted)';\n return item.color ? `var(--kf-category-${item.color})` : 'var(--kf-primary)';\n}\n\nfunction chipStyle(item: CalendarItem, alpha = 14): CSSProperties {\n const c = itemColor(item);\n const pending = item.status === 'pending';\n return {\n background: `color-mix(in srgb, ${c} ${pending ? Math.round(alpha / 2) : alpha}%, var(--kf-surface))`,\n borderInlineStart: `3px ${pending ? 'dashed' : 'solid'} ${c}`,\n };\n}\n\nconst timeText = (item: CalendarItem) =>\n !isAllDay(item) && item.startTime ? `${item.startTime}${item.endTime ? ` – ${item.endTime}` : ''}` : '';\n\n/** Screen-reader-only status after the visible text (keeps label-in-name). */\nfunction StatusText({ item, labels }: { item: CalendarItem; labels: EventCalendarLabels }) {\n const parts = [item.status === 'pending' && labels.pending, item.busy && labels.busy].filter(Boolean);\n return parts.length ? <span className=\"sr-only\">, {parts.join(', ')}</span> : null;\n}\n\nconst inRange = (day: IsoDate, r?: CalendarRange | null) => !!r && day >= r.start && day <= r.end;\nconst ordered = (a: IsoDate, b: IsoDate) => (a <= b ? { start: a, end: b } : { start: b, end: a });\nconst pointRect = (x: number, y: number) => new DOMRect(x, y, 0, 0);\n\nfunction useControlled<T>(value: T | undefined, initial: T, onChange?: (v: T) => void) {\n const [inner, setInner] = useState(initial);\n const current = value ?? inner;\n const set = (v: T) => {\n if (value === undefined) setInner(v);\n onChange?.(v);\n };\n return [current, set] as const;\n}\n\nfunction GlyphButton({\n glyph,\n label,\n pressed,\n onClick,\n}: {\n glyph: GlyphName;\n label: string;\n pressed?: boolean;\n onClick: () => void;\n}) {\n return (\n <button\n type=\"button\"\n aria-label={label}\n title={label}\n aria-pressed={pressed}\n onClick={onClick}\n className={cx(\n 'inline-grid size-9 shrink-0 cursor-pointer place-items-center rounded-full border-0 text-fg transition-colors duration-150 pointer-coarse:size-11',\n 'focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-focus',\n pressed ? 'bg-surface-muted' : 'bg-transparent hover:bg-surface-muted',\n )}\n >\n <Glyph name={glyph} size={18} />\n </button>\n );\n}\n\n/** One item as a compact bar or row. */\nfunction ItemChip({\n item,\n labels,\n className,\n style,\n onOpen,\n}: {\n item: CalendarItem;\n labels: EventCalendarLabels;\n className?: string;\n style?: CSSProperties;\n onOpen: (item: CalendarItem, el: HTMLElement) => void;\n}) {\n const time = !isAllDay(item) ? item.startTime : undefined;\n return (\n <button\n type=\"button\"\n title={[item.title, timeText(item), item.status === 'pending' && labels.pending].filter(Boolean).join(' · ')}\n onPointerDown={(e) => e.stopPropagation()}\n onDoubleClick={(e) => e.stopPropagation()}\n onClick={(e) => onOpen(item, e.currentTarget)}\n className={cx(\n 'flex h-[19px] min-w-0 cursor-pointer items-center gap-1 overflow-hidden rounded-xs border-0 px-1.5 text-left font-sans text-[11px] leading-none font-medium text-fg',\n 'focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-focus',\n item.status === 'pending' && 'italic',\n className,\n )}\n style={{ ...chipStyle(item), ...style }}\n >\n {(item.busy || item.icon) && (\n <Icon\n name={item.busy ? 'lock' : item.icon!}\n size={12}\n className=\"shrink-0\"\n style={{ color: itemColor(item) }}\n />\n )}\n {time && <span className=\"shrink-0 tabular-nums\">{time} </span>}\n <span className=\"truncate\">{item.title}</span>\n <StatusText item={item} labels={labels} />\n </button>\n );\n}\n\n/* ---------------- Day rows (month weeks and the all-day lane) ---------------- */\n\ninterface DayRowsProps {\n weeks: IsoDate[][];\n items: CalendarItem[];\n lanes: number;\n /** Top offset of the first lane (room for the day number in month view). */\n top: number;\n minHeight: number;\n showNumbers: boolean;\n month?: string;\n today: IsoDate;\n workDays: readonly Weekday[];\n highlight: CalendarRange | null;\n focusDay: IsoDate;\n locale: string;\n labels: EventCalendarLabels;\n onCellPointerDown: (day: IsoDate, e: PointerEvent<HTMLElement>) => void;\n onCellPointerEnter: (day: IsoDate) => void;\n onCellDoubleClick: (day: IsoDate, e: React.MouseEvent<HTMLElement>) => void;\n onGridKeyDown: (e: KeyboardEvent<HTMLElement>) => void;\n onFocusDay: (day: IsoDate) => void;\n onOpenItem: (item: CalendarItem, el: HTMLElement) => void;\n onOpenDay: (day: IsoDate, el: HTMLElement) => void;\n ariaLabel: string;\n}\n\nfunction DayRows({\n weeks,\n items,\n lanes,\n top,\n minHeight,\n showNumbers,\n month,\n today,\n workDays,\n highlight,\n focusDay,\n locale,\n labels,\n onCellPointerDown,\n onCellPointerEnter,\n onCellDoubleClick,\n onGridKeyDown,\n onFocusDay,\n onOpenItem,\n onOpenDay,\n ariaLabel,\n}: DayRowsProps) {\n // Month shows every item; the all-day lane of week and day views only the all-day ones.\n const allDayItems = useMemo(() => (showNumbers ? items : items.filter(isAllDay)), [items, showNumbers]);\n return (\n <div role=\"grid\" aria-label={ariaLabel} onKeyDown={onGridKeyDown} className=\"grid\">\n {weeks.map((week) => {\n const bars = packRow(allDayItems, week);\n const used = Math.max(0, ...bars.map((b) => b.lane + 1));\n const shown = Math.min(used, lanes);\n const hidden = week.map((_, col) => bars.filter((b) => b.lane >= lanes && b.from <= col && b.to >= col).length);\n const height = Math.max(minHeight, top + shown * LANE + (hidden.some(Boolean) ? LANE : 0) + 4);\n return (\n <div\n key={week[0]}\n role=\"row\"\n className=\"grid border-b border-border last:border-b-0\"\n style={{ gridTemplateColumns: `repeat(${week.length}, minmax(0, 1fr))` }}\n >\n {week.map((day, col) => {\n const isToday = day === today;\n const outside = month !== undefined && day.slice(0, 7) !== month;\n const selected = inRange(day, highlight);\n const off = !workDays.includes(weekday(day));\n return (\n <div\n key={day}\n role=\"gridcell\"\n data-day={day}\n tabIndex={day === focusDay ? 0 : -1}\n aria-selected={selected}\n aria-current={isToday ? 'date' : undefined}\n onFocus={() => onFocusDay(day)}\n onPointerDown={(e) => onCellPointerDown(day, e)}\n onPointerEnter={() => onCellPointerEnter(day)}\n onDoubleClick={(e) => onCellDoubleClick(day, e)}\n className={cx(\n 'relative border-r border-border last:border-r-0 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-focus',\n selected ? 'bg-primary/12' : off ? 'bg-surface-muted/50' : 'bg-transparent',\n )}\n style={{ height }}\n >\n {showNumbers ? (\n <span\n className={cx(\n 'absolute top-1 right-1 grid h-6 min-w-6 place-items-center rounded-full px-1 font-sans text-xs font-semibold tabular-nums',\n isToday ? 'bg-primary text-on-primary' : outside ? 'text-fg-muted' : 'text-fg',\n )}\n >\n {toDate(day).getUTCDate()}\n <span className=\"sr-only\">\n {' '}\n – {dayLabel(day, locale)}\n {isToday && `, ${labels.todaySuffix}`}\n </span>\n </span>\n ) : (\n <span className=\"sr-only\">\n {dayLabel(day, locale)}\n {isToday && `, ${labels.todaySuffix}`}\n </span>\n )}\n {bars\n .filter((b) => b.from === col && b.lane < lanes)\n .map((b) => (\n <Bar\n key={b.item.id}\n bar={b as PackedBar<CalendarItem>}\n top={top}\n labels={labels}\n onOpen={onOpenItem}\n />\n ))}\n {hidden[col]! > 0 && (\n <button\n type=\"button\"\n aria-label={`${labels.more(hidden[col]!)}, ${dayLabel(day, locale)}`}\n onPointerDown={(e) => e.stopPropagation()}\n onDoubleClick={(e) => e.stopPropagation()}\n onClick={(e) => onOpenDay(day, e.currentTarget)}\n className=\"absolute right-0.5 left-0.5 z-[1] h-[19px] cursor-pointer rounded-xs border-0 bg-transparent px-1.5 text-left font-sans text-[11px] font-semibold text-link hover:bg-surface-muted focus-visible:outline-2 focus-visible:outline-focus\"\n style={{ top: top + lanes * LANE }}\n >\n {labels.more(hidden[col]!)}\n </button>\n )}\n </div>\n );\n })}\n </div>\n );\n })}\n </div>\n );\n}\n\nfunction Bar({\n bar,\n top,\n labels,\n onOpen,\n}: {\n bar: PackedBar<CalendarItem>;\n top: number;\n labels: EventCalendarLabels;\n onOpen: (item: CalendarItem, el: HTMLElement) => void;\n}) {\n const span = bar.to - bar.from + 1;\n return (\n <ItemChip\n item={bar.item}\n labels={labels}\n onOpen={onOpen}\n className={cx(\n 'absolute z-[1]',\n bar.continuesBefore ? 'rounded-l-none' : '',\n bar.continuesAfter ? 'rounded-r-none' : '',\n )}\n style={{\n top: top + bar.lane * LANE,\n left: bar.continuesBefore ? 0 : 2,\n width: `calc(${span * 100}% - ${(bar.continuesBefore ? 0 : 2) + (bar.continuesAfter ? 0 : 2)}px)`,\n }}\n />\n );\n}\n\n/* ---------------- Hour grid (week and day) ---------------- */\n\ninterface SlotDrag {\n day: IsoDate;\n a: number;\n b: number;\n}\n\nfunction slotRange(s: SlotDrag): CalendarRange {\n const from = Math.min(s.a, s.b) * SLOT;\n const to = (Math.max(s.a, s.b) + 1) * SLOT;\n return { start: s.day, end: s.day, startTime: timeOf(from), endTime: timeOf(to) };\n}\n\nfunction HourGrid({\n days,\n items,\n today,\n now,\n workDays,\n highlight,\n startHour,\n labels,\n onOpenItem,\n onSelect,\n}: {\n days: IsoDate[];\n items: CalendarItem[];\n today: IsoDate;\n now?: string;\n workDays: readonly Weekday[];\n highlight: CalendarRange | null;\n startHour: number;\n labels: EventCalendarLabels;\n onOpenItem: (item: CalendarItem, el: HTMLElement) => void;\n onSelect: (range: CalendarRange, rect: DOMRect) => void;\n}) {\n const scroller = useRef<HTMLDivElement>(null);\n const [drag, setDrag] = useState<SlotDrag | null>(null);\n const key = days.join();\n\n useEffect(() => {\n if (scroller.current) scroller.current.scrollTop = startHour * HOUR - 8;\n }, [days.length, startHour]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const slotAt = (e: PointerEvent<HTMLElement> | React.MouseEvent<HTMLElement>) => {\n const r = e.currentTarget.getBoundingClientRect();\n return Math.min(47, Math.max(0, Math.floor((e.clientY - r.top) / (HOUR / 2))));\n };\n\n const nowMin = now ? minutesOf(now) : null;\n const shown = drag ? slotRange(drag) : highlight?.startTime ? highlight : null;\n\n return (\n <div ref={scroller} className=\"max-h-[560px] overflow-y-auto [scrollbar-gutter:stable]\" key={key}>\n <div className=\"relative flex\" style={{ height: 24 * HOUR }}>\n <div aria-hidden=\"true\" className=\"relative w-14 shrink-0\">\n {Array.from({ length: 23 }, (_, i) => (\n <span\n key={i}\n className=\"absolute right-2 -translate-y-1/2 font-sans text-[11px] text-fg-muted tabular-nums\"\n style={{ top: (i + 1) * HOUR }}\n >\n {timeOf((i + 1) * 60)}\n </span>\n ))}\n {nowMin !== null && days.includes(today) && (\n <span\n className=\"absolute right-1 z-[2] -translate-y-1/2 rounded-xs bg-danger-solid px-1 font-sans text-[10px] font-semibold text-on-danger-solid tabular-nums\"\n style={{ top: (nowMin / 60) * HOUR }}\n >\n {now}\n </span>\n )}\n </div>\n <div className=\"grid flex-1\" style={{ gridTemplateColumns: `repeat(${days.length}, minmax(0, 1fr))` }}>\n {days.map((day) => {\n const placed = placeDay(items, day);\n const off = !workDays.includes(weekday(day));\n const sel = shown && shown.start === day ? shown : null;\n return (\n <div\n key={day}\n data-testid={`hours-${day}`}\n className={cx(\n 'relative border-l border-border select-none',\n day === today ? 'bg-primary/5' : off ? 'bg-surface-muted/50' : 'bg-transparent',\n )}\n style={{\n backgroundImage: `repeating-linear-gradient(to bottom, transparent 0 ${HOUR - 1}px, var(--kf-border) ${HOUR - 1}px ${HOUR}px)`,\n }}\n onPointerDown={(e) => {\n if (e.button !== 0 || e.pointerType === 'touch') return;\n e.currentTarget.setPointerCapture(e.pointerId);\n const s = slotAt(e);\n setDrag({ day, a: s, b: s });\n }}\n onPointerMove={(e) => {\n if (drag?.day === day) setDrag({ ...drag, b: slotAt(e) });\n }}\n onPointerUp={(e) => {\n if (!drag) return;\n const moved = drag.a !== drag.b;\n setDrag(null);\n if (moved) onSelect(slotRange(drag), pointRect(e.clientX, e.clientY));\n }}\n onPointerCancel={() => setDrag(null)}\n onDoubleClick={(e) => {\n const s = slotAt(e) - (slotAt(e) % 2);\n setDrag(null);\n onSelect(slotRange({ day, a: s, b: s + 1 }), pointRect(e.clientX, e.clientY));\n }}\n >\n {sel && (\n <div\n aria-hidden=\"true\"\n className=\"absolute inset-x-0.5 z-[1] rounded-sm bg-primary/20 px-1.5 py-0.5 font-sans text-[11px] font-semibold text-fg ring-1 ring-primary tabular-nums\"\n style={{\n top: (minutesOf(sel.startTime!) / 60) * HOUR,\n height: ((minutesOf(sel.endTime!) - minutesOf(sel.startTime!)) / 60) * HOUR,\n }}\n >\n {sel.startTime} – {sel.endTime}\n </div>\n )}\n {placed.map((p) => {\n const height = Math.max(((p.to - p.from) / 60) * HOUR - 2, 18);\n const start = timeOf(p.from);\n const end = timeOf(p.to);\n return (\n <button\n key={p.item.id}\n type=\"button\"\n onPointerDown={(e) => e.stopPropagation()}\n onDoubleClick={(e) => e.stopPropagation()}\n onClick={(e) => onOpenItem(p.item, e.currentTarget)}\n className={cx(\n 'absolute z-[1] flex cursor-pointer flex-col items-start overflow-hidden rounded-md border-0 px-1.5 py-0.5 text-left font-sans text-[11px] leading-tight text-fg shadow-sm',\n 'focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-focus',\n p.item.status === 'pending' && 'italic',\n )}\n style={{\n ...chipStyle(p.item, 22),\n top: (p.from / 60) * HOUR + 1,\n height,\n left: `calc(${(p.column / p.columns) * 100}% + 2px)`,\n width: `calc(${100 / p.columns}% - 4px)`,\n }}\n >\n <span className={height >= 34 ? 'max-w-full truncate tabular-nums text-fg-muted' : 'sr-only'}>\n {start} – {end}{' '}\n </span>\n <span className=\"flex max-w-full items-center gap-1 font-semibold\">\n {p.item.busy && <Icon name=\"lock\" size={11} className=\"shrink-0\" />}\n <span className=\"truncate\">{p.item.title}</span>\n <StatusText item={p.item} labels={labels} />\n </span>\n {height >= 52 && p.item.location && (\n <span className=\"truncate text-fg-muted\"> {p.item.location}</span>\n )}\n </button>\n );\n })}\n {nowMin !== null && day === today && (\n <div\n aria-hidden=\"true\"\n className=\"absolute inset-x-0 z-[2] h-px bg-danger-solid\"\n style={{ top: (nowMin / 60) * HOUR }}\n >\n <span className=\"absolute -top-[3px] -left-[4px] size-[7px] rounded-full bg-danger-solid\" />\n </div>\n )}\n </div>\n );\n })}\n </div>\n </div>\n </div>\n );\n}\n\n/* ---------------- Agenda (small screens, \"Today\" card) ---------------- */\n\nexport interface CalendarAgendaProps {\n days: IsoDate[];\n today: IsoDate;\n items: CalendarItem[];\n locale?: string;\n labels?: Partial<EventCalendarLabels>;\n onOpenItem?: (item: CalendarItem, el: HTMLElement) => void;\n /** Double-tap (or double-click) on a day. */\n onSelectRange?: (range: CalendarRange, rect: DOMRect) => void;\n /** Days without items are hidden (except today). */\n className?: string;\n}\n\n/**\n * The calendar as a list of days that have something (today always shows). `EventCalendar` uses it below 768 px; on\n * its own it is the read-only \"Today\" card of a dashboard (`days={[today]}`).\n */\nexport function CalendarAgenda({\n days,\n today,\n items,\n locale = 'en-US',\n labels: labelsProp,\n onOpenItem,\n onSelectRange,\n className,\n}: CalendarAgendaProps) {\n const labels = { ...DEFAULT_CALENDAR_LABELS, ...labelsProp };\n const rows = days\n .map((day) => ({ day, list: sortItems(items.filter((i) => touches(i, day, day))) }))\n .filter((r) => r.list.length > 0 || r.day === today);\n if (rows.length === 0)\n return <p className={cx('m-0 p-4 font-sans text-sm text-fg-muted', className)}>{labels.empty}</p>;\n return (\n <ul className={cx('m-0 grid list-none gap-0 p-0 font-sans', className)}>\n {rows.map(({ day, list }) => (\n <li\n key={day}\n className=\"flex gap-3 border-b border-border px-3 py-2.5 last:border-b-0\"\n onDoubleClick={(e) => onSelectRange?.({ start: day, end: day }, pointRect(e.clientX, e.clientY))}\n >\n <div className=\"grid w-10 shrink-0 content-start justify-items-center gap-0.5 pt-0.5\">\n <span className=\"text-[11px] font-semibold text-fg-muted uppercase\">{weekdayName(day, locale)}</span>\n <span\n className={cx(\n 'grid size-7 place-items-center rounded-full text-sm font-bold tabular-nums',\n day === today ? 'bg-primary text-on-primary' : 'text-fg',\n )}\n >\n {toDate(day).getUTCDate()}\n </span>\n </div>\n <div className=\"grid min-w-0 flex-1 content-start gap-1\">\n {list.length === 0 ? (\n <span className=\"py-1 text-sm text-fg-muted\">{labels.empty}</span>\n ) : (\n list.map((item) => (\n <button\n key={item.id}\n type=\"button\"\n onClick={(e) => onOpenItem?.(item, e.currentTarget)}\n className={cx(\n 'flex min-h-9 w-full cursor-pointer items-center gap-2 rounded-sm border-0 px-2 py-1 text-left text-sm text-fg pointer-coarse:min-h-11',\n 'focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-focus',\n item.status === 'pending' && 'italic',\n )}\n style={chipStyle(item)}\n >\n {(item.busy || item.icon) && (\n <Icon\n name={item.busy ? 'lock' : item.icon!}\n size={14}\n className=\"shrink-0\"\n style={{ color: itemColor(item) }}\n />\n )}\n {!isAllDay(item) && item.startTime && (\n <span className=\"shrink-0 text-xs tabular-nums\">{item.startTime} </span>\n )}\n <span className=\"min-w-0 flex-1 truncate font-medium\">{item.title}</span>\n {item.status === 'pending' && (\n <span className=\"shrink-0 text-xs text-fg-muted\">, {labels.pending}</span>\n )}\n {item.busy && <span className=\"sr-only\">, {labels.busy}</span>}\n </button>\n ))\n )}\n </div>\n </li>\n ))}\n </ul>\n );\n}\n\n/* ---------------- EventCalendar ---------------- */\n\nexport interface EventCalendarProps {\n items: CalendarItem[];\n /** Today in the organization's time zone (from the server). */\n today: IsoDate;\n /**\n * Current time `HH:mm` for the time line. Omit it to use the browser's clock (set after mounting, refreshed every\n * minute).\n */\n now?: string;\n view?: CalendarView;\n defaultView?: CalendarView;\n onViewChange?: (view: CalendarView) => void;\n /** The day the view is built around. Defaults to `today`. */\n anchor?: IsoDate;\n onAnchorChange?: (anchor: IsoDate) => void;\n /** Working weekdays (others are shaded). Defaults to Monday–Friday. */\n workDays?: readonly Weekday[];\n /** 1 = Monday (default) … 7 = Sunday. */\n weekStartsOn?: Weekday;\n /** BCP 47 locale for day and month names. Defaults to `en-US`. */\n locale?: string;\n labels?: Partial<EventCalendarLabels>;\n /** A range kept highlighted (e.g. while the product's create drawer is open). */\n selection?: CalendarRange | null;\n /** Keeps the current days on screen, dimmed, while the next range loads. */\n loading?: boolean;\n /** Called when the user selects days or times (drag, double-click, `Enter` on a day). */\n onSelectRange?: (range: CalendarRange) => void;\n /** Actions for a selection, shown as a menu next to it. Return `[]` to show nothing. */\n quickActions?: (range: CalendarRange) => CalendarQuickAction[];\n onOpenItem?: (item: CalendarItem) => void;\n /** Content of the popover opened next to an item (usually `EventDetails`). */\n renderItemPopover?: (item: CalendarItem, close: () => void) => ReactNode;\n /** Extra toolbar actions (a \"+\" button, \"Ask AI\"). */\n toolbarEnd?: ReactNode;\n /** Side panel (mini calendar, upcoming, filters); shown at 1024 px and wider. */\n aside?: ReactNode;\n asideOpen?: boolean;\n defaultAsideOpen?: boolean;\n onAsideOpenChange?: (open: boolean) => void;\n /** First hour shown in week and day views. Default 8. */\n startHour?: number;\n /** Lanes of bars per day in month view before \"+N more\". Default 3. */\n monthLanes?: number;\n /** Keyboard shortcuts while focus is inside the calendar. Default `true`. */\n shortcuts?: boolean;\n showHelp?: boolean;\n headingLevel?: 2 | 3;\n className?: string;\n}\n\ntype Floating =\n | { type: 'item'; item: CalendarItem; rect: DOMRect; returnTo: HTMLElement | null }\n | { type: 'day'; day: IsoDate; rect: DOMRect; returnTo: HTMLElement | null }\n | { type: 'menu'; range: CalendarRange; actions: CalendarQuickAction[]; rect: DOMRect; returnTo: HTMLElement | null };\n\nconst isTyping = (el: EventTarget | null) =>\n el instanceof HTMLElement &&\n (el.isContentEditable ||\n ['INPUT', 'TEXTAREA', 'SELECT'].includes(el.tagName) ||\n !!el.closest('[role=\"radiogroup\"],[role=\"menu\"]'));\n\n/**\n * Day, week and month calendar (ADR-0016). Controlled and presentational: the product loads `items` for the visible\n * range, expands recurring events, and decides what the quick actions and the item popover do.\n */\nexport function EventCalendar({\n items,\n today,\n now: nowProp,\n view: viewProp,\n defaultView = 'week',\n onViewChange,\n anchor: anchorProp,\n onAnchorChange,\n workDays = [1, 2, 3, 4, 5],\n weekStartsOn = 1,\n locale = 'en-US',\n labels: labelsProp,\n selection = null,\n loading = false,\n onSelectRange,\n quickActions,\n onOpenItem,\n renderItemPopover,\n toolbarEnd,\n aside,\n asideOpen: asideOpenProp,\n defaultAsideOpen = true,\n onAsideOpenChange,\n startHour = 8,\n monthLanes = 3,\n shortcuts = true,\n showHelp = true,\n headingLevel = 2,\n className,\n}: EventCalendarProps) {\n const labels = {\n ...DEFAULT_CALENDAR_LABELS,\n ...labelsProp,\n views: { ...DEFAULT_CALENDAR_LABELS.views, ...labelsProp?.views },\n };\n const [view, setView] = useControlled(viewProp, defaultView, onViewChange);\n const [anchor, setAnchor] = useControlled(anchorProp, today, onAnchorChange);\n const [asideOpen, setAsideOpen] = useControlled(asideOpenProp, defaultAsideOpen, onAsideOpenChange);\n const wide = useMediaQuery('(min-width: 48rem)');\n const panelRoom = useMediaQuery('(min-width: 64rem)');\n const days = visibleDays(view, anchor, weekStartsOn);\n const month = view === 'month' ? anchor.slice(0, 7) : undefined;\n\n // Browser clock when the product does not pass `now` (after mount: no hydration mismatch).\n const [clock, setClock] = useState<string>();\n useEffect(() => {\n if (nowProp !== undefined) return;\n const tick = () => {\n const d = new Date();\n setClock(timeOf(d.getHours() * 60 + d.getMinutes()));\n };\n tick();\n const id = window.setInterval(tick, 60_000);\n return () => window.clearInterval(id);\n }, [nowProp]);\n const now = nowProp ?? clock;\n\n const [floating, setFloating] = useState<Floating | null>(null);\n const [drag, setDrag] = useState<{ start: IsoDate; end: IsoDate } | null>(null);\n const [keySel, setKeySel] = useState<{ start: IsoDate; end: IsoDate } | null>(null);\n const [focusDay, setFocusDay] = useState<IsoDate>(anchor);\n const moveFocus = useRef(false);\n const root = useRef<HTMLDivElement>(null);\n const gridDay = days.includes(focusDay) ? focusDay : days.includes(anchor) ? anchor : days[0]!;\n\n useEffect(() => {\n if (!moveFocus.current) return;\n moveFocus.current = false;\n root.current?.querySelector<HTMLElement>(`[role=\"gridcell\"][data-day=\"${gridDay}\"]`)?.focus();\n });\n\n const highlight: CalendarRange | null =\n (drag && ordered(drag.start, drag.end)) ||\n (keySel && ordered(keySel.start, keySel.end)) ||\n (floating?.type === 'menu' ? floating.range : null) ||\n selection;\n\n const select = (range: CalendarRange, rect: DOMRect, returnTo: HTMLElement | null) => {\n onSelectRange?.(range);\n const actions = quickActions?.(range) ?? [];\n if (actions.length) setFloating({ type: 'menu', range, actions, rect, returnTo });\n };\n\n const openItem = (item: CalendarItem, el: HTMLElement) => {\n onOpenItem?.(item);\n if (renderItemPopover) setFloating({ type: 'item', item, rect: el.getBoundingClientRect(), returnTo: el });\n };\n\n // Drag across days: finish on pointer up anywhere; cancel when the window loses focus.\n useEffect(() => {\n if (!drag) return;\n const up = (e: globalThis.PointerEvent) => {\n setDrag(null);\n if (drag.start !== drag.end) select(ordered(drag.start, drag.end), pointRect(e.clientX, e.clientY), null);\n };\n const cancel = () => setDrag(null);\n window.addEventListener('pointerup', up);\n window.addEventListener('blur', cancel);\n return () => {\n window.removeEventListener('pointerup', up);\n window.removeEventListener('blur', cancel);\n };\n });\n\n const go = (next: IsoDate) => setAnchor(next);\n const changeView = (v: CalendarView) => setView(v);\n\n const onRootKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (!shortcuts || e.defaultPrevented || e.altKey || e.ctrlKey || e.metaKey || floating || isTyping(e.target))\n return;\n const k = e.key.toLowerCase();\n if (k === 't') go(today);\n else if (k === 'd') changeView('day');\n else if (k === 'w') changeView('week');\n else if (k === 'm') changeView('month');\n else if (e.key === 'ArrowLeft') go(shiftAnchor(view, anchor, -1));\n else if (e.key === 'ArrowRight') go(shiftAnchor(view, anchor, 1));\n else return;\n e.preventDefault();\n };\n\n const onGridKeyDown = (e: KeyboardEvent<HTMLElement>) => {\n if (e.target instanceof HTMLElement && e.target.getAttribute('role') !== 'gridcell') return;\n const step: Record<string, number> = { ArrowLeft: -1, ArrowRight: 1 };\n if (view === 'month') Object.assign(step, { ArrowUp: -7, ArrowDown: 7 });\n if (e.key in step) {\n e.preventDefault();\n e.stopPropagation();\n const next = addDays(gridDay, step[e.key]!);\n setKeySel(e.shiftKey ? { start: keySel?.start ?? gridDay, end: next } : null);\n if (!days.includes(next)) go(view === 'month' ? next : shiftAnchor(view, anchor, Math.sign(step[e.key]!)));\n moveFocus.current = true;\n setFocusDay(next);\n } else if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n const cell = e.target as HTMLElement;\n select(\n keySel ? ordered(keySel.start, keySel.end) : { start: gridDay, end: gridDay },\n cell.getBoundingClientRect(),\n cell,\n );\n setKeySel(null);\n } else if (e.key === 'Escape' && keySel) {\n setKeySel(null);\n }\n };\n\n const dayRowHandlers = {\n onCellPointerDown: (day: IsoDate, e: PointerEvent<HTMLElement>) => {\n if (e.button !== 0 || e.pointerType === 'touch') return;\n setKeySel(null);\n setDrag({ start: day, end: day });\n },\n onCellPointerEnter: (day: IsoDate) => {\n if (drag && drag.end !== day) setDrag({ ...drag, end: day });\n },\n onCellDoubleClick: (day: IsoDate, e: React.MouseEvent<HTMLElement>) => {\n setDrag(null);\n select({ start: day, end: day }, pointRect(e.clientX, e.clientY), e.currentTarget);\n },\n onFocusDay: (day: IsoDate) => setFocusDay(day),\n onOpenItem: openItem,\n onOpenDay: (day: IsoDate, el: HTMLElement) =>\n setFloating({ type: 'day', day, rect: el.getBoundingClientRect(), returnTo: el }),\n };\n\n const closeFloating = () => setFloating(null);\n const restoreFocus = (e: Event) => {\n e.preventDefault();\n const target = floating?.returnTo;\n if (target?.isConnected) target.focus();\n };\n\n /* Title: \"November 2026\"; the week takes its middle day's month. */\n const titleDay = view === 'week' ? days[3]! : anchor;\n const parts = new Intl.DateTimeFormat(locale, { timeZone: 'UTC', month: 'long', year: 'numeric' }).formatToParts(\n toDate(titleDay),\n );\n const Heading = `h${headingLevel}` as 'h2';\n\n const board = !wide ? (\n <CalendarAgenda\n days={days}\n today={today}\n items={items}\n locale={locale}\n labels={labels}\n onOpenItem={openItem}\n onSelectRange={(r, rect) => select(r, rect, null)}\n />\n ) : view === 'month' ? (\n <div>\n <div aria-hidden=\"true\" className=\"grid grid-cols-7 border-b border-border\">\n {days.slice(0, 7).map((d) => (\n <span key={d} className=\"px-2 py-1.5 text-right font-sans text-xs font-semibold text-fg-muted\">\n {weekdayName(d, locale)}\n </span>\n ))}\n </div>\n <DayRows\n weeks={Array.from({ length: 6 }, (_, i) => days.slice(i * 7, i * 7 + 7))}\n items={items}\n lanes={monthLanes}\n top={30}\n minHeight={112}\n showNumbers\n month={month}\n today={today}\n workDays={workDays}\n highlight={highlight}\n focusDay={gridDay}\n locale={locale}\n labels={labels}\n onGridKeyDown={onGridKeyDown}\n ariaLabel={labels.grid}\n {...dayRowHandlers}\n />\n </div>\n ) : (\n <div>\n <div className=\"flex border-b border-border [scrollbar-gutter:stable] overflow-hidden\">\n <div className=\"w-14 shrink-0\" />\n <div\n aria-hidden=\"true\"\n className=\"grid flex-1\"\n style={{ gridTemplateColumns: `repeat(${days.length}, minmax(0, 1fr))` }}\n >\n {days.map((d) =>\n view === 'day' ? (\n <span\n key={d}\n className={cx('px-2 py-2 font-sans text-sm font-semibold', d === today ? 'text-primary' : 'text-fg')}\n >\n {dayLabel(d, locale)}\n </span>\n ) : (\n <span\n key={d}\n className=\"flex items-center justify-center gap-1.5 py-2 font-sans text-xs font-semibold text-fg-muted\"\n >\n {weekdayName(d, locale)}\n <span\n className={cx(\n 'grid size-7 place-items-center rounded-full text-sm tabular-nums',\n d === today ? 'bg-primary text-on-primary' : 'text-fg',\n )}\n >\n {toDate(d).getUTCDate()}\n </span>\n </span>\n ),\n )}\n </div>\n </div>\n <div className=\"flex border-b border-border [scrollbar-gutter:stable] overflow-hidden\">\n <span className=\"w-14 shrink-0 pt-1.5 pr-2 text-right font-sans text-[11px] text-fg-muted\">\n {labels.allDay}\n </span>\n <div className=\"flex-1\">\n <DayRows\n weeks={[days]}\n items={items}\n lanes={view === 'day' ? 8 : 4}\n top={4}\n minHeight={32}\n showNumbers={false}\n today={today}\n workDays={workDays}\n highlight={highlight?.startTime ? null : highlight}\n focusDay={gridDay}\n locale={locale}\n labels={labels}\n onGridKeyDown={onGridKeyDown}\n ariaLabel={`${labels.grid}, ${labels.allDay}`}\n {...dayRowHandlers}\n />\n </div>\n </div>\n <HourGrid\n days={days}\n items={items}\n today={today}\n now={now}\n workDays={workDays}\n highlight={highlight}\n startHour={startHour}\n labels={labels}\n onOpenItem={openItem}\n onSelect={(r, rect) => select(r, rect, null)}\n />\n </div>\n );\n\n const showAside = !!aside && asideOpen && panelRoom;\n\n return (\n <div\n ref={root}\n onKeyDown={onRootKeyDown}\n className={cx('grid gap-4 font-sans', showAside && 'lg:grid-cols-[minmax(0,1fr)_17.5rem]', className)}\n >\n <div className=\"min-w-0 overflow-hidden rounded-lg border border-border bg-surface\">\n <div className=\"flex flex-wrap items-center gap-2 border-b border-border px-3 py-2.5\">\n <Heading className=\"m-0 mr-auto font-display text-lg font-bold text-fg capitalize\">\n {parts.map((p, i) =>\n p.type === 'year' ? (\n <span key={i} className=\"font-normal text-fg-muted\">\n {p.value}\n </span>\n ) : (\n p.value\n ),\n )}\n </Heading>\n <div className=\"flex items-center gap-1\">\n <GlyphButton\n glyph=\"chevron-left\"\n label={labels.previous}\n onClick={() => go(shiftAnchor(view, anchor, -1))}\n />\n <Button variant=\"secondary\" size=\"sm\" title=\"T\" onClick={() => go(today)}>\n {labels.today}\n </Button>\n <GlyphButton glyph=\"chevron-right\" label={labels.next} onClick={() => go(shiftAnchor(view, anchor, 1))} />\n </div>\n <SegmentedControl\n size=\"sm\"\n aria-label={labels.viewsLabel}\n value={view}\n onValueChange={(v) => changeView(v as CalendarView)}\n options={(['day', 'week', 'month'] as const).map((v) => ({ value: v, label: labels.views[v] }))}\n />\n {toolbarEnd}\n {aside && panelRoom && (\n <GlyphButton\n glyph=\"sidebar\"\n label={labels.togglePanel}\n pressed={asideOpen}\n onClick={() => setAsideOpen(!asideOpen)}\n />\n )}\n </div>\n <div\n aria-busy={loading || undefined}\n className={cx('select-none transition-opacity duration-150', loading && 'pointer-events-none opacity-60')}\n >\n {board}\n </div>\n {showHelp && (\n <p className=\"m-0 border-t border-border px-3 py-2 text-xs text-fg-muted\">\n {wide ? labels.help : labels.helpTouch}\n </p>\n )}\n </div>\n {showAside && (\n <aside className=\"grid content-start gap-5 rounded-lg border border-border bg-surface p-4\">{aside}</aside>\n )}\n\n {/* Item and \"+N more\" popovers, anchored to the element that opened them. */}\n <RadixPopover.Root\n open={floating?.type === 'item' || floating?.type === 'day'}\n onOpenChange={(o) => !o && closeFloating()}\n >\n <RadixPopover.Anchor\n virtualRef={{ current: { getBoundingClientRect: () => floating?.rect ?? pointRect(0, 0) } }}\n />\n {floating?.type === 'item' && (\n <PopoverContent\n aria-label={floating.item.title}\n side=\"right\"\n align=\"start\"\n className=\"w-[21.25rem] p-0\"\n onCloseAutoFocus={restoreFocus}\n >\n {renderItemPopover?.(floating.item, closeFloating)}\n </PopoverContent>\n )}\n {floating?.type === 'day' && (\n <PopoverContent\n title={dayLabel(floating.day, locale)}\n size=\"sm\"\n side=\"bottom\"\n align=\"start\"\n onCloseAutoFocus={restoreFocus}\n >\n <div className=\"grid max-h-80 gap-1 overflow-y-auto\">\n {sortItems(items.filter((i) => touches(i, floating.day, floating.day))).map((item) => (\n <ItemChip\n key={item.id}\n item={item}\n labels={labels}\n className=\"h-7! text-xs\"\n onOpen={(it) => {\n onOpenItem?.(it);\n if (renderItemPopover)\n setFloating({ type: 'item', item: it, rect: floating.rect, returnTo: floating.returnTo });\n }}\n />\n ))}\n </div>\n </PopoverContent>\n )}\n </RadixPopover.Root>\n\n {/* Quick actions for a selection, opened next to the pointer or the focused day. */}\n <DropdownMenu open={floating?.type === 'menu'} onOpenChange={(o) => !o && closeFloating()}>\n <DropdownMenuTrigger asChild>\n <span\n aria-hidden=\"true\"\n tabIndex={-1}\n className=\"pointer-events-none fixed\"\n style={{\n left: floating?.rect.left ?? 0,\n top: floating?.rect.top ?? 0,\n width: floating?.rect.width ?? 0,\n height: floating?.rect.height ?? 0,\n }}\n />\n </DropdownMenuTrigger>\n {floating?.type === 'menu' && (\n <DropdownMenuContent onCloseAutoFocus={restoreFocus} className=\"min-w-64\">\n <DropdownMenuLabel>\n {rangeLabel(floating.range.start, floating.range.end, locale)}\n {floating.range.startTime && ` · ${floating.range.startTime} – ${floating.range.endTime}`}\n </DropdownMenuLabel>\n {floating.actions.map((a) => (\n <DropdownMenuItem key={a.key} icon={a.icon} onSelect={a.onSelect}>\n <span className=\"grid\">\n <span>{a.label}</span>\n {a.hint && <span className=\"text-xs font-normal text-fg-muted\">{a.hint}</span>}\n </span>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n )}\n </DropdownMenu>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type IconName } from '../icon/icon';
3
+ import { type IsoDate } from './dates';
4
+ export interface EventDetailsProps {
5
+ title: ReactNode;
6
+ /** Dot color, e.g. `itemColor(item)`. */
7
+ color?: string;
8
+ /** "Thu, Nov 13 · 09:00 – 10:00". */
9
+ when?: ReactNode;
10
+ /** "Every week", shown with a repeat icon. */
11
+ repeat?: ReactNode;
12
+ /** Header actions (edit, delete `IconButton`s). */
13
+ actions?: ReactNode;
14
+ /** Shows a close button. */
15
+ onClose?: () => void;
16
+ closeLabel?: string;
17
+ /** `EventDetailsRow`s, guests, RSVP, a confirmation: the product decides. */
18
+ children?: ReactNode;
19
+ className?: string;
20
+ }
21
+ /**
22
+ * The layout of an event's popover or panel (ADR-0016): colored title, time and repeat lines, header actions and a
23
+ * scrolling body. It has no data or behavior; fill it with `EventDetailsRow`, `Avatar`, `Badge`, `SegmentedControl`
24
+ * (RSVP) and `Button`.
25
+ */
26
+ export declare function EventDetails({ title, color, when, repeat, actions, onClose, closeLabel, children, className, }: EventDetailsProps): import("react").JSX.Element;
27
+ /** One fact with an icon: location, organizer, visibility, a link. */
28
+ export declare function EventDetailsRow({ icon, children, className, }: {
29
+ icon?: IconName;
30
+ children: ReactNode;
31
+ className?: string;
32
+ }): import("react").JSX.Element;
33
+ export interface CalendarYearProps {
34
+ /** Shown year. */
35
+ year: number;
36
+ onYearChange: (year: number) => void;
37
+ /** Selected month, `YYYY-MM`. */
38
+ value?: string;
39
+ onValueChange?: (month: string) => void;
40
+ /** Today; its month gets a ring. */
41
+ today?: IsoDate;
42
+ locale?: string;
43
+ labels?: {
44
+ previous?: string;
45
+ next?: string;
46
+ };
47
+ className?: string;
48
+ }
49
+ /** A 12-month grid for jumping between months (the month view's side panel). */
50
+ export declare function CalendarYear({ year, onYearChange, value, onValueChange, today, locale, labels, className, }: CalendarYearProps): import("react").JSX.Element;
@@ -0,0 +1,124 @@
1
+ "use client";
2
+ import { cx as e } from "../lib/cx.js";
3
+ import { Icon as t } from "../icon/icon.js";
4
+ import { Glyph as n } from "../lib/glyphs.js";
5
+ import { toDate as r } from "./dates.js";
6
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
7
+ //#region src/event-calendar/event-details.tsx
8
+ function o({ title: r, color: o, when: s, repeat: c, actions: l, onClose: u, closeLabel: d = "Close", children: f, className: p }) {
9
+ return /* @__PURE__ */ a("div", {
10
+ className: e("grid font-sans text-sm text-fg", p),
11
+ children: [/* @__PURE__ */ a("div", {
12
+ className: "flex items-start gap-2.5 border-b border-border p-4 pb-3",
13
+ children: [
14
+ /* @__PURE__ */ i("span", {
15
+ "aria-hidden": "true",
16
+ className: "mt-1.5 size-2.5 shrink-0 rounded-full",
17
+ style: { background: o ?? "var(--kf-primary)" }
18
+ }),
19
+ /* @__PURE__ */ a("div", {
20
+ className: "grid min-w-0 flex-1 gap-0.5",
21
+ children: [
22
+ /* @__PURE__ */ i("p", {
23
+ className: "m-0 font-display text-[15px] leading-snug font-bold break-words",
24
+ children: r
25
+ }),
26
+ s && /* @__PURE__ */ i("p", {
27
+ className: "m-0 text-fg-muted tabular-nums",
28
+ children: s
29
+ }),
30
+ c && /* @__PURE__ */ a("p", {
31
+ className: "m-0 flex items-center gap-1.5 text-fg-muted",
32
+ children: [/* @__PURE__ */ i(t, {
33
+ name: "sync",
34
+ size: 14
35
+ }), c]
36
+ })
37
+ ]
38
+ }),
39
+ (l || u) && /* @__PURE__ */ a("div", {
40
+ className: "-mt-1 -mr-1 flex shrink-0 items-center",
41
+ children: [l, u && /* @__PURE__ */ i("button", {
42
+ type: "button",
43
+ "aria-label": d,
44
+ title: d,
45
+ onClick: u,
46
+ className: "inline-grid size-8 cursor-pointer place-items-center rounded-full border-0 bg-transparent text-fg hover:bg-surface-muted focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-focus pointer-coarse:size-11",
47
+ children: /* @__PURE__ */ i(n, {
48
+ name: "close",
49
+ size: 16
50
+ })
51
+ })]
52
+ })
53
+ ]
54
+ }), f && /* @__PURE__ */ i("div", {
55
+ className: "grid max-h-[60vh] gap-3 overflow-y-auto p-4",
56
+ children: f
57
+ })]
58
+ });
59
+ }
60
+ function s({ icon: n, children: r, className: o }) {
61
+ return /* @__PURE__ */ a("div", {
62
+ className: e("flex items-start gap-2.5", o),
63
+ children: [n ? /* @__PURE__ */ i(t, {
64
+ name: n,
65
+ size: 16,
66
+ className: "mt-0.5 shrink-0 text-fg-muted"
67
+ }) : /* @__PURE__ */ i("span", { className: "w-4 shrink-0" }), /* @__PURE__ */ i("div", {
68
+ className: "min-w-0 flex-1 break-words",
69
+ children: r
70
+ })]
71
+ });
72
+ }
73
+ function c({ year: t, onYearChange: o, value: s, onValueChange: c, today: l, locale: u = "en-US", labels: d, className: f }) {
74
+ let p = new Intl.DateTimeFormat(u, {
75
+ timeZone: "UTC",
76
+ month: "short"
77
+ }), m = new Intl.DateTimeFormat(u, {
78
+ timeZone: "UTC",
79
+ month: "long",
80
+ year: "numeric"
81
+ }), h = l?.slice(0, 7), g = (e, r, a) => /* @__PURE__ */ i("button", {
82
+ type: "button",
83
+ "aria-label": r,
84
+ title: r,
85
+ onClick: () => o(t + a),
86
+ className: "inline-grid size-8 cursor-pointer place-items-center rounded-full border-0 bg-transparent text-fg hover:bg-surface-muted focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-focus pointer-coarse:size-11",
87
+ children: /* @__PURE__ */ i(n, {
88
+ name: e,
89
+ size: 16
90
+ })
91
+ });
92
+ return /* @__PURE__ */ a("div", {
93
+ className: e("grid gap-2 font-sans", f),
94
+ children: [/* @__PURE__ */ a("div", {
95
+ className: "flex items-center justify-between",
96
+ children: [/* @__PURE__ */ i("p", {
97
+ className: "m-0 text-sm font-bold text-fg tabular-nums",
98
+ "aria-live": "polite",
99
+ children: t
100
+ }), /* @__PURE__ */ a("div", {
101
+ className: "flex",
102
+ children: [g("chevron-left", d?.previous ?? "Previous year", -1), g("chevron-right", d?.next ?? "Next year", 1)]
103
+ })]
104
+ }), /* @__PURE__ */ i("div", {
105
+ className: "grid grid-cols-3 gap-1",
106
+ children: Array.from({ length: 12 }, (n, a) => {
107
+ let o = `${t}-${String(a + 1).padStart(2, "0")}`, l = r(`${o}-01`), u = o === s;
108
+ return /* @__PURE__ */ i("button", {
109
+ type: "button",
110
+ "aria-pressed": u,
111
+ "aria-current": o === h ? "date" : void 0,
112
+ "aria-label": `${p.format(l)} – ${m.format(l)}`,
113
+ onClick: () => c?.(o),
114
+ className: e("h-9 cursor-pointer rounded-sm border-0 text-sm font-semibold capitalize text-fg transition-colors duration-150 pointer-coarse:h-11", "focus-visible:outline-3 focus-visible:outline-offset-1 focus-visible:outline-focus", u ? "bg-primary/15" : "bg-transparent hover:bg-surface-muted", o === h && "ring-1 ring-primary"),
115
+ children: p.format(l)
116
+ }, o);
117
+ })
118
+ })]
119
+ });
120
+ }
121
+ //#endregion
122
+ export { c as CalendarYear, o as EventDetails, s as EventDetailsRow };
123
+
124
+ //# sourceMappingURL=event-details.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-details.js","names":["EventDetails","cx","className","color","title","when","repeat","Icon","actions","onClose","closeLabel","Glyph","children","EventDetailsRow","icon","CalendarYear","fmt","locale","long","current","today","nav","label","onYearChange","year","delta","glyph","labels","key","i","date","toDate","selected","value","onValueChange"],"sources":["../../src/event-calendar/event-details.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactNode } from 'react';\nimport { cx } from '../lib/cx';\nimport { Glyph } from '../lib/glyphs';\nimport { Icon, type IconName } from '../icon/icon';\nimport { toDate, type IsoDate } from './dates';\n\nexport interface EventDetailsProps {\n title: ReactNode;\n /** Dot color, e.g. `itemColor(item)`. */\n color?: string;\n /** \"Thu, Nov 13 · 09:00 – 10:00\". */\n when?: ReactNode;\n /** \"Every week\", shown with a repeat icon. */\n repeat?: ReactNode;\n /** Header actions (edit, delete `IconButton`s). */\n actions?: ReactNode;\n /** Shows a close button. */\n onClose?: () => void;\n closeLabel?: string;\n /** `EventDetailsRow`s, guests, RSVP, a confirmation: the product decides. */\n children?: ReactNode;\n className?: string;\n}\n\n/**\n * The layout of an event's popover or panel (ADR-0016): colored title, time and repeat lines, header actions and a\n * scrolling body. It has no data or behavior; fill it with `EventDetailsRow`, `Avatar`, `Badge`, `SegmentedControl`\n * (RSVP) and `Button`.\n */\nexport function EventDetails({\n title,\n color,\n when,\n repeat,\n actions,\n onClose,\n closeLabel = 'Close',\n children,\n className,\n}: EventDetailsProps) {\n return (\n <div className={cx('grid font-sans text-sm text-fg', className)}>\n <div className=\"flex items-start gap-2.5 border-b border-border p-4 pb-3\">\n <span\n aria-hidden=\"true\"\n className=\"mt-1.5 size-2.5 shrink-0 rounded-full\"\n style={{ background: color ?? 'var(--kf-primary)' }}\n />\n <div className=\"grid min-w-0 flex-1 gap-0.5\">\n <p className=\"m-0 font-display text-[15px] leading-snug font-bold break-words\">{title}</p>\n {when && <p className=\"m-0 text-fg-muted tabular-nums\">{when}</p>}\n {repeat && (\n <p className=\"m-0 flex items-center gap-1.5 text-fg-muted\">\n <Icon name=\"sync\" size={14} />\n {repeat}\n </p>\n )}\n </div>\n {(actions || onClose) && (\n <div className=\"-mt-1 -mr-1 flex shrink-0 items-center\">\n {actions}\n {onClose && (\n <button\n type=\"button\"\n aria-label={closeLabel}\n title={closeLabel}\n onClick={onClose}\n className=\"inline-grid size-8 cursor-pointer place-items-center rounded-full border-0 bg-transparent text-fg hover:bg-surface-muted focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-focus pointer-coarse:size-11\"\n >\n <Glyph name=\"close\" size={16} />\n </button>\n )}\n </div>\n )}\n </div>\n {children && <div className=\"grid max-h-[60vh] gap-3 overflow-y-auto p-4\">{children}</div>}\n </div>\n );\n}\n\n/** One fact with an icon: location, organizer, visibility, a link. */\nexport function EventDetailsRow({\n icon,\n children,\n className,\n}: {\n icon?: IconName;\n children: ReactNode;\n className?: string;\n}) {\n return (\n <div className={cx('flex items-start gap-2.5', className)}>\n {icon ? (\n <Icon name={icon} size={16} className=\"mt-0.5 shrink-0 text-fg-muted\" />\n ) : (\n <span className=\"w-4 shrink-0\" />\n )}\n <div className=\"min-w-0 flex-1 break-words\">{children}</div>\n </div>\n );\n}\n\n/* ---------------- Year view ---------------- */\n\nexport interface CalendarYearProps {\n /** Shown year. */\n year: number;\n onYearChange: (year: number) => void;\n /** Selected month, `YYYY-MM`. */\n value?: string;\n onValueChange?: (month: string) => void;\n /** Today; its month gets a ring. */\n today?: IsoDate;\n locale?: string;\n labels?: { previous?: string; next?: string };\n className?: string;\n}\n\n/** A 12-month grid for jumping between months (the month view's side panel). */\nexport function CalendarYear({\n year,\n onYearChange,\n value,\n onValueChange,\n today,\n locale = 'en-US',\n labels,\n className,\n}: CalendarYearProps) {\n const fmt = new Intl.DateTimeFormat(locale, { timeZone: 'UTC', month: 'short' });\n const long = new Intl.DateTimeFormat(locale, { timeZone: 'UTC', month: 'long', year: 'numeric' });\n const current = today?.slice(0, 7);\n const nav = (glyph: 'chevron-left' | 'chevron-right', label: string, delta: number) => (\n <button\n type=\"button\"\n aria-label={label}\n title={label}\n onClick={() => onYearChange(year + delta)}\n className=\"inline-grid size-8 cursor-pointer place-items-center rounded-full border-0 bg-transparent text-fg hover:bg-surface-muted focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-focus pointer-coarse:size-11\"\n >\n <Glyph name={glyph} size={16} />\n </button>\n );\n return (\n <div className={cx('grid gap-2 font-sans', className)}>\n <div className=\"flex items-center justify-between\">\n <p className=\"m-0 text-sm font-bold text-fg tabular-nums\" aria-live=\"polite\">\n {year}\n </p>\n <div className=\"flex\">\n {nav('chevron-left', labels?.previous ?? 'Previous year', -1)}\n {nav('chevron-right', labels?.next ?? 'Next year', 1)}\n </div>\n </div>\n <div className=\"grid grid-cols-3 gap-1\">\n {Array.from({ length: 12 }, (_, i) => {\n const key = `${year}-${String(i + 1).padStart(2, '0')}`;\n const date = toDate(`${key}-01`);\n const selected = key === value;\n return (\n <button\n key={key}\n type=\"button\"\n aria-pressed={selected}\n aria-current={key === current ? 'date' : undefined}\n aria-label={`${fmt.format(date)} – ${long.format(date)}`}\n onClick={() => onValueChange?.(key)}\n className={cx(\n 'h-9 cursor-pointer rounded-sm border-0 text-sm font-semibold capitalize text-fg transition-colors duration-150 pointer-coarse:h-11',\n 'focus-visible:outline-3 focus-visible:outline-offset-1 focus-visible:outline-focus',\n selected ? 'bg-primary/15' : 'bg-transparent hover:bg-surface-muted',\n key === current && 'ring-1 ring-primary',\n )}\n >\n {fmt.format(date)}\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { type IsoDate } from './dates';
2
+ /** The fields the layout needs (a subset of `CalendarItem`). */
3
+ export interface LayoutItem {
4
+ id: string;
5
+ start: IsoDate;
6
+ /** Inclusive last day; defaults to `start`. */
7
+ end?: IsoDate;
8
+ allDay?: boolean;
9
+ startTime?: string;
10
+ endTime?: string;
11
+ title: string;
12
+ }
13
+ export declare const endOf: (item: LayoutItem) => string;
14
+ /** All-day unless it has a start time. */
15
+ export declare const isAllDay: (item: LayoutItem) => boolean;
16
+ export declare const touches: (item: LayoutItem, from: IsoDate, to: IsoDate) => boolean;
17
+ /** Start day, then start time (all-day first), then longer first, then title. */
18
+ export declare function sortItems<T extends LayoutItem>(items: readonly T[]): T[];
19
+ export interface PackedBar<T> {
20
+ item: T;
21
+ /** First and last column (0-based) inside the row. */
22
+ from: number;
23
+ to: number;
24
+ lane: number;
25
+ /** The item starts before or ends after this row: square that side. */
26
+ continuesBefore: boolean;
27
+ continuesAfter: boolean;
28
+ }
29
+ /**
30
+ * Lays out items as bars across one row of consecutive days (a week): each bar takes the first lane where it does not
31
+ * collide. Items outside the row are dropped.
32
+ */
33
+ export declare function packRow<T extends LayoutItem>(items: readonly T[], days: readonly IsoDate[]): PackedBar<T>[];
34
+ export interface PlacedEvent<T> {
35
+ item: T;
36
+ /** Minutes since midnight inside this day. */
37
+ from: number;
38
+ to: number;
39
+ column: number;
40
+ columns: number;
41
+ }
42
+ /** The shortest block drawn, in minutes, so a 5-minute event is still clickable. */
43
+ export declare const MIN_BLOCK = 20;
44
+ /**
45
+ * Places timed items on one day: an item that started earlier begins at 00:00 and one that continues ends at 24:00.
46
+ * Overlapping items form a cluster and sit side by side in the first free column; the cluster shares its column count.
47
+ */
48
+ export declare function placeDay<T extends LayoutItem>(items: readonly T[], day: IsoDate): PlacedEvent<T>[];
@@ -0,0 +1,55 @@
1
+ import { daysBetween as e, minutesOf as t } from "./dates.js";
2
+ //#region src/event-calendar/layout.ts
3
+ var n = (e) => e.end ?? e.start, r = (e) => e.allDay ?? !e.startTime, i = (e, t, r) => e.start <= r && n(e) >= t;
4
+ function a(t) {
5
+ return [...t].sort((t, i) => t.start.localeCompare(i.start) || Number(!r(t)) - Number(!r(i)) || (t.startTime ?? "").localeCompare(i.startTime ?? "") || e(i.start, n(i)) - e(t.start, n(t)) || t.title.localeCompare(i.title));
6
+ }
7
+ function o(t, r) {
8
+ let o = r[0], s = r[r.length - 1];
9
+ if (!o || !s) return [];
10
+ let c = [], l = [];
11
+ for (let u of a(t)) {
12
+ if (!i(u, o, s)) continue;
13
+ let t = Math.max(0, e(o, u.start)), a = Math.min(r.length - 1, e(o, n(u))), d = c.findIndex((e) => e.every((e) => e < t || e > a));
14
+ d === -1 && (d = c.push([]) - 1);
15
+ for (let e = t; e <= a; e++) c[d].push(e);
16
+ l.push({
17
+ item: u,
18
+ from: t,
19
+ to: a,
20
+ lane: d,
21
+ continuesBefore: u.start < o,
22
+ continuesAfter: n(u) > s
23
+ });
24
+ }
25
+ return l;
26
+ }
27
+ function s(e, a) {
28
+ let o = e.filter((e) => !r(e) && i(e, a, a)).map((e) => {
29
+ let r = e.start < a ? 0 : t(e.startTime ?? "00:00"), i = n(e) > a || !e.endTime ? 1440 : t(e.endTime);
30
+ return {
31
+ item: e,
32
+ from: r,
33
+ to: Math.min(1440, Math.max(i, r + 20))
34
+ };
35
+ }).sort((e, t) => e.from - t.from || t.to - e.to), s = [], c = [], l = [], u = -1, d = () => {
36
+ for (let e of c) e.columns = l.length;
37
+ c = [], l = [];
38
+ };
39
+ for (let e of o) {
40
+ e.from >= u && d();
41
+ let t = l.findIndex((t) => t <= e.from);
42
+ t === -1 && (t = l.push(0) - 1), l[t] = e.to;
43
+ let n = {
44
+ ...e,
45
+ column: t,
46
+ columns: 1
47
+ };
48
+ c.push(n), s.push(n), u = Math.max(u, e.to);
49
+ }
50
+ return d(), s;
51
+ }
52
+ //#endregion
53
+ export { n as endOf, r as isAllDay, o as packRow, s as placeDay, a as sortItems, i as touches };
54
+
55
+ //# sourceMappingURL=layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.js","names":["endOf","item","isAllDay","touches","to","from","sortItems","items","a","b","daysBetween","packRow","first","days","last","lanes","bars","lane","cols","c","placeDay","spans","i","day","minutesOf","rawTo","placed","cluster","columnEnds","clusterEnd","close","p","s","column","end"],"sources":["../../src/event-calendar/layout.ts"],"sourcesContent":["import { daysBetween, minutesOf, type IsoDate } from './dates';\n\n/** The fields the layout needs (a subset of `CalendarItem`). */\nexport interface LayoutItem {\n id: string;\n start: IsoDate;\n /** Inclusive last day; defaults to `start`. */\n end?: IsoDate;\n allDay?: boolean;\n startTime?: string;\n endTime?: string;\n title: string;\n}\n\nexport const endOf = (item: LayoutItem) => item.end ?? item.start;\n/** All-day unless it has a start time. */\nexport const isAllDay = (item: LayoutItem) => item.allDay ?? !item.startTime;\nexport const touches = (item: LayoutItem, from: IsoDate, to: IsoDate) => item.start <= to && endOf(item) >= from;\n\n/** Start day, then start time (all-day first), then longer first, then title. */\nexport function sortItems<T extends LayoutItem>(items: readonly T[]): T[] {\n return [...items].sort(\n (a, b) =>\n a.start.localeCompare(b.start) ||\n Number(!isAllDay(a)) - Number(!isAllDay(b)) ||\n (a.startTime ?? '').localeCompare(b.startTime ?? '') ||\n daysBetween(b.start, endOf(b)) - daysBetween(a.start, endOf(a)) ||\n a.title.localeCompare(b.title),\n );\n}\n\nexport interface PackedBar<T> {\n item: T;\n /** First and last column (0-based) inside the row. */\n from: number;\n to: number;\n lane: number;\n /** The item starts before or ends after this row: square that side. */\n continuesBefore: boolean;\n continuesAfter: boolean;\n}\n\n/**\n * Lays out items as bars across one row of consecutive days (a week): each bar takes the first lane where it does not\n * collide. Items outside the row are dropped.\n */\nexport function packRow<T extends LayoutItem>(items: readonly T[], days: readonly IsoDate[]): PackedBar<T>[] {\n const first = days[0];\n const last = days[days.length - 1];\n if (!first || !last) return [];\n const lanes: number[][] = []; // occupied columns per lane\n const bars: PackedBar<T>[] = [];\n for (const item of sortItems(items)) {\n if (!touches(item, first, last)) continue;\n const from = Math.max(0, daysBetween(first, item.start));\n const to = Math.min(days.length - 1, daysBetween(first, endOf(item)));\n let lane = lanes.findIndex((cols) => cols.every((c) => c < from || c > to));\n if (lane === -1) lane = lanes.push([]) - 1;\n for (let c = from; c <= to; c++) lanes[lane]!.push(c);\n bars.push({ item, from, to, lane, continuesBefore: item.start < first, continuesAfter: endOf(item) > last });\n }\n return bars;\n}\n\nexport interface PlacedEvent<T> {\n item: T;\n /** Minutes since midnight inside this day. */\n from: number;\n to: number;\n column: number;\n columns: number;\n}\n\n/** The shortest block drawn, in minutes, so a 5-minute event is still clickable. */\nexport const MIN_BLOCK = 20;\n\n/**\n * Places timed items on one day: an item that started earlier begins at 00:00 and one that continues ends at 24:00.\n * Overlapping items form a cluster and sit side by side in the first free column; the cluster shares its column count.\n */\nexport function placeDay<T extends LayoutItem>(items: readonly T[], day: IsoDate): PlacedEvent<T>[] {\n const spans = items\n .filter((i) => !isAllDay(i) && touches(i, day, day))\n .map((item) => {\n const from = item.start < day ? 0 : minutesOf(item.startTime ?? '00:00');\n const rawTo = endOf(item) > day || !item.endTime ? 24 * 60 : minutesOf(item.endTime);\n return { item, from, to: Math.min(24 * 60, Math.max(rawTo, from + MIN_BLOCK)) };\n })\n .sort((a, b) => a.from - b.from || b.to - a.to);\n\n const placed: PlacedEvent<T>[] = [];\n let cluster: PlacedEvent<T>[] = [];\n let columnEnds: number[] = [];\n let clusterEnd = -1;\n const close = () => {\n for (const p of cluster) p.columns = columnEnds.length;\n cluster = [];\n columnEnds = [];\n };\n for (const s of spans) {\n if (s.from >= clusterEnd) close();\n let column = columnEnds.findIndex((end) => end <= s.from);\n if (column === -1) column = columnEnds.push(0) - 1;\n columnEnds[column] = s.to;\n const p = { ...s, column, columns: 1 };\n cluster.push(p);\n placed.push(p);\n clusterEnd = Math.max(clusterEnd, s.to);\n }\n close();\n return placed;\n}\n"],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ export type UploadStatus = 'queued' | 'uploading' | 'done' | 'error';
2
+ export interface UploadItem {
3
+ id: string;
4
+ file: File;
5
+ status: UploadStatus;
6
+ /** 0–100 while uploading. */
7
+ progress?: number;
8
+ error?: string;
9
+ }
10
+ export interface FileUploadProps {
11
+ /** Files already added (controlled). Upload them yourself and update `status`/`progress`. */
12
+ items: UploadItem[];
13
+ /** New valid files (already checked against `accept`, `maxSize`, `maxFiles`). */
14
+ onAdd: (files: File[]) => void;
15
+ onRemove: (id: string) => void;
16
+ /** Files rejected by validation, with the reason. */
17
+ onReject?: (rejections: {
18
+ file: File;
19
+ reason: string;
20
+ }[]) => void;
21
+ /** Same syntax as `<input accept>`: ".pdf,.csv,image/*". */
22
+ accept?: string;
23
+ /** Bytes. */
24
+ maxSize?: number;
25
+ maxFiles?: number;
26
+ multiple?: boolean;
27
+ disabled?: boolean;
28
+ id?: string;
29
+ /**
30
+ * `dropzone` (default): drag-and-drop area plus a file list. `button`: one "Choose file" button and a hint
31
+ * (forms with little room). `image`: a single image with a preview, "Change" and "Remove" (logos, banners, photos).
32
+ */
33
+ variant?: FileUploadVariant;
34
+ /** `image` only: the image already saved, shown until a new file is added. */
35
+ src?: string;
36
+ /** `image` only: removes the saved `src` (the new file, if any, is removed with `onRemove`). */
37
+ onClear?: () => void;
38
+ /** `image` only: `square` (logo), `wide` (16:9 banner) or `avatar` (round, with an edit button on the photo). */
39
+ imageShape?: 'square' | 'wide' | 'avatar';
40
+ /** `image` only: what happens without an image ("Without a logo, the project uses its client's logo"). */
41
+ fallbackText?: string;
42
+ labels?: Partial<typeof LABELS>;
43
+ className?: string;
44
+ }
45
+ export type FileUploadVariant = 'dropzone' | 'button' | 'image';
46
+ declare const LABELS: {
47
+ title: string;
48
+ browse: string;
49
+ /** `{types}` and `{size}` are replaced. */
50
+ constraints: string;
51
+ remove: string;
52
+ tooBig: string;
53
+ wrongType: string;
54
+ tooMany: string;
55
+ uploading: string;
56
+ done: string;
57
+ chooseFile: string;
58
+ uploadImage: string;
59
+ changeImage: string;
60
+ removeImage: string;
61
+ imagePreview: string;
62
+ images: string;
63
+ };
64
+ export declare function formatBytes(bytes: number): string;
65
+ /**
66
+ * Drag-and-drop (or tap to browse) file input with validation, image previews and per-file
67
+ * progress. The component validates and lists; your app uploads and reports progress.
68
+ */
69
+ export declare function FileUpload({ items, onAdd, onRemove, onReject, accept, maxSize, maxFiles, multiple: multipleProp, disabled, variant, src, onClear, imageShape, fallbackText, labels: overrides, className, ...rest }: FileUploadProps): import("react").JSX.Element;
70
+ export {};