@k2b/ui 0.20.0 → 0.22.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 (595) hide show
  1. package/dist/browser/actions/Button.js +20 -31
  2. package/dist/browser/actions/Button.js.map +1 -1
  3. package/dist/browser/actions/ContextMenu.js +10 -4
  4. package/dist/browser/actions/ContextMenu.js.map +1 -1
  5. package/dist/browser/actions/CopyButton.js +10 -8
  6. package/dist/browser/actions/CopyButton.js.map +1 -1
  7. package/dist/browser/actions/FilterChip.js +3 -1
  8. package/dist/browser/actions/FilterChip.js.map +1 -1
  9. package/dist/browser/actions/GestureMenu.js +4 -0
  10. package/dist/browser/actions/GestureMenu.js.map +1 -1
  11. package/dist/browser/actions/SpotlightSearch.js +3 -1
  12. package/dist/browser/actions/SpotlightSearch.js.map +1 -1
  13. package/dist/browser/actions/filter-messages.js +20 -0
  14. package/dist/browser/actions/filter-messages.js.map +1 -0
  15. package/dist/browser/actions/spotlight-messages.js +16 -0
  16. package/dist/browser/actions/spotlight-messages.js.map +1 -0
  17. package/dist/browser/chat/ChatComposer.js +47 -41
  18. package/dist/browser/chat/ChatComposer.js.map +1 -1
  19. package/dist/browser/chat/ChatPrimitives.js +25 -23
  20. package/dist/browser/chat/ChatPrimitives.js.map +1 -1
  21. package/dist/browser/chat/ChatRoot.js +3 -3
  22. package/dist/browser/chat/ChatRoot.js.map +1 -1
  23. package/dist/browser/chat/ChatTimeline.js +12 -12
  24. package/dist/browser/chat/ChatTimeline.js.map +1 -1
  25. package/dist/browser/chat/chat-messages.js +236 -0
  26. package/dist/browser/chat/chat-messages.js.map +1 -0
  27. package/dist/browser/content/Calendar.js +1960 -575
  28. package/dist/browser/content/Calendar.js.map +1 -1
  29. package/dist/browser/content/Chart.js +15 -8
  30. package/dist/browser/content/Chart.js.map +1 -1
  31. package/dist/browser/content/ChartExplorer.js +20 -12
  32. package/dist/browser/content/ChartExplorer.js.map +1 -1
  33. package/dist/browser/content/ChartExplorerControls.js +9 -7
  34. package/dist/browser/content/ChartExplorerControls.js.map +1 -1
  35. package/dist/browser/content/ChartFilterControls.js +4 -2
  36. package/dist/browser/content/ChartFilterControls.js.map +1 -1
  37. package/dist/browser/content/ChartSnapshotView.js +3 -3
  38. package/dist/browser/content/ChartSnapshotView.js.map +1 -1
  39. package/dist/browser/content/DataTable.js +68 -59
  40. package/dist/browser/content/DataTable.js.map +1 -1
  41. package/dist/browser/content/Docs.js +3 -1
  42. package/dist/browser/content/Docs.js.map +1 -1
  43. package/dist/browser/content/FileBrowser.js +30 -26
  44. package/dist/browser/content/FileBrowser.js.map +1 -1
  45. package/dist/browser/content/FileTree.js +9 -7
  46. package/dist/browser/content/FileTree.js.map +1 -1
  47. package/dist/browser/content/FileView.js +37 -28
  48. package/dist/browser/content/FileView.js.map +1 -1
  49. package/dist/browser/content/Lightbox.js +9 -7
  50. package/dist/browser/content/Lightbox.js.map +1 -1
  51. package/dist/browser/content/LogEntriesTable.js +3 -3
  52. package/dist/browser/content/LogEntriesTable.js.map +1 -1
  53. package/dist/browser/content/MessageRow.js +24 -22
  54. package/dist/browser/content/MessageRow.js.map +1 -1
  55. package/dist/browser/content/Pagination.js +7 -7
  56. package/dist/browser/content/Pagination.js.map +1 -1
  57. package/dist/browser/content/PdfPreview.js +15 -13
  58. package/dist/browser/content/PdfPreview.js.map +1 -1
  59. package/dist/browser/content/RangePicker.js +3 -1
  60. package/dist/browser/content/RangePicker.js.map +1 -1
  61. package/dist/browser/content/StructuredDataPreview.js +3 -1
  62. package/dist/browser/content/StructuredDataPreview.js.map +1 -1
  63. package/dist/browser/content/Timeline.js +13 -11
  64. package/dist/browser/content/Timeline.js.map +1 -1
  65. package/dist/browser/content/VideoPlayer.js +5 -5
  66. package/dist/browser/content/VideoPlayer.js.map +1 -1
  67. package/dist/browser/content/VirtualFeed.js +6 -4
  68. package/dist/browser/content/VirtualFeed.js.map +1 -1
  69. package/dist/browser/content/ZoomPanViewport.js +10 -7
  70. package/dist/browser/content/ZoomPanViewport.js.map +1 -1
  71. package/dist/browser/content/calendar-messages.js +121 -0
  72. package/dist/browser/content/calendar-messages.js.map +1 -0
  73. package/dist/browser/content/calendar-month-layout.js +108 -0
  74. package/dist/browser/content/calendar-month-layout.js.map +1 -0
  75. package/dist/browser/content/calendar-pointer.js +4 -3
  76. package/dist/browser/content/calendar-pointer.js.map +1 -1
  77. package/dist/browser/content/chart-messages.js +136 -0
  78. package/dist/browser/content/chart-messages.js.map +1 -0
  79. package/dist/browser/content/collection-selection.js +2 -0
  80. package/dist/browser/content/collection-selection.js.map +1 -1
  81. package/dist/browser/content/data-table-messages.js +24 -0
  82. package/dist/browser/content/data-table-messages.js.map +1 -0
  83. package/dist/browser/content/docs-messages.js +24 -0
  84. package/dist/browser/content/docs-messages.js.map +1 -0
  85. package/dist/browser/content/feed-messages.js +34 -0
  86. package/dist/browser/content/feed-messages.js.map +1 -0
  87. package/dist/browser/content/file-browser-messages.js +69 -0
  88. package/dist/browser/content/file-browser-messages.js.map +1 -0
  89. package/dist/browser/content/file-view-messages.js +64 -0
  90. package/dist/browser/content/file-view-messages.js.map +1 -0
  91. package/dist/browser/content/index.js.map +1 -1
  92. package/dist/browser/content/lightbox-messages.js +36 -0
  93. package/dist/browser/content/lightbox-messages.js.map +1 -0
  94. package/dist/browser/content/log-entries-messages.js +20 -0
  95. package/dist/browser/content/log-entries-messages.js.map +1 -0
  96. package/dist/browser/content/markdown-info-block-messages.js +24 -0
  97. package/dist/browser/content/markdown-info-block-messages.js.map +1 -0
  98. package/dist/browser/content/markdown-info-blocks.js +3 -3
  99. package/dist/browser/content/markdown-info-blocks.js.map +1 -1
  100. package/dist/browser/content/markdown-links.js +2 -2
  101. package/dist/browser/content/markdown-links.js.map +1 -1
  102. package/dist/browser/content/markdown-reference-messages.js +30 -0
  103. package/dist/browser/content/markdown-reference-messages.js.map +1 -0
  104. package/dist/browser/content/pagination-messages.js +38 -0
  105. package/dist/browser/content/pagination-messages.js.map +1 -0
  106. package/dist/browser/content/pdf-messages.js +43 -0
  107. package/dist/browser/content/pdf-messages.js.map +1 -0
  108. package/dist/browser/content/range-picker-messages.js +20 -0
  109. package/dist/browser/content/range-picker-messages.js.map +1 -0
  110. package/dist/browser/content/structured-data-messages.js +22 -0
  111. package/dist/browser/content/structured-data-messages.js.map +1 -0
  112. package/dist/browser/content/timeline-messages.js +62 -0
  113. package/dist/browser/content/timeline-messages.js.map +1 -0
  114. package/dist/browser/content/video-messages.js +24 -0
  115. package/dist/browser/content/video-messages.js.map +1 -0
  116. package/dist/browser/content/viewport-messages.js +28 -0
  117. package/dist/browser/content/viewport-messages.js.map +1 -0
  118. package/dist/browser/feedback/HoverPreview.js +34 -6
  119. package/dist/browser/feedback/HoverPreview.js.map +1 -1
  120. package/dist/browser/feedback/InstallGuide.js +18 -18
  121. package/dist/browser/feedback/InstallGuide.js.map +1 -1
  122. package/dist/browser/feedback/install-messages.js +104 -0
  123. package/dist/browser/feedback/install-messages.js.map +1 -0
  124. package/dist/browser/feedback/prompt-messages.js +65 -0
  125. package/dist/browser/feedback/prompt-messages.js.map +1 -0
  126. package/dist/browser/feedback/prompts.js +14 -11
  127. package/dist/browser/feedback/prompts.js.map +1 -1
  128. package/dist/browser/feedback/toast-messages.js +18 -0
  129. package/dist/browser/feedback/toast-messages.js.map +1 -0
  130. package/dist/browser/feedback/toast.js +4 -3
  131. package/dist/browser/feedback/toast.js.map +1 -1
  132. package/dist/browser/index.js +1 -1
  133. package/dist/browser/index.js.map +1 -1
  134. package/dist/browser/inputs/AutocompleteEditor.js +6 -4
  135. package/dist/browser/inputs/AutocompleteEditor.js.map +1 -1
  136. package/dist/browser/inputs/AutocompleteSelect.js +10 -8
  137. package/dist/browser/inputs/AutocompleteSelect.js.map +1 -1
  138. package/dist/browser/inputs/ChoiceGroups.js +4 -0
  139. package/dist/browser/inputs/ChoiceGroups.js.map +1 -1
  140. package/dist/browser/inputs/ChoiceInputs.js +5 -5
  141. package/dist/browser/inputs/ChoiceInputs.js.map +1 -1
  142. package/dist/browser/inputs/Combobox.js +3 -1
  143. package/dist/browser/inputs/Combobox.js.map +1 -1
  144. package/dist/browser/inputs/DatePicker.js +46 -10
  145. package/dist/browser/inputs/DatePicker.js.map +1 -1
  146. package/dist/browser/inputs/FileDropTarget.js +6 -6
  147. package/dist/browser/inputs/FileDropTarget.js.map +1 -1
  148. package/dist/browser/inputs/FileInputs.js +30 -21
  149. package/dist/browser/inputs/FileInputs.js.map +1 -1
  150. package/dist/browser/inputs/MultiSelectInput.js +7 -5
  151. package/dist/browser/inputs/MultiSelectInput.js.map +1 -1
  152. package/dist/browser/inputs/NumberInput.js +4 -2
  153. package/dist/browser/inputs/NumberInput.js.map +1 -1
  154. package/dist/browser/inputs/QrScanner.js +5 -5
  155. package/dist/browser/inputs/QrScanner.js.map +1 -1
  156. package/dist/browser/inputs/Select.js +7 -5
  157. package/dist/browser/inputs/Select.js.map +1 -1
  158. package/dist/browser/inputs/SelectChip.js +3 -3
  159. package/dist/browser/inputs/SelectChip.js.map +1 -1
  160. package/dist/browser/inputs/SignatureInput.js +9 -3
  161. package/dist/browser/inputs/SignatureInput.js.map +1 -1
  162. package/dist/browser/inputs/SpecialInputs.js +4 -2
  163. package/dist/browser/inputs/SpecialInputs.js.map +1 -1
  164. package/dist/browser/inputs/TagEditor.js +8 -6
  165. package/dist/browser/inputs/TagEditor.js.map +1 -1
  166. package/dist/browser/inputs/TagsInput.js +5 -5
  167. package/dist/browser/inputs/TagsInput.js.map +1 -1
  168. package/dist/browser/inputs/TemplateEditor.js +5 -5
  169. package/dist/browser/inputs/TemplateEditor.js.map +1 -1
  170. package/dist/browser/inputs/TextInput.js +3 -1
  171. package/dist/browser/inputs/TextInput.js.map +1 -1
  172. package/dist/browser/inputs/completion-messages.js +24 -0
  173. package/dist/browser/inputs/completion-messages.js.map +1 -0
  174. package/dist/browser/inputs/date-picker.js +24 -0
  175. package/dist/browser/inputs/date-picker.js.map +1 -1
  176. package/dist/browser/inputs/file-drop-messages.js +63 -0
  177. package/dist/browser/inputs/file-drop-messages.js.map +1 -0
  178. package/dist/browser/inputs/file-drop.js.map +1 -1
  179. package/dist/browser/inputs/file-input-messages.js +60 -0
  180. package/dist/browser/inputs/file-input-messages.js.map +1 -0
  181. package/dist/browser/inputs/icon-messages.js +22 -0
  182. package/dist/browser/inputs/icon-messages.js.map +1 -0
  183. package/dist/browser/inputs/input-messages.js +38 -0
  184. package/dist/browser/inputs/input-messages.js.map +1 -0
  185. package/dist/browser/inputs/markdown/MarkdownEditor.js +10 -6
  186. package/dist/browser/inputs/markdown/MarkdownEditor.js.map +1 -1
  187. package/dist/browser/inputs/markdown/Toolbar.js +13 -13
  188. package/dist/browser/inputs/markdown/Toolbar.js.map +1 -1
  189. package/dist/browser/inputs/markdown/editor-messages.js +43 -0
  190. package/dist/browser/inputs/markdown/editor-messages.js.map +1 -0
  191. package/dist/browser/inputs/markdown/toolbar-messages.js +40 -0
  192. package/dist/browser/inputs/markdown/toolbar-messages.js.map +1 -0
  193. package/dist/browser/inputs/qr-messages.js +26 -0
  194. package/dist/browser/inputs/qr-messages.js.map +1 -0
  195. package/dist/browser/inputs/select-messages.js +63 -0
  196. package/dist/browser/inputs/select-messages.js.map +1 -0
  197. package/dist/browser/inputs/tag-messages.js +44 -0
  198. package/dist/browser/inputs/tag-messages.js.map +1 -0
  199. package/dist/browser/inputs/template-messages.js +22 -0
  200. package/dist/browser/inputs/template-messages.js.map +1 -0
  201. package/dist/browser/internal/render-error-messages.js +20 -0
  202. package/dist/browser/internal/render-error-messages.js.map +1 -0
  203. package/dist/browser/internal/render-error.js +3 -1
  204. package/dist/browser/internal/render-error.js.map +1 -1
  205. package/dist/browser/internal/text-selection.js +101 -0
  206. package/dist/browser/internal/text-selection.js.map +1 -0
  207. package/dist/browser/intl/messages.js +12 -1155
  208. package/dist/browser/intl/messages.js.map +1 -1
  209. package/dist/browser/layout/AppWorkspace.js +561 -418
  210. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  211. package/dist/browser/layout/BottomSheet.js +6 -1
  212. package/dist/browser/layout/BottomSheet.js.map +1 -1
  213. package/dist/browser/layout/Discussion.js +8 -5
  214. package/dist/browser/layout/Discussion.js.map +1 -1
  215. package/dist/browser/layout/FloatingWindow.js +8 -5
  216. package/dist/browser/layout/FloatingWindow.js.map +1 -1
  217. package/dist/browser/layout/Navigation.js +7 -6
  218. package/dist/browser/layout/Navigation.js.map +1 -1
  219. package/dist/browser/layout/PageTitle.js +370 -0
  220. package/dist/browser/layout/PageTitle.js.map +1 -0
  221. package/dist/browser/layout/PanelDialog.js +8 -6
  222. package/dist/browser/layout/PanelDialog.js.map +1 -1
  223. package/dist/browser/layout/Panes.js +23 -15
  224. package/dist/browser/layout/Panes.js.map +1 -1
  225. package/dist/browser/layout/PullToRefresh.js +13 -4
  226. package/dist/browser/layout/PullToRefresh.js.map +1 -1
  227. package/dist/browser/layout/Settings.js +14 -12
  228. package/dist/browser/layout/Settings.js.map +1 -1
  229. package/dist/browser/layout/SettingsCollection.js +6 -5
  230. package/dist/browser/layout/SettingsCollection.js.map +1 -1
  231. package/dist/browser/layout/SettingsModal.js +3 -1
  232. package/dist/browser/layout/SettingsModal.js.map +1 -1
  233. package/dist/browser/layout/app-workspace-controller.js +743 -12
  234. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  235. package/dist/browser/layout/app-workspace-state.js +3 -2
  236. package/dist/browser/layout/app-workspace-state.js.map +1 -1
  237. package/dist/browser/layout/floating-window-messages.js +28 -0
  238. package/dist/browser/layout/floating-window-messages.js.map +1 -0
  239. package/dist/browser/layout/index.js +2 -0
  240. package/dist/browser/layout/index.js.map +1 -1
  241. package/dist/browser/layout/navigation-model.js.map +1 -1
  242. package/dist/browser/layout/page-title-controller.js +169 -0
  243. package/dist/browser/layout/page-title-controller.js.map +1 -0
  244. package/dist/browser/layout/panel-dialog-messages.js +20 -0
  245. package/dist/browser/layout/panel-dialog-messages.js.map +1 -0
  246. package/dist/browser/layout/panes-messages.js +48 -0
  247. package/dist/browser/layout/panes-messages.js.map +1 -0
  248. package/dist/browser/layout/refresh-messages.js +20 -0
  249. package/dist/browser/layout/refresh-messages.js.map +1 -0
  250. package/dist/browser/layout/settings-messages.js +54 -0
  251. package/dist/browser/layout/settings-messages.js.map +1 -0
  252. package/dist/browser/layout/workspace-messages.js +56 -0
  253. package/dist/browser/layout/workspace-messages.js.map +1 -0
  254. package/dist/browser/surfaces/Avatar.js +5 -5
  255. package/dist/browser/surfaces/Avatar.js.map +1 -1
  256. package/dist/browser/surfaces/ResourceCard.js +4 -2
  257. package/dist/browser/surfaces/ResourceCard.js.map +1 -1
  258. package/dist/browser/surfaces/Tag.js +3 -3
  259. package/dist/browser/surfaces/Tag.js.map +1 -1
  260. package/dist/browser/surfaces/avatar-messages.js +26 -0
  261. package/dist/browser/surfaces/avatar-messages.js.map +1 -0
  262. package/dist/browser/surfaces/resource-messages.js +26 -0
  263. package/dist/browser/surfaces/resource-messages.js.map +1 -0
  264. package/dist/browser/widgets/Widget.js +6 -0
  265. package/dist/browser/widgets/Widget.js.map +1 -1
  266. package/dist/ssr/actions/Button.js +21 -32
  267. package/dist/ssr/actions/Button.js.map +1 -1
  268. package/dist/ssr/actions/ContextMenu.js +7 -3
  269. package/dist/ssr/actions/ContextMenu.js.map +1 -1
  270. package/dist/ssr/actions/CopyButton.js +9 -7
  271. package/dist/ssr/actions/CopyButton.js.map +1 -1
  272. package/dist/ssr/actions/FilterChip.js +3 -1
  273. package/dist/ssr/actions/FilterChip.js.map +1 -1
  274. package/dist/ssr/actions/GestureMenu.js +4 -0
  275. package/dist/ssr/actions/GestureMenu.js.map +1 -1
  276. package/dist/ssr/actions/SpotlightSearch.js +3 -1
  277. package/dist/ssr/actions/SpotlightSearch.js.map +1 -1
  278. package/dist/ssr/actions/filter-messages.js +20 -0
  279. package/dist/ssr/actions/filter-messages.js.map +1 -0
  280. package/dist/ssr/actions/spotlight-messages.js +16 -0
  281. package/dist/ssr/actions/spotlight-messages.js.map +1 -0
  282. package/dist/ssr/chat/ChatComposer.js +47 -41
  283. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  284. package/dist/ssr/chat/ChatPrimitives.js +23 -21
  285. package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
  286. package/dist/ssr/chat/ChatRoot.js +3 -3
  287. package/dist/ssr/chat/ChatRoot.js.map +1 -1
  288. package/dist/ssr/chat/ChatTimeline.js +11 -11
  289. package/dist/ssr/chat/ChatTimeline.js.map +1 -1
  290. package/dist/ssr/chat/chat-messages.js +236 -0
  291. package/dist/ssr/chat/chat-messages.js.map +1 -0
  292. package/dist/ssr/content/Calendar.js +1232 -115
  293. package/dist/ssr/content/Calendar.js.map +1 -1
  294. package/dist/ssr/content/Chart.js +12 -5
  295. package/dist/ssr/content/Chart.js.map +1 -1
  296. package/dist/ssr/content/ChartExplorer.js +10 -8
  297. package/dist/ssr/content/ChartExplorer.js.map +1 -1
  298. package/dist/ssr/content/ChartExplorerControls.js +9 -7
  299. package/dist/ssr/content/ChartExplorerControls.js.map +1 -1
  300. package/dist/ssr/content/ChartFilterControls.js +4 -2
  301. package/dist/ssr/content/ChartFilterControls.js.map +1 -1
  302. package/dist/ssr/content/ChartSnapshotView.js +3 -3
  303. package/dist/ssr/content/ChartSnapshotView.js.map +1 -1
  304. package/dist/ssr/content/DataTable.js +10 -4
  305. package/dist/ssr/content/DataTable.js.map +1 -1
  306. package/dist/ssr/content/Docs.js +3 -1
  307. package/dist/ssr/content/Docs.js.map +1 -1
  308. package/dist/ssr/content/FileBrowser.js +30 -26
  309. package/dist/ssr/content/FileBrowser.js.map +1 -1
  310. package/dist/ssr/content/FileTree.js +9 -7
  311. package/dist/ssr/content/FileTree.js.map +1 -1
  312. package/dist/ssr/content/FileView.js +37 -28
  313. package/dist/ssr/content/FileView.js.map +1 -1
  314. package/dist/ssr/content/Lightbox.js +8 -6
  315. package/dist/ssr/content/Lightbox.js.map +1 -1
  316. package/dist/ssr/content/LogEntriesTable.js +3 -3
  317. package/dist/ssr/content/LogEntriesTable.js.map +1 -1
  318. package/dist/ssr/content/MessageRow.js +24 -22
  319. package/dist/ssr/content/MessageRow.js.map +1 -1
  320. package/dist/ssr/content/Pagination.js +6 -6
  321. package/dist/ssr/content/Pagination.js.map +1 -1
  322. package/dist/ssr/content/PdfPreview.js +15 -13
  323. package/dist/ssr/content/PdfPreview.js.map +1 -1
  324. package/dist/ssr/content/RangePicker.js +3 -1
  325. package/dist/ssr/content/RangePicker.js.map +1 -1
  326. package/dist/ssr/content/StructuredDataPreview.js +3 -1
  327. package/dist/ssr/content/StructuredDataPreview.js.map +1 -1
  328. package/dist/ssr/content/Timeline.js +13 -11
  329. package/dist/ssr/content/Timeline.js.map +1 -1
  330. package/dist/ssr/content/VideoPlayer.js +5 -5
  331. package/dist/ssr/content/VideoPlayer.js.map +1 -1
  332. package/dist/ssr/content/VirtualFeed.js +6 -4
  333. package/dist/ssr/content/VirtualFeed.js.map +1 -1
  334. package/dist/ssr/content/ZoomPanViewport.js +7 -4
  335. package/dist/ssr/content/ZoomPanViewport.js.map +1 -1
  336. package/dist/ssr/content/calendar-messages.js +121 -0
  337. package/dist/ssr/content/calendar-messages.js.map +1 -0
  338. package/dist/ssr/content/calendar-month-layout.js +108 -0
  339. package/dist/ssr/content/calendar-month-layout.js.map +1 -0
  340. package/dist/ssr/content/calendar-pointer.js +4 -3
  341. package/dist/ssr/content/calendar-pointer.js.map +1 -1
  342. package/dist/ssr/content/chart-messages.js +136 -0
  343. package/dist/ssr/content/chart-messages.js.map +1 -0
  344. package/dist/ssr/content/collection-selection.js +2 -0
  345. package/dist/ssr/content/collection-selection.js.map +1 -1
  346. package/dist/ssr/content/data-table-messages.js +24 -0
  347. package/dist/ssr/content/data-table-messages.js.map +1 -0
  348. package/dist/ssr/content/docs-messages.js +24 -0
  349. package/dist/ssr/content/docs-messages.js.map +1 -0
  350. package/dist/ssr/content/feed-messages.js +34 -0
  351. package/dist/ssr/content/feed-messages.js.map +1 -0
  352. package/dist/ssr/content/file-browser-messages.js +69 -0
  353. package/dist/ssr/content/file-browser-messages.js.map +1 -0
  354. package/dist/ssr/content/file-view-messages.js +64 -0
  355. package/dist/ssr/content/file-view-messages.js.map +1 -0
  356. package/dist/ssr/content/index.js.map +1 -1
  357. package/dist/ssr/content/lightbox-messages.js +36 -0
  358. package/dist/ssr/content/lightbox-messages.js.map +1 -0
  359. package/dist/ssr/content/log-entries-messages.js +20 -0
  360. package/dist/ssr/content/log-entries-messages.js.map +1 -0
  361. package/dist/ssr/content/markdown-info-block-messages.js +24 -0
  362. package/dist/ssr/content/markdown-info-block-messages.js.map +1 -0
  363. package/dist/ssr/content/markdown-info-blocks.js +3 -3
  364. package/dist/ssr/content/markdown-info-blocks.js.map +1 -1
  365. package/dist/ssr/content/markdown-links.js +2 -2
  366. package/dist/ssr/content/markdown-links.js.map +1 -1
  367. package/dist/ssr/content/markdown-reference-messages.js +30 -0
  368. package/dist/ssr/content/markdown-reference-messages.js.map +1 -0
  369. package/dist/ssr/content/pagination-messages.js +38 -0
  370. package/dist/ssr/content/pagination-messages.js.map +1 -0
  371. package/dist/ssr/content/pdf-messages.js +43 -0
  372. package/dist/ssr/content/pdf-messages.js.map +1 -0
  373. package/dist/ssr/content/range-picker-messages.js +20 -0
  374. package/dist/ssr/content/range-picker-messages.js.map +1 -0
  375. package/dist/ssr/content/structured-data-messages.js +22 -0
  376. package/dist/ssr/content/structured-data-messages.js.map +1 -0
  377. package/dist/ssr/content/timeline-messages.js +62 -0
  378. package/dist/ssr/content/timeline-messages.js.map +1 -0
  379. package/dist/ssr/content/video-messages.js +24 -0
  380. package/dist/ssr/content/video-messages.js.map +1 -0
  381. package/dist/ssr/content/viewport-messages.js +28 -0
  382. package/dist/ssr/content/viewport-messages.js.map +1 -0
  383. package/dist/ssr/feedback/HoverPreview.js +34 -6
  384. package/dist/ssr/feedback/HoverPreview.js.map +1 -1
  385. package/dist/ssr/feedback/InstallGuide.js +18 -18
  386. package/dist/ssr/feedback/InstallGuide.js.map +1 -1
  387. package/dist/ssr/feedback/install-messages.js +104 -0
  388. package/dist/ssr/feedback/install-messages.js.map +1 -0
  389. package/dist/ssr/feedback/prompt-messages.js +65 -0
  390. package/dist/ssr/feedback/prompt-messages.js.map +1 -0
  391. package/dist/ssr/feedback/prompts.js +14 -11
  392. package/dist/ssr/feedback/prompts.js.map +1 -1
  393. package/dist/ssr/feedback/toast-messages.js +18 -0
  394. package/dist/ssr/feedback/toast-messages.js.map +1 -0
  395. package/dist/ssr/feedback/toast.js +4 -3
  396. package/dist/ssr/feedback/toast.js.map +1 -1
  397. package/dist/ssr/index.js +1 -1
  398. package/dist/ssr/index.js.map +1 -1
  399. package/dist/ssr/inputs/AutocompleteEditor.js +5 -3
  400. package/dist/ssr/inputs/AutocompleteEditor.js.map +1 -1
  401. package/dist/ssr/inputs/AutocompleteSelect.js +10 -8
  402. package/dist/ssr/inputs/AutocompleteSelect.js.map +1 -1
  403. package/dist/ssr/inputs/ChoiceGroups.js +4 -0
  404. package/dist/ssr/inputs/ChoiceGroups.js.map +1 -1
  405. package/dist/ssr/inputs/ChoiceInputs.js +5 -5
  406. package/dist/ssr/inputs/ChoiceInputs.js.map +1 -1
  407. package/dist/ssr/inputs/Combobox.js +3 -1
  408. package/dist/ssr/inputs/Combobox.js.map +1 -1
  409. package/dist/ssr/inputs/DatePicker.js +34 -4
  410. package/dist/ssr/inputs/DatePicker.js.map +1 -1
  411. package/dist/ssr/inputs/FileDropTarget.js +6 -6
  412. package/dist/ssr/inputs/FileDropTarget.js.map +1 -1
  413. package/dist/ssr/inputs/FileInputs.js +29 -20
  414. package/dist/ssr/inputs/FileInputs.js.map +1 -1
  415. package/dist/ssr/inputs/MultiSelectInput.js +7 -5
  416. package/dist/ssr/inputs/MultiSelectInput.js.map +1 -1
  417. package/dist/ssr/inputs/NumberInput.js +4 -2
  418. package/dist/ssr/inputs/NumberInput.js.map +1 -1
  419. package/dist/ssr/inputs/QrScanner.js +4 -4
  420. package/dist/ssr/inputs/QrScanner.js.map +1 -1
  421. package/dist/ssr/inputs/Select.js +7 -5
  422. package/dist/ssr/inputs/Select.js.map +1 -1
  423. package/dist/ssr/inputs/SelectChip.js +3 -3
  424. package/dist/ssr/inputs/SelectChip.js.map +1 -1
  425. package/dist/ssr/inputs/SignatureInput.js +9 -3
  426. package/dist/ssr/inputs/SignatureInput.js.map +1 -1
  427. package/dist/ssr/inputs/SpecialInputs.js +4 -2
  428. package/dist/ssr/inputs/SpecialInputs.js.map +1 -1
  429. package/dist/ssr/inputs/TagEditor.js +8 -6
  430. package/dist/ssr/inputs/TagEditor.js.map +1 -1
  431. package/dist/ssr/inputs/TagsInput.js +5 -5
  432. package/dist/ssr/inputs/TagsInput.js.map +1 -1
  433. package/dist/ssr/inputs/TemplateEditor.js +5 -5
  434. package/dist/ssr/inputs/TemplateEditor.js.map +1 -1
  435. package/dist/ssr/inputs/TextInput.js +3 -1
  436. package/dist/ssr/inputs/TextInput.js.map +1 -1
  437. package/dist/ssr/inputs/completion-messages.js +24 -0
  438. package/dist/ssr/inputs/completion-messages.js.map +1 -0
  439. package/dist/ssr/inputs/date-picker.js +24 -0
  440. package/dist/ssr/inputs/date-picker.js.map +1 -1
  441. package/dist/ssr/inputs/file-drop-messages.js +63 -0
  442. package/dist/ssr/inputs/file-drop-messages.js.map +1 -0
  443. package/dist/ssr/inputs/file-drop.js.map +1 -1
  444. package/dist/ssr/inputs/file-input-messages.js +60 -0
  445. package/dist/ssr/inputs/file-input-messages.js.map +1 -0
  446. package/dist/ssr/inputs/icon-messages.js +22 -0
  447. package/dist/ssr/inputs/icon-messages.js.map +1 -0
  448. package/dist/ssr/inputs/input-messages.js +38 -0
  449. package/dist/ssr/inputs/input-messages.js.map +1 -0
  450. package/dist/ssr/inputs/markdown/MarkdownEditor.js +9 -5
  451. package/dist/ssr/inputs/markdown/MarkdownEditor.js.map +1 -1
  452. package/dist/ssr/inputs/markdown/Toolbar.js +13 -13
  453. package/dist/ssr/inputs/markdown/Toolbar.js.map +1 -1
  454. package/dist/ssr/inputs/markdown/editor-messages.js +43 -0
  455. package/dist/ssr/inputs/markdown/editor-messages.js.map +1 -0
  456. package/dist/ssr/inputs/markdown/toolbar-messages.js +40 -0
  457. package/dist/ssr/inputs/markdown/toolbar-messages.js.map +1 -0
  458. package/dist/ssr/inputs/qr-messages.js +26 -0
  459. package/dist/ssr/inputs/qr-messages.js.map +1 -0
  460. package/dist/ssr/inputs/select-messages.js +63 -0
  461. package/dist/ssr/inputs/select-messages.js.map +1 -0
  462. package/dist/ssr/inputs/tag-messages.js +44 -0
  463. package/dist/ssr/inputs/tag-messages.js.map +1 -0
  464. package/dist/ssr/inputs/template-messages.js +22 -0
  465. package/dist/ssr/inputs/template-messages.js.map +1 -0
  466. package/dist/ssr/internal/render-error-messages.js +20 -0
  467. package/dist/ssr/internal/render-error-messages.js.map +1 -0
  468. package/dist/ssr/internal/render-error.js +3 -1
  469. package/dist/ssr/internal/render-error.js.map +1 -1
  470. package/dist/ssr/internal/text-selection.js +101 -0
  471. package/dist/ssr/internal/text-selection.js.map +1 -0
  472. package/dist/ssr/intl/messages.js +12 -1155
  473. package/dist/ssr/intl/messages.js.map +1 -1
  474. package/dist/ssr/layout/AppWorkspace.js +203 -96
  475. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  476. package/dist/ssr/layout/BottomSheet.js +1 -0
  477. package/dist/ssr/layout/BottomSheet.js.map +1 -1
  478. package/dist/ssr/layout/Discussion.js +8 -5
  479. package/dist/ssr/layout/Discussion.js.map +1 -1
  480. package/dist/ssr/layout/FloatingWindow.js +8 -5
  481. package/dist/ssr/layout/FloatingWindow.js.map +1 -1
  482. package/dist/ssr/layout/Navigation.js +6 -5
  483. package/dist/ssr/layout/Navigation.js.map +1 -1
  484. package/dist/ssr/layout/PageTitle.js +253 -0
  485. package/dist/ssr/layout/PageTitle.js.map +1 -0
  486. package/dist/ssr/layout/PanelDialog.js +8 -6
  487. package/dist/ssr/layout/PanelDialog.js.map +1 -1
  488. package/dist/ssr/layout/Panes.js +22 -14
  489. package/dist/ssr/layout/Panes.js.map +1 -1
  490. package/dist/ssr/layout/PullToRefresh.js +13 -4
  491. package/dist/ssr/layout/PullToRefresh.js.map +1 -1
  492. package/dist/ssr/layout/Settings.js +14 -12
  493. package/dist/ssr/layout/Settings.js.map +1 -1
  494. package/dist/ssr/layout/SettingsCollection.js +6 -5
  495. package/dist/ssr/layout/SettingsCollection.js.map +1 -1
  496. package/dist/ssr/layout/SettingsModal.js +3 -1
  497. package/dist/ssr/layout/SettingsModal.js.map +1 -1
  498. package/dist/ssr/layout/app-workspace-controller.js +743 -12
  499. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  500. package/dist/ssr/layout/app-workspace-state.js +3 -2
  501. package/dist/ssr/layout/app-workspace-state.js.map +1 -1
  502. package/dist/ssr/layout/floating-window-messages.js +28 -0
  503. package/dist/ssr/layout/floating-window-messages.js.map +1 -0
  504. package/dist/ssr/layout/index.js +2 -0
  505. package/dist/ssr/layout/index.js.map +1 -1
  506. package/dist/ssr/layout/navigation-model.js.map +1 -1
  507. package/dist/ssr/layout/page-title-controller.js +169 -0
  508. package/dist/ssr/layout/page-title-controller.js.map +1 -0
  509. package/dist/ssr/layout/panel-dialog-messages.js +20 -0
  510. package/dist/ssr/layout/panel-dialog-messages.js.map +1 -0
  511. package/dist/ssr/layout/panes-messages.js +48 -0
  512. package/dist/ssr/layout/panes-messages.js.map +1 -0
  513. package/dist/ssr/layout/refresh-messages.js +20 -0
  514. package/dist/ssr/layout/refresh-messages.js.map +1 -0
  515. package/dist/ssr/layout/settings-messages.js +54 -0
  516. package/dist/ssr/layout/settings-messages.js.map +1 -0
  517. package/dist/ssr/layout/workspace-messages.js +56 -0
  518. package/dist/ssr/layout/workspace-messages.js.map +1 -0
  519. package/dist/ssr/surfaces/Avatar.js +5 -5
  520. package/dist/ssr/surfaces/Avatar.js.map +1 -1
  521. package/dist/ssr/surfaces/ResourceCard.js +4 -2
  522. package/dist/ssr/surfaces/ResourceCard.js.map +1 -1
  523. package/dist/ssr/surfaces/Tag.js +3 -3
  524. package/dist/ssr/surfaces/Tag.js.map +1 -1
  525. package/dist/ssr/surfaces/avatar-messages.js +26 -0
  526. package/dist/ssr/surfaces/avatar-messages.js.map +1 -0
  527. package/dist/ssr/surfaces/resource-messages.js +26 -0
  528. package/dist/ssr/surfaces/resource-messages.js.map +1 -0
  529. package/dist/ssr/widgets/Widget.js +6 -0
  530. package/dist/ssr/widgets/Widget.js.map +1 -1
  531. package/dist/styles.css +1 -1
  532. package/dist/types/actions/GestureMenu.d.ts +2 -0
  533. package/dist/types/actions/filter-messages.d.ts +8 -0
  534. package/dist/types/actions/spotlight-messages.d.ts +8 -0
  535. package/dist/types/chat/chat-messages.d.ts +116 -0
  536. package/dist/types/content/Calendar.d.ts +32 -0
  537. package/dist/types/content/DataTable.d.ts +2 -0
  538. package/dist/types/content/FileView.d.ts +0 -10
  539. package/dist/types/content/calendar-messages.d.ts +60 -0
  540. package/dist/types/content/calendar-month-layout.d.ts +52 -0
  541. package/dist/types/content/chart-messages.d.ts +32 -0
  542. package/dist/types/content/data-table-messages.d.ts +10 -0
  543. package/dist/types/content/docs-messages.d.ts +10 -0
  544. package/dist/types/content/feed-messages.d.ts +15 -0
  545. package/dist/types/content/file-browser-messages.d.ts +33 -0
  546. package/dist/types/content/file-view-messages.d.ts +30 -0
  547. package/dist/types/content/index.d.ts +1 -1
  548. package/dist/types/content/lightbox-messages.d.ts +16 -0
  549. package/dist/types/content/log-entries-messages.d.ts +8 -0
  550. package/dist/types/content/markdown-info-block-messages.d.ts +12 -0
  551. package/dist/types/content/markdown-reference-messages.d.ts +15 -0
  552. package/dist/types/content/pagination-messages.d.ts +17 -0
  553. package/dist/types/content/pdf-messages.d.ts +20 -0
  554. package/dist/types/content/range-picker-messages.d.ts +8 -0
  555. package/dist/types/content/structured-data-messages.d.ts +9 -0
  556. package/dist/types/content/timeline-messages.d.ts +29 -0
  557. package/dist/types/content/video-messages.d.ts +10 -0
  558. package/dist/types/content/viewport-messages.d.ts +12 -0
  559. package/dist/types/feedback/install-messages.d.ts +50 -0
  560. package/dist/types/feedback/prompt-messages.d.ts +31 -0
  561. package/dist/types/feedback/toast-messages.d.ts +9 -0
  562. package/dist/types/index.d.ts +1 -0
  563. package/dist/types/inputs/completion-messages.d.ts +10 -0
  564. package/dist/types/inputs/date-picker.d.ts +7 -0
  565. package/dist/types/inputs/file-drop-messages.d.ts +30 -0
  566. package/dist/types/inputs/file-drop.d.ts +3 -3
  567. package/dist/types/inputs/file-input-messages.d.ts +28 -0
  568. package/dist/types/inputs/icon-messages.d.ts +9 -0
  569. package/dist/types/inputs/input-messages.d.ts +17 -0
  570. package/dist/types/inputs/markdown/editor-messages.d.ts +20 -0
  571. package/dist/types/inputs/markdown/toolbar-messages.d.ts +18 -0
  572. package/dist/types/inputs/qr-messages.d.ts +11 -0
  573. package/dist/types/inputs/select-messages.d.ts +30 -0
  574. package/dist/types/inputs/tag-messages.d.ts +20 -0
  575. package/dist/types/inputs/template-messages.d.ts +9 -0
  576. package/dist/types/internal/render-error-messages.d.ts +8 -0
  577. package/dist/types/internal/text-selection.d.ts +18 -0
  578. package/dist/types/intl/messages.d.ts +6 -544
  579. package/dist/types/layout/AppWorkspace.d.ts +19 -4
  580. package/dist/types/layout/PageTitle.d.ts +64 -0
  581. package/dist/types/layout/app-workspace-controller.d.ts +4 -0
  582. package/dist/types/layout/app-workspace-state.d.ts +3 -2
  583. package/dist/types/layout/floating-window-messages.d.ts +12 -0
  584. package/dist/types/layout/index.d.ts +3 -0
  585. package/dist/types/layout/navigation-model.d.ts +7 -0
  586. package/dist/types/layout/page-title-controller.d.ts +13 -0
  587. package/dist/types/layout/panel-dialog-messages.d.ts +8 -0
  588. package/dist/types/layout/panes-messages.d.ts +22 -0
  589. package/dist/types/layout/refresh-messages.d.ts +8 -0
  590. package/dist/types/layout/settings-messages.d.ts +25 -0
  591. package/dist/types/layout/workspace-messages.d.ts +26 -0
  592. package/dist/types/surfaces/avatar-messages.d.ts +11 -0
  593. package/dist/types/surfaces/resource-messages.d.ts +11 -0
  594. package/dist/types/widgets/Widget.d.ts +5 -1
  595. 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,10 @@ 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
