@k2b/ui 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 (610) hide show
  1. package/dist/browser/actions/ContextMenu.js +3 -1
  2. package/dist/browser/actions/ContextMenu.js.map +1 -1
  3. package/dist/browser/actions/FilterChip.js +3 -1
  4. package/dist/browser/actions/FilterChip.js.map +1 -1
  5. package/dist/browser/actions/SpotlightSearch.js +3 -1
  6. package/dist/browser/actions/SpotlightSearch.js.map +1 -1
  7. package/dist/browser/actions/filter-messages.js +20 -0
  8. package/dist/browser/actions/filter-messages.js.map +1 -0
  9. package/dist/browser/actions/spotlight-messages.js +16 -0
  10. package/dist/browser/actions/spotlight-messages.js.map +1 -0
  11. package/dist/browser/chat/ChatComposer.js +47 -41
  12. package/dist/browser/chat/ChatComposer.js.map +1 -1
  13. package/dist/browser/chat/ChatPrimitives.js +25 -23
  14. package/dist/browser/chat/ChatPrimitives.js.map +1 -1
  15. package/dist/browser/chat/ChatRoot.js +3 -3
  16. package/dist/browser/chat/ChatRoot.js.map +1 -1
  17. package/dist/browser/chat/ChatTimeline.js +12 -12
  18. package/dist/browser/chat/ChatTimeline.js.map +1 -1
  19. package/dist/browser/chat/chat-messages.js +236 -0
  20. package/dist/browser/chat/chat-messages.js.map +1 -0
  21. package/dist/browser/content/Calendar.js +1096 -1060
  22. package/dist/browser/content/Calendar.js.map +1 -1
  23. package/dist/browser/content/CalendarDayView.js +1187 -0
  24. package/dist/browser/content/CalendarDayView.js.map +1 -0
  25. package/dist/browser/content/CalendarWeekView.js +1571 -0
  26. package/dist/browser/content/CalendarWeekView.js.map +1 -0
  27. package/dist/browser/content/Chart.js +15 -8
  28. package/dist/browser/content/Chart.js.map +1 -1
  29. package/dist/browser/content/ChartExplorer.js +185 -85
  30. package/dist/browser/content/ChartExplorer.js.map +1 -1
  31. package/dist/browser/content/ChartExplorerControls.js +9 -7
  32. package/dist/browser/content/ChartExplorerControls.js.map +1 -1
  33. package/dist/browser/content/ChartFilterControls.js +93 -34
  34. package/dist/browser/content/ChartFilterControls.js.map +1 -1
  35. package/dist/browser/content/ChartSnapshotView.js +3 -3
  36. package/dist/browser/content/ChartSnapshotView.js.map +1 -1
  37. package/dist/browser/content/DataTable.js +238 -201
  38. package/dist/browser/content/DataTable.js.map +1 -1
  39. package/dist/browser/content/Docs.js +3 -1
  40. package/dist/browser/content/Docs.js.map +1 -1
  41. package/dist/browser/content/FileBrowser.js +30 -26
  42. package/dist/browser/content/FileBrowser.js.map +1 -1
  43. package/dist/browser/content/FileTree.js +9 -7
  44. package/dist/browser/content/FileTree.js.map +1 -1
  45. package/dist/browser/content/FileView.js +37 -28
  46. package/dist/browser/content/FileView.js.map +1 -1
  47. package/dist/browser/content/Lightbox.js +9 -7
  48. package/dist/browser/content/Lightbox.js.map +1 -1
  49. package/dist/browser/content/LogEntriesTable.js +3 -3
  50. package/dist/browser/content/LogEntriesTable.js.map +1 -1
  51. package/dist/browser/content/MessageRow.js +24 -22
  52. package/dist/browser/content/MessageRow.js.map +1 -1
  53. package/dist/browser/content/Pagination.js +7 -7
  54. package/dist/browser/content/Pagination.js.map +1 -1
  55. package/dist/browser/content/PdfPreview.js +15 -13
  56. package/dist/browser/content/PdfPreview.js.map +1 -1
  57. package/dist/browser/content/RangePicker.js +3 -1
  58. package/dist/browser/content/RangePicker.js.map +1 -1
  59. package/dist/browser/content/StructuredDataPreview.js +3 -1
  60. package/dist/browser/content/StructuredDataPreview.js.map +1 -1
  61. package/dist/browser/content/Timeline.js +13 -11
  62. package/dist/browser/content/Timeline.js.map +1 -1
  63. package/dist/browser/content/VideoPlayer.js +5 -5
  64. package/dist/browser/content/VideoPlayer.js.map +1 -1
  65. package/dist/browser/content/VirtualFeed.js +6 -4
  66. package/dist/browser/content/VirtualFeed.js.map +1 -1
  67. package/dist/browser/content/ZoomPanViewport.js +10 -7
  68. package/dist/browser/content/ZoomPanViewport.js.map +1 -1
  69. package/dist/browser/content/calendar-day-scroll.js +98 -0
  70. package/dist/browser/content/calendar-day-scroll.js.map +1 -0
  71. package/dist/browser/content/calendar-days.js +408 -0
  72. package/dist/browser/content/calendar-days.js.map +1 -0
  73. package/dist/browser/content/calendar-dialogs.js +236 -0
  74. package/dist/browser/content/calendar-dialogs.js.map +1 -0
  75. package/dist/browser/content/calendar-messages.js +249 -3
  76. package/dist/browser/content/calendar-messages.js.map +1 -1
  77. package/dist/browser/content/calendar-pointer.js +19 -6
  78. package/dist/browser/content/calendar-pointer.js.map +1 -1
  79. package/dist/browser/content/calendar-shared.js +328 -0
  80. package/dist/browser/content/calendar-shared.js.map +1 -0
  81. package/dist/browser/content/calendar-time-view.js +1649 -0
  82. package/dist/browser/content/calendar-time-view.js.map +1 -0
  83. package/dist/browser/content/chart-messages.js +146 -0
  84. package/dist/browser/content/chart-messages.js.map +1 -0
  85. package/dist/browser/content/collection-selection.js +2 -0
  86. package/dist/browser/content/collection-selection.js.map +1 -1
  87. package/dist/browser/content/data-table-messages.js +24 -0
  88. package/dist/browser/content/data-table-messages.js.map +1 -0
  89. package/dist/browser/content/docs-messages.js +24 -0
  90. package/dist/browser/content/docs-messages.js.map +1 -0
  91. package/dist/browser/content/feed-messages.js +34 -0
  92. package/dist/browser/content/feed-messages.js.map +1 -0
  93. package/dist/browser/content/file-browser-messages.js +69 -0
  94. package/dist/browser/content/file-browser-messages.js.map +1 -0
  95. package/dist/browser/content/file-view-messages.js +64 -0
  96. package/dist/browser/content/file-view-messages.js.map +1 -0
  97. package/dist/browser/content/index.js.map +1 -1
  98. package/dist/browser/content/lightbox-messages.js +36 -0
  99. package/dist/browser/content/lightbox-messages.js.map +1 -0
  100. package/dist/browser/content/log-entries-messages.js +20 -0
  101. package/dist/browser/content/log-entries-messages.js.map +1 -0
  102. package/dist/browser/content/markdown-info-block-messages.js +24 -0
  103. package/dist/browser/content/markdown-info-block-messages.js.map +1 -0
  104. package/dist/browser/content/markdown-info-blocks.js +3 -3
  105. package/dist/browser/content/markdown-info-blocks.js.map +1 -1
  106. package/dist/browser/content/markdown-links.js +2 -2
  107. package/dist/browser/content/markdown-links.js.map +1 -1
  108. package/dist/browser/content/markdown-reference-messages.js +30 -0
  109. package/dist/browser/content/markdown-reference-messages.js.map +1 -0
  110. package/dist/browser/content/pagination-messages.js +38 -0
  111. package/dist/browser/content/pagination-messages.js.map +1 -0
  112. package/dist/browser/content/pdf-messages.js +43 -0
  113. package/dist/browser/content/pdf-messages.js.map +1 -0
  114. package/dist/browser/content/range-picker-messages.js +20 -0
  115. package/dist/browser/content/range-picker-messages.js.map +1 -0
  116. package/dist/browser/content/structured-data-messages.js +22 -0
  117. package/dist/browser/content/structured-data-messages.js.map +1 -0
  118. package/dist/browser/content/timeline-messages.js +62 -0
  119. package/dist/browser/content/timeline-messages.js.map +1 -0
  120. package/dist/browser/content/video-messages.js +24 -0
  121. package/dist/browser/content/video-messages.js.map +1 -0
  122. package/dist/browser/content/viewport-messages.js +28 -0
  123. package/dist/browser/content/viewport-messages.js.map +1 -0
  124. package/dist/browser/feedback/HoverPreview.js +34 -6
  125. package/dist/browser/feedback/HoverPreview.js.map +1 -1
  126. package/dist/browser/feedback/InstallGuide.js +18 -18
  127. package/dist/browser/feedback/InstallGuide.js.map +1 -1
  128. package/dist/browser/feedback/install-messages.js +104 -0
  129. package/dist/browser/feedback/install-messages.js.map +1 -0
  130. package/dist/browser/feedback/prompt-messages.js +65 -0
  131. package/dist/browser/feedback/prompt-messages.js.map +1 -0
  132. package/dist/browser/feedback/prompts.js +14 -11
  133. package/dist/browser/feedback/prompts.js.map +1 -1
  134. package/dist/browser/feedback/toast-messages.js +18 -0
  135. package/dist/browser/feedback/toast-messages.js.map +1 -0
  136. package/dist/browser/feedback/toast.js +4 -3
  137. package/dist/browser/feedback/toast.js.map +1 -1
  138. package/dist/browser/index.js +1 -1
  139. package/dist/browser/index.js.map +1 -1
  140. package/dist/browser/inputs/AutocompleteEditor.js +6 -4
  141. package/dist/browser/inputs/AutocompleteEditor.js.map +1 -1
  142. package/dist/browser/inputs/AutocompleteSelect.js +10 -8
  143. package/dist/browser/inputs/AutocompleteSelect.js.map +1 -1
  144. package/dist/browser/inputs/ChoiceGroups.js +4 -0
  145. package/dist/browser/inputs/ChoiceGroups.js.map +1 -1
  146. package/dist/browser/inputs/ChoiceInputs.js +5 -5
  147. package/dist/browser/inputs/ChoiceInputs.js.map +1 -1
  148. package/dist/browser/inputs/Combobox.js +3 -2
  149. package/dist/browser/inputs/Combobox.js.map +1 -1
  150. package/dist/browser/inputs/FileDropTarget.js +6 -6
  151. package/dist/browser/inputs/FileDropTarget.js.map +1 -1
  152. package/dist/browser/inputs/FileInputs.js +30 -21
  153. package/dist/browser/inputs/FileInputs.js.map +1 -1
  154. package/dist/browser/inputs/MultiSelectInput.js +7 -5
  155. package/dist/browser/inputs/MultiSelectInput.js.map +1 -1
  156. package/dist/browser/inputs/NumberInput.js +4 -2
  157. package/dist/browser/inputs/NumberInput.js.map +1 -1
  158. package/dist/browser/inputs/QrScanner.js +5 -5
  159. package/dist/browser/inputs/QrScanner.js.map +1 -1
  160. package/dist/browser/inputs/Select.js +7 -5
  161. package/dist/browser/inputs/Select.js.map +1 -1
  162. package/dist/browser/inputs/SelectChip.js +3 -3
  163. package/dist/browser/inputs/SelectChip.js.map +1 -1
  164. package/dist/browser/inputs/SignatureInput.js +9 -3
  165. package/dist/browser/inputs/SignatureInput.js.map +1 -1
  166. package/dist/browser/inputs/SpecialInputs.js +4 -2
  167. package/dist/browser/inputs/SpecialInputs.js.map +1 -1
  168. package/dist/browser/inputs/TagEditor.js +8 -6
  169. package/dist/browser/inputs/TagEditor.js.map +1 -1
  170. package/dist/browser/inputs/TagsInput.js +5 -5
  171. package/dist/browser/inputs/TagsInput.js.map +1 -1
  172. package/dist/browser/inputs/TemplateEditor.js +5 -5
  173. package/dist/browser/inputs/TemplateEditor.js.map +1 -1
  174. package/dist/browser/inputs/TextInput.js +3 -1
  175. package/dist/browser/inputs/TextInput.js.map +1 -1
  176. package/dist/browser/inputs/completion-messages.js +24 -0
  177. package/dist/browser/inputs/completion-messages.js.map +1 -0
  178. package/dist/browser/inputs/file-drop-messages.js +63 -0
  179. package/dist/browser/inputs/file-drop-messages.js.map +1 -0
  180. package/dist/browser/inputs/file-drop.js.map +1 -1
  181. package/dist/browser/inputs/file-input-messages.js +60 -0
  182. package/dist/browser/inputs/file-input-messages.js.map +1 -0
  183. package/dist/browser/inputs/icon-messages.js +22 -0
  184. package/dist/browser/inputs/icon-messages.js.map +1 -0
  185. package/dist/browser/inputs/input-messages.js +38 -0
  186. package/dist/browser/inputs/input-messages.js.map +1 -0
  187. package/dist/browser/inputs/markdown/MarkdownEditor.js +10 -6
  188. package/dist/browser/inputs/markdown/MarkdownEditor.js.map +1 -1
  189. package/dist/browser/inputs/markdown/Toolbar.js +13 -13
  190. package/dist/browser/inputs/markdown/Toolbar.js.map +1 -1
  191. package/dist/browser/inputs/markdown/editor-messages.js +43 -0
  192. package/dist/browser/inputs/markdown/editor-messages.js.map +1 -0
  193. package/dist/browser/inputs/markdown/toolbar-messages.js +40 -0
  194. package/dist/browser/inputs/markdown/toolbar-messages.js.map +1 -0
  195. package/dist/browser/inputs/qr-messages.js +26 -0
  196. package/dist/browser/inputs/qr-messages.js.map +1 -0
  197. package/dist/browser/inputs/select-messages.js +63 -0
  198. package/dist/browser/inputs/select-messages.js.map +1 -0
  199. package/dist/browser/inputs/tag-messages.js +44 -0
  200. package/dist/browser/inputs/tag-messages.js.map +1 -0
  201. package/dist/browser/inputs/template-messages.js +22 -0
  202. package/dist/browser/inputs/template-messages.js.map +1 -0
  203. package/dist/browser/internal/render-error-messages.js +20 -0
  204. package/dist/browser/internal/render-error-messages.js.map +1 -0
  205. package/dist/browser/internal/render-error.js +3 -1
  206. package/dist/browser/internal/render-error.js.map +1 -1
  207. package/dist/browser/internal/text-selection.js +101 -0
  208. package/dist/browser/internal/text-selection.js.map +1 -0
  209. package/dist/browser/intl/messages.js +6 -1155
  210. package/dist/browser/intl/messages.js.map +1 -1
  211. package/dist/browser/layout/AppWorkspace.js +594 -425
  212. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  213. package/dist/browser/layout/BottomSheet.js +6 -1
  214. package/dist/browser/layout/BottomSheet.js.map +1 -1
  215. package/dist/browser/layout/Discussion.js +8 -5
  216. package/dist/browser/layout/Discussion.js.map +1 -1
  217. package/dist/browser/layout/FloatingWindow.js +8 -5
  218. package/dist/browser/layout/FloatingWindow.js.map +1 -1
  219. package/dist/browser/layout/Navigation.js +7 -6
  220. package/dist/browser/layout/Navigation.js.map +1 -1
  221. package/dist/browser/layout/PageTitle.js +373 -0
  222. package/dist/browser/layout/PageTitle.js.map +1 -0
  223. package/dist/browser/layout/PanelDialog.js +8 -6
  224. package/dist/browser/layout/PanelDialog.js.map +1 -1
  225. package/dist/browser/layout/Panes.js +23 -15
  226. package/dist/browser/layout/Panes.js.map +1 -1
  227. package/dist/browser/layout/PullToRefresh.js +13 -4
  228. package/dist/browser/layout/PullToRefresh.js.map +1 -1
  229. package/dist/browser/layout/Settings.js +14 -12
  230. package/dist/browser/layout/Settings.js.map +1 -1
  231. package/dist/browser/layout/SettingsCollection.js +6 -5
  232. package/dist/browser/layout/SettingsCollection.js.map +1 -1
  233. package/dist/browser/layout/SettingsModal.js +3 -1
  234. package/dist/browser/layout/SettingsModal.js.map +1 -1
  235. package/dist/browser/layout/app-workspace-controller.js +821 -12
  236. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  237. package/dist/browser/layout/app-workspace-state.js +3 -2
  238. package/dist/browser/layout/app-workspace-state.js.map +1 -1
  239. package/dist/browser/layout/floating-window-messages.js +28 -0
  240. package/dist/browser/layout/floating-window-messages.js.map +1 -0
  241. package/dist/browser/layout/index.js +2 -0
  242. package/dist/browser/layout/index.js.map +1 -1
  243. package/dist/browser/layout/navigation-model.js.map +1 -1
  244. package/dist/browser/layout/page-title-controller.js +169 -0
  245. package/dist/browser/layout/page-title-controller.js.map +1 -0
  246. package/dist/browser/layout/panel-dialog-messages.js +20 -0
  247. package/dist/browser/layout/panel-dialog-messages.js.map +1 -0
  248. package/dist/browser/layout/panes-messages.js +48 -0
  249. package/dist/browser/layout/panes-messages.js.map +1 -0
  250. package/dist/browser/layout/refresh-messages.js +20 -0
  251. package/dist/browser/layout/refresh-messages.js.map +1 -0
  252. package/dist/browser/layout/settings-messages.js +54 -0
  253. package/dist/browser/layout/settings-messages.js.map +1 -0
  254. package/dist/browser/layout/workspace-messages.js +56 -0
  255. package/dist/browser/layout/workspace-messages.js.map +1 -0
  256. package/dist/browser/surfaces/Avatar.js +5 -5
  257. package/dist/browser/surfaces/Avatar.js.map +1 -1
  258. package/dist/browser/surfaces/ResourceCard.js +4 -2
  259. package/dist/browser/surfaces/ResourceCard.js.map +1 -1
  260. package/dist/browser/surfaces/StatCell.js +18 -6
  261. package/dist/browser/surfaces/StatCell.js.map +1 -1
  262. package/dist/browser/surfaces/Tag.js +3 -3
  263. package/dist/browser/surfaces/Tag.js.map +1 -1
  264. package/dist/browser/surfaces/avatar-messages.js +26 -0
  265. package/dist/browser/surfaces/avatar-messages.js.map +1 -0
  266. package/dist/browser/surfaces/resource-messages.js +26 -0
  267. package/dist/browser/surfaces/resource-messages.js.map +1 -0
  268. package/dist/browser/widgets/Widget.js +6 -0
  269. package/dist/browser/widgets/Widget.js.map +1 -1
  270. package/dist/ssr/actions/ContextMenu.js.map +1 -1
  271. package/dist/ssr/actions/FilterChip.js +3 -1
  272. package/dist/ssr/actions/FilterChip.js.map +1 -1
  273. package/dist/ssr/actions/SpotlightSearch.js +3 -1
  274. package/dist/ssr/actions/SpotlightSearch.js.map +1 -1
  275. package/dist/ssr/actions/filter-messages.js +20 -0
  276. package/dist/ssr/actions/filter-messages.js.map +1 -0
  277. package/dist/ssr/actions/spotlight-messages.js +16 -0
  278. package/dist/ssr/actions/spotlight-messages.js.map +1 -0
  279. package/dist/ssr/chat/ChatComposer.js +47 -41
  280. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  281. package/dist/ssr/chat/ChatPrimitives.js +23 -21
  282. package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
  283. package/dist/ssr/chat/ChatRoot.js +3 -3
  284. package/dist/ssr/chat/ChatRoot.js.map +1 -1
  285. package/dist/ssr/chat/ChatTimeline.js +11 -11
  286. package/dist/ssr/chat/ChatTimeline.js.map +1 -1
  287. package/dist/ssr/chat/chat-messages.js +236 -0
  288. package/dist/ssr/chat/chat-messages.js.map +1 -0
  289. package/dist/ssr/content/Calendar.js +534 -346
  290. package/dist/ssr/content/Calendar.js.map +1 -1
  291. package/dist/ssr/content/CalendarDayView.js +800 -0
  292. package/dist/ssr/content/CalendarDayView.js.map +1 -0
  293. package/dist/ssr/content/CalendarWeekView.js +1069 -0
  294. package/dist/ssr/content/CalendarWeekView.js.map +1 -0
  295. package/dist/ssr/content/Chart.js +12 -5
  296. package/dist/ssr/content/Chart.js.map +1 -1
  297. package/dist/ssr/content/ChartExplorer.js +98 -37
  298. package/dist/ssr/content/ChartExplorer.js.map +1 -1
  299. package/dist/ssr/content/ChartExplorerControls.js +9 -7
  300. package/dist/ssr/content/ChartExplorerControls.js.map +1 -1
  301. package/dist/ssr/content/ChartFilterControls.js +52 -8
  302. package/dist/ssr/content/ChartFilterControls.js.map +1 -1
  303. package/dist/ssr/content/ChartSnapshotView.js +3 -3
  304. package/dist/ssr/content/ChartSnapshotView.js.map +1 -1
  305. package/dist/ssr/content/DataTable.js +77 -53
  306. package/dist/ssr/content/DataTable.js.map +1 -1
  307. package/dist/ssr/content/Docs.js +3 -1
  308. package/dist/ssr/content/Docs.js.map +1 -1
  309. package/dist/ssr/content/FileBrowser.js +30 -26
  310. package/dist/ssr/content/FileBrowser.js.map +1 -1
  311. package/dist/ssr/content/FileTree.js +9 -7
  312. package/dist/ssr/content/FileTree.js.map +1 -1
  313. package/dist/ssr/content/FileView.js +37 -28
  314. package/dist/ssr/content/FileView.js.map +1 -1
  315. package/dist/ssr/content/Lightbox.js +8 -6
  316. package/dist/ssr/content/Lightbox.js.map +1 -1
  317. package/dist/ssr/content/LogEntriesTable.js +3 -3
  318. package/dist/ssr/content/LogEntriesTable.js.map +1 -1
  319. package/dist/ssr/content/MessageRow.js +24 -22
  320. package/dist/ssr/content/MessageRow.js.map +1 -1
  321. package/dist/ssr/content/Pagination.js +6 -6
  322. package/dist/ssr/content/Pagination.js.map +1 -1
  323. package/dist/ssr/content/PdfPreview.js +15 -13
  324. package/dist/ssr/content/PdfPreview.js.map +1 -1
  325. package/dist/ssr/content/RangePicker.js +3 -1
  326. package/dist/ssr/content/RangePicker.js.map +1 -1
  327. package/dist/ssr/content/StructuredDataPreview.js +3 -1
  328. package/dist/ssr/content/StructuredDataPreview.js.map +1 -1
  329. package/dist/ssr/content/Timeline.js +13 -11
  330. package/dist/ssr/content/Timeline.js.map +1 -1
  331. package/dist/ssr/content/VideoPlayer.js +5 -5
  332. package/dist/ssr/content/VideoPlayer.js.map +1 -1
  333. package/dist/ssr/content/VirtualFeed.js +6 -4
  334. package/dist/ssr/content/VirtualFeed.js.map +1 -1
  335. package/dist/ssr/content/ZoomPanViewport.js +7 -4
  336. package/dist/ssr/content/ZoomPanViewport.js.map +1 -1
  337. package/dist/ssr/content/calendar-day-scroll.js +98 -0
  338. package/dist/ssr/content/calendar-day-scroll.js.map +1 -0
  339. package/dist/ssr/content/calendar-days.js +408 -0
  340. package/dist/ssr/content/calendar-days.js.map +1 -0
  341. package/dist/ssr/content/calendar-dialogs.js +159 -0
  342. package/dist/ssr/content/calendar-dialogs.js.map +1 -0
  343. package/dist/ssr/content/calendar-messages.js +249 -3
  344. package/dist/ssr/content/calendar-messages.js.map +1 -1
  345. package/dist/ssr/content/calendar-pointer.js +19 -6
  346. package/dist/ssr/content/calendar-pointer.js.map +1 -1
  347. package/dist/ssr/content/calendar-shared.js +261 -0
  348. package/dist/ssr/content/calendar-shared.js.map +1 -0
  349. package/dist/ssr/content/calendar-time-view.js +1306 -0
  350. package/dist/ssr/content/calendar-time-view.js.map +1 -0
  351. package/dist/ssr/content/chart-messages.js +146 -0
  352. package/dist/ssr/content/chart-messages.js.map +1 -0
  353. package/dist/ssr/content/collection-selection.js +2 -0
  354. package/dist/ssr/content/collection-selection.js.map +1 -1
  355. package/dist/ssr/content/data-table-messages.js +24 -0
  356. package/dist/ssr/content/data-table-messages.js.map +1 -0
  357. package/dist/ssr/content/docs-messages.js +24 -0
  358. package/dist/ssr/content/docs-messages.js.map +1 -0
  359. package/dist/ssr/content/feed-messages.js +34 -0
  360. package/dist/ssr/content/feed-messages.js.map +1 -0
  361. package/dist/ssr/content/file-browser-messages.js +69 -0
  362. package/dist/ssr/content/file-browser-messages.js.map +1 -0
  363. package/dist/ssr/content/file-view-messages.js +64 -0
  364. package/dist/ssr/content/file-view-messages.js.map +1 -0
  365. package/dist/ssr/content/index.js.map +1 -1
  366. package/dist/ssr/content/lightbox-messages.js +36 -0
  367. package/dist/ssr/content/lightbox-messages.js.map +1 -0
  368. package/dist/ssr/content/log-entries-messages.js +20 -0
  369. package/dist/ssr/content/log-entries-messages.js.map +1 -0
  370. package/dist/ssr/content/markdown-info-block-messages.js +24 -0
  371. package/dist/ssr/content/markdown-info-block-messages.js.map +1 -0
  372. package/dist/ssr/content/markdown-info-blocks.js +3 -3
  373. package/dist/ssr/content/markdown-info-blocks.js.map +1 -1
  374. package/dist/ssr/content/markdown-links.js +2 -2
  375. package/dist/ssr/content/markdown-links.js.map +1 -1
  376. package/dist/ssr/content/markdown-reference-messages.js +30 -0
  377. package/dist/ssr/content/markdown-reference-messages.js.map +1 -0
  378. package/dist/ssr/content/pagination-messages.js +38 -0
  379. package/dist/ssr/content/pagination-messages.js.map +1 -0
  380. package/dist/ssr/content/pdf-messages.js +43 -0
  381. package/dist/ssr/content/pdf-messages.js.map +1 -0
  382. package/dist/ssr/content/range-picker-messages.js +20 -0
  383. package/dist/ssr/content/range-picker-messages.js.map +1 -0
  384. package/dist/ssr/content/structured-data-messages.js +22 -0
  385. package/dist/ssr/content/structured-data-messages.js.map +1 -0
  386. package/dist/ssr/content/timeline-messages.js +62 -0
  387. package/dist/ssr/content/timeline-messages.js.map +1 -0
  388. package/dist/ssr/content/video-messages.js +24 -0
  389. package/dist/ssr/content/video-messages.js.map +1 -0
  390. package/dist/ssr/content/viewport-messages.js +28 -0
  391. package/dist/ssr/content/viewport-messages.js.map +1 -0
  392. package/dist/ssr/feedback/HoverPreview.js +34 -6
  393. package/dist/ssr/feedback/HoverPreview.js.map +1 -1
  394. package/dist/ssr/feedback/InstallGuide.js +18 -18
  395. package/dist/ssr/feedback/InstallGuide.js.map +1 -1
  396. package/dist/ssr/feedback/install-messages.js +104 -0
  397. package/dist/ssr/feedback/install-messages.js.map +1 -0
  398. package/dist/ssr/feedback/prompt-messages.js +65 -0
  399. package/dist/ssr/feedback/prompt-messages.js.map +1 -0
  400. package/dist/ssr/feedback/prompts.js +14 -11
  401. package/dist/ssr/feedback/prompts.js.map +1 -1
  402. package/dist/ssr/feedback/toast-messages.js +18 -0
  403. package/dist/ssr/feedback/toast-messages.js.map +1 -0
  404. package/dist/ssr/feedback/toast.js +4 -3
  405. package/dist/ssr/feedback/toast.js.map +1 -1
  406. package/dist/ssr/index.js +1 -1
  407. package/dist/ssr/index.js.map +1 -1
  408. package/dist/ssr/inputs/AutocompleteEditor.js +5 -3
  409. package/dist/ssr/inputs/AutocompleteEditor.js.map +1 -1
  410. package/dist/ssr/inputs/AutocompleteSelect.js +10 -8
  411. package/dist/ssr/inputs/AutocompleteSelect.js.map +1 -1
  412. package/dist/ssr/inputs/ChoiceGroups.js +4 -0
  413. package/dist/ssr/inputs/ChoiceGroups.js.map +1 -1
  414. package/dist/ssr/inputs/ChoiceInputs.js +5 -5
  415. package/dist/ssr/inputs/ChoiceInputs.js.map +1 -1
  416. package/dist/ssr/inputs/Combobox.js +3 -1
  417. package/dist/ssr/inputs/Combobox.js.map +1 -1
  418. package/dist/ssr/inputs/FileDropTarget.js +6 -6
  419. package/dist/ssr/inputs/FileDropTarget.js.map +1 -1
  420. package/dist/ssr/inputs/FileInputs.js +29 -20
  421. package/dist/ssr/inputs/FileInputs.js.map +1 -1
  422. package/dist/ssr/inputs/MultiSelectInput.js +7 -5
  423. package/dist/ssr/inputs/MultiSelectInput.js.map +1 -1
  424. package/dist/ssr/inputs/NumberInput.js +4 -2
  425. package/dist/ssr/inputs/NumberInput.js.map +1 -1
  426. package/dist/ssr/inputs/QrScanner.js +4 -4
  427. package/dist/ssr/inputs/QrScanner.js.map +1 -1
  428. package/dist/ssr/inputs/Select.js +7 -5
  429. package/dist/ssr/inputs/Select.js.map +1 -1
  430. package/dist/ssr/inputs/SelectChip.js +3 -3
  431. package/dist/ssr/inputs/SelectChip.js.map +1 -1
  432. package/dist/ssr/inputs/SignatureInput.js +9 -3
  433. package/dist/ssr/inputs/SignatureInput.js.map +1 -1
  434. package/dist/ssr/inputs/SpecialInputs.js +4 -2
  435. package/dist/ssr/inputs/SpecialInputs.js.map +1 -1
  436. package/dist/ssr/inputs/TagEditor.js +8 -6
  437. package/dist/ssr/inputs/TagEditor.js.map +1 -1
  438. package/dist/ssr/inputs/TagsInput.js +5 -5
  439. package/dist/ssr/inputs/TagsInput.js.map +1 -1
  440. package/dist/ssr/inputs/TemplateEditor.js +5 -5
  441. package/dist/ssr/inputs/TemplateEditor.js.map +1 -1
  442. package/dist/ssr/inputs/TextInput.js +3 -1
  443. package/dist/ssr/inputs/TextInput.js.map +1 -1
  444. package/dist/ssr/inputs/completion-messages.js +24 -0
  445. package/dist/ssr/inputs/completion-messages.js.map +1 -0
  446. package/dist/ssr/inputs/file-drop-messages.js +63 -0
  447. package/dist/ssr/inputs/file-drop-messages.js.map +1 -0
  448. package/dist/ssr/inputs/file-drop.js.map +1 -1
  449. package/dist/ssr/inputs/file-input-messages.js +60 -0
  450. package/dist/ssr/inputs/file-input-messages.js.map +1 -0
  451. package/dist/ssr/inputs/icon-messages.js +22 -0
  452. package/dist/ssr/inputs/icon-messages.js.map +1 -0
  453. package/dist/ssr/inputs/input-messages.js +38 -0
  454. package/dist/ssr/inputs/input-messages.js.map +1 -0
  455. package/dist/ssr/inputs/markdown/MarkdownEditor.js +9 -5
  456. package/dist/ssr/inputs/markdown/MarkdownEditor.js.map +1 -1
  457. package/dist/ssr/inputs/markdown/Toolbar.js +13 -13
  458. package/dist/ssr/inputs/markdown/Toolbar.js.map +1 -1
  459. package/dist/ssr/inputs/markdown/editor-messages.js +43 -0
  460. package/dist/ssr/inputs/markdown/editor-messages.js.map +1 -0
  461. package/dist/ssr/inputs/markdown/toolbar-messages.js +40 -0
  462. package/dist/ssr/inputs/markdown/toolbar-messages.js.map +1 -0
  463. package/dist/ssr/inputs/qr-messages.js +26 -0
  464. package/dist/ssr/inputs/qr-messages.js.map +1 -0
  465. package/dist/ssr/inputs/select-messages.js +63 -0
  466. package/dist/ssr/inputs/select-messages.js.map +1 -0
  467. package/dist/ssr/inputs/tag-messages.js +44 -0
  468. package/dist/ssr/inputs/tag-messages.js.map +1 -0
  469. package/dist/ssr/inputs/template-messages.js +22 -0
  470. package/dist/ssr/inputs/template-messages.js.map +1 -0
  471. package/dist/ssr/internal/render-error-messages.js +20 -0
  472. package/dist/ssr/internal/render-error-messages.js.map +1 -0
  473. package/dist/ssr/internal/render-error.js +3 -1
  474. package/dist/ssr/internal/render-error.js.map +1 -1
  475. package/dist/ssr/internal/text-selection.js +101 -0
  476. package/dist/ssr/internal/text-selection.js.map +1 -0
  477. package/dist/ssr/intl/messages.js +6 -1155
  478. package/dist/ssr/intl/messages.js.map +1 -1
  479. package/dist/ssr/layout/AppWorkspace.js +219 -103
  480. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  481. package/dist/ssr/layout/BottomSheet.js +1 -0
  482. package/dist/ssr/layout/BottomSheet.js.map +1 -1
  483. package/dist/ssr/layout/Discussion.js +8 -5
  484. package/dist/ssr/layout/Discussion.js.map +1 -1
  485. package/dist/ssr/layout/FloatingWindow.js +8 -5
  486. package/dist/ssr/layout/FloatingWindow.js.map +1 -1
  487. package/dist/ssr/layout/Navigation.js +6 -5
  488. package/dist/ssr/layout/Navigation.js.map +1 -1
  489. package/dist/ssr/layout/PageTitle.js +256 -0
  490. package/dist/ssr/layout/PageTitle.js.map +1 -0
  491. package/dist/ssr/layout/PanelDialog.js +8 -6
  492. package/dist/ssr/layout/PanelDialog.js.map +1 -1
  493. package/dist/ssr/layout/Panes.js +22 -14
  494. package/dist/ssr/layout/Panes.js.map +1 -1
  495. package/dist/ssr/layout/PullToRefresh.js +13 -4
  496. package/dist/ssr/layout/PullToRefresh.js.map +1 -1
  497. package/dist/ssr/layout/Settings.js +14 -12
  498. package/dist/ssr/layout/Settings.js.map +1 -1
  499. package/dist/ssr/layout/SettingsCollection.js +6 -5
  500. package/dist/ssr/layout/SettingsCollection.js.map +1 -1
  501. package/dist/ssr/layout/SettingsModal.js +3 -1
  502. package/dist/ssr/layout/SettingsModal.js.map +1 -1
  503. package/dist/ssr/layout/app-workspace-controller.js +821 -12
  504. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  505. package/dist/ssr/layout/app-workspace-state.js +3 -2
  506. package/dist/ssr/layout/app-workspace-state.js.map +1 -1
  507. package/dist/ssr/layout/floating-window-messages.js +28 -0
  508. package/dist/ssr/layout/floating-window-messages.js.map +1 -0
  509. package/dist/ssr/layout/index.js +2 -0
  510. package/dist/ssr/layout/index.js.map +1 -1
  511. package/dist/ssr/layout/navigation-model.js.map +1 -1
  512. package/dist/ssr/layout/page-title-controller.js +169 -0
  513. package/dist/ssr/layout/page-title-controller.js.map +1 -0
  514. package/dist/ssr/layout/panel-dialog-messages.js +20 -0
  515. package/dist/ssr/layout/panel-dialog-messages.js.map +1 -0
  516. package/dist/ssr/layout/panes-messages.js +48 -0
  517. package/dist/ssr/layout/panes-messages.js.map +1 -0
  518. package/dist/ssr/layout/refresh-messages.js +20 -0
  519. package/dist/ssr/layout/refresh-messages.js.map +1 -0
  520. package/dist/ssr/layout/settings-messages.js +54 -0
  521. package/dist/ssr/layout/settings-messages.js.map +1 -0
  522. package/dist/ssr/layout/workspace-messages.js +56 -0
  523. package/dist/ssr/layout/workspace-messages.js.map +1 -0
  524. package/dist/ssr/surfaces/Avatar.js +5 -5
  525. package/dist/ssr/surfaces/Avatar.js.map +1 -1
  526. package/dist/ssr/surfaces/ResourceCard.js +4 -2
  527. package/dist/ssr/surfaces/ResourceCard.js.map +1 -1
  528. package/dist/ssr/surfaces/StatCell.js +2 -2
  529. package/dist/ssr/surfaces/StatCell.js.map +1 -1
  530. package/dist/ssr/surfaces/Tag.js +3 -3
  531. package/dist/ssr/surfaces/Tag.js.map +1 -1
  532. package/dist/ssr/surfaces/avatar-messages.js +26 -0
  533. package/dist/ssr/surfaces/avatar-messages.js.map +1 -0
  534. package/dist/ssr/surfaces/resource-messages.js +26 -0
  535. package/dist/ssr/surfaces/resource-messages.js.map +1 -0
  536. package/dist/ssr/widgets/Widget.js +6 -0
  537. package/dist/ssr/widgets/Widget.js.map +1 -1
  538. package/dist/styles.css +1 -1
  539. package/dist/types/actions/filter-messages.d.ts +8 -0
  540. package/dist/types/actions/spotlight-messages.d.ts +8 -0
  541. package/dist/types/chat/chat-messages.d.ts +116 -0
  542. package/dist/types/content/Calendar.d.ts +91 -0
  543. package/dist/types/content/CalendarDayView.d.ts +7 -0
  544. package/dist/types/content/CalendarWeekView.d.ts +7 -0
  545. package/dist/types/content/ChartExplorer.d.ts +36 -1
  546. package/dist/types/content/ChartFilterControls.d.ts +6 -1
  547. package/dist/types/content/DataTable.d.ts +7 -0
  548. package/dist/types/content/FileView.d.ts +0 -10
  549. package/dist/types/content/calendar-day-scroll.d.ts +42 -0
  550. package/dist/types/content/calendar-days.d.ts +192 -0
  551. package/dist/types/content/calendar-dialogs.d.ts +22 -0
  552. package/dist/types/content/calendar-messages.d.ts +119 -1
  553. package/dist/types/content/calendar-pointer.d.ts +9 -0
  554. package/dist/types/content/calendar-shared.d.ts +69 -0
  555. package/dist/types/content/calendar-time-view.d.ts +252 -0
  556. package/dist/types/content/chart-messages.d.ts +37 -0
  557. package/dist/types/content/data-table-messages.d.ts +10 -0
  558. package/dist/types/content/docs-messages.d.ts +10 -0
  559. package/dist/types/content/feed-messages.d.ts +15 -0
  560. package/dist/types/content/file-browser-messages.d.ts +33 -0
  561. package/dist/types/content/file-view-messages.d.ts +30 -0
  562. package/dist/types/content/index.d.ts +2 -2
  563. package/dist/types/content/lightbox-messages.d.ts +16 -0
  564. package/dist/types/content/log-entries-messages.d.ts +8 -0
  565. package/dist/types/content/markdown-info-block-messages.d.ts +12 -0
  566. package/dist/types/content/markdown-reference-messages.d.ts +15 -0
  567. package/dist/types/content/pagination-messages.d.ts +17 -0
  568. package/dist/types/content/pdf-messages.d.ts +20 -0
  569. package/dist/types/content/range-picker-messages.d.ts +8 -0
  570. package/dist/types/content/structured-data-messages.d.ts +9 -0
  571. package/dist/types/content/timeline-messages.d.ts +29 -0
  572. package/dist/types/content/video-messages.d.ts +10 -0
  573. package/dist/types/content/viewport-messages.d.ts +12 -0
  574. package/dist/types/feedback/install-messages.d.ts +50 -0
  575. package/dist/types/feedback/prompt-messages.d.ts +31 -0
  576. package/dist/types/feedback/toast-messages.d.ts +9 -0
  577. package/dist/types/index.d.ts +1 -0
  578. package/dist/types/inputs/completion-messages.d.ts +10 -0
  579. package/dist/types/inputs/file-drop-messages.d.ts +30 -0
  580. package/dist/types/inputs/file-drop.d.ts +3 -3
  581. package/dist/types/inputs/file-input-messages.d.ts +28 -0
  582. package/dist/types/inputs/icon-messages.d.ts +9 -0
  583. package/dist/types/inputs/input-messages.d.ts +17 -0
  584. package/dist/types/inputs/markdown/editor-messages.d.ts +20 -0
  585. package/dist/types/inputs/markdown/toolbar-messages.d.ts +18 -0
  586. package/dist/types/inputs/qr-messages.d.ts +11 -0
  587. package/dist/types/inputs/select-messages.d.ts +30 -0
  588. package/dist/types/inputs/tag-messages.d.ts +20 -0
  589. package/dist/types/inputs/template-messages.d.ts +9 -0
  590. package/dist/types/internal/render-error-messages.d.ts +8 -0
  591. package/dist/types/internal/text-selection.d.ts +18 -0
  592. package/dist/types/intl/messages.d.ts +3 -544
  593. package/dist/types/layout/AppWorkspace.d.ts +42 -5
  594. package/dist/types/layout/PageTitle.d.ts +65 -0
  595. package/dist/types/layout/app-workspace-controller.d.ts +12 -0
  596. package/dist/types/layout/app-workspace-state.d.ts +3 -2
  597. package/dist/types/layout/floating-window-messages.d.ts +12 -0
  598. package/dist/types/layout/index.d.ts +3 -0
  599. package/dist/types/layout/navigation-model.d.ts +7 -0
  600. package/dist/types/layout/page-title-controller.d.ts +13 -0
  601. package/dist/types/layout/panel-dialog-messages.d.ts +8 -0
  602. package/dist/types/layout/panes-messages.d.ts +22 -0
  603. package/dist/types/layout/refresh-messages.d.ts +8 -0
  604. package/dist/types/layout/settings-messages.d.ts +25 -0
  605. package/dist/types/layout/workspace-messages.d.ts +26 -0
  606. package/dist/types/surfaces/StatCell.d.ts +5 -0
  607. package/dist/types/surfaces/avatar-messages.d.ts +11 -0
  608. package/dist/types/surfaces/resource-messages.d.ts +11 -0
  609. package/dist/types/widgets/Widget.d.ts +5 -1
  610. package/package.json +1 -1
