@k2b/ui 0.33.0 → 0.35.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 (310) hide show
  1. package/dist/base.css +14 -1
  2. package/dist/browser/actions/ContextMenu.js +13 -0
  3. package/dist/browser/actions/ContextMenu.js.map +1 -1
  4. package/dist/browser/actions/Dropdown.js +16 -4
  5. package/dist/browser/actions/Dropdown.js.map +1 -1
  6. package/dist/browser/actions/SelectionToolbar.js +129 -0
  7. package/dist/browser/actions/SelectionToolbar.js.map +1 -0
  8. package/dist/browser/actions/index.js +1 -0
  9. package/dist/browser/actions/index.js.map +1 -1
  10. package/dist/browser/charts.js +6 -0
  11. package/dist/browser/charts.js.map +1 -0
  12. package/dist/browser/chat/ChatComposer.js +525 -407
  13. package/dist/browser/chat/ChatComposer.js.map +1 -1
  14. package/dist/browser/chat/chat-messages.js +4 -0
  15. package/dist/browser/chat/chat-messages.js.map +1 -1
  16. package/dist/browser/chat/composer-document.js +19 -0
  17. package/dist/browser/chat/composer-document.js.map +1 -1
  18. package/dist/browser/chat/index.js.map +1 -1
  19. package/dist/browser/content/Chart.js +8 -0
  20. package/dist/browser/content/Chart.js.map +1 -1
  21. package/dist/browser/content/FileGrid.js +231 -9
  22. package/dist/browser/content/FileGrid.js.map +1 -1
  23. package/dist/browser/content/FileTypeIcon.js +15 -0
  24. package/dist/browser/content/FileTypeIcon.js.map +1 -1
  25. package/dist/browser/content/FileView.js +11 -4
  26. package/dist/browser/content/FileView.js.map +1 -1
  27. package/dist/browser/content/MatchText.js +61 -0
  28. package/dist/browser/content/MatchText.js.map +1 -0
  29. package/dist/browser/content/MessageRow.js +73 -53
  30. package/dist/browser/content/MessageRow.js.map +1 -1
  31. package/dist/browser/content/ReactionBar.js +3 -1
  32. package/dist/browser/content/ReactionBar.js.map +1 -1
  33. package/dist/browser/content/calendar-day-scroll.js +4 -3
  34. package/dist/browser/content/calendar-day-scroll.js.map +1 -1
  35. package/dist/browser/content/chart-bar.js +476 -0
  36. package/dist/browser/content/chart-bar.js.map +1 -0
  37. package/dist/browser/content/file-list-messages.js +52 -0
  38. package/dist/browser/content/file-list-messages.js.map +1 -0
  39. package/dist/browser/content/index.js +2 -1
  40. package/dist/browser/content/index.js.map +1 -1
  41. package/dist/browser/feedback/Tooltip.js +31 -14
  42. package/dist/browser/feedback/Tooltip.js.map +1 -1
  43. package/dist/browser/inputs/ChoiceList.js +178 -0
  44. package/dist/browser/inputs/ChoiceList.js.map +1 -0
  45. package/dist/browser/inputs/ChoiceSlider.js +314 -0
  46. package/dist/browser/inputs/ChoiceSlider.js.map +1 -0
  47. package/dist/browser/inputs/ChoiceTiles.js +135 -0
  48. package/dist/browser/inputs/ChoiceTiles.js.map +1 -0
  49. package/dist/browser/inputs/ColorChoices.js +120 -0
  50. package/dist/browser/inputs/ColorChoices.js.map +1 -0
  51. package/dist/browser/inputs/QrScanner.js +95 -13
  52. package/dist/browser/inputs/QrScanner.js.map +1 -1
  53. package/dist/browser/inputs/TextInput.js +15 -13
  54. package/dist/browser/inputs/TextInput.js.map +1 -1
  55. package/dist/browser/inputs/index.js +4 -0
  56. package/dist/browser/inputs/index.js.map +1 -1
  57. package/dist/browser/inputs/qr-messages.js +2 -0
  58. package/dist/browser/inputs/qr-messages.js.map +1 -1
  59. package/dist/browser/internal/radio-keys.js +13 -0
  60. package/dist/browser/internal/radio-keys.js.map +1 -0
  61. package/dist/browser/layout/AnchoredPopover.js +180 -0
  62. package/dist/browser/layout/AnchoredPopover.js.map +1 -0
  63. package/dist/browser/layout/AppWorkspace.js +155 -20
  64. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  65. package/dist/browser/layout/DetailPanel.js +443 -333
  66. package/dist/browser/layout/DetailPanel.js.map +1 -1
  67. package/dist/browser/layout/MobileShell.js +21 -7
  68. package/dist/browser/layout/MobileShell.js.map +1 -1
  69. package/dist/browser/layout/Settings.js +283 -175
  70. package/dist/browser/layout/Settings.js.map +1 -1
  71. package/dist/browser/layout/SidebarRailHint.js +79 -0
  72. package/dist/browser/layout/SidebarRailHint.js.map +1 -0
  73. package/dist/browser/layout/SidebarSwitcher.js +79 -66
  74. package/dist/browser/layout/SidebarSwitcher.js.map +1 -1
  75. package/dist/browser/layout/TabBar.js +18 -4
  76. package/dist/browser/layout/TabBar.js.map +1 -1
  77. package/dist/browser/layout/app-workspace-controller.js +11 -4
  78. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  79. package/dist/browser/layout/detail-panel-messages.js +4 -2
  80. package/dist/browser/layout/detail-panel-messages.js.map +1 -1
  81. package/dist/browser/layout/index.js +2 -1
  82. package/dist/browser/layout/index.js.map +1 -1
  83. package/dist/browser/layout/settings-messages.js +26 -2
  84. package/dist/browser/layout/settings-messages.js.map +1 -1
  85. package/dist/browser/surfaces/Avatar.js +2 -14
  86. package/dist/browser/surfaces/Avatar.js.map +1 -1
  87. package/dist/browser/surfaces/DotStrip.js +70 -0
  88. package/dist/browser/surfaces/DotStrip.js.map +1 -0
  89. package/dist/browser/surfaces/ProgressRing.js +3 -0
  90. package/dist/browser/surfaces/ProgressRing.js.map +1 -1
  91. package/dist/browser/surfaces/ResourceCard.js +125 -68
  92. package/dist/browser/surfaces/ResourceCard.js.map +1 -1
  93. package/dist/browser/surfaces/index.js +2 -0
  94. package/dist/browser/surfaces/index.js.map +1 -1
  95. package/dist/browser/surfaces/person-color.js +18 -0
  96. package/dist/browser/surfaces/person-color.js.map +1 -0
  97. package/dist/browser/surfaces/resource-messages.js +6 -2
  98. package/dist/browser/surfaces/resource-messages.js.map +1 -1
  99. package/dist/browser/text-editor/TextEditor.js +1358 -0
  100. package/dist/browser/text-editor/TextEditor.js.map +1 -0
  101. package/dist/browser/text-editor/clipboard-html.js +152 -0
  102. package/dist/browser/text-editor/clipboard-html.js.map +1 -0
  103. package/dist/browser/text-editor/clipboard-loading.js +68 -0
  104. package/dist/browser/text-editor/clipboard-loading.js.map +1 -0
  105. package/dist/browser/text-editor/clipboard.js +51 -0
  106. package/dist/browser/text-editor/clipboard.js.map +1 -0
  107. package/dist/browser/text-editor/engine.js +125 -0
  108. package/dist/browser/text-editor/engine.js.map +1 -0
  109. package/dist/browser/text-editor/format.js +218 -0
  110. package/dist/browser/text-editor/format.js.map +1 -0
  111. package/dist/browser/text-editor/formatted.js +164 -0
  112. package/dist/browser/text-editor/formatted.js.map +1 -0
  113. package/dist/browser/text-editor/language.js +19 -0
  114. package/dist/browser/text-editor/language.js.map +1 -0
  115. package/dist/browser/text-editor/markdown-table.js +563 -0
  116. package/dist/browser/text-editor/markdown-table.js.map +1 -0
  117. package/dist/browser/text-editor/messages.js +233 -0
  118. package/dist/browser/text-editor/messages.js.map +1 -0
  119. package/dist/browser/text-editor/paste.js +115 -0
  120. package/dist/browser/text-editor/paste.js.map +1 -0
  121. package/dist/browser/text-editor/table.js +1760 -0
  122. package/dist/browser/text-editor/table.js.map +1 -0
  123. package/dist/browser/text-editor.js +5 -0
  124. package/dist/browser/text-editor.js.map +1 -0
  125. package/dist/browser/widgets/Widget.js +3 -2
  126. package/dist/browser/widgets/Widget.js.map +1 -1
  127. package/dist/ssr/actions/ContextMenu.js +9 -0
  128. package/dist/ssr/actions/ContextMenu.js.map +1 -1
  129. package/dist/ssr/actions/Dropdown.js +15 -4
  130. package/dist/ssr/actions/Dropdown.js.map +1 -1
  131. package/dist/ssr/actions/SelectionToolbar.js +104 -0
  132. package/dist/ssr/actions/SelectionToolbar.js.map +1 -0
  133. package/dist/ssr/actions/index.js +1 -0
  134. package/dist/ssr/actions/index.js.map +1 -1
  135. package/dist/ssr/charts.js +6 -0
  136. package/dist/ssr/charts.js.map +1 -0
  137. package/dist/ssr/chat/ChatComposer.js +132 -53
  138. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  139. package/dist/ssr/chat/chat-messages.js +4 -0
  140. package/dist/ssr/chat/chat-messages.js.map +1 -1
  141. package/dist/ssr/chat/composer-document.js +19 -0
  142. package/dist/ssr/chat/composer-document.js.map +1 -1
  143. package/dist/ssr/chat/index.js.map +1 -1
  144. package/dist/ssr/content/Chart.js +8 -0
  145. package/dist/ssr/content/Chart.js.map +1 -1
  146. package/dist/ssr/content/FileGrid.js +132 -5
  147. package/dist/ssr/content/FileGrid.js.map +1 -1
  148. package/dist/ssr/content/FileTypeIcon.js +15 -0
  149. package/dist/ssr/content/FileTypeIcon.js.map +1 -1
  150. package/dist/ssr/content/FileView.js +11 -4
  151. package/dist/ssr/content/FileView.js.map +1 -1
  152. package/dist/ssr/content/MatchText.js +56 -0
  153. package/dist/ssr/content/MatchText.js.map +1 -0
  154. package/dist/ssr/content/MessageRow.js +16 -6
  155. package/dist/ssr/content/MessageRow.js.map +1 -1
  156. package/dist/ssr/content/ReactionBar.js +3 -1
  157. package/dist/ssr/content/ReactionBar.js.map +1 -1
  158. package/dist/ssr/content/calendar-day-scroll.js +4 -3
  159. package/dist/ssr/content/calendar-day-scroll.js.map +1 -1
  160. package/dist/ssr/content/chart-bar.js +476 -0
  161. package/dist/ssr/content/chart-bar.js.map +1 -0
  162. package/dist/ssr/content/file-list-messages.js +52 -0
  163. package/dist/ssr/content/file-list-messages.js.map +1 -0
  164. package/dist/ssr/content/index.js +2 -1
  165. package/dist/ssr/content/index.js.map +1 -1
  166. package/dist/ssr/feedback/Tooltip.js +31 -14
  167. package/dist/ssr/feedback/Tooltip.js.map +1 -1
  168. package/dist/ssr/inputs/ChoiceList.js +95 -0
  169. package/dist/ssr/inputs/ChoiceList.js.map +1 -0
  170. package/dist/ssr/inputs/ChoiceSlider.js +191 -0
  171. package/dist/ssr/inputs/ChoiceSlider.js.map +1 -0
  172. package/dist/ssr/inputs/ChoiceTiles.js +61 -0
  173. package/dist/ssr/inputs/ChoiceTiles.js.map +1 -0
  174. package/dist/ssr/inputs/ColorChoices.js +60 -0
  175. package/dist/ssr/inputs/ColorChoices.js.map +1 -0
  176. package/dist/ssr/inputs/QrScanner.js +89 -10
  177. package/dist/ssr/inputs/QrScanner.js.map +1 -1
  178. package/dist/ssr/inputs/TextInput.js +13 -1
  179. package/dist/ssr/inputs/TextInput.js.map +1 -1
  180. package/dist/ssr/inputs/index.js +4 -0
  181. package/dist/ssr/inputs/index.js.map +1 -1
  182. package/dist/ssr/inputs/qr-messages.js +2 -0
  183. package/dist/ssr/inputs/qr-messages.js.map +1 -1
  184. package/dist/ssr/internal/radio-keys.js +13 -0
  185. package/dist/ssr/internal/radio-keys.js.map +1 -0
  186. package/dist/ssr/layout/AnchoredPopover.js +142 -0
  187. package/dist/ssr/layout/AnchoredPopover.js.map +1 -0
  188. package/dist/ssr/layout/AppWorkspace.js +154 -20
  189. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  190. package/dist/ssr/layout/DetailPanel.js +181 -108
  191. package/dist/ssr/layout/DetailPanel.js.map +1 -1
  192. package/dist/ssr/layout/MobileShell.js +20 -6
  193. package/dist/ssr/layout/MobileShell.js.map +1 -1
  194. package/dist/ssr/layout/Settings.js +122 -45
  195. package/dist/ssr/layout/Settings.js.map +1 -1
  196. package/dist/ssr/layout/SidebarRailHint.js +79 -0
  197. package/dist/ssr/layout/SidebarRailHint.js.map +1 -0
  198. package/dist/ssr/layout/SidebarSwitcher.js +13 -3
  199. package/dist/ssr/layout/SidebarSwitcher.js.map +1 -1
  200. package/dist/ssr/layout/TabBar.js +11 -3
  201. package/dist/ssr/layout/TabBar.js.map +1 -1
  202. package/dist/ssr/layout/app-workspace-controller.js +11 -4
  203. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  204. package/dist/ssr/layout/detail-panel-messages.js +4 -2
  205. package/dist/ssr/layout/detail-panel-messages.js.map +1 -1
  206. package/dist/ssr/layout/index.js +2 -1
  207. package/dist/ssr/layout/index.js.map +1 -1
  208. package/dist/ssr/layout/settings-messages.js +26 -2
  209. package/dist/ssr/layout/settings-messages.js.map +1 -1
  210. package/dist/ssr/surfaces/Avatar.js +2 -14
  211. package/dist/ssr/surfaces/Avatar.js.map +1 -1
  212. package/dist/ssr/surfaces/DotStrip.js +31 -0
  213. package/dist/ssr/surfaces/DotStrip.js.map +1 -0
  214. package/dist/ssr/surfaces/ProgressRing.js +3 -0
  215. package/dist/ssr/surfaces/ProgressRing.js.map +1 -1
  216. package/dist/ssr/surfaces/ResourceCard.js +40 -15
  217. package/dist/ssr/surfaces/ResourceCard.js.map +1 -1
  218. package/dist/ssr/surfaces/index.js +2 -0
  219. package/dist/ssr/surfaces/index.js.map +1 -1
  220. package/dist/ssr/surfaces/person-color.js +18 -0
  221. package/dist/ssr/surfaces/person-color.js.map +1 -0
  222. package/dist/ssr/surfaces/resource-messages.js +6 -2
  223. package/dist/ssr/surfaces/resource-messages.js.map +1 -1
  224. package/dist/ssr/text-editor/TextEditor.js +1155 -0
  225. package/dist/ssr/text-editor/TextEditor.js.map +1 -0
  226. package/dist/ssr/text-editor/clipboard-html.js +152 -0
  227. package/dist/ssr/text-editor/clipboard-html.js.map +1 -0
  228. package/dist/ssr/text-editor/clipboard-loading.js +68 -0
  229. package/dist/ssr/text-editor/clipboard-loading.js.map +1 -0
  230. package/dist/ssr/text-editor/clipboard.js +51 -0
  231. package/dist/ssr/text-editor/clipboard.js.map +1 -0
  232. package/dist/ssr/text-editor/engine.js +125 -0
  233. package/dist/ssr/text-editor/engine.js.map +1 -0
  234. package/dist/ssr/text-editor/format.js +218 -0
  235. package/dist/ssr/text-editor/format.js.map +1 -0
  236. package/dist/ssr/text-editor/formatted.js +164 -0
  237. package/dist/ssr/text-editor/formatted.js.map +1 -0
  238. package/dist/ssr/text-editor/language.js +19 -0
  239. package/dist/ssr/text-editor/language.js.map +1 -0
  240. package/dist/ssr/text-editor/markdown-table.js +563 -0
  241. package/dist/ssr/text-editor/markdown-table.js.map +1 -0
  242. package/dist/ssr/text-editor/messages.js +233 -0
  243. package/dist/ssr/text-editor/messages.js.map +1 -0
  244. package/dist/ssr/text-editor/paste.js +115 -0
  245. package/dist/ssr/text-editor/paste.js.map +1 -0
  246. package/dist/ssr/text-editor/table.js +1760 -0
  247. package/dist/ssr/text-editor/table.js.map +1 -0
  248. package/dist/ssr/text-editor.js +5 -0
  249. package/dist/ssr/text-editor.js.map +1 -0
  250. package/dist/ssr/widgets/Widget.js +3 -2
  251. package/dist/ssr/widgets/Widget.js.map +1 -1
  252. package/dist/styles.css +1 -1
  253. package/dist/types/actions/ContextMenu.d.ts +5 -0
  254. package/dist/types/actions/Dropdown.d.ts +7 -0
  255. package/dist/types/actions/SelectionToolbar.d.ts +38 -0
  256. package/dist/types/actions/index.d.ts +2 -0
  257. package/dist/types/charts.d.ts +5 -0
  258. package/dist/types/chat/ChatComposer.d.ts +15 -0
  259. package/dist/types/chat/chat-messages.d.ts +2 -0
  260. package/dist/types/chat/composer-document.d.ts +5 -0
  261. package/dist/types/chat/index.d.ts +1 -1
  262. package/dist/types/content/Chart.d.ts +2 -1
  263. package/dist/types/content/FileGrid.d.ts +43 -3
  264. package/dist/types/content/FileTypeIcon.d.ts +10 -0
  265. package/dist/types/content/FileView.d.ts +5 -1
  266. package/dist/types/content/MatchText.d.ts +21 -0
  267. package/dist/types/content/MessageRow.d.ts +2 -0
  268. package/dist/types/content/calendar-day-scroll.d.ts +2 -1
  269. package/dist/types/content/chart-bar.d.ts +60 -0
  270. package/dist/types/content/file-list-messages.d.ts +24 -0
  271. package/dist/types/content/index.d.ts +3 -2
  272. package/dist/types/feedback/Tooltip.d.ts +8 -2
  273. package/dist/types/inputs/ChoiceList.d.ts +28 -0
  274. package/dist/types/inputs/ChoiceSlider.d.ts +36 -0
  275. package/dist/types/inputs/ChoiceTiles.d.ts +25 -0
  276. package/dist/types/inputs/ColorChoices.d.ts +19 -0
  277. package/dist/types/inputs/index.d.ts +8 -0
  278. package/dist/types/inputs/qr-messages.d.ts +1 -0
  279. package/dist/types/internal/radio-keys.d.ts +5 -0
  280. package/dist/types/layout/AnchoredPopover.d.ts +31 -0
  281. package/dist/types/layout/AppWorkspace.d.ts +10 -0
  282. package/dist/types/layout/DetailPanel.d.ts +17 -0
  283. package/dist/types/layout/MobileShell.d.ts +5 -2
  284. package/dist/types/layout/Settings.d.ts +22 -0
  285. package/dist/types/layout/SidebarRailHint.d.ts +26 -0
  286. package/dist/types/layout/TabBar.d.ts +5 -0
  287. package/dist/types/layout/detail-panel-messages.d.ts +1 -0
  288. package/dist/types/layout/index.d.ts +3 -2
  289. package/dist/types/layout/settings-messages.d.ts +12 -0
  290. package/dist/types/surfaces/DotStrip.d.ts +22 -0
  291. package/dist/types/surfaces/ProgressRing.d.ts +2 -1
  292. package/dist/types/surfaces/ResourceCard.d.ts +9 -0
  293. package/dist/types/surfaces/index.d.ts +4 -1
  294. package/dist/types/surfaces/person-color.d.ts +10 -0
  295. package/dist/types/surfaces/resource-messages.d.ts +2 -0
  296. package/dist/types/text-editor/TextEditor.d.ts +69 -0
  297. package/dist/types/text-editor/clipboard-html.d.ts +9 -0
  298. package/dist/types/text-editor/clipboard-loading.d.ts +8 -0
  299. package/dist/types/text-editor/clipboard.d.ts +20 -0
  300. package/dist/types/text-editor/engine.d.ts +34 -0
  301. package/dist/types/text-editor/format.d.ts +34 -0
  302. package/dist/types/text-editor/formatted.d.ts +1 -0
  303. package/dist/types/text-editor/language.d.ts +8 -0
  304. package/dist/types/text-editor/markdown-table.d.ts +105 -0
  305. package/dist/types/text-editor/messages.d.ts +113 -0
  306. package/dist/types/text-editor/paste.d.ts +6 -0
  307. package/dist/types/text-editor/table.d.ts +81 -0
  308. package/dist/types/text-editor.d.ts +4 -0
  309. package/dist/types/widgets/Widget.d.ts +3 -2
  310. package/package.json +28 -3
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["layout/Settings.tsx"],"sourcesContent":["import { children, createMemo, createUniqueId, type JSX, Show } from \"solid-js\";\nimport { Button, type ButtonVariant } from \"../actions/Button\";\nimport { usePromptMessages } from \"../feedback/prompt-messages\";\nimport type { MaybeAccessor } from \"../inputs/field-contract\";\nimport { useSettingsMessages } from \"./settings-messages\";\n\nconst read = <T,>(value: MaybeAccessor<T>): T => (typeof value === \"function\" ? (value as () => T)() : value);\n\nexport type SettingsPageProps = {\n title: JSX.Element;\n subtitle?: JSX.Element;\n icon?: string;\n actions?: JSX.Element;\n children: JSX.Element;\n footer?: JSX.Element;\n scrollPreserveKey?: string;\n class?: string;\n style?: JSX.CSSProperties | string;\n};\n\nexport function SettingsPage(props: SettingsPageProps): JSX.Element {\n return (\n <section class={`k2b-settings-page${props.class ? ` ${props.class}` : \"\"}`} style={props.style}>\n <header class=\"k2b-settings-page__header\">\n <Show when={props.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n <div class=\"k2b-settings-page__heading\">\n <h1>{props.title}</h1>\n <Show when={props.subtitle}>\n <p>{props.subtitle}</p>\n </Show>\n </div>\n <Show when={props.actions}>\n <div class=\"k2b-settings-page__actions\">{props.actions}</div>\n </Show>\n </header>\n <div class=\"k2b-settings-page__body\" data-scroll-preserve={props.scrollPreserveKey}>\n {props.children}\n </div>\n <Show when={props.footer}>\n <footer class=\"k2b-settings-page__footer\">{props.footer}</footer>\n </Show>\n </section>\n );\n}\n\nexport type SettingsSectionProps = {\n title: JSX.Element;\n subtitle?: JSX.Element;\n icon?: string;\n actions?: JSX.Element;\n children: JSX.Element;\n class?: string;\n};\n\n/**\n * A full-page settings group: a heading, optional actions and its fields on the\n * page surface without a card. Dialogs keep using PanelDialog.Section.\n */\nexport function SettingsSection(props: SettingsSectionProps): JSX.Element {\n const headingId = `k2b-settings-section-${createUniqueId()}`;\n return (\n <section class={`k2b-settings-section${props.class ? ` ${props.class}` : \"\"}`} aria-labelledby={headingId}>\n <header class=\"k2b-settings-section__header\">\n <Show when={props.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n <div class=\"k2b-settings-section__heading\">\n <h2 id={headingId}>{props.title}</h2>\n <Show when={props.subtitle}>\n <p>{props.subtitle}</p>\n </Show>\n </div>\n <Show when={props.actions}>\n <div class=\"k2b-settings-section__actions\">{props.actions}</div>\n </Show>\n </header>\n <div class=\"k2b-settings-section__body\">{props.children}</div>\n </section>\n );\n}\n\nconst SETTINGS_GROUP_ACTION = Symbol(\"SettingsGroup.Action\");\n\nexport type SettingsGroupProps = {\n title: JSX.Element;\n description?: JSX.Element;\n children: JSX.Element;\n class?: string;\n};\n\nexport type SettingsGroupActionProps = {\n children: JSX.Element;\n};\n\ntype SettingsGroupActionDefinition = {\n readonly kind: typeof SETTINGS_GROUP_ACTION;\n readonly props: SettingsGroupActionProps;\n};\n\ntype SettingsGroupComponent = ((props: SettingsGroupProps) => JSX.Element) & {\n Action: (props: SettingsGroupActionProps) => JSX.Element;\n};\n\nconst SettingsGroupAction = (props: SettingsGroupActionProps): JSX.Element =>\n ({ kind: SETTINGS_GROUP_ACTION, props }) satisfies SettingsGroupActionDefinition as unknown as JSX.Element;\n\nconst collectSettingsGroupActions = (value: unknown): SettingsGroupActionDefinition[] => {\n if (Array.isArray(value)) return value.flatMap(collectSettingsGroupActions);\n return value && typeof value === \"object\" && (value as { kind?: unknown }).kind === SETTINGS_GROUP_ACTION\n ? [value as SettingsGroupActionDefinition]\n : [];\n};\n\nconst collectSettingsGroupContent = (value: unknown): JSX.Element[] => {\n if (Array.isArray(value)) return value.flatMap(collectSettingsGroupContent);\n return value && typeof value === \"object\" && (value as { kind?: unknown }).kind === SETTINGS_GROUP_ACTION ? [] : [value as JSX.Element];\n};\n\nexport const SettingsGroup = ((props: SettingsGroupProps): JSX.Element => {\n const resolved = children(() => props.children);\n const action = createMemo(() => collectSettingsGroupActions(resolved())[0]);\n const content = createMemo(() => collectSettingsGroupContent(resolved()));\n const headingId = `k2b-settings-group-${createUniqueId()}`;\n return (\n <section class={`k2b-settings-group${props.class ? ` ${props.class}` : \"\"}`} aria-labelledby={headingId}>\n <header class=\"k2b-settings-group__header\">\n <div class=\"k2b-settings-group__heading\">\n <h3 id={headingId}>{props.title}</h3>\n <Show when={props.description}>\n <p>{props.description}</p>\n </Show>\n </div>\n <Show when={action()}>{(slot) => <div class=\"k2b-settings-group__action\">{slot().props.children}</div>}</Show>\n </header>\n <div class=\"k2b-settings-group__body\">{content()}</div>\n </section>\n );\n}) as SettingsGroupComponent;\n\nSettingsGroup.Action = SettingsGroupAction;\n\nexport const sameSettingValue = (left: unknown, right: unknown): boolean => JSON.stringify(left) === JSON.stringify(right);\n\nexport const readSettingsError = async (\n response: Pick<Response, \"json\">,\n fallback: string,\n): Promise<{ message: string; fields: Record<string, string> }> => {\n const data = (await response.json().catch(() => null)) as {\n message?: string;\n errors?: Record<string, string>;\n } | null;\n return { message: data?.message ?? fallback, fields: data?.errors ?? {} };\n};\n\nexport type SettingsFieldProps = {\n label: string;\n description: string;\n error: MaybeAccessor<string | undefined>;\n changed?: MaybeAccessor<boolean>;\n children: JSX.Element | ((control: SettingsFieldControlProps) => JSX.Element);\n class?: string;\n};\n\nexport type SettingsFieldControlProps = {\n describedBy: () => string;\n};\n\nexport function SettingsField(props: SettingsFieldProps): JSX.Element {\n const settingsMessages = useSettingsMessages();\n const id = createUniqueId();\n const descriptionId = `k2b-settings-field-${id}-description`;\n const errorId = `k2b-settings-field-${id}-error`;\n const describedBy = () => (read(props.error) ? `${descriptionId} ${errorId}` : descriptionId);\n const control = () =>\n typeof props.children === \"function\"\n ? (props.children as (control: SettingsFieldControlProps) => JSX.Element)({ describedBy })\n : props.children;\n return (\n <div class={`k2b-settings-field ${props.class ?? \"\"}`}>\n <div class=\"k2b-settings-field__copy\">\n <div class=\"k2b-settings-field__heading\">\n <strong>{props.label}</strong>\n <Show when={props.changed !== undefined && read(props.changed)}>\n <span>{settingsMessages().unsaved}</span>\n </Show>\n </div>\n <p id={descriptionId}>{props.description}</p>\n </div>\n {control()}\n <Show when={read(props.error)}>\n {(error) => (\n <p id={errorId} class=\"k2b-settings-field__error\" role=\"alert\">\n <i class=\"ti ti-alert-circle\" aria-hidden=\"true\" /> {error()}\n </p>\n )}\n </Show>\n </div>\n );\n}\n\nexport type SettingsSaveBarProps = {\n changeCount: MaybeAccessor<number>;\n loading: MaybeAccessor<boolean>;\n saveDisabled?: MaybeAccessor<boolean>;\n onDiscard: () => void;\n onSave: () => void;\n saveLabel?: string;\n saveVariant?: ButtonVariant;\n class?: string;\n};\n\nconst SettingsActions = (\n props: SettingsSaveBarProps & {\n disableWithoutChanges?: boolean;\n },\n): JSX.Element => {\n const promptMessages = usePromptMessages();\n const settingsMessages = useSettingsMessages();\n const changeCount = () => read(props.changeCount);\n const loading = () => read(props.loading);\n const disabled = () => loading() || Boolean(props.disableWithoutChanges && changeCount() === 0);\n const saveDisabled = () => disabled() || Boolean(props.saveDisabled !== undefined && read(props.saveDisabled));\n return (\n <div class=\"k2b-settings-actions\">\n <Button variant=\"secondary\" disabled={disabled()} onClick={props.onDiscard}>\n {promptMessages().discard}\n </Button>\n <Button\n variant={props.saveVariant ?? \"primary\"}\n loading={loading()}\n loadingLabel={settingsMessages().saving}\n disabled={saveDisabled()}\n onClick={props.onSave}\n >\n <i class=\"ti ti-device-floppy\" aria-hidden=\"true\" />\n {props.saveLabel ?? settingsMessages().saveChanges}\n </Button>\n </div>\n );\n};\n\nexport function SettingsSaveBar(props: SettingsSaveBarProps): JSX.Element {\n const settingsMessages = useSettingsMessages();\n const changeCount = () => read(props.changeCount);\n return (\n <Show when={changeCount() > 0}>\n <div class={`k2b-settings-save-bar ${props.class ?? \"\"}`}>\n <p role=\"status\" aria-live=\"polite\">\n <strong>{changeCount()}</strong> {settingsMessages().unsavedChangeLabel({ count: changeCount() })}\n </p>\n <SettingsActions {...props} />\n </div>\n </Show>\n );\n}\n\nexport type SettingsPanelFooterProps = SettingsSaveBarProps;\n\nexport function SettingsPanelFooter(props: SettingsPanelFooterProps): JSX.Element {\n const settingsMessages = useSettingsMessages();\n const changeCount = () => read(props.changeCount);\n return (\n <>\n <p class=\"k2b-settings-panel-footer__status\" role=\"status\" aria-live=\"polite\">\n <Show when={changeCount() > 0} fallback={settingsMessages().noUnsavedChanges}>\n <strong>{changeCount()}</strong> {settingsMessages().unsavedChangeLabel({ count: changeCount() })}\n </Show>\n </p>\n <SettingsActions {...props} disableWithoutChanges />\n </>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["layout/Settings.tsx"],"sourcesContent":["import { children, createMemo, createUniqueId, type JSX, Show } from \"solid-js\";\nimport { Button, type ButtonVariant } from \"../actions/Button\";\nimport { usePromptMessages } from \"../feedback/prompt-messages\";\nimport type { MaybeAccessor } from \"../inputs/field-contract\";\nimport { useSettingsMessages } from \"./settings-messages\";\n\nconst read = <T,>(value: MaybeAccessor<T>): T => (typeof value === \"function\" ? (value as () => T)() : value);\n\nexport type SettingsPageProps = {\n title: JSX.Element;\n /** False when a surrounding head already shows the title, such as a workspace level; the actions move to the footer. */\n header?: boolean;\n subtitle?: JSX.Element;\n icon?: string;\n actions?: JSX.Element;\n children: JSX.Element;\n footer?: JSX.Element;\n scrollPreserveKey?: string;\n class?: string;\n style?: JSX.CSSProperties | string;\n};\n\nexport function SettingsPage(props: SettingsPageProps): JSX.Element {\n return (\n <section\n class={`k2b-settings-page${props.class ? ` ${props.class}` : \"\"}`}\n style={props.style}\n aria-label={props.header === false && typeof props.title === \"string\" ? props.title : undefined}\n >\n <Show when={props.header !== false}>\n <header class=\"k2b-settings-page__header\">\n <Show when={props.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n <div class=\"k2b-settings-page__heading\">\n <h1>{props.title}</h1>\n <Show when={props.subtitle}>\n <p>{props.subtitle}</p>\n </Show>\n </div>\n <Show when={props.actions}>\n <div class=\"k2b-settings-page__actions\">{props.actions}</div>\n </Show>\n </header>\n </Show>\n <div class=\"k2b-settings-page__body\" data-scroll-preserve={props.scrollPreserveKey}>\n {props.children}\n </div>\n <Show when={props.footer}>\n <footer class=\"k2b-settings-page__footer\">{props.footer}</footer>\n </Show>\n </section>\n );\n}\n\nexport type SettingsSectionProps = {\n title: JSX.Element;\n subtitle?: JSX.Element;\n icon?: string;\n actions?: JSX.Element;\n children: JSX.Element;\n class?: string;\n};\n\n/**\n * A full-page settings group: a heading, optional actions and its fields on the\n * page surface without a card. Dialogs keep using PanelDialog.Section.\n */\nexport function SettingsSection(props: SettingsSectionProps): JSX.Element {\n const headingId = `k2b-settings-section-${createUniqueId()}`;\n return (\n <section class={`k2b-settings-section${props.class ? ` ${props.class}` : \"\"}`} aria-labelledby={headingId}>\n <header class=\"k2b-settings-section__header\">\n <Show when={props.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n <div class=\"k2b-settings-section__heading\">\n <h2 id={headingId}>{props.title}</h2>\n <Show when={props.subtitle}>\n <p>{props.subtitle}</p>\n </Show>\n </div>\n <Show when={props.actions}>\n <div class=\"k2b-settings-section__actions\">{props.actions}</div>\n </Show>\n </header>\n <div class=\"k2b-settings-section__body\">{props.children}</div>\n </section>\n );\n}\n\nconst SETTINGS_GROUP_ACTION = Symbol(\"SettingsGroup.Action\");\n\nexport type SettingsGroupProps = {\n title: JSX.Element;\n description?: JSX.Element;\n children: JSX.Element;\n class?: string;\n};\n\nexport type SettingsGroupActionProps = {\n children: JSX.Element;\n};\n\ntype SettingsGroupActionDefinition = {\n readonly kind: typeof SETTINGS_GROUP_ACTION;\n readonly props: SettingsGroupActionProps;\n};\n\ntype SettingsGroupComponent = ((props: SettingsGroupProps) => JSX.Element) & {\n Action: (props: SettingsGroupActionProps) => JSX.Element;\n};\n\nconst SettingsGroupAction = (props: SettingsGroupActionProps): JSX.Element =>\n ({ kind: SETTINGS_GROUP_ACTION, props }) satisfies SettingsGroupActionDefinition as unknown as JSX.Element;\n\nconst collectSettingsGroupActions = (value: unknown): SettingsGroupActionDefinition[] => {\n if (Array.isArray(value)) return value.flatMap(collectSettingsGroupActions);\n return value && typeof value === \"object\" && (value as { kind?: unknown }).kind === SETTINGS_GROUP_ACTION\n ? [value as SettingsGroupActionDefinition]\n : [];\n};\n\nconst collectSettingsGroupContent = (value: unknown): JSX.Element[] => {\n if (Array.isArray(value)) return value.flatMap(collectSettingsGroupContent);\n return value && typeof value === \"object\" && (value as { kind?: unknown }).kind === SETTINGS_GROUP_ACTION ? [] : [value as JSX.Element];\n};\n\nexport const SettingsGroup = ((props: SettingsGroupProps): JSX.Element => {\n const resolved = children(() => props.children);\n const action = createMemo(() => collectSettingsGroupActions(resolved())[0]);\n const content = createMemo(() => collectSettingsGroupContent(resolved()));\n const headingId = `k2b-settings-group-${createUniqueId()}`;\n return (\n <section class={`k2b-settings-group${props.class ? ` ${props.class}` : \"\"}`} aria-labelledby={headingId}>\n <header class=\"k2b-settings-group__header\">\n <div class=\"k2b-settings-group__heading\">\n <h3 id={headingId}>{props.title}</h3>\n <Show when={props.description}>\n <p>{props.description}</p>\n </Show>\n </div>\n <Show when={action()}>{(slot) => <div class=\"k2b-settings-group__action\">{slot().props.children}</div>}</Show>\n </header>\n <div class=\"k2b-settings-group__body\">{content()}</div>\n </section>\n );\n}) as SettingsGroupComponent;\n\nSettingsGroup.Action = SettingsGroupAction;\n\nexport const sameSettingValue = (left: unknown, right: unknown): boolean => JSON.stringify(left) === JSON.stringify(right);\n\nexport const readSettingsError = async (\n response: Pick<Response, \"json\">,\n fallback: string,\n): Promise<{ message: string; fields: Record<string, string> }> => {\n const data = (await response.json().catch(() => null)) as {\n message?: string;\n errors?: Record<string, string>;\n } | null;\n return { message: data?.message ?? fallback, fields: data?.errors ?? {} };\n};\n\nexport type SettingsFieldProps = {\n label: string;\n description: string;\n error: MaybeAccessor<string | undefined>;\n changed?: MaybeAccessor<boolean>;\n children: JSX.Element | ((control: SettingsFieldControlProps) => JSX.Element);\n class?: string;\n};\n\nexport type SettingsFieldControlProps = {\n describedBy: () => string;\n};\n\nexport function SettingsField(props: SettingsFieldProps): JSX.Element {\n const settingsMessages = useSettingsMessages();\n const id = createUniqueId();\n const descriptionId = `k2b-settings-field-${id}-description`;\n const errorId = `k2b-settings-field-${id}-error`;\n const describedBy = () => (read(props.error) ? `${descriptionId} ${errorId}` : descriptionId);\n const control = () =>\n typeof props.children === \"function\"\n ? (props.children as (control: SettingsFieldControlProps) => JSX.Element)({ describedBy })\n : props.children;\n return (\n <div class={`k2b-settings-field ${props.class ?? \"\"}`}>\n <div class=\"k2b-settings-field__copy\">\n <div class=\"k2b-settings-field__heading\">\n <strong>{props.label}</strong>\n <Show when={props.changed !== undefined && read(props.changed)}>\n <span>{settingsMessages().unsaved}</span>\n </Show>\n </div>\n <p id={descriptionId}>{props.description}</p>\n </div>\n {control()}\n <Show when={read(props.error)}>\n {(error) => (\n <p id={errorId} class=\"k2b-settings-field__error\" role=\"alert\">\n <i class=\"ti ti-alert-circle\" aria-hidden=\"true\" /> {error()}\n </p>\n )}\n </Show>\n </div>\n );\n}\n\nexport type SettingsSaveBarProps = {\n changeCount: MaybeAccessor<number>;\n loading: MaybeAccessor<boolean>;\n saveDisabled?: MaybeAccessor<boolean>;\n onDiscard: () => void;\n onSave: () => void;\n saveLabel?: string;\n saveVariant?: ButtonVariant;\n class?: string;\n};\n\nconst SettingsActions = (\n props: SettingsSaveBarProps & {\n disableWithoutChanges?: boolean;\n },\n): JSX.Element => {\n const promptMessages = usePromptMessages();\n const settingsMessages = useSettingsMessages();\n const changeCount = () => read(props.changeCount);\n const loading = () => read(props.loading);\n const disabled = () => loading() || Boolean(props.disableWithoutChanges && changeCount() === 0);\n const saveDisabled = () => disabled() || Boolean(props.saveDisabled !== undefined && read(props.saveDisabled));\n return (\n <div class=\"k2b-settings-actions\">\n <Button variant=\"secondary\" disabled={disabled()} onClick={props.onDiscard}>\n {promptMessages().discard}\n </Button>\n <Button\n variant={props.saveVariant ?? \"primary\"}\n loading={loading()}\n loadingLabel={settingsMessages().saving}\n disabled={saveDisabled()}\n onClick={props.onSave}\n >\n <i class=\"ti ti-device-floppy\" aria-hidden=\"true\" />\n {props.saveLabel ?? settingsMessages().saveChanges}\n </Button>\n </div>\n );\n};\n\nexport function SettingsSaveBar(props: SettingsSaveBarProps): JSX.Element {\n const settingsMessages = useSettingsMessages();\n const changeCount = () => read(props.changeCount);\n return (\n <Show when={changeCount() > 0}>\n <div class={`k2b-settings-save-bar ${props.class ?? \"\"}`}>\n <p role=\"status\" aria-live=\"polite\">\n <strong>{changeCount()}</strong> {settingsMessages().unsavedChangeLabel({ count: changeCount() })}\n </p>\n <SettingsActions {...props} />\n </div>\n </Show>\n );\n}\n\nexport type SettingsPanelFooterProps = SettingsSaveBarProps;\n\nexport function SettingsPanelFooter(props: SettingsPanelFooterProps): JSX.Element {\n const settingsMessages = useSettingsMessages();\n const changeCount = () => read(props.changeCount);\n return (\n <>\n <p class=\"k2b-settings-panel-footer__status\" role=\"status\" aria-live=\"polite\">\n <Show when={changeCount() > 0} fallback={settingsMessages().noUnsavedChanges}>\n <strong>{changeCount()}</strong> {settingsMessages().unsavedChangeLabel({ count: changeCount() })}\n </Show>\n </p>\n <SettingsActions {...props} disableWithoutChanges />\n </>\n );\n}\n\nexport type SaveStatusState = \"saved\" | \"draft\" | \"saving\" | \"failed\" | \"invalid\" | \"unknown\" | \"readonly\";\n\nexport type SaveStatusProps = {\n /** What the person's values are now: saved, a draft with changes, being saved, or a problem that kept them unsaved. */\n state: MaybeAccessor<SaveStatusState>;\n /** Formatted time of the last save, shown with `saved`. */\n savedAt?: MaybeAccessor<string | undefined>;\n /** Fields to check, shown with `invalid`. Default 1. */\n invalidCount?: MaybeAccessor<number>;\n /** With both handlers, Discard and Save follow the status while there is something to save. */\n onDiscard?: () => void;\n onSave?: () => void;\n saveLabel?: string;\n saveDisabled?: MaybeAccessor<boolean>;\n class?: string;\n};\n\nconst SAVE_STATUS_ICON: Record<SaveStatusState, string> = {\n saved: \"ti ti-check\",\n draft: \"ti ti-pencil\",\n saving: \"ti ti-loader-2\",\n failed: \"ti ti-alert-triangle\",\n invalid: \"ti ti-alert-triangle\",\n unknown: \"ti ti-help-circle\",\n readonly: \"ti ti-lock\",\n};\n\n/**\n * The save status of a settings form at one fixed place, usually the head of its column. It reserves its width, so\n * a change of state never moves the title or the buttons beside it. Problems with one field stay at that field.\n */\nexport function SaveStatus(props: SaveStatusProps): JSX.Element {\n const settingsMessages = useSettingsMessages();\n const state = () => read(props.state);\n const text = () => {\n const t = settingsMessages();\n switch (state()) {\n case \"saved\": {\n const at = props.savedAt === undefined ? undefined : read(props.savedAt);\n return at ? t.statusSavedAt({ time: at }) : t.statusSaved;\n }\n case \"draft\":\n return t.statusDraft;\n case \"saving\":\n return t.saving;\n case \"failed\":\n return t.statusFailed;\n case \"invalid\":\n return t.statusInvalid({ count: props.invalidCount === undefined ? 1 : read(props.invalidCount) });\n case \"unknown\":\n return t.statusUnknown;\n case \"readonly\":\n return t.statusReadOnly;\n }\n };\n const hasActions = () => Boolean(props.onSave && props.onDiscard) && state() !== \"readonly\";\n const pending = () => state() === \"draft\" || state() === \"failed\" || state() === \"invalid\" || state() === \"saving\";\n return (\n <div class={`k2b-save-status ${props.class ?? \"\"}`}>\n <span class=\"k2b-save-status__slot\">\n <span class=\"k2b-save-status__state\" data-state={state()} role=\"status\" aria-live=\"polite\">\n <i class={`${SAVE_STATUS_ICON[state()]}${state() === \"saving\" ? \" k2b-spin\" : \"\"}`} aria-hidden=\"true\" />\n {text()}\n </span>\n </span>\n <Show when={hasActions()}>\n <SettingsActions\n changeCount={() => (pending() ? 1 : 0)}\n loading={() => state() === \"saving\"}\n saveDisabled={() => state() === \"invalid\" || Boolean(props.saveDisabled !== undefined && read(props.saveDisabled))}\n onDiscard={props.onDiscard!}\n onSave={props.onSave!}\n saveLabel={props.saveLabel ?? settingsMessages().save}\n disableWithoutChanges\n />\n </Show>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,79 @@
1
+ import { createComponent as _$createComponent } from "solid-js/web";
2
+ import { memo as _$memo } from "solid-js/web";
3
+ import { createSignal, onCleanup, onMount, Show } from "solid-js";
4
+ import { Tooltip } from "../feedback/Tooltip";
5
+
6
+ /**
7
+ * True while `element` sits in the collapsed sidebar rail, which shows icons
8
+ * without labels. The stylesheet sets `--k2b-sidebar-rail` exactly where it
9
+ * collapses the sidebar, so this follows the same container width and state.
10
+ */
11
+ export const inSidebarRail = element => element?.isConnected === true && getComputedStyle(element).getPropertyValue("--k2b-sidebar-rail").trim() === "1";
12
+
13
+ /** True while a label fades out because it does not fit. */
14
+ const clipped = element => Boolean(element && (element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth));
15
+
16
+ /**
17
+ * A sidebar entry's name, or its `title`, in the hint the Cloud app rail uses.
18
+ * In the collapsed rail it names the icon beside it at once. Elsewhere it
19
+ * shows above the entry with the usual delay, and only when it says more than
20
+ * the visible label: a label cut off, or a title with details. A native
21
+ * `title` on `target` gives way to it, so no hint shows twice.
22
+ */
23
+ export function SidebarRailHint(props) {
24
+ const needed = () => {
25
+ const target = props.target();
26
+ if (inSidebarRail(target)) return true;
27
+ const visible = target?.querySelector(props.labelSelector);
28
+ return clipped(visible) || (visible?.textContent?.trim() ?? "") !== props.label?.trim();
29
+ };
30
+ // A long sidebar carries no hint for entries nobody points at: the hint
31
+ // mounts on the first hover or focus that needs it (or that would show a
32
+ // native title), before the tooltip's own pointerenter and focusin
33
+ // listeners see that same gesture. `target` must stay the same element;
34
+ // key the hint to it when the element can change.
35
+ const [armed, setArmed] = createSignal(false);
36
+ onMount(() => {
37
+ const target = props.target();
38
+ const focusHost = props.focusTarget?.() ?? target;
39
+ if (!target || !focusHost) return;
40
+ const arm = event => {
41
+ if (armed() || event.pointerType === "touch") return;
42
+ if (!props.titled && !needed()) return;
43
+ setArmed(true);
44
+ props.onArm?.();
45
+ };
46
+ target.addEventListener("pointerover", arm);
47
+ focusHost.addEventListener("focus", arm);
48
+ onCleanup(() => {
49
+ target.removeEventListener("pointerover", arm);
50
+ focusHost.removeEventListener("focus", arm);
51
+ });
52
+ });
53
+ return _$createComponent(Show, {
54
+ get when() {
55
+ return _$memo(() => !!armed())() && props.label;
56
+ },
57
+ children: label => _$createComponent(Tooltip, {
58
+ get target() {
59
+ return props.target;
60
+ },
61
+ get focusTarget() {
62
+ return props.focusTarget;
63
+ },
64
+ get content() {
65
+ return label();
66
+ },
67
+ get placement() {
68
+ return inSidebarRail(props.target()) ? "right" : "top";
69
+ },
70
+ get delay() {
71
+ return inSidebarRail(props.target()) ? 0 : undefined;
72
+ },
73
+ get disabled() {
74
+ return !needed();
75
+ }
76
+ })
77
+ });
78
+ }
79
+ //# sourceMappingURL=SidebarRailHint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["layout/SidebarRailHint.tsx"],"sourcesContent":["import { createSignal, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { Tooltip } from \"../feedback/Tooltip\";\n\n/**\n * True while `element` sits in the collapsed sidebar rail, which shows icons\n * without labels. The stylesheet sets `--k2b-sidebar-rail` exactly where it\n * collapses the sidebar, so this follows the same container width and state.\n */\nexport const inSidebarRail = (element: Element | undefined): boolean =>\n element?.isConnected === true && getComputedStyle(element).getPropertyValue(\"--k2b-sidebar-rail\").trim() === \"1\";\n\n/** True while a label fades out because it does not fit. */\nconst clipped = (element: Element | null | undefined): boolean =>\n Boolean(element && (element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth));\n\n/**\n * A sidebar entry's name, or its `title`, in the hint the Cloud app rail uses.\n * In the collapsed rail it names the icon beside it at once. Elsewhere it\n * shows above the entry with the usual delay, and only when it says more than\n * the visible label: a label cut off, or a title with details. A native\n * `title` on `target` gives way to it, so no hint shows twice.\n */\nexport function SidebarRailHint(props: {\n target: () => HTMLElement | undefined;\n label: string | undefined;\n /** The element that holds keyboard focus for the entry, when that is not `target`. */\n focusTarget?: () => HTMLElement | undefined;\n /** The visible label text inside `target`. */\n labelSelector: string;\n /** The entry renders a native `title`, which the hint replaces from the first hover or focus. */\n titled?: boolean;\n /** Called once the hint takes over; the entry stops rendering its native `title`. */\n onArm?: () => void;\n}): JSX.Element {\n const needed = () => {\n const target = props.target();\n if (inSidebarRail(target)) return true;\n const visible = target?.querySelector(props.labelSelector);\n return clipped(visible) || (visible?.textContent?.trim() ?? \"\") !== props.label?.trim();\n };\n // A long sidebar carries no hint for entries nobody points at: the hint\n // mounts on the first hover or focus that needs it (or that would show a\n // native title), before the tooltip's own pointerenter and focusin\n // listeners see that same gesture. `target` must stay the same element;\n // key the hint to it when the element can change.\n const [armed, setArmed] = createSignal(false);\n onMount(() => {\n const target = props.target();\n const focusHost = props.focusTarget?.() ?? target;\n if (!target || !focusHost) return;\n const arm = (event: Event) => {\n if (armed() || (event as PointerEvent).pointerType === \"touch\") return;\n if (!props.titled && !needed()) return;\n setArmed(true);\n props.onArm?.();\n };\n target.addEventListener(\"pointerover\", arm);\n focusHost.addEventListener(\"focus\", arm);\n onCleanup(() => {\n target.removeEventListener(\"pointerover\", arm);\n focusHost.removeEventListener(\"focus\", arm);\n });\n });\n return (\n <Show when={armed() && props.label}>\n {(label) => (\n <Tooltip\n target={props.target}\n focusTarget={props.focusTarget}\n content={label()}\n placement={inSidebarRail(props.target()) ? \"right\" : \"top\"}\n delay={inSidebarRail(props.target()) ? 0 : undefined}\n disabled={!needed()}\n />\n )}\n </Show>\n );\n}\n"],"mappings":";;AAAA,SAAS,YAAY,EAAY,SAAS,EAAE,OAAO,EAAE,IAAI,QAAQ,UAAU;AAC3E,SAAS,OAAO,QAAQ,qBAAqB;;AAE7C;AACA;AACA;AACA;AACA;AACA,OAAO,MAAM,aAAa,GAAI,OAA4B,IACxD,OAAO,EAAE,WAAW,KAAK,IAAI,IAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG;;AAElH;AACA,MAAM,OAAO,GAAI,OAAmC,IAClD,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;;AAEhH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAAS,eAAe,CAAC,KAW/B,EAAe;EACd,MAAM,MAAM,GAAG,MAAM;IACnB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,IAAI;IACtC,MAAM,OAAO,GAAG,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,aAAa,CAAC;IAC1D,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACzF,CAAC;EACD;EACA;EACA;EACA;EACA;EACA,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC;EAC7C,OAAO,CAAC,MAAM;IACZ,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,GAAG,CAAC,IAAI,MAAM;IACjD,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE;IAC3B,MAAM,GAAG,GAAI,KAAY,IAAK;MAC5B,IAAI,KAAK,CAAC,CAAC,IAAK,KAAK,CAAkB,WAAW,KAAK,OAAO,EAAE;MAChE,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE;MAChC,QAAQ,CAAC,IAAI,CAAC;MACd,KAAK,CAAC,KAAK,GAAG,CAAC;IACjB,CAAC;IACD,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,GAAG,CAAC;IAC3C,SAAS,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,CAAC;IACxC,SAAS,CAAC,MAAM;MACd,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,GAAG,CAAC;MAC9C,SAAS,CAAC,mBAAmB,CAAC,OAAO,EAAE,GAAG,CAAC;IAC7C,CAAC,CAAC;EACJ,CAAC,CAAC;EACF,yBACG,IAAI;IAAA,IAAC,IAAI;MAAA,OAAE,oBAAK,CAAC,CAAC,OAAI,KAAK,CAAC,KAAK;IAAA;IAAA,UAC9B,KAAK,sBACJ,OAAO;MAAA,IACN,MAAM;QAAA,OAAE,KAAK,CAAC,MAAM;MAAA;MAAA,IACpB,WAAW;QAAA,OAAE,KAAK,CAAC,WAAW;MAAA;MAAA,IAC9B,OAAO;QAAA,OAAE,KAAK,CAAC,CAAC;MAAA;MAAA,IAChB,SAAS;QAAA,OAAE,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,KAAK;MAAA;MAAA,IAC1D,KAAK;QAAA,OAAE,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS;MAAA;MAAA,IACpD,QAAQ;QAAA,OAAE,CAAC,MAAM,CAAC,CAAC;MAAA;IAAA;EAEtB;AAGP","ignoreList":[]}
@@ -13,7 +13,7 @@ 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 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><!$><!/>`),
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
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>`),
@@ -30,6 +30,7 @@ import { isServer } from "solid-js/web";
30
30
  import { dropdownPosition } from "../actions/Dropdown";
