@k2b/ui 0.5.0 → 0.6.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 (387) hide show
  1. package/dist/browser/actions/Button.js +11 -2
  2. package/dist/browser/actions/Button.js.map +1 -1
  3. package/dist/browser/actions/ContextMenu.js.map +1 -1
  4. package/dist/browser/actions/CopyButton.js.map +1 -1
  5. package/dist/browser/actions/Disclosure.js.map +1 -1
  6. package/dist/browser/actions/Dropdown.js.map +1 -1
  7. package/dist/browser/actions/FilterChip.js.map +1 -1
  8. package/dist/browser/actions/RemoveButton.js.map +1 -1
  9. package/dist/browser/actions/SegmentedControl.js.map +1 -1
  10. package/dist/browser/actions/SplitButton.js.map +1 -1
  11. package/dist/browser/actions/SpotlightSearch.js.map +1 -1
  12. package/dist/browser/actions/Tabs.js.map +1 -1
  13. package/dist/browser/actions/Toolbar.js.map +1 -1
  14. package/dist/browser/actions/index.js.map +1 -1
  15. package/dist/browser/chat/ChatComposer.js.map +1 -1
  16. package/dist/browser/chat/ChatContextPopup.js.map +1 -1
  17. package/dist/browser/chat/ChatPrimitives.js.map +1 -1
  18. package/dist/browser/chat/ChatRoot.js.map +1 -1
  19. package/dist/browser/chat/ChatTasks.js +1 -1
  20. package/dist/browser/chat/ChatTasks.js.map +1 -1
  21. package/dist/browser/chat/ChatTimeline.js.map +1 -1
  22. package/dist/browser/chat/chat-behavior.js.map +1 -1
  23. package/dist/browser/chat/composer-document.js.map +1 -1
  24. package/dist/browser/chat/index.js.map +1 -1
  25. package/dist/browser/content/Calendar.js.map +1 -1
  26. package/dist/browser/content/Chart.js.map +1 -1
  27. package/dist/browser/content/ChartExplorer.js.map +1 -1
  28. package/dist/browser/content/ChartExplorerControls.js.map +1 -1
  29. package/dist/browser/content/ChartFilterControls.js +1 -1
  30. package/dist/browser/content/ChartFilterControls.js.map +1 -1
  31. package/dist/browser/content/ChartSnapshotView.js.map +1 -1
  32. package/dist/browser/content/CodeDisplay.js.map +1 -1
  33. package/dist/browser/content/DataTable.js.map +1 -1
  34. package/dist/browser/content/Docs.js.map +1 -1
  35. package/dist/browser/content/FileBrowser.js.map +1 -1
  36. package/dist/browser/content/FileGrid.js.map +1 -1
  37. package/dist/browser/content/FileTree.js.map +1 -1
  38. package/dist/browser/content/FileView.js.map +1 -1
  39. package/dist/browser/content/Lightbox.js.map +1 -1
  40. package/dist/browser/content/LogEntriesTable.js.map +1 -1
  41. package/dist/browser/content/MarkdownView.js.map +1 -1
  42. package/dist/browser/content/Pagination.js.map +1 -1
  43. package/dist/browser/content/PdfPreview.js.map +1 -1
  44. package/dist/browser/content/RangePicker.js.map +1 -1
  45. package/dist/browser/content/StructuredDataPreview.js.map +1 -1
  46. package/dist/browser/content/ZoomPanViewport.js +396 -0
  47. package/dist/browser/content/ZoomPanViewport.js.map +1 -0
  48. package/dist/browser/content/calendar-event-layout.js.map +1 -1
  49. package/dist/browser/content/calendar-pointer.js.map +1 -1
  50. package/dist/browser/content/chart-cursor.js.map +1 -1
  51. package/dist/browser/content/chart-explorer.js.map +1 -1
  52. package/dist/browser/content/chart-inspection.js.map +1 -1
  53. package/dist/browser/content/chart-line-gaps.js.map +1 -1
  54. package/dist/browser/content/chart-map-viewport.js.map +1 -1
  55. package/dist/browser/content/chart-snapshot.js.map +1 -1
  56. package/dist/browser/content/chart-state-timeline.js.map +1 -1
  57. package/dist/browser/content/chart-svg.js.map +1 -1
  58. package/dist/browser/content/code-highlight.js.map +1 -1
  59. package/dist/browser/content/collection-selection.js.map +1 -1
  60. package/dist/browser/content/delimited-preferences.js.map +1 -1
  61. package/dist/browser/content/file-tree.js.map +1 -1
  62. package/dist/browser/content/file-view-preview.js.map +1 -1
  63. package/dist/browser/content/index.js +1 -0
  64. package/dist/browser/content/index.js.map +1 -1
  65. package/dist/browser/content/zoom-pan.js +54 -0
  66. package/dist/browser/content/zoom-pan.js.map +1 -0
  67. package/dist/browser/feedback/InlineGuidance.js.map +1 -1
  68. package/dist/browser/feedback/Tooltip.js.map +1 -1
  69. package/dist/browser/feedback/dialog-core.js.map +1 -1
  70. package/dist/browser/feedback/index.js.map +1 -1
  71. package/dist/browser/feedback/prompts.js.map +1 -1
  72. package/dist/browser/feedback/toast.js.map +1 -1
  73. package/dist/browser/feedback/tooltip-position.js.map +1 -1
  74. package/dist/browser/inputs/AutocompleteEditor.js.map +1 -1
  75. package/dist/browser/inputs/AutocompleteSelect.js.map +1 -1
  76. package/dist/browser/inputs/Checkbox.js.map +1 -1
  77. package/dist/browser/inputs/CheckboxCard.js.map +1 -1
  78. package/dist/browser/inputs/ChoiceGroups.js.map +1 -1
  79. package/dist/browser/inputs/ChoiceInputs.js.map +1 -1
  80. package/dist/browser/inputs/Combobox.js.map +1 -1
  81. package/dist/browser/inputs/DatePicker.js.map +1 -1
  82. package/dist/browser/inputs/FileInputs.js.map +1 -1
  83. package/dist/browser/inputs/MultiSelectInput.js.map +1 -1
  84. package/dist/browser/inputs/NumberInput.js.map +1 -1
  85. package/dist/browser/inputs/Select.js.map +1 -1
  86. package/dist/browser/inputs/SelectChip.js.map +1 -1
  87. package/dist/browser/inputs/SpecialInputs.js.map +1 -1
  88. package/dist/browser/inputs/Switch.js.map +1 -1
  89. package/dist/browser/inputs/TagEditor.js.map +1 -1
  90. package/dist/browser/inputs/TagsInput.js.map +1 -1
  91. package/dist/browser/inputs/TemplateEditor.js.map +1 -1
  92. package/dist/browser/inputs/TextInput.js +2 -1
  93. package/dist/browser/inputs/TextInput.js.map +1 -1
  94. package/dist/browser/inputs/choice.js.map +1 -1
  95. package/dist/browser/inputs/completion/behaviors.js.map +1 -1
  96. package/dist/browser/inputs/completion/engine.js.map +1 -1
  97. package/dist/browser/inputs/completion/index.js.map +1 -1
  98. package/dist/browser/inputs/completion/overlay.js.map +1 -1
  99. package/dist/browser/inputs/date-picker.js.map +1 -1
  100. package/dist/browser/inputs/editor-dom.js.map +1 -1
  101. package/dist/browser/inputs/field-contract.js.map +1 -1
  102. package/dist/browser/inputs/icon-options.js.map +1 -1
  103. package/dist/browser/inputs/image-crop.js.map +1 -1
  104. package/dist/browser/inputs/index.js.map +1 -1
  105. package/dist/browser/inputs/markdown/MarkdownEditor.js.map +1 -1
  106. package/dist/browser/inputs/markdown/Toolbar.js.map +1 -1
  107. package/dist/browser/inputs/markdown/actions.js.map +1 -1
  108. package/dist/browser/inputs/markdown/active-formats.js.map +1 -1
  109. package/dist/browser/inputs/markdown/behaviors.js.map +1 -1
  110. package/dist/browser/inputs/markdown/code-zone.js.map +1 -1
  111. package/dist/browser/internal/color.js.map +1 -1
  112. package/dist/browser/internal/field.js.map +1 -1
  113. package/dist/browser/internal/portal.js.map +1 -1
  114. package/dist/browser/intl/Format.js.map +1 -1
  115. package/dist/browser/intl/index.js.map +1 -1
  116. package/dist/browser/intl/locale.js.map +1 -1
  117. package/dist/browser/intl/messages.js +6 -0
  118. package/dist/browser/intl/messages.js.map +1 -1
  119. package/dist/browser/layout/AppOverview.js.map +1 -1
  120. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  121. package/dist/browser/layout/BottomSheet.js.map +1 -1
  122. package/dist/browser/layout/DataPanel.js.map +1 -1
  123. package/dist/browser/layout/DetailPanel.js.map +1 -1
  124. package/dist/browser/layout/Discussion.js.map +1 -1
  125. package/dist/browser/layout/FloatingWindow.js.map +1 -1
  126. package/dist/browser/layout/Navigation.js.map +1 -1
  127. package/dist/browser/layout/PanelDialog.js.map +1 -1
  128. package/dist/browser/layout/PanelHeader.js.map +1 -1
  129. package/dist/browser/layout/Panes.js.map +1 -1
  130. package/dist/browser/layout/PullToRefresh.js +8 -7
  131. package/dist/browser/layout/PullToRefresh.js.map +1 -1
  132. package/dist/browser/layout/ScrollArea.js.map +1 -1
  133. package/dist/browser/layout/Settings.js.map +1 -1
  134. package/dist/browser/layout/SettingsCollection.js.map +1 -1
  135. package/dist/browser/layout/SettingsModal.js.map +1 -1
  136. package/dist/browser/layout/SidebarItemPreview.js.map +1 -1
  137. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  138. package/dist/browser/layout/app-workspace-state.js.map +1 -1
  139. package/dist/browser/layout/floating-window-geometry.js.map +1 -1
  140. package/dist/browser/layout/index.js.map +1 -1
  141. package/dist/browser/layout/navigation-model.js.map +1 -1
  142. package/dist/browser/layout/panes-layout.js.map +1 -1
  143. package/dist/browser/layout/scroll-fade.js.map +1 -1
  144. package/dist/browser/layout/stable-id.js.map +1 -1
  145. package/dist/browser/surfaces/Avatar.js.map +1 -1
  146. package/dist/browser/surfaces/DescriptionList.js.map +1 -1
  147. package/dist/browser/surfaces/LinkCard.js.map +1 -1
  148. package/dist/browser/surfaces/NotFoundState.js.map +1 -1
  149. package/dist/browser/surfaces/NoticeCard.js.map +1 -1
  150. package/dist/browser/surfaces/Paper.js.map +1 -1
  151. package/dist/browser/surfaces/Placeholder.js.map +1 -1
  152. package/dist/browser/surfaces/ProgressBar.js.map +1 -1
  153. package/dist/browser/surfaces/StatCell.js.map +1 -1
  154. package/dist/browser/surfaces/StatGrid.js.map +1 -1
  155. package/dist/browser/surfaces/StatusBadge.js.map +1 -1
  156. package/dist/browser/surfaces/Tag.js.map +1 -1
  157. package/dist/browser/surfaces/index.js.map +1 -1
  158. package/dist/browser/widgets/Widget.js.map +1 -1
  159. package/dist/browser/widgets/WidgetHero.js.map +1 -1
  160. package/dist/browser/widgets/WidgetList.js.map +1 -1
  161. package/dist/browser/widgets/WidgetPills.js.map +1 -1
  162. package/dist/browser/widgets/WidgetStat.js.map +1 -1
  163. package/dist/browser/widgets/WidgetStatus.js.map +1 -1
  164. package/dist/ssr/actions/Button.js +16 -6
  165. package/dist/ssr/actions/Button.js.map +1 -1
  166. package/dist/ssr/actions/ContextMenu.js.map +1 -1
  167. package/dist/ssr/actions/CopyButton.js +2 -1
  168. package/dist/ssr/actions/CopyButton.js.map +1 -1
  169. package/dist/ssr/actions/Disclosure.js.map +1 -1
  170. package/dist/ssr/actions/Dropdown.js +7 -6
  171. package/dist/ssr/actions/Dropdown.js.map +1 -1
  172. package/dist/ssr/actions/FilterChip.js +5 -4
  173. package/dist/ssr/actions/FilterChip.js.map +1 -1
  174. package/dist/ssr/actions/RemoveButton.js +1 -0
  175. package/dist/ssr/actions/RemoveButton.js.map +1 -1
  176. package/dist/ssr/actions/SegmentedControl.js.map +1 -1
  177. package/dist/ssr/actions/SplitButton.js +1 -0
  178. package/dist/ssr/actions/SplitButton.js.map +1 -1
  179. package/dist/ssr/actions/SpotlightSearch.js.map +1 -1
  180. package/dist/ssr/actions/Tabs.js.map +1 -1
  181. package/dist/ssr/actions/Toolbar.js.map +1 -1
  182. package/dist/ssr/actions/index.js.map +1 -1
  183. package/dist/ssr/chat/ChatComposer.js +6 -5
  184. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  185. package/dist/ssr/chat/ChatContextPopup.js.map +1 -1
  186. package/dist/ssr/chat/ChatPrimitives.js +6 -5
  187. package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
  188. package/dist/ssr/chat/ChatRoot.js.map +1 -1
  189. package/dist/ssr/chat/ChatTasks.js +1 -1
  190. package/dist/ssr/chat/ChatTasks.js.map +1 -1
  191. package/dist/ssr/chat/ChatTimeline.js +5 -4
  192. package/dist/ssr/chat/ChatTimeline.js.map +1 -1
  193. package/dist/ssr/chat/chat-behavior.js.map +1 -1
  194. package/dist/ssr/chat/composer-document.js.map +1 -1
  195. package/dist/ssr/chat/index.js.map +1 -1
  196. package/dist/ssr/content/Calendar.js +2 -1
  197. package/dist/ssr/content/Calendar.js.map +1 -1
  198. package/dist/ssr/content/Chart.js.map +1 -1
  199. package/dist/ssr/content/ChartExplorer.js.map +1 -1
  200. package/dist/ssr/content/ChartExplorerControls.js +5 -4
  201. package/dist/ssr/content/ChartExplorerControls.js.map +1 -1
  202. package/dist/ssr/content/ChartFilterControls.js +3 -2
  203. package/dist/ssr/content/ChartFilterControls.js.map +1 -1
  204. package/dist/ssr/content/ChartSnapshotView.js.map +1 -1
  205. package/dist/ssr/content/CodeDisplay.js.map +1 -1
  206. package/dist/ssr/content/DataTable.js +1 -0
  207. package/dist/ssr/content/DataTable.js.map +1 -1
  208. package/dist/ssr/content/Docs.js +1 -0
  209. package/dist/ssr/content/Docs.js.map +1 -1
  210. package/dist/ssr/content/FileBrowser.js +2 -1
  211. package/dist/ssr/content/FileBrowser.js.map +1 -1
  212. package/dist/ssr/content/FileGrid.js.map +1 -1
  213. package/dist/ssr/content/FileTree.js +2 -1
  214. package/dist/ssr/content/FileTree.js.map +1 -1
  215. package/dist/ssr/content/FileView.js +5 -4
  216. package/dist/ssr/content/FileView.js.map +1 -1
  217. package/dist/ssr/content/Lightbox.js +2 -1
  218. package/dist/ssr/content/Lightbox.js.map +1 -1
  219. package/dist/ssr/content/LogEntriesTable.js.map +1 -1
  220. package/dist/ssr/content/MarkdownView.js.map +1 -1
  221. package/dist/ssr/content/Pagination.js +2 -1
  222. package/dist/ssr/content/Pagination.js.map +1 -1
  223. package/dist/ssr/content/PdfPreview.js.map +1 -1
  224. package/dist/ssr/content/RangePicker.js.map +1 -1
  225. package/dist/ssr/content/StructuredDataPreview.js.map +1 -1
  226. package/dist/ssr/content/ZoomPanViewport.js +300 -0
  227. package/dist/ssr/content/ZoomPanViewport.js.map +1 -0
  228. package/dist/ssr/content/calendar-event-layout.js.map +1 -1
  229. package/dist/ssr/content/calendar-pointer.js.map +1 -1
  230. package/dist/ssr/content/chart-cursor.js.map +1 -1
  231. package/dist/ssr/content/chart-explorer.js.map +1 -1
  232. package/dist/ssr/content/chart-inspection.js.map +1 -1
  233. package/dist/ssr/content/chart-line-gaps.js.map +1 -1
  234. package/dist/ssr/content/chart-map-viewport.js.map +1 -1
  235. package/dist/ssr/content/chart-snapshot.js.map +1 -1
  236. package/dist/ssr/content/chart-state-timeline.js.map +1 -1
  237. package/dist/ssr/content/chart-svg.js.map +1 -1
  238. package/dist/ssr/content/code-highlight.js.map +1 -1
  239. package/dist/ssr/content/collection-selection.js.map +1 -1
  240. package/dist/ssr/content/delimited-preferences.js.map +1 -1
  241. package/dist/ssr/content/file-tree.js.map +1 -1
  242. package/dist/ssr/content/file-view-preview.js.map +1 -1
  243. package/dist/ssr/content/index.js +1 -0
  244. package/dist/ssr/content/index.js.map +1 -1
  245. package/dist/ssr/content/zoom-pan.js +54 -0
  246. package/dist/ssr/content/zoom-pan.js.map +1 -0
  247. package/dist/ssr/feedback/InlineGuidance.js.map +1 -1
  248. package/dist/ssr/feedback/Tooltip.js.map +1 -1
  249. package/dist/ssr/feedback/dialog-core.js.map +1 -1
  250. package/dist/ssr/feedback/index.js.map +1 -1
  251. package/dist/ssr/feedback/prompts.js +3 -2
  252. package/dist/ssr/feedback/prompts.js.map +1 -1
  253. package/dist/ssr/feedback/toast.js.map +1 -1
  254. package/dist/ssr/feedback/tooltip-position.js.map +1 -1
  255. package/dist/ssr/inputs/AutocompleteEditor.js +3 -2
  256. package/dist/ssr/inputs/AutocompleteEditor.js.map +1 -1
  257. package/dist/ssr/inputs/AutocompleteSelect.js +5 -4
  258. package/dist/ssr/inputs/AutocompleteSelect.js.map +1 -1
  259. package/dist/ssr/inputs/Checkbox.js +1 -0
  260. package/dist/ssr/inputs/Checkbox.js.map +1 -1
  261. package/dist/ssr/inputs/CheckboxCard.js.map +1 -1
  262. package/dist/ssr/inputs/ChoiceGroups.js.map +1 -1
  263. package/dist/ssr/inputs/ChoiceInputs.js +1 -0
  264. package/dist/ssr/inputs/ChoiceInputs.js.map +1 -1
  265. package/dist/ssr/inputs/Combobox.js +2 -1
  266. package/dist/ssr/inputs/Combobox.js.map +1 -1
  267. package/dist/ssr/inputs/DatePicker.js +4 -3
  268. package/dist/ssr/inputs/DatePicker.js.map +1 -1
  269. package/dist/ssr/inputs/FileInputs.js +2 -1
  270. package/dist/ssr/inputs/FileInputs.js.map +1 -1
  271. package/dist/ssr/inputs/MultiSelectInput.js +4 -3
  272. package/dist/ssr/inputs/MultiSelectInput.js.map +1 -1
  273. package/dist/ssr/inputs/NumberInput.js +2 -1
  274. package/dist/ssr/inputs/NumberInput.js.map +1 -1
  275. package/dist/ssr/inputs/Select.js +4 -3
  276. package/dist/ssr/inputs/Select.js.map +1 -1
  277. package/dist/ssr/inputs/SelectChip.js +3 -2
  278. package/dist/ssr/inputs/SelectChip.js.map +1 -1
  279. package/dist/ssr/inputs/SpecialInputs.js +1 -0
  280. package/dist/ssr/inputs/SpecialInputs.js.map +1 -1
  281. package/dist/ssr/inputs/Switch.js.map +1 -1
  282. package/dist/ssr/inputs/TagEditor.js +3 -2
  283. package/dist/ssr/inputs/TagEditor.js.map +1 -1
  284. package/dist/ssr/inputs/TagsInput.js.map +1 -1
  285. package/dist/ssr/inputs/TemplateEditor.js +1 -0
  286. package/dist/ssr/inputs/TemplateEditor.js.map +1 -1
  287. package/dist/ssr/inputs/TextInput.js +6 -4
  288. package/dist/ssr/inputs/TextInput.js.map +1 -1
  289. package/dist/ssr/inputs/choice.js.map +1 -1
  290. package/dist/ssr/inputs/completion/behaviors.js.map +1 -1
  291. package/dist/ssr/inputs/completion/engine.js.map +1 -1
  292. package/dist/ssr/inputs/completion/index.js.map +1 -1
  293. package/dist/ssr/inputs/completion/overlay.js.map +1 -1
  294. package/dist/ssr/inputs/date-picker.js.map +1 -1
  295. package/dist/ssr/inputs/editor-dom.js.map +1 -1
  296. package/dist/ssr/inputs/field-contract.js.map +1 -1
  297. package/dist/ssr/inputs/icon-options.js.map +1 -1
  298. package/dist/ssr/inputs/image-crop.js.map +1 -1
  299. package/dist/ssr/inputs/index.js.map +1 -1
  300. package/dist/ssr/inputs/markdown/MarkdownEditor.js +3 -2
  301. package/dist/ssr/inputs/markdown/MarkdownEditor.js.map +1 -1
  302. package/dist/ssr/inputs/markdown/Toolbar.js.map +1 -1
  303. package/dist/ssr/inputs/markdown/actions.js.map +1 -1
  304. package/dist/ssr/inputs/markdown/active-formats.js.map +1 -1
  305. package/dist/ssr/inputs/markdown/behaviors.js.map +1 -1
  306. package/dist/ssr/inputs/markdown/code-zone.js.map +1 -1
  307. package/dist/ssr/internal/color.js.map +1 -1
  308. package/dist/ssr/internal/field.js.map +1 -1
  309. package/dist/ssr/internal/portal.js.map +1 -1
  310. package/dist/ssr/intl/Format.js.map +1 -1
  311. package/dist/ssr/intl/index.js.map +1 -1
  312. package/dist/ssr/intl/locale.js.map +1 -1
  313. package/dist/ssr/intl/messages.js +6 -0
  314. package/dist/ssr/intl/messages.js.map +1 -1
  315. package/dist/ssr/layout/AppOverview.js +2 -1
  316. package/dist/ssr/layout/AppOverview.js.map +1 -1
  317. package/dist/ssr/layout/AppWorkspace.js +7 -6
  318. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  319. package/dist/ssr/layout/BottomSheet.js.map +1 -1
  320. package/dist/ssr/layout/DataPanel.js +1 -0
  321. package/dist/ssr/layout/DataPanel.js.map +1 -1
  322. package/dist/ssr/layout/DetailPanel.js +1 -0
  323. package/dist/ssr/layout/DetailPanel.js.map +1 -1
  324. package/dist/ssr/layout/Discussion.js +3 -2
  325. package/dist/ssr/layout/Discussion.js.map +1 -1
  326. package/dist/ssr/layout/FloatingWindow.js +1 -0
  327. package/dist/ssr/layout/FloatingWindow.js.map +1 -1
  328. package/dist/ssr/layout/Navigation.js +3 -2
  329. package/dist/ssr/layout/Navigation.js.map +1 -1
  330. package/dist/ssr/layout/PanelDialog.js +1 -0
  331. package/dist/ssr/layout/PanelDialog.js.map +1 -1
  332. package/dist/ssr/layout/PanelHeader.js.map +1 -1
  333. package/dist/ssr/layout/Panes.js.map +1 -1
  334. package/dist/ssr/layout/PullToRefresh.js +1 -1
  335. package/dist/ssr/layout/PullToRefresh.js.map +1 -1
  336. package/dist/ssr/layout/ScrollArea.js.map +1 -1
  337. package/dist/ssr/layout/Settings.js +2 -1
  338. package/dist/ssr/layout/Settings.js.map +1 -1
  339. package/dist/ssr/layout/SettingsCollection.js +1 -0
  340. package/dist/ssr/layout/SettingsCollection.js.map +1 -1
  341. package/dist/ssr/layout/SettingsModal.js.map +1 -1
  342. package/dist/ssr/layout/SidebarItemPreview.js.map +1 -1
  343. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  344. package/dist/ssr/layout/app-workspace-state.js.map +1 -1
  345. package/dist/ssr/layout/floating-window-geometry.js.map +1 -1
  346. package/dist/ssr/layout/index.js.map +1 -1
  347. package/dist/ssr/layout/navigation-model.js.map +1 -1
  348. package/dist/ssr/layout/panes-layout.js.map +1 -1
  349. package/dist/ssr/layout/scroll-fade.js.map +1 -1
  350. package/dist/ssr/layout/stable-id.js.map +1 -1
  351. package/dist/ssr/surfaces/Avatar.js +2 -1
  352. package/dist/ssr/surfaces/Avatar.js.map +1 -1
  353. package/dist/ssr/surfaces/DescriptionList.js.map +1 -1
  354. package/dist/ssr/surfaces/LinkCard.js.map +1 -1
  355. package/dist/ssr/surfaces/NotFoundState.js.map +1 -1
  356. package/dist/ssr/surfaces/NoticeCard.js.map +1 -1
  357. package/dist/ssr/surfaces/Paper.js +2 -1
  358. package/dist/ssr/surfaces/Paper.js.map +1 -1
  359. package/dist/ssr/surfaces/Placeholder.js +2 -1
  360. package/dist/ssr/surfaces/Placeholder.js.map +1 -1
  361. package/dist/ssr/surfaces/ProgressBar.js.map +1 -1
  362. package/dist/ssr/surfaces/StatCell.js +2 -1
  363. package/dist/ssr/surfaces/StatCell.js.map +1 -1
  364. package/dist/ssr/surfaces/StatGrid.js +1 -0
  365. package/dist/ssr/surfaces/StatGrid.js.map +1 -1
  366. package/dist/ssr/surfaces/StatusBadge.js.map +1 -1
  367. package/dist/ssr/surfaces/Tag.js.map +1 -1
  368. package/dist/ssr/surfaces/index.js.map +1 -1
  369. package/dist/ssr/widgets/Widget.js +1 -0
  370. package/dist/ssr/widgets/Widget.js.map +1 -1
  371. package/dist/ssr/widgets/WidgetHero.js.map +1 -1
  372. package/dist/ssr/widgets/WidgetList.js.map +1 -1
  373. package/dist/ssr/widgets/WidgetPills.js.map +1 -1
  374. package/dist/ssr/widgets/WidgetStat.js +1 -0
  375. package/dist/ssr/widgets/WidgetStat.js.map +1 -1
  376. package/dist/ssr/widgets/WidgetStatus.js.map +1 -1
  377. package/dist/styles.css +1 -1
  378. package/dist/types/actions/Button.d.ts +5 -0
  379. package/dist/types/actions/SplitButton.d.ts +1 -1
  380. package/dist/types/actions/SpotlightSearch.d.ts +1 -1
  381. package/dist/types/actions/index.d.ts +1 -1
  382. package/dist/types/content/ZoomPanViewport.d.ts +33 -0
  383. package/dist/types/content/index.d.ts +2 -0
  384. package/dist/types/content/zoom-pan.d.ts +29 -0
  385. package/dist/types/feedback/prompts.d.ts +4 -3
  386. package/dist/types/intl/messages.d.ts +3 -0
  387. package/package.json +9 -10
