@k2b/ui 0.28.0 → 0.30.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 (278) hide show
  1. package/README.md +1 -1
  2. package/dist/base.css +2 -2
  3. package/dist/browser/actions/ContextMenu.js +5 -0
  4. package/dist/browser/actions/ContextMenu.js.map +1 -1
  5. package/dist/browser/actions/DragAndDrop.js +89 -0
  6. package/dist/browser/actions/DragAndDrop.js.map +1 -0
  7. package/dist/browser/actions/Dropdown.js +6 -3
  8. package/dist/browser/actions/Dropdown.js.map +1 -1
  9. package/dist/browser/actions/FilterChip.js +137 -7
  10. package/dist/browser/actions/FilterChip.js.map +1 -1
  11. package/dist/browser/actions/GestureMenu.js +26 -3
  12. package/dist/browser/actions/GestureMenu.js.map +1 -1
  13. package/dist/browser/actions/SegmentedControl.js +5 -9
  14. package/dist/browser/actions/SegmentedControl.js.map +1 -1
  15. package/dist/browser/actions/SpotlightSearch.js +6 -3
  16. package/dist/browser/actions/SpotlightSearch.js.map +1 -1
  17. package/dist/browser/actions/Tabs.js +5 -2
  18. package/dist/browser/actions/Tabs.js.map +1 -1
  19. package/dist/browser/actions/ViewTabs.js +294 -0
  20. package/dist/browser/actions/ViewTabs.js.map +1 -0
  21. package/dist/browser/actions/drag-and-drop-messages.js +75 -0
  22. package/dist/browser/actions/drag-and-drop-messages.js.map +1 -0
  23. package/dist/browser/actions/drag-and-drop.js +692 -0
  24. package/dist/browser/actions/drag-and-drop.js.map +1 -0
  25. package/dist/browser/actions/filter-messages.js +6 -2
  26. package/dist/browser/actions/filter-messages.js.map +1 -1
  27. package/dist/browser/actions/index.js +3 -1
  28. package/dist/browser/actions/index.js.map +1 -1
  29. package/dist/browser/chat/ChatComposer.js +1229 -605
  30. package/dist/browser/chat/ChatComposer.js.map +1 -1
  31. package/dist/browser/chat/ChatDecision.js +814 -0
  32. package/dist/browser/chat/ChatDecision.js.map +1 -0
  33. package/dist/browser/chat/ChatPrimitives.js +292 -153
  34. package/dist/browser/chat/ChatPrimitives.js.map +1 -1
  35. package/dist/browser/chat/ChatTimeline.js.map +1 -1
  36. package/dist/browser/chat/chat-messages.js +14 -0
  37. package/dist/browser/chat/chat-messages.js.map +1 -1
  38. package/dist/browser/chat/command-search.js +35 -17
  39. package/dist/browser/chat/command-search.js.map +1 -1
  40. package/dist/browser/chat/index.js +10 -3
  41. package/dist/browser/chat/index.js.map +1 -1
  42. package/dist/browser/chat/types.js.map +1 -1
  43. package/dist/browser/content/Calendar.js +146 -119
  44. package/dist/browser/content/Calendar.js.map +1 -1
  45. package/dist/browser/content/CalendarWeekView.js +291 -266
  46. package/dist/browser/content/CalendarWeekView.js.map +1 -1
  47. package/dist/browser/content/Chart.js +54 -71
  48. package/dist/browser/content/Chart.js.map +1 -1
  49. package/dist/browser/content/DataTable.js +224 -155
  50. package/dist/browser/content/DataTable.js.map +1 -1
  51. package/dist/browser/content/FileBrowser.js +2 -2
  52. package/dist/browser/content/FileBrowser.js.map +1 -1
  53. package/dist/browser/content/FileTree.js +42 -36
  54. package/dist/browser/content/FileTree.js.map +1 -1
  55. package/dist/browser/content/FileTypeIcon.js +72 -0
  56. package/dist/browser/content/FileTypeIcon.js.map +1 -0
  57. package/dist/browser/content/FileView.js +2 -2
  58. package/dist/browser/content/FileView.js.map +1 -1
  59. package/dist/browser/content/ReferenceChip.js +162 -0
  60. package/dist/browser/content/ReferenceChip.js.map +1 -0
  61. package/dist/browser/content/calendar-pointer.js +9 -0
  62. package/dist/browser/content/calendar-pointer.js.map +1 -1
  63. package/dist/browser/content/calendar-time-view.js +6 -3
  64. package/dist/browser/content/calendar-time-view.js.map +1 -1
  65. package/dist/browser/content/data-table-messages.js +4 -2
  66. package/dist/browser/content/data-table-messages.js.map +1 -1
  67. package/dist/browser/content/index.js +2 -0
  68. package/dist/browser/content/index.js.map +1 -1
  69. package/dist/browser/feedback/MovedHint.js +197 -0
  70. package/dist/browser/feedback/MovedHint.js.map +1 -0
  71. package/dist/browser/feedback/dialog-core.js +66 -9
  72. package/dist/browser/feedback/dialog-core.js.map +1 -1
  73. package/dist/browser/feedback/index.js +1 -0
  74. package/dist/browser/feedback/index.js.map +1 -1
  75. package/dist/browser/feedback/prompts.js +6 -1
  76. package/dist/browser/feedback/prompts.js.map +1 -1
  77. package/dist/browser/inputs/DatePicker.js +337 -212
  78. package/dist/browser/inputs/DatePicker.js.map +1 -1
  79. package/dist/browser/inputs/date-picker.js +59 -5
  80. package/dist/browser/inputs/date-picker.js.map +1 -1
  81. package/dist/browser/intl/messages.js +12 -0
  82. package/dist/browser/intl/messages.js.map +1 -1
  83. package/dist/browser/intl/weekend.js +39 -0
  84. package/dist/browser/intl/weekend.js.map +1 -0
  85. package/dist/browser/layout/AppOverview.js +1 -2
  86. package/dist/browser/layout/AppOverview.js.map +1 -1
  87. package/dist/browser/layout/AppWorkspace.js +947 -531
  88. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  89. package/dist/browser/layout/PageTitle.js +3 -2
  90. package/dist/browser/layout/PageTitle.js.map +1 -1
  91. package/dist/browser/layout/PanelDialog.js +88 -86
  92. package/dist/browser/layout/PanelDialog.js.map +1 -1
  93. package/dist/browser/layout/ResizeSeparator.js +81 -0
  94. package/dist/browser/layout/ResizeSeparator.js.map +1 -0
  95. package/dist/browser/layout/SettingsModal.js +2 -2
  96. package/dist/browser/layout/SettingsModal.js.map +1 -1
  97. package/dist/browser/layout/SidebarSwitcher.js +19 -11
  98. package/dist/browser/layout/SidebarSwitcher.js.map +1 -1
  99. package/dist/browser/layout/TabBar.js +16 -13
  100. package/dist/browser/layout/TabBar.js.map +1 -1
  101. package/dist/browser/layout/app-host-width.js +44 -0
  102. package/dist/browser/layout/app-host-width.js.map +1 -0
  103. package/dist/browser/layout/app-workspace-controller.js +337 -44
  104. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  105. package/dist/browser/layout/index.js +4 -1
  106. package/dist/browser/layout/index.js.map +1 -1
  107. package/dist/browser/layout/resize-separator.js +90 -0
  108. package/dist/browser/layout/resize-separator.js.map +1 -0
  109. package/dist/browser/layout/workspace-messages.js +12 -2
  110. package/dist/browser/layout/workspace-messages.js.map +1 -1
  111. package/dist/browser/surfaces/LinkCard.js +1 -1
  112. package/dist/browser/surfaces/LinkCard.js.map +1 -1
  113. package/dist/browser/surfaces/Placeholder.js +45 -11
  114. package/dist/browser/surfaces/Placeholder.js.map +1 -1
  115. package/dist/browser/surfaces/StatCell.js +23 -0
  116. package/dist/browser/surfaces/StatCell.js.map +1 -1
  117. package/dist/browser/widgets/Widget.js +1 -1
  118. package/dist/browser/widgets/Widget.js.map +1 -1
  119. package/dist/ssr/actions/ContextMenu.js +5 -0
  120. package/dist/ssr/actions/ContextMenu.js.map +1 -1
  121. package/dist/ssr/actions/DragAndDrop.js +63 -0
  122. package/dist/ssr/actions/DragAndDrop.js.map +1 -0
  123. package/dist/ssr/actions/Dropdown.js +5 -2
  124. package/dist/ssr/actions/Dropdown.js.map +1 -1
  125. package/dist/ssr/actions/FilterChip.js +59 -7
  126. package/dist/ssr/actions/FilterChip.js.map +1 -1
  127. package/dist/ssr/actions/GestureMenu.js +26 -3
  128. package/dist/ssr/actions/GestureMenu.js.map +1 -1
  129. package/dist/ssr/actions/SegmentedControl.js +1 -2
  130. package/dist/ssr/actions/SegmentedControl.js.map +1 -1
  131. package/dist/ssr/actions/SpotlightSearch.js +2 -2
  132. package/dist/ssr/actions/SpotlightSearch.js.map +1 -1
  133. package/dist/ssr/actions/Tabs.js +2 -2
  134. package/dist/ssr/actions/Tabs.js.map +1 -1
  135. package/dist/ssr/actions/ViewTabs.js +211 -0
  136. package/dist/ssr/actions/ViewTabs.js.map +1 -0
  137. package/dist/ssr/actions/drag-and-drop-messages.js +75 -0
  138. package/dist/ssr/actions/drag-and-drop-messages.js.map +1 -0
  139. package/dist/ssr/actions/drag-and-drop.js +692 -0
  140. package/dist/ssr/actions/drag-and-drop.js.map +1 -0
  141. package/dist/ssr/actions/filter-messages.js +6 -2
  142. package/dist/ssr/actions/filter-messages.js.map +1 -1
  143. package/dist/ssr/actions/index.js +3 -1
  144. package/dist/ssr/actions/index.js.map +1 -1
  145. package/dist/ssr/chat/ChatComposer.js +668 -136
  146. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  147. package/dist/ssr/chat/ChatDecision.js +479 -0
  148. package/dist/ssr/chat/ChatDecision.js.map +1 -0
  149. package/dist/ssr/chat/ChatPrimitives.js +95 -24
  150. package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
  151. package/dist/ssr/chat/ChatTimeline.js.map +1 -1
  152. package/dist/ssr/chat/chat-messages.js +14 -0
  153. package/dist/ssr/chat/chat-messages.js.map +1 -1
  154. package/dist/ssr/chat/command-search.js +35 -17
  155. package/dist/ssr/chat/command-search.js.map +1 -1
  156. package/dist/ssr/chat/index.js +10 -3
  157. package/dist/ssr/chat/index.js.map +1 -1
  158. package/dist/ssr/chat/types.js.map +1 -1
  159. package/dist/ssr/content/Calendar.js +112 -103
  160. package/dist/ssr/content/Calendar.js.map +1 -1
  161. package/dist/ssr/content/CalendarWeekView.js +42 -28
  162. package/dist/ssr/content/CalendarWeekView.js.map +1 -1
  163. package/dist/ssr/content/Chart.js +19 -23
  164. package/dist/ssr/content/Chart.js.map +1 -1
  165. package/dist/ssr/content/DataTable.js +78 -31
  166. package/dist/ssr/content/DataTable.js.map +1 -1
  167. package/dist/ssr/content/FileBrowser.js +2 -2
  168. package/dist/ssr/content/FileBrowser.js.map +1 -1
  169. package/dist/ssr/content/FileTree.js +21 -14
  170. package/dist/ssr/content/FileTree.js.map +1 -1
  171. package/dist/ssr/content/FileTypeIcon.js +50 -0
  172. package/dist/ssr/content/FileTypeIcon.js.map +1 -0
  173. package/dist/ssr/content/FileView.js +2 -2
  174. package/dist/ssr/content/FileView.js.map +1 -1
  175. package/dist/ssr/content/ReferenceChip.js +121 -0
  176. package/dist/ssr/content/ReferenceChip.js.map +1 -0
  177. package/dist/ssr/content/calendar-pointer.js +9 -0
  178. package/dist/ssr/content/calendar-pointer.js.map +1 -1
  179. package/dist/ssr/content/calendar-time-view.js +6 -3
  180. package/dist/ssr/content/calendar-time-view.js.map +1 -1
  181. package/dist/ssr/content/data-table-messages.js +4 -2
  182. package/dist/ssr/content/data-table-messages.js.map +1 -1
  183. package/dist/ssr/content/index.js +2 -0
  184. package/dist/ssr/content/index.js.map +1 -1
  185. package/dist/ssr/feedback/MovedHint.js +166 -0
  186. package/dist/ssr/feedback/MovedHint.js.map +1 -0
  187. package/dist/ssr/feedback/dialog-core.js +66 -9
  188. package/dist/ssr/feedback/dialog-core.js.map +1 -1
  189. package/dist/ssr/feedback/index.js +1 -0
  190. package/dist/ssr/feedback/index.js.map +1 -1
  191. package/dist/ssr/feedback/prompts.js +6 -1
  192. package/dist/ssr/feedback/prompts.js.map +1 -1
  193. package/dist/ssr/inputs/DatePicker.js +138 -69
  194. package/dist/ssr/inputs/DatePicker.js.map +1 -1
  195. package/dist/ssr/inputs/date-picker.js +59 -5
  196. package/dist/ssr/inputs/date-picker.js.map +1 -1
  197. package/dist/ssr/intl/messages.js +12 -0
  198. package/dist/ssr/intl/messages.js.map +1 -1
  199. package/dist/ssr/intl/weekend.js +39 -0
  200. package/dist/ssr/intl/weekend.js.map +1 -0
  201. package/dist/ssr/layout/AppOverview.js +1 -2
  202. package/dist/ssr/layout/AppOverview.js.map +1 -1
  203. package/dist/ssr/layout/AppWorkspace.js +457 -116
  204. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  205. package/dist/ssr/layout/PageTitle.js +3 -2
  206. package/dist/ssr/layout/PageTitle.js.map +1 -1
  207. package/dist/ssr/layout/PanelDialog.js +7 -6
  208. package/dist/ssr/layout/PanelDialog.js.map +1 -1
  209. package/dist/ssr/layout/ResizeSeparator.js +45 -0
  210. package/dist/ssr/layout/ResizeSeparator.js.map +1 -0
  211. package/dist/ssr/layout/SettingsModal.js +2 -2
  212. package/dist/ssr/layout/SettingsModal.js.map +1 -1
  213. package/dist/ssr/layout/SidebarSwitcher.js +19 -11
  214. package/dist/ssr/layout/SidebarSwitcher.js.map +1 -1
  215. package/dist/ssr/layout/TabBar.js +2 -2
  216. package/dist/ssr/layout/TabBar.js.map +1 -1
  217. package/dist/ssr/layout/app-host-width.js +44 -0
  218. package/dist/ssr/layout/app-host-width.js.map +1 -0
  219. package/dist/ssr/layout/app-workspace-controller.js +337 -44
  220. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  221. package/dist/ssr/layout/index.js +4 -1
  222. package/dist/ssr/layout/index.js.map +1 -1
  223. package/dist/ssr/layout/resize-separator.js +90 -0
  224. package/dist/ssr/layout/resize-separator.js.map +1 -0
  225. package/dist/ssr/layout/workspace-messages.js +12 -2
  226. package/dist/ssr/layout/workspace-messages.js.map +1 -1
  227. package/dist/ssr/surfaces/LinkCard.js +1 -1
  228. package/dist/ssr/surfaces/LinkCard.js.map +1 -1
  229. package/dist/ssr/surfaces/Placeholder.js +25 -6
  230. package/dist/ssr/surfaces/Placeholder.js.map +1 -1
  231. package/dist/ssr/surfaces/StatCell.js +23 -0
  232. package/dist/ssr/surfaces/StatCell.js.map +1 -1
  233. package/dist/ssr/widgets/Widget.js +1 -1
  234. package/dist/ssr/widgets/Widget.js.map +1 -1
  235. package/dist/styles.css +1 -1
  236. package/dist/types/actions/ContextMenu.d.ts +1 -0
  237. package/dist/types/actions/DragAndDrop.d.ts +29 -0
  238. package/dist/types/actions/Dropdown.d.ts +4 -0
  239. package/dist/types/actions/FilterChip.d.ts +22 -0
  240. package/dist/types/actions/ViewTabs.d.ts +30 -0
  241. package/dist/types/actions/drag-and-drop-messages.d.ts +35 -0
  242. package/dist/types/actions/drag-and-drop.d.ts +36 -0
  243. package/dist/types/actions/filter-messages.d.ts +2 -0
  244. package/dist/types/actions/index.d.ts +6 -2
  245. package/dist/types/chat/ChatComposer.d.ts +71 -1
  246. package/dist/types/chat/ChatDecision.d.ts +149 -0
  247. package/dist/types/chat/ChatPrimitives.d.ts +14 -1
  248. package/dist/types/chat/ChatTimeline.d.ts +2 -1
  249. package/dist/types/chat/chat-messages.d.ts +7 -0
  250. package/dist/types/chat/command-search.d.ts +5 -0
  251. package/dist/types/chat/index.d.ts +28 -5
  252. package/dist/types/chat/types.d.ts +54 -1
  253. package/dist/types/content/Chart.d.ts +9 -3
  254. package/dist/types/content/DataTable.d.ts +3 -0
  255. package/dist/types/content/FileTypeIcon.d.ts +27 -0
  256. package/dist/types/content/ReferenceChip.d.ts +49 -0
  257. package/dist/types/content/calendar-pointer.d.ts +6 -0
  258. package/dist/types/content/data-table-messages.d.ts +1 -0
  259. package/dist/types/content/index.d.ts +3 -0
  260. package/dist/types/feedback/MovedHint.d.ts +25 -0
  261. package/dist/types/feedback/dialog-core.d.ts +5 -2
  262. package/dist/types/feedback/index.d.ts +2 -0
  263. package/dist/types/feedback/prompts.d.ts +2 -0
  264. package/dist/types/inputs/DatePicker.d.ts +7 -0
  265. package/dist/types/inputs/date-picker.d.ts +25 -1
  266. package/dist/types/intl/messages.d.ts +6 -0
  267. package/dist/types/intl/weekend.d.ts +12 -0
  268. package/dist/types/layout/AppWorkspace.d.ts +48 -10
  269. package/dist/types/layout/ResizeSeparator.d.ts +9 -0
  270. package/dist/types/layout/TabBar.d.ts +7 -0
  271. package/dist/types/layout/app-host-width.d.ts +6 -0
  272. package/dist/types/layout/app-workspace-controller.d.ts +2 -0
  273. package/dist/types/layout/index.d.ts +5 -2
  274. package/dist/types/layout/resize-separator.d.ts +18 -0
  275. package/dist/types/layout/workspace-messages.d.ts +5 -0
  276. package/dist/types/surfaces/Placeholder.d.ts +2 -1
  277. package/dist/types/surfaces/StatCell.d.ts +6 -0
  278. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["layout/SettingsModal.tsx"],"sourcesContent":["import { children, createEffect, createMemo, createSignal, createUniqueId, For, type JSX, Show } from \"solid-js\";\nimport { IconButton } from \"../actions/Button\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { createScrollFade } from \"./scroll-fade\";\nimport { useSettingsMessages } from \"./settings-messages\";\nimport { assertUniqueStableUiIds } from \"./stable-id\";\n\nconst SETTINGS_MODAL_TAB = Symbol(\"SettingsModal.Tab\");\nconst SETTINGS_MODAL_GROUP = Symbol(\"SettingsModal.Group\");\nconst SETTINGS_MODAL_FOOTER = Symbol(\"SettingsModal.Footer\");\n\nexport type SettingsModalTabTone = \"default\" | \"danger\";\n\nexport type SettingsModalTabProps = {\n id: string;\n title: string;\n description?: string;\n icon?: string;\n tone?: SettingsModalTabTone;\n children: JSX.Element;\n};\n\nexport type SettingsModalGroupProps = {\n title: string;\n children: JSX.Element;\n};\n\nexport type SettingsModalFooterProps = {\n children: JSX.Element;\n};\n\ntype SettingsModalTabDefinition = {\n readonly kind: typeof SETTINGS_MODAL_TAB;\n readonly props: SettingsModalTabProps;\n};\n\ntype SettingsModalGroupDefinition = {\n readonly kind: typeof SETTINGS_MODAL_GROUP;\n readonly props: SettingsModalGroupProps;\n};\n\ntype SettingsModalFooterDefinition = {\n readonly kind: typeof SETTINGS_MODAL_FOOTER;\n readonly props: SettingsModalFooterProps;\n};\n\nexport type SettingsModalProps = {\n /** Accessible name for the settings surface. */\n title: string;\n /** @deprecated Retained for source compatibility; tab descriptions carry the visible context. */\n subtitle?: string;\n /** @deprecated Retained for source compatibility; tab icons identify the rail entries. */\n icon?: string;\n defaultTab?: string;\n activeTab?: string;\n onTabChange?: (id: string) => void;\n onClose?: () => void;\n closeLabel?: string;\n class?: string;\n children: JSX.Element;\n};\n\ntype SettingsModalComponent = ((props: SettingsModalProps) => JSX.Element) & {\n Tab: (props: SettingsModalTabProps) => JSX.Element;\n Group: (props: SettingsModalGroupProps) => JSX.Element;\n Footer: (props: SettingsModalFooterProps) => JSX.Element;\n};\n\nconst isTabDefinition = (value: unknown): value is SettingsModalTabDefinition =>\n !!value && typeof value === \"object\" && (value as { kind?: unknown }).kind === SETTINGS_MODAL_TAB;\n\nconst isGroupDefinition = (value: unknown): value is SettingsModalGroupDefinition =>\n !!value && typeof value === \"object\" && (value as { kind?: unknown }).kind === SETTINGS_MODAL_GROUP;\n\nconst isFooterDefinition = (value: unknown): value is SettingsModalFooterDefinition =>\n !!value && typeof value === \"object\" && (value as { kind?: unknown }).kind === SETTINGS_MODAL_FOOTER;\n\nconst collectTabs = (value: unknown): SettingsModalTabDefinition[] => {\n if (Array.isArray(value)) return value.flatMap(collectTabs);\n if (isGroupDefinition(value)) return collectTabs(value.props.children);\n return isTabDefinition(value) ? [value] : [];\n};\n\nconst collectRailEntries = (value: unknown): (SettingsModalGroupDefinition | SettingsModalTabDefinition)[] => {\n if (Array.isArray(value)) return value.flatMap(collectRailEntries);\n if (isGroupDefinition(value) || isTabDefinition(value)) return [value];\n return [];\n};\n\nconst splitPanelChildren = (value: unknown): { content: JSX.Element[]; footer?: SettingsModalFooterDefinition } => {\n if (Array.isArray(value)) {\n return value.reduce<{ content: JSX.Element[]; footer?: SettingsModalFooterDefinition }>(\n (result, entry) => {\n const next = splitPanelChildren(entry);\n result.content.push(...next.content);\n if (next.footer) result.footer = next.footer;\n return result;\n },\n { content: [] },\n );\n }\n return isFooterDefinition(value) ? { content: [], footer: value } : { content: [value as JSX.Element] };\n};\n\nfunction SettingsModalTab(props: SettingsModalTabProps): JSX.Element {\n return { kind: SETTINGS_MODAL_TAB, props } satisfies SettingsModalTabDefinition as unknown as JSX.Element;\n}\n\nfunction SettingsModalGroup(props: SettingsModalGroupProps): JSX.Element {\n return { kind: SETTINGS_MODAL_GROUP, props } satisfies SettingsModalGroupDefinition as unknown as JSX.Element;\n}\n\nfunction SettingsModalFooter(props: SettingsModalFooterProps): JSX.Element {\n return { kind: SETTINGS_MODAL_FOOTER, props } satisfies SettingsModalFooterDefinition as unknown as JSX.Element;\n}\n\nconst SettingsModal = ((props: SettingsModalProps): JSX.Element => {\n const messages = useUiMessages();\n const settingsMessages = useSettingsMessages();\n const resolved = children(() => props.children);\n const railEntries = createMemo(() => collectRailEntries(resolved()));\n const tabs = createMemo(() => {\n const collected = collectTabs(resolved());\n assertUniqueStableUiIds(\n collected.map((tab) => tab.props.id),\n \"SettingsModal.Tab id\",\n );\n return collected;\n });\n const instanceId = `k2b-settings-${createUniqueId()}`;\n const tabRefs = new Map<string, HTMLButtonElement>();\n let tabList: HTMLElement | undefined;\n // Narrow surfaces show the categories as one scrolling row; the fade tells that more follow.\n createScrollFade(\n () => tabList,\n () => true,\n );\n const firstTabId = () => tabs()[0]?.props.id ?? \"\";\n const [localActiveTab, setLocalActiveTab] = createSignal(props.defaultTab ?? firstTabId());\n const requestedActiveTabId = () => props.activeTab ?? (localActiveTab() || firstTabId());\n const resolvedActiveTabId = createMemo(() =>\n tabs().some((tab) => tab.props.id === requestedActiveTabId()) ? requestedActiveTabId() : firstTabId(),\n );\n // `defaultTab`, `activeTab` and clicks can select a category past the edge of the scrolling row or rail.\n createEffect(() => {\n const id = resolvedActiveTabId();\n queueMicrotask(() => tabRefs.get(id)?.scrollIntoView?.({ block: \"nearest\", inline: \"nearest\" }));\n });\n const activeTab = () => tabs().find((tab) => tab.props.id === resolvedActiveTabId()) ?? null;\n const resolvedPanelChildren = children(() => activeTab()?.props.children);\n const panelChildren = createMemo(() => splitPanelChildren(resolvedPanelChildren()));\n\n const selectTab = (id: string) => {\n if (props.activeTab === undefined) setLocalActiveTab(id);\n props.onTabChange?.(id);\n };\n\n const moveTabFocus = (event: KeyboardEvent, currentId: string) => {\n const currentIndex = tabs().findIndex((tab) => tab.props.id === currentId);\n if (currentIndex < 0 || tabs().length === 0) return;\n let nextIndex: number | null = null;\n if (event.key === \"ArrowRight\" || event.key === \"ArrowDown\") nextIndex = (currentIndex + 1) % tabs().length;\n if (event.key === \"ArrowLeft\" || event.key === \"ArrowUp\") nextIndex = (currentIndex - 1 + tabs().length) % tabs().length;\n if (event.key === \"Home\") nextIndex = 0;\n if (event.key === \"End\") nextIndex = tabs().length - 1;\n if (nextIndex === null) return;\n event.preventDefault();\n const nextTab = tabs()[nextIndex];\n if (!nextTab) return;\n selectTab(nextTab.props.id);\n tabRefs.get(nextTab.props.id)?.focus();\n };\n\n const tabId = (id: string) => `${instanceId}-tab-${id}`;\n const panelId = (id: string) => `${instanceId}-panel-${id}`;\n\n const TabButton = (tab: SettingsModalTabDefinition): JSX.Element => {\n const active = () => resolvedActiveTabId() === tab.props.id;\n return (\n <button\n ref={(element) => tabRefs.set(tab.props.id, element)}\n id={tabId(tab.props.id)}\n type=\"button\"\n role=\"tab\"\n aria-selected={active()}\n aria-controls={active() ? panelId(tab.props.id) : undefined}\n tabIndex={active() ? 0 : -1}\n data-state={active() ? \"active\" : \"idle\"}\n data-active={active() ? \"true\" : undefined}\n data-tone={tab.props.tone ?? \"default\"}\n onClick={() => selectTab(tab.props.id)}\n onKeyDown={(event) => moveTabFocus(event, tab.props.id)}\n >\n <Show when={tab.props.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n <span>{tab.props.title}</span>\n </button>\n );\n };\n\n return (\n <div class={`k2b-settings ${props.class ?? \"\"}`} role=\"region\" aria-label={props.title}>\n <Show when={props.onClose}>\n <IconButton class=\"k2b-settings__close\" label={props.closeLabel ?? messages().close} onClick={props.onClose}>\n <i class=\"ti ti-x\" aria-hidden=\"true\" />\n </IconButton>\n </Show>\n <aside class=\"k2b-settings__rail\">\n <nav\n ref={tabList}\n class=\"k2b-settings__tabs\"\n aria-label={settingsMessages().sectionsLabel({ title: props.title })}\n role=\"tablist\"\n data-scroll-fade-mode=\"both\"\n data-scroll-fade-axis=\"horizontal\"\n >\n <For each={railEntries()}>\n {(entry) =>\n isGroupDefinition(entry) ? (\n <div class=\"k2b-settings__tab-group\" role=\"presentation\">\n <span class=\"k2b-settings__tab-group-label\" aria-hidden=\"true\">\n {entry.props.title}\n </span>\n <For each={collectTabs(entry.props.children)}>{(tab) => TabButton(tab)}</For>\n </div>\n ) : (\n TabButton(entry)\n )\n }\n </For>\n </nav>\n </aside>\n <div class=\"k2b-settings__content\">\n <Show when={activeTab()}>\n {(tab) => (\n <section\n id={panelId(tab().props.id)}\n class=\"k2b-settings__body\"\n role=\"tabpanel\"\n aria-labelledby={tabId(tab().props.id)}\n tabIndex={0}\n data-tone={tab().props.tone ?? \"default\"}\n >\n <div class=\"k2b-settings__section\">\n <div class=\"k2b-settings__section-heading\">\n <h2>{tab().props.title}</h2>\n <Show when={tab().props.description}>{(description) => <p>{description()}</p>}</Show>\n </div>\n {panelChildren().content}\n </div>\n </section>\n )}\n </Show>\n <Show when={panelChildren().footer}>{(footer) => <footer class=\"k2b-settings__footer\">{footer().props.children}</footer>}</Show>\n </div>\n </div>\n );\n}) as SettingsModalComponent;\n\nSettingsModal.Tab = SettingsModalTab;\nSettingsModal.Group = SettingsModalGroup;\nSettingsModal.Footer = SettingsModalFooter;\n\nexport default SettingsModal;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["layout/SettingsModal.tsx"],"sourcesContent":["import { children, createEffect, createMemo, createSignal, createUniqueId, For, type JSX, Show } from \"solid-js\";\nimport { IconButton } from \"../actions/Button\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { createScrollFade } from \"./scroll-fade\";\nimport { useSettingsMessages } from \"./settings-messages\";\nimport { assertUniqueStableUiIds } from \"./stable-id\";\n\nconst SETTINGS_MODAL_TAB = Symbol(\"SettingsModal.Tab\");\nconst SETTINGS_MODAL_GROUP = Symbol(\"SettingsModal.Group\");\nconst SETTINGS_MODAL_FOOTER = Symbol(\"SettingsModal.Footer\");\n\nexport type SettingsModalTabTone = \"default\" | \"danger\";\n\nexport type SettingsModalTabProps = {\n id: string;\n title: string;\n description?: string;\n icon?: string;\n tone?: SettingsModalTabTone;\n children: JSX.Element;\n};\n\nexport type SettingsModalGroupProps = {\n title: string;\n children: JSX.Element;\n};\n\nexport type SettingsModalFooterProps = {\n children: JSX.Element;\n};\n\ntype SettingsModalTabDefinition = {\n readonly kind: typeof SETTINGS_MODAL_TAB;\n readonly props: SettingsModalTabProps;\n};\n\ntype SettingsModalGroupDefinition = {\n readonly kind: typeof SETTINGS_MODAL_GROUP;\n readonly props: SettingsModalGroupProps;\n};\n\ntype SettingsModalFooterDefinition = {\n readonly kind: typeof SETTINGS_MODAL_FOOTER;\n readonly props: SettingsModalFooterProps;\n};\n\nexport type SettingsModalProps = {\n /** Accessible name for the settings surface. */\n title: string;\n /** @deprecated Retained for source compatibility; tab descriptions carry the visible context. */\n subtitle?: string;\n /** @deprecated Retained for source compatibility; tab icons identify the rail entries. */\n icon?: string;\n defaultTab?: string;\n activeTab?: string;\n onTabChange?: (id: string) => void;\n onClose?: () => void;\n closeLabel?: string;\n class?: string;\n children: JSX.Element;\n};\n\ntype SettingsModalComponent = ((props: SettingsModalProps) => JSX.Element) & {\n Tab: (props: SettingsModalTabProps) => JSX.Element;\n Group: (props: SettingsModalGroupProps) => JSX.Element;\n Footer: (props: SettingsModalFooterProps) => JSX.Element;\n};\n\nconst isTabDefinition = (value: unknown): value is SettingsModalTabDefinition =>\n !!value && typeof value === \"object\" && (value as { kind?: unknown }).kind === SETTINGS_MODAL_TAB;\n\nconst isGroupDefinition = (value: unknown): value is SettingsModalGroupDefinition =>\n !!value && typeof value === \"object\" && (value as { kind?: unknown }).kind === SETTINGS_MODAL_GROUP;\n\nconst isFooterDefinition = (value: unknown): value is SettingsModalFooterDefinition =>\n !!value && typeof value === \"object\" && (value as { kind?: unknown }).kind === SETTINGS_MODAL_FOOTER;\n\nconst collectTabs = (value: unknown): SettingsModalTabDefinition[] => {\n if (Array.isArray(value)) return value.flatMap(collectTabs);\n if (isGroupDefinition(value)) return collectTabs(value.props.children);\n return isTabDefinition(value) ? [value] : [];\n};\n\nconst collectRailEntries = (value: unknown): (SettingsModalGroupDefinition | SettingsModalTabDefinition)[] => {\n if (Array.isArray(value)) return value.flatMap(collectRailEntries);\n if (isGroupDefinition(value) || isTabDefinition(value)) return [value];\n return [];\n};\n\nconst splitPanelChildren = (value: unknown): { content: JSX.Element[]; footer?: SettingsModalFooterDefinition } => {\n if (Array.isArray(value)) {\n return value.reduce<{ content: JSX.Element[]; footer?: SettingsModalFooterDefinition }>(\n (result, entry) => {\n const next = splitPanelChildren(entry);\n result.content.push(...next.content);\n if (next.footer) result.footer = next.footer;\n return result;\n },\n { content: [] },\n );\n }\n return isFooterDefinition(value) ? { content: [], footer: value } : { content: [value as JSX.Element] };\n};\n\nfunction SettingsModalTab(props: SettingsModalTabProps): JSX.Element {\n return { kind: SETTINGS_MODAL_TAB, props } satisfies SettingsModalTabDefinition as unknown as JSX.Element;\n}\n\nfunction SettingsModalGroup(props: SettingsModalGroupProps): JSX.Element {\n return { kind: SETTINGS_MODAL_GROUP, props } satisfies SettingsModalGroupDefinition as unknown as JSX.Element;\n}\n\nfunction SettingsModalFooter(props: SettingsModalFooterProps): JSX.Element {\n return { kind: SETTINGS_MODAL_FOOTER, props } satisfies SettingsModalFooterDefinition as unknown as JSX.Element;\n}\n\nconst SettingsModal = ((props: SettingsModalProps): JSX.Element => {\n const messages = useUiMessages();\n const settingsMessages = useSettingsMessages();\n const resolved = children(() => props.children);\n const railEntries = createMemo(() => collectRailEntries(resolved()));\n const tabs = createMemo(() => {\n const collected = collectTabs(resolved());\n assertUniqueStableUiIds(\n collected.map((tab) => tab.props.id),\n \"SettingsModal.Tab id\",\n );\n return collected;\n });\n const instanceId = `k2b-settings-${createUniqueId()}`;\n const tabRefs = new Map<string, HTMLButtonElement>();\n let tabList: HTMLElement | undefined;\n // Narrow surfaces show the categories as one scrolling row; the fade tells that more follow.\n createScrollFade(\n () => tabList,\n () => true,\n );\n const firstTabId = () => tabs()[0]?.props.id ?? \"\";\n const [localActiveTab, setLocalActiveTab] = createSignal(props.defaultTab ?? firstTabId());\n const requestedActiveTabId = () => props.activeTab ?? (localActiveTab() || firstTabId());\n const resolvedActiveTabId = createMemo(() =>\n tabs().some((tab) => tab.props.id === requestedActiveTabId()) ? requestedActiveTabId() : firstTabId(),\n );\n // `defaultTab`, `activeTab` and clicks can select a category past the edge of the scrolling row or rail.\n createEffect(() => {\n const id = resolvedActiveTabId();\n queueMicrotask(() => tabRefs.get(id)?.scrollIntoView?.({ block: \"nearest\", inline: \"nearest\" }));\n });\n const activeTab = () => tabs().find((tab) => tab.props.id === resolvedActiveTabId()) ?? null;\n const resolvedPanelChildren = children(() => activeTab()?.props.children);\n const panelChildren = createMemo(() => splitPanelChildren(resolvedPanelChildren()));\n\n const selectTab = (id: string) => {\n if (props.activeTab === undefined) setLocalActiveTab(id);\n props.onTabChange?.(id);\n };\n\n const moveTabFocus = (event: KeyboardEvent, currentId: string) => {\n const currentIndex = tabs().findIndex((tab) => tab.props.id === currentId);\n if (currentIndex < 0 || tabs().length === 0) return;\n let nextIndex: number | null = null;\n if (event.key === \"ArrowRight\" || event.key === \"ArrowDown\") nextIndex = (currentIndex + 1) % tabs().length;\n if (event.key === \"ArrowLeft\" || event.key === \"ArrowUp\") nextIndex = (currentIndex - 1 + tabs().length) % tabs().length;\n if (event.key === \"Home\") nextIndex = 0;\n if (event.key === \"End\") nextIndex = tabs().length - 1;\n if (nextIndex === null) return;\n event.preventDefault();\n const nextTab = tabs()[nextIndex];\n if (!nextTab) return;\n selectTab(nextTab.props.id);\n tabRefs.get(nextTab.props.id)?.focus();\n };\n\n const tabId = (id: string) => `${instanceId}-tab-${id}`;\n const panelId = (id: string) => `${instanceId}-panel-${id}`;\n\n const TabButton = (tab: SettingsModalTabDefinition): JSX.Element => {\n const active = () => resolvedActiveTabId() === tab.props.id;\n return (\n <button\n ref={(element) => tabRefs.set(tab.props.id, element)}\n id={tabId(tab.props.id)}\n type=\"button\"\n role=\"tab\"\n aria-selected={active()}\n aria-controls={active() ? panelId(tab.props.id) : undefined}\n tabIndex={active() ? 0 : -1}\n data-state={active() ? \"active\" : \"idle\"}\n data-active={active() ? \"true\" : undefined}\n data-tone={tab.props.tone ?? \"default\"}\n onClick={() => selectTab(tab.props.id)}\n onKeyDown={(event) => moveTabFocus(event, tab.props.id)}\n >\n <Show when={tab.props.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n <span class=\"k2b-truncate-fade\">{tab.props.title}</span>\n </button>\n );\n };\n\n return (\n <div class={`k2b-settings ${props.class ?? \"\"}`} role=\"region\" aria-label={props.title}>\n <Show when={props.onClose}>\n <IconButton class=\"k2b-settings__close\" label={props.closeLabel ?? messages().close} onClick={props.onClose}>\n <i class=\"ti ti-x\" aria-hidden=\"true\" />\n </IconButton>\n </Show>\n <aside class=\"k2b-settings__rail\">\n <nav\n ref={tabList}\n class=\"k2b-settings__tabs\"\n aria-label={settingsMessages().sectionsLabel({ title: props.title })}\n role=\"tablist\"\n data-scroll-fade-mode=\"both\"\n data-scroll-fade-axis=\"horizontal\"\n >\n <For each={railEntries()}>\n {(entry) =>\n isGroupDefinition(entry) ? (\n <div class=\"k2b-settings__tab-group\" role=\"presentation\">\n <span class=\"k2b-settings__tab-group-label k2b-truncate-fade\" aria-hidden=\"true\">\n {entry.props.title}\n </span>\n <For each={collectTabs(entry.props.children)}>{(tab) => TabButton(tab)}</For>\n </div>\n ) : (\n TabButton(entry)\n )\n }\n </For>\n </nav>\n </aside>\n <div class=\"k2b-settings__content\">\n <Show when={activeTab()}>\n {(tab) => (\n <section\n id={panelId(tab().props.id)}\n class=\"k2b-settings__body\"\n role=\"tabpanel\"\n aria-labelledby={tabId(tab().props.id)}\n tabIndex={0}\n data-tone={tab().props.tone ?? \"default\"}\n >\n <div class=\"k2b-settings__section\">\n <div class=\"k2b-settings__section-heading\">\n <h2>{tab().props.title}</h2>\n <Show when={tab().props.description}>{(description) => <p>{description()}</p>}</Show>\n </div>\n {panelChildren().content}\n </div>\n </section>\n )}\n </Show>\n <Show when={panelChildren().footer}>{(footer) => <footer class=\"k2b-settings__footer\">{footer().props.children}</footer>}</Show>\n </div>\n </div>\n );\n}) as SettingsModalComponent;\n\nSettingsModal.Tab = SettingsModalTab;\nSettingsModal.Group = SettingsModalGroup;\nSettingsModal.Footer = SettingsModalFooter;\n\nexport default SettingsModal;\n"],"mappings":"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","ignoreList":[]}