31
31
  import { returnFocus, ringOnReturn } from "../internal/focus-return";
32
32
  import { useUiMessages } from "../intl/messages";
33
+ import { SidebarRailHint } from "./SidebarRailHint";
33
34
 
34
35
  /** One container a person can switch to, such as a notebook, a space, or a mailbox. */
35
36
 
@@ -58,6 +59,7 @@ export function AppWorkspaceSidebarSwitcher(props) {
58
59
  const [open, setOpen] = createSignal(false);
59
60
  const [query, setQuery] = createSignal("");
60
61
  let trigger;
62
+ const [hinted, setHinted] = createSignal(false);
61
63
  let panel;
62
64
  let search;
63
65
  let keyboardOpened = true;
@@ -226,7 +228,9 @@ export function AppWorkspaceSidebarSwitcher(props) {
226
228
  [_el$8, _co$] = _$getNextMarker(_el$7.nextSibling),
227
229
  _el$9 = _el$5.nextSibling,
228
230
  _el$0 = _el$9.nextSibling,
229
- _el$1 = _el$2.nextSibling,
231
+ _el$19 = _el$2.nextSibling,
232
+ [_el$20, _co$4] = _$getNextMarker(_el$19.nextSibling),
233
+ _el$1 = _el$20.nextSibling,
230
234
  _el$15 = _el$1.firstChild,
231
235
  [_el$16, _co$2] = _$getNextMarker(_el$15.nextSibling),
232
236
  _el$13 = _el$16.nextSibling,
@@ -255,13 +259,22 @@ export function AppWorkspaceSidebarSwitcher(props) {
255
259
  return props.description;
256
260
  },
257
261
  children: description => (() => {
258
- var _el$19 = _$getNextElement(_tmpl$4);
259
- _$insert(_el$19, description);
260
- return _el$19;
262
+ var _el$21 = _$getNextElement(_tmpl$4);
263
+ _$insert(_el$21, description);
264
+ return _el$21;
261
265
  })()
262
266
  }), _el$8, _co$);