@@ -0,0 +1,1306 @@
1
+ import { ssrStyle as _$ssrStyle } from "solid-js/web";
2
+ import { memo as _$memo } from "solid-js/web";
3
+ import { ssrStyleProperty as _$ssrStyleProperty } from "solid-js/web";
4
+ import { createComponent as _$createComponent } from "solid-js/web";
5
+ import { escape as _$escape } from "solid-js/web";
6
+ import { ssrAttribute as _$ssrAttribute } from "solid-js/web";
7
+ import { ssr as _$ssr } from "solid-js/web";
8
+ var _tmpl$ = "<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><rect x=\"1.75\" y=\"1.75\" width=\"12.5\" height=\"12.5\" rx=\"3.5\"></rect><path d=\"M4.6 8.3l2.3 2.3 4.6-4.9\"></path></svg>",
9
+ _tmpl$2 = ["<button type=\"button\" class=\"k2b-calendar-check\" role=\"checkbox\"", ">", "</button>"],
10
+ _tmpl$3 = ["<span class=\"k2b-calendar-check\"", " aria-hidden=\"true\">", "</span>"],
11
+ _tmpl$4 = "<span class=\"k2b-calendar-band__fill\" aria-hidden=\"true\"></span>",
12
+ _tmpl$5 = "<span class=\"k2b-calendar-band__grip\" data-edge=\"start\" aria-hidden=\"true\"></span>",
13
+ _tmpl$6 = "<span class=\"k2b-calendar-band__grip\" data-edge=\"end\" aria-hidden=\"true\"></span>",
14
+ _tmpl$7 = ["<div class=\"k2b-calendar-band\"", " style=\"", "\">", "", "", "", "</div>"],
15
+ _tmpl$8 = ["<div class=\"k2b-calendar-marker\"", " style=\"", "\"><span class=\"k2b-calendar-marker__line\" aria-hidden=\"true\"></span><span class=\"k2b-calendar-marker__pill\">", "", "</span></div>"],
16
+ _tmpl$9 = ["<span class=\"k2b-calendar-marker__time\">", "</span>"],
17
+ _tmpl$0 = ["<button type=\"button\" class=\"k2b-calendar-gap__button\"", "><i class=\"ti ti-plus\" aria-hidden=\"true\"></i><span class=\"k2b-calendar-gap__text\">", "</span></button>"],
18
+ _tmpl$1 = ["<div class=\"k2b-calendar-gap\"", " style=\"", "\"><span class=\"k2b-calendar-gap__zone\" aria-hidden=\"true\"></span>", "</div>"],
19
+ _tmpl$10 = ["<span class=\"k2b-calendar-slot\" style=\"", "\" aria-hidden=\"true\"></span>"],
20
+ _tmpl$11 = ["<div class=\"k2b-calendar-draft\" style=\"", "\"><span class=\"k2b-calendar-draft__grip\" data-edge=\"start\" aria-hidden=\"true\"></span><button type=\"button\" class=\"k2b-calendar-draft__open\"", "><i class=\"ti ti-plus\" aria-hidden=\"true\"></i><span>", "–", " · ", "</span></button><span class=\"k2b-calendar-draft__grip\" data-edge=\"end\" aria-hidden=\"true\"></span></div>"],
21
+ _tmpl$12 = ["<div class=\"k2b-calendar-ghost\" data-live=\"true\"", " style=\"", "\" aria-hidden=\"true\"><span class=\"k2b-calendar-ghost__title\">", "</span><span class=\"k2b-calendar-ghost__time\">", "</span>", "</div>"],
22
+ _tmpl$13 = ["<span class=\"k2b-calendar-ghost__fit\"", ">", "</span>"],
23
+ _tmpl$14 = ["<div class=\"k2b-calendar-popover\" popover=\"auto\" role=\"dialog\"", " data-kind=\"create\">", "</div>"],
24
+ _tmpl$15 = ["<span class=\"k2b-calendar-allday-chip\"", " style=\"", "\">", "", "</span>"];
25
+ import { dates as calendar } from "@k2b/stdlib";
26
+ import { createEffect, createMemo, createSignal, For, on, onCleanup, onMount, Show, untrack } from "solid-js";
27
+ import { announce } from "../feedback/announce";
28
+ import { addDayKeys, buildDays, clockAt, DAY_MINUTES, dayKeyOf, dayLanes, dayMinuteAt, dayTopTerms, dayYTerms, freeGaps, GAP_LABEL_MINUTES, GAP_LONG_MINUTES, gapProposal, instantInDay, instantsInDay, minuteInDay, readDayGeometry, resizedInDay, snapMinutes, subtractTerms, termsCss, wakeMinutes } from "./calendar-days";
29
+ import { useCalendarMessages } from "./calendar-messages";
30
+ import { startCalendarPointerSession } from "./calendar-pointer";
31
+ import { EventChip, eventHref, ownerDateConfig, parseDate, placeCalendarPopover, validDate } from "./calendar-shared";
32
+
33
+ /**
34
+ * Shared state and parts of the day and week views with `dayHours`: the time model of the loaded days, the selection,
35
+ * the quick create, pointer gestures, and the pieces both views draw into a day's timeline.
36
+ */
37
+
38
+ /** What the header and the calendar's controller ask of the active day or week view. */
39
+
40
+ const COLOR_TOKENS = {
41
+ blue: "#3b82f6",
42
+ emerald: "#10b981",
43
+ amber: "#f59e0b",
44
+ red: "#ef4444",
45
+ violet: "#8b5cf6",
46
+ cyan: "#06b6d4",
47
+ zinc: "#a1a1aa"
48
+ };
49
+ export const eventAccent = event => event.colorHex ?? COLOR_TOKENS[event.color ?? "blue"];
50
+
51
+ /** Minimum minutes an overlap counts for a band, about the height of its title. */
52
+ const LANE_MINUTES = 20;
53
+ export const reducedMotion = () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
54
+
55
+ /** Swallows the click a browser sends right after a gesture ends, never the next one. */
56
+ export const swallowNextClick = () => {
57
+ const stop = event => {
58
+ event.stopPropagation();
59
+ event.preventDefault();
60
+ };
61
+ window.addEventListener("click", stop, {
62
+ capture: true,
63
+ once: true
64
+ });
65
+ window.setTimeout(() => window.removeEventListener("click", stop, {
66
+ capture: true
67
+ }), 120);
68
+ };
69
+ export const createTimeView = props => {
70
+ const messages = useCalendarMessages();
71
+ const dateConfig = createMemo(() => ownerDateConfig(props.owner));
72
+ const hours = () => props.hours;
73
+ const wake = createMemo(() => wakeMinutes(props.hours));
74
+ const keyOf = date => calendar.formatDateKey(date, dateConfig());
75
+ const parseKey = key => calendar.parseCalendarDate(key, dateConfig());
76
+
77
+ /** The loaded days: the host's range, or the day or the week of the date. */
78
+ const range = createMemo(() => {
79
+ const context = dateConfig();
80
+ const loaded = props.owner.range;
81
+ if (loaded) {
82
+ const from = parseDate(loaded.from, context);
83
+ const to = parseDate(loaded.to, context);
84
+ if (validDate(from) && validDate(to)) {
85
+ const first = calendar.formatDateKey(from, context);
86
+ const last = calendar.formatDateKey(new Date(Math.max(from.getTime(), to.getTime() - 1)), context);
87
+ return {
88
+ first,
89
+ last
90
+ };
91
+ }
92
+ }
93
+ const key = calendar.formatDateKey(props.date, context);
94
+ if (props.view === "day") return {
95
+ first: key,
96
+ last: key
97
+ };
98
+ const start = calendar.formatDateKey(calendar.startOfWeek(props.date, context), context);
99
+ return {
100
+ first: start,
101
+ last: addDayKeys(start, 6)
102
+ };
103
+ }, undefined, {
104
+ equals: (left, right) => left.first === right.first && left.last === right.last
105
+ });
106
+ const anchorKey = createMemo(() => keyOf(props.date));
107
+
108
+ /** Checkbox states the reader just set, shown until the host's events agree or drop the entry. */
109
+ const [checks, setChecks] = createSignal({});
110
+ const [justChecked, setJustChecked] = createSignal(new Set());
111
+ createEffect(on(() => props.events, events => {
112
+ const current = untrack(checks);
113
+ const ids = Object.keys(current);
114
+ if (ids.length === 0) return;
115
+ const next = {
116
+ ...current
117
+ };
118
+ for (const id of ids) {
119
+ const event = events.find(candidate => candidate.id === id);
120
+ if (!event || event.checked === current[id]) delete next[id];
121
+ }
122
+ setChecks(next);
123
+ }, {
124
+ defer: true
125
+ }));
126
+ const checkedOf = event => event.checked === undefined ? undefined : checks()[event.id] ?? event.checked;
127
+ /** What Space on an entry's chip does: check its box, where it has one the reader may change. */
128
+ const checkOf = event => checkedOf(event) !== undefined && props.owner.onEventCheck ? () => toggleCheck(event) : undefined;
129
+ const forgetJustChecked = id => setJustChecked(value => {
130
+ if (!value.has(id)) return value;
131
+ const rest = new Set(value);
132
+ rest.delete(id);
133
+ return rest;
134
+ });
135
+ /** Today's day for a moment after its last open to-do was checked off, which its heading celebrates. */
136
+ const [cheered, setCheered] = createSignal(null);
137
+ let cheerTimer = 0;
138
+ // The server renders the view too, and has no window.
139
+ onCleanup(() => clearTimeout(cheerTimer));
140
+ /** The entries with a checkbox on a day: its deadlines, the to-dos planned into its hours, and the ones due all day. */
141
+ const dueOn = key => {
142
+ const model = dayOf(key);
143
+ return [...model.markers.map(marker => marker.item), ...model.bands.map(band => band.item), ...model.spans.filter(span => span.marker && span.firstKey === key).map(span => span.item)].filter(item => item.checked !== undefined);
144
+ };
145
+ const toggleCheck = event => {
146
+ const current = checkedOf(event);
147
+ if (current === undefined || !props.owner.onEventCheck) return;
148
+ const next = !current;
149
+ setChecks(value => ({
150
+ ...value,
151
+ [event.id]: next
152
+ }));
153
+ if (next) {
154
+ setJustChecked(value => new Set([...value, event.id]));
155
+ window.setTimeout(() => forgetJustChecked(event.id), 1100);
156
+ const today = nowKey();
157
+ const due = dueOn(today);
158
+ if (due.includes(event) && due.every(item => checkedOf(item))) {
159
+ // The heading shows it only for a moment, so a screen reader hears it once instead.
160
+ announce(messages().calendarAllDone);
161
+ setCheered(today);
162
+ window.clearTimeout(cheerTimer);
163
+ cheerTimer = window.setTimeout(() => setCheered(null), 2200);
164
+ }
165
+ } else setCheered(null);
166
+ // A change the host refuses puts the box back as it was.
167
+ void Promise.resolve(props.owner.onEventCheck(event, next)).catch(() => {
168
+ forgetJustChecked(event.id);
169
+ if (next) setCheered(null);
170
+ setChecks(value => {
171
+ if (value[event.id] !== next) return value;
172
+ const rest = {
173
+ ...value
174
+ };
175
+ delete rest[event.id];
176
+ return rest;
177
+ });
178
+ });
179
+ };
180
+ const entries = createMemo(() => {
181
+ const context = dateConfig();
182
+ return props.events.flatMap(event => {
183
+ const start = parseDate(event.start, context);
184
+ if (!validDate(start)) return [];
185
+ const marker = event.display === "marker";
186
+ const parsedEnd = event.end ? parseDate(event.end, context) : null;
187
+ let end = parsedEnd && validDate(parsedEnd) && parsedEnd > start ? parsedEnd : null;
188
+ if (!end) end = event.allDay ? calendar.addDays(calendar.startOfDay(start, context), 1, context) : marker ? start : new Date(start.getTime() + 3_600_000);
189
+ return [{
190
+ item: event,
191
+ start,
192
+ end,
193
+ allDay: Boolean(event.allDay),
194
+ marker
195
+ }];
196
+ });
197
+ });
198
+ const days = createMemo(() => buildDays(range().first, range().last, entries(), props.hours, dateConfig()));
199
+ const emptyModel = key => ({
200
+ key,
201
+ bands: [],
202
+ markers: [],
203
+ spans: [],
204
+ night: false,
205
+ empty: true
206
+ });
207
+ const dayOf = key => days().get(key) ?? emptyModel(key);
208
+ const sourceOf = createMemo(() => new Map(entries().map(entry => [entry.item, entry])));
209
+
210
+ /** The day that holds now: before the start hour still the day before. */
211
+ const nowKey = createMemo(() => dayKeyOf(props.now, props.hours, dateConfig()));
212
+ const nowMinute = createMemo(() => minuteInDay(nowKey(), props.now, props.hours, dateConfig()));
213
+ /** Now as a minute of a day: past days lie wholly before it, coming days after. */
214
+ const nowIn = key => key === nowKey() ? nowMinute() : key < nowKey() ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
215
+ const calendarToday = createMemo(() => keyOf(props.now));
216
+ const clock = minute => clockAt(minute, props.hours);
217
+ const duration = minutes => messages().calendarDuration({
218
+ minutes: Math.max(1, Math.round(minutes))
219
+ });
220
+ const instant = (key, minute) => instantInDay(key, minute, props.hours, dateConfig());
221
+ const slot = (key, start, end) => instantsInDay(key, start, end, props.hours, dateConfig());
222
+ const dayStartMinute = hour => Math.max(0, (hour - props.hours[0]) * 60);
223
+
224
+ /** A day's timed piece as the event chip reads it. */
225
+ const normalized = (event, key) => {
226
+ const source = sourceOf().get(event);
227
+ const start = source?.start ?? parseDate(event.start, dateConfig());
228
+ const end = source?.end ?? start;
229
+ return {
230
+ ...event,
231
+ startDate: start,
232
+ endDate: end,
233
+ sourceStartDate: start,
234
+ sourceEndDate: end,
235
+ dayKey: key
236
+ };
237
+ };
238
+ const [selection, setSelection] = createSignal(null);
239
+ const [touchDraft, setTouchDraft] = createSignal(null);
240
+ const [activeKey, setActiveKey] = createSignal(null);
241
+ const [ghost, setGhost] = createSignal(null);
242
+ const [movingId, setMovingId] = createSignal("");
243
+ const [dragging, setDragging] = createSignal("");
244
+ const [nightOverrides, setNightOverrides] = createSignal({});
245
+ const [quick, setQuick] = createSignal(null);
246
+ const rangeOfSelection = value => value.start === undefined || value.end === undefined ? {
247
+ start: parseKey(value.key),
248
+ end: calendar.addDays(parseKey(value.key), 1, dateConfig()),
249
+ allDay: true
250
+ } : {
251
+ ...slot(value.key, value.start, value.end),
252
+ allDay: false
253
+ };
254
+ createEffect(on(selection, value => props.owner.onSelectionChange?.(value ? rangeOfSelection(value) : null), {
255
+ defer: true
256
+ }));
257
+ onCleanup(() => {
258
+ if (untrack(selection)) props.owner.onSelectionChange?.(null);
259
+ });
260
+
261
+ // Body elements of the days on screen, for pointer positions.
262
+ const bodies = new Map();
263
+ const registerBody = (key, element, expanded) => {
264
+ bodies.set(key, {
265
+ element,
266
+ expanded
267
+ });
268
+ onCleanup(() => {
269
+ if (bodies.get(key)?.element === element) bodies.delete(key);
270
+ });
271
+ };
272
+ const bodyAt = (clientX, clientY) => {
273
+ for (const [key, body] of bodies) {
274
+ if (!body.element.isConnected) continue;
275
+ const rect = body.element.getBoundingClientRect();
276
+ if (clientX < rect.left || clientX >= rect.right || clientY < rect.top || clientY >= rect.bottom) continue;
277
+ const geometry = readDayGeometry(body.element, wake(), body.expanded());
278
+ return {
279
+ key,
280
+ element: body.element,
281
+ geometry,
282
+ minute: dayMinuteAt(geometry, clientY - rect.top)
283
+ };
284
+ }
285
+ return null;
286
+ };
287
+ const limitOf = key => bodies.get(key)?.expanded() ? DAY_MINUTES : wake();
288
+ const nightOpen = (key, model) => nightOverrides()[key] ?? model.night;
289
+ const setNight = (key, open) => setNightOverrides(value => ({
290
+ ...value,
291
+ [key]: open
292
+ }));
293
+
294
+ /** The gap under a minute while dragging, and whether `need` minutes fit it; the gap shows "fits" or how much is missing. */
295
+ const fitAt = (key, minute, need, span) => {
296
+ const gap = freeGaps(dayOf(key).bands, wake(), Number.NEGATIVE_INFINITY).find(candidate => minute >= candidate.start && minute < candidate.end);
297
+ if (!gap) return null;
298
+ const fits = gap.end - gap.start >= need;
299
+ if (fits && span && (span.start < gap.start || span.end > gap.end)) return null;
300
+ return {
301
+ gap,
302
+ fits,
303
+ text: fits ? messages().calendarFits : messages().calendarTooShort({
304
+ duration: duration(need - (gap.end - gap.start))
305
+ })
306
+ };
307
+ };
308
+ const [gapHit, setGapHit] = createSignal(null);
309
+ const overlapAt = (key, start, end, except) => dayOf(key).bands.find(band => band.item.id !== except && band.start < end && band.end > start)?.item ?? null;
310
+ const openQuickCreate = (key, start, end, anchor, create) => {
311
+ const range = rangeOfSelection({
312
+ key,
313
+ start,
314
+ end
315
+ });
316
+ setTouchDraft(null);
317
+ if (!props.owner.renderQuickCreate) {
318
+ props.owner.onSlotActivate?.(range);
319
+ return;
320
+ }
321
+ setSelection({
322
+ key,
323
+ start,
324
+ end
325
+ });
326
+ setQuick({
327
+ range,
328
+ anchor,
329
+ create,
330
+ key,
331
+ start,
332
+ end
333
+ });
334
+ };
335
+ const canCreate = () => Boolean(props.owner.renderQuickCreate || props.owner.onSlotActivate);
336
+
337
+ /** The time a new entry takes: the selection, today's next full hour while today shows, else 09:00 of the first day. */
338
+ const createTarget = visible => {
339
+ const current = selection();
340
+ if (current && current.start !== undefined && current.end !== undefined) return {
341
+ key: current.key,
342
+ start: current.start,
343
+ end: current.end
344
+ };
345
+ const nine = dayStartMinute(9);
346
+ const nextHour = key => {
347
+ const minute = Math.ceil((nowMinute() + 1) / 60) * 60;
348
+ return key === nowKey() ? minute <= wake() - 60 ? minute : null : nine;
349
+ };
350
+ let key;
351
+ let start;
352
+ if (current) {
353
+ key = current.key;
354
+ start = key === nowKey() ? nextHour(key) : nine;
355
+ } else if (nowKey() >= visible.first && nowKey() <= visible.last) {
356
+ key = nowKey();
357
+ start = nextHour(key);
358
+ } else {
359
+ key = visible.first;
360
+ start = nine;
361
+ }
362
+ if (start === null) {
363
+ key = addDayKeys(key, 1);
364
+ start = nine;
365
+ }
366
+ return {
367
+ key,
368
+ start,
369
+ end: start + 60
370
+ };
371
+ };
372
+
373
+ // Pointer gestures: moving and resizing bands and markers, drawing a new event, and dragging entries in.
374
+ let cancelGesture;
375
+ onCleanup(() => cancelGesture?.());
376
+ const step = event => event.shiftKey ? 5 : 15;
377
+ const shiftHeld = {
378
+ current: false
379
+ };
380
+ const trackShift = event => {
381
+ shiftHeld.current = event.shiftKey;
382
+ };
383
+ onMount(() => {
384
+ window.addEventListener("keydown", trackShift, true);
385
+ window.addEventListener("keyup", trackShift, true);
386
+ onCleanup(() => {
387
+ window.removeEventListener("keydown", trackShift, true);
388
+ window.removeEventListener("keyup", trackShift, true);
389
+ });
390
+ });
391
+ const endGesture = () => {
392
+ setGhost(null);
393
+ setGapHit(null);
394
+ setMovingId("");
395
+ setDragging("");
396
+ };
397
+ const startMove = (pointerEvent, event, key, start, end, scroller) => {
398
+ const marker = event.display === "marker";
399
+ if (!props.owner.onEventDrop) return;
400
+ const body = bodies.get(key);
401
+ if (!body) return;
402
+ const rect = body.element.getBoundingClientRect();
403
+ const geometry = readDayGeometry(body.element, wake(), body.expanded());
404
+ const grab = dayMinuteAt(geometry, pointerEvent.clientY - rect.top) - start;
405
+ const length = end - start;
406
+ cancelGesture?.();
407
+ cancelGesture = startCalendarPointerSession({
408
+ event: pointerEvent,
409
+ scrollContainer: scroller,
410
+ resolve: (clientX, clientY) => {
411
+ const hit = bodyAt(clientX, clientY);
412
+ if (!hit) return null;
413
+ const limit = limitOf(hit.key);
414
+ const from = Math.max(0, Math.min(limit - Math.max(length, 15), snapMinutes(hit.minute - grab, step({
415
+ shiftKey: shiftHeld.current
416
+ }))));
417
+ return {
418
+ key: hit.key,
419
+ start: from,
420
+ end: from + length
421
+ };
422
+ },
423
+ onActivate: () => {
424
+ setMovingId(event.id);
425
+ setDragging("move");
426
+ setSelection(null);
427
+ },
428
+ onPreview: next => {
429
+ const clash = marker ? null : overlapAt(next.key, next.start, next.end, event.id);
430
+ const fit = marker ? null : fitAt(next.key, next.start + (next.end - next.start) / 2, next.end - next.start, next);
431
+ setGapHit(fit ? {
432
+ key: next.key,
433
+ start: fit.gap.start,
434
+ fits: fit.fits,
435
+ text: fit.text
436
+ } : null);
437
+ const time = marker ? messages().calendarDue({
438
+ time: clock(next.start)
439
+ }) : `${clock(next.start)}–${clock(next.end)} · ${duration(next.end - next.start)}`;
440
+ setGhost({
441
+ key: next.key,
442
+ start: next.start,
443
+ end: marker ? next.start + 20 : next.end,
444
+ title: event.title,
445
+ time: clash ? `${time} · ${messages().calendarOverlaps({
446
+ title: clash.title
447
+ })}` : time,
448
+ colorHex: eventAccent(event),
449
+ warn: Boolean(clash),
450
+ fit: fit ? {
451
+ fits: fit.fits,
452
+ text: fit.text
453
+ } : undefined
454
+ });
455
+ },
456
+ onCommit: next => {
457
+ endGesture();
458
+ swallowNextClick();
459
+ if (next.key === key && next.start === start && next.end === end) return;
460
+ const source = sourceOf().get(event);
461
+ // A moved entry keeps its real length, also when it lands across a clock change.
462
+ const startDate = instant(next.key, next.start);
463
+ const endDate = marker ? startDate : source ? new Date(startDate.getTime() + source.end.getTime() - source.start.getTime()) : slot(next.key, next.start, next.end).end;
464
+ if (source && source.start.getTime() === startDate.getTime() && source.end.getTime() === endDate.getTime()) return;
465
+ props.owner.onEventDrop?.(event, {
466
+ start: startDate,
467
+ end: endDate,
468
+ allDay: false
469
+ });
470
+ },
471
+ onCancel: endGesture
472
+ });
473
+ };
474
+ const startResize = (pointerEvent, event, key, start, end, edge, scroller) => {
475
+ if (!props.owner.onEventResize) return;
476
+ pointerEvent.preventDefault();
477
+ pointerEvent.stopPropagation();
478
+ const body = bodies.get(key);
479
+ if (!body) return;
480
+ cancelGesture?.();
481
+ cancelGesture = startCalendarPointerSession({
482
+ event: pointerEvent,
483
+ scrollContainer: scroller,
484
+ threshold: 1,
485
+ resolve: (_clientX, clientY) => {
486
+ const rect = body.element.getBoundingClientRect();
487
+ const geometry = readDayGeometry(body.element, wake(), body.expanded());
488
+ const minute = snapMinutes(dayMinuteAt(geometry, clientY - rect.top), step({
489
+ shiftKey: shiftHeld.current
490
+ }));
491
+ const limit = limitOf(key);
492
+ const size = step({
493
+ shiftKey: shiftHeld.current
494
+ });
495
+ return edge === "end" ? {
496
+ start,
497
+ end: Math.max(start + size, Math.min(limit, minute))
498
+ } : {
499
+ start: Math.max(0, Math.min(end - size, minute)),
500
+ end
501
+ };
502
+ },
503
+ onActivate: () => {
504
+ setMovingId(event.id);
505
+ setDragging(edge);
506
+ },
507
+ onPreview: next => setGhost({
508
+ key,
509
+ start: next.start,
510
+ end: next.end,
511
+ title: event.title,
512
+ time: `${clock(next.start)}–${clock(next.end)} · ${duration(next.end - next.start)}`,
513
+ colorHex: eventAccent(event)
514
+ }),
515
+ onCommit: next => {
516
+ endGesture();
517
+ swallowNextClick();
518
+ if (next.start === start && next.end === end) return;
519
+ const source = sourceOf().get(event);
520
+ const range = source ? resizedInDay(source, edge, key, next, props.hours, dateConfig()) : slot(key, next.start, next.end);
521
+ props.owner.onEventResize?.(event, {
522
+ ...range,
523
+ allDay: false
524
+ });
525
+ },
526
+ onCancel: endGesture
527
+ });
528
+ };
529
+
530
+ /** Drawing on free time: a new event with its live length, on a 15-minute grid, with Shift on 5 minutes. */
531
+ const startDraw = (pointerEvent, key, scroller) => {
532
+ if (!canCreate() || pointerEvent.pointerType !== "mouse") return;
533
+ const body = bodies.get(key);
534
+ if (!body) return;
535
+ const minuteAt = clientY => {
536
+ const rect = body.element.getBoundingClientRect();
537
+ const geometry = readDayGeometry(body.element, wake(), body.expanded());
538
+ return Math.max(0, Math.min(limitOf(key), dayMinuteAt(geometry, clientY - rect.top)));
539
+ };
540
+ const origin = minuteAt(pointerEvent.clientY);
541
+ cancelGesture?.();
542
+ cancelGesture = startCalendarPointerSession({
543
+ event: pointerEvent,
544
+ scrollContainer: scroller,
545
+ resolve: (_clientX, clientY) => {
546
+ const size = step({
547
+ shiftKey: shiftHeld.current
548
+ });
549
+ const minute = minuteAt(clientY);
550
+ const from = Math.floor(Math.min(origin, minute) / size) * size;
551
+ let to = Math.ceil(Math.max(origin, minute) / size) * size;
552
+ if (to - from < size) to = from + size;
553
+ return {
554
+ start: from,
555
+ end: Math.min(to, limitOf(key))
556
+ };
557
+ },
558
+ onActivate: () => {
559
+ setDragging("draw");
560
+ setSelection(null);
561
+ setTouchDraft(null);
562
+ },
563
+ onPreview: next => setGhost({
564
+ key,
565
+ start: next.start,
566
+ end: next.end,
567
+ title: messages().calendarNewEvent,
568
+ time: `${clock(next.start)}–${clock(next.end)} · ${duration(next.end - next.start)}`
569
+ }),
570
+ onCommit: next => {
571
+ const anchor = document.querySelector(".k2b-calendar-ghost[data-live]")?.getBoundingClientRect() ?? body.element;
572
+ endGesture();
573
+ swallowNextClick();
574
+ openQuickCreate(key, next.start, next.end, anchor);
575
+ },
576
+ onCancel: endGesture
577
+ });
578
+ };
579
+
580
+ /** Follows a pointer that pressed an entry outside the calendar into its free time. */
581
+ const dragIn = (pointerEvent, item, onDrop, scroller) => {
582
+ if (pointerEvent.button !== 0 || !pointerEvent.isPrimary) return;
583
+ cancelGesture?.();
584
+ cancelGesture = undefined;
585
+ const length = Math.max(15, Math.round(item.minutes));
586
+ const color = item.colorHex ?? COLOR_TOKENS[item.color ?? "blue"];
587
+ let token;
588
+ let spring;
589
+ const target = pointerEvent.target instanceof HTMLElement ? pointerEvent.target.closest("li, [data-calendar-drag-source]") : null;
590
+ let held = false;
591
+ let cleaned = false;
592
+ const preventContextMenu = event => event.preventDefault();
593
+ const preventScroll = event => {
594
+ if (held) event.preventDefault();
595
+ };
596
+ const cleanup = () => {
597
+ if (cleaned) return;
598
+ cleaned = true;
599
+ document.removeEventListener("touchmove", preventScroll);
600
+ window.removeEventListener("contextmenu", preventContextMenu, true);
601
+ if (pointerEvent.pointerType === "touch") held = false;
602
+ if (target) delete target.dataset.lifted;
603
+ token?.remove();
604
+ token = undefined;
605
+ if (spring) window.clearTimeout(spring.timer);
606
+ spring = undefined;
607
+ endGesture();
608
+ };
609
+ const begin = () => {
610
+ cancelGesture = startCalendarPointerSession({
611
+ event: pointerEvent,
612
+ scrollContainer: scroller,
613
+ armAutoScroll: true,
614
+ threshold: held && pointerEvent.pointerType !== "mouse" ? 1 : 6,
615
+ resolve: (clientX, clientY) => {
616
+ const hit = bodyAt(clientX, clientY);
617
+ if (!hit || hit.minute >= limitOf(hit.key)) return {
618
+ key: "",
619
+ start: 0,
620
+ end: 0,
621
+ clash: null
622
+ };
623
+ const fit = fitAt(hit.key, hit.minute, length);
624
+ let start = snapMinutes(hit.minute - length / 2, 15);
625
+ if (fit?.fits) start = Math.max(fit.gap.start, Math.min(fit.gap.end - length, start));
626
+ start = Math.max(0, Math.min(limitOf(hit.key) - length, start));
627
+ return {
628
+ key: hit.key,
629
+ start,
630
+ end: start + length,
631
+ clash: overlapAt(hit.key, start, start + length),
632
+ fit
633
+ };
634
+ },
635
+ onActivate: () => {
636
+ setDragging("external");
637
+ setSelection(null);
638
+ token = document.createElement("div");
639
+ token.className = "k2b-calendar-token";
640
+ token.textContent = item.title;
641
+ token.style.setProperty("--k2b-calendar-accent", color);
642
+ token.setAttribute("aria-hidden", "true");
643
+ document.body.append(token);
644
+ },
645
+ onMove: (clientX, clientY) => {
646
+ if (token) token.style.transform = `translate(${clientX + 12}px, ${clientY + 10}px)`;
647
+ // A folded run of empty days opens when the entry rests on it.
648
+ const empty = document.elementFromPoint(clientX, clientY)?.closest("[data-calendar-unfold]");
649
+ if (empty && spring?.element !== empty) {
650
+ if (spring) window.clearTimeout(spring.timer);
651
+ spring = {
652
+ element: empty,
653
+ timer: window.setTimeout(() => empty.click(), 650)
654
+ };
655
+ } else if (!empty && spring) {
656
+ window.clearTimeout(spring.timer);
657
+ spring = undefined;
658
+ }
659
+ },
660
+ onPreview: next => {
661
+ if (token) token.dataset.hidden = next.key ? "true" : "false";
662
+ if (!next.key) {
663
+ setGhost(null);
664
+ setGapHit(null);
665
+ return;
666
+ }
667
+ setGapHit(next.fit ? {
668
+ key: next.key,
669
+ start: next.fit.gap.start,
670
+ fits: next.fit.fits,
671
+ text: next.fit.text
672
+ } : null);
673
+ const time = `${clock(next.start)}–${clock(next.end)} · ${duration(length)}`;
674
+ setGhost({
675
+ key: next.key,
676
+ start: next.start,
677
+ end: next.end,
678
+ title: item.title,
679
+ time: next.clash ? `${time} · ${messages().calendarOverlaps({
680
+ title: next.clash.title
681
+ })}` : time,
682
+ colorHex: color,
683
+ warn: Boolean(next.clash),
684
+ fit: next.fit ? {
685
+ fits: next.fit.fits,
686
+ text: next.fit.text
687
+ } : undefined
688
+ });
689
+ },
690
+ onCommit: next => {
691
+ swallowNextClick();
692
+ if (next.key) onDrop({
693
+ ...slot(next.key, next.start, next.end),
694
+ allDay: false
695
+ });
696
+ },
697
+ onEnd: cleanup
698
+ });
699
+ };
700
+ if (pointerEvent.pointerType === "mouse") {
701
+ begin();
702
+ return;
703
+ }
704
+ // A finger first holds the entry still, so a short swipe keeps scrolling the list it sits in.
705
+ const origin = {
706
+ x: pointerEvent.clientX,
707
+ y: pointerEvent.clientY
708
+ };
709
+ const abort = () => {
710
+ window.clearTimeout(timer);
711
+ window.removeEventListener("pointermove", watch);
712
+ window.removeEventListener("pointerup", abort);
713
+ window.removeEventListener("pointercancel", abort);
714
+ window.removeEventListener("contextmenu", preventContextMenu, true);
715
+ if (target) delete target.dataset.lifted;
716
+ if (cancelGesture === abort) cancelGesture = undefined;
717
+ };
718
+ const watch = event => {
719
+ if (event.pointerId === pointerEvent.pointerId && Math.hypot(event.clientX - origin.x, event.clientY - origin.y) > 10) abort();
720
+ };
721
+ const timer = window.setTimeout(() => {
722
+ abort();
723
+ held = true;
724
+ if (target) target.dataset.lifted = "true";
725
+ navigator.vibrate?.(8);
726
+ document.addEventListener("touchmove", preventScroll, {
727
+ passive: false
728
+ });
729
+ window.addEventListener("contextmenu", preventContextMenu, true);
730
+ begin();
731
+ }, 420);
732
+ window.addEventListener("pointermove", watch);
733
+ window.addEventListener("pointerup", abort);
734
+ window.addEventListener("pointercancel", abort);
735
+ window.addEventListener("contextmenu", preventContextMenu, true);
736
+ cancelGesture = abort;
737
+ };
738
+ return {
739
+ props,
740
+ messages,
741
+ dateConfig,
742
+ hours,
743
+ wake,
744
+ range,
745
+ anchorKey,
746
+ days,
747
+ dayOf,
748
+ keyOf,
749
+ parseKey,
750
+ nowKey,
751
+ nowMinute,
752
+ nowIn,
753
+ calendarToday,
754
+ clock,
755
+ duration,
756
+ instant,
757
+ normalized,
758
+ checkedOf,
759
+ toggleCheck,
760
+ checkOf,
761
+ justChecked,
762
+ cheered,
763
+ selection,
764
+ setSelection,
765
+ touchDraft,
766
+ setTouchDraft,
767
+ activeKey,
768
+ setActiveKey,
769
+ ghost,
770
+ gapHit,
771
+ movingId,
772
+ dragging,
773
+ nightOpen,
774
+ setNight,
775
+ quick,
776
+ setQuick,
777
+ openQuickCreate,
778
+ canCreate,
779
+ createTarget,
780
+ rangeOfSelection,
781
+ registerBody,
782
+ bodyAt,
783
+ limitOf,
784
+ startMove,
785
+ startResize,
786
+ startDraw,
787
+ dragIn,
788
+ dayStartMinute
789
+ };
790
+ };
791
+ /**
792
+ * German short dates read "Fr 9. Okt", without the dots of the abbreviations; with `comma`, a title such as
793
+ * "Fr, 9. Okt 2026" keeps the comma after the day.
794
+ */
795
+ export const compactGermanDate = (text, locale, comma = false) => locale?.startsWith("de") ? text.replace(comma ? /\b(Mo|Di|Mi|Do|Fr|Sa|So)\./g : /\b(Mo|Di|Mi|Do|Fr|Sa|So)\.,?/g, "$1").replace(/\b(Jan|Feb|Mär|Apr|Jun|Jul|Aug|Sep|Sept|Okt|Nov|Dez)\./g, "$1") : text;
796
+
797
+ /** A short day such as "Fri 9" or "Fr 9.", in the calendar's locale. */
798
+ export const shortDay = (view, key, withMonth = false) => compactGermanDate(view.parseKey(key).toLocaleDateString(view.dateConfig().locale ?? "en", {
799
+ weekday: "short",
800
+ day: "numeric",
801
+ ...(withMonth ? {
802
+ month: "short"
803
+ } : {}),
804
+ timeZone: view.dateConfig().timeZone
805
+ }), view.dateConfig().locale);
806
+
807
+ /** A long day such as "Friday, October 9", with the year when it is not this year's. */
808
+ export const longDay = (view, key) => view.parseKey(key).toLocaleDateString(view.dateConfig().locale ?? "en", {
809
+ weekday: "long",
810
+ month: "long",
811
+ day: "numeric",
812
+ ...(key.slice(0, 4) !== view.calendarToday().slice(0, 4) ? {
813
+ year: "numeric"
814
+ } : {}),
815
+ timeZone: view.dateConfig().timeZone
816
+ });
817
+ const CHECK_PATH = "M4.6 8.3l2.3 2.3 4.6-4.9";
818
+
819
+ /** A to-do's checkbox: it draws its check, and the title beside it strikes through. */
820
+ export const TimeCheck = props => {
821
+ const checked = () => props.view.checkedOf(props.event) ?? false;
822
+ const box = _$ssr(_tmpl$);
823
+ return _$createComponent(Show, {
824
+ get when() {
825
+ return props.view.props.owner.onEventCheck;
826
+ },
827
+ get fallback() {
828
+ return _$ssr(_tmpl$3, _$ssrAttribute("data-checked", checked() ? "true" : _$escape(undefined, true), false), _$escape(box));
829
+ },
830
+ get children() {
831
+ return _$ssr(_tmpl$2, _$ssrAttribute("aria-checked", checked() ? "true" : "false", false) + _$ssrAttribute("aria-label", _$escape(props.view.messages().calendarDone({
832
+ title: props.event.title
833
+ }), true), false) + _$ssrAttribute("tabindex", _$escape(props.tabIndex, true), false) + _$ssrAttribute("data-checked", checked() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-just-checked", props.view.justChecked().has(props.event.id) ? "true" : _$escape(undefined, true), false), _$escape(box));
834
+ }
835
+ });
836
+ };
837
+
838
+ /** A timed entry in a day's timeline: a band as long as the entry, side by side with overlapping ones. */
839
+ export const TimeBand = props => {
840
+ const view = props.view;
841
+ const event = () => props.band.item;
842
+ const wake = () => view.wake();
843
+ const limit = () => props.expanded ? DAY_MINUTES : wake();
844
+ const visibleStart = () => Math.max(0, props.band.start);
845
+ const visibleEnd = () => Math.min(limit(), props.band.end);
846
+ const top = () => dayTopTerms(wake(), props.expanded, visibleStart());
847
+ const bottom = () => dayYTerms(wake(), props.expanded, visibleEnd());
848
+ const now = () => view.nowIn(props.dayKey);
849
+ const running = () => now() >= props.band.start && now() < props.band.end && Number.isFinite(now());
850
+ const past = () => now() >= props.band.end;
851
+ const length = () => props.band.end - props.band.start;
852
+ const pixels = () => length() / 60 * props.hourPx - 2;
853
+ const size = () => pixels() < 27 ? "xs" : pixels() < 40 ? "s" : "m";
854
+ const checked = () => view.checkedOf(event());
855
+ const remaining = () => running() ? view.messages().calendarRemaining({
856
+ duration: view.duration(props.band.end - now())
857
+ }) : undefined;
858
+ const lines = () => Math.max(1, Math.floor((pixels() - 24) / 15));
859
+ return _$ssr(_tmpl$7, _$ssrAttribute("data-calendar-entry", _$escape(event().id, true), false) + _$ssrAttribute("data-size", _$escape(size(), true), false) + _$ssrAttribute("data-past", past() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-running", running() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-checked", checked() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-checkbox", checked() !== undefined ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-just-checked", view.justChecked().has(event().id) ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-cut-bottom", props.band.end > limit() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-moving", view.movingId() === event().id ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-display", _$escape(event().display, true), false), _$ssrStyleProperty("--k2b-calendar-accent:", _$escape(eventAccent(event()), true)) + _$ssrStyleProperty(";--k2b-calendar-lane:", _$escape(String(props.band.lane), true)) + _$ssrStyleProperty(";--k2b-calendar-lanes:", _$escape(String(props.band.lanes), true)) + _$ssrStyleProperty(";--k2b-calendar-lines:", _$escape(String(lines()), true)) + _$ssrStyleProperty(";--k2b-calendar-progress:", running() ? `${_$escape(((now() - props.band.start) / length() * 100).toFixed(1), true)}%` : _$escape(undefined, true)) + _$ssrStyleProperty(";top:", `calc(${_$escape(termsCss(top()), true)} + 1px)`) + _$ssrStyleProperty(";height:", `max(var(--k2b-calendar-band-min), calc(${_$escape(termsCss(subtractTerms(bottom(), top())), true)} - 2px))`), _$escape(_$createComponent(Show, {
860
+ get when() {
861
+ return running();
862
+ },
863
+ get children() {
864
+ return _$ssr(_tmpl$4);
865
+ }
866
+ })), _$escape(_$createComponent(Show, {
867
+ get when() {
868
+ return checked() !== undefined;
869
+ },
870
+ get children() {
871
+ return _$createComponent(TimeCheck, {
872
+ view: view,
873
+ get event() {
874
+ return event();
875
+ },
876
+ get tabIndex() {
877
+ return props.tabIndex === undefined ? undefined : -1;
878
+ }
879
+ });
880
+ }
881
+ })), _$escape(_$createComponent(EventChip, {
882
+ get event() {
883
+ return view.normalized(event(), props.dayKey);
884
+ },
885
+ get owner() {
886
+ return view.props.owner;
887
+ },
888
+ get href() {
889
+ return eventHref(view.props.owner, event());
890
+ },
891
+ fill: true,
892
+ timeline: true,
893
+ get compact() {
894
+ return props.compact;
895
+ },
896
+ get timeLabel() {
897
+ return `${view.clock(props.band.start)}–${view.clock(props.band.end)}`;
898
+ },
899
+ get showLocation() {
900
+ return _$memo(() => !!(props.showLocation && size() === "m"))() && pixels() >= 64;
901
+ },
902
+ get remaining() {
903
+ return remaining();
904
+ },
905
+ get checkbox() {
906
+ return checked() !== undefined;
907
+ },
908
+ get onCheck() {
909
+ return view.checkOf(event());
910
+ },
911
+ get moving() {
912
+ return view.movingId() === event().id;
913
+ },
914
+ get tabIndex() {
915
+ return props.tabIndex;
916
+ },
917
+ get stop() {
918
+ return props.stop;
919
+ },
920
+ get onMovePointerDown() {
921
+ return view.props.owner.onEventDrop ? pointerEvent => view.startMove(pointerEvent, event(), props.dayKey, props.band.start, props.band.end, props.scroller?.()) : undefined;
922
+ }
923
+ })), _$escape(_$createComponent(Show, {
924
+ get when() {
925
+ return view.props.owner.onEventResize;
926
+ },
927
+ get children() {
928
+ return [_$ssr(_tmpl$5), _$createComponent(Show, {
929
+ get when() {
930
+ return props.band.end <= limit();
931
+ },
932
+ get children() {
933
+ return _$ssr(_tmpl$6);
934
+ }
935
+ })];
936
+ }
937
+ })));
938
+ };
939
+
940
+ /** A point in time such as a deadline: a dashed line across the day and a pill with its checkbox and title. */
941
+ export const TimeMarker = props => {
942
+ const view = props.view;
943
+ const checked = () => view.checkedOf(props.event);
944
+ const past = () => view.nowIn(props.dayKey) >= props.minute;
945
+ return _$ssr(_tmpl$8, _$ssrAttribute("data-calendar-entry", _$escape(props.event.id, true), false) + _$ssrAttribute("data-past", past() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-overdue", past() && checked() === false ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-checked", checked() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-just-checked", view.justChecked().has(props.event.id) ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-above", props.above ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-moving", view.movingId() === props.event.id ? "true" : _$escape(undefined, true), false), _$ssrStyleProperty("--k2b-calendar-accent:", _$escape(eventAccent(props.event), true)) + _$ssrStyleProperty(";--k2b-calendar-marker-lane:", _$escape(String(props.lane), true)) + _$ssrStyleProperty(";--k2b-calendar-marker-lanes:", _$escape(String(props.lanes), true)) + _$ssrStyleProperty(";top:", _$escape(termsCss(dayTopTerms(view.wake(), props.expanded, props.minute)), true)), _$escape(_$createComponent(Show, {
946
+ get when() {
947
+ return checked() !== undefined;
948
+ },
949
+ get children() {
950
+ return _$createComponent(TimeCheck, {
951
+ view: view,
952
+ get event() {
953
+ return props.event;
954
+ },
955
+ get tabIndex() {
956
+ return props.tabIndex === undefined ? undefined : -1;
957
+ }
958
+ });
959
+ }
960
+ })), _$escape(_$createComponent(EventChip, {
961
+ get event() {
962
+ return view.normalized(props.event, props.dayKey);
963
+ },
964
+ get owner() {
965
+ return view.props.owner;
966
+ },
967
+ get href() {
968
+ return eventHref(view.props.owner, props.event);
969
+ },
970
+ compact: true,
971
+ timeline: true,
972
+ get checkbox() {
973
+ return checked() !== undefined;
974
+ },
975
+ get onCheck() {
976
+ return view.checkOf(props.event);
977
+ },
978
+ get tabIndex() {
979
+ return props.tabIndex;
980
+ },
981
+ get stop() {
982
+ return props.stop;
983
+ },
984
+ get trailing() {
985
+ return _$createComponent(Show, {
986
+ get when() {
987
+ return props.showTime;
988
+ },
989
+ get children() {
990
+ return _$ssr(_tmpl$9, _$escape(view.clock(props.minute)));
991
+ }
992
+ });
993
+ },
994
+ get onMovePointerDown() {
995
+ return view.props.owner.onEventDrop ? pointerEvent => view.startMove(pointerEvent, props.event, props.dayKey, props.minute, props.minute, props.scroller?.()) : undefined;
996
+ }
997
+ })));
998
+ };
999
+
1000
+ /** Free time between entries, labelled from an hour on; activating it creates there. */
1001
+ export const TimeGap = props => {
1002
+ const view = props.view;
1003
+ const length = () => props.gap.end - props.gap.start;
1004
+ const proposal = () => gapProposal(props.gap, view.hours());
1005
+ const label = () => view.messages().calendarFree({
1006
+ duration: view.duration(length())
1007
+ });
1008
+ const hit = () => {
1009
+ const current = view.gapHit();
1010
+ return current && current.key === props.dayKey && current.start === props.gap.start ? current : null;
1011
+ };
1012
+ const top = () => dayYTerms(view.wake(), props.expanded, props.gap.start);
1013
+ /**
1014
+ * Shorter free time is hidden until something is dragged into it, and past free time has no label, so neither is a
1015
+ * keyboard stop.
1016
+ */
1017
+ const labelled = () => length() >= GAP_LABEL_MINUTES;
1018
+ const stop = () => labelled() && !props.gap.past ? props.stop : undefined;
1019
+ return _$ssr(_tmpl$1, _$ssrAttribute("data-short", labelled() ? _$escape(undefined, true) : "true", false) + _$ssrAttribute("data-long", length() >= GAP_LONG_MINUTES ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-past", props.gap.past ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-aside", props.aside ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-hit", hit() ? hit().fits ? "fit" : "short" : _$escape(undefined, true), false), _$ssrStyleProperty("top:", _$escape(termsCss(top()), true)) + _$ssrStyleProperty(";height:", _$escape(termsCss(subtractTerms(dayYTerms(view.wake(), props.expanded, props.gap.end), top())), true)), _$escape(_$createComponent(Show, {
1020
+ get when() {
1021
+ return view.canCreate();
1022
+ },
1023
+ get children() {
1024
+ return _$ssr(_tmpl$0, _$ssrAttribute("tabindex", labelled() ? _$escape(props.tabIndex ?? (props.gap.past ? -1 : 0), true) : -1, false) + _$ssrAttribute("data-stop", _$escape(stop()?.id, true), false) + _$ssrAttribute("data-col", _$escape(stop()?.column, true), false) + _$ssrAttribute("data-minute", _$escape(stop()?.minute, true), false) + _$ssrAttribute("aria-label", _$escape(view.messages().calendarFreeAction({
1025
+ duration: view.duration(length()),
1026
+ from: view.clock(props.gap.start),
1027
+ to: view.clock(props.gap.end),
1028
+ start: view.clock(proposal()[0]),
1029
+ end: view.clock(proposal()[1])
1030
+ }), true), false) + _$ssrAttribute("title", _$escape(view.messages().calendarCreateAt({
1031
+ start: view.clock(proposal()[0]),
1032
+ end: view.clock(proposal()[1])
1033
+ }), true), false), hit() ? _$escape(hit().text) : _$escape(label()));
1034
+ }
1035
+ })));
1036
+ };
1037
+
1038
+ /** The preview of a drag, a draw, or an entry dragged in, and the selected slot. */
1039
+ export const TimeOverlays = props => {
1040
+ const view = props.view;
1041
+ const ghost = () => {
1042
+ const current = view.ghost();
1043
+ return current && current.key === props.dayKey ? current : null;
1044
+ };
1045
+ const selected = () => {
1046
+ const current = view.selection();
1047
+ return current && current.key === props.dayKey && current.start !== undefined && current.end !== undefined ? current : null;
1048
+ };
1049
+ const draft = () => {
1050
+ const current = view.touchDraft();
1051
+ return current && current.key === props.dayKey ? current : null;
1052
+ };
1053
+ const box = (start, end) => {
1054
+ const top = dayTopTerms(view.wake(), props.expanded, start);
1055
+ return {
1056
+ top: termsCss(top),
1057
+ height: termsCss(subtractTerms(dayYTerms(view.wake(), props.expanded, end), top))
1058
+ };
1059
+ };
1060
+ return [_$createComponent(Show, {
1061
+ get when() {
1062
+ return selected();
1063
+ },
1064
+ children: slot => _$ssr(_tmpl$10, _$ssrStyle(box(slot().start, slot().end)))
1065
+ }), _$createComponent(Show, {
1066
+ get when() {
1067
+ return draft();
1068
+ },
1069
+ children: slot => _$ssr(_tmpl$11, _$ssrStyle(box(slot().start, slot().end)), _$ssrAttribute("aria-label", _$escape(view.messages().calendarCreateAt({
1070
+ start: view.clock(slot().start),
1071
+ end: view.clock(slot().end)
1072
+ }), true), false), _$escape(view.clock(slot().start)), _$escape(view.clock(slot().end)), _$escape(view.duration(slot().end - slot().start)))
1073
+ }), _$createComponent(Show, {
1074
+ get when() {
1075
+ return ghost();
1076
+ },
1077
+ children: current => _$ssr(_tmpl$12, _$ssrAttribute("data-size", current().end - current().start < 40 ? "s" : "m", false) + _$ssrAttribute("data-warn", current().warn ? "true" : _$escape(undefined, true), false), _$ssrStyle({
1078
+ ...box(current().start, current().end),
1079
+ "--k2b-calendar-accent": current().colorHex ?? "var(--k2b-action)"
1080
+ }), _$escape(current().title), _$escape(current().time), _$escape(_$createComponent(Show, {
1081
+ get when() {
1082
+ return current().fit;
1083
+ },
1084
+ children: fit => _$ssr(_tmpl$13, _$ssrAttribute("data-fit", fit().fits ? "fit" : "short", false), _$escape(fit().text))
1085
+ })))
1086
+ })];
1087
+ };
1088
+
1089
+ /** The handles of a tapped slot change its start or end. */
1090
+ const startDraftResize = (view, pointerEvent, edge) => {
1091
+ const draft = view.touchDraft();
1092
+ if (!draft) return;
1093
+ pointerEvent.preventDefault();
1094
+ pointerEvent.stopPropagation();
1095
+ startCalendarPointerSession({
1096
+ event: pointerEvent,
1097
+ threshold: 1,
1098
+ resolve: (clientX, clientY) => {
1099
+ const hit = view.bodyAt(clientX, clientY);
1100
+ if (!hit || hit.key !== draft.key) return null;
1101
+ const minute = snapMinutes(hit.minute, 15);
1102
+ const current = view.touchDraft() ?? draft;
1103
+ return edge === "end" ? {
1104
+ ...current,
1105
+ end: Math.max(current.start + 15, Math.min(view.limitOf(draft.key), minute))
1106
+ } : {
1107
+ ...current,
1108
+ start: Math.max(0, Math.min(current.end - 15, minute))
1109
+ };
1110
+ },
1111
+ onPreview: next => {
1112
+ view.setTouchDraft(next);
1113
+ view.setSelection({
1114
+ key: next.key,
1115
+ start: next.start,
1116
+ end: next.end
1117
+ });
1118
+ },
1119
+ onCommit: () => swallowNextClick()
1120
+ });
1121
+ };
1122
+
1123
+ /** Free time of a day with the gap of now trimmed, as both views draw it. */
1124
+ export const dayGaps = (view, key) => freeGaps(view.dayOf(key).bands, view.wake(), view.nowIn(key));
1125
+
1126
+ /** The bands of a day with their lanes, cut to what its timeline draws. */
1127
+ export const dayBands = (view, key, expanded) => {
1128
+ const limit = expanded ? DAY_MINUTES : view.wake();
1129
+ const visible = view.dayOf(key).bands.filter(band => Math.min(limit, band.end) > Math.max(0, band.start));
1130
+ return dayLanes(visible, LANE_MINUTES);
1131
+ };
1132
+
1133
+ /** Entries the folded night hides, as chips with their time. */
1134
+ export const foldedEntries = (view, key) => {
1135
+ const model = view.dayOf(key);
1136
+ const wake = view.wake();
1137
+ return [...model.bands.filter(band => band.end > wake).map(band => ({
1138
+ event: band.item,
1139
+ time: band.start >= wake ? view.clock(band.start) : view.messages().calendarUntil({
1140
+ time: view.clock(band.end)
1141
+ })
1142
+ })), ...model.markers.filter(marker => marker.minute >= wake).map(marker => ({
1143
+ event: marker.item,
1144
+ time: view.clock(marker.minute)
1145
+ }))];
1146
+ };
1147
+
1148
+ /** The quick create at a slot or gap, as in the month view. */
1149
+ export const TimeQuickCreate = props => {
1150
+ const view = props.view;
1151
+ let element;
1152
+ let returnFocus = null;
1153
+ createEffect(() => {
1154
+ const current = view.quick();
1155
+ if (!element) return;
1156
+ if (!current) {
1157
+ if (element.matches(":popover-open")) element.hidePopover();
1158
+ return;
1159
+ }
1160
+ returnFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;
1161
+ if (!element.matches(":popover-open")) element.showPopover();
1162
+ queueMicrotask(() => {
1163
+ if (view.quick() !== current || !element?.isConnected) return;
1164
+ placeCalendarPopover(current.anchor, element);
1165
+ element.querySelector("input,textarea,select,button,a[href],[tabindex]:not([tabindex='-1'])")?.focus();
1166
+ });
1167
+ });
1168
+ const close = restore => {
1169
+ if (!view.quick()) return;
1170
+ view.setQuick(null);
1171
+ view.setSelection(null);
1172
+ if (restore && returnFocus?.isConnected) returnFocus.focus({
1173
+ preventScroll: true
1174
+ });
1175
+ };
1176
+ return _$ssr(_tmpl$14, _$ssrAttribute("aria-label", _$escape(view.messages().calendarQuickCreate, true), false), _$escape(_$createComponent(Show, {
1177
+ get when() {
1178
+ return view.quick();
1179
+ },
1180
+ keyed: true,
1181
+ children: value => view.props.owner.renderQuickCreate?.(value.range, {
1182
+ create: value.create,
1183
+ close: () => {
1184
+ if (view.quick() === value) close(true);
1185
+ }
1186
+ })
1187
+ })));
1188
+ };
1189
+
1190
+ /** All-day entries of a day as chips: bars with torn ends where they go on, and points due that day. */
1191
+ export const AllDayChips = props => {
1192
+ const view = props.view;
1193
+ return _$createComponent(For, {
1194
+ get each() {
1195
+ return props.spans;
1196
+ },
1197
+ children: span => {
1198
+ const event = span.item;
1199
+ const checked = () => view.checkedOf(event);
1200
+ return _$ssr(_tmpl$15, _$ssrAttribute("data-bar", span.marker ? _$escape(undefined, true) : "true", false) + _$ssrAttribute("data-checkbox", checked() !== undefined ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-checked", checked() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-just-checked", view.justChecked().has(event.id) ? "true" : _$escape(undefined, true), false), _$ssrStyleProperty("--k2b-calendar-accent:", _$escape(eventAccent(event), true)), _$escape(_$createComponent(Show, {
1201
+ get when() {
1202
+ return checked() !== undefined;
1203
+ },
1204
+ get children() {
1205
+ return _$createComponent(TimeCheck, {
1206
+ view: view,
1207
+ event: event
1208
+ });
1209
+ }
1210
+ })), _$escape(_$createComponent(EventChip, {
1211
+ get event() {
1212
+ return view.normalized(event, props.dayKey);
1213
+ },
1214
+ get owner() {
1215
+ return view.props.owner;
1216
+ },
1217
+ get href() {
1218
+ return eventHref(view.props.owner, event);
1219
+ },
1220
+ compact: true,
1221
+ timeline: true,
1222
+ get bar() {
1223
+ return !span.marker;
1224
+ },
1225
+ get checkbox() {
1226
+ return checked() !== undefined;
1227
+ },
1228
+ get onCheck() {
1229
+ return view.checkOf(event);
1230
+ },
1231
+ get continuesBefore() {
1232
+ return span.firstKey < props.dayKey;
1233
+ },
1234
+ get continuesAfter() {
1235
+ return span.lastKey > props.dayKey;
1236
+ }
1237
+ })));
1238
+ }
1239
+ });
1240
+ };
1241
+
1242
+ /** Hour labels and lines of a day's timeline with the night open, and the date at midnight. */
1243
+ export const nightHours = wake => {
1244
+ const hours = [];
1245
+ for (let minute = wake + 60; minute < DAY_MINUTES; minute += 60) hours.push(minute);
1246
+ return hours;
1247
+ };
1248
+ export const isNearNow = (view, key, minute) => key === view.nowKey() && Math.abs(view.nowMinute() - minute) < 14;
1249
+
1250
+ /** Whether a marker sits right above a band's start, so its pill goes above the line. */
1251
+ export const markerAbove = (model, minute) => model.bands.some(band => band.start >= minute - 10 && band.start <= minute + 20);
1252
+
1253
+ /** Whether a deadline pill sits near the middle of a gap, so the gap's label moves aside. */
1254
+ export const gapAside = (model, gap) => {
1255
+ const middle = (gap.start + gap.end) / 2;
1256
+ return model.markers.some(marker => marker.minute > gap.start - 10 && marker.minute < gap.end + 10 && Math.abs(marker.minute - middle) < 25);
1257
+ };
1258
+
1259
+ /** A day's counts for its header: events and all-day entries, to-dos and deadlines. */
1260
+ export const daySummary = (view, key) => {
1261
+ const model = view.dayOf(key);
1262
+ const isTask = event => event.display === "marker" || event.checked !== undefined;
1263
+ const all = [...model.bands.map(band => band.item), ...model.markers.map(marker => marker.item), ...model.spans.map(span => span.item)];
1264
+ const tasks = all.filter(isTask).length;
1265
+ return view.messages().calendarDaySummary({
1266
+ events: all.length - tasks,
1267
+ tasks
1268
+ });
1269
+ };
1270
+
1271
+ /** What starts within the next hour today, such as "Planning in 12 min". */
1272
+ export const soonNote = (view, key) => {
1273
+ if (key !== view.nowKey()) return "";
1274
+ const now = view.nowMinute();
1275
+ const next = view.dayOf(key).bands.filter(band => band.start > now && band.start - now <= 60 && !view.checkedOf(band.item)).sort((left, right) => left.start - right.start)[0];
1276
+ return next ? view.messages().calendarSoon({
1277
+ title: next.item.title,
1278
+ duration: view.duration(next.start - now)
1279
+ }) : "";
1280
+ };
1281
+
1282
+ /** The busy minutes of a day's waking hours, merged, with the color of the first entry, for the thin load line. */
1283
+ export const dayLoad = (view, key) => {
1284
+ const pieces = view.dayOf(key).bands.map(band => ({
1285
+ start: Math.max(0, band.start),
1286
+ end: Math.min(view.wake(), band.end),
1287
+ color: eventAccent(band.item)
1288
+ })).filter(piece => piece.end > piece.start).sort((left, right) => left.start - right.start);
1289
+ const merged = [];
1290
+ for (const piece of pieces) {
1291
+ const last = merged[merged.length - 1];
1292
+ if (last && piece.start <= last.end) last.end = Math.max(last.end, piece.end);else merged.push({
1293
+ ...piece
1294
+ });
1295
+ }
1296
+ return merged;
1297
+ };
1298
+
1299
+ /** Day keys of the week that holds a day, from its first day. */
1300
+ export const weekKeysOf = (view, key) => {
1301
+ const start = view.keyOf(calendar.startOfWeek(view.parseKey(key), view.dateConfig()));
1302
+ return Array.from({
1303
+ length: 7
1304
+ }, (_, index) => addDayKeys(start, index));
1305
+ };
1306
+ //# sourceMappingURL=calendar-time-view.js.map