+ /** Asks the owning `AppWorkspace.Detail` for the previous or next item, as `detail.direction` of `-1` or `1`. */
39
+ export const APP_WORKSPACE_DETAIL_STEP_EVENT = "k2b-app-workspace-detail-step";
29
40
  const previewSidebarHidden = (root, hidden) => {
30
41
  const sidebar = sidebarElement(root);
31
42
  if (!sidebar) return;
@@ -53,15 +64,16 @@ const sizeLimits = (root, handle, kind) => {
53
64
  const controlled = controlledPanel(root, handle);
54
65
  const main = kind === "pane" ? handle.closest(".k2b-app-workspace__main") : mainElement(root);
55
66
  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);
67
+ // A detail shares the content area with the main region, as the stylesheet
68
+ // fits it. The area already leaves out a sidebar in its own column; as the
69
+ // compact overlay or stacked above the content, the sidebar takes none of it.
70
+ const content = kind === "detail" ? controlled?.closest(".k2b-app-workspace__content") : null;
59
71
  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
72
  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
73
  return appWorkspaceResizeLimits({
62
74
  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,
75
+ workspaceSize: kind === "drawer" ? root.getBoundingClientRect().height : kind === "pane" && main ? main.getBoundingClientRect().width : (content ?? root).getBoundingClientRect().width,
76
+ reservedSize: kind === "detail" ? 16 : kind === "pane" ? panes.reduce((total, pane) => total + (pane === controlled ? 0 : elementSize(pane, "pane")), 0) : 0,
65
77
  min: numberData(handle, "workspaceMinSize", defaultMin),
66
78
  max: numberData(handle, "workspaceMaxSize", defaultMax),
67
79
  sidebarCollapsible: kind === "sidebar" && sidebarCollapsible(root)
@@ -165,8 +177,613 @@ const measureLabel = label => {
165
177
  label.style.setProperty("--k2b-sidebar-label-overflow", `${overflow}px`);
166
178
  if (overflow > 2) label.dataset.overflow = "true";else delete label.dataset.overflow;
167
179
  };
180
+
181
+ /** An open overlay remembers the regions it made inert, so it leaves the application's own `inert` alone. */
182
+
183
+ /**
184
+ * The elements Tab stops at, in order. A roving tab index, as in a tree, keeps
185
+ * links and buttons at `tabindex="-1"`; they take focus but are no stops.
186
+ */
187
+ 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");
188
+ /** Several controllers can see one click on a nested workspace's button; the innermost one, which sees it first, owns it. */
189
+ const claimedToggleClicks = new WeakSet();
190
+ const claimedDetailGestures = new WeakSet();
191
+
192
+ /**
193
+ * The compact overlay: from 48 to 64 rem the sidebar opens over the work area
194
+ * from the button in the workspace's head. While it is open the rest of
195
+ * the workspace is inert, Tab stays in the sidebar, and Escape, the scrim,
196
+ * choosing an item, hiding the sidebar, or leaving the width range close it
197
+ * again. The state is one attribute on the workspace root, so server-rendered
198
+ * and hydrated workspaces behave the same.
199
+ */
200
+ const overlayTarget = toggle => {
201
+ const root = workspaceRoot(toggle);
202
+ // The button belongs to its workspace's own sidebar. A sidebar rendered apart
203
+ // from the head, for example in an island, can carry another id than the one
204
+ // the head named, so the button learns the real one here.
205
+ const sidebar = root ? sidebarElement(root) : null;
206
+ if (!root || !sidebar || sidebar.hidden || sidebar.dataset.mobile === "stacked") return null;
207
+ if (sidebar.id) toggle.setAttribute("aria-controls", sidebar.id);
208
+ return {
209
+ root,
210
+ sidebar,
211
+ toggle
212
+ };
213
+ };
214
+ 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
215
  export const installAppWorkspaceController = (options = {}) => {
169
216
  const eventRoot = options.root ?? document;
217
+ // A document has no owner document; an element root listens on its own.
218
+ const ownerDocument = eventRoot.ownerDocument ?? document;
219
+ const ownerWindow = ownerDocument.defaultView ?? window;
220
+ let overlay = null;
221
+ const compact = typeof window.matchMedia === "function" ? window.matchMedia(COMPACT_QUERY) : null;
222
+ // A server-rendered head names the sidebar before the sidebar renders; the button learns its real id now.
223
+ for (const toggle of eventRoot.querySelectorAll(TOGGLE_SELECTOR)) overlayTarget(toggle);
224
+ const openOverlay = target => {
225
+ if (overlay) closeOverlay("none");
226
+ const inerted = overlayRegions(target.root, target.sidebar).filter(region => !region.hasAttribute("inert"));
227
+ overlay = {
228
+ ...target,
229
+ inerted
230
+ };
231
+ target.root.dataset.sidebarOverlay = "open";
232
+ target.toggle.setAttribute("aria-expanded", "true");
233
+ inerted.forEach(region => region.setAttribute("inert", ""));
234
+ // Focus starts on the current destination, so the reader knows where they
235
+ // are: on its own tab stop, or on the tree item around it.
236
+ const current = target.sidebar.querySelector("[aria-current='page'], .is-active");
237
+ const stops = tabStopsIn(target.sidebar);
238
+ const first = (current && (stops.find(element => current.contains(element)) ?? stops.findLast(element => element.contains(current)))) ?? stops[0];
239
+ if (first) first.focus();else {
240
+ target.sidebar.tabIndex = -1;
241
+ target.sidebar.focus();
242
+ }
243
+ };
244
+ /**
245
+ * `"button"` returns focus to the button. `"kept"` leaves it where it moved,
246
+ * for example into a dialog an item opened, and only rescues focus that the
247
+ * closing sidebar would hide. `"none"` moves nothing, for cleanup.
248
+ */
249
+ const closeOverlay = focus => {
250
+ const closing = overlay;
251
+ if (!closing) return;
252
+ overlay = null;
253
+ delete closing.root.dataset.sidebarOverlay;
254
+ closing.toggle.setAttribute("aria-expanded", "false");
255
+ closing.inerted.forEach(region => region.removeAttribute("inert"));
256
+ if (focus === "none") return;
257
+ const active = document.activeElement;
258
+ if (focus === "button" || !active || active === document.body || closing.sidebar.contains(active)) closing.toggle.focus();
259
+ };
260
+ const onClick = event => {
261
+ const target = eventElement(event);
262
+ const toggle = target?.closest(TOGGLE_SELECTOR);
263
+ if (toggle) {
264
+ const next = overlayTarget(toggle);
265
+ if (!next || claimedToggleClicks.has(event)) return;
266
+ claimedToggleClicks.add(event);
267
+ if (overlay?.sidebar === next.sidebar) closeOverlay("button");else if (compact?.matches) openOverlay(next);
268
+ return;
269
+ }
270
+ if (!overlay || !target) return;
271
+ // The scrim is the workspace root's own pseudo-element.
272
+ if (target === overlay.root) {
273
+ closeOverlay("button");
274
+ return;
275
+ }
276
+ // Choosing a destination closes the overlay: a link, or the button of a
277
+ // row. A tree folder that only expands, a control that opens a popup or
278
+ // expands something, such as a row's preview, and an item's own actions
279
+ // keep it open.
280
+ const control = target.closest("a[href], button");
281
+ if (!control || !overlay.sidebar.contains(control)) return;
282
+ 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;
283
+ if (control.matches("a[href]") || control.closest(ITEM_SELECTOR)) closeOverlay("kept");
284
+ };
285
+ const onOverlayKeyDown = event => {
286
+ if (!overlay || event.defaultPrevented) return;
287
+ const target = eventElement(event);
288
+ if (!target) return;
289
+ // Escape also closes it when a click left focus on nothing, so on the body.
290
+ if (event.key === "Escape" && (overlay.sidebar.contains(target) || target === ownerDocument.body)) {
291
+ event.preventDefault();
292
+ closeOverlay("button");
293
+ return;
294
+ }
295
+ if (event.key !== "Tab" || !overlay.sidebar.contains(target)) return;
296
+ const stops = tabStopsIn(overlay.sidebar);
297
+ const first = stops[0];
298
+ const last = stops.at(-1);
299
+ if (!first || !last) {
300
+ event.preventDefault();
301
+ return;
302
+ }
303
+ if (event.shiftKey && (document.activeElement === first || document.activeElement === overlay.sidebar)) {
304
+ event.preventDefault();
305
+ last.focus();
306
+ } else if (!event.shiftKey && document.activeElement === last) {
307
+ event.preventDefault();
308
+ first.focus();
309
+ }
310
+ };
311
+ const onCompactChange = () => {
312
+ if (!compact?.matches) closeOverlay("none");
313
+ };
314
+ const phone = typeof window.matchMedia === "function" ? window.matchMedia("(max-width: 47.999rem)") : null;
315
+ const wide = typeof window.matchMedia === "function" ? window.matchMedia("(min-width: 48rem)") : null;
316
+ const touchDrawer = typeof window.matchMedia === "function" ? window.matchMedia(`${COMPACT_QUERY} and (pointer: coarse)`) : null;
317
+ const reducedMotion = typeof window.matchMedia === "function" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null;
318
+ const detailSelector = ".k2b-app-workspace__detail";
319
+ const grabberSelector = ".k2b-app-workspace__detail-grabber";
320
+ const trailSelector = ".k2b-detail-trail";
321
+ const detailHidden = new WeakMap();
322
+ const remembered = new WeakMap();
323
+ const lastFocus = new WeakMap();
324
+ const trailPadding = new WeakMap();
325
+ const heldTrails = new Set();
326
+ const touchedDetails = new Set();
327
+ // Only a panel blocks scrolling for its touch gestures; a document-wide
328
+ // non-passive listener would make every scroll on the page wait for script.
329
+ const touchMoveAsides = new Set();
330
+ const titleTabIndices = new Set();
331
+ const motionFrames = new Map();
332
+ const motionRoots = new Set();
333
+ const revealFrames = new Map();
334
+ const openDetails = root => rootElements(root, detailSelector).filter(aside => !aside.hidden);
335
+ const closeControl = aside => Array.from(aside.querySelectorAll("[data-workspace-detail-close]")).find(control => control.closest(detailSelector) === aside);
336
+ const closable = aside => aside.hasAttribute("data-workspace-detail-closable") || Boolean(closeControl(aside));
337
+ const requestClose = aside => {
338
+ if (aside.hasAttribute("data-workspace-detail-closable")) aside.dispatchEvent(new CustomEvent(APP_WORKSPACE_DETAIL_CLOSE_EVENT));else closeControl(aside)?.click();
339
+ };
340
+ const verticalScroller = (target, boundary) => {
341
+ for (let element = target; element && boundary.contains(element); element = element.parentElement) {
342
+ if (element instanceof HTMLElement && /^(auto|scroll)$/.test(getComputedStyle(element).overflowY) && element.scrollHeight > element.clientHeight) return element;
343
+ if (element === boundary) break;
344
+ }
345
+ return null;
346
+ };
347
+ const refreshItem = snapshot => {
348
+ snapshot.top = snapshot.item.getBoundingClientRect().top;
349
+ snapshot.scrollTop = snapshot.scroller?.scrollTop ?? 0;
350
+ };
351
+ const rememberInteraction = event => {
352
+ const target = eventElement(event);
353
+ const root = target?.closest(ROOT_SELECTOR);
354
+ if (!target || !root || !observedRoots.has(root)) return;
355
+ const previous = remembered.get(root);
356
+ if (previous && openDetails(root).length) refreshItem(previous);
357
+ const main = mainElement(root);
358
+ const item = target.closest(FOCUSABLE_SELECTOR);
359
+ if (!main || !item || !main.contains(item) || item.closest(ROOT_SELECTOR) !== root) return;
360
+ if (event instanceof KeyboardEvent && event.key !== "Enter" && event.key !== " ") return;
361
+ const snapshot = {
362
+ item,
363
+ interaction: event instanceof KeyboardEvent ? "keyboard" : "pointer",
364
+ scroller: verticalScroller(item, main),
365
+ scrollTop: 0,
366
+ top: 0,
367
+ fresh: true
368
+ };
369
+ refreshItem(snapshot);
370
+ remembered.set(root, snapshot);
371
+ // Enter in an editor or a field types; only an item that chooses something moves on to its title.
372
+ if (event instanceof KeyboardEvent && !target.closest(KEY_OWNER_SELECTOR)) {
373
+ const aside = openDetails(root).find(isVisible);
374
+ if (aside) requestTitle(aside, true);
375
+ }
376
+ };
377
+ const onDetailFocusIn = event => {
378
+ const target = eventElement(event);
379
+ const root = target?.closest(ROOT_SELECTOR);
380
+ if (!target || !root || !observedRoots.has(root)) return;
381
+ lastFocus.set(root, target);
382
+ const previous = remembered.get(root);
383
+ // Pointer focus follows pointerdown; keeping that snapshot also keeps the
384
+ // interaction that opened the panel rather than treating focus as a new one.
385
+ if (previous?.item.contains(target)) {
386
+ const main = mainElement(root);
387
+ if (target !== previous.item && target instanceof HTMLElement && main) {
388
+ previous.item = target;
389
+ previous.scroller = verticalScroller(target, main);
390
+ refreshItem(previous);
391
+ }
392
+ return;
393
+ }
394
+ rememberInteraction(event);
395
+ };
396
+ const titleIn = aside => aside.querySelector("h1, h2, h3, [role='heading']");
397
+ let focusingTitle = null;
398
+ const focusTitle = aside => {
399
+ const title = titleIn(aside);
400
+ if (!title) return false;
401
+ if (!title.matches(FOCUSABLE_SELECTOR) && !title.hasAttribute("tabindex")) {
402
+ title.tabIndex = -1;
403
+ titleTabIndices.add(title);
404
+ }
405
+ focusingTitle = title;
406
+ try {
407
+ title.focus({
408
+ preventScroll: true
409
+ });
410
+ } finally {
411
+ focusingTitle = null;
412
+ }
413
+ return true;
414
+ };
415
+ let pendingTitle = null;
416
+ const cancelTitle = () => {
417
+ pendingTitle?.observer.disconnect();
418
+ pendingTitle = null;
419
+ };
420
+ const cancelTitleOnInteraction = event => {
421
+ if (event.type !== "focusin" || event.target !== focusingTitle) cancelTitle();
422
+ };
423
+ const requestTitle = (aside, waitForChange = false) => {
424
+ cancelTitle();
425
+ if (aside.hidden || !aside.isConnected) return;
426
+ if (!waitForChange && focusTitle(aside)) return;
427
+ const previousTitle = titleIn(aside);
428
+ const previousText = previousTitle?.textContent;
429
+ // Loading fallbacks and selection changes can produce their heading after
430
+ // the opening interaction. A later user action always takes precedence.
431
+ const observer = new MutationObserver(() => {
432
+ if (aside.hidden || !aside.isConnected) {
433
+ cancelTitle();
434
+ return;
435
+ }
436
+ const title = titleIn(aside);
437
+ if (!title || waitForChange && title === previousTitle && title.textContent === previousText) return;
438
+ cancelTitle();
439
+ focusTitle(aside);
440
+ });
441
+ pendingTitle = {
442
+ aside,
443
+ observer
444
+ };
445
+ observer.observe(aside, {
446
+ childList: true,
447
+ subtree: true,
448
+ characterData: true
449
+ });
450
+ // An element-scoped controller cannot see its own root leave the document.
451
+ observer.observe(ownerDocument, {
452
+ childList: true,
453
+ subtree: true
454
+ });
455
+ };
456
+ const setDetent = (aside, full) => {
457
+ touchedDetails.add(aside);
458
+ if (full) aside.dataset.workspaceDetailSheet = "full";else delete aside.dataset.workspaceDetailSheet;
459
+ aside.querySelector(grabberSelector)?.setAttribute("aria-pressed", String(full));
460
+ };
461
+ const clearDrag = aside => {
462
+ aside.style.removeProperty("--k2b-workspace-detail-sheet-height");
463
+ aside.style.removeProperty("transform");
464
+ delete aside.dataset.workspaceDetailDragging;
465
+ };
466
+ const trailsIn = root => {
467
+ const main = mainElement(root);
468
+ return main ? rootElements(root, trailSelector).filter(trail => main.contains(trail)) : [];
469
+ };
470
+ const clearHolds = root => {
471
+ for (const trail of trailsIn(root)) {
472
+ trail.style.removeProperty("--k2b-detail-trail-hold");
473
+ heldTrails.delete(trail);
474
+ }
475
+ };
476
+ const rememberTrailPadding = root => {
477
+ if (!openDetails(root).some(isVisible)) return;
478
+ for (const trail of trailsIn(root)) trailPadding.set(trail, Number.parseFloat(getComputedStyle(trail).paddingInlineEnd) || 0);
479
+ };
480
+ const shrinkHold = trail => {
481
+ const hold = Number.parseFloat(trail.style.getPropertyValue("--k2b-detail-trail-hold")) || 0;
482
+ const visible = trail.scrollWidth <= trail.clientWidth || trail.scrollLeft < 1 ? 0 : Math.min(hold, Math.max(0, Math.ceil(trail.scrollLeft + trail.clientWidth - (trail.scrollWidth - hold))));
483
+ if (visible > 0) trail.style.setProperty("--k2b-detail-trail-hold", `${visible}px`);else {
484
+ trail.style.removeProperty("--k2b-detail-trail-hold");
485
+ heldTrails.delete(trail);
486
+ }
487
+ };
488
+ const onTrailScroll = event => {
489
+ const target = eventElement(event);
490
+ if (target instanceof HTMLElement && heldTrails.has(target)) shrinkHold(target);
491
+ };
492
+ const anchorItem = (root, aside, snapshot) => {
493
+ if (!wide?.matches || touchDrawer?.matches && closable(aside) || trailsIn(root).length || !snapshot?.item.isConnected) return;
494
+ if (!mainElement(root)?.contains(snapshot.item) || snapshot.item.closest(ROOT_SELECTOR) !== root) return;
495
+ const scroller = snapshot.scroller;
496
+ if (scroller?.isConnected && scroller.scrollTop === snapshot.scrollTop) scroller.scrollTop += snapshot.item.getBoundingClientRect().top - snapshot.top;
497
+ };
498
+ const detailTransition = (aside, wasHidden) => {
499
+ const root = aside.closest(ROOT_SELECTOR);
500
+ detailHidden.set(aside, Boolean(aside.hidden));
501
+ if (!root || !observedRoots.has(root) || Boolean(aside.hidden) === wasHidden) return;
502
+ touchedDetails.add(aside);
503
+ const pending = revealFrames.get(root);
504
+ if (pending !== undefined) cancelAnimationFrame(pending);
505
+ revealFrames.delete(root);
506
+ const snapshot = remembered.get(root);
507
+ const followedInteraction = snapshot?.fresh ?? false;
508
+ if (snapshot) snapshot.fresh = false;
509
+ if (aside.hidden) {
510
+ if (pendingTitle?.aside === aside) cancelTitle();
511
+ const trails = trailsIn(root);
512
+ // Restore all padding before the first layout read, or the browser can
513
+ // clamp scrollLeft as soon as the open panel's trailing space disappears.
514
+ for (const trail of trails) {
515
+ const hold = trailPadding.get(trail) ?? 0;
516
+ if (hold > 0) {
517
+ trail.style.setProperty("--k2b-detail-trail-hold", `${hold}px`);
518
+ heldTrails.add(trail);
519
+ }
520
+ }
521
+ trails.forEach(shrinkHold);
522
+ anchorItem(root, aside, snapshot);
523
+ const focused = ownerDocument.activeElement;
524
+ if (snapshot?.item.isConnected && (aside.contains(lastFocus.get(root) ?? null) || aside.contains(focused) || focused === ownerDocument.body)) snapshot.item.focus({
525
+ preventScroll: true
526
+ });
527
+ clearDrag(aside);
528
+ if (detailDrag?.aside === aside) finishDetailDrag(true);
529
+ return;
530
+ }
531
+ clearHolds(root);
532
+ anchorItem(root, aside, snapshot);
533
+ if (phone?.matches) setDetent(aside, false);
534
+ rememberTrailPadding(root);
535
+ if (followedInteraction && snapshot) {
536
+ revealFrames.set(root, requestAnimationFrame(() => {
537
+ revealFrames.delete(root);
538
+ if (!aside.hidden && aside.isConnected && snapshot.item.isConnected && mainElement(root)?.contains(snapshot.item) && snapshot.item.closest(ROOT_SELECTOR) === root) {
539
+ const behavior = reducedMotion?.matches ? "auto" : "smooth";
540
+ if (phone?.matches) {
541
+ const sheetTop = ownerWindow.innerHeight - aside.offsetHeight;
542
+ const overlap = snapshot.item.getBoundingClientRect().bottom - sheetTop + 8;
543
+ const main = mainElement(root);
544
+ if (overlap > 0 && main) (verticalScroller(snapshot.item, main) ?? ownerDocument.scrollingElement)?.scrollBy({
545
+ top: overlap,
546
+ behavior
547
+ });
548
+ } else snapshot.item.scrollIntoView({
549
+ block: "nearest",
550
+ inline: "nearest",
551
+ behavior
552
+ });
553
+ }
554
+ }));
555
+ if (snapshot.interaction === "keyboard" || phone?.matches) requestTitle(aside);
556
+ }
557
+ };
558
+ const onDetailKeyDown = event => {
559
+ if (event.defaultPrevented || event.ctrlKey || event.metaKey || event.altKey) return;
560
+ const target = eventElement(event);
561
+ if (!target || target.closest(KEY_OWNER_SELECTOR)) return;
562
+ if (ownerDocument.querySelector("dialog[open], [aria-modal='true']")) return;
563
+ try {
564
+ if (ownerDocument.querySelector(":popover-open")) return;
565
+ } catch {
566
+ // Older engines have no popover selector; the other popup guards still apply.
567
+ }
568
+ const root = target.closest(ROOT_SELECTOR);
569
+ let aside = target.closest(detailSelector);
570
+ if (aside?.hidden || aside && (!eventRoot.contains(aside) || aside.closest(ROOT_SELECTOR) !== root)) aside = null;
571
+ if (!aside && root && observedRoots.has(root) && mainElement(root)?.contains(target)) aside = openDetails(root)[0] ?? null;
572
+ if (!aside && target === ownerDocument.body) {
573
+ const open = allRoots().flatMap(openDetails);
574
+ if (open.length === 1) aside = open[0];
575
+ }
576
+ const owningRoot = aside?.closest(ROOT_SELECTOR);
577
+ if (!aside || !owningRoot) return;
578
+ if (event.key === "Escape" && closable(aside)) requestClose(aside);else if ((event.key.toLowerCase() === "j" || event.key.toLowerCase() === "k") && aside.hasAttribute("data-workspace-detail-steppable")) aside.dispatchEvent(new CustomEvent(APP_WORKSPACE_DETAIL_STEP_EVENT, {
579
+ detail: {
580
+ direction: event.key.toLowerCase() === "j" ? 1 : -1
581
+ }
582
+ }));else if (event.key === "F6") {
583
+ if (aside.contains(target)) {
584
+ const item = remembered.get(owningRoot)?.item;
585
+ const main = mainElement(owningRoot);
586
+ (item?.isConnected ? item : main ? tabStopsIn(main)[0] : null)?.focus({
587
+ preventScroll: true
588
+ });
589
+ } else focusTitle(aside);
590
+ } else return;
591
+ event.preventDefault();
592
+ };
593
+ let detailDrag = null;
594
+ let detailDragFrame = null;
595
+ let suppressedClick = null;
596
+ let suppressedClickTimer = null;
597
+ const paintDetailDrag = () => {
598
+ detailDragFrame = null;
599
+ const drag = detailDrag;
600
+ if (!drag?.moved) return;
601
+ drag.aside.dataset.workspaceDetailDragging = "true";
602
+ touchedDetails.add(drag.aside);
603
+ if (drag.source === "drawer") drag.aside.style.transform = `translateX(${Math.max(0, drag.dx)}px)`;else {
604
+ const height = ownerWindow.innerHeight;
605
+ drag.aside.style.setProperty("--k2b-workspace-detail-sheet-height", `${clamp(drag.startHeight - drag.dy, 0, Math.max(0, height - 8))}px`);
606
+ }
607
+ };
608
+ const scheduleDetailDrag = () => {
609
+ if (detailDragFrame === null) detailDragFrame = requestAnimationFrame(paintDetailDrag);
610
+ };
611
+ const finishDetailDrag = cancelled => {
612
+ const drag = detailDrag;
613
+ if (!drag) return;
614
+ detailDrag = null;
615
+ if (detailDragFrame !== null) cancelAnimationFrame(detailDragFrame);
616
+ detailDragFrame = null;
617
+ drag.releaseTextSelection?.();
618
+ if (drag.source === "pointer") {
619
+ if (drag.target instanceof HTMLElement && drag.target.hasPointerCapture?.(drag.pointerId)) drag.target.releasePointerCapture(drag.pointerId);
620
+ if (drag.moved) {
621
+ suppressedClick = drag.aside;
622
+ if (suppressedClickTimer !== null) clearTimeout(suppressedClickTimer);
623
+ suppressedClickTimer = setTimeout(() => {
624
+ suppressedClick = null;
625
+ suppressedClickTimer = null;
626
+ }, 0);
627
+ }
628
+ }
629
+ clearDrag(drag.aside);
630
+ if (cancelled || !drag.moved) return;
631
+ if (drag.source === "drawer") {
632
+ if (drag.dx > 80 || drag.dx > 30 && drag.velocity > 0.5) requestClose(drag.aside);
633
+ } else if (drag.dy > 60) {
634
+ setDetent(drag.aside, false);
635
+ if (!drag.full && closable(drag.aside)) requestClose(drag.aside);
636
+ } else if (drag.dy < -60) setDetent(drag.aside, true);
637
+ };
638
+ const beginDetailDrag = (aside, target, source, x, y, pointerId) => {
639
+ detailDrag = {
640
+ aside,
641
+ target,
642
+ source,
643
+ pointerId,
644
+ startX: x,
645
+ startY: y,
646
+ startHeight: aside.getBoundingClientRect().height,
647
+ full: aside.dataset.workspaceDetailSheet === "full",
648
+ dx: 0,
649
+ dy: 0,
650
+ time: performance.now(),
651
+ velocity: 0,
652
+ moved: false
653
+ };
654
+ return detailDrag;
655
+ };
656
+ const onSheetPointerDown = event => {
657
+ if (!(event instanceof PointerEvent) || !phone?.matches || event.button !== 0 || !event.isPrimary || claimedDetailGestures.has(event)) return;
658
+ const target = eventElement(event);
659
+ const aside = target?.closest(detailSelector);
660
+ const root = aside?.closest(ROOT_SELECTOR);
661
+ if (!target || !aside || !root || aside.hidden || !observedRoots.has(root) || target.closest(ROOT_SELECTOR) !== root) return;
662
+ const grabber = target.closest(grabberSelector);
663
+ if (!grabber && (!target.closest(".k2b-detail-panel__header") || target.closest("a, button, input, select, textarea, [role='button'], [contenteditable]:not([contenteditable='false'])"))) return;
664
+ claimedDetailGestures.add(event);
665
+ if (detailDrag) finishDetailDrag(true);
666
+ const drag = beginDetailDrag(aside, grabber ?? target, "pointer", event.clientX, event.clientY, event.pointerId);
667
+ drag.releaseTextSelection = suppressTextSelection(event.pointerId);
668
+ if (drag.target instanceof HTMLElement) drag.target.setPointerCapture?.(event.pointerId);
669
+ aside.dataset.workspaceDetailDragging = "true";
670
+ touchedDetails.add(aside);
671
+ };
672
+ const onSheetPointerMove = event => {
673
+ const drag = detailDrag;
674
+ if (!drag || drag.source !== "pointer" || drag.pointerId !== event.pointerId) return;
675
+ drag.dy = event.clientY - drag.startY;
676
+ drag.moved ||= Math.abs(drag.dy) > 4;
677
+ if (drag.moved) scheduleDetailDrag();
678
+ };
679
+ const onSheetPointerEnd = event => {
680
+ if (!(event instanceof PointerEvent)) return;
681
+ if (detailDrag?.source === "pointer" && detailDrag.pointerId === event.pointerId) finishDetailDrag(event.type !== "pointerup");
682
+ };
683
+ const onGrabberClick = event => {
684
+ const target = eventElement(event);
685
+ const grabber = target?.closest(grabberSelector);
686
+ const aside = grabber?.closest(detailSelector);
687
+ if (!aside || aside.hidden || !phone?.matches || claimedToggleClicks.has(event)) return;
688
+ claimedToggleClicks.add(event);
689
+ if (suppressedClick === aside && event instanceof MouseEvent && event.detail !== 0) {
690
+ event.preventDefault();
691
+ suppressedClick = null;
692
+ return;
693
+ }
694
+ setDetent(aside, aside.dataset.workspaceDetailSheet !== "full");
695
+ };
696
+ const ownsTouchGesture = (target, aside, source) => {
697
+ for (let element = target; element && element !== aside; element = element.parentElement) {
698
+ if (element.matches("input, textarea, select, [contenteditable]:not([contenteditable='false']), [role='slider'], [draggable='true'], canvas")) return true;
699
+ const action = getComputedStyle(element).getPropertyValue("touch-action");
700
+ const horizontal = /\bpan-(x|left|right)\b/.test(action);
701
+ const vertical = /\bpan-(y|up|down)\b/.test(action);
702
+ if (action.trim() === "none" || (source === "drawer" ? vertical && !horizontal : horizontal && !vertical)) return true;
703
+ }
704
+ return false;
705
+ };
706
+ const onDetailTouchStart = event => {
707
+ if (!(event instanceof TouchEvent) || event.touches.length !== 1) {
708
+ if (detailDrag && detailDrag.source !== "pointer") finishDetailDrag(true);
709
+ return;
710
+ }
711
+ if (detailDrag || claimedDetailGestures.has(event)) return;
712
+ const target = eventElement(event);
713
+ const aside = target?.closest(detailSelector);
714
+ const touch = event.touches[0];
715
+ const root = aside?.closest(ROOT_SELECTOR);
716
+ if (!target || !aside || !root || aside.hidden || !touch || !observedRoots.has(root) || target.closest(ROOT_SELECTOR) !== root) return;
717
+ if (phone?.matches && (verticalScroller(target, aside) ?? aside).scrollTop <= 0) {
718
+ if (!ownsTouchGesture(target, aside, "sheet")) beginDetailDrag(aside, target, "sheet", touch.clientX, touch.clientY, touch.identifier);
719
+ } else if (touchDrawer?.matches && closable(aside)) {
720
+ if (!ownsTouchGesture(target, aside, "drawer")) beginDetailDrag(aside, target, "drawer", touch.clientX, touch.clientY, touch.identifier);
721
+ }
722
+ if (detailDrag) claimedDetailGestures.add(event);
723
+ };
724
+ const onDetailTouchMove = event => {
725
+ const drag = detailDrag;
726
+ if (!(event instanceof TouchEvent) || !drag || drag.source === "pointer") return;
727
+ const touch = Array.from(event.touches).find(touch => touch.identifier === drag.pointerId);
728
+ if (!touch || event.touches.length !== 1) {
729
+ finishDetailDrag(true);
730
+ return;
731
+ }
732
+ const dx = touch.clientX - drag.startX;
733
+ const dy = touch.clientY - drag.startY;
734
+ const now = performance.now();
735
+ drag.velocity = (dx - drag.dx) / Math.max(1, now - drag.time);
736
+ drag.time = now;
737
+ drag.dx = dx;
738
+ drag.dy = dy;
739
+ if (!drag.moved) {
740
+ if (drag.source === "sheet") {
741
+ if (dy < 0 || (verticalScroller(drag.target, drag.aside) ?? drag.aside).scrollTop > 0) {
742
+ finishDetailDrag(true);
743
+ return;
744
+ }
745
+ if (dy <= 4) return;
746
+ } else {
747
+ if (Math.max(Math.abs(dx), Math.abs(dy)) <= 8) return;
748
+ if (dx <= Math.abs(dy)) {
749
+ finishDetailDrag(true);
750
+ return;
751
+ }
752
+ for (let element = drag.target; element && drag.aside.contains(element); element = element.parentElement) {
753
+ if (element instanceof HTMLElement && /^(auto|scroll)$/.test(getComputedStyle(element).overflowX) && element.scrollWidth > element.clientWidth && element.scrollLeft > 0) {
754
+ finishDetailDrag(true);
755
+ return;
756
+ }
757
+ if (element === drag.aside) break;
758
+ }
759
+ }
760
+ drag.moved = true;
761
+ }
762
+ event.preventDefault();
763
+ scheduleDetailDrag();
764
+ };
765
+ const onDetailTouchEnd = event => {
766
+ if (detailDrag && detailDrag.source !== "pointer") finishDetailDrag(event.type === "touchcancel");
767
+ };
768
+ const onDetailDoubleClick = event => {
769
+ const handle = resizeHandle(event);
770
+ const root = handle?.closest(ROOT_SELECTOR);
771
+ if (!handle || !root || resizeKind(handle) !== "detail" || !workspaceResizable(root) || !controlsResizableRegion(root, handle, "detail")) return;
772
+ const widths = {
773
+ ...layoutState.detailWidths
774
+ };
775
+ delete widths[panelId(handle)];
776
+ layoutState = {
777
+ ...layoutState,
778
+ detailWidths: widths
779
+ };
780
+ const variable = appWorkspacePanelVariable("detail", panelId(handle));
781
+ root.style.removeProperty(variable);
782
+ if (getComputedStyle(root).getPropertyValue(variable).trim()) root.style.setProperty(variable, `${numberData(handle, "workspaceDefaultSize", APP_WORKSPACE_DETAIL_DEFAULT)}px`);
783
+ updateHandleValue(root, handle, "detail", currentSize(root, handle, "detail"));
784
+ rememberTrailPadding(root);
785
+ options.writeState?.(layoutState);
786
+ };
170
787
  const stopScrollFades = installScrollFades(eventRoot);
171
788
  let layoutState = normalizeAppWorkspaceLayoutState(options.readState?.()) ?? {
172
789
  version: 2
@@ -246,9 +863,10 @@ export const installAppWorkspaceController = (options = {}) => {
246
863
  const size = finished.kind === "pane" ? finished.liveSize : applySize(finished.root, finished.handle, finished.kind, finished.liveSize);
247
864
  persistSize(finished.handle, finished.kind, size);
248
865
  if (finished.kind !== "drawer") reconcilePanes(finished.root, layoutState);
866
+ if (finished.kind === "detail") rememberTrailPadding(finished.root);
249
867
  }
250
868
  if (finished.handle.hasPointerCapture?.(finished.pointerId)) finished.handle.releasePointerCapture(finished.pointerId);
251
- document.body.style.userSelect = finished.previousUserSelect;
869
+ finished.releaseTextSelection();
252
870
  window.removeEventListener("pointermove", onPointerMove);
253
871
  window.removeEventListener("pointerup", stopResize);
254
872
  window.removeEventListener("pointercancel", stopResize);
@@ -274,11 +892,10 @@ export const installAppWorkspaceController = (options = {}) => {
274
892
  moved: false,
275
893
  hiding: false,
276
894
  direction: resizeDirection(handle, kind),
277
- previousUserSelect: document.body.style.userSelect
895
+ releaseTextSelection: suppressTextSelection(event.pointerId)
278
896
  };
279
897
  root.dataset.workspaceResizeActive = kind;
280
898
  handle.dataset.workspaceResizeActive = "true";
281
- document.body.style.userSelect = "none";
282
899
  handle.setPointerCapture?.(event.pointerId);
283
900
  window.addEventListener("pointermove", onPointerMove);
284
901
  window.addEventListener("pointerup", stopResize);
@@ -312,6 +929,7 @@ export const installAppWorkspaceController = (options = {}) => {
312
929
  event.preventDefault();
313
930
  persistSize(handle, kind, applySize(root, handle, kind, requested));
314
931
  if (kind === "sidebar" || kind === "detail") reconcilePanes(root, layoutState);
932
+ if (kind === "detail") rememberTrailPadding(root);
315
933
  };
316
934
  const allRoots = () => {
317
935
  const nested = Array.from(eventRoot.querySelectorAll(ROOT_SELECTOR));
@@ -324,6 +942,15 @@ export const installAppWorkspaceController = (options = {}) => {
324
942
  return allRoots().filter(root => getComputedStyle(root).display !== "none" && root.getBoundingClientRect().width > 0);
325
943
  };
326
944
  const reconcile = () => {
945
+ if (detailDrag && (detailDrag.source === "drawer" ? !touchDrawer?.matches : !phone?.matches)) finishDetailDrag(true);
946
+ allRoots().forEach(root => {
947
+ if (!phone?.matches) {
948
+ for (const aside of rootElements(root, detailSelector)) {
949
+ if (aside.dataset.workspaceDetailSheet === "full") setDetent(aside, false);
950
+ }
951
+ }
952
+ rememberTrailPadding(root);
953
+ });
327
954
  roots().forEach(root => {
328
955
  // `data-workspace-resizable="false"` already refuses pointer and keyboard
329
956
  // resizing; without this the same workspace still had persisted sizes
@@ -347,6 +974,7 @@ export const installAppWorkspaceController = (options = {}) => {
347
974
  });
348
975
  reconcilePanes(root, layoutState, active?.root === root ? active : null);
349
976
  });
977
+ heldTrails.forEach(shrinkHold);
350
978
  };
351
979
  /**
352
980
  * A handle's limits move whenever anything around it does — opening a detail
@@ -400,28 +1028,94 @@ export const installAppWorkspaceController = (options = {}) => {
400
1028
  scheduleReconcile(true);
401
1029
  });
402
1030
  const syncObservedRoots = () => {
403
- if (!resizeObserver) return;
1031
+ for (const elements of [touchedDetails, titleTabIndices, motionRoots]) {
1032
+ elements.forEach(element => {
1033
+ if (!element.isConnected) elements.delete(element);
1034
+ });
1035
+ }
404
1036
  const next = new Set(allRoots());
405
1037
  observedRoots.forEach(root => {
406
1038
  if (!next.has(root)) {
407
- resizeObserver.unobserve(root);
1039
+ resizeObserver?.unobserve(root);
1040
+ const frame = motionFrames.get(root);
1041
+ if (frame !== undefined) cancelAnimationFrame(frame);
1042
+ motionFrames.delete(root);
408
1043
  observedRoots.delete(root);
409
1044
  }
410
1045
  });
1046
+ touchMoveAsides.forEach(aside => {
1047
+ if (aside.isConnected) return;
1048
+ aside.removeEventListener("touchmove", onDetailTouchMove);
1049
+ touchMoveAsides.delete(aside);
1050
+ });
411
1051
  next.forEach(root => {
1052
+ rootElements(root, detailSelector).forEach(aside => {
1053
+ if (!detailHidden.has(aside)) detailHidden.set(aside, Boolean(aside.hidden));
1054
+ if (touchMoveAsides.has(aside)) return;
1055
+ aside.addEventListener("touchmove", onDetailTouchMove, {
1056
+ passive: false
1057
+ });
1058
+ touchMoveAsides.add(aside);
1059
+ });
412
1060
  if (observedRoots.has(root)) return;
413
1061
  observedRoots.add(root);
414
- resizeObserver.observe(root);
1062
+ resizeObserver?.observe(root);
1063
+ if (!root.hasAttribute("data-workspace-motion")) {
1064
+ motionRoots.add(root);
1065
+ motionFrames.set(root, requestAnimationFrame(() => {
1066
+ motionFrames.set(root, requestAnimationFrame(() => {
1067
+ motionFrames.delete(root);
1068
+ if (observedRoots.has(root)) root.dataset.workspaceMotion = "true";
1069
+ }));
1070
+ }));
1071
+ }
1072
+ rememberTrailPadding(root);
415
1073
  });
416
1074
  };
417
1075
  const layoutNode = node => node instanceof Element && (node.matches(LAYOUT_REGION_SELECTOR) || Boolean(node.querySelector(LAYOUT_REGION_SELECTOR)));
418
1076
  const mutationObserver = typeof MutationObserver === "undefined" ? null : new MutationObserver(records => {
1077
+ if (pendingTitle && (pendingTitle.aside.hidden || !pendingTitle.aside.isConnected)) cancelTitle();
1078
+ // Hiding or removing the sidebar, or its button, ends the overlay.
1079
+ if (overlay && (overlay.sidebar.hidden || !overlay.sidebar.isConnected || !overlay.toggle.isConnected)) closeOverlay("kept");
1080
+ const details = new Set();
1081
+ for (const record of records) {
1082
+ if (record.type === "attributes" && record.target instanceof HTMLElement && record.target.matches(detailSelector) && !details.has(record.target)) {
1083
+ details.add(record.target);
1084
+ detailTransition(record.target, detailHidden.get(record.target) ?? record.oldValue !== null);
1085
+ }
1086
+ }
419
1087
  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
1088
  if (!changed) return;
421
1089
  syncObservedRoots();
422
1090
  scheduleReconcile();
423
1091
  });
424
1092
  eventRoot.addEventListener("pointerdown", onPointerDown);
1093
+ eventRoot.addEventListener("click", onClick);
1094
+ ownerDocument.addEventListener("keydown", onOverlayKeyDown);
1095
+ ownerWindow.addEventListener("keydown", onDetailKeyDown);
1096
+ ownerDocument.addEventListener("focusin", cancelTitleOnInteraction, true);
1097
+ ownerDocument.addEventListener("pointerdown", cancelTitleOnInteraction, true);
1098
+ ownerDocument.addEventListener("keydown", cancelTitleOnInteraction, true);
1099
+ eventRoot.addEventListener("pointerdown", rememberInteraction, true);
1100
+ eventRoot.addEventListener("keydown", rememberInteraction, true);
1101
+ eventRoot.addEventListener("focusin", onDetailFocusIn);
1102
+ eventRoot.addEventListener("scroll", onTrailScroll, {
1103
+ passive: true,
1104
+ capture: true
1105
+ });
1106
+ eventRoot.addEventListener("pointerdown", onSheetPointerDown);
1107
+ eventRoot.addEventListener("click", onGrabberClick);
1108
+ eventRoot.addEventListener("dblclick", onDetailDoubleClick);
1109
+ window.addEventListener("pointermove", onSheetPointerMove);
1110
+ window.addEventListener("pointerup", onSheetPointerEnd);
1111
+ window.addEventListener("pointercancel", onSheetPointerEnd);
1112
+ eventRoot.addEventListener("lostpointercapture", onSheetPointerEnd);
1113
+ eventRoot.addEventListener("touchstart", onDetailTouchStart, {
1114
+ passive: true
1115
+ });
1116
+ eventRoot.addEventListener("touchend", onDetailTouchEnd);
1117
+ eventRoot.addEventListener("touchcancel", onDetailTouchEnd);
1118
+ compact?.addEventListener("change", onCompactChange);
425
1119
  eventRoot.addEventListener("keydown", onKeyDown);
426
1120
  eventRoot.addEventListener("focusin", onFocusIn);
427
1121
  eventRoot.addEventListener("pointerover", onPointerOver);
@@ -429,13 +1123,46 @@ export const installAppWorkspaceController = (options = {}) => {
429
1123
  syncObservedRoots();
430
1124
  mutationObserver?.observe(eventRoot, {
431
1125
  attributes: true,
1126
+ attributeOldValue: true,
432
1127
  attributeFilter: ["hidden"],
433
1128
  childList: true,
434
1129
  subtree: true
435
1130
  });
436
1131
  scheduleReconcile();
437
1132
  return () => {
1133
+ cancelTitle();
438
1134
  stopScrollFades();
1135
+ finishDetailDrag(true);
1136
+ if (suppressedClickTimer !== null) clearTimeout(suppressedClickTimer);
1137
+ motionFrames.forEach(cancelAnimationFrame);
1138
+ revealFrames.forEach(cancelAnimationFrame);
1139
+ motionRoots.forEach(root => delete root.dataset.workspaceMotion);
1140
+ heldTrails.forEach(trail => trail.style.removeProperty("--k2b-detail-trail-hold"));
1141
+ touchedDetails.forEach(aside => {
1142
+ clearDrag(aside);
1143
+ delete aside.dataset.workspaceDetailSheet;
1144
+ aside.querySelector(grabberSelector)?.setAttribute("aria-pressed", "false");
1145
+ });
1146
+ titleTabIndices.forEach(title => title.removeAttribute("tabindex"));
1147
+ ownerWindow.removeEventListener("keydown", onDetailKeyDown);
1148
+ ownerDocument.removeEventListener("focusin", cancelTitleOnInteraction, true);
1149
+ ownerDocument.removeEventListener("pointerdown", cancelTitleOnInteraction, true);
1150
+ ownerDocument.removeEventListener("keydown", cancelTitleOnInteraction, true);
1151
+ eventRoot.removeEventListener("pointerdown", rememberInteraction, true);
1152
+ eventRoot.removeEventListener("keydown", rememberInteraction, true);
1153
+ eventRoot.removeEventListener("focusin", onDetailFocusIn);
1154
+ eventRoot.removeEventListener("scroll", onTrailScroll, true);
1155
+ eventRoot.removeEventListener("pointerdown", onSheetPointerDown);
1156
+ eventRoot.removeEventListener("click", onGrabberClick);
1157
+ eventRoot.removeEventListener("dblclick", onDetailDoubleClick);
1158
+ window.removeEventListener("pointermove", onSheetPointerMove);
1159
+ window.removeEventListener("pointerup", onSheetPointerEnd);
1160
+ window.removeEventListener("pointercancel", onSheetPointerEnd);
1161
+ eventRoot.removeEventListener("lostpointercapture", onSheetPointerEnd);
1162
+ eventRoot.removeEventListener("touchstart", onDetailTouchStart);
1163
+ touchMoveAsides.forEach(aside => aside.removeEventListener("touchmove", onDetailTouchMove));
1164
+ eventRoot.removeEventListener("touchend", onDetailTouchEnd);
1165
+ eventRoot.removeEventListener("touchcancel", onDetailTouchEnd);
439
1166
  // Flush the latest coalesced pointer sample before listeners and frames are
440
1167
  // torn down, so unmounting during a drag cannot lose the final size.
441
1168
  stopResize();
@@ -443,7 +1170,11 @@ export const installAppWorkspaceController = (options = {}) => {
443
1170
  mutationObserver?.disconnect();
444
1171
  resizeObserver?.disconnect();
445
1172
  observedRoots.clear();
1173
+ closeOverlay("none");
446
1174
  eventRoot.removeEventListener("pointerdown", onPointerDown);
1175
+ eventRoot.removeEventListener("click", onClick);
1176
+ ownerDocument.removeEventListener("keydown", onOverlayKeyDown);
1177
+ compact?.removeEventListener("change", onCompactChange);
447
1178
  eventRoot.removeEventListener("keydown", onKeyDown);
448
1179
  eventRoot.removeEventListener("focusin", onFocusIn);
449
1180
  eventRoot.removeEventListener("pointerover", onPointerOver);