@@ -13,16 +13,17 @@ import { setAttribute as _$setAttribute } from "solid-js/web";
13
13
  import { use as _$use } from "solid-js/web";
14
14
  var _tmpl$ = /*#__PURE__*/_$template(`<div class="k2b-choice-search k2b-sidebar-switcher__search"><i class="ti ti-search"aria-hidden=true></i><input type=search data-switcher-row>`),
15
15
  _tmpl$2 = /*#__PURE__*/_$template(`<ul class=k2b-sidebar-switcher__actions>`),
16
- _tmpl$3 = /*#__PURE__*/_$template(`<div><button type=button class=k2b-sidebar-switcher__trigger aria-haspopup=dialog><span class=k2b-sidebar-switcher__icon aria-hidden=true><i></i></span><span class=k2b-sidebar-switcher__copy aria-hidden=true><span></span><!$><!/></span><i class="ti ti-selector k2b-sidebar-switcher__chevron"aria-hidden=true></i><span class=k2b-sr-only></span></button><div popover=auto tabindex=-1 role=dialog class=k2b-sidebar-switcher__panel><!$><!/><ul class=k2b-sidebar-switcher__options></ul><!$><!/>`),
17
- _tmpl$4 = /*#__PURE__*/_$template(`<small>`),
16
+ _tmpl$3 = /*#__PURE__*/_$template(`<div><button type=button class=k2b-sidebar-switcher__trigger aria-haspopup=dialog><span class=k2b-sidebar-switcher__icon aria-hidden=true><i></i></span><span class=k2b-sidebar-switcher__copy aria-hidden=true><span class=k2b-truncate-fade-lines></span><!$><!/></span><i class="ti ti-selector k2b-sidebar-switcher__chevron"aria-hidden=true></i><span class=k2b-sr-only></span></button><div popover=auto tabindex=-1 role=dialog class=k2b-sidebar-switcher__panel><!$><!/><ul class=k2b-sidebar-switcher__options></ul><!$><!/>`),
17
+ _tmpl$4 = /*#__PURE__*/_$template(`<small class=k2b-truncate-fade>`),
18
18
  _tmpl$5 = /*#__PURE__*/_$template(`<li class=k2b-choice-status role=status>`),
