@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
@@ -1,8 +1,15 @@
1
- import { APP_WORKSPACE_DETAIL_MAX, APP_WORKSPACE_DETAIL_MIN, APP_WORKSPACE_DRAWER_MAX, APP_WORKSPACE_DRAWER_MIN, APP_WORKSPACE_MAIN_MIN, APP_WORKSPACE_PANE_MAX, APP_WORKSPACE_PANE_MIN, APP_WORKSPACE_SIDEBAR_COLLAPSED, APP_WORKSPACE_SIDEBAR_MAX, APP_WORKSPACE_SIDEBAR_MIN, appWorkspacePanelVariable, appWorkspaceResizeLimits, fitAppWorkspacePaneSizes, normalizeAppWorkspaceLayoutState, resolveAppWorkspaceSidebarWidth, safeAppWorkspacePanelId, shouldCollapseAppWorkspaceSidebar } from "./app-workspace-state";
1
+ import { suppressTextSelection } from "../internal/text-selection";
2
+ import { APP_WORKSPACE_DETAIL_DEFAULT, APP_WORKSPACE_DETAIL_MAX, APP_WORKSPACE_DETAIL_MIN, APP_WORKSPACE_DRAWER_MAX, APP_WORKSPACE_DRAWER_MIN, APP_WORKSPACE_MAIN_MIN, APP_WORKSPACE_PANE_MAX, APP_WORKSPACE_PANE_MIN, APP_WORKSPACE_SIDEBAR_COLLAPSED, APP_WORKSPACE_SIDEBAR_MAX, APP_WORKSPACE_SIDEBAR_MIN, appWorkspacePanelVariable, appWorkspaceResizeLimits, fitAppWorkspacePaneSizes, normalizeAppWorkspaceLayoutState, resolveAppWorkspaceSidebarWidth, safeAppWorkspacePanelId, shouldCollapseAppWorkspaceSidebar } from "./app-workspace-state";
2
3
  import { installScrollFades } from "./scroll-fade";
3
4
  const HANDLE_SELECTOR = "[data-app-workspace-resize]";
4
5
  const ROOT_SELECTOR = "[data-k2b-app-workspace]";
5
6
  const LAYOUT_REGION_SELECTOR = [ROOT_SELECTOR, ".k2b-app-workspace__sidebar", ".k2b-app-workspace__main-pane", ".k2b-app-workspace__detail", ".k2b-app-workspace__drawer", HANDLE_SELECTOR].join(",");
7
+ const TOGGLE_SELECTOR = "[data-app-workspace-sidebar-toggle]";
8
+ /** The width range in which the sidebar is an overlay; it matches the compact media query in the stylesheet. */
9
+ const COMPACT_QUERY = "(min-width: 48rem) and (max-width: 63.999rem)";
10
+ const FOCUSABLE_SELECTOR = ["a[href]", "button:not([disabled])", "input:not([disabled]):not([type='hidden'])", "select:not([disabled])", "textarea:not([disabled])", "[tabindex]:not([tabindex='-1'])"].join(",");
11
+ /** Text entry, menus, dialogs, and open popups keep their own keys. */
12
+ const KEY_OWNER_SELECTOR = "input, textarea, select, [contenteditable]:not([contenteditable='false']), [role='textbox'], [role='combobox'], [role='searchbox'], [role='spinbutton'], [role='menu'], [role='listbox'], [role='dialog'], dialog, [aria-haspopup]:not([aria-haspopup='false'])[aria-expanded='true']";
6
13
  const LABEL_SELECTOR = ".k2b-app-workspace__sidebar-item-label[data-marquee='true']";
7
14
  const LABEL_TEXT_SELECTOR = ".k2b-app-workspace__sidebar-item-label-text";
8
15
  const ITEM_SELECTOR = ".k2b-app-workspace__sidebar-item";
@@ -26,6 +33,14 @@ const sidebarHideable = root => sidebarElement(root)?.dataset.workspaceHideable
26
33
  * stays application state, so the controller only requests the change.
27
34
  */
28
35
  export const APP_WORKSPACE_SIDEBAR_HIDE_EVENT = "k2b-app-workspace-sidebar-hide";