263
267
  _$setAttribute(_el$0, "id", `${id}-purpose`);
264
268
  _$insert(_el$0, () => [props.description, props.switchLabel].filter(Boolean).join(", "));
269
+ _$insert(_el$, _$createComponent(SidebarRailHint, {
270
+ target: () => trigger,
271
+ get label() {
272
+ return props.label;
273
+ },
274
+ labelSelector: ".k2b-sidebar-switcher__copy > span",
275
+ titled: true,
276
+ onArm: () => setHinted(true)
277
+ }), _el$20, _co$4);
265
278
  _el$1.addEventListener("toggle", event => {
266
279
  if (event.newState === "open") return;
267
280
  setOpen(false);
@@ -310,32 +323,32 @@ export function AppWorkspaceSidebarSwitcher(props) {
310
323
  },
311
324
  get fallback() {
312
325
  return (() => {
313
- var _el$20 = _$getNextElement(_tmpl$5);
314
- _$insert(_el$20, _$createComponent(Show, {
326
+ var _el$22 = _$getNextElement(_tmpl$5);
327
+ _$insert(_el$22, _$createComponent(Show, {
315
328
  get when() {
316
329
  return props.error;
317
330
  },
318
331
  get fallback() {
319
332
  return [_$getNextElement(_tmpl$6), (() => {
320
- var _el$22 = _$getNextElement(_tmpl$7);
321
- _$insert(_el$22, () => messages().loading);
322
- return _el$22;
333
+ var _el$24 = _$getNextElement(_tmpl$7);
334
+ _$insert(_el$24, () => messages().loading);
335
+ return _el$24;
323
336
  })()];
324
337
  },
325
338
  children: error => [(() => {
326
- var _el$23 = _$getNextElement(_tmpl$7);
327
- _$insert(_el$23, error);
328
- return _el$23;
339
+ var _el$25 = _$getNextElement(_tmpl$7);
340
+ _$insert(_el$25, error);
341
+ return _el$25;
329
342
  })(), (() => {
330
- var _el$24 = _$getNextElement(_tmpl$8);
331
- _el$24.$$click = () => props.onLoad?.();
332
- _$insert(_el$24, () => messages().retry);
343
+ var _el$26 = _$getNextElement(_tmpl$8);
344
+ _el$26.$$click = () => props.onLoad?.();
345
+ _$insert(_el$26, () => messages().retry);
333
346
  _$runHydrationEvents();
334
- return _el$24;
347
+ return _el$26;
335
348
  })()]
336
349
  }));
337
- _$effect(() => _$setAttribute(_el$20, "data-tone", props.error ? "danger" : undefined));
338
- return _el$20;
350
+ _$effect(() => _$setAttribute(_el$22, "data-tone", props.error ? "danger" : undefined));
351
+ return _el$22;
339
352
  })();
340
353
  },
341
354
  get children() {
@@ -345,52 +358,52 @@ export function AppWorkspaceSidebarSwitcher(props) {
345
358
  },
346
359
  get fallback() {
347
360
  return (() => {
348
- var _el$25 = _$getNextElement(_tmpl$5);
349
- _$insert(_el$25, () => messages().noResults);
350
- return _el$25;
361
+ var _el$27 = _$getNextElement(_tmpl$5);
362
+ _$insert(_el$27, () => messages().noResults);
363
+ return _el$27;
351
364
  })();
352
365
  },
353
366
  children: option => {
354
367
  const current = () => option.id === props.currentId;
355
368
  return (() => {
356
- var _el$26 = _$getNextElement(_tmpl$9),
357
- _el$27 = _el$26.firstChild,
358
- _el$28 = _el$27.firstChild,
369
+ var _el$28 = _$getNextElement(_tmpl$9),
359
370
  _el$29 = _el$28.firstChild,
360
- _el$30 = _el$28.nextSibling,
371
+ _el$30 = _el$29.firstChild,
361
372
  _el$31 = _el$30.firstChild,
362
- _el$32 = _el$31.nextSibling,
363
- [_el$33, _co$4] = _$getNextMarker(_el$32.nextSibling),
364
- _el$34 = _el$30.nextSibling;
365
- _el$27.$$click = event => {
373
+ _el$32 = _el$30.nextSibling,
374
+ _el$33 = _el$32.firstChild,
375
+ _el$34 = _el$33.nextSibling,
376
+ [_el$35, _co$5] = _$getNextMarker(_el$34.nextSibling),
377
+ _el$36 = _el$32.nextSibling;
378
+ _el$29.$$click = event => {
366
379
  // The open container is already here: choosing it only closes the panel.
367
380
  if (current() && plainClick(event)) {
368
381
  event.preventDefault();
369
382
  hide(true);
370
383
  } else follow(event);
371
384
  };
372
- _$insert(_el$31, () => option.label);
373
- _$insert(_el$30, _$createComponent(Show, {
385
+ _$insert(_el$33, () => option.label);
386
+ _$insert(_el$32, _$createComponent(Show, {
374
387
  get when() {
375
388
  return option.description;
376
389
  },
377
390
  children: description => (() => {
378
- var _el$35 = _$getNextElement(_tmpl$0);
379
- _$insert(_el$35, description);
380
- return _el$35;
391
+ var _el$37 = _$getNextElement(_tmpl$0);
392
+ _$insert(_el$37, description);
393
+ return _el$37;
381
394
  })()
382
- }), _el$33, _co$4);
395
+ }), _el$35, _co$5);
383
396
  _$effect(_p$ => {
384
397
  var _v$1 = option.href,
385
398
  _v$10 = current() ? "true" : undefined,
386
399
  _v$11 = tint(option.color ?? props.color),
387
400
  _v$12 = iconClass(option.icon ?? props.icon),
388
401
  _v$13 = current() ? undefined : "true";
389
- _v$1 !== _p$.e && _$setAttribute(_el$27, "href", _p$.e = _v$1);
390
- _v$10 !== _p$.t && _$setAttribute(_el$27, "aria-current", _p$.t = _v$10);
391
- _p$.a = _$style(_el$28, _v$11, _p$.a);
392
- _v$12 !== _p$.o && _$className(_el$29, _p$.o = _v$12);
393
- _v$13 !== _p$.i && _$setAttribute(_el$34, "data-hidden", _p$.i = _v$13);
402
+ _v$1 !== _p$.e && _$setAttribute(_el$29, "href", _p$.e = _v$1);
403
+ _v$10 !== _p$.t && _$setAttribute(_el$29, "aria-current", _p$.t = _v$10);
404
+ _p$.a = _$style(_el$30, _v$11, _p$.a);
405
+ _v$12 !== _p$.o && _$className(_el$31, _p$.o = _v$12);
406
+ _v$13 !== _p$.i && _$setAttribute(_el$36, "data-hidden", _p$.i = _v$13);
394
407
  return _p$;
395
408
  }, {
396
409
  e: undefined,
@@ -400,7 +413,7 @@ export function AppWorkspaceSidebarSwitcher(props) {
400
413
  i: undefined
401
414
  });
402
415
  _$runHydrationEvents();
403
- return _el$26;
416
+ return _el$28;
404
417
  })();
405
418
  }
406
419
  });
@@ -417,26 +430,26 @@ export function AppWorkspaceSidebarSwitcher(props) {
417
430
  return props.actions;
418
431
  },
419
432
  children: item => (() => {
420
- var _el$36 = _$getNextElement(_tmpl$1);
421
- _$insert(_el$36, _$createComponent(Show, {
433
+ var _el$38 = _$getNextElement(_tmpl$1);
434
+ _$insert(_el$38, _$createComponent(Show, {
422
435
  get when() {
423
436
  return item.href;
424
437
  },
425
438
  get fallback() {
426
439
  return (() => {
427
- var _el$37 = _$getNextElement(_tmpl$10),
428
- _el$38 = _el$37.firstChild,
429
- _el$39 = _el$38.nextSibling,
430
- _el$40 = _el$39.firstChild;
431
- _el$37.$$click = () => choose(() => item.action?.());
432
- _$insert(_el$40, () => item.label);
440
+ var _el$39 = _$getNextElement(_tmpl$10),
441
+ _el$40 = _el$39.firstChild,
442
+ _el$41 = _el$40.nextSibling,
443
+ _el$42 = _el$41.firstChild;
444
+ _el$39.$$click = () => choose(() => item.action?.());
445
+ _$insert(_el$42, () => item.label);
433
446
  _$effect(_p$ => {
434
447
  var _v$14 = item.disabled,
435
448
  _v$15 = item.disabled ? "true" : undefined,
436
449
  _v$16 = iconClass(item.icon);
437
- _v$14 !== _p$.e && _$setProperty(_el$37, "disabled", _p$.e = _v$14);
438
- _v$15 !== _p$.t && _$setAttribute(_el$37, "aria-disabled", _p$.t = _v$15);
439
- _v$16 !== _p$.a && _$className(_el$38, _p$.a = _v$16);
450
+ _v$14 !== _p$.e && _$setProperty(_el$39, "disabled", _p$.e = _v$14);
451
+ _v$15 !== _p$.t && _$setAttribute(_el$39, "aria-disabled", _p$.t = _v$15);
452
+ _v$16 !== _p$.a && _$className(_el$40, _p$.a = _v$16);
440
453
  return _p$;
441
454
  }, {
442
455
  e: undefined,
@@ -444,23 +457,23 @@ export function AppWorkspaceSidebarSwitcher(props) {
444
457
  a: undefined
445
458
  });
446
459
  _$runHydrationEvents();
447
- return _el$37;
460
+ return _el$39;
448
461
  })();
449
462
  },
450
463
  children: href => (() => {
451
- var _el$41 = _$getNextElement(_tmpl$11),
452
- _el$42 = _el$41.firstChild,
453
- _el$43 = _el$42.nextSibling,
454
- _el$44 = _el$43.firstChild;
455
- _el$41.$$click = event => item.disabled || follow(event);
456
- _$insert(_el$44, () => item.label);
464
+ var _el$43 = _$getNextElement(_tmpl$11),
465
+ _el$44 = _el$43.firstChild,
466
+ _el$45 = _el$44.nextSibling,
467
+ _el$46 = _el$45.firstChild;
468
+ _el$43.$$click = event => item.disabled || follow(event);
469
+ _$insert(_el$46, () => item.label);
457
470
  _$effect(_p$ => {
458
471
  var _v$17 = item.disabled ? undefined : href(),
459
472
  _v$18 = item.disabled ? "true" : undefined,
460
473
  _v$19 = iconClass(item.icon);
461
- _v$17 !== _p$.e && _$setAttribute(_el$41, "href", _p$.e = _v$17);
462
- _v$18 !== _p$.t && _$setAttribute(_el$41, "aria-disabled", _p$.t = _v$18);
463
- _v$19 !== _p$.a && _$className(_el$42, _p$.a = _v$19);
474
+ _v$17 !== _p$.e && _$setAttribute(_el$43, "href", _p$.e = _v$17);
475
+ _v$18 !== _p$.t && _$setAttribute(_el$43, "aria-disabled", _p$.t = _v$18);
476
+ _v$19 !== _p$.a && _$className(_el$44, _p$.a = _v$19);
464
477
  return _p$;
465
478
  }, {
466
479
  e: undefined,
@@ -468,10 +481,10 @@ export function AppWorkspaceSidebarSwitcher(props) {
468
481
  a: undefined
469
482
  });
470
483
  _$runHydrationEvents();
471
- return _el$41;
484
+ return _el$43;
472
485
  })()
473
486
  }));
474
- return _el$36;
487
+ return _el$38;
475
488
  })()
476
489
  }));
477
490
  return _el$14;
@@ -482,7 +495,7 @@ export function AppWorkspaceSidebarSwitcher(props) {
482
495
  _v$4 = props.description ? "" : undefined,
483
496
  _v$5 = props.label,
484
497
  _v$6 = open(),
485
- _v$7 = props.label,
498
+ _v$7 = hinted() ? undefined : props.label,
486
499
  _v$8 = tint(props.color),
487
500
  _v$9 = iconClass(props.icon),
488
501
  _v$0 = props.switchLabel;