19
19
  _tmpl$6 = /*#__PURE__*/_$template(`<i class="ti ti-loader-2 k2b-spin"aria-hidden=true>`),
20
20
  _tmpl$7 = /*#__PURE__*/_$template(`<span>`),
21
21
  _tmpl$8 = /*#__PURE__*/_$template(`<button type=button data-switcher-row>`),
22
22
  _tmpl$9 = /*#__PURE__*/_$template(`<li><a class="k2b-dropdown__item k2b-sidebar-switcher__option"data-switcher-row data-switcher-option><span class=k2b-sidebar-switcher__option-icon aria-hidden=true><i></i></span><span class=k2b-dropdown__copy><span></span><!$><!/></span><i class="ti ti-check k2b-dropdown__check"aria-hidden=true>`),
23
- _tmpl$0 = /*#__PURE__*/_$template(`<li>`),
24
- _tmpl$1 = /*#__PURE__*/_$template(`<button type=button class=k2b-dropdown__item data-switcher-row><i aria-hidden=true></i><span class=k2b-dropdown__copy><span>`),
25
- _tmpl$10 = /*#__PURE__*/_$template(`<a class=k2b-dropdown__item data-switcher-row><i aria-hidden=true></i><span class=k2b-dropdown__copy><span>`);
23
+ _tmpl$0 = /*#__PURE__*/_$template(`<small>`),
24
+ _tmpl$1 = /*#__PURE__*/_$template(`<li>`),
25
+ _tmpl$10 = /*#__PURE__*/_$template(`<button type=button class=k2b-dropdown__item data-switcher-row><i aria-hidden=true></i><span class=k2b-dropdown__copy><span>`),
26
+ _tmpl$11 = /*#__PURE__*/_$template(`<a class=k2b-dropdown__item data-switcher-row><i aria-hidden=true></i><span class=k2b-dropdown__copy><span>`);
26
27
  import { documentNavigate } from "@k2b/ssr/nav";