36
+ /** Asks the owning `AppWorkspace.Detail` to close; its `onClose` decides. */
37
+ export const APP_WORKSPACE_DETAIL_CLOSE_EVENT = "k2b-app-workspace-detail-close";
38
+ /**
39
+ * Asks the owning Detail to step by `detail.direction` (`-1` or `1`). It writes
40
+ * the Main element showing the selection to `detail.item`, read synchronously
41
+ * by the controller after dispatch.
42
+ */
43
+ export const APP_WORKSPACE_DETAIL_STEP_EVENT = "k2b-app-workspace-detail-step";
29
44
  const previewSidebarHidden = (root, hidden) => {
30
45
  const sidebar = sidebarElement(root);
31
46
  if (!sidebar) return;
@@ -53,15 +68,17 @@ const sizeLimits = (root, handle, kind) => {
53
68
  const controlled = controlledPanel(root, handle);
54
69
  const main = kind === "pane" ? handle.closest(".k2b-app-workspace__main") : mainElement(root);
55
70
  const panes = main ? Array.from(main.querySelectorAll(".k2b-app-workspace__main-pane")).filter(pane => pane.closest(".k2b-app-workspace__main") === main && !pane.classList.contains("is-primary") && isVisible(pane)) : [];
56
- const details = rootElements(root, ".k2b-app-workspace__detail").filter(isVisible);
57
- const sidebarWidth = elementSize(sidebarElement(root), "sidebar");
58
- const otherDetailWidth = details.reduce((total, detail) => total + (detail === controlled ? 0 : elementSize(detail, "detail")), 0);
71
+ // Content ends before the detail track, so its width alone would shrink a
72
+ // persisted panel again on every reconciliation. Measure from Content's
73
+ // start to the workspace's inner end: this includes the detail column and
74
+ // leaves out a desktop sidebar, while an overlay sidebar takes no width.
75
+ const content = kind === "detail" ? controlled?.closest(".k2b-app-workspace__content") : null;
59
76
  const defaultMin = kind === "sidebar" ? APP_WORKSPACE_SIDEBAR_MIN : kind === "pane" ? APP_WORKSPACE_PANE_MIN : kind === "detail" ? APP_WORKSPACE_DETAIL_MIN : APP_WORKSPACE_DRAWER_MIN;
60
77
  const defaultMax = kind === "sidebar" ? APP_WORKSPACE_SIDEBAR_MAX : kind === "pane" ? APP_WORKSPACE_PANE_MAX : kind === "detail" ? APP_WORKSPACE_DETAIL_MAX : APP_WORKSPACE_DRAWER_MAX;
61
78
  return appWorkspaceResizeLimits({
62
79
  kind,
63
- workspaceSize: kind === "drawer" ? root.getBoundingClientRect().height : kind === "pane" && main ? main.getBoundingClientRect().width : root.getBoundingClientRect().width,
64
- reservedSize: kind === "sidebar" ? otherDetailWidth : kind === "pane" ? panes.reduce((total, pane) => total + (pane === controlled ? 0 : elementSize(pane, "pane")), 0) : kind === "detail" ? sidebarWidth + otherDetailWidth : 0,
80
+ workspaceSize: kind === "drawer" ? root.getBoundingClientRect().height : kind === "pane" && main ? main.getBoundingClientRect().width : content ? root.getBoundingClientRect().right - root.clientLeft - content.getBoundingClientRect().left : root.getBoundingClientRect().width,
81
+ reservedSize: kind === "detail" ? 8 : kind === "pane" ? panes.reduce((total, pane) => total + (pane === controlled ? 0 : elementSize(pane, "pane")), 0) : 0,
65
82
  min: numberData(handle, "workspaceMinSize", defaultMin),
66
83
  max: numberData(handle, "workspaceMaxSize", defaultMax),
67
84
  sidebarCollapsible: kind === "sidebar" && sidebarCollapsible(root)
@@ -165,8 +182,693 @@ const measureLabel = label => {
165
182
  label.style.setProperty("--k2b-sidebar-label-overflow", `${overflow}px`);
166
183
  if (overflow > 2) label.dataset.overflow = "true";else delete label.dataset.overflow;
167
184
  };
185
+
186
+ /** An open overlay remembers the regions it made inert, so it leaves the application's own `inert` alone. */
187
+
188
+ /**
189
+ * The elements Tab stops at, in order. A roving tab index, as in a tree, keeps
190
+ * links and buttons at `tabindex="-1"`; they take focus but are no stops.
191
+ */
192
+ const tabStopsIn = container => Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR)).filter(element => element.tabIndex >= 0 && element.getClientRects().length > 0 && !element.closest("[inert]") && getComputedStyle(element).visibility !== "hidden");
193
+ /** Several controllers can see one click on a nested workspace's button; the innermost one, which sees it first, owns it. */
194
+ const claimedToggleClicks = new WeakSet();
195
+ const claimedDetailGestures = new WeakSet();
196
+
197
+ /**
198
+ * The compact overlay: from 48 to 64 rem the sidebar opens over the work area
199
+ * from the button in the workspace's head. While it is open the rest of
200
+ * the workspace is inert, Tab stays in the sidebar, and Escape, the scrim,
201
+ * choosing an item, hiding the sidebar, or leaving the width range close it
202
+ * again. The state is one attribute on the workspace root, so server-rendered
203
+ * and hydrated workspaces behave the same.
204
+ */
205
+ const overlayTarget = toggle => {
206
+ const root = workspaceRoot(toggle);
207
+ // The button belongs to its workspace's own sidebar. A sidebar rendered apart
208
+ // from the head, for example in an island, can carry another id than the one
209
+ // the head named, so the button learns the real one here.
210
+ const sidebar = root ? sidebarElement(root) : null;
211
+ if (!root || !sidebar || sidebar.hidden || sidebar.dataset.mobile === "stacked") return null;
212
+ if (sidebar.id) toggle.setAttribute("aria-controls", sidebar.id);
213
+ return {
214
+ root,
215
+ sidebar,
216
+ toggle
217
+ };
218
+ };
219
+ const overlayRegions = (root, sidebar) => Array.from(root.children).flatMap(child => child instanceof HTMLElement && (child.localName === "solid-island" || child.localName === "solid-client") ? Array.from(child.children) : [child]).filter(child => child instanceof HTMLElement && child !== sidebar && !child.contains(sidebar));
168
220
  export const installAppWorkspaceController = (options = {}) => {
169
221
  const eventRoot = options.root ?? document;
222
+ // A document has no owner document; an element root listens on its own.
223
+ const ownerDocument = eventRoot.ownerDocument ?? document;
224
+ const ownerWindow = ownerDocument.defaultView ?? window;
225
+ let overlay = null;
226
+ const compact = typeof window.matchMedia === "function" ? window.matchMedia(COMPACT_QUERY) : null;
227
+ // A server-rendered head names the sidebar before the sidebar renders; the button learns its real id now.
228
+ for (const toggle of eventRoot.querySelectorAll(TOGGLE_SELECTOR)) overlayTarget(toggle);
229
+ const openOverlay = target => {
230
+ if (overlay) closeOverlay("none");
231
+ const inerted = overlayRegions(target.root, target.sidebar).filter(region => !region.hasAttribute("inert"));
232
+ overlay = {
233
+ ...target,
234
+ inerted
235
+ };
236
+ target.root.dataset.sidebarOverlay = "open";
237
+ target.toggle.setAttribute("aria-expanded", "true");
238
+ inerted.forEach(region => region.setAttribute("inert", ""));
239
+ // Focus starts on the current destination, so the reader knows where they
240
+ // are: on its own tab stop, or on the tree item around it.
241
+ const current = target.sidebar.querySelector("[aria-current='page'], .is-active");
242
+ const stops = tabStopsIn(target.sidebar);
243
+ const first = (current && (stops.find(element => current.contains(element)) ?? stops.findLast(element => element.contains(current)))) ?? stops[0];
244
+ if (first) first.focus();else {
245
+ target.sidebar.tabIndex = -1;
246
+ target.sidebar.focus();
247
+ }
248
+ };
249
+ /**
250
+ * `"button"` returns focus to the button. `"kept"` leaves it where it moved,
251
+ * for example into a dialog an item opened, and only rescues focus that the
252
+ * closing sidebar would hide. `"none"` moves nothing, for cleanup.
253
+ */
254
+ const closeOverlay = focus => {
255
+ const closing = overlay;
256
+ if (!closing) return;
257
+ overlay = null;
258
+ delete closing.root.dataset.sidebarOverlay;
259
+ closing.toggle.setAttribute("aria-expanded", "false");
260
+ closing.inerted.forEach(region => region.removeAttribute("inert"));
261
+ if (focus === "none") return;
262
+ const active = document.activeElement;
263
+ if (focus === "button" || !active || active === document.body || closing.sidebar.contains(active)) closing.toggle.focus();
264
+ };
265
+ const onClick = event => {
266
+ const target = eventElement(event);
267
+ const toggle = target?.closest(TOGGLE_SELECTOR);
268
+ if (toggle) {
269
+ const next = overlayTarget(toggle);
270
+ if (!next || claimedToggleClicks.has(event)) return;
271
+ claimedToggleClicks.add(event);
272
+ if (overlay?.sidebar === next.sidebar) closeOverlay("button");else if (compact?.matches) openOverlay(next);
273
+ return;
274
+ }
275
+ if (!overlay || !target) return;
276
+ // The scrim is the workspace root's own pseudo-element.
277
+ if (target === overlay.root) {
278
+ closeOverlay("button");
279
+ return;
280
+ }
281
+ // Choosing a destination closes the overlay: a link, or the button of a
282
+ // row. A tree folder that only expands, a control that opens a popup or
283
+ // expands something, such as a row's preview, and an item's own actions
284
+ // keep it open.
285
+ const control = target.closest("a[href], button");
286
+ if (!control || !overlay.sidebar.contains(control)) return;
287
+ if (target.closest("[data-k2b-nav-tree-toggle]") || control.closest("[data-k2b-nav-tree-disclosure], .k2b-app-workspace__sidebar-item-action, .k2b-app-workspace__sidebar-item-actions") || control.matches("[aria-haspopup], [aria-expanded]")) return;
288
+ if (control.matches("a[href]") || control.closest(ITEM_SELECTOR)) closeOverlay("kept");
289
+ };
290
+ const onOverlayKeyDown = event => {
291
+ if (!overlay || event.defaultPrevented) return;
292
+ const target = eventElement(event);
293
+ if (!target) return;
294
+ // Escape also closes it when a click left focus on nothing, so on the body.
295
+ if (event.key === "Escape" && (overlay.sidebar.contains(target) || target === ownerDocument.body)) {
296
+ event.preventDefault();
297
+ closeOverlay("button");
298
+ return;
299
+ }
300
+ if (event.key !== "Tab" || !overlay.sidebar.contains(target)) return;
301
+ const stops = tabStopsIn(overlay.sidebar);
302
+ const first = stops[0];
303
+ const last = stops.at(-1);
304
+ if (!first || !last) {
305
+ event.preventDefault();
306
+ return;
307
+ }
308
+ if (event.shiftKey && (document.activeElement === first || document.activeElement === overlay.sidebar)) {
309
+ event.preventDefault();
310
+ last.focus();
311
+ } else if (!event.shiftKey && document.activeElement === last) {
312
+ event.preventDefault();
313
+ first.focus();
314
+ }
315
+ };
316
+ const onCompactChange = () => {
317
+ if (!compact?.matches) closeOverlay("none");
318
+ };
319
+ const phone = typeof window.matchMedia === "function" ? window.matchMedia("(max-width: 47.999rem)") : null;
320
+ const wide = typeof window.matchMedia === "function" ? window.matchMedia("(min-width: 48rem)") : null;
321
+ const touchDrawer = typeof window.matchMedia === "function" ? window.matchMedia(`${COMPACT_QUERY} and (pointer: coarse)`) : null;
322
+ const reducedMotion = typeof window.matchMedia === "function" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null;
323
+ const detailSelector = ".k2b-app-workspace__detail";
324
+ const grabberSelector = ".k2b-app-workspace__detail-grabber";
325
+ const detailHidden = new WeakMap();
326
+ const remembered = new WeakMap();
327
+ const lastFocus = new WeakMap();
328
+ const touchedDetails = new Set();
329
+ // Only a panel blocks scrolling for its touch gestures; a document-wide
330
+ // non-passive listener would make every scroll on the page wait for script.
331
+ const touchMoveAsides = new Set();
332
+ const titleTabIndices = new Set();
333
+ const motionFrames = new Map();
334
+ const pendingAnchors = new Map();
335
+ const slides = new Map();
336
+ const motionRoots = new Set();
337
+ const revealFrames = new Map();
338
+ const openDetails = root => rootElements(root, detailSelector).filter(aside => !aside.hidden);
339
+ const closeControl = aside => Array.from(aside.querySelectorAll("[data-workspace-detail-close]")).find(control => control.closest(detailSelector) === aside);
340
+ const closable = aside => aside.hasAttribute("data-workspace-detail-closable") || Boolean(closeControl(aside));
341
+ const requestClose = aside => {
342
+ if (aside.hasAttribute("data-workspace-detail-closable")) aside.dispatchEvent(new CustomEvent(APP_WORKSPACE_DETAIL_CLOSE_EVENT));else closeControl(aside)?.click();
343
+ };
344
+ const scrollerOn = (axis, target, boundary) => {
345
+ for (let element = target; element && boundary.contains(element); element = element.parentElement) {
346
+ if (element instanceof HTMLElement && /^(auto|scroll)$/.test(axis === "y" ? getComputedStyle(element).overflowY : getComputedStyle(element).overflowX) && (axis === "y" ? element.scrollHeight > element.clientHeight : element.scrollWidth > element.clientWidth)) return element;
347
+ if (element === boundary) break;
348
+ }
349
+ return null;
350
+ };
351
+ const verticalScroller = (target, boundary) => scrollerOn("y", target, boundary);
352
+ const refreshItem = snapshot => {
353
+ snapshot.top = snapshot.item.getBoundingClientRect().top;
354
+ snapshot.scrollTop = snapshot.scroller?.scrollTop ?? 0;
355
+ };
356
+ // A table row can exceed its scroller's width, so keep the clicked cell for horizontal reveal.
357
+ const rememberInteraction = event => {
358
+ const target = eventElement(event);
359
+ const root = target?.closest(ROOT_SELECTOR);
360
+ if (!target || !root || !observedRoots.has(root)) return;
361
+ const previous = remembered.get(root);
362
+ if (previous && openDetails(root).length) refreshItem(previous);
363
+ const main = mainElement(root);
364
+ const item = target.closest(FOCUSABLE_SELECTOR);
365
+ if (!main || !item || !main.contains(item) || item.closest(ROOT_SELECTOR) !== root) return;
366
+ if (event instanceof KeyboardEvent && event.key !== "Enter" && event.key !== " ") return;
367
+ const cell = target.closest("td, th");
368
+ const snapshot = {
369
+ item,
370
+ cell: cell && main.contains(cell) && cell.closest(ROOT_SELECTOR) === root ? cell : null,
371
+ interaction: event instanceof KeyboardEvent ? "keyboard" : "pointer",
372
+ scroller: verticalScroller(item, main),
373
+ scrollTop: 0,
374
+ top: 0,
375
+ fresh: true
376
+ };
377
+ refreshItem(snapshot);
378
+ remembered.set(root, snapshot);
379
+ // Enter in an editor or a field types; only an item that chooses something moves on to its title.
380
+ if (event instanceof KeyboardEvent && !target.closest(KEY_OWNER_SELECTOR)) {
381
+ const aside = openDetails(root).find(isVisible);
382
+ if (aside) requestTitle(aside, true);
383
+ }
384
+ };
385
+ const onDetailFocusIn = event => {
386
+ const target = eventElement(event);
387
+ const root = target?.closest(ROOT_SELECTOR);
388
+ if (!target || !root || !observedRoots.has(root)) return;
389
+ lastFocus.set(root, target);
390
+ const previous = remembered.get(root);
391
+ // Pointer focus follows pointerdown; keeping that snapshot also keeps the
392
+ // interaction that opened the panel rather than treating focus as a new one.
393
+ if (previous?.item.contains(target)) {
394
+ const main = mainElement(root);
395
+ if (target !== previous.item && target instanceof HTMLElement && main) {
396
+ previous.item = target;
397
+ previous.scroller = verticalScroller(target, main);
398
+ refreshItem(previous);
399
+ }
400
+ return;
401
+ }
402
+ rememberInteraction(event);
403
+ };
404
+ const titleIn = aside => aside.querySelector("h1, h2, h3, [role='heading']");
405
+ let focusingTitle = null;
406
+ const focusTitle = aside => {
407
+ const title = titleIn(aside);
408
+ if (!title) return false;
409
+ if (!title.matches(FOCUSABLE_SELECTOR) && !title.hasAttribute("tabindex")) {
410
+ title.tabIndex = -1;
411
+ titleTabIndices.add(title);
412
+ }
413
+ focusingTitle = title;
414
+ try {
415
+ title.focus({
416
+ preventScroll: true
417
+ });
418
+ } finally {
419
+ focusingTitle = null;
420
+ }
421
+ return true;
422
+ };
423
+ let pendingTitle = null;
424
+ const cancelTitle = () => {
425
+ pendingTitle?.observer.disconnect();
426
+ pendingTitle = null;
427
+ };
428
+ // A step from inside the panel can remove the focused element with the old
429
+ // content, so focus falls to the body. The panel keeps owning the steps until
430
+ // focus or a pointer goes elsewhere, so a quick second J still ends on the title.
431
+ let panelStep = null;
432
+ const cancelTitleOnInteraction = event => {
433
+ if (event.type !== "keydown" && !(event.target instanceof Node && panelStep?.contains(event.target))) panelStep = null;
434
+ if (event.type !== "focusin" || event.target !== focusingTitle) cancelTitle();
435
+ };
436
+ const requestTitle = (aside, waitForChange = false) => {
437
+ cancelTitle();
438
+ if (aside.hidden || !aside.isConnected) return;
439
+ if (!waitForChange && focusTitle(aside)) return;
440
+ const previousTitle = titleIn(aside);
441
+ const previousText = previousTitle?.textContent;
442
+ // Loading fallbacks and selection changes can produce their heading after
443
+ // the opening interaction. A later user action always takes precedence.
444
+ const observer = new MutationObserver(() => {
445
+ if (aside.hidden || !aside.isConnected) {
446
+ cancelTitle();
447
+ return;
448
+ }
449
+ const title = titleIn(aside);
450
+ if (!title || waitForChange && title === previousTitle && title.textContent === previousText) return;
451
+ cancelTitle();
452
+ focusTitle(aside);
453
+ });
454
+ pendingTitle = {
455
+ aside,
456
+ observer
457
+ };
458
+ observer.observe(aside, {
459
+ childList: true,
460
+ subtree: true,
461
+ characterData: true
462
+ });
463
+ // An element-scoped controller cannot see its own root leave the document.
464
+ observer.observe(ownerDocument, {
465
+ childList: true,
466
+ subtree: true
467
+ });
468
+ };
469
+ const setDetent = (aside, full) => {
470
+ touchedDetails.add(aside);
471
+ if (full) aside.dataset.workspaceDetailSheet = "full";else delete aside.dataset.workspaceDetailSheet;
472
+ aside.querySelector(grabberSelector)?.setAttribute("aria-pressed", String(full));
473
+ };
474
+ const clearDrag = aside => {
475
+ aside.style.removeProperty("--k2b-workspace-detail-sheet-height");
476
+ aside.style.removeProperty("transform");
477
+ delete aside.dataset.workspaceDetailDragging;
478
+ };
479
+ const anchorItem = (root, aside, snapshot) => {
480
+ if (!wide?.matches || touchDrawer?.matches && closable(aside) || !snapshot?.item.isConnected) return;
481
+ if (!mainElement(root)?.contains(snapshot.item) || snapshot.item.closest(ROOT_SELECTOR) !== root) return;
482
+ const scroller = snapshot.scroller;
483
+ if (scroller?.isConnected && scroller.scrollTop === snapshot.scrollTop) scroller.scrollTop += snapshot.item.getBoundingClientRect().top - snapshot.top;
484
+ };
485
+ // From 64 rem the workspace does not clip, so the panel's shadow shows on
486
+ // every edge. A panel sliding in or out would cross a framed workspace's
487
+ // edge, so the workspace clips while the panel moves (see the stylesheet).
488
+ const slide = (root, aside) => {
489
+ slides.get(root)?.();
490
+ if (!root.hasAttribute("data-workspace-motion") || reducedMotion?.matches || !wide?.matches) return;
491
+ const end = () => {
492
+ aside.removeEventListener("transitionend", onEnd);
493
+ aside.removeEventListener("transitioncancel", onEnd);
494
+ cancelAnimationFrame(frame);
495
+ slides.delete(root);
496
+ delete root.dataset.workspaceDetailSliding;
497
+ };
498
+ const onEnd = event => {
499
+ if (event.target === aside && event.propertyName === "transform") end();
500
+ };
501
+ aside.addEventListener("transitionend", onEnd);
502
+ aside.addEventListener("transitioncancel", onEnd);
503
+ // A slow first frame must not end the clip early, so only a panel that
504
+ // does not slide at all ends it in that frame.
505
+ const frame = requestAnimationFrame(() => {
506
+ const sliding = aside.getAnimations?.().some(animation => "transitionProperty" in animation && animation.transitionProperty === "transform");
507
+ if (!sliding) end();
508
+ });
509
+ slides.set(root, end);
510
+ root.dataset.workspaceDetailSliding = "";
511
+ };
512
+ const revealItem = (root, aside, snapshot) => {
513
+ const pending = revealFrames.get(root);
514
+ if (pending !== undefined) cancelAnimationFrame(pending);
515
+ revealFrames.set(root, requestAnimationFrame(() => {
516
+ revealFrames.delete(root);
517
+ if (!aside.hidden && aside.isConnected && snapshot.item.isConnected && mainElement(root)?.contains(snapshot.item) && snapshot.item.closest(ROOT_SELECTOR) === root) {
518
+ const behavior = reducedMotion?.matches ? "auto" : "smooth";
519
+ const main = mainElement(root);
520
+ const cell = snapshot.cell;
521
+ const target = cell?.isConnected && main?.contains(cell) ? cell : snapshot.item;
522
+ if (phone?.matches && main) {
523
+ // The sheet covers Main's lower part, so the item ends 8px above it;
524
+ // a step can also land above Main's top or beside it, as in a board.
525
+ const page = ownerDocument.scrollingElement;
526
+ const vertical = verticalScroller(target, main) ?? page;
527
+ const horizontal = scrollerOn("x", target, main) ?? page;
528
+ const bounds = scroller => scroller && scroller !== page ? scroller.getBoundingClientRect() : null;
529
+ const box = target.getBoundingClientRect();
530
+ const top = Math.max(0, bounds(vertical)?.top ?? 0);
531
+ const left = Math.max(0, bounds(horizontal)?.left ?? 0);
532
+ const right = Math.min(ownerWindow.innerWidth, bounds(horizontal)?.right ?? Infinity);
533
+ const dy = box.top < top ? box.top - top - 8 : Math.max(0, box.bottom - (ownerWindow.innerHeight - aside.offsetHeight) + 8);
534
+ // As with scrollIntoView's "nearest", an item past both edges stays put
535
+ // and one wider than the view keeps its start in view.
536
+ const dx = box.left < left && box.right > right ? 0 : box.left < left ? box.left - left - 8 : box.right > right ? Math.min(box.right - right + 8, Math.max(0, box.left - left - 8)) : 0;
537
+ if (vertical && vertical === horizontal) {
538
+ if (dy || dx) vertical.scrollBy({
539
+ top: dy,
540
+ left: dx,
541
+ behavior
542
+ });
543
+ } else {
544
+ if (dy) vertical?.scrollBy({
545
+ top: dy,
546
+ behavior
547
+ });
548
+ if (dx) horizontal?.scrollBy({
549
+ left: dx,
550
+ behavior
551
+ });
552
+ }
553
+ } else target.scrollIntoView({
554
+ block: "nearest",
555
+ inline: "nearest",
556
+ behavior
557
+ });
558
+ }
559
+ }));
560
+ };
561
+ const detailTransition = (aside, wasHidden) => {
562
+ const root = aside.closest(ROOT_SELECTOR);
563
+ detailHidden.set(aside, Boolean(aside.hidden));
564
+ if (!root || !observedRoots.has(root) || Boolean(aside.hidden) === wasHidden) return;
565
+ pendingAnchors.get(root)?.();
566
+ slide(root, aside);
567
+ touchedDetails.add(aside);
568
+ const pending = revealFrames.get(root);
569
+ if (pending !== undefined) cancelAnimationFrame(pending);
570
+ revealFrames.delete(root);
571
+ const snapshot = remembered.get(root);
572
+ const followedInteraction = snapshot?.fresh ?? false;
573
+ if (snapshot) snapshot.fresh = false;
574
+ if (aside.hidden) {
575
+ if (pendingTitle?.aside === aside) cancelTitle();
576
+ if (panelStep === aside) panelStep = null;
577
+ if (root.hasAttribute("data-workspace-motion") && !reducedMotion?.matches && wide?.matches) {
578
+ // Closing holds the detail column until the slide ends; anchor after Main widens.
579
+ const cancel = () => {
580
+ root.removeEventListener("transitionend", onTransitionEnd);
581
+ clearTimeout(timer);
582
+ pendingAnchors.delete(root);
583
+ };
584
+ const finish = () => {
585
+ cancel();
586
+ if (aside.hidden && aside.isConnected) anchorItem(root, aside, snapshot);
587
+ };
588
+ const onTransitionEnd = event => {
589
+ if (event.target === root && event.propertyName === "--k2b-workspace-detail-track") finish();
590
+ };
591
+ const timer = setTimeout(finish, 300);
592
+ root.addEventListener("transitionend", onTransitionEnd);
593
+ pendingAnchors.set(root, cancel);
594
+ } else anchorItem(root, aside, snapshot);
595
+ const focused = ownerDocument.activeElement;
596
+ if (snapshot?.item.isConnected && (aside.contains(lastFocus.get(root) ?? null) || aside.contains(focused) || focused === ownerDocument.body)) snapshot.item.focus({
597
+ preventScroll: true
598
+ });
599
+ clearDrag(aside);
600
+ if (detailDrag?.aside === aside) finishDetailDrag(true);
601
+ return;
602
+ }
603
+ anchorItem(root, aside, snapshot);
604
+ if (phone?.matches) setDetent(aside, false);
605
+ if (followedInteraction && snapshot) {
606
+ revealItem(root, aside, snapshot);
607
+ if (snapshot.interaction === "keyboard" || phone?.matches) requestTitle(aside);
608
+ }
609
+ };
610
+ const onDetailKeyDown = event => {
611
+ if (event.defaultPrevented || event.ctrlKey || event.metaKey || event.altKey) return;
612
+ const target = eventElement(event);
613
+ if (!target || target.closest(KEY_OWNER_SELECTOR)) return;
614
+ if (ownerDocument.querySelector("dialog[open], [aria-modal='true']")) return;
615
+ try {
616
+ if (ownerDocument.querySelector(":popover-open")) return;
617
+ } catch {
618
+ // Older engines have no popover selector; the other popup guards still apply.
619
+ }
620
+ const root = target.closest(ROOT_SELECTOR);
621
+ let aside = target.closest(detailSelector);
622
+ if (aside?.hidden || aside && (!eventRoot.contains(aside) || aside.closest(ROOT_SELECTOR) !== root)) aside = null;
623
+ if (!aside && root && observedRoots.has(root) && mainElement(root)?.contains(target)) aside = openDetails(root)[0] ?? null;
624
+ if (!aside && target === ownerDocument.body) {
625
+ const open = allRoots().flatMap(openDetails);
626
+ if (open.length === 1) aside = open[0];
627
+ }
628
+ const owningRoot = aside?.closest(ROOT_SELECTOR);
629
+ if (!aside || !owningRoot) return;
630
+ if (event.key === "Escape" && closable(aside)) requestClose(aside);else if ((event.key.toLowerCase() === "j" || event.key.toLowerCase() === "k") && aside.hasAttribute("data-workspace-detail-steppable")) {
631
+ const main = mainElement(owningRoot);
632
+ const inMain = remembered.get(owningRoot)?.item.contains(target) || main?.contains(target);
633
+ const inPanel = aside.contains(target) || target === ownerDocument.body && panelStep === aside;
634
+ panelStep = inPanel ? aside : null;
635
+ const previousTitle = inPanel ? titleIn(aside) : null;
636
+ const previousText = previousTitle?.textContent;
637
+ const detail = {
638
+ direction: event.key.toLowerCase() === "j" ? 1 : -1
639
+ };
640
+ aside.dispatchEvent(new CustomEvent(APP_WORKSPACE_DETAIL_STEP_EVENT, {
641
+ detail
642
+ }));
643
+ const shown = detail.item;
644
+ const item = shown instanceof HTMLElement && main?.contains(shown) && shown.closest(ROOT_SELECTOR) === owningRoot ? shown : null;
645
+ if (item && main) {
646
+ const snapshot = {
647
+ item,
648
+ cell: null,
649
+ interaction: "keyboard",
650
+ scroller: verticalScroller(item, main),
651
+ scrollTop: 0,
652
+ top: 0,
653
+ fresh: false
654
+ };
655
+ refreshItem(snapshot);
656
+ remembered.set(owningRoot, snapshot);
657
+ revealItem(owningRoot, aside, snapshot);
658
+ }
659
+ const title = titleIn(aside);
660
+ if (item && inMain) item.focus({
661
+ preventScroll: true
662
+ });
663
+ // A panel that swapped its title during the event has the new one now.
664
+ else if (item && inPanel && title && (title !== previousTitle || title.textContent !== previousText)) focusTitle(aside);
665
+ // This key's capture cancelled an earlier step's title request, so a
666
+ // step from the body, even past the last item, asks again.
667
+ else if (inPanel && (item || target === ownerDocument.body)) requestTitle(aside, Boolean(item));
668
+ } else if (event.key === "F6") {
669
+ if (aside.contains(target)) {
670
+ const item = remembered.get(owningRoot)?.item;
671
+ const main = mainElement(owningRoot);
672
+ (item?.isConnected ? item : main ? tabStopsIn(main)[0] : null)?.focus({
673
+ preventScroll: true
674
+ });
675
+ } else focusTitle(aside);
676
+ } else return;
677
+ event.preventDefault();
678
+ };
679
+ let detailDrag = null;
680
+ let detailDragFrame = null;
681
+ let suppressedClick = null;
682
+ let suppressedClickTimer = null;
683
+ const paintDetailDrag = () => {
684
+ detailDragFrame = null;
685
+ const drag = detailDrag;
686
+ if (!drag?.moved) return;
687
+ drag.aside.dataset.workspaceDetailDragging = "true";
688
+ touchedDetails.add(drag.aside);
689
+ if (drag.source === "drawer") drag.aside.style.transform = `translateX(${Math.max(0, drag.dx)}px)`;else {
690
+ const height = ownerWindow.innerHeight;
691
+ drag.aside.style.setProperty("--k2b-workspace-detail-sheet-height", `${clamp(drag.startHeight - drag.dy, 0, Math.max(0, height - 8))}px`);
692
+ }
693
+ };
694
+ const scheduleDetailDrag = () => {
695
+ if (detailDragFrame === null) detailDragFrame = requestAnimationFrame(paintDetailDrag);
696
+ };
697
+ const finishDetailDrag = cancelled => {
698
+ const drag = detailDrag;
699
+ if (!drag) return;
700
+ detailDrag = null;
701
+ if (detailDragFrame !== null) cancelAnimationFrame(detailDragFrame);
702
+ detailDragFrame = null;
703
+ drag.releaseTextSelection?.();
704
+ if (drag.source === "pointer") {
705
+ if (drag.target instanceof HTMLElement && drag.target.hasPointerCapture?.(drag.pointerId)) drag.target.releasePointerCapture(drag.pointerId);
706
+ if (drag.moved) {
707
+ suppressedClick = drag.aside;
708
+ if (suppressedClickTimer !== null) clearTimeout(suppressedClickTimer);
709
+ suppressedClickTimer = setTimeout(() => {
710
+ suppressedClick = null;
711
+ suppressedClickTimer = null;
712
+ }, 0);
713
+ }
714
+ }
715
+ clearDrag(drag.aside);
716
+ if (cancelled || !drag.moved) return;
717
+ if (drag.source === "drawer") {
718
+ if (drag.dx > 80 || drag.dx > 30 && drag.velocity > 0.5) requestClose(drag.aside);
719
+ } else if (drag.dy > 60) {
720
+ setDetent(drag.aside, false);
721
+ if (!drag.full && closable(drag.aside)) requestClose(drag.aside);
722
+ } else if (drag.dy < -60) setDetent(drag.aside, true);
723
+ };
724
+ const beginDetailDrag = (aside, target, source, x, y, pointerId) => {
725
+ detailDrag = {
726
+ aside,
727
+ target,
728
+ source,
729
+ pointerId,
730
+ startX: x,
731
+ startY: y,
732
+ startHeight: aside.getBoundingClientRect().height,
733
+ full: aside.dataset.workspaceDetailSheet === "full",
734
+ dx: 0,
735
+ dy: 0,
736
+ time: performance.now(),
737
+ velocity: 0,
738
+ moved: false
739
+ };
740
+ return detailDrag;
741
+ };
742
+ const onSheetPointerDown = event => {
743
+ if (!(event instanceof PointerEvent) || !phone?.matches || event.button !== 0 || !event.isPrimary || claimedDetailGestures.has(event)) return;
744
+ const target = eventElement(event);
745
+ const aside = target?.closest(detailSelector);
746
+ const root = aside?.closest(ROOT_SELECTOR);
747
+ if (!target || !aside || !root || aside.hidden || !observedRoots.has(root) || target.closest(ROOT_SELECTOR) !== root) return;
748
+ const grabber = target.closest(grabberSelector);
749
+ if (!grabber && (!target.closest(".k2b-detail-panel__header") || target.closest("a, button, input, select, textarea, [role='button'], [contenteditable]:not([contenteditable='false'])"))) return;
750
+ claimedDetailGestures.add(event);
751
+ if (detailDrag) finishDetailDrag(true);
752
+ const drag = beginDetailDrag(aside, grabber ?? target, "pointer", event.clientX, event.clientY, event.pointerId);
753
+ drag.releaseTextSelection = suppressTextSelection(event.pointerId);
754
+ if (drag.target instanceof HTMLElement) drag.target.setPointerCapture?.(event.pointerId);
755
+ aside.dataset.workspaceDetailDragging = "true";
756
+ touchedDetails.add(aside);
757
+ };
758
+ const onSheetPointerMove = event => {
759
+ const drag = detailDrag;
760
+ if (!drag || drag.source !== "pointer" || drag.pointerId !== event.pointerId) return;
761
+ drag.dy = event.clientY - drag.startY;
762
+ drag.moved ||= Math.abs(drag.dy) > 4;
763
+ if (drag.moved) scheduleDetailDrag();
764
+ };
765
+ const onSheetPointerEnd = event => {
766
+ if (!(event instanceof PointerEvent)) return;
767
+ if (detailDrag?.source === "pointer" && detailDrag.pointerId === event.pointerId) finishDetailDrag(event.type !== "pointerup");
768
+ };
769
+ const onGrabberClick = event => {
770
+ const target = eventElement(event);
771
+ const grabber = target?.closest(grabberSelector);
772
+ const aside = grabber?.closest(detailSelector);
773
+ if (!aside || aside.hidden || !phone?.matches || claimedToggleClicks.has(event)) return;
774
+ claimedToggleClicks.add(event);
775
+ if (suppressedClick === aside && event instanceof MouseEvent && event.detail !== 0) {
776
+ event.preventDefault();
777
+ suppressedClick = null;
778
+ return;
779
+ }
780
+ setDetent(aside, aside.dataset.workspaceDetailSheet !== "full");
781
+ };
782
+ const ownsTouchGesture = (target, aside, source) => {
783
+ for (let element = target; element && element !== aside; element = element.parentElement) {
784
+ if (element.matches("input, textarea, select, [contenteditable]:not([contenteditable='false']), [role='slider'], [draggable='true'], canvas")) return true;
785
+ const action = getComputedStyle(element).getPropertyValue("touch-action");
786
+ const horizontal = /\bpan-(x|left|right)\b/.test(action);
787
+ const vertical = /\bpan-(y|up|down)\b/.test(action);
788
+ if (action.trim() === "none" || (source === "drawer" ? vertical && !horizontal : horizontal && !vertical)) return true;
789
+ }
790
+ return false;
791
+ };
792
+ const onDetailTouchStart = event => {
793
+ if (!(event instanceof TouchEvent) || event.touches.length !== 1) {
794
+ if (detailDrag && detailDrag.source !== "pointer") finishDetailDrag(true);
795
+ return;
796
+ }
797
+ if (detailDrag || claimedDetailGestures.has(event)) return;
798
+ const target = eventElement(event);
799
+ const aside = target?.closest(detailSelector);
800
+ const touch = event.touches[0];
801
+ const root = aside?.closest(ROOT_SELECTOR);
802
+ if (!target || !aside || !root || aside.hidden || !touch || !observedRoots.has(root) || target.closest(ROOT_SELECTOR) !== root) return;
803
+ if (phone?.matches && (verticalScroller(target, aside) ?? aside).scrollTop <= 0) {
804
+ if (!ownsTouchGesture(target, aside, "sheet")) beginDetailDrag(aside, target, "sheet", touch.clientX, touch.clientY, touch.identifier);
805
+ } else if (touchDrawer?.matches && closable(aside)) {
806
+ if (!ownsTouchGesture(target, aside, "drawer")) beginDetailDrag(aside, target, "drawer", touch.clientX, touch.clientY, touch.identifier);
807
+ }
808
+ if (detailDrag) claimedDetailGestures.add(event);
809
+ };
810
+ const onDetailTouchMove = event => {
811
+ const drag = detailDrag;
812
+ if (!(event instanceof TouchEvent) || !drag || drag.source === "pointer") return;
813
+ const touch = Array.from(event.touches).find(touch => touch.identifier === drag.pointerId);
814
+ if (!touch || event.touches.length !== 1) {
815
+ finishDetailDrag(true);
816
+ return;
817
+ }
818
+ const dx = touch.clientX - drag.startX;
819
+ const dy = touch.clientY - drag.startY;
820
+ const now = performance.now();
821
+ drag.velocity = (dx - drag.dx) / Math.max(1, now - drag.time);
822
+ drag.time = now;
823
+ drag.dx = dx;
824
+ drag.dy = dy;
825
+ if (!drag.moved) {
826
+ if (drag.source === "sheet") {
827
+ if (dy < 0 || (verticalScroller(drag.target, drag.aside) ?? drag.aside).scrollTop > 0) {
828
+ finishDetailDrag(true);
829
+ return;
830
+ }
831
+ if (dy <= 4) return;
832
+ } else {
833
+ if (Math.max(Math.abs(dx), Math.abs(dy)) <= 8) return;
834
+ if (dx <= Math.abs(dy)) {
835
+ finishDetailDrag(true);
836
+ return;
837
+ }
838
+ for (let element = drag.target; element && drag.aside.contains(element); element = element.parentElement) {
839
+ if (element instanceof HTMLElement && /^(auto|scroll)$/.test(getComputedStyle(element).overflowX) && element.scrollWidth > element.clientWidth && element.scrollLeft > 0) {
840
+ finishDetailDrag(true);
841
+ return;
842
+ }
843
+ if (element === drag.aside) break;
844
+ }
845
+ }
846
+ drag.moved = true;
847
+ }
848
+ event.preventDefault();
849
+ scheduleDetailDrag();
850
+ };
851
+ const onDetailTouchEnd = event => {
852
+ if (detailDrag && detailDrag.source !== "pointer") finishDetailDrag(event.type === "touchcancel");
853
+ };
854
+ const onDetailDoubleClick = event => {
855
+ const handle = resizeHandle(event);
856
+ const root = handle?.closest(ROOT_SELECTOR);
857
+ if (!handle || !root || resizeKind(handle) !== "detail" || !workspaceResizable(root) || !controlsResizableRegion(root, handle, "detail")) return;
858
+ const widths = {
859
+ ...layoutState.detailWidths
860
+ };
861
+ delete widths[panelId(handle)];
862
+ layoutState = {
863
+ ...layoutState,
864
+ detailWidths: widths
865
+ };
866
+ const variable = appWorkspacePanelVariable("detail", panelId(handle));
867
+ root.style.removeProperty(variable);
868
+ if (getComputedStyle(root).getPropertyValue(variable).trim()) root.style.setProperty(variable, `${numberData(handle, "workspaceDefaultSize", APP_WORKSPACE_DETAIL_DEFAULT)}px`);
869
+ updateHandleValue(root, handle, "detail", currentSize(root, handle, "detail"));
870
+ options.writeState?.(layoutState);
871
+ };
170
872
  const stopScrollFades = installScrollFades(eventRoot);
171
873
  let layoutState = normalizeAppWorkspaceLayoutState(options.readState?.()) ?? {
172
874
  version: 2
@@ -248,7 +950,7 @@ export const installAppWorkspaceController = (options = {}) => {
248
950
  if (finished.kind !== "drawer") reconcilePanes(finished.root, layoutState);
249
951
  }
250
952
  if (finished.handle.hasPointerCapture?.(finished.pointerId)) finished.handle.releasePointerCapture(finished.pointerId);
251
- document.body.style.userSelect = finished.previousUserSelect;
953
+ finished.releaseTextSelection();
252
954
  window.removeEventListener("pointermove", onPointerMove);
253
955
  window.removeEventListener("pointerup", stopResize);
254
956
  window.removeEventListener("pointercancel", stopResize);
@@ -274,11 +976,10 @@ export const installAppWorkspaceController = (options = {}) => {
274
976
  moved: false,
275
977
  hiding: false,
276
978
  direction: resizeDirection(handle, kind),
277
- previousUserSelect: document.body.style.userSelect
979
+ releaseTextSelection: suppressTextSelection(event.pointerId)
278
980
  };
279
981
  root.dataset.workspaceResizeActive = kind;
280
982
  handle.dataset.workspaceResizeActive = "true";
281
- document.body.style.userSelect = "none";
282
983
  handle.setPointerCapture?.(event.pointerId);
283
984
  window.addEventListener("pointermove", onPointerMove);
284
985
  window.addEventListener("pointerup", stopResize);
@@ -324,6 +1025,14 @@ export const installAppWorkspaceController = (options = {}) => {
324
1025
  return allRoots().filter(root => getComputedStyle(root).display !== "none" && root.getBoundingClientRect().width > 0);
325
1026
  };
326
1027
  const reconcile = () => {
1028
+ if (detailDrag && (detailDrag.source === "drawer" ? !touchDrawer?.matches : !phone?.matches)) finishDetailDrag(true);
1029
+ allRoots().forEach(root => {
1030
+ if (!phone?.matches) {
1031
+ for (const aside of rootElements(root, detailSelector)) {
1032
+ if (aside.dataset.workspaceDetailSheet === "full") setDetent(aside, false);
1033
+ }
1034
+ }
1035
+ });
327
1036
  roots().forEach(root => {
328
1037
  // `data-workspace-resizable="false"` already refuses pointer and keyboard
329
1038
  // resizing; without this the same workspace still had persisted sizes
@@ -400,28 +1109,91 @@ export const installAppWorkspaceController = (options = {}) => {
400
1109
  scheduleReconcile(true);
401
1110
  });
402
1111
  const syncObservedRoots = () => {
403
- if (!resizeObserver) return;
1112
+ for (const elements of [touchedDetails, titleTabIndices, motionRoots]) {
1113
+ elements.forEach(element => {
1114
+ if (!element.isConnected) elements.delete(element);
1115
+ });
1116
+ }
404
1117
  const next = new Set(allRoots());
405
1118
  observedRoots.forEach(root => {
406
1119
  if (!next.has(root)) {
407
- resizeObserver.unobserve(root);
1120
+ pendingAnchors.get(root)?.();
1121
+ slides.get(root)?.();
1122
+ resizeObserver?.unobserve(root);
1123
+ const frame = motionFrames.get(root);
1124
+ if (frame !== undefined) cancelAnimationFrame(frame);
1125
+ motionFrames.delete(root);
408
1126
  observedRoots.delete(root);
409
1127
  }
410
1128
  });
1129
+ touchMoveAsides.forEach(aside => {
1130
+ if (aside.isConnected) return;
1131
+ aside.removeEventListener("touchmove", onDetailTouchMove);
1132
+ touchMoveAsides.delete(aside);
1133
+ });
411
1134
  next.forEach(root => {
1135
+ rootElements(root, detailSelector).forEach(aside => {
1136
+ if (!detailHidden.has(aside)) detailHidden.set(aside, Boolean(aside.hidden));
1137
+ if (touchMoveAsides.has(aside)) return;
1138
+ aside.addEventListener("touchmove", onDetailTouchMove, {
1139
+ passive: false
1140
+ });
1141
+ touchMoveAsides.add(aside);
1142
+ });
412
1143
  if (observedRoots.has(root)) return;
413
1144
  observedRoots.add(root);
414
- resizeObserver.observe(root);
1145
+ resizeObserver?.observe(root);
1146
+ if (!root.hasAttribute("data-workspace-motion")) {
1147
+ motionRoots.add(root);
1148
+ motionFrames.set(root, requestAnimationFrame(() => {
1149
+ motionFrames.set(root, requestAnimationFrame(() => {
1150
+ motionFrames.delete(root);
1151
+ if (observedRoots.has(root)) root.dataset.workspaceMotion = "true";
1152
+ }));
1153
+ }));
1154
+ }
415
1155
  });
416
1156
  };
417
1157
  const layoutNode = node => node instanceof Element && (node.matches(LAYOUT_REGION_SELECTOR) || Boolean(node.querySelector(LAYOUT_REGION_SELECTOR)));
418
1158
  const mutationObserver = typeof MutationObserver === "undefined" ? null : new MutationObserver(records => {
1159
+ if (pendingTitle && (pendingTitle.aside.hidden || !pendingTitle.aside.isConnected)) cancelTitle();
1160
+ // Hiding or removing the sidebar, or its button, ends the overlay.
1161
+ if (overlay && (overlay.sidebar.hidden || !overlay.sidebar.isConnected || !overlay.toggle.isConnected)) closeOverlay("kept");
1162
+ const details = new Set();
1163
+ for (const record of records) {
1164
+ if (record.type === "attributes" && record.target instanceof HTMLElement && record.target.matches(detailSelector) && !details.has(record.target)) {
1165
+ details.add(record.target);
1166
+ detailTransition(record.target, detailHidden.get(record.target) ?? record.oldValue !== null);
1167
+ }
1168
+ }
419
1169
  const changed = records.some(record => record.type === "attributes" ? record.target instanceof Element && record.target.matches(LAYOUT_REGION_SELECTOR) : [...Array.from(record.addedNodes), ...Array.from(record.removedNodes)].some(layoutNode));
420
1170
  if (!changed) return;
421
1171
  syncObservedRoots();
422
1172
  scheduleReconcile();
423
1173
  });
424
1174
  eventRoot.addEventListener("pointerdown", onPointerDown);
1175
+ eventRoot.addEventListener("click", onClick);
1176
+ ownerDocument.addEventListener("keydown", onOverlayKeyDown);
1177
+ ownerWindow.addEventListener("keydown", onDetailKeyDown);
1178
+ ownerDocument.addEventListener("focusin", cancelTitleOnInteraction, true);
1179
+ ownerDocument.addEventListener("pointerdown", cancelTitleOnInteraction, true);
1180
+ ownerDocument.addEventListener("keydown", cancelTitleOnInteraction, true);
1181
+ eventRoot.addEventListener("pointerdown", rememberInteraction, true);
1182
+ eventRoot.addEventListener("keydown", rememberInteraction, true);
1183
+ eventRoot.addEventListener("focusin", onDetailFocusIn);
1184
+ eventRoot.addEventListener("pointerdown", onSheetPointerDown);
1185
+ eventRoot.addEventListener("click", onGrabberClick);
1186
+ eventRoot.addEventListener("dblclick", onDetailDoubleClick);
1187
+ window.addEventListener("pointermove", onSheetPointerMove);
1188
+ window.addEventListener("pointerup", onSheetPointerEnd);
1189
+ window.addEventListener("pointercancel", onSheetPointerEnd);
1190
+ eventRoot.addEventListener("lostpointercapture", onSheetPointerEnd);
1191
+ eventRoot.addEventListener("touchstart", onDetailTouchStart, {
1192
+ passive: true
1193
+ });
1194
+ eventRoot.addEventListener("touchend", onDetailTouchEnd);
1195
+ eventRoot.addEventListener("touchcancel", onDetailTouchEnd);
1196
+ compact?.addEventListener("change", onCompactChange);
425
1197
  eventRoot.addEventListener("keydown", onKeyDown);
426
1198
  eventRoot.addEventListener("focusin", onFocusIn);
427
1199
  eventRoot.addEventListener("pointerover", onPointerOver);
@@ -429,13 +1201,46 @@ export const installAppWorkspaceController = (options = {}) => {
429
1201
  syncObservedRoots();
430
1202
  mutationObserver?.observe(eventRoot, {
431
1203
  attributes: true,
1204
+ attributeOldValue: true,
432
1205
  attributeFilter: ["hidden"],
433
1206
  childList: true,
434
1207
  subtree: true
435
1208
  });
436
1209
  scheduleReconcile();
437
1210
  return () => {
1211
+ cancelTitle();
1212
+ pendingAnchors.forEach(cancel => cancel());
1213
+ slides.forEach(end => end());
438
1214
  stopScrollFades();
1215
+ finishDetailDrag(true);
1216
+ if (suppressedClickTimer !== null) clearTimeout(suppressedClickTimer);
1217
+ motionFrames.forEach(cancelAnimationFrame);
1218
+ revealFrames.forEach(cancelAnimationFrame);
1219
+ motionRoots.forEach(root => delete root.dataset.workspaceMotion);
1220
+ touchedDetails.forEach(aside => {
1221
+ clearDrag(aside);
1222
+ delete aside.dataset.workspaceDetailSheet;
1223
+ aside.querySelector(grabberSelector)?.setAttribute("aria-pressed", "false");
1224
+ });
1225
+ titleTabIndices.forEach(title => title.removeAttribute("tabindex"));
1226
+ ownerWindow.removeEventListener("keydown", onDetailKeyDown);
1227
+ ownerDocument.removeEventListener("focusin", cancelTitleOnInteraction, true);
1228
+ ownerDocument.removeEventListener("pointerdown", cancelTitleOnInteraction, true);
1229
+ ownerDocument.removeEventListener("keydown", cancelTitleOnInteraction, true);
1230
+ eventRoot.removeEventListener("pointerdown", rememberInteraction, true);
1231
+ eventRoot.removeEventListener("keydown", rememberInteraction, true);
1232
+ eventRoot.removeEventListener("focusin", onDetailFocusIn);
1233
+ eventRoot.removeEventListener("pointerdown", onSheetPointerDown);
1234
+ eventRoot.removeEventListener("click", onGrabberClick);
1235
+ eventRoot.removeEventListener("dblclick", onDetailDoubleClick);
1236
+ window.removeEventListener("pointermove", onSheetPointerMove);
1237
+ window.removeEventListener("pointerup", onSheetPointerEnd);
1238
+ window.removeEventListener("pointercancel", onSheetPointerEnd);
1239
+ eventRoot.removeEventListener("lostpointercapture", onSheetPointerEnd);
1240
+ eventRoot.removeEventListener("touchstart", onDetailTouchStart);
1241
+ touchMoveAsides.forEach(aside => aside.removeEventListener("touchmove", onDetailTouchMove));
1242
+ eventRoot.removeEventListener("touchend", onDetailTouchEnd);
1243
+ eventRoot.removeEventListener("touchcancel", onDetailTouchEnd);
439
1244
  // Flush the latest coalesced pointer sample before listeners and frames are
440
1245
  // torn down, so unmounting during a drag cannot lose the final size.
441
1246
  stopResize();
@@ -443,7 +1248,11 @@ export const installAppWorkspaceController = (options = {}) => {
443
1248
  mutationObserver?.disconnect();
444
1249
  resizeObserver?.disconnect();
445
1250
  observedRoots.clear();
1251
+ closeOverlay("none");
446
1252
  eventRoot.removeEventListener("pointerdown", onPointerDown);
1253
+ eventRoot.removeEventListener("click", onClick);
1254
+ ownerDocument.removeEventListener("keydown", onOverlayKeyDown);
1255
+ compact?.removeEventListener("change", onCompactChange);
447
1256
  eventRoot.removeEventListener("keydown", onKeyDown);
448
1257
  eventRoot.removeEventListener("focusin", onFocusIn);
449
1258
  eventRoot.removeEventListener("pointerover", onPointerOver);