@@ -0,0 +1,396 @@
1
+ import { template as _$template } from "solid-js/web";
2
+ import { delegateEvents as _$delegateEvents } from "solid-js/web";
3
+ import { setStyleProperty as _$setStyleProperty } from "solid-js/web";
4
+ import { style as _$style } from "solid-js/web";
5
+ import { use as _$use } from "solid-js/web";
6
+ import { runHydrationEvents as _$runHydrationEvents } from "solid-js/web";
7
+ import { addEventListener as _$addEventListener } from "solid-js/web";
8
+ import { setAttribute as _$setAttribute } from "solid-js/web";
9
+ import { getNextMarker as _$getNextMarker } from "solid-js/web";
10
+ import { insert as _$insert } from "solid-js/web";
11
+ import { className as _$className } from "solid-js/web";
12
+ import { effect as _$effect } from "solid-js/web";
13
+ import { getNextElement as _$getNextElement } from "solid-js/web";
14
+ import { memo as _$memo } from "solid-js/web";
15
+ import { createComponent as _$createComponent } from "solid-js/web";
16
+ var _tmpl$ = /*#__PURE__*/_$template(`<i aria-hidden=true>`),
17
+ _tmpl$2 = /*#__PURE__*/_$template(`<footer class=k2b-dialog__actions>`),
18
+ _tmpl$3 = /*#__PURE__*/_$template(`<div class="k2b-dialog__panel k2b-dialog__stack"><!$><!/><div class=k2b-zoom-pan-dialog><!$><!/><!$><!/>`),
19
+ _tmpl$4 = /*#__PURE__*/_$template(`<button type=button class="k2b-button k2b-icon-button"data-variant=secondary><i aria-hidden=true>`),
20
+ _tmpl$5 = /*#__PURE__*/_$template(`<div role=group tabindex=0><div class=k2b-zoom-pan__stage></div><div class=k2b-zoom-pan__controls><!$><!/><!$><!/><!$><!/><!$><!/>`);
21
+ import { createSignal, For, onCleanup, onMount, Show } from "solid-js";
22
+ import { Button } from "../actions/Button";
23
+ import { dialogCore } from "../feedback/dialog-core";
24
+ import { DialogHeader } from "../feedback/prompts";
25
+ import { LocaleProvider, useLocale } from "../intl/locale";
26
+ import { useUiMessages } from "../intl/messages";
27
+ import { clampZoomPan, panZoomPan, ZOOM_PAN_FIT, ZOOM_PAN_STEP, zoomZoomPanAt } from "./zoom-pan";
28
+ const PAN_KEY_STEP = 48;
29
+ const DRAG_THRESHOLD = 4;
30
+ const PAN_KEYS = {
31
+ ArrowLeft: [PAN_KEY_STEP, 0],
32
+ ArrowRight: [-PAN_KEY_STEP, 0],
33
+ ArrowUp: [0, PAN_KEY_STEP],
34
+ ArrowDown: [0, -PAN_KEY_STEP]
35
+ };
36
+
37
+ /** Current screen transform of the stage, including a running CSS transition. */
38
+ const renderedTransform = (stage, fallback) => {
39
+ const match = /^matrix\(([^)]+)\)$/.exec(getComputedStyle(stage).transform ?? "");
40
+ const values = match?.[1]?.split(",").map(Number);
41
+ if (!values || values.length !== 6 || values.some(value => !Number.isFinite(value)) || !values[0]) return fallback;
42
+ return {
43
+ scale: values[0],
44
+ x: values[4] ?? 0,
45
+ y: values[5] ?? 0
46
+ };
47
+ };
48
+ const ActionButton = props => {
49
+ const [pending, setPending] = createSignal(false);
50
+ const run = async () => {
51
+ if (pending()) return;
52
+ setPending(true);
53
+ try {
54
+ await props.action.onSelect();
55
+ } catch (error) {
56
+ console.error("Zoom-pan action failed", error);
57
+ } finally {
58
+ setPending(false);
59
+ }
60
+ };
61
+ return _$createComponent(Button, {
62
+ variant: "secondary",
63
+ get loading() {
64
+ return pending();
65
+ },
66
+ onClick: () => void run(),
67
+ get children() {
68
+ return [_$createComponent(Show, {
69
+ get when() {
70
+ return props.action.icon;
71
+ },
72
+ children: icon => (() => {
73
+ var _el$ = _$getNextElement(_tmpl$);
74
+ _$effect(() => _$className(_el$, icon()));
75
+ return _el$;
76
+ })()
77
+ }), _$memo(() => props.action.label)];
78
+ }
79
+ });
80
+ };
81
+
82
+ /**
83
+ * Makes any content zoomable (fit to 8×) and pannable with buttons, Ctrl/Cmd +
84
+ * wheel, pinch, drag, and keys. It applies a CSS transform, so vector content
85
+ * stays crisp and is never re-rendered. The view always starts at fit.
86
+ */
87
+ export function ZoomPanViewport(props) {
88
+ const messages = useUiMessages();
89
+ const locale = useLocale();
90
+ const [transform, setTransform] = createSignal(ZOOM_PAN_FIT);
91
+ const [smooth, setSmooth] = createSignal(false);
92
+ const [dragging, setDragging] = createSignal(false);
93
+ let root;
94
+ let stage;
95
+ const pointers = new Map();
96
+ let drag;
97
+ let pinch;
98
+ let suppressClick = false;
99
+ const zoomed = () => transform().scale > 1;
100
+ const geometry = () => {
101
+ const rect = root?.getBoundingClientRect();
102
+ const width = rect?.width ?? 0;
103
+ const height = rect?.height ?? 0;
104
+ const content = stage?.firstElementChild?.getBoundingClientRect();
105
+ if (!rect || !stage || !content || content.width <= 0 || content.height <= 0) {
106
+ return {
107
+ width,
108
+ height,
109
+ content: {
110
+ left: 0,
111
+ top: 0,
112
+ width,
113
+ height
114
+ }
115
+ };
116
+ }
117
+ const current = renderedTransform(stage, transform());
118
+ return {
119
+ width,
120
+ height,
121
+ content: {
122
+ left: (content.left - rect.left - current.x) / current.scale,
123
+ top: (content.top - rect.top - current.y) / current.scale,
124
+ width: content.width / current.scale,
125
+ height: content.height / current.scale
126
+ }
127
+ };
128
+ };
129
+ const apply = (next, animate) => {
130
+ setSmooth(animate);
131
+ setTransform(next);
132
+ };
133
+ const local = event => {
134
+ const rect = root?.getBoundingClientRect();
135
+ return {
136
+ x: event.clientX - (rect?.left ?? 0),
137
+ y: event.clientY - (rect?.top ?? 0)
138
+ };
139
+ };
140
+ const zoomBy = (factor, point, animate = true) => {
141
+ const box = geometry();
142
+ const current = transform();
143
+ apply(zoomZoomPanAt(current, current.scale * factor, point ?? {
144
+ x: box.width / 2,
145
+ y: box.height / 2
146
+ }, box), animate);
147
+ };
148
+ const reset = () => apply(ZOOM_PAN_FIT, true);
149
+ const openFullscreen = () => {
150
+ const fullscreen = props.fullscreen;
151
+ if (!fullscreen) return;
152
+ const currentLocale = locale();
153
+ void dialogCore.open(close => _$createComponent(LocaleProvider, {
154
+ locale: currentLocale,
155
+ get children() {
156
+ var _el$2 = _$getNextElement(_tmpl$3),
157
+ _el$9 = _el$2.firstChild,
158
+ [_el$0, _co$3] = _$getNextMarker(_el$9.nextSibling),
159
+ _el$3 = _el$0.nextSibling,
160
+ _el$5 = _el$3.firstChild,
161
+ [_el$6, _co$] = _$getNextMarker(_el$5.nextSibling),
162
+ _el$7 = _el$6.nextSibling,
163
+ [_el$8, _co$2] = _$getNextMarker(_el$7.nextSibling);
164
+ _$insert(_el$2, _$createComponent(DialogHeader, {
165
+ get title() {
166
+ return fullscreen.title;
167
+ },
168
+ close: () => close()
169
+ }), _el$0, _co$3);
170
+ _$insert(_el$3, _$createComponent(ZoomPanViewport, {
171
+ get label() {
172
+ return props.label;
173
+ },
174
+ get children() {
175
+ return fullscreen.content();
176
+ }
177
+ }), _el$6, _co$);
178
+ _$insert(_el$3, _$createComponent(Show, {
179
+ get when() {
180
+ return fullscreen.actions?.length;
181
+ },
182
+ get children() {
183
+ var _el$4 = _$getNextElement(_tmpl$2);
184
+ _$insert(_el$4, _$createComponent(For, {
185
+ get each() {
186
+ return fullscreen.actions;
187
+ },
188
+ children: action => _$createComponent(ActionButton, {
189
+ action: action
190
+ })
191
+ }));
192
+ return _el$4;
193
+ }
194
+ }), _el$8, _co$2);
195
+ return _el$2;
196
+ }
197
+ }), {
198
+ panelClassName: "k2b-dialog k2b-dialog--full",
199
+ ariaLabel: fullscreen.title,
200
+ initialFocus: dialog => dialog.querySelector(".k2b-zoom-pan")
201
+ });
202
+ };
203
+ const handleKeyDown = event => {
204
+ if (event.target !== root || event.ctrlKey || event.metaKey || event.altKey) return;
205
+ const key = event.key;
206
+ if (key === "+" || key === "=") zoomBy(ZOOM_PAN_STEP);else if (key === "-" || key === "_") zoomBy(1 / ZOOM_PAN_STEP);else if (key === "0") reset();else if ((key === "f" || key === "F") && props.fullscreen) openFullscreen();else {
207
+ const delta = PAN_KEYS[key];
208
+ // At fit the arrow keys keep scrolling the page.
209
+ if (!delta || !zoomed()) return;
210
+ apply(panZoomPan(transform(), delta[0], delta[1], geometry()), true);
211
+ }
212
+ event.preventDefault();
213
+ };
214
+
215
+ // Plain wheel keeps scrolling the page; Ctrl/Cmd + wheel (and trackpad pinch) zooms toward the pointer.
216
+ const handleWheel = event => {
217
+ if (!event.ctrlKey && !event.metaKey) return;
218
+ event.preventDefault();
219
+ const lines = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? 400 : 1;
220
+ const delta = Math.max(-50, Math.min(50, event.deltaY * lines));
221
+ zoomBy(Math.exp(-delta / 100), local(event), false);
222
+ };
223
+ const handlePointerDown = event => {
224
+ if (event.button !== 0 || event.target.closest("button, a, input, select, textarea")) return;
225
+ pointers.set(event.pointerId, local(event));
226
+ if (pointers.size === 2) {
227
+ const [first, second] = [...pointers.values()];
228
+ pinch = {
229
+ distance: Math.max(1, Math.hypot(second.x - first.x, second.y - first.y)),
230
+ center: {
231
+ x: (first.x + second.x) / 2,
232
+ y: (first.y + second.y) / 2
233
+ },
234
+ origin: transform()
235
+ };
236
+ drag = undefined;
237
+ } else if (pointers.size === 1 && zoomed()) {
238
+ // Panning starts only above fit, so clicks and text selection keep working at fit.
239
+ drag = {
240
+ id: event.pointerId,
241
+ x: event.clientX,
242
+ y: event.clientY,
243
+ origin: transform(),
244
+ moved: false
245
+ };
246
+ } else return;
247
+ try {
248
+ event.currentTarget.setPointerCapture(event.pointerId);
249
+ } catch {
250
+ // A synthetic or already released pointer cannot be captured; moves still arrive while inside.
251
+ }
252
+ };
253
+ const handlePointerMove = event => {
254
+ if (!pointers.has(event.pointerId)) return;
255
+ pointers.set(event.pointerId, local(event));
256
+ if (pinch && pointers.size >= 2) {
257
+ const [first, second] = [...pointers.values()];
258
+ const distance = Math.hypot(second.x - first.x, second.y - first.y);
259
+ const center = {
260
+ x: (first.x + second.x) / 2,
261
+ y: (first.y + second.y) / 2
262
+ };
263
+ const box = geometry();
264
+ const scaled = zoomZoomPanAt(pinch.origin, pinch.origin.scale * (distance / pinch.distance), pinch.center, box);
265
+ apply(panZoomPan(scaled, center.x - pinch.center.x, center.y - pinch.center.y, box), false);
266
+ return;
267
+ }
268
+ if (drag?.id !== event.pointerId) return;
269
+ const dx = event.clientX - drag.x;
270
+ const dy = event.clientY - drag.y;
271
+ if (!drag.moved && Math.hypot(dx, dy) < DRAG_THRESHOLD) return;
272
+ drag.moved = true;
273
+ setDragging(true);
274
+ apply(panZoomPan(drag.origin, dx, dy, geometry()), false);
275
+ };
276
+ const handlePointerEnd = event => {
277
+ pointers.delete(event.pointerId);
278
+ if (pointers.size < 2) pinch = undefined;
279
+ if (drag?.id !== event.pointerId) return;
280
+ if (drag.moved) {
281
+ // The click that follows this pointerup (if the browser sends one) comes in the same task.
282
+ suppressClick = true;
283
+ setTimeout(() => {
284
+ suppressClick = false;
285
+ });
286
+ }
287
+ drag = undefined;
288
+ setDragging(false);
289
+ };
290
+ onMount(() => {
291
+ const element = root;
292
+ if (!element) return;
293
+ // A drag must not also count as a click on the content or its owner.
294
+ const click = event => {
295
+ if (!suppressClick) return;
296
+ suppressClick = false;
297
+ event.preventDefault();
298
+ event.stopPropagation();
299
+ };
300
+ // Keep a two-finger gesture for pinch zoom instead of page panning.
301
+ const touchMove = event => {
302
+ if (event.touches.length > 1) event.preventDefault();
303
+ };
304
+ element.addEventListener("click", click, true);
305
+ element.addEventListener("touchmove", touchMove, {
306
+ passive: false
307
+ });
308
+ const observer = typeof ResizeObserver === "undefined" ? undefined : new ResizeObserver(() => apply(clampZoomPan(transform(), geometry()), false));
309
+ observer?.observe(element);
310
+ onCleanup(() => {
311
+ element.removeEventListener("click", click, true);
312
+ element.removeEventListener("touchmove", touchMove);
313
+ observer?.disconnect();
314
+ });
315
+ });
316
+ const control = (label, shortcut, icon, action) => (() => {
317
+ var _el$1 = _$getNextElement(_tmpl$4),
318
+ _el$10 = _el$1.firstChild;
319
+ _$addEventListener(_el$1, "click", action, true);
320
+ _$setAttribute(_el$1, "aria-label", label);
321
+ _$setAttribute(_el$1, "title", `${label} (${shortcut})`);
322
+ _$className(_el$10, `ti ${icon}`);
323
+ _$runHydrationEvents();
324
+ return _el$1;
325
+ })();
326
+ return (() => {
327
+ var _el$11 = _$getNextElement(_tmpl$5),
328
+ _el$12 = _el$11.firstChild,
329
+ _el$13 = _el$12.nextSibling,
330
+ _el$14 = _el$13.firstChild,
331
+ [_el$15, _co$4] = _$getNextMarker(_el$14.nextSibling),
332
+ _el$16 = _el$15.nextSibling,
333
+ [_el$17, _co$5] = _$getNextMarker(_el$16.nextSibling),
334
+ _el$18 = _el$17.nextSibling,
335
+ [_el$19, _co$6] = _$getNextMarker(_el$18.nextSibling),
336
+ _el$20 = _el$19.nextSibling,
337
+ [_el$21, _co$7] = _$getNextMarker(_el$20.nextSibling);
338
+ _el$11.addEventListener("pointercancel", handlePointerEnd);
339
+ _el$11.$$pointerup = handlePointerEnd;
340
+ _el$11.$$pointermove = handlePointerMove;
341
+ _el$11.$$pointerdown = handlePointerDown;
342
+ _el$11.addEventListener("wheel", handleWheel);
343
+ _el$11.$$keydown = handleKeyDown;
344
+ var _ref$ = root;
345
+ typeof _ref$ === "function" ? _$use(_ref$, _el$11) : root = _el$11;
346
+ var _ref$2 = stage;
347
+ typeof _ref$2 === "function" ? _$use(_ref$2, _el$12) : stage = _el$12;
348
+ _$insert(_el$12, () => props.children);
349
+ _$insert(_el$13, () => control(messages().zoomIn, "+", "ti-plus", () => zoomBy(ZOOM_PAN_STEP)), _el$15, _co$4);
350
+ _$insert(_el$13, () => control(messages().zoomOut, "-", "ti-minus", () => zoomBy(1 / ZOOM_PAN_STEP)), _el$17, _co$5);
351
+ _$insert(_el$13, () => control(messages().resetZoom, "0", "ti-focus-centered", reset), _el$19, _co$6);
352
+ _$insert(_el$13, _$createComponent(Show, {
353
+ get when() {
354
+ return props.fullscreen;
355
+ },
356
+ get children() {
357
+ return control(messages().openFullscreen, "F", "ti-maximize", openFullscreen);
358
+ }
359
+ }), _el$21, _co$7);
360
+ _$effect(_p$ => {
361
+ var _v$ = `k2b-zoom-pan ${props.class ?? ""}`,
362
+ _v$2 = props.style,
363
+ _v$3 = props.label,
364
+ _v$4 = messages().zoomPanKeys,
365
+ _v$5 = props.controls ?? "visible",
366
+ _v$6 = zoomed() ? "true" : undefined,
367
+ _v$7 = dragging() ? "true" : undefined,
368
+ _v$8 = smooth() ? "true" : undefined,
369
+ _v$9 = `translate(${transform().x}px, ${transform().y}px) scale(${transform().scale})`;
370
+ _v$ !== _p$.e && _$className(_el$11, _p$.e = _v$);
371
+ _p$.t = _$style(_el$11, _v$2, _p$.t);
372
+ _v$3 !== _p$.a && _$setAttribute(_el$11, "aria-label", _p$.a = _v$3);
373
+ _v$4 !== _p$.o && _$setAttribute(_el$11, "aria-description", _p$.o = _v$4);
374
+ _v$5 !== _p$.i && _$setAttribute(_el$11, "data-controls", _p$.i = _v$5);
375
+ _v$6 !== _p$.n && _$setAttribute(_el$11, "data-zoomed", _p$.n = _v$6);
376
+ _v$7 !== _p$.s && _$setAttribute(_el$11, "data-dragging", _p$.s = _v$7);
377
+ _v$8 !== _p$.h && _$setAttribute(_el$12, "data-smooth", _p$.h = _v$8);
378
+ _v$9 !== _p$.r && _$setStyleProperty(_el$12, "transform", _p$.r = _v$9);
379
+ return _p$;
380
+ }, {
381
+ e: undefined,
382
+ t: undefined,
383
+ a: undefined,
384
+ o: undefined,
385
+ i: undefined,
386
+ n: undefined,
387
+ s: undefined,
388
+ h: undefined,
389
+ r: undefined
390
+ });
391
+ _$runHydrationEvents();
392
+ return _el$11;
393
+ })();
394
+ }
395
+ _$delegateEvents(["click", "keydown", "pointerdown", "pointermove", "pointerup"]);
396
+ //# sourceMappingURL=ZoomPanViewport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["content/ZoomPanViewport.tsx"],"sourcesContent":["import { createSignal, For, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { Button } from \"../actions/Button\";\nimport { dialogCore } from \"../feedback/dialog-core\";\nimport { DialogHeader } from \"../feedback/prompts\";\nimport { LocaleProvider, useLocale } from \"../intl/locale\";\nimport { useUiMessages } from \"../intl/messages\";\nimport {\n clampZoomPan,\n panZoomPan,\n ZOOM_PAN_FIT,\n ZOOM_PAN_STEP,\n type ZoomPanGeometry,\n type ZoomPanTransform,\n zoomZoomPanAt,\n} from \"./zoom-pan\";\n\nexport type ZoomPanAction = {\n label: string;\n icon?: string;\n /** Runs the action; the button shows a pending state until a returned promise settles. Handle failures here. */\n onSelect: () => void | Promise<void>;\n};\n\nexport type ZoomPanFullscreen = {\n /** Heading and accessible name of the fullscreen dialog. */\n title: string;\n /** Renders a fresh copy of the content for the dialog. Called once per opening. */\n content: () => JSX.Element;\n /** Actions shown in the fullscreen dialog, for example exports. */\n actions?: readonly ZoomPanAction[];\n};\n\nexport type ZoomPanViewportProps = {\n /** Accessible name of the focusable viewport. */\n label: string;\n /** The zoomable content. Its first element is measured to keep it on screen. */\n children: JSX.Element;\n /** Enables the fullscreen control and the `F` shortcut. */\n fullscreen?: ZoomPanFullscreen;\n /** `hover` reveals the controls on hover, on focus, and while zoomed in. Touch screens always show them. */\n controls?: \"visible\" | \"hover\";\n class?: string;\n style?: JSX.CSSProperties;\n};\n\nconst PAN_KEY_STEP = 48;\nconst DRAG_THRESHOLD = 4;\nconst PAN_KEYS: Record<string, readonly [number, number]> = {\n ArrowLeft: [PAN_KEY_STEP, 0],\n ArrowRight: [-PAN_KEY_STEP, 0],\n ArrowUp: [0, PAN_KEY_STEP],\n ArrowDown: [0, -PAN_KEY_STEP],\n};\n\n/** Current screen transform of the stage, including a running CSS transition. */\nconst renderedTransform = (stage: HTMLElement, fallback: ZoomPanTransform): ZoomPanTransform => {\n const match = /^matrix\\(([^)]+)\\)$/.exec(getComputedStyle(stage).transform ?? \"\");\n const values = match?.[1]?.split(\",\").map(Number);\n if (!values || values.length !== 6 || values.some((value) => !Number.isFinite(value)) || !values[0]) return fallback;\n return { scale: values[0], x: values[4] ?? 0, y: values[5] ?? 0 };\n};\n\nconst ActionButton = (props: { action: ZoomPanAction }): JSX.Element => {\n const [pending, setPending] = createSignal(false);\n const run = async () => {\n if (pending()) return;\n setPending(true);\n try {\n await props.action.onSelect();\n } catch (error) {\n console.error(\"Zoom-pan action failed\", error);\n } finally {\n setPending(false);\n }\n };\n return (\n <Button variant=\"secondary\" loading={pending()} onClick={() => void run()}>\n <Show when={props.action.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n {props.action.label}\n </Button>\n );\n};\n\n/**\n * Makes any content zoomable (fit to 8×) and pannable with buttons, Ctrl/Cmd +\n * wheel, pinch, drag, and keys. It applies a CSS transform, so vector content\n * stays crisp and is never re-rendered. The view always starts at fit.\n */\nexport function ZoomPanViewport(props: ZoomPanViewportProps): JSX.Element {\n const messages = useUiMessages();\n const locale = useLocale();\n const [transform, setTransform] = createSignal<ZoomPanTransform>(ZOOM_PAN_FIT);\n const [smooth, setSmooth] = createSignal(false);\n const [dragging, setDragging] = createSignal(false);\n let root: HTMLDivElement | undefined;\n let stage: HTMLDivElement | undefined;\n const pointers = new Map<number, { x: number; y: number }>();\n let drag: { id: number; x: number; y: number; origin: ZoomPanTransform; moved: boolean } | undefined;\n let pinch: { distance: number; center: { x: number; y: number }; origin: ZoomPanTransform } | undefined;\n let suppressClick = false;\n\n const zoomed = () => transform().scale > 1;\n\n const geometry = (): ZoomPanGeometry => {\n const rect = root?.getBoundingClientRect();\n const width = rect?.width ?? 0;\n const height = rect?.height ?? 0;\n const content = stage?.firstElementChild?.getBoundingClientRect();\n if (!rect || !stage || !content || content.width <= 0 || content.height <= 0) {\n return { width, height, content: { left: 0, top: 0, width, height } };\n }\n const current = renderedTransform(stage, transform());\n return {\n width,\n height,\n content: {\n left: (content.left - rect.left - current.x) / current.scale,\n top: (content.top - rect.top - current.y) / current.scale,\n width: content.width / current.scale,\n height: content.height / current.scale,\n },\n };\n };\n\n const apply = (next: ZoomPanTransform, animate: boolean) => {\n setSmooth(animate);\n setTransform(next);\n };\n\n const local = (event: { clientX: number; clientY: number }) => {\n const rect = root?.getBoundingClientRect();\n return { x: event.clientX - (rect?.left ?? 0), y: event.clientY - (rect?.top ?? 0) };\n };\n\n const zoomBy = (factor: number, point?: { x: number; y: number }, animate = true) => {\n const box = geometry();\n const current = transform();\n apply(zoomZoomPanAt(current, current.scale * factor, point ?? { x: box.width / 2, y: box.height / 2 }, box), animate);\n };\n\n const reset = () => apply(ZOOM_PAN_FIT, true);\n\n const openFullscreen = () => {\n const fullscreen = props.fullscreen;\n if (!fullscreen) return;\n const currentLocale = locale();\n void dialogCore.open<void>(\n (close) => (\n <LocaleProvider locale={currentLocale}>\n <div class=\"k2b-dialog__panel k2b-dialog__stack\">\n <DialogHeader title={fullscreen.title} close={() => close()} />\n <div class=\"k2b-zoom-pan-dialog\">\n <ZoomPanViewport label={props.label}>{fullscreen.content()}</ZoomPanViewport>\n <Show when={fullscreen.actions?.length}>\n <footer class=\"k2b-dialog__actions\">\n <For each={fullscreen.actions}>{(action) => <ActionButton action={action} />}</For>\n </footer>\n </Show>\n </div>\n </div>\n </LocaleProvider>\n ),\n {\n panelClassName: \"k2b-dialog k2b-dialog--full\",\n ariaLabel: fullscreen.title,\n initialFocus: (dialog) => dialog.querySelector<HTMLElement>(\".k2b-zoom-pan\"),\n },\n );\n };\n\n const handleKeyDown: JSX.EventHandler<HTMLDivElement, KeyboardEvent> = (event) => {\n if (event.target !== root || event.ctrlKey || event.metaKey || event.altKey) return;\n const key = event.key;\n if (key === \"+\" || key === \"=\") zoomBy(ZOOM_PAN_STEP);\n else if (key === \"-\" || key === \"_\") zoomBy(1 / ZOOM_PAN_STEP);\n else if (key === \"0\") reset();\n else if ((key === \"f\" || key === \"F\") && props.fullscreen) openFullscreen();\n else {\n const delta = PAN_KEYS[key];\n // At fit the arrow keys keep scrolling the page.\n if (!delta || !zoomed()) return;\n apply(panZoomPan(transform(), delta[0], delta[1], geometry()), true);\n }\n event.preventDefault();\n };\n\n // Plain wheel keeps scrolling the page; Ctrl/Cmd + wheel (and trackpad pinch) zooms toward the pointer.\n const handleWheel: JSX.EventHandler<HTMLDivElement, WheelEvent> = (event) => {\n if (!event.ctrlKey && !event.metaKey) return;\n event.preventDefault();\n const lines = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? 400 : 1;\n const delta = Math.max(-50, Math.min(50, event.deltaY * lines));\n zoomBy(Math.exp(-delta / 100), local(event), false);\n };\n\n const handlePointerDown: JSX.EventHandler<HTMLDivElement, PointerEvent> = (event) => {\n if (event.button !== 0 || (event.target as Element).closest(\"button, a, input, select, textarea\")) return;\n pointers.set(event.pointerId, local(event));\n if (pointers.size === 2) {\n const [first, second] = [...pointers.values()] as [{ x: number; y: number }, { x: number; y: number }];\n pinch = {\n distance: Math.max(1, Math.hypot(second.x - first.x, second.y - first.y)),\n center: { x: (first.x + second.x) / 2, y: (first.y + second.y) / 2 },\n origin: transform(),\n };\n drag = undefined;\n } else if (pointers.size === 1 && zoomed()) {\n // Panning starts only above fit, so clicks and text selection keep working at fit.\n drag = { id: event.pointerId, x: event.clientX, y: event.clientY, origin: transform(), moved: false };\n } else return;\n try {\n event.currentTarget.setPointerCapture(event.pointerId);\n } catch {\n // A synthetic or already released pointer cannot be captured; moves still arrive while inside.\n }\n };\n\n const handlePointerMove: JSX.EventHandler<HTMLDivElement, PointerEvent> = (event) => {\n if (!pointers.has(event.pointerId)) return;\n pointers.set(event.pointerId, local(event));\n if (pinch && pointers.size >= 2) {\n const [first, second] = [...pointers.values()] as [{ x: number; y: number }, { x: number; y: number }];\n const distance = Math.hypot(second.x - first.x, second.y - first.y);\n const center = { x: (first.x + second.x) / 2, y: (first.y + second.y) / 2 };\n const box = geometry();\n const scaled = zoomZoomPanAt(pinch.origin, pinch.origin.scale * (distance / pinch.distance), pinch.center, box);\n apply(panZoomPan(scaled, center.x - pinch.center.x, center.y - pinch.center.y, box), false);\n return;\n }\n if (drag?.id !== event.pointerId) return;\n const dx = event.clientX - drag.x;\n const dy = event.clientY - drag.y;\n if (!drag.moved && Math.hypot(dx, dy) < DRAG_THRESHOLD) return;\n drag.moved = true;\n setDragging(true);\n apply(panZoomPan(drag.origin, dx, dy, geometry()), false);\n };\n\n const handlePointerEnd: JSX.EventHandler<HTMLDivElement, PointerEvent> = (event) => {\n pointers.delete(event.pointerId);\n if (pointers.size < 2) pinch = undefined;\n if (drag?.id !== event.pointerId) return;\n if (drag.moved) {\n // The click that follows this pointerup (if the browser sends one) comes in the same task.\n suppressClick = true;\n setTimeout(() => {\n suppressClick = false;\n });\n }\n drag = undefined;\n setDragging(false);\n };\n\n onMount(() => {\n const element = root;\n if (!element) return;\n // A drag must not also count as a click on the content or its owner.\n const click = (event: MouseEvent) => {\n if (!suppressClick) return;\n suppressClick = false;\n event.preventDefault();\n event.stopPropagation();\n };\n // Keep a two-finger gesture for pinch zoom instead of page panning.\n const touchMove = (event: TouchEvent) => {\n if (event.touches.length > 1) event.preventDefault();\n };\n element.addEventListener(\"click\", click, true);\n element.addEventListener(\"touchmove\", touchMove, { passive: false });\n const observer =\n typeof ResizeObserver === \"undefined\" ? undefined : new ResizeObserver(() => apply(clampZoomPan(transform(), geometry()), false));\n observer?.observe(element);\n onCleanup(() => {\n element.removeEventListener(\"click\", click, true);\n element.removeEventListener(\"touchmove\", touchMove);\n observer?.disconnect();\n });\n });\n\n const control = (label: string, shortcut: string, icon: string, action: () => void) => (\n <button\n type=\"button\"\n class=\"k2b-button k2b-icon-button\"\n data-variant=\"secondary\"\n aria-label={label}\n title={`${label} (${shortcut})`}\n onClick={action}\n >\n <i class={`ti ${icon}`} aria-hidden=\"true\" />\n </button>\n );\n\n return (\n <div\n ref={root}\n class={`k2b-zoom-pan ${props.class ?? \"\"}`}\n style={props.style}\n role=\"group\"\n aria-label={props.label}\n aria-description={messages().zoomPanKeys}\n tabIndex={0}\n data-controls={props.controls ?? \"visible\"}\n data-zoomed={zoomed() ? \"true\" : undefined}\n data-dragging={dragging() ? \"true\" : undefined}\n onKeyDown={handleKeyDown}\n onWheel={handleWheel}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerEnd}\n onPointerCancel={handlePointerEnd}\n >\n <div\n ref={stage}\n class=\"k2b-zoom-pan__stage\"\n data-smooth={smooth() ? \"true\" : undefined}\n style={{ transform: `translate(${transform().x}px, ${transform().y}px) scale(${transform().scale})` }}\n >\n {props.children}\n </div>\n <div class=\"k2b-zoom-pan__controls\">\n {control(messages().zoomIn, \"+\", \"ti-plus\", () => zoomBy(ZOOM_PAN_STEP))}\n {control(messages().zoomOut, \"-\", \"ti-minus\", () => zoomBy(1 / ZOOM_PAN_STEP))}\n {control(messages().resetZoom, \"0\", \"ti-focus-centered\", reset)}\n <Show when={props.fullscreen}>{control(messages().openFullscreen, \"F\", \"ti-maximize\", openFullscreen)}</Show>\n </div>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["heapPush","heap","value","before","push","index","length","parent","Math","floor","heapPop","first","last","pop","undefined","left","right","next","layoutGroup","group","groupId","active","freeLanes","assigned","laneCount","entry","end","start","released","lane","item","groupStart","groupEnd","reduce","latest","max","map","lanes","layoutCalendarIntervals","items","bounds","sorted","interval","sort","groups","Number","NEGATIVE_INFINITY","flatMap","entries"],"sources":["content/calendar-event-layout.ts"],"sourcesContent":["export type CalendarIntervalLayout<T> = {\n item: T;\n lane: number;\n lanes: number;\n groupId: number;\n groupStart: number;\n groupEnd: number;\n};\n\ntype BoundedItem<T> = {\n item: T;\n start: number;\n end: number;\n};\n\ntype ActiveLane = {\n end: number;\n lane: number;\n};\n\nconst heapPush = <T>(heap: T[], value: T, before: (left: T, right: T) => boolean): void => {\n heap.push(value);\n let index = heap.length - 1;\n while (index > 0) {\n const parent = Math.floor((index - 1) / 2);\n if (!before(heap[index]!, heap[parent]!)) break;\n [heap[parent], heap[index]] = [heap[index]!, heap[parent]!];\n index = parent;\n }\n};\n\nconst heapPop = <T>(heap: T[], before: (left: T, right: T) => boolean): T | undefined => {\n const first = heap[0];\n const last = heap.pop();\n if (heap.length === 0 || last === undefined) return first;\n heap[0] = last;\n let index = 0;\n while (true) {\n const left = index * 2 + 1;\n const right = left + 1;\n let next = index;\n if (left < heap.length && before(heap[left]!, heap[next]!)) next = left;\n if (right < heap.length && before(heap[right]!, heap[next]!)) next = right;\n if (next === index) return first;\n [heap[index], heap[next]] = [heap[next]!, heap[index]!];\n index = next;\n }\n};\n\nconst layoutGroup = <T>(group: readonly BoundedItem<T>[], groupId: number): CalendarIntervalLayout<T>[] => {\n const active: ActiveLane[] = [];\n const freeLanes: number[] = [];\n const assigned: Array<{ item: T; lane: number }> = [];\n let laneCount = 0;\n\n for (const entry of group) {\n while (active[0] && active[0].end <= entry.start) {\n const released = heapPop(active, (left, right) => left.end < right.end || (left.end === right.end && left.lane < right.lane));\n if (released) heapPush(freeLanes, released.lane, (left, right) => left < right);\n }\n const lane = heapPop(freeLanes, (left, right) => left < right) ?? laneCount++;\n heapPush(active, { end: entry.end, lane }, (left, right) => left.end < right.end || (left.end === right.end && left.lane < right.lane));\n assigned.push({ item: entry.item, lane });\n }\n\n const groupStart = group[0]?.start ?? 0;\n const groupEnd = group.reduce((latest, entry) => Math.max(latest, entry.end), groupStart);\n return assigned.map(({ item, lane }) => ({ item, lane, lanes: Math.max(1, laneCount), groupId, groupStart, groupEnd }));\n};\n\n/**\n * Assigns the lowest available visual lane to overlapping intervals.\n * Sorting plus two binary heaps keeps large overlap groups at O(n log n).\n */\nexport const layoutCalendarIntervals = <T>(\n items: readonly T[],\n bounds: (item: T) => { start: number; end: number },\n): CalendarIntervalLayout<T>[] => {\n const sorted = items\n .map((item) => {\n const interval = bounds(item);\n return { item, start: interval.start, end: Math.max(interval.start, interval.end) };\n })\n .sort((left, right) => left.start - right.start || right.end - left.end);\n const groups: Array<Array<BoundedItem<T>>> = [];\n let group: Array<BoundedItem<T>> = [];\n let groupEnd = Number.NEGATIVE_INFINITY;\n\n for (const entry of sorted) {\n if (group.length === 0 || entry.start < groupEnd) {\n group.push(entry);\n groupEnd = Math.max(groupEnd, entry.end);\n continue;\n }\n groups.push(group);\n group = [entry];\n groupEnd = entry.end;\n }\n if (group.length > 0) groups.push(group);\n\n return groups.flatMap((entries, groupId) => layoutGroup(entries, groupId));\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/calendar-event-layout.ts"],"sourcesContent":["export type CalendarIntervalLayout<T> = {\n item: T;\n lane: number;\n lanes: number;\n groupId: number;\n groupStart: number;\n groupEnd: number;\n};\n\ntype BoundedItem<T> = {\n item: T;\n start: number;\n end: number;\n};\n\ntype ActiveLane = {\n end: number;\n lane: number;\n};\n\nconst heapPush = <T>(heap: T[], value: T, before: (left: T, right: T) => boolean): void => {\n heap.push(value);\n let index = heap.length - 1;\n while (index > 0) {\n const parent = Math.floor((index - 1) / 2);\n if (!before(heap[index]!, heap[parent]!)) break;\n [heap[parent], heap[index]] = [heap[index]!, heap[parent]!];\n index = parent;\n }\n};\n\nconst heapPop = <T>(heap: T[], before: (left: T, right: T) => boolean): T | undefined => {\n const first = heap[0];\n const last = heap.pop();\n if (heap.length === 0 || last === undefined) return first;\n heap[0] = last;\n let index = 0;\n while (true) {\n const left = index * 2 + 1;\n const right = left + 1;\n let next = index;\n if (left < heap.length && before(heap[left]!, heap[next]!)) next = left;\n if (right < heap.length && before(heap[right]!, heap[next]!)) next = right;\n if (next === index) return first;\n [heap[index], heap[next]] = [heap[next]!, heap[index]!];\n index = next;\n }\n};\n\nconst layoutGroup = <T>(group: readonly BoundedItem<T>[], groupId: number): CalendarIntervalLayout<T>[] => {\n const active: ActiveLane[] = [];\n const freeLanes: number[] = [];\n const assigned: Array<{ item: T; lane: number }> = [];\n let laneCount = 0;\n\n for (const entry of group) {\n while (active[0] && active[0].end <= entry.start) {\n const released = heapPop(active, (left, right) => left.end < right.end || (left.end === right.end && left.lane < right.lane));\n if (released) heapPush(freeLanes, released.lane, (left, right) => left < right);\n }\n const lane = heapPop(freeLanes, (left, right) => left < right) ?? laneCount++;\n heapPush(active, { end: entry.end, lane }, (left, right) => left.end < right.end || (left.end === right.end && left.lane < right.lane));\n assigned.push({ item: entry.item, lane });\n }\n\n const groupStart = group[0]?.start ?? 0;\n const groupEnd = group.reduce((latest, entry) => Math.max(latest, entry.end), groupStart);\n return assigned.map(({ item, lane }) => ({ item, lane, lanes: Math.max(1, laneCount), groupId, groupStart, groupEnd }));\n};\n\n/**\n * Assigns the lowest available visual lane to overlapping intervals.\n * Sorting plus two binary heaps keeps large overlap groups at O(n log n).\n */\nexport const layoutCalendarIntervals = <T>(\n items: readonly T[],\n bounds: (item: T) => { start: number; end: number },\n): CalendarIntervalLayout<T>[] => {\n const sorted = items\n .map((item) => {\n const interval = bounds(item);\n return { item, start: interval.start, end: Math.max(interval.start, interval.end) };\n })\n .sort((left, right) => left.start - right.start || right.end - left.end);\n const groups: Array<Array<BoundedItem<T>>> = [];\n let group: Array<BoundedItem<T>> = [];\n let groupEnd = Number.NEGATIVE_INFINITY;\n\n for (const entry of sorted) {\n if (group.length === 0 || entry.start < groupEnd) {\n group.push(entry);\n groupEnd = Math.max(groupEnd, entry.end);\n continue;\n }\n groups.push(group);\n group = [entry];\n groupEnd = entry.end;\n }\n if (group.length > 0) groups.push(group);\n\n return groups.flatMap((entries, groupId) => layoutGroup(entries, groupId));\n};\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["CALENDAR_SNAP_MINUTES","snapCalendarMinutes","minutes","step","Math","round","calendarDayIndexAtPoint","clientX","startX","width","days","min","floor","calendarMinuteAtPoint","clientY","top","height","startHour","endHour","totalMinutes","max","ratio","calendarAutoScrollSpeed","bottom","edge","maximum","ceil","cancelActiveSession","startCalendarPointerSession","options","event","button","isPrimary","pointerId","target","currentTarget","HTMLElement","startY","threshold","previousUserSelect","document","body","style","userSelect","active","finished","latest","scrollFrame","preview","value","resolve","onPreview","autoScroll","scrollContainer","rect","getBoundingClientRect","speed","before","scrollTop","requestAnimationFrame","cleanup","cancelAnimationFrame","window","removeEventListener","onMove","onUp","cancel","onKeyDown","hasPointerCapture","releasePointerCapture","activate","setPointerCapture","onActivate","onCancel","hypot","preventDefault","onCommit","key","addEventListener","passive"],"sources":["content/calendar-pointer.ts"],"sourcesContent":["export const CALENDAR_SNAP_MINUTES = 15;\n\nexport const snapCalendarMinutes = (minutes: number, step = CALENDAR_SNAP_MINUTES): number => Math.round(minutes / step) * step;\n\nexport const calendarDayIndexAtPoint = (clientX: number, startX: number, width: number, days: number): number | null => {\n if (days <= 0 || width <= 0 || clientX < startX || clientX >= startX + width) return null;\n return Math.min(days - 1, Math.floor(((clientX - startX) / width) * days));\n};\n\nexport const calendarMinuteAtPoint = (clientY: number, top: number, height: number, startHour: number, endHour: number): number => {\n const totalMinutes = Math.max(60, (endHour - startHour + 1) * 60);\n const ratio = height > 0 ? Math.min(1, Math.max(0, (clientY - top) / height)) : 0;\n return snapCalendarMinutes(startHour * 60 + ratio * totalMinutes);\n};\n\nexport const calendarAutoScrollSpeed = (clientY: number, top: number, bottom: number, edge = 56, maximum = 18): number => {\n if (clientY < top + edge) return -Math.ceil(maximum * Math.min(1, (top + edge - clientY) / edge));\n if (clientY > bottom - edge) return Math.ceil(maximum * Math.min(1, (clientY - (bottom - edge)) / edge));\n return 0;\n};\n\ntype CalendarPointerSessionOptions<T> = {\n event: PointerEvent;\n resolve: (clientX: number, clientY: number) => T | null;\n onActivate?: () => void;\n onPreview: (value: T) => void;\n onCommit: (value: T) => void;\n onCancel?: () => void;\n scrollContainer?: HTMLElement;\n threshold?: number;\n};\n\nlet cancelActiveSession: (() => void) | null = null;\n\n/**\n * Owns one pointer gesture from threshold crossing through commit or cancel.\n * Views provide geometry through `resolve`; this helper owns global cleanup,\n * pointer cancellation, Escape handling, and edge auto-scroll.\n */\nexport const startCalendarPointerSession = <T>(options: CalendarPointerSessionOptions<T>): (() => void) => {\n if (options.event.button !== 0 || !options.event.isPrimary) return () => {};\n\n cancelActiveSession?.();\n\n const pointerId = options.event.pointerId;\n const target = options.event.currentTarget instanceof HTMLElement ? options.event.currentTarget : null;\n const startX = options.event.clientX;\n const startY = options.event.clientY;\n // Leave enough room for normal click jitter before an event becomes a drag.\n const threshold = options.threshold ?? 6;\n const previousUserSelect = document.body.style.userSelect;\n let clientX = startX;\n let clientY = startY;\n let active = false;\n let finished = false;\n let latest: T | null = null;\n let scrollFrame = 0;\n\n const preview = () => {\n const value = options.resolve(clientX, clientY);\n if (value === null) return;\n latest = value;\n options.onPreview(value);\n };\n\n const autoScroll = () => {\n scrollFrame = 0;\n if (!active || !options.scrollContainer) return;\n const rect = options.scrollContainer.getBoundingClientRect();\n const speed = calendarAutoScrollSpeed(clientY, rect.top, rect.bottom);\n if (speed !== 0) {\n const before = options.scrollContainer.scrollTop;\n options.scrollContainer.scrollTop += speed;\n if (options.scrollContainer.scrollTop !== before) preview();\n }\n scrollFrame = requestAnimationFrame(autoScroll);\n };\n\n const cleanup = () => {\n if (scrollFrame) cancelAnimationFrame(scrollFrame);\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n window.removeEventListener(\"pointercancel\", cancel);\n window.removeEventListener(\"blur\", cancel);\n window.removeEventListener(\"keydown\", onKeyDown);\n if (target?.hasPointerCapture?.(pointerId)) target.releasePointerCapture(pointerId);\n document.body.style.userSelect = previousUserSelect;\n if (cancelActiveSession === cancel) cancelActiveSession = null;\n };\n\n const activate = () => {\n if (active) return;\n active = true;\n document.body.style.userSelect = \"none\";\n target?.setPointerCapture?.(pointerId);\n options.onActivate?.();\n preview();\n if (options.scrollContainer) scrollFrame = requestAnimationFrame(autoScroll);\n };\n\n function cancel() {\n if (finished) return;\n finished = true;\n cleanup();\n if (active) options.onCancel?.();\n }\n\n function onMove(event: PointerEvent) {\n if (finished || event.pointerId !== pointerId) return;\n clientX = event.clientX;\n clientY = event.clientY;\n if (!active && Math.hypot(clientX - startX, clientY - startY) >= threshold) activate();\n if (!active) return;\n event.preventDefault();\n preview();\n }\n\n function onUp(event: PointerEvent) {\n if (finished || event.pointerId !== pointerId) return;\n finished = true;\n cleanup();\n if (active && latest !== null) options.onCommit(latest);\n else if (active) options.onCancel?.();\n }\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key !== \"Escape\") return;\n event.preventDefault();\n cancel();\n }\n\n window.addEventListener(\"pointermove\", onMove, { passive: false });\n window.addEventListener(\"pointerup\", onUp);\n window.addEventListener(\"pointercancel\", cancel);\n window.addEventListener(\"blur\", cancel);\n window.addEventListener(\"keydown\", onKeyDown);\n cancelActiveSession = cancel;\n return cancel;\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/calendar-pointer.ts"],"sourcesContent":["export const CALENDAR_SNAP_MINUTES = 15;\n\nexport const snapCalendarMinutes = (minutes: number, step = CALENDAR_SNAP_MINUTES): number => Math.round(minutes / step) * step;\n\nexport const calendarDayIndexAtPoint = (clientX: number, startX: number, width: number, days: number): number | null => {\n if (days <= 0 || width <= 0 || clientX < startX || clientX >= startX + width) return null;\n return Math.min(days - 1, Math.floor(((clientX - startX) / width) * days));\n};\n\nexport const calendarMinuteAtPoint = (clientY: number, top: number, height: number, startHour: number, endHour: number): number => {\n const totalMinutes = Math.max(60, (endHour - startHour + 1) * 60);\n const ratio = height > 0 ? Math.min(1, Math.max(0, (clientY - top) / height)) : 0;\n return snapCalendarMinutes(startHour * 60 + ratio * totalMinutes);\n};\n\nexport const calendarAutoScrollSpeed = (clientY: number, top: number, bottom: number, edge = 56, maximum = 18): number => {\n if (clientY < top + edge) return -Math.ceil(maximum * Math.min(1, (top + edge - clientY) / edge));\n if (clientY > bottom - edge) return Math.ceil(maximum * Math.min(1, (clientY - (bottom - edge)) / edge));\n return 0;\n};\n\ntype CalendarPointerSessionOptions<T> = {\n event: PointerEvent;\n resolve: (clientX: number, clientY: number) => T | null;\n onActivate?: () => void;\n onPreview: (value: T) => void;\n onCommit: (value: T) => void;\n onCancel?: () => void;\n scrollContainer?: HTMLElement;\n threshold?: number;\n};\n\nlet cancelActiveSession: (() => void) | null = null;\n\n/**\n * Owns one pointer gesture from threshold crossing through commit or cancel.\n * Views provide geometry through `resolve`; this helper owns global cleanup,\n * pointer cancellation, Escape handling, and edge auto-scroll.\n */\nexport const startCalendarPointerSession = <T>(options: CalendarPointerSessionOptions<T>): (() => void) => {\n if (options.event.button !== 0 || !options.event.isPrimary) return () => {};\n\n cancelActiveSession?.();\n\n const pointerId = options.event.pointerId;\n const target = options.event.currentTarget instanceof HTMLElement ? options.event.currentTarget : null;\n const startX = options.event.clientX;\n const startY = options.event.clientY;\n // Leave enough room for normal click jitter before an event becomes a drag.\n const threshold = options.threshold ?? 6;\n const previousUserSelect = document.body.style.userSelect;\n let clientX = startX;\n let clientY = startY;\n let active = false;\n let finished = false;\n let latest: T | null = null;\n let scrollFrame = 0;\n\n const preview = () => {\n const value = options.resolve(clientX, clientY);\n if (value === null) return;\n latest = value;\n options.onPreview(value);\n };\n\n const autoScroll = () => {\n scrollFrame = 0;\n if (!active || !options.scrollContainer) return;\n const rect = options.scrollContainer.getBoundingClientRect();\n const speed = calendarAutoScrollSpeed(clientY, rect.top, rect.bottom);\n if (speed !== 0) {\n const before = options.scrollContainer.scrollTop;\n options.scrollContainer.scrollTop += speed;\n if (options.scrollContainer.scrollTop !== before) preview();\n }\n scrollFrame = requestAnimationFrame(autoScroll);\n };\n\n const cleanup = () => {\n if (scrollFrame) cancelAnimationFrame(scrollFrame);\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n window.removeEventListener(\"pointercancel\", cancel);\n window.removeEventListener(\"blur\", cancel);\n window.removeEventListener(\"keydown\", onKeyDown);\n if (target?.hasPointerCapture?.(pointerId)) target.releasePointerCapture(pointerId);\n document.body.style.userSelect = previousUserSelect;\n if (cancelActiveSession === cancel) cancelActiveSession = null;\n };\n\n const activate = () => {\n if (active) return;\n active = true;\n document.body.style.userSelect = \"none\";\n target?.setPointerCapture?.(pointerId);\n options.onActivate?.();\n preview();\n if (options.scrollContainer) scrollFrame = requestAnimationFrame(autoScroll);\n };\n\n function cancel() {\n if (finished) return;\n finished = true;\n cleanup();\n if (active) options.onCancel?.();\n }\n\n function onMove(event: PointerEvent) {\n if (finished || event.pointerId !== pointerId) return;\n clientX = event.clientX;\n clientY = event.clientY;\n if (!active && Math.hypot(clientX - startX, clientY - startY) >= threshold) activate();\n if (!active) return;\n event.preventDefault();\n preview();\n }\n\n function onUp(event: PointerEvent) {\n if (finished || event.pointerId !== pointerId) return;\n finished = true;\n cleanup();\n if (active && latest !== null) options.onCommit(latest);\n else if (active) options.onCancel?.();\n }\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key !== \"Escape\") return;\n event.preventDefault();\n cancel();\n }\n\n window.addEventListener(\"pointermove\", onMove, { passive: false });\n window.addEventListener(\"pointerup\", onUp);\n window.addEventListener(\"pointercancel\", cancel);\n window.addEventListener(\"blur\", cancel);\n window.addEventListener(\"keydown\", onKeyDown);\n cancelActiveSession = cancel;\n return cancel;\n};\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["createChartCursor","options","state","listeners","Set","notify","listener","formatX","read","subscribe","add","delete","move","source","x","Number","isFinite","clear"],"sources":["content/chart-cursor.ts"],"sourcesContent":["export type ChartCursorState = { source: symbol; x: number } | null;\n\n/** Share one numeric X value between line charts. Create one instance per group. */\nexport function createChartCursor(options: { formatX?: (x: number) => string } = {}) {\n let state: ChartCursorState = null;\n const listeners = new Set<(state: ChartCursorState) => void>();\n const notify = () => {\n for (const listener of listeners) listener(state);\n };\n return {\n formatX: options.formatX,\n read: () => state,\n subscribe(listener: (state: ChartCursorState) => void) {\n listeners.add(listener);\n listener(state);\n return () => {\n listeners.delete(listener);\n };\n },\n move(source: symbol, x: number) {\n if (!Number.isFinite(x) || (state?.source === source && state.x === x)) return;\n state = { source, x };\n notify();\n },\n clear(source: symbol) {\n if (state?.source !== source) return;\n state = null;\n notify();\n },\n };\n}\nexport type ChartCursor = ReturnType<typeof createChartCursor>;\n"],"mappings":"AAEA;AACA,OAAO,SAASA,iBAAiBA,CAACC,OAA4C,GAAG,CAAC,CAAC,EAAE;EACnF,IAAIC,KAAuB,GAAG,IAAI;EAClC,MAAMC,SAAS,GAAG,IAAIC,GAAG,CAAoC,CAAC;EAC9D,MAAMC,MAAM,GAAGA,CAAA,KAAM;IACnB,KAAK,MAAMC,QAAQ,IAAIH,SAAS,EAAEG,QAAQ,CAACJ,KAAK,CAAC;EACnD,CAAC;EACD,OAAO;IACLK,OAAO,EAAEN,OAAO,CAACM,OAAO;IACxBC,IAAI,EAAEA,CAAA,KAAMN,KAAK;IACjBO,SAASA,CAACH,QAA2C,EAAE;MACrDH,SAAS,CAACO,GAAG,CAACJ,QAAQ,CAAC;MACvBA,QAAQ,CAACJ,KAAK,CAAC;MACf,OAAO,MAAM;QACXC,SAAS,CAACQ,MAAM,CAACL,QAAQ,CAAC;MAC5B,CAAC;IACH,CAAC;IACDM,IAAIA,CAACC,MAAc,EAAEC,CAAS,EAAE;MAC9B,IAAI,CAACC,MAAM,CAACC,QAAQ,CAACF,CAAC,CAAC,IAAKZ,KAAK,EAAEW,MAAM,KAAKA,MAAM,IAAIX,KAAK,CAACY,CAAC,KAAKA,CAAE,EAAE;MACxEZ,KAAK,GAAG;QAAEW,MAAM;QAAEC;MAAE,CAAC;MACrBT,MAAM,CAAC,CAAC;IACV,CAAC;IACDY,KAAKA,CAACJ,MAAc,EAAE;MACpB,IAAIX,KAAK,EAAEW,MAAM,KAAKA,MAAM,EAAE;MAC9BX,KAAK,GAAG,IAAI;MACZG,MAAM,CAAC,CAAC;IACV;EACF,CAAC;AACH","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/chart-cursor.ts"],"sourcesContent":["export type ChartCursorState = { source: symbol; x: number } | null;\n\n/** Share one numeric X value between line charts. Create one instance per group. */\nexport function createChartCursor(options: { formatX?: (x: number) => string } = {}) {\n let state: ChartCursorState = null;\n const listeners = new Set<(state: ChartCursorState) => void>();\n const notify = () => {\n for (const listener of listeners) listener(state);\n };\n return {\n formatX: options.formatX,\n read: () => state,\n subscribe(listener: (state: ChartCursorState) => void) {\n listeners.add(listener);\n listener(state);\n return () => {\n listeners.delete(listener);\n };\n },\n move(source: symbol, x: number) {\n if (!Number.isFinite(x) || (state?.source === source && state.x === x)) return;\n state = { source, x };\n notify();\n },\n clear(source: symbol) {\n if (state?.source !== source) return;\n state = null;\n notify();\n },\n };\n}\nexport type ChartCursor = ReturnType<typeof createChartCursor>;\n"],"mappings":"AAEA;AACA,OAAO,SAAS,iBAAiB,CAAC,OAA4C,GAAG,CAAC,CAAC,EAAE;EACnF,IAAI,KAAuB,GAAG,IAAI;EAClC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAoC,CAAC;EAC9D,MAAM,MAAM,GAAG,MAAM;IACnB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC;EACnD,CAAC;EACD,OAAO;IACL,OAAO,EAAE,OAAO,CAAC,OAAO;IACxB,IAAI,EAAE,MAAM,KAAK;IACjB,SAAS,CAAC,QAA2C,EAAE;MACrD,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC;MACvB,QAAQ,CAAC,KAAK,CAAC;MACf,OAAO,MAAM;QACX,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC;MAC5B,CAAC;IACH,CAAC;IACD,IAAI,CAAC,MAAc,EAAE,CAAS,EAAE;MAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAK,KAAK,EAAE,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,CAAC,KAAK,CAAE,EAAE;MACxE,KAAK,GAAG;QAAE,MAAM;QAAE;MAAE,CAAC;MACrB,MAAM,CAAC,CAAC;IACV,CAAC;IACD,KAAK,CAAC,MAAc,EAAE;MACpB,IAAI,KAAK,EAAE,MAAM,KAAK,MAAM,EAAE;MAC9B,KAAK,GAAG,IAAI;MACZ,MAAM,CAAC,CAAC;IACV;EACF,CAAC;AACH","ignoreList":[]}