27
28
  import { createMemo, createSignal, createUniqueId, For, onCleanup, Show } from "solid-js";
28
29
  import { isServer } from "solid-js/web";
@@ -73,8 +74,13 @@ export function AppWorkspaceSidebarSwitcher(props) {
73
74
  if (props.options === undefined) props.onLoad?.();
74
75
  };
75
76
 
76
- // The collapsed rail is a narrow column from 64 rem, so the panel opens beside it instead of below.
77
- const inRail = () => Boolean(trigger?.closest('[data-sidebar-collapsed="true"] .k2b-app-workspace__sidebar[data-workspace-collapsible="true"]') && window.matchMedia("(min-width: 64rem)").matches);
77
+ // The collapsed rail is a narrow column from a 64 rem host, so the panel opens beside it instead of below.
78
+ // The workspace's stylesheet states which form its sidebar has.
79
+ const inRail = () => {
80
+ const root = trigger?.closest("[data-k2b-app-workspace]");
81
+ const sidebar = root ? Array.from(root.querySelectorAll(".k2b-app-workspace__sidebar")).find(element => element.closest("[data-k2b-app-workspace]") === root) : undefined;
82
+ return Boolean(root?.dataset.sidebarCollapsed === "true" && sidebar?.dataset.workspaceCollapsible === "true" && getComputedStyle(sidebar ?? root).getPropertyValue("--k2b-workspace-sidebar-form").trim() === "column");
83
+ };
78
84
  /** Whether the panel opens above its trigger; chosen on opening and on a viewport resize only. */
79
85
  let above = false;
80
86
  /**
@@ -130,6 +136,7 @@ export function AppWorkspaceSidebarSwitcher(props) {
130
136
  const reposition = () => open() && place();
131
137
  const resize = () => open() && place(true);
132
138
  // Arriving options, an error, or the search field grow the panel after it opened, so its size places it too.
139
+ // The trigger changes size when a host turns the rail into the expanded overlay, without a window resize.
133
140
  let resizing;
134
141
  const listen = on => {
135
142
  const method = on ? "addEventListener" : "removeEventListener";
@@ -138,6 +145,7 @@ export function AppWorkspaceSidebarSwitcher(props) {
138
145
  if (on && panel) {
139
146
  resizing ??= new ResizeObserver(reposition);
140
147
  resizing.observe(panel);
148
+ if (trigger) resizing.observe(trigger);
141
149
  } else resizing?.disconnect();
142
150
  };
143
151
  // Server rendering cleans up too, where no window exists.
@@ -367,7 +375,7 @@ export function AppWorkspaceSidebarSwitcher(props) {
367
375
  return option.description;
368
376
  },
369
377
  children: description => (() => {
370
- var _el$35 = _$getNextElement(_tmpl$4);
378
+ var _el$35 = _$getNextElement(_tmpl$0);
371
379
  _$insert(_el$35, description);
372
380
  return _el$35;
373
381
  })()
@@ -409,14 +417,14 @@ export function AppWorkspaceSidebarSwitcher(props) {
409
417
  return props.actions;
410
418
  },
411
419
  children: item => (() => {
412
- var _el$36 = _$getNextElement(_tmpl$0);
420
+ var _el$36 = _$getNextElement(_tmpl$1);
413
421
  _$insert(_el$36, _$createComponent(Show, {
414
422
  get when() {
415
423
  return item.href;
416
424
  },
417
425
  get fallback() {
418
426
  return (() => {
419
- var _el$37 = _$getNextElement(_tmpl$1),
427
+ var _el$37 = _$getNextElement(_tmpl$10),
420
428
  _el$38 = _el$37.firstChild,
421
429
  _el$39 = _el$38.nextSibling,
422
430
  _el$40 = _el$39.firstChild;
@@ -440,7 +448,7 @@ export function AppWorkspaceSidebarSwitcher(props) {
440
448
  })();
441
449
  },
442
450
  children: href => (() => {
443
- var _el$41 = _$getNextElement(_tmpl$10),
451
+ var _el$41 = _$getNextElement(_tmpl$11),
444
452
  _el$42 = _el$41.firstChild,
445
453
  _el$43 = _el$42.nextSibling,
446
454
  _el$44 = _el$43.firstChild;
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["layout/SidebarSwitcher.tsx"],"sourcesContent":["import { documentNavigate } from \"@k2b/ssr/nav\";\nimport { createMemo, createSignal, createUniqueId, For, type JSX, onCleanup, Show } from \"solid-js\";\nimport { isServer } from \"solid-js/web\";\nimport { dropdownPosition } from \"../actions/Dropdown\";\nimport { returnFocus, ringOnReturn } from \"../internal/focus-return\";\nimport { useUiMessages } from \"../intl/messages\";\n\n/** One container a person can switch to, such as a notebook, a space, or a mailbox. */\nexport type AppWorkspaceSwitcherOption = {\n id: string;\n label: string;\n /** One secondary fact, such as a mailbox's address. */\n description?: string;\n /** Tabler icon class; without it the row takes the switcher's icon. */\n icon?: string;\n /** Tints the icon; without it the app accent does. */\n color?: string;\n href: string;\n};\n\n/** A row below the containers, such as \"New notebook\" or \"All notebooks\". */\nexport type AppWorkspaceSwitcherAction = {\n id: string;\n label: string;\n icon: string;\n disabled?: boolean;\n} & ({ href: string; action?: never } | { action: () => void; href?: never });\n\nexport type AppWorkspaceSidebarSwitcherProps = {\n /** The current container's ID among `options`. */\n currentId: string;\n /** The current container's name. */\n label: string;\n /** One secondary fact under the name, such as a mailbox's address. */\n description?: string;\n icon: string;\n /** Tints the icon; without it the app accent does. */\n color?: string;\n /** Names the button's purpose and its panel, such as \"Switch notebook\". */\n switchLabel: string;\n /** Every container the person can switch to, the current one included; `undefined` until they are loaded. */\n options?: readonly AppWorkspaceSwitcherOption[];\n /** Shown in place of the options when loading them failed; the panel offers to try again through `onLoad`. */\n error?: string;\n /**\n * Asks for `options` while they are `undefined`: when a pointer or the focus first reaches the button, so the list\n * is usually there when the panel opens, on every opening, and from the panel's retry. Ignore repeated calls while a\n * request runs.\n */\n onLoad?: () => void;\n actions?: readonly AppWorkspaceSwitcherAction[];\n /**\n * A host menu around the switcher, such as the phone menu, finishes dismissing itself before a chosen container\n * opens or an action runs; `false` cancels the choice. Navigation passes its own.\n */\n beforeSelect?: () => boolean | void | Promise<boolean | void>;\n /** Sizes the switcher in its place, such as `flex-1` beside a button in one row. */\n class?: string;\n};\n\n/** From this many containers the panel scrolls, so it offers a search field. */\nexport const APP_WORKSPACE_SWITCHER_SEARCH_FROM = 8;\n\n/** The space between trigger and panel, and the panel's distance from the viewport edges, as for every dropdown. */\nconst SWITCHER_GAP = 4;\nconst SWITCHER_INSET = 8;\n\nconst iconClass = (icon: string) => (icon.split(/\\s+/).includes(\"ti\") ? icon : `ti ${icon}`);\nconst tint = (color: string | undefined) => (color ? { \"--k2b-sidebar-switcher-color\": color } : undefined);\nconst plainClick = (event: MouseEvent) => event.button === 0 && !(event.metaKey || event.ctrlKey || event.shiftKey || event.altKey);\n\n/**\n * The current container at the top of a sidebar: its icon, name, and an optional fact, with a chevron that opens the\n * other containers, a search field when there are many, and actions such as \"New …\" and \"All …\". The rows are links,\n * so a container also opens in a new tab. In a collapsed rail it shows only the icon and opens beside the rail.\n */\nexport function AppWorkspaceSidebarSwitcher(props: AppWorkspaceSidebarSwitcherProps): JSX.Element {\n const messages = useUiMessages();\n const id = `k2b-sidebar-switcher-${createUniqueId().replace(/[^a-zA-Z0-9_-]/g, \"-\")}`;\n const [open, setOpen] = createSignal(false);\n const [query, setQuery] = createSignal(\"\");\n let trigger: HTMLButtonElement | undefined;\n let panel: HTMLDivElement | undefined;\n let search: HTMLInputElement | undefined;\n let keyboardOpened = true;\n /** Whether the panel was open when a press on the button began; the press itself light-dismisses it first. */\n let openAtPress: boolean | undefined;\n\n const searchable = () => (props.options?.length ?? 0) >= APP_WORKSPACE_SWITCHER_SEARCH_FROM;\n const visible = createMemo(() => {\n const needle = query().trim().toLocaleLowerCase();\n const options = props.options ?? [];\n if (!needle) return options;\n return options.filter((option) => [option.label, option.description].some((part) => part?.toLocaleLowerCase().includes(needle)));\n });\n const load = () => {\n if (props.options === undefined) props.onLoad?.();\n };\n\n // The collapsed rail is a narrow column from 64 rem, so the panel opens beside it instead of below.\n const inRail = () =>\n Boolean(\n trigger?.closest('[data-sidebar-collapsed=\"true\"] .k2b-app-workspace__sidebar[data-workspace-collapsible=\"true\"]') &&\n window.matchMedia(\"(min-width: 64rem)\").matches,\n );\n /** Whether the panel opens above its trigger; chosen on opening and on a viewport resize only. */\n let above = false;\n /**\n * Places the panel beside its trigger. `choose` picks its side again; otherwise it keeps the side, so arriving\n * options, an error, or a narrowed search never flip it to the other side while it is open.\n */\n const place = (choose = false) => {\n if (!trigger || !panel) return;\n const rect = trigger.getBoundingClientRect();\n const viewport = { width: window.innerWidth, height: window.innerHeight };\n const rail = inRail();\n // As wide as the sidebar row and never narrower than a menu, so long names keep their words; fixed while open,\n // so filtering never changes the panel's width.\n panel.style.setProperty(\"--k2b-sidebar-switcher-width\", `${rail ? 0 : Math.round(rect.width)}px`);\n if (rail) {\n panel.style.removeProperty(\"--k2b-sidebar-switcher-room\");\n panel.style.removeProperty(\"min-height\");\n panel.style.bottom = \"auto\";\n const position = dropdownPosition(rect, panel.getBoundingClientRect(), \"right-start\", viewport);\n panel.style.left = `${position.left}px`;\n panel.style.top = `${position.top}px`;\n return;\n }\n // Below the trigger, or above it when the panel at its tallest does not fit below and there is more room above,\n // as in the lower half of the phone menu. Its tallest is its CSS max-height, min(28rem, 80dvh), so the side does\n // not depend on what the panel shows at the moment. It never covers its trigger: it takes at most the room on its\n // side, and its list scrolls.\n const roomBelow = viewport.height - rect.bottom - SWITCHER_GAP - SWITCHER_INSET;\n const roomAbove = rect.top - SWITCHER_GAP - SWITCHER_INSET;\n if (choose) {\n const rem = Number.parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;\n above = Math.min(28 * rem, 0.8 * viewport.height) > roomBelow && roomAbove > roomBelow;\n panel.style.removeProperty(\"min-height\");\n }\n const room = Math.max(0, above ? roomAbove : roomBelow);\n panel.style.setProperty(\"--k2b-sidebar-switcher-room\", `${room}px`);\n panel.style.left = `${dropdownPosition(rect, panel.getBoundingClientRect(), \"bottom-right\", viewport).left}px`;\n if (above) {\n // Its bottom edge stays beside the trigger, and it does not shrink while open, so a narrowed search keeps the\n // search field where the person is typing.\n const height = Math.min(room, Math.max(panel.getBoundingClientRect().height, Number.parseFloat(panel.style.minHeight) || 0));\n panel.style.minHeight = `${height}px`;\n panel.style.top = \"auto\";\n panel.style.bottom = `${document.documentElement.clientHeight - rect.top + SWITCHER_GAP}px`;\n } else {\n panel.style.top = `${rect.bottom + SWITCHER_GAP}px`;\n panel.style.bottom = \"auto\";\n }\n };\n const reposition = () => open() && place();\n const resize = () => open() && place(true);\n // Arriving options, an error, or the search field grow the panel after it opened, so its size places it too.\n let resizing: ResizeObserver | undefined;\n const listen = (on: boolean) => {\n const method = on ? \"addEventListener\" : \"removeEventListener\";\n window[method](\"resize\", resize);\n window[method](\"scroll\", reposition, true);\n if (on && panel) {\n resizing ??= new ResizeObserver(reposition);\n resizing.observe(panel);\n } else resizing?.disconnect();\n };\n // Server rendering cleans up too, where no window exists.\n onCleanup(() => isServer || listen(false));\n /** Lets the host dismiss its menu first, then opens the link or runs the action unless the host cancels. */\n const choose = (run: () => void) => {\n hide(false);\n if (!props.beforeSelect) return run();\n void Promise.resolve(props.beforeSelect()).then((allowed) => {\n if (allowed !== false) run();\n });\n };\n const follow = (event: MouseEvent & { currentTarget: HTMLAnchorElement }) => {\n if (!plainClick(event)) return;\n if (!props.beforeSelect) return hide(false);\n event.preventDefault();\n const href = event.currentTarget.href;\n choose(() => documentNavigate(href));\n };\n\n const rows = () => (panel ? Array.from(panel.querySelectorAll<HTMLElement>(\"[data-switcher-row]:not([aria-disabled='true'])\")) : []);\n const focusRow = (index: number) => {\n const all = rows();\n if (all.length) all[(index + all.length) % all.length]?.focus();\n };\n const show = (focus: \"start\" | \"end\" = \"start\") => {\n if (!panel || panel.matches(\":popover-open\")) return;\n load();\n keyboardOpened = ringOnReturn(trigger);\n setQuery(\"\");\n panel.showPopover();\n setOpen(true);\n listen(true);\n place(true);\n queueMicrotask(() => {\n // On touch the search field waits for a tap, so the keyboard does not cover the list on opening.\n if (searchable() && focus === \"start\" && !window.matchMedia(\"(pointer: coarse)\").matches) search?.focus();\n else if (focus === \"end\") focusRow(-1);\n // While the list loads, the panel holds focus, so arriving rows do not move it.\n else (panel?.querySelector<HTMLElement>('[aria-current=\"true\"]') ?? (props.options ? rows()[0] : panel))?.focus();\n });\n };\n const hide = (restoreFocus: boolean) => {\n if (restoreFocus) returnFocus(trigger, keyboardOpened);\n if (panel?.matches(\":popover-open\")) panel.hidePopover();\n };\n\n const onPanelKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement;\n const all = rows();\n const index = all.indexOf(target);\n if (event.key === \"Escape\") {\n // The panel closes alone; an overlay sidebar around it stays open.\n event.preventDefault();\n event.stopPropagation();\n hide(true);\n } else if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n focusRow(index + (event.key === \"ArrowDown\" ? 1 : -1));\n } else if ((event.key === \"Home\" || event.key === \"End\") && target !== search) {\n event.preventDefault();\n focusRow(event.key === \"Home\" ? 0 : -1);\n } else if (event.key === \"Enter\" && target === search) {\n event.preventDefault();\n panel?.querySelector<HTMLElement>(\"[data-switcher-option]\")?.click();\n } else if (\n search &&\n target !== search &&\n event.key.length === 1 &&\n event.key !== \" \" &&\n !(event.metaKey || event.ctrlKey || event.altKey)\n ) {\n // Typing anywhere in a long list searches it.\n event.preventDefault();\n setQuery(query() + event.key);\n search.focus();\n }\n };\n\n return (\n <div class={`k2b-sidebar-switcher ${props.class ?? \"\"}`} data-description={props.description ? \"\" : undefined}>\n <button\n ref={trigger}\n type=\"button\"\n class=\"k2b-sidebar-switcher__trigger\"\n aria-label={props.label}\n aria-describedby={`${id}-purpose`}\n aria-haspopup=\"dialog\"\n aria-expanded={open()}\n aria-controls={id}\n // The full name for a truncated title and for the icon in a collapsed rail.\n title={props.label}\n onPointerEnter={load}\n onFocus={load}\n onPointerDown={() => (openAtPress = panel?.matches(\":popover-open\"))}\n onClick={() => {\n const wasOpen = openAtPress ?? panel?.matches(\":popover-open\");\n openAtPress = undefined;\n if (wasOpen) hide(false);\n else show();\n }}\n onKeyDown={(event) => {\n if (event.key !== \"ArrowDown\" && event.key !== \"ArrowUp\") return;\n event.preventDefault();\n if (open()) focusRow(event.key === \"ArrowDown\" ? 0 : -1);\n else show(event.key === \"ArrowDown\" ? \"start\" : \"end\");\n }}\n >\n <span class=\"k2b-sidebar-switcher__icon\" style={tint(props.color)} aria-hidden=\"true\">\n <i class={iconClass(props.icon)} />\n </span>\n <span class=\"k2b-sidebar-switcher__copy\" aria-hidden=\"true\">\n <span>{props.label}</span>\n <Show when={props.description}>{(description) => <small>{description()}</small>}</Show>\n </span>\n <i class=\"ti ti-selector k2b-sidebar-switcher__chevron\" aria-hidden=\"true\" />\n <span id={`${id}-purpose`} class=\"k2b-sr-only\">\n {[props.description, props.switchLabel].filter(Boolean).join(\", \")}\n </span>\n </button>\n <div\n ref={panel}\n id={id}\n popover=\"auto\"\n tabIndex={-1}\n role=\"dialog\"\n aria-label={props.switchLabel}\n class=\"k2b-sidebar-switcher__panel\"\n onKeyDown={onPanelKeyDown}\n onFocusOut={(event) => {\n const next = event.relatedTarget as Node | null;\n // Tabbing out closes the panel; focus that leaves the window keeps it.\n if (next && !panel?.contains(next) && next !== trigger) hide(false);\n }}\n onToggle={(event) => {\n if ((event as ToggleEvent).newState === \"open\") return;\n setOpen(false);\n listen(false);\n }}\n >\n <Show when={searchable()}>\n <div class=\"k2b-choice-search k2b-sidebar-switcher__search\">\n <i class=\"ti ti-search\" aria-hidden=\"true\" />\n <input\n ref={search}\n type=\"search\"\n data-switcher-row\n value={query()}\n placeholder={messages().search}\n aria-label={messages().searchLabel}\n aria-controls={`${id}-options`}\n onInput={(event) => setQuery(event.currentTarget.value)}\n />\n </div>\n </Show>\n <ul id={`${id}-options`} class=\"k2b-sidebar-switcher__options\">\n <Show\n when={props.options}\n fallback={\n <li class=\"k2b-choice-status\" role=\"status\" data-tone={props.error ? \"danger\" : undefined}>\n <Show\n when={props.error}\n fallback={\n <>\n <i class=\"ti ti-loader-2 k2b-spin\" aria-hidden=\"true\" />\n <span>{messages().loading}</span>\n </>\n }\n >\n {(error) => (\n <>\n <span>{error()}</span>\n <button type=\"button\" data-switcher-row onClick={() => props.onLoad?.()}>\n {messages().retry}\n </button>\n </>\n )}\n </Show>\n </li>\n }\n >\n <For\n each={visible()}\n fallback={\n <li class=\"k2b-choice-status\" role=\"status\">\n {messages().noResults}\n </li>\n }\n >\n {(option) => {\n const current = () => option.id === props.currentId;\n return (\n <li>\n <a\n href={option.href}\n class=\"k2b-dropdown__item k2b-sidebar-switcher__option\"\n data-switcher-row\n data-switcher-option\n aria-current={current() ? \"true\" : undefined}\n onClick={(event) => {\n // The open container is already here: choosing it only closes the panel.\n if (current() && plainClick(event)) {\n event.preventDefault();\n hide(true);\n } else follow(event);\n }}\n >\n <span class=\"k2b-sidebar-switcher__option-icon\" style={tint(option.color ?? props.color)} aria-hidden=\"true\">\n <i class={iconClass(option.icon ?? props.icon)} />\n </span>\n <span class=\"k2b-dropdown__copy\">\n <span>{option.label}</span>\n <Show when={option.description}>{(description) => <small>{description()}</small>}</Show>\n </span>\n <i class=\"ti ti-check k2b-dropdown__check\" data-hidden={current() ? undefined : \"true\"} aria-hidden=\"true\" />\n </a>\n </li>\n );\n }}\n </For>\n </Show>\n </ul>\n <Show when={props.actions?.length}>\n <ul class=\"k2b-sidebar-switcher__actions\">\n <For each={props.actions}>\n {(item) => (\n <li>\n <Show\n when={item.href}\n fallback={\n <button\n type=\"button\"\n class=\"k2b-dropdown__item\"\n data-switcher-row\n disabled={item.disabled}\n aria-disabled={item.disabled ? \"true\" : undefined}\n onClick={() => choose(() => item.action?.())}\n >\n <i class={iconClass(item.icon)} aria-hidden=\"true\" />\n <span class=\"k2b-dropdown__copy\">\n <span>{item.label}</span>\n </span>\n </button>\n }\n >\n {(href) => (\n <a\n href={item.disabled ? undefined : href()}\n class=\"k2b-dropdown__item\"\n data-switcher-row\n aria-disabled={item.disabled ? \"true\" : undefined}\n onClick={(event) => item.disabled || follow(event)}\n >\n <i class={iconClass(item.icon)} aria-hidden=\"true\" />\n <span class=\"k2b-dropdown__copy\">\n <span>{item.label}</span>\n </span>\n </a>\n )}\n </Show>\n </li>\n )}\n </For>\n </ul>\n </Show>\n </div>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["layout/SidebarSwitcher.tsx"],"sourcesContent":["import { documentNavigate } from \"@k2b/ssr/nav\";\nimport { createMemo, createSignal, createUniqueId, For, type JSX, onCleanup, Show } from \"solid-js\";\nimport { isServer } from \"solid-js/web\";\nimport { dropdownPosition } from \"../actions/Dropdown\";\nimport { returnFocus, ringOnReturn } from \"../internal/focus-return\";\nimport { useUiMessages } from \"../intl/messages\";\n\n/** One container a person can switch to, such as a notebook, a space, or a mailbox. */\nexport type AppWorkspaceSwitcherOption = {\n id: string;\n label: string;\n /** One secondary fact, such as a mailbox's address. */\n description?: string;\n /** Tabler icon class; without it the row takes the switcher's icon. */\n icon?: string;\n /** Tints the icon; without it the app accent does. */\n color?: string;\n href: string;\n};\n\n/** A row below the containers, such as \"New notebook\" or \"All notebooks\". */\nexport type AppWorkspaceSwitcherAction = {\n id: string;\n label: string;\n icon: string;\n disabled?: boolean;\n} & ({ href: string; action?: never } | { action: () => void; href?: never });\n\nexport type AppWorkspaceSidebarSwitcherProps = {\n /** The current container's ID among `options`. */\n currentId: string;\n /** The current container's name. */\n label: string;\n /** One secondary fact under the name, such as a mailbox's address. */\n description?: string;\n icon: string;\n /** Tints the icon; without it the app accent does. */\n color?: string;\n /** Names the button's purpose and its panel, such as \"Switch notebook\". */\n switchLabel: string;\n /** Every container the person can switch to, the current one included; `undefined` until they are loaded. */\n options?: readonly AppWorkspaceSwitcherOption[];\n /** Shown in place of the options when loading them failed; the panel offers to try again through `onLoad`. */\n error?: string;\n /**\n * Asks for `options` while they are `undefined`: when a pointer or the focus first reaches the button, so the list\n * is usually there when the panel opens, on every opening, and from the panel's retry. Ignore repeated calls while a\n * request runs.\n */\n onLoad?: () => void;\n actions?: readonly AppWorkspaceSwitcherAction[];\n /**\n * A host menu around the switcher, such as the phone menu, finishes dismissing itself before a chosen container\n * opens or an action runs; `false` cancels the choice. Navigation passes its own.\n */\n beforeSelect?: () => boolean | void | Promise<boolean | void>;\n /** Sizes the switcher in its place, such as `flex-1` beside a button in one row. */\n class?: string;\n};\n\n/** From this many containers the panel scrolls, so it offers a search field. */\nexport const APP_WORKSPACE_SWITCHER_SEARCH_FROM = 8;\n\n/** The space between trigger and panel, and the panel's distance from the viewport edges, as for every dropdown. */\nconst SWITCHER_GAP = 4;\nconst SWITCHER_INSET = 8;\n\nconst iconClass = (icon: string) => (icon.split(/\\s+/).includes(\"ti\") ? icon : `ti ${icon}`);\nconst tint = (color: string | undefined) => (color ? { \"--k2b-sidebar-switcher-color\": color } : undefined);\nconst plainClick = (event: MouseEvent) => event.button === 0 && !(event.metaKey || event.ctrlKey || event.shiftKey || event.altKey);\n\n/**\n * The current container at the top of a sidebar: its icon, name, and an optional fact, with a chevron that opens the\n * other containers, a search field when there are many, and actions such as \"New …\" and \"All …\". The rows are links,\n * so a container also opens in a new tab. In a collapsed rail it shows only the icon and opens beside the rail.\n */\nexport function AppWorkspaceSidebarSwitcher(props: AppWorkspaceSidebarSwitcherProps): JSX.Element {\n const messages = useUiMessages();\n const id = `k2b-sidebar-switcher-${createUniqueId().replace(/[^a-zA-Z0-9_-]/g, \"-\")}`;\n const [open, setOpen] = createSignal(false);\n const [query, setQuery] = createSignal(\"\");\n let trigger: HTMLButtonElement | undefined;\n let panel: HTMLDivElement | undefined;\n let search: HTMLInputElement | undefined;\n let keyboardOpened = true;\n /** Whether the panel was open when a press on the button began; the press itself light-dismisses it first. */\n let openAtPress: boolean | undefined;\n\n const searchable = () => (props.options?.length ?? 0) >= APP_WORKSPACE_SWITCHER_SEARCH_FROM;\n const visible = createMemo(() => {\n const needle = query().trim().toLocaleLowerCase();\n const options = props.options ?? [];\n if (!needle) return options;\n return options.filter((option) => [option.label, option.description].some((part) => part?.toLocaleLowerCase().includes(needle)));\n });\n const load = () => {\n if (props.options === undefined) props.onLoad?.();\n };\n\n // The collapsed rail is a narrow column from a 64 rem host, so the panel opens beside it instead of below.\n // The workspace's stylesheet states which form its sidebar has.\n const inRail = () => {\n const root = trigger?.closest<HTMLElement>(\"[data-k2b-app-workspace]\");\n const sidebar = root\n ? Array.from(root.querySelectorAll<HTMLElement>(\".k2b-app-workspace__sidebar\")).find(\n (element) => element.closest(\"[data-k2b-app-workspace]\") === root,\n )\n : undefined;\n return Boolean(\n root?.dataset.sidebarCollapsed === \"true\" &&\n sidebar?.dataset.workspaceCollapsible === \"true\" &&\n getComputedStyle(sidebar ?? root)\n .getPropertyValue(\"--k2b-workspace-sidebar-form\")\n .trim() === \"column\",\n );\n };\n /** Whether the panel opens above its trigger; chosen on opening and on a viewport resize only. */\n let above = false;\n /**\n * Places the panel beside its trigger. `choose` picks its side again; otherwise it keeps the side, so arriving\n * options, an error, or a narrowed search never flip it to the other side while it is open.\n */\n const place = (choose = false) => {\n if (!trigger || !panel) return;\n const rect = trigger.getBoundingClientRect();\n const viewport = { width: window.innerWidth, height: window.innerHeight };\n const rail = inRail();\n // As wide as the sidebar row and never narrower than a menu, so long names keep their words; fixed while open,\n // so filtering never changes the panel's width.\n panel.style.setProperty(\"--k2b-sidebar-switcher-width\", `${rail ? 0 : Math.round(rect.width)}px`);\n if (rail) {\n panel.style.removeProperty(\"--k2b-sidebar-switcher-room\");\n panel.style.removeProperty(\"min-height\");\n panel.style.bottom = \"auto\";\n const position = dropdownPosition(rect, panel.getBoundingClientRect(), \"right-start\", viewport);\n panel.style.left = `${position.left}px`;\n panel.style.top = `${position.top}px`;\n return;\n }\n // Below the trigger, or above it when the panel at its tallest does not fit below and there is more room above,\n // as in the lower half of the phone menu. Its tallest is its CSS max-height, min(28rem, 80dvh), so the side does\n // not depend on what the panel shows at the moment. It never covers its trigger: it takes at most the room on its\n // side, and its list scrolls.\n const roomBelow = viewport.height - rect.bottom - SWITCHER_GAP - SWITCHER_INSET;\n const roomAbove = rect.top - SWITCHER_GAP - SWITCHER_INSET;\n if (choose) {\n const rem = Number.parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;\n above = Math.min(28 * rem, 0.8 * viewport.height) > roomBelow && roomAbove > roomBelow;\n panel.style.removeProperty(\"min-height\");\n }\n const room = Math.max(0, above ? roomAbove : roomBelow);\n panel.style.setProperty(\"--k2b-sidebar-switcher-room\", `${room}px`);\n panel.style.left = `${dropdownPosition(rect, panel.getBoundingClientRect(), \"bottom-right\", viewport).left}px`;\n if (above) {\n // Its bottom edge stays beside the trigger, and it does not shrink while open, so a narrowed search keeps the\n // search field where the person is typing.\n const height = Math.min(room, Math.max(panel.getBoundingClientRect().height, Number.parseFloat(panel.style.minHeight) || 0));\n panel.style.minHeight = `${height}px`;\n panel.style.top = \"auto\";\n panel.style.bottom = `${document.documentElement.clientHeight - rect.top + SWITCHER_GAP}px`;\n } else {\n panel.style.top = `${rect.bottom + SWITCHER_GAP}px`;\n panel.style.bottom = \"auto\";\n }\n };\n const reposition = () => open() && place();\n const resize = () => open() && place(true);\n // Arriving options, an error, or the search field grow the panel after it opened, so its size places it too.\n // The trigger changes size when a host turns the rail into the expanded overlay, without a window resize.\n let resizing: ResizeObserver | undefined;\n const listen = (on: boolean) => {\n const method = on ? \"addEventListener\" : \"removeEventListener\";\n window[method](\"resize\", resize);\n window[method](\"scroll\", reposition, true);\n if (on && panel) {\n resizing ??= new ResizeObserver(reposition);\n resizing.observe(panel);\n if (trigger) resizing.observe(trigger);\n } else resizing?.disconnect();\n };\n // Server rendering cleans up too, where no window exists.\n onCleanup(() => isServer || listen(false));\n /** Lets the host dismiss its menu first, then opens the link or runs the action unless the host cancels. */\n const choose = (run: () => void) => {\n hide(false);\n if (!props.beforeSelect) return run();\n void Promise.resolve(props.beforeSelect()).then((allowed) => {\n if (allowed !== false) run();\n });\n };\n const follow = (event: MouseEvent & { currentTarget: HTMLAnchorElement }) => {\n if (!plainClick(event)) return;\n if (!props.beforeSelect) return hide(false);\n event.preventDefault();\n const href = event.currentTarget.href;\n choose(() => documentNavigate(href));\n };\n\n const rows = () => (panel ? Array.from(panel.querySelectorAll<HTMLElement>(\"[data-switcher-row]:not([aria-disabled='true'])\")) : []);\n const focusRow = (index: number) => {\n const all = rows();\n if (all.length) all[(index + all.length) % all.length]?.focus();\n };\n const show = (focus: \"start\" | \"end\" = \"start\") => {\n if (!panel || panel.matches(\":popover-open\")) return;\n load();\n keyboardOpened = ringOnReturn(trigger);\n setQuery(\"\");\n panel.showPopover();\n setOpen(true);\n listen(true);\n place(true);\n queueMicrotask(() => {\n // On touch the search field waits for a tap, so the keyboard does not cover the list on opening.\n if (searchable() && focus === \"start\" && !window.matchMedia(\"(pointer: coarse)\").matches) search?.focus();\n else if (focus === \"end\") focusRow(-1);\n // While the list loads, the panel holds focus, so arriving rows do not move it.\n else (panel?.querySelector<HTMLElement>('[aria-current=\"true\"]') ?? (props.options ? rows()[0] : panel))?.focus();\n });\n };\n const hide = (restoreFocus: boolean) => {\n if (restoreFocus) returnFocus(trigger, keyboardOpened);\n if (panel?.matches(\":popover-open\")) panel.hidePopover();\n };\n\n const onPanelKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement;\n const all = rows();\n const index = all.indexOf(target);\n if (event.key === \"Escape\") {\n // The panel closes alone; an overlay sidebar around it stays open.\n event.preventDefault();\n event.stopPropagation();\n hide(true);\n } else if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n focusRow(index + (event.key === \"ArrowDown\" ? 1 : -1));\n } else if ((event.key === \"Home\" || event.key === \"End\") && target !== search) {\n event.preventDefault();\n focusRow(event.key === \"Home\" ? 0 : -1);\n } else if (event.key === \"Enter\" && target === search) {\n event.preventDefault();\n panel?.querySelector<HTMLElement>(\"[data-switcher-option]\")?.click();\n } else if (\n search &&\n target !== search &&\n event.key.length === 1 &&\n event.key !== \" \" &&\n !(event.metaKey || event.ctrlKey || event.altKey)\n ) {\n // Typing anywhere in a long list searches it.\n event.preventDefault();\n setQuery(query() + event.key);\n search.focus();\n }\n };\n\n return (\n <div class={`k2b-sidebar-switcher ${props.class ?? \"\"}`} data-description={props.description ? \"\" : undefined}>\n <button\n ref={trigger}\n type=\"button\"\n class=\"k2b-sidebar-switcher__trigger\"\n aria-label={props.label}\n aria-describedby={`${id}-purpose`}\n aria-haspopup=\"dialog\"\n aria-expanded={open()}\n aria-controls={id}\n // The full name for a truncated title and for the icon in a collapsed rail.\n title={props.label}\n onPointerEnter={load}\n onFocus={load}\n onPointerDown={() => (openAtPress = panel?.matches(\":popover-open\"))}\n onClick={() => {\n const wasOpen = openAtPress ?? panel?.matches(\":popover-open\");\n openAtPress = undefined;\n if (wasOpen) hide(false);\n else show();\n }}\n onKeyDown={(event) => {\n if (event.key !== \"ArrowDown\" && event.key !== \"ArrowUp\") return;\n event.preventDefault();\n if (open()) focusRow(event.key === \"ArrowDown\" ? 0 : -1);\n else show(event.key === \"ArrowDown\" ? \"start\" : \"end\");\n }}\n >\n <span class=\"k2b-sidebar-switcher__icon\" style={tint(props.color)} aria-hidden=\"true\">\n <i class={iconClass(props.icon)} />\n </span>\n <span class=\"k2b-sidebar-switcher__copy\" aria-hidden=\"true\">\n <span class=\"k2b-truncate-fade-lines\">{props.label}</span>\n <Show when={props.description}>{(description) => <small class=\"k2b-truncate-fade\">{description()}</small>}</Show>\n </span>\n <i class=\"ti ti-selector k2b-sidebar-switcher__chevron\" aria-hidden=\"true\" />\n <span id={`${id}-purpose`} class=\"k2b-sr-only\">\n {[props.description, props.switchLabel].filter(Boolean).join(\", \")}\n </span>\n </button>\n <div\n ref={panel}\n id={id}\n popover=\"auto\"\n tabIndex={-1}\n role=\"dialog\"\n aria-label={props.switchLabel}\n class=\"k2b-sidebar-switcher__panel\"\n onKeyDown={onPanelKeyDown}\n onFocusOut={(event) => {\n const next = event.relatedTarget as Node | null;\n // Tabbing out closes the panel; focus that leaves the window keeps it.\n if (next && !panel?.contains(next) && next !== trigger) hide(false);\n }}\n onToggle={(event) => {\n if ((event as ToggleEvent).newState === \"open\") return;\n setOpen(false);\n listen(false);\n }}\n >\n <Show when={searchable()}>\n <div class=\"k2b-choice-search k2b-sidebar-switcher__search\">\n <i class=\"ti ti-search\" aria-hidden=\"true\" />\n <input\n ref={search}\n type=\"search\"\n data-switcher-row\n value={query()}\n placeholder={messages().search}\n aria-label={messages().searchLabel}\n aria-controls={`${id}-options`}\n onInput={(event) => setQuery(event.currentTarget.value)}\n />\n </div>\n </Show>\n <ul id={`${id}-options`} class=\"k2b-sidebar-switcher__options\">\n <Show\n when={props.options}\n fallback={\n <li class=\"k2b-choice-status\" role=\"status\" data-tone={props.error ? \"danger\" : undefined}>\n <Show\n when={props.error}\n fallback={\n <>\n <i class=\"ti ti-loader-2 k2b-spin\" aria-hidden=\"true\" />\n <span>{messages().loading}</span>\n </>\n }\n >\n {(error) => (\n <>\n <span>{error()}</span>\n <button type=\"button\" data-switcher-row onClick={() => props.onLoad?.()}>\n {messages().retry}\n </button>\n </>\n )}\n </Show>\n </li>\n }\n >\n <For\n each={visible()}\n fallback={\n <li class=\"k2b-choice-status\" role=\"status\">\n {messages().noResults}\n </li>\n }\n >\n {(option) => {\n const current = () => option.id === props.currentId;\n return (\n <li>\n <a\n href={option.href}\n class=\"k2b-dropdown__item k2b-sidebar-switcher__option\"\n data-switcher-row\n data-switcher-option\n aria-current={current() ? \"true\" : undefined}\n onClick={(event) => {\n // The open container is already here: choosing it only closes the panel.\n if (current() && plainClick(event)) {\n event.preventDefault();\n hide(true);\n } else follow(event);\n }}\n >\n <span class=\"k2b-sidebar-switcher__option-icon\" style={tint(option.color ?? props.color)} aria-hidden=\"true\">\n <i class={iconClass(option.icon ?? props.icon)} />\n </span>\n <span class=\"k2b-dropdown__copy\">\n <span>{option.label}</span>\n <Show when={option.description}>{(description) => <small>{description()}</small>}</Show>\n </span>\n <i class=\"ti ti-check k2b-dropdown__check\" data-hidden={current() ? undefined : \"true\"} aria-hidden=\"true\" />\n </a>\n </li>\n );\n }}\n </For>\n </Show>\n </ul>\n <Show when={props.actions?.length}>\n <ul class=\"k2b-sidebar-switcher__actions\">\n <For each={props.actions}>\n {(item) => (\n <li>\n <Show\n when={item.href}\n fallback={\n <button\n type=\"button\"\n class=\"k2b-dropdown__item\"\n data-switcher-row\n disabled={item.disabled}\n aria-disabled={item.disabled ? \"true\" : undefined}\n onClick={() => choose(() => item.action?.())}\n >\n <i class={iconClass(item.icon)} aria-hidden=\"true\" />\n <span class=\"k2b-dropdown__copy\">\n <span>{item.label}</span>\n </span>\n </button>\n }\n >\n {(href) => (\n <a\n href={item.disabled ? undefined : href()}\n class=\"k2b-dropdown__item\"\n data-switcher-row\n aria-disabled={item.disabled ? \"true\" : undefined}\n onClick={(event) => item.disabled || follow(event)}\n >\n <i class={iconClass(item.icon)} aria-hidden=\"true\" />\n <span class=\"k2b-dropdown__copy\">\n <span>{item.label}</span>\n </span>\n </a>\n )}\n </Show>\n </li>\n )}\n </For>\n </ul>\n </Show>\n </div>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -6,7 +6,7 @@ import { getNextElement as _$getNextElement } from "solid-js/web";
6
6
  import { insert as _$insert } from "solid-js/web";
7
7
  import { createComponent as _$createComponent } from "solid-js/web";
8
8
  var _tmpl$ = /*#__PURE__*/_$template(`<nav><ul>`),
9
- _tmpl$2 = /*#__PURE__*/_$template(`<li><a><i aria-hidden=true></i><span>`);
9
+ _tmpl$2 = /*#__PURE__*/_$template(`<li><a><i aria-hidden=true></i><span class=k2b-truncate-fade>`);
10
10
  import { For } from "solid-js";
11
11
  /** A phone app's bottom navigation holds at most five destinations. */
12
12
  const TAB_BAR_MAX_ITEMS = 5;
@@ -31,16 +31,16 @@ export function TabBar(props) {
31
31
  _el$6 = _el$5.nextSibling;
32
32
  _$insert(_el$6, () => item.label);
33
33
  _$effect(_p$ => {
34
- var _v$3 = item.href,
35
- _v$4 = item.current ? "page" : undefined,
36
- _v$5 = item.id,
37
- _v$6 = item.title ?? item.label,
38
- _v$7 = item.icon;
39
- _v$3 !== _p$.e && _$setAttribute(_el$4, "href", _p$.e = _v$3);
40
- _v$4 !== _p$.t && _$setAttribute(_el$4, "aria-current", _p$.t = _v$4);
41
- _v$5 !== _p$.a && _$setAttribute(_el$4, "data-tab", _p$.a = _v$5);
42
- _v$6 !== _p$.o && _$setAttribute(_el$4, "data-k2b-title", _p$.o = _v$6);
43
- _v$7 !== _p$.i && _$className(_el$5, _p$.i = _v$7);
34
+ var _v$4 = item.href,
35
+ _v$5 = item.current ? "page" : undefined,
36
+ _v$6 = item.id,
37
+ _v$7 = item.title ?? item.label,
38
+ _v$8 = item.icon;
39
+ _v$4 !== _p$.e && _$setAttribute(_el$4, "href", _p$.e = _v$4);
40
+ _v$5 !== _p$.t && _$setAttribute(_el$4, "aria-current", _p$.t = _v$5);
41
+ _v$6 !== _p$.a && _$setAttribute(_el$4, "data-tab", _p$.a = _v$6);
42
+ _v$7 !== _p$.o && _$setAttribute(_el$4, "data-k2b-title", _p$.o = _v$7);
43
+ _v$8 !== _p$.i && _$className(_el$5, _p$.i = _v$8);
44
44
  return _p$;
45
45
  }, {
46
46
  e: undefined,
@@ -54,13 +54,16 @@ export function TabBar(props) {
54
54
  }));
55
55
  _$effect(_p$ => {
56
56
  var _v$ = props.class ? `k2b-tab-bar ${props.class}` : "k2b-tab-bar",
57
- _v$2 = props.label;
57
+ _v$2 = props.label,
58
+ _v$3 = props.variant === "floating" ? "floating" : undefined;
58
59
  _v$ !== _p$.e && _$className(_el$, _p$.e = _v$);
59
60
  _v$2 !== _p$.t && _$setAttribute(_el$, "aria-label", _p$.t = _v$2);
61
+ _v$3 !== _p$.a && _$setAttribute(_el$, "data-variant", _p$.a = _v$3);
60
62
  return _p$;
61
63
  }, {
62
64
  e: undefined,
63
- t: undefined
65
+ t: undefined,
66
+ a: undefined
64
67
  });
65
68
  return _el$;
66
69
  })();
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["layout/TabBar.tsx"],"sourcesContent":["import { For, type JSX } from \"solid-js\";\n\nexport type TabBarItem = {\n id: string;\n label: string;\n /** Icon class, for example `ti ti-home`. */\n icon: string;\n href: string;\n /** The header title of the page this item opens, shown while that page loads. Defaults to `label`. */\n title?: string;\n /** The page this item leads to is open. */\n current?: boolean;\n};\n\nexport type TabBarProps = {\n /** Accessible name of the navigation landmark. */\n label: string;\n /** Up to five destinations; further items are not rendered. Put the rest behind a \"More\" destination. */\n items: readonly TabBarItem[];\n class?: string;\n};\n\n/** A phone app's bottom navigation holds at most five destinations. */\nconst TAB_BAR_MAX_ITEMS = 5;\n\n/**\n * Bottom navigation between a phone app's top-level pages: native links with equal widths, an icon above each label,\n * and `aria-current=\"page\"` on the open page. Place it in `MobileShell`'s footer; it pads the bottom safe area. There a\n * tab switches at the first touch: the shell shows the item's `title` while its page loads.\n */\nexport function TabBar(props: TabBarProps): JSX.Element {\n return (\n <nav class={props.class ? `k2b-tab-bar ${props.class}` : \"k2b-tab-bar\"} aria-label={props.label}>\n <ul>\n <For each={props.items.slice(0, TAB_BAR_MAX_ITEMS)}>\n {(item) => (\n <li>\n <a\n href={item.href}\n aria-current={item.current ? \"page\" : undefined}\n data-tab={item.id}\n data-k2b-title={item.title ?? item.label}\n >\n <i class={item.icon} aria-hidden=\"true\" />\n <span>{item.label}</span>\n </a>\n </li>\n )}\n </For>\n </ul>\n </nav>\n );\n}\n\nexport default TabBar;\n"],"mappings":";;;;;;;;;AAAA,SAAS,GAAG,QAAkB,UAAU;AAsBxC;AACA,MAAM,iBAAiB,GAAG,CAAC;;AAE3B;AACA;AACA;AACA;AACA;AACA,OAAO,SAAS,MAAM,CAAC,KAAkB,EAAe;EACtD;IAAA;MAAA;IAAA,kCAGO,GAAG;MAAA,IAAC,IAAI;QAAA,OAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC;MAAA;MAAA,UAC9C,IAAI;QAAA;UAAA;UAAA;UAAA;QAAA,sBASO,IAAI,CAAC,KAAK;QAAA;UAAA,WANX,IAAI,CAAC,IAAI;YAAA,OACD,IAAI,CAAC,OAAO,GAAG,MAAM,GAAG,SAAS;YAAA,OACrC,IAAI,CAAC,EAAE;YAAA,OACD,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK;YAAA,OAE9B,IAAI,CAAC,IAAI;UAAA;UAAA;UAAA;UAAA;UAAA;UAAA;QAAA;UAAA;UAAA;UAAA;UAAA;UAAA;QAAA;QAAA;MAAA;IAIxB;IAAA;MAAA,UAfK,KAAK,CAAC,KAAK,GAAG,eAAe,KAAK,CAAC,KAAK,EAAE,GAAG,aAAa;QAAA,OAAc,KAAK,CAAC,KAAK;MAAA;MAAA;MAAA;IAAA;MAAA;MAAA;IAAA;IAAA;EAAA;AAoBnG;AAEA,eAAe,MAAM","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["layout/TabBar.tsx"],"sourcesContent":["import { For, type JSX } from \"solid-js\";\n\nexport type TabBarItem = {\n id: string;\n label: string;\n /** Icon class, for example `ti ti-home`. */\n icon: string;\n href: string;\n /** The header title of the page this item opens, shown while that page loads. Defaults to `label`. */\n title?: string;\n /** The page this item leads to is open. */\n current?: boolean;\n};\n\nexport type TabBarProps = {\n /** Accessible name of the navigation landmark. */\n label: string;\n /** Up to five destinations; further items are not rendered. Put the rest behind a \"More\" destination. */\n items: readonly TabBarItem[];\n /**\n * `bar` (the default) is flat on the page canvas and pads the bottom safe area. `floating` is a rounded bar that the\n * host places above the content, away from the safe areas; its open item is a raised chip. The host may paint it\n * with `--k2b-tab-bar-background`, color its items with `--k2b-tab-bar-color`, and color the open item with\n * `--k2b-tab-bar-selected-background` and `--k2b-tab-bar-selected-color`.\n */\n variant?: \"bar\" | \"floating\";\n class?: string;\n};\n\n/** A phone app's bottom navigation holds at most five destinations. */\nconst TAB_BAR_MAX_ITEMS = 5;\n\n/**\n * Bottom navigation between a phone app's top-level pages: native links with equal widths, an icon above each label,\n * and `aria-current=\"page\"` on the open page. Place it in `MobileShell`'s footer; it pads the bottom safe area. There a\n * tab switches at the first touch: the shell shows the item's `title` while its page loads.\n */\nexport function TabBar(props: TabBarProps): JSX.Element {\n return (\n <nav\n class={props.class ? `k2b-tab-bar ${props.class}` : \"k2b-tab-bar\"}\n aria-label={props.label}\n data-variant={props.variant === \"floating\" ? \"floating\" : undefined}\n >\n <ul>\n <For each={props.items.slice(0, TAB_BAR_MAX_ITEMS)}>\n {(item) => (\n <li>\n <a\n href={item.href}\n aria-current={item.current ? \"page\" : undefined}\n data-tab={item.id}\n data-k2b-title={item.title ?? item.label}\n >\n <i class={item.icon} aria-hidden=\"true\" />\n <span class=\"k2b-truncate-fade\">{item.label}</span>\n </a>\n </li>\n )}\n </For>\n </ul>\n </nav>\n );\n}\n\nexport default TabBar;\n"],"mappings":";;;;;;;;;AAAA,SAAS,GAAG,QAAkB,UAAU;AA6BxC;AACA,MAAM,iBAAiB,GAAG,CAAC;;AAE3B;AACA;AACA;AACA;AACA;AACA,OAAO,SAAS,MAAM,CAAC,KAAkB,EAAe;EACtD;IAAA;MAAA;IAAA,kCAOO,GAAG;MAAA,IAAC,IAAI;QAAA,OAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC;MAAA;MAAA,UAC9C,IAAI;QAAA;UAAA;UAAA;UAAA;QAAA,sBASiC,IAAI,CAAC,KAAK;QAAA;UAAA,WANrC,IAAI,CAAC,IAAI;YAAA,OACD,IAAI,CAAC,OAAO,GAAG,MAAM,GAAG,SAAS;YAAA,OACrC,IAAI,CAAC,EAAE;YAAA,OACD,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK;YAAA,OAE9B,IAAI,CAAC,IAAI;UAAA;UAAA;UAAA;UAAA;UAAA;UAAA;QAAA;UAAA;UAAA;UAAA;UAAA;UAAA;QAAA;QAAA;MAAA;IAIxB;IAAA;MAAA,UAlBE,KAAK,CAAC,KAAK,GAAG,eAAe,KAAK,CAAC,KAAK,EAAE,GAAG,aAAa;QAAA,OACrD,KAAK,CAAC,KAAK;QAAA,OACT,KAAK,CAAC,OAAO,KAAK,UAAU,GAAG,UAAU,GAAG,SAAS;MAAA;MAAA;MAAA;MAAA;IAAA;MAAA;MAAA;MAAA;IAAA;IAAA;EAAA;AAqBzE;AAEA,eAAe,MAAM","ignoreList":[]}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Watches whether workspace chrome has at least `minRem` of app host width.
3
+ * CSS for the same chrome uses `@container k2b-app-area (min-width: …)`.
4
+ * Call with a mounted element; the returned function stops all observation.
5
+ */
6
+ export function watchAppHostWidth(element, minRem, update) {
7
+ const root = document.documentElement;
8
+ const workspace = element.closest(".k2b-app-workspace") ?? element;
9
+ let host;
10
+ let matches;
11
+ let stopped = false;
12
+ const px = value => Number.parseFloat(value) || 0;
13
+ const check = () => {
14
+ if (stopped) return;
15
+ let ancestor = element.parentElement;
16
+ while (ancestor && !getComputedStyle(ancestor).containerName.split(/\s+/).includes("k2b-app-area")) {
17
+ ancestor = ancestor.parentElement;
18
+ }
19
+ const target = ancestor ?? root;
20
+ if (target !== host) {
21
+ host = target;
22
+ observer?.disconnect();
23
+ for (const observed of new Set([root, host, workspace])) observer?.observe(observed);
24
+ }
25
+ const style = getComputedStyle(target);
26
+ // Container queries measure fractional content-box pixels, before transforms.
27
+ const width = px(style.width) - (style.boxSizing === "border-box" ? px(style.paddingLeft) + px(style.paddingRight) + px(style.borderLeftWidth) + px(style.borderRightWidth) : 0);
28
+ const next = width >= minRem * px(getComputedStyle(root).fontSize);
29
+ if (next !== matches) {
30
+ matches = next;
31
+ update(next);
32
+ }
33
+ };
34
+ // A host gains or loses its name together with a width change (Cloud's panel column), which the workspace sees.
35
+ const observer = typeof ResizeObserver === "undefined" ? undefined : new ResizeObserver(check);
36
+ if (!observer) window.addEventListener("resize", check);
37
+ check();
38
+ return () => {
39
+ stopped = true;
40
+ observer?.disconnect();
41
+ window.removeEventListener("resize", check);
42
+ };
43
+ }
44
+ //# sourceMappingURL=app-host-width.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["layout/app-host-width.ts"],"sourcesContent":["/**\n * Watches whether workspace chrome has at least `minRem` of app host width.\n * CSS for the same chrome uses `@container k2b-app-area (min-width: …)`.\n * Call with a mounted element; the returned function stops all observation.\n */\nexport function watchAppHostWidth(element: Element, minRem: number, update: (matches: boolean) => void): () => void {\n const root = document.documentElement;\n const workspace = element.closest(\".k2b-app-workspace\") ?? element;\n let host: Element | undefined;\n let matches: boolean | undefined;\n let stopped = false;\n const px = (value: string) => Number.parseFloat(value) || 0;\n const check = () => {\n if (stopped) return;\n let ancestor = element.parentElement;\n while (ancestor && !getComputedStyle(ancestor).containerName.split(/\\s+/).includes(\"k2b-app-area\")) {\n ancestor = ancestor.parentElement;\n }\n const target = ancestor ?? root;\n if (target !== host) {\n host = target;\n observer?.disconnect();\n for (const observed of new Set([root, host, workspace])) observer?.observe(observed);\n }\n const style = getComputedStyle(target);\n // Container queries measure fractional content-box pixels, before transforms.\n const width =\n px(style.width) -\n (style.boxSizing === \"border-box\"\n ? px(style.paddingLeft) + px(style.paddingRight) + px(style.borderLeftWidth) + px(style.borderRightWidth)\n : 0);\n const next = width >= minRem * px(getComputedStyle(root).fontSize);\n if (next !== matches) {\n matches = next;\n update(next);\n }\n };\n // A host gains or loses its name together with a width change (Cloud's panel column), which the workspace sees.\n const observer = typeof ResizeObserver === \"undefined\" ? undefined : new ResizeObserver(check);\n if (!observer) window.addEventListener(\"resize\", check);\n check();\n return () => {\n stopped = true;\n observer?.disconnect();\n window.removeEventListener(\"resize\", check);\n };\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA,OAAO,SAAS,iBAAiB,CAAC,OAAgB,EAAE,MAAc,EAAE,MAAkC,EAAc;EAClH,MAAM,IAAI,GAAG,QAAQ,CAAC,eAAe;EACrC,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,OAAO;EAClE,IAAI,IAAyB;EAC7B,IAAI,OAA4B;EAChC,IAAI,OAAO,GAAG,KAAK;EACnB,MAAM,EAAE,GAAI,KAAa,IAAK,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;EAC3D,MAAM,KAAK,GAAG,MAAM;IAClB,IAAI,OAAO,EAAE;IACb,IAAI,QAAQ,GAAG,OAAO,CAAC,aAAa;IACpC,OAAO,QAAQ,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE;MAClG,QAAQ,GAAG,QAAQ,CAAC,aAAa;IACnC;IACA,MAAM,MAAM,GAAG,QAAQ,IAAI,IAAI;IAC/B,IAAI,MAAM,KAAK,IAAI,EAAE;MACnB,IAAI,GAAG,MAAM;MACb,QAAQ,EAAE,UAAU,CAAC,CAAC;MACtB,KAAK,MAAM,QAAQ,IAAI,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC;IACtF;IACA,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,CAAC;IACtC;IACA,MAAM,KAAK,GACT,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IACd,KAAK,CAAC,SAAS,KAAK,YAAY,GAC7B,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,GACvG,CAAC,CAAC;IACR,MAAM,IAAI,GAAG,KAAK,IAAI,MAAM,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;IAClE,IAAI,IAAI,KAAK,OAAO,EAAE;MACpB,OAAO,GAAG,IAAI;MACd,MAAM,CAAC,IAAI,CAAC;IACd;EACF,CAAC;EACD;EACA,MAAM,QAAQ,GAAG,OAAO,cAAc,KAAK,WAAW,GAAG,SAAS,GAAG,IAAI,cAAc,CAAC,KAAK,CAAC;EAC9F,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,KAAK,CAAC;EACvD,KAAK,CAAC,CAAC;EACP,OAAO,MAAM;IACX,OAAO,GAAG,IAAI;IACd,QAAQ,EAAE,UAAU,CAAC,CAAC;IACtB,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC;EAC7C,CAAC;AACH","ignoreList":[]}