bitboss-ui 3.0.0-beta.53 → 3.0.0-beta.57

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 (489) hide show
  1. package/README.md +55 -38
  2. package/bin/bitboss-ui-mcp.mjs +18 -8
  3. package/bin/bitboss-ui.mjs +136 -24
  4. package/dist/ai/BbAccordion.md +119 -178
  5. package/dist/ai/BbAlert.md +44 -14
  6. package/dist/ai/BbAsterisk.md +10 -8
  7. package/dist/ai/BbAvatar.md +14 -29
  8. package/dist/ai/BbBadge.md +36 -21
  9. package/dist/ai/BbBaseButton.md +45 -21
  10. package/dist/ai/BbBaseCheckboxIcon.md +4 -4
  11. package/dist/ai/BbBreadcrumbs.md +2 -2
  12. package/dist/ai/BbButton.md +60 -49
  13. package/dist/ai/BbCalendar.md +29 -13
  14. package/dist/ai/BbCheckbox.md +29 -10
  15. package/dist/ai/BbCheckboxGroup.md +20 -9
  16. package/dist/ai/BbCollapsible.md +5 -4
  17. package/dist/ai/BbColorInput.md +11 -9
  18. package/dist/ai/BbColorPalette.md +1 -1
  19. package/dist/ai/BbConfirm.md +86 -114
  20. package/dist/ai/BbConfirmPortal.md +3 -3
  21. package/dist/ai/BbDatePicker.md +34 -27
  22. package/dist/ai/BbDatePickerInput.md +22 -13
  23. package/dist/ai/BbDialog.md +954 -446
  24. package/dist/ai/BbDropdown.md +15 -7
  25. package/dist/ai/BbDropdownButton.md +4 -4
  26. package/dist/ai/BbDropzone.md +89 -45
  27. package/dist/ai/BbForm.md +45 -25
  28. package/dist/ai/BbHost.md +159 -0
  29. package/dist/ai/BbHoverCard.md +12 -12
  30. package/dist/ai/BbHoverCardPortal.md +4 -4
  31. package/dist/ai/BbIndicator.md +41 -14
  32. package/dist/ai/BbNumberInput.md +9 -7
  33. package/dist/ai/BbOffCanvas.md +489 -291
  34. package/dist/ai/BbPagination.md +5 -4
  35. package/dist/ai/BbPopover.md +24 -18
  36. package/dist/ai/BbPopoverPortal.md +4 -4
  37. package/dist/ai/BbProgress.md +3 -3
  38. package/dist/ai/BbPtScope.md +5 -5
  39. package/dist/ai/BbRadio.md +8 -6
  40. package/dist/ai/BbRadioGroup.md +25 -9
  41. package/dist/ai/BbRating.md +14 -8
  42. package/dist/ai/BbSelect.md +69 -37
  43. package/dist/ai/BbSelectPopover.md +52 -29
  44. package/dist/ai/BbSlider.md +36 -13
  45. package/dist/ai/BbSpinner.md +4 -2
  46. package/dist/ai/BbSwitch.md +10 -8
  47. package/dist/ai/BbSwitchGroup.md +15 -14
  48. package/dist/ai/BbTable.md +13 -8
  49. package/dist/ai/BbTabs.md +43 -33
  50. package/dist/ai/BbTag.md +4 -4
  51. package/dist/ai/BbTextInput.md +31 -5
  52. package/dist/ai/BbTextarea.md +16 -8
  53. package/dist/ai/BbTimePicker.md +29 -14
  54. package/dist/ai/BbTimePickerInput.md +6 -6
  55. package/dist/ai/BbToast.md +109 -205
  56. package/dist/ai/BbToastPortal.md +3 -3
  57. package/dist/ai/BbTooltip.md +14 -13
  58. package/dist/ai/BbTree.md +33 -39
  59. package/dist/ai/CommonField.md +4 -4
  60. package/dist/ai/changelog.json +454 -42
  61. package/dist/ai/components.json +88 -66
  62. package/dist/ai/composables/useBbDialogContext.md +145 -0
  63. package/dist/ai/composables/useBbFormContext.md +10 -7
  64. package/dist/ai/composables/useBbOffCanvasContext.md +65 -0
  65. package/dist/ai/composables/useConfirm.md +25 -25
  66. package/dist/ai/composables/useMobile.md +2 -3
  67. package/dist/ai/composables/useToast.md +24 -24
  68. package/dist/ai/guides/agent-contract.md +9 -9
  69. package/dist/ai/guides/app-layout.md +4 -4
  70. package/dist/ai/guides/component-picker.md +2 -2
  71. package/dist/ai/guides/design-language.md +2 -6
  72. package/dist/ai/guides/design-tokens.md +7 -5
  73. package/dist/ai/guides/eslint-rules.md +69 -0
  74. package/dist/ai/guides/fetch-items-playbook.md +4 -0
  75. package/dist/ai/guides/inertia-helpers.md +188 -130
  76. package/dist/ai/guides/installation-and-plugin-setup.md +100 -97
  77. package/dist/ai/guides/migration/components/bb-collapsible.md +5 -5
  78. package/dist/ai/guides/migration/components/bb-dialog.md +13 -12
  79. package/dist/ai/guides/migration/components/bb-dropzone.md +8 -8
  80. package/dist/ai/guides/migration/components/bb-host.md +41 -0
  81. package/dist/ai/guides/migration/components/bb-offcanvas.md +10 -9
  82. package/dist/ai/guides/migration/components/bb-select-popover.md +2 -2
  83. package/dist/ai/guides/migration/components/bb-select.md +15 -15
  84. package/dist/ai/guides/migration/components/bb-toast.md +23 -17
  85. package/dist/ai/guides/migration/components/bb-tree.md +8 -8
  86. package/dist/ai/guides/migration/components/use-confirm.md +1 -1
  87. package/dist/ai/guides/migration/from-async-validator.md +2 -2
  88. package/dist/ai/guides/migration/v2-to-v3.md +219 -21
  89. package/dist/ai/guides/migration/v3-beta-css-classes.md +11 -0
  90. package/dist/ai/guides/migration/v3-beta-tooling.md +18 -2
  91. package/dist/ai/guides/options-items-playbook.md +8 -1
  92. package/dist/ai/guides/page-shell.md +11 -0
  93. package/dist/ai/guides/passthrough.md +24 -33
  94. package/dist/ai/guides/preset-components.md +32 -5
  95. package/dist/ai/guides/validated-forms.md +50 -27
  96. package/dist/ai/helpers/definePreset.json +26 -0
  97. package/dist/ai/helpers/definePreset.ts +234 -0
  98. package/dist/ai/helpers/inertia/manifest.json +21 -13
  99. package/dist/ai/helpers/inertia/types.ts +18 -7
  100. package/dist/ai/helpers/inertia/useConfirmOnRouteLeave.ts +13 -8
  101. package/dist/ai/helpers/inertia/usePaginatedResponseContext.ts +39 -18
  102. package/dist/ai/helpers/inertia/useQueryObject.ts +68 -33
  103. package/dist/ai/index.md +18 -13
  104. package/dist/ai/manifest/components/BbAccordion.json +6 -2
  105. package/dist/ai/manifest/components/BbAccordion.tree.json +13 -3
  106. package/dist/ai/manifest/components/BbAlert.json +4 -3
  107. package/dist/ai/manifest/components/BbAlert.tree.json +3 -3
  108. package/dist/ai/manifest/components/BbBaseButton.json +1 -1
  109. package/dist/ai/manifest/components/BbBaseCheckboxIcon.tree.json +4 -4
  110. package/dist/ai/manifest/components/BbBreadcrumbs.tree.json +1 -1
  111. package/dist/ai/manifest/components/BbButton.json +1 -1
  112. package/dist/ai/manifest/components/BbCalendar.json +2 -2
  113. package/dist/ai/manifest/components/BbCheckbox.json +4 -3
  114. package/dist/ai/manifest/components/BbCheckbox.tree.json +3 -2
  115. package/dist/ai/manifest/components/BbCheckboxGroup.json +4 -3
  116. package/dist/ai/manifest/components/BbCheckboxGroup.tree.json +4 -1
  117. package/dist/ai/manifest/components/BbCollapsible.json +1 -1
  118. package/dist/ai/manifest/components/BbColorInput.json +5 -4
  119. package/dist/ai/manifest/components/BbColorInput.tree.json +1 -1
  120. package/dist/ai/manifest/components/BbColorPalette.json +1 -1
  121. package/dist/ai/manifest/components/BbColorPalette.tree.json +1 -1
  122. package/dist/ai/manifest/components/BbConfirm.json +3 -4
  123. package/dist/ai/manifest/components/BbConfirm.tree.json +1 -1
  124. package/dist/ai/manifest/components/BbConfirmPortal.json +3 -3
  125. package/dist/ai/manifest/components/BbDatePicker.json +4 -4
  126. package/dist/ai/manifest/components/BbDatePicker.tree.json +1 -1
  127. package/dist/ai/manifest/components/BbDatePickerInput.json +7 -6
  128. package/dist/ai/manifest/components/BbDatePickerInput.tree.json +1 -1
  129. package/dist/ai/manifest/components/BbDialog.json +22 -12
  130. package/dist/ai/manifest/components/BbDialog.tree.json +4 -2
  131. package/dist/ai/manifest/components/BbDropdown.json +2 -2
  132. package/dist/ai/manifest/components/BbDropdown.tree.json +1 -1
  133. package/dist/ai/manifest/components/BbDropdownButton.json +2 -2
  134. package/dist/ai/manifest/components/BbDropdownButton.tree.json +1 -1
  135. package/dist/ai/manifest/components/BbDropzone.json +2 -2
  136. package/dist/ai/manifest/components/BbHost.json +14 -0
  137. package/dist/ai/manifest/components/BbHost.tree.json +9 -0
  138. package/dist/ai/manifest/components/BbHoverCardPortal.json +3 -3
  139. package/dist/ai/manifest/components/BbNumberInput.json +5 -4
  140. package/dist/ai/manifest/components/BbOffCanvas.json +22 -12
  141. package/dist/ai/manifest/components/BbOffCanvas.tree.json +13 -1
  142. package/dist/ai/manifest/components/BbPopover.json +1 -1
  143. package/dist/ai/manifest/components/BbPopover.tree.json +1 -1
  144. package/dist/ai/manifest/components/BbPopoverPortal.json +3 -3
  145. package/dist/ai/manifest/components/BbProgress.json +1 -1
  146. package/dist/ai/manifest/components/BbRadio.json +5 -4
  147. package/dist/ai/manifest/components/BbRadio.tree.json +2 -1
  148. package/dist/ai/manifest/components/BbRadioGroup.json +4 -3
  149. package/dist/ai/manifest/components/BbRadioGroup.tree.json +3 -0
  150. package/dist/ai/manifest/components/BbRating.json +4 -3
  151. package/dist/ai/manifest/components/BbRating.tree.json +2 -0
  152. package/dist/ai/manifest/components/BbSelect.json +6 -5
  153. package/dist/ai/manifest/components/BbSelect.tree.json +1 -1
  154. package/dist/ai/manifest/components/BbSelectPopover.json +2 -2
  155. package/dist/ai/manifest/components/BbSelectPopover.tree.json +1 -1
  156. package/dist/ai/manifest/components/BbSlider.json +6 -5
  157. package/dist/ai/manifest/components/BbSwitch.json +6 -5
  158. package/dist/ai/manifest/components/BbSwitch.tree.json +2 -1
  159. package/dist/ai/manifest/components/BbSwitchGroup.json +12 -11
  160. package/dist/ai/manifest/components/BbSwitchGroup.tree.json +3 -0
  161. package/dist/ai/manifest/components/BbTable.json +1 -1
  162. package/dist/ai/manifest/components/BbTable.tree.json +1 -1
  163. package/dist/ai/manifest/components/BbTabs.tree.json +1 -0
  164. package/dist/ai/manifest/components/BbTag.json +4 -3
  165. package/dist/ai/manifest/components/BbTextInput.json +5 -4
  166. package/dist/ai/manifest/components/BbTextarea.json +5 -4
  167. package/dist/ai/manifest/components/BbTimePicker.json +2 -2
  168. package/dist/ai/manifest/components/BbTimePicker.tree.json +1 -1
  169. package/dist/ai/manifest/components/BbTimePickerInput.json +6 -5
  170. package/dist/ai/manifest/components/BbTimePickerInput.tree.json +1 -1
  171. package/dist/ai/manifest/components/BbToast.json +4 -8
  172. package/dist/ai/manifest/components/BbToast.removed.json +1 -1
  173. package/dist/ai/manifest/components/BbToastPortal.json +6 -3
  174. package/dist/ai/manifest/components/BbTree.json +1 -1
  175. package/dist/ai/manifest/components/CommonField.json +5 -4
  176. package/dist/ai/manifest/components/CommonField.tree.json +76 -1
  177. package/dist/ai/manifest/index.json +9 -10
  178. package/dist/ai/manifest/meta.json +29 -4
  179. package/dist/ai/manifest/types.advanced.json +15 -7
  180. package/dist/ai/manifest/types.api.json +8 -7
  181. package/dist/ai/manifest/types.wrapper.json +2 -3
  182. package/dist/ai/recipes/inertia/approvals-inbox.md +180 -162
  183. package/dist/ai/recipes/inertia/inline-edit-workspace.md +13 -14
  184. package/dist/ai/recipes/inertia/onboarding.md +15 -18
  185. package/dist/ai/recipes/inertia/ownership-atlas.md +67 -30
  186. package/dist/ai/recipes/inertia/record-form.md +14 -41
  187. package/dist/ai/recipes/inertia/records-workspace.md +121 -97
  188. package/dist/ai/recipes/inertia/settings-workspace.md +176 -213
  189. package/dist/ai/recipes/inertia/upload-center.md +30 -24
  190. package/dist/ai/recipes/inertia/wizard-form.md +9 -7
  191. package/dist/ai/recipes/nuxt/approvals-inbox.md +180 -161
  192. package/dist/ai/recipes/nuxt/inline-edit-workspace.md +11 -13
  193. package/dist/ai/recipes/nuxt/onboarding.md +15 -18
  194. package/dist/ai/recipes/nuxt/ownership-atlas.md +63 -26
  195. package/dist/ai/recipes/nuxt/record-form.md +14 -42
  196. package/dist/ai/recipes/nuxt/records-workspace.md +111 -96
  197. package/dist/ai/recipes/nuxt/settings-workspace.md +178 -219
  198. package/dist/ai/recipes/nuxt/upload-center.md +25 -23
  199. package/dist/ai/recipes/nuxt/wizard-form.md +9 -7
  200. package/dist/ai/recipes/vue/approvals-inbox.md +181 -163
  201. package/dist/ai/recipes/vue/inline-edit-workspace.md +10 -12
  202. package/dist/ai/recipes/vue/onboarding.md +15 -20
  203. package/dist/ai/recipes/vue/ownership-atlas.md +63 -26
  204. package/dist/ai/recipes/vue/record-form.md +14 -42
  205. package/dist/ai/recipes/vue/records-workspace.md +111 -96
  206. package/dist/ai/recipes/vue/settings-workspace.md +178 -219
  207. package/dist/ai/recipes/vue/upload-center.md +25 -23
  208. package/dist/ai/recipes/vue/wizard-form.md +9 -9
  209. package/dist/ai/source/BbAccordion.md +79 -9
  210. package/dist/ai/source/BbAlert.md +34 -12
  211. package/dist/ai/source/BbBaseButton.md +15 -2
  212. package/dist/ai/source/BbBaseCheckboxIcon.md +4 -0
  213. package/dist/ai/source/BbButton.md +18 -4
  214. package/dist/ai/source/BbCalendar.md +10 -5
  215. package/dist/ai/source/BbCheckbox.md +27 -8
  216. package/dist/ai/source/BbCheckboxGroup.md +26 -6
  217. package/dist/ai/source/BbCollapsible.md +6 -7
  218. package/dist/ai/source/BbColorInput.md +9 -6
  219. package/dist/ai/source/BbColorPalette.md +0 -1
  220. package/dist/ai/source/BbConfirm.md +16 -28
  221. package/dist/ai/source/BbConfirmPortal.md +7 -14
  222. package/dist/ai/source/BbDatePicker.md +66 -2
  223. package/dist/ai/source/BbDatePickerInput.md +19 -16
  224. package/dist/ai/source/BbDialog.md +340 -50
  225. package/dist/ai/source/BbDropdown.md +5 -5
  226. package/dist/ai/source/BbDropdownGroup.md +5 -4
  227. package/dist/ai/source/BbDropzone.md +29 -10
  228. package/dist/ai/source/BbForm.md +20 -1
  229. package/dist/ai/source/BbHost.md +97 -0
  230. package/dist/ai/source/BbHoverCard.md +5 -5
  231. package/dist/ai/source/BbHoverCardPortal.md +7 -7
  232. package/dist/ai/source/BbNumberInput.md +10 -7
  233. package/dist/ai/source/BbOffCanvas.md +892 -53
  234. package/dist/ai/source/BbPopover.md +5 -6
  235. package/dist/ai/source/BbPopoverPortal.md +7 -7
  236. package/dist/ai/source/BbProgress.md +1 -1
  237. package/dist/ai/source/BbRadio.md +29 -8
  238. package/dist/ai/source/BbRadioGroup.md +25 -6
  239. package/dist/ai/source/BbRating.md +22 -6
  240. package/dist/ai/source/BbSelect.md +21 -11
  241. package/dist/ai/source/BbSelectPopover.md +10 -7
  242. package/dist/ai/source/BbSlider.md +47 -11
  243. package/dist/ai/source/BbSwitch.md +22 -3
  244. package/dist/ai/source/BbSwitchGroup.md +20 -1
  245. package/dist/ai/source/BbTable.md +5 -3
  246. package/dist/ai/source/BbTabs.md +33 -3
  247. package/dist/ai/source/BbTabsList.md +16 -3
  248. package/dist/ai/source/BbTabsPanels.md +6 -0
  249. package/dist/ai/source/BbTabsRoot.md +6 -0
  250. package/dist/ai/source/BbTag.md +9 -6
  251. package/dist/ai/source/BbTextInput.md +10 -7
  252. package/dist/ai/source/BbTextarea.md +10 -7
  253. package/dist/ai/source/BbTimePicker.md +23 -2
  254. package/dist/ai/source/BbTimePickerInput.md +14 -20
  255. package/dist/ai/source/BbToast.md +58 -27
  256. package/dist/ai/source/BbToastPortal.md +25 -14
  257. package/dist/ai/source/BbTree.md +21 -12
  258. package/dist/ai/source/CommonField.md +393 -45
  259. package/dist/ai/source/CommonPopover.md +4 -0
  260. package/dist/components/BbAccordion/BbAccordion.vue_vue_type_script_setup_true_lang.js +47 -33
  261. package/dist/components/BbAccordion/types.d.ts +21 -6
  262. package/dist/components/BbAccordion/types.js +2 -0
  263. package/dist/components/BbAlert/BbAlert.vue_vue_type_script_setup_true_lang.js +39 -37
  264. package/dist/components/BbAlert/types.d.ts +11 -4
  265. package/dist/components/BbBaseButton/BbBaseButton.vue_vue_type_script_setup_true_lang.js +5 -5
  266. package/dist/components/BbBaseButton/types.d.ts +3 -2
  267. package/dist/components/BbButton/BbButton.vue_vue_type_script_setup_true_lang.js +81 -80
  268. package/dist/components/BbButton/types.d.ts +3 -2
  269. package/dist/components/BbCalendar/BbCalendar.vue_vue_type_script_setup_true_lang.js +4 -4
  270. package/dist/components/BbCalendar/types.d.ts +6 -1
  271. package/dist/components/BbCalendar/useDayjsLocale.d.ts +8 -0
  272. package/dist/components/BbCalendar/useDayjsLocale.js +14 -2
  273. package/dist/components/BbCheckbox/BbCheckbox.vue.d.ts +1 -1
  274. package/dist/components/BbCheckbox/BbCheckbox.vue_vue_type_script_setup_true_lang.js +86 -84
  275. package/dist/components/BbCheckbox/types.d.ts +7 -6
  276. package/dist/components/BbCheckboxGroup/BbCheckboxGroup.vue_vue_type_script_setup_true_lang.js +91 -90
  277. package/dist/components/BbCheckboxGroup/types.d.ts +7 -6
  278. package/dist/components/BbCollapsible/BbCollapsible.vue_vue_type_script_setup_true_lang.js +1 -1
  279. package/dist/components/BbCollapsible/types.d.ts +4 -4
  280. package/dist/components/BbColorInput/BbColorInput.vue_vue_type_script_setup_true_lang.js +69 -68
  281. package/dist/components/BbColorInput/types.d.ts +7 -6
  282. package/dist/components/BbColorPalette/BbColorPalette.vue_vue_type_script_setup_true_lang.js +0 -1
  283. package/dist/components/BbConfirm/BbConfirm.vue_vue_type_script_setup_true_lang.js +46 -48
  284. package/dist/components/BbConfirm/BbConfirmPortal.vue.d.ts +1 -1
  285. package/dist/components/BbConfirm/BbConfirmPortal.vue_vue_type_script_setup_true_lang.js +1 -1
  286. package/dist/components/BbConfirm/types.d.ts +5 -12
  287. package/dist/components/BbDatePicker/BbDatePicker.vue_vue_type_script_setup_true_lang.js +118 -103
  288. package/dist/components/BbDatePicker/types.d.ts +8 -0
  289. package/dist/components/BbDatePickerInput/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +303 -309
  290. package/dist/components/BbDatePickerInput/types.d.ts +15 -11
  291. package/dist/components/BbDialog/BbDialog.vue.d.ts +10 -0
  292. package/dist/components/BbDialog/BbDialog.vue_vue_type_script_setup_true_lang.js +250 -164
  293. package/dist/components/BbDialog/types.d.ts +113 -12
  294. package/dist/components/BbDropdown/BbDropdown.vue_vue_type_script_setup_true_lang.js +0 -1
  295. package/dist/components/BbDropdown/BbDropdownList.vue_vue_type_script_setup_true_lang.js +1 -1
  296. package/dist/components/BbDropdown/DropdownPipelineResolver.vue_vue_type_script_setup_true_lang.js +13 -13
  297. package/dist/components/BbDropdown/types.d.ts +5 -4
  298. package/dist/components/BbDropzone/BbDropzone.vue.d.ts +2 -2
  299. package/dist/components/BbDropzone/BbDropzone.vue_vue_type_script_setup_true_lang.js +120 -116
  300. package/dist/components/BbDropzone/types.d.ts +8 -3
  301. package/dist/components/BbForm/BbForm.vue_vue_type_script_setup_true_lang.js +179 -173
  302. package/dist/components/BbForm/bindFormField.d.ts +2 -3
  303. package/dist/components/BbHost/BbHost.vue.d.ts +4 -0
  304. package/dist/components/BbHost/BbHost.vue.js +5 -0
  305. package/dist/components/BbHost/BbHost.vue_vue_type_script_setup_true_lang.js +30 -0
  306. package/dist/components/BbHost/BbHostOpening.d.ts +27 -0
  307. package/dist/components/BbHost/BbHostOpening.js +43 -0
  308. package/dist/components/BbHost/types.d.ts +7 -0
  309. package/dist/components/BbHoverCard/BbHoverCardPortal.vue.d.ts +2 -2
  310. package/dist/components/BbHoverCard/types.d.ts +5 -5
  311. package/dist/components/BbNumberInput/BbNumberInput.vue_vue_type_script_setup_true_lang.js +143 -142
  312. package/dist/components/BbNumberInput/types.d.ts +8 -7
  313. package/dist/components/BbOffCanvas/BbOffCanvas.vue.d.ts +11 -0
  314. package/dist/components/BbOffCanvas/BbOffCanvas.vue_vue_type_script_setup_true_lang.js +520 -253
  315. package/dist/components/BbOffCanvas/sheetSnap.d.ts +64 -0
  316. package/dist/components/BbOffCanvas/sheetSnap.js +58 -0
  317. package/dist/components/BbOffCanvas/types.d.ts +124 -19
  318. package/dist/components/BbPagination/BbPagination.vue_vue_type_script_setup_true_lang.js +68 -68
  319. package/dist/components/BbPopover/BbPopover.vue_vue_type_script_setup_true_lang.js +0 -1
  320. package/dist/components/BbPopover/BbPopoverPortal.vue.d.ts +2 -2
  321. package/dist/components/BbPopover/types.d.ts +5 -5
  322. package/dist/components/BbProgress/types.d.ts +1 -1
  323. package/dist/components/BbRadio/BbRadio.vue.d.ts +1 -1
  324. package/dist/components/BbRadio/BbRadio.vue_vue_type_script_setup_true_lang.js +66 -64
  325. package/dist/components/BbRadio/types.d.ts +7 -6
  326. package/dist/components/BbRadioGroup/BbRadioGroup.vue_vue_type_script_setup_true_lang.js +96 -95
  327. package/dist/components/BbRadioGroup/types.d.ts +7 -6
  328. package/dist/components/BbRating/BbRating.vue_vue_type_script_setup_true_lang.js +79 -78
  329. package/dist/components/BbRating/types.d.ts +7 -6
  330. package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +162 -158
  331. package/dist/components/BbSelect/types.d.ts +12 -10
  332. package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +7 -5
  333. package/dist/components/BbSelectPopover/types.d.ts +5 -4
  334. package/dist/components/BbSlider/BbSlider.vue_vue_type_script_setup_true_lang.js +177 -168
  335. package/dist/components/BbSlider/types.d.ts +14 -6
  336. package/dist/components/BbSwitch/BbSwitch.vue.d.ts +1 -1
  337. package/dist/components/BbSwitch/BbSwitch.vue_vue_type_script_setup_true_lang.js +89 -87
  338. package/dist/components/BbSwitch/types.d.ts +2 -1
  339. package/dist/components/BbSwitchGroup/BbSwitchGroup.vue_vue_type_script_setup_true_lang.js +131 -130
  340. package/dist/components/BbSwitchGroup/types.d.ts +2 -1
  341. package/dist/components/BbTable/types.d.ts +5 -3
  342. package/dist/components/BbTabs/BbTabs.vue_vue_type_script_setup_true_lang.js +33 -30
  343. package/dist/components/BbTabs/BbTabsList.vue_vue_type_script_setup_true_lang.js +54 -50
  344. package/dist/components/BbTabs/tablistName.d.ts +4 -0
  345. package/dist/components/BbTabs/tablistName.js +13 -0
  346. package/dist/components/BbTag/BbTag.vue_vue_type_script_setup_true_lang.js +64 -63
  347. package/dist/components/BbTag/types.d.ts +7 -6
  348. package/dist/components/BbTextInput/BbTextInput.vue_vue_type_script_setup_true_lang.js +71 -70
  349. package/dist/components/BbTextInput/types.d.ts +8 -7
  350. package/dist/components/BbTextarea/BbTextarea.vue_vue_type_script_setup_true_lang.js +81 -80
  351. package/dist/components/BbTextarea/types.d.ts +8 -7
  352. package/dist/components/BbTimePicker/BbTimePicker.vue_vue_type_script_setup_true_lang.js +90 -86
  353. package/dist/components/BbTimePicker/types.d.ts +6 -0
  354. package/dist/components/BbTimePickerInput/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +162 -167
  355. package/dist/components/BbTimePickerInput/types.d.ts +9 -8
  356. package/dist/components/BbToast/BbToast.vue_vue_type_script_setup_true_lang.js +41 -34
  357. package/dist/components/BbToast/BbToastMessage.vue_vue_type_script_setup_true_lang.js +79 -78
  358. package/dist/components/BbToast/BbToastPortal.vue.d.ts +5 -5
  359. package/dist/components/BbToast/BbToastPortal.vue_vue_type_script_setup_true_lang.js +1 -1
  360. package/dist/components/BbToast/BbToastRegion.vue.d.ts +2 -0
  361. package/dist/components/BbToast/BbToastRegion.vue_vue_type_script_setup_true_lang.js +66 -66
  362. package/dist/components/BbToast/types.d.ts +17 -8
  363. package/dist/components/BbTree/BbTree.vue.d.ts +1 -1
  364. package/dist/components/BbTree/BbTree.vue_vue_type_script_setup_true_lang.js +1 -1
  365. package/dist/components/BbTree/types.d.ts +6 -6
  366. package/dist/components/CommonField/CommonField.vue.d.ts +2 -1
  367. package/dist/components/CommonField/CommonField.vue_vue_type_script_setup_true_lang.js +146 -99
  368. package/dist/components/CommonField/types.d.ts +18 -12
  369. package/dist/components/CommonPopover/CommonPopover.vue_vue_type_script_setup_true_lang.js +32 -29
  370. package/dist/composables/formSubmitLock.d.ts +35 -0
  371. package/dist/composables/formSubmitLock.js +17 -2
  372. package/dist/composables/hostOpenings.d.ts +82 -0
  373. package/dist/composables/hostOpenings.js +70 -0
  374. package/dist/composables/hostRegistry.d.ts +39 -0
  375. package/dist/composables/hostRegistry.js +21 -0
  376. package/dist/composables/overlayRegistry.d.ts +195 -0
  377. package/dist/composables/overlayRegistry.js +296 -0
  378. package/dist/composables/useBbDialogContext.d.ts +100 -0
  379. package/dist/composables/useBbDialogContext.js +56 -0
  380. package/dist/composables/useBbFormContext.d.ts +7 -0
  381. package/dist/composables/useBbFormContext.js +40 -34
  382. package/dist/composables/useBbOffCanvasContext.d.ts +23 -0
  383. package/dist/composables/useBbOffCanvasContext.js +8 -0
  384. package/dist/composables/useBbTabsContext.js +140 -171
  385. package/dist/composables/useConfig.js +4 -0
  386. package/dist/composables/useConfirm.d.ts +44 -21
  387. package/dist/composables/useConfirm.js +4 -4
  388. package/dist/composables/useKeyboardInset.js +10 -20
  389. package/dist/composables/useOnDemandOpener.d.ts +35 -0
  390. package/dist/composables/useOnDemandOpener.js +30 -0
  391. package/dist/composables/useOverlayNavigation.d.ts +37 -0
  392. package/dist/composables/useOverlayNavigation.js +89 -0
  393. package/dist/composables/useRefusedCloseAnnouncement.d.ts +13 -0
  394. package/dist/composables/useRefusedCloseAnnouncement.js +15 -0
  395. package/dist/composables/useToast.d.ts +5 -6
  396. package/dist/composables/useToast.js +4 -3
  397. package/dist/composables/useUrlQueryParam.d.ts +21 -0
  398. package/dist/composables/useUrlQueryParam.js +48 -0
  399. package/dist/deprecation/ai-deprecations.json.d.ts +3 -10
  400. package/dist/deprecation/ai-deprecations.json.js +1 -1
  401. package/dist/directives/bbDate.d.ts +40 -9
  402. package/dist/directives/bbDialog.d.ts +60 -0
  403. package/dist/directives/bbDialog.js +7 -0
  404. package/dist/directives/bbHoverCard.d.ts +3 -3
  405. package/dist/directives/bbHoverCard.js +1 -1
  406. package/dist/directives/bbOffCanvas.d.ts +46 -0
  407. package/dist/directives/bbOffCanvas.js +7 -0
  408. package/dist/directives/bbPopover.d.ts +3 -3
  409. package/dist/directives/bbPopover.js +1 -1
  410. package/dist/directives/bbTime.d.ts +23 -6
  411. package/dist/directives/directivePortal.d.ts +11 -11
  412. package/dist/directives/directivePortal.js +1 -1
  413. package/dist/directives/overlayTrigger.d.ts +28 -0
  414. package/dist/directives/overlayTrigger.js +93 -0
  415. package/dist/i18n/locales/cs.json +6 -2
  416. package/dist/i18n/locales/da.json +6 -2
  417. package/dist/i18n/locales/de-CH.json +6 -2
  418. package/dist/i18n/locales/de.json +6 -2
  419. package/dist/i18n/locales/el.json +6 -2
  420. package/dist/i18n/locales/en-GB.json +6 -2
  421. package/dist/i18n/locales/en.json +6 -2
  422. package/dist/i18n/locales/es-MX.json +6 -2
  423. package/dist/i18n/locales/es.json +6 -2
  424. package/dist/i18n/locales/fi.json +6 -2
  425. package/dist/i18n/locales/fr.json +6 -2
  426. package/dist/i18n/locales/hu.json +6 -2
  427. package/dist/i18n/locales/it.json +6 -2
  428. package/dist/i18n/locales/ja.json +6 -2
  429. package/dist/i18n/locales/ko.json +6 -2
  430. package/dist/i18n/locales/nb.json +6 -2
  431. package/dist/i18n/locales/nl.json +6 -2
  432. package/dist/i18n/locales/pl.json +6 -2
  433. package/dist/i18n/locales/pt-BR.json +6 -2
  434. package/dist/i18n/locales/pt-PT.json +6 -2
  435. package/dist/i18n/locales/ro.json +6 -2
  436. package/dist/i18n/locales/ru.json +6 -2
  437. package/dist/i18n/locales/sv.json +6 -2
  438. package/dist/i18n/locales/tr.json +6 -2
  439. package/dist/i18n/locales/uk.json +6 -2
  440. package/dist/i18n/locales/zh-CN.json +6 -2
  441. package/dist/i18n/locales/zh-HK.json +6 -2
  442. package/dist/i18n/locales/zh-TW.json +6 -2
  443. package/dist/icon-scan.d.ts +21 -0
  444. package/dist/icon-scan.js +29 -26
  445. package/dist/index.d.ts +14 -5
  446. package/dist/index.js +75 -72
  447. package/dist/llms-full.txt +5982 -4188
  448. package/dist/llms-medium.txt +120 -122
  449. package/dist/llms.txt +11 -7
  450. package/dist/locale-blueprint.json +6 -2
  451. package/dist/nuxt-auto-imports.js +3 -1
  452. package/dist/nuxt-module.d.ts +7 -4
  453. package/dist/nuxt.js +23 -20
  454. package/dist/plugin.js +29 -25
  455. package/dist/project-dts.d.ts +15 -2
  456. package/dist/project-dts.js +16 -10
  457. package/dist/runtime/nuxt-plugin.js +19 -17
  458. package/dist/styles.css +2 -2
  459. package/dist/types/Config.d.ts +33 -7
  460. package/dist/types/ptComponentMap.d.ts +1 -1
  461. package/dist/utilities/functions/isTextEntry.d.ts +5 -0
  462. package/dist/utilities/functions/isTextEntry.js +15 -0
  463. package/dist/utilities/functions/responsiveDefault.d.ts +7 -0
  464. package/dist/utilities/functions/responsiveDefault.js +11 -0
  465. package/dist/utilities/misc/autofocus.d.ts +20 -0
  466. package/dist/utilities/misc/autofocus.js +11 -0
  467. package/dist/utils/copyData.d.ts +13 -0
  468. package/dist/utils/copyData.js +29 -0
  469. package/dist/utils/cssLayers.d.ts +10 -0
  470. package/dist/utils/cssLayers.js +23 -18
  471. package/dist/utils/versionCheck.js +1 -1
  472. package/dist/vite-plugin.d.ts +29 -14
  473. package/dist/vite.js +247 -242
  474. package/llms.txt +11 -7
  475. package/package.json +1 -1
  476. package/scripts/lib/agent-manifest.mjs +22 -3
  477. package/scripts/lib/css-class-check.mjs +33 -2
  478. package/scripts/lib/define-preset-copy.mjs +123 -0
  479. package/scripts/lib/eslint-disable.mjs +22 -2
  480. package/scripts/lib/eslint-plugin.d.ts +4 -2
  481. package/scripts/lib/eslint-plugin.mjs +130 -93
  482. package/scripts/lib/portal-names.mjs +198 -28
  483. package/scripts/lib/prefer-v-bb-dialog.mjs +455 -0
  484. package/scripts/lib/project-variant-dts.mjs +53 -1
  485. package/scripts/lib/rule-registry.mjs +379 -0
  486. package/scripts/lib/swap-noun.mjs +33 -0
  487. package/scripts/lib/unimported-components.mjs +3 -1
  488. package/scripts/lib/validate-bb-markup.mjs +93 -77
  489. package/scripts/lib/required-in-form.mjs +0 -240
@@ -33,6 +33,11 @@ recipes.
33
33
  [BbSelectPopover](../../BbSelectPopover.md) (§ One popover per table row is
34
34
  load-bearing here) · [BbBadge](../../BbBadge.md) (the `loading` /
35
35
  `append:icon` interplay).
36
+ - Each toast and alert variant's icon set once in the build config; the
37
+ code below passes no `icon` for them:
38
+ `toastVariants: { success: { icon: 'lucide:circle-check' }, destructive: { icon: 'lucide:circle-x' } }`
39
+ and `alertVariants: { warning: { icon: 'lucide:triangle-alert' }, destructive: { icon: 'lucide:circle-x' } }`
40
+ ([BbToast § Variant icons](../../BbToast.md#variant-icons)).
36
41
 
37
42
  Guides: [Inline Edit Playbook](../../guides/inline-edit-playbook.md) (who owns
38
43
  the edit — this page is the autosave answer) ·
@@ -43,7 +48,7 @@ label state) · [Page Shell](../../guides/page-shell.md) ·
43
48
  Siblings: [vue](../vue/inline-edit-workspace.md) ·
44
49
  [inertia](../inertia/inline-edit-workspace.md).
45
50
 
46
- Platform assumptions: `<BbConfirm />` and `<BbToast />` mounted once in
51
+ Platform assumptions: `<BbHost />` mounted once in
47
52
  `app.vue` — never in a page; the layout chrome from the guides copied into
48
53
  `app/components/` and `app/composables/`. Server routes: `GET /api/issues` (accepts
49
54
  `search`, `status[]`, `priority[]`, `assignee`, `tab`, `page`, `perPage`;
@@ -616,7 +621,6 @@ export function provideBacklogWorkspace(): BacklogWorkspaceContext {
616
621
  toast({
617
622
  title: `${issue.ref}: ${FIELD_LABELS[key]} updated`,
618
623
  variant: 'success',
619
- icon: 'lucide:circle-check',
620
624
  actions: [
621
625
  {
622
626
  text: 'Undo',
@@ -640,7 +644,6 @@ export function provideBacklogWorkspace(): BacklogWorkspaceContext {
640
644
  toast({
641
645
  title: `Couldn't save the ${key} of ${issue.ref} — reverted.`,
642
646
  variant: 'destructive',
643
- icon: 'lucide:circle-x',
644
647
  });
645
648
  }
646
649
  };
@@ -668,7 +671,6 @@ export function provideBacklogWorkspace(): BacklogWorkspaceContext {
668
671
  toast({
669
672
  title: `Duplicated as ${copy.ref}.`,
670
673
  variant: 'success',
671
- icon: 'lucide:circle-check',
672
674
  });
673
675
  };
674
676
 
@@ -681,7 +683,6 @@ export function provideBacklogWorkspace(): BacklogWorkspaceContext {
681
683
  toast({
682
684
  title: `${issue.ref} moved to Sprint 25.`,
683
685
  variant: 'success',
684
- icon: 'lucide:circle-check',
685
686
  });
686
687
  };
687
688
 
@@ -699,7 +700,6 @@ export function provideBacklogWorkspace(): BacklogWorkspaceContext {
699
700
  toast({
700
701
  title: `${issue.ref} deleted.`,
701
702
  variant: 'success',
702
- icon: 'lucide:circle-check',
703
703
  });
704
704
  };
705
705
 
@@ -752,7 +752,6 @@ export function provideBacklogWorkspace(): BacklogWorkspaceContext {
752
752
  toast({
753
753
  title: `${count} issues moved to ${label}.`,
754
754
  variant: 'success',
755
- icon: 'lucide:circle-check',
756
755
  });
757
756
  };
758
757
 
@@ -767,7 +766,6 @@ export function provideBacklogWorkspace(): BacklogWorkspaceContext {
767
766
  toast({
768
767
  title: `${count} issues assigned to ${assignee.name}.`,
769
768
  variant: 'success',
770
- icon: 'lucide:circle-check',
771
769
  });
772
770
  };
773
771
 
@@ -782,7 +780,6 @@ export function provideBacklogWorkspace(): BacklogWorkspaceContext {
782
780
  toast({
783
781
  title: `${count} issues moved to Sprint 25.`,
784
782
  variant: 'success',
785
- icon: 'lucide:circle-check',
786
783
  });
787
784
  };
788
785
 
@@ -1158,6 +1155,7 @@ const rowClass = (item: Issue) =>
1158
1155
  <BbSelectPopover
1159
1156
  v-model="ctx.filters.assignee"
1160
1157
  clearable
1158
+ :filter-by="false"
1161
1159
  item-text="name"
1162
1160
  :items="searchMembers"
1163
1161
  >
@@ -1431,6 +1429,7 @@ const label = computed(
1431
1429
  of its own), matching how the row stores it. -->
1432
1430
  <BbSelectPopover
1433
1431
  compact
1432
+ :filter-by="false"
1434
1433
  item-text="name"
1435
1434
  :items="searchMembers"
1436
1435
  :model-value="assignee"
@@ -1573,6 +1572,7 @@ const ctx = useBacklogWorkspace();
1573
1572
  </BbSelectPopover>
1574
1573
 
1575
1574
  <BbSelectPopover
1575
+ :filter-by="false"
1576
1576
  item-text="name"
1577
1577
  :items="searchMembers"
1578
1578
  :model-value="null"
@@ -1631,11 +1631,9 @@ const ctx = useBacklogWorkspace();
1631
1631
  <!-- components/BacklogWorkspace/IssuePeek.vue -->
1632
1632
  <template>
1633
1633
  <div v-if="issue" class="flex flex-col gap-4 text-sm">
1634
- <!-- Identity header. -->
1634
+ <!-- Identity header: the sidebar title already shows the ref, so the
1635
+ body opens on the issue's title. -->
1635
1636
  <header class="flex flex-col gap-1">
1636
- <p class="text-xs font-medium text-(--bb-text-muted)">
1637
- {{ issue.ref }}
1638
- </p>
1639
1637
  <h2 class="text-base font-semibold">{{ issue.title }}</h2>
1640
1638
  </header>
1641
1639
 
@@ -24,7 +24,12 @@ Sibling recipes: [Vue](../vue/onboarding.md) ·
24
24
  those files before anything below, and do not hand-roll replacements —
25
25
  the peek stack, the close semantics and the sidebar's out-of-flow
26
26
  behaviour are all load-bearing here.
27
- - `<BbConfirm />` and `<BbToast />` mounted once in `app.vue` — never in a page.
27
+ - `<BbHost />` mounted once in `app.vue` — never in a page.
28
+ - Each toast and alert variant's icon set once in the build config; the
29
+ code below passes no `icon` for them:
30
+ `toastVariants: { success: { icon: 'lucide:circle-check' }, destructive: { icon: 'lucide:circle-x' } }`
31
+ and `alertVariants: { warning: { icon: 'lucide:triangle-alert' }, destructive: { icon: 'lucide:circle-x' } }`
32
+ ([BbToast § Variant icons](../../BbToast.md#variant-icons)).
28
33
  - [App Layout](../../guides/app-layout.md) and
29
34
  [Page Shell](../../guides/page-shell.md) copied into `app/components/` and `app/composables/`
30
35
  per their guides — this page assumes the chrome exists and renders inside
@@ -489,7 +494,6 @@ export function provideOnboardingWorkspace(): OnboardingWorkspaceContext {
489
494
  toast({
490
495
  title: `"${title}" checked off.`,
491
496
  variant: 'success',
492
- icon: 'lucide:circle-check',
493
497
  });
494
498
  openNextTodo(id);
495
499
  };
@@ -516,7 +520,6 @@ export function provideOnboardingWorkspace(): OnboardingWorkspaceContext {
516
520
  toast({
517
521
  title: `${integration.name} ${next ? 'connected' : 'disconnected'}.`,
518
522
  variant: 'success',
519
- icon: 'lucide:circle-check',
520
523
  });
521
524
  // The server owns completion: connecting checks the step off, and
522
525
  // disconnecting the last tool reopens it, so both end in a re-pull.
@@ -527,7 +530,6 @@ export function provideOnboardingWorkspace(): OnboardingWorkspaceContext {
527
530
  toast({
528
531
  title: `Could not ${next ? 'connect' : 'disconnect'} ${integration.name}.`,
529
532
  variant: 'destructive',
530
- icon: 'lucide:circle-x',
531
533
  });
532
534
  } finally {
533
535
  integration.busy = false;
@@ -543,7 +545,6 @@ export function provideOnboardingWorkspace(): OnboardingWorkspaceContext {
543
545
  toast({
544
546
  title: `${emails.length} invitation${emails.length === 1 ? '' : 's'} sent.`,
545
547
  variant: 'success',
546
- icon: 'lucide:circle-check',
547
548
  });
548
549
  };
549
550
 
@@ -553,7 +554,6 @@ export function provideOnboardingWorkspace(): OnboardingWorkspaceContext {
553
554
  toast({
554
555
  title: `${draft.name} created.`,
555
556
  variant: 'success',
556
- icon: 'lucide:circle-check',
557
557
  });
558
558
  };
559
559
 
@@ -577,7 +577,6 @@ export function provideOnboardingWorkspace(): OnboardingWorkspaceContext {
577
577
  toast({
578
578
  title: `${result.imported} customers imported.`,
579
579
  variant: 'success',
580
- icon: 'lucide:circle-check',
581
580
  });
582
581
  } finally {
583
582
  importState.uploading = false;
@@ -597,14 +596,12 @@ export function provideOnboardingWorkspace(): OnboardingWorkspaceContext {
597
596
  ? 'Payment reminders are on.'
598
597
  : 'Payment reminders turned off.',
599
598
  variant: 'success',
600
- icon: 'lucide:circle-check',
601
599
  });
602
600
  } catch {
603
601
  reminders.enabled = !enabled;
604
602
  toast({
605
603
  title: 'Could not update reminders.',
606
604
  variant: 'destructive',
607
- icon: 'lucide:circle-x',
608
605
  });
609
606
  }
610
607
  };
@@ -618,7 +615,6 @@ export function provideOnboardingWorkspace(): OnboardingWorkspaceContext {
618
615
  toast({
619
616
  title: 'Reminder schedule updated.',
620
617
  variant: 'success',
621
- icon: 'lucide:circle-check',
622
618
  });
623
619
  };
624
620
 
@@ -635,7 +631,6 @@ export function provideOnboardingWorkspace(): OnboardingWorkspaceContext {
635
631
  toast({
636
632
  title: 'Onboarding dismissed. Find it again under Settings → Setup.',
637
633
  variant: 'success',
638
- icon: 'lucide:circle-check',
639
634
  });
640
635
  await navigateTo('/dashboard');
641
636
  };
@@ -1330,22 +1325,24 @@ const ctx = useOnboardingWorkspace();
1330
1325
 
1331
1326
  // The captured-but-not-imported file is this leaf's own state.
1332
1327
  const file = ref<File | null>(null);
1333
- const fileError = ref('');
1328
+ const fileError = ref<string[]>([]);
1334
1329
 
1335
- // Rejects never reach the model — map the typed error to a message and feed
1336
- // it back through `errors` (the display is a round-trip, not automatic).
1337
- const onReject = (error: DropZoneError) => {
1338
- fileError.value =
1330
+ // Rejects never reach the model — map the drop's typed errors to messages
1331
+ // and feed them back through `errors` (the display is a round-trip, not
1332
+ // automatic). One `error` per drop carries every rejection.
1333
+ const onReject = (rejections: DropZoneError[]) => {
1334
+ fileError.value = rejections.map((error) =>
1339
1335
  error.type === 'maxSize'
1340
1336
  ? `${error.filename} is ${error.formattedSize} — the limit is ${error.formattedMaxSize}.`
1341
1337
  : error.type === 'accept'
1342
1338
  ? `${error.filename} is not a CSV file.`
1343
- : `${error.filename} was rejected.`;
1339
+ : `${error.filename} was rejected.`
1340
+ );
1344
1341
  };
1345
1342
 
1346
1343
  const startImport = async () => {
1347
1344
  if (!file.value) return;
1348
- fileError.value = '';
1345
+ fileError.value = [];
1349
1346
  await ctx.importCustomers(file.value);
1350
1347
  file.value = null;
1351
1348
  };
@@ -32,7 +32,12 @@ changes.
32
32
  those files before anything below, and do not hand-roll replacements —
33
33
  the peek stack, the close semantics and the sidebar's out-of-flow
34
34
  behaviour are all load-bearing here.
35
- - `<BbToast />` mounted once in `app.vue` — never in a page.
35
+ - `<BbHost />` mounted once in `app.vue` — never in a page.
36
+ - Each toast and alert variant's icon set once in the build config; the
37
+ code below passes no `icon` for them:
38
+ `toastVariants: { success: { icon: 'lucide:circle-check' }, destructive: { icon: 'lucide:circle-x' } }`
39
+ and `alertVariants: { warning: { icon: 'lucide:triangle-alert' }, destructive: { icon: 'lucide:circle-x' } }`
40
+ ([BbToast § Variant icons](../../BbToast.md#variant-icons)).
36
41
  - The route file `pages/ownership/index.vue` mounts the assembly from
37
42
  `components/OwnershipAtlas/` (every file under `pages/` becomes a route,
38
43
  `.ts` files included, so the page's parts live in `components/`).
@@ -492,7 +497,6 @@ export function provideOwnershipAtlas(): OwnershipAtlasContext {
492
497
  toast({
493
498
  title: `Holdings transferred to ${target?.name ?? 'the selected owner'}.`,
494
499
  variant: 'success',
495
- icon: 'lucide:circle-check',
496
500
  });
497
501
  };
498
502
 
@@ -623,8 +627,8 @@ export function useOwnershipAtlas(): OwnershipAtlasContext {
623
627
  :loading="ctx.ownersPending.value"
624
628
  loading-text="Loading owners…"
625
629
  pt:row="owner-row"
630
+ pt:row:expanded="row-expanded"
626
631
  pt:row:highlighted="row-peeked"
627
- :row-class="rowClass"
628
632
  selectable
629
633
  >
630
634
  <template #name="{ item, content }">
@@ -633,6 +637,13 @@ export function useOwnershipAtlas(): OwnershipAtlasContext {
633
637
  <span class="truncate text-xs text-(--bb-text-muted)">{{
634
638
  item.email
635
639
  }}</span>
640
+ <!-- On a phone Team and Region are hidden; their facts move here. -->
641
+ <span
642
+ v-if="isMobile"
643
+ class="truncate text-xs text-(--bb-text-muted)"
644
+ >
645
+ {{ item.team }} · {{ REGION_LABEL[item.region] }}
646
+ </span>
636
647
  </div>
637
648
  </template>
638
649
 
@@ -739,6 +750,7 @@ export function useOwnershipAtlas(): OwnershipAtlasContext {
739
750
  </template>
740
751
 
741
752
  <script setup lang="ts">
753
+ import { computed } from 'vue';
742
754
  import {
743
755
  BbBreadcrumbs,
744
756
  BbButton,
@@ -747,6 +759,7 @@ import {
747
759
  BbTable,
748
760
  BbTabs,
749
761
  BbTextInput,
762
+ useMobile,
750
763
  vBbTooltip,
751
764
  type BbTableColumn,
752
765
  } from 'bitboss-ui';
@@ -760,15 +773,19 @@ import type { Owner } from '~/types';
760
773
 
761
774
  const ctx = provideOwnershipAtlas();
762
775
 
776
+ const { isMobile } = useMobile();
777
+
763
778
  /** Four data columns — the nested holdings table snaps onto them 1:1. The
764
779
  * owner's title rides under Team; the holdings count lives on the expand
765
- * control in the actions column. */
766
- const columns: Array<BbTableColumn<Owner>> = [
780
+ * control in the actions column. On a phone Team and Region leave (the BbTable
781
+ * guide's "hide columns, don't scroll"): four equal tracks at 390px would
782
+ * break names mid-word. */
783
+ const columns = computed<Array<BbTableColumn<Owner>>>(() => [
767
784
  { key: 'name', label: 'Owner' },
768
- { key: 'team', label: 'Team' },
769
- { key: 'region', label: 'Region' },
785
+ { key: 'team', label: 'Team', hidden: isMobile.value },
786
+ { key: 'region', label: 'Region', hidden: isMobile.value },
770
787
  { key: 'monthlyTotal', label: '$ / mo', align: 'right' },
771
- ];
788
+ ]);
772
789
 
773
790
  const money = (value: number) =>
774
791
  new Intl.NumberFormat('en-US', {
@@ -776,13 +793,6 @@ const money = (value: number) =>
776
793
  currency: 'USD',
777
794
  maximumFractionDigits: 0,
778
795
  }).format(value);
779
-
780
- // `pt:row` carries the static base class (pointer cursor — rows are click
781
- // targets) and `pt:row:highlighted` the peek wash (the table knows which row
782
- // is highlighted); `rowClass` keeps only what the table cannot know — whether
783
- // the row is expanded.
784
- const rowClass = (item: Owner) =>
785
- ctx.expanded.value.includes(item.id) ? 'row-expanded' : undefined;
786
796
  </script>
787
797
 
788
798
  <style scoped>
@@ -835,7 +845,9 @@ const rowClass = (item: Owner) =>
835
845
  padding-inline: 0;
836
846
  }
837
847
 
838
- /* Row states, painted through the public row-class API. */
848
+ /* Row states, painted through passthrough: `pt:row` carries the static base
849
+ class (pointer cursor — rows are click targets), `pt:row:expanded` and
850
+ `pt:row:highlighted` the states the table already knows. */
839
851
  :deep(.owner-row) {
840
852
  cursor: pointer;
841
853
  }
@@ -845,10 +857,10 @@ const rowClass = (item: Owner) =>
845
857
  background-color: color-mix(in oklab, var(--bb-text) 2.5%, transparent);
846
858
  }
847
859
 
848
- /* Peek-open = accent wash + a 1px lead pin on the row's start edge. */
860
+ /* Peek-open = an accent wash; BbTable paints the lead bar on the highlighted
861
+ row itself. */
849
862
  :deep(.row-peeked) {
850
863
  background-color: color-mix(in oklab, var(--bb-primary) 6%, transparent);
851
- box-shadow: inset 1px 0 0 0 var(--bb-primary);
852
864
  }
853
865
  </style>
854
866
  ```
@@ -874,6 +886,10 @@ const rowClass = (item: Owner) =>
874
886
  <span class="text-xs text-(--bb-text-muted)">
875
887
  Since {{ monthLabel(item.since) }} · {{ item.region }}
876
888
  </span>
889
+ <!-- On a phone Type and Status are hidden; their facts move here. -->
890
+ <span v-if="isMobile" class="text-xs text-(--bb-text-muted)">
891
+ {{ KIND_LABEL[item.kind] }} · {{ STATUS_LABEL[item.status] }}
892
+ </span>
877
893
  </div>
878
894
  </template>
879
895
 
@@ -897,12 +913,15 @@ const rowClass = (item: Owner) =>
897
913
  </template>
898
914
 
899
915
  <script setup lang="ts">
900
- import { BbBadge, BbTable, type BbTableColumn } from 'bitboss-ui';
916
+ import { computed } from 'vue';
917
+ import { BbBadge, BbTable, useMobile, type BbTableColumn } from 'bitboss-ui';
901
918
  import { KIND_LABEL, STATUS_LABEL, STATUS_VARIANT } from './context';
902
919
  import type { Holding, Owner } from '~/types';
903
920
 
904
921
  defineProps<{ owner: Owner }>();
905
922
 
923
+ const { isMobile } = useMobile();
924
+
906
925
  /**
907
926
  * Explicit snaps onto the parent grid, by the PARENT's column keys (Owner /
908
927
  * Team / Region / $ / mo); the parent's select column is accounted for by
@@ -912,14 +931,16 @@ defineProps<{ owner: Owner }>();
912
931
  * the parent's $/mo. With all four snapped, the parent's select and actions
913
932
  * tracks fold into the child's first/last cells as padding — the child
914
933
  * starts flush with the parent's first data column, and that inset is what
915
- * reads as hierarchy.
934
+ * reads as hierarchy. On a phone the parent hides Team and Region, so the
935
+ * columns that snap onto them hide too: a hidden parent column has no track
936
+ * for a child cell to land on.
916
937
  */
917
- const columns: Array<BbTableColumn<Holding>> = [
938
+ const columns = computed<Array<BbTableColumn<Holding>>>(() => [
918
939
  { key: 'name', label: 'Resource', snap: 'name' },
919
- { key: 'kind', label: 'Type', snap: 'team' },
920
- { key: 'status', label: 'Status', snap: 'region' },
940
+ { key: 'kind', label: 'Type', snap: 'team', hidden: isMobile.value },
941
+ { key: 'status', label: 'Status', snap: 'region', hidden: isMobile.value },
921
942
  { key: 'monthlyCost', label: '$ / mo', align: 'right', snap: 'monthlyTotal' },
922
- ];
943
+ ]);
923
944
 
924
945
  const money = (value: number) =>
925
946
  value === 0
@@ -1091,9 +1112,9 @@ const onTransfer = (value: unknown) => {
1091
1112
  <!-- components/OwnershipAtlas/OwnerPeek.vue -->
1092
1113
  <template>
1093
1114
  <div v-if="owner" class="flex flex-col gap-4 text-sm">
1094
- <!-- Identity header. -->
1115
+ <!-- Identity: the sidebar title (`#sidebar-title`) already names the
1116
+ owner, so the peek opens on email + role, never a second name. -->
1095
1117
  <header class="flex flex-col gap-1">
1096
- <h2 class="text-base font-semibold tracking-tight">{{ owner.name }}</h2>
1097
1118
  <p class="text-xs text-(--bb-text-muted)">{{ owner.email }}</p>
1098
1119
  <p class="text-xs text-(--bb-text-muted)">
1099
1120
  {{ owner.title }} · {{ owner.team }} ·
@@ -1329,6 +1350,14 @@ export interface OwnerDetail extends Owner {
1329
1350
  structural inset, plus a hairline and a faint wash, is the entire
1330
1351
  hierarchy treatment. No extra padding inset: an inset would make the
1331
1352
  alignment lie.
1353
+ - **On a phone the tables shed columns, they do not scroll.** Four equal
1354
+ `fixed` tracks at 390px leave ~70px a column and names break mid-word, so
1355
+ Team and Region carry `hidden: isMobile.value` (`useMobile()`, the
1356
+ one-tier form of the BbTable guide's "On a phone" pattern) and their facts
1357
+ stack under the owner's email in the identity cell. The holdings columns
1358
+ that snap onto them (`snap: 'team'` / `'region'`) take the same `hidden`:
1359
+ a hidden parent column has no track for a child cell to land on, and
1360
+ Type · Status move under the resource name.
1332
1361
  - **Cell-padding overrides use direct-child combinators.** `.table-flush`
1333
1362
  bleeds the owner table past the page padding and re-adds the inset on the
1334
1363
  outermost cells — but only via
@@ -1338,6 +1367,11 @@ export interface OwnerDetail extends Owner {
1338
1367
  nested table's cells and clobber the offset padding it computes to stay on
1339
1368
  the parent grid. The expand cell itself is excluded from the inset and
1340
1369
  zero-padded, so the nested table gets the full row width to snap within.
1370
+ - **Row states the table knows go through passthrough.** `pt:row` carries
1371
+ the static base class (pointer cursor), `pt:row:expanded` the quiet ink
1372
+ wash and `pt:row:highlighted` the peek's accent wash — no `row-class`
1373
+ function re-deriving `expanded`. The highlighted row's lead bar is the
1374
+ table's own; the page adds only the wash.
1341
1375
  - **Expansion is rung-3 page state.** `expanded` lives in the context
1342
1376
  because four surfaces touch it: the per-row control, the topbar toggle,
1343
1377
  the bulk bar's Expand, and the peek's "Expand in table". Binding it
@@ -1354,6 +1388,9 @@ export interface OwnerDetail extends Owner {
1354
1388
  as the sidebar title); the stack emptying clears the highlight. Highlight
1355
1389
  and selection remain independent axes — you can peek one owner while
1356
1390
  twelve are selected for transfer.
1391
+ - **The peek never repeats its title.** The shell's `#sidebar-title` (an
1392
+ `<h2>`) already names the owner, so `OwnerPeek` opens on email and role
1393
+ instead of a second heading with the same name.
1357
1394
  - **The context coopts, leaves consume.** `shell` and the table context are
1358
1395
  joined once in `provideOwnershipAtlas()`; five components share filters,
1359
1396
  selection, expansion, the peek and the transfer action through one
@@ -27,7 +27,12 @@ Sibling recipes: [Vue](../vue/record-form.md) ·
27
27
  those files before anything below, and do not hand-roll replacements —
28
28
  the peek stack, the close semantics and the sidebar's out-of-flow
29
29
  behaviour are all load-bearing here.
30
- - `<BbConfirm />` and `<BbToast />` mounted once in `app.vue` — never in a page.
30
+ - `<BbHost />` mounted once in `app.vue` — never in a page.
31
+ - Each toast and alert variant's icon set once in the build config; the
32
+ code below passes no `icon` for them:
33
+ `toastVariants: { success: { icon: 'lucide:circle-check' }, destructive: { icon: 'lucide:circle-x' } }`
34
+ and `alertVariants: { warning: { icon: 'lucide:triangle-alert' }, destructive: { icon: 'lucide:circle-x' } }`
35
+ ([BbToast § Variant icons](../../BbToast.md#variant-icons)).
31
36
  - Server routes: `GET /api/invoices/:id`, `POST /api/invoices`,
32
37
  `PUT /api/invoices/:id`, `DELETE /api/invoices/:id` (422 on validation
33
38
  failure with `{ errors: { field: ['message'] } }`), plus
@@ -564,7 +569,6 @@ export function provideInvoiceForm(): InvoiceFormContext {
564
569
  toast({
565
570
  title: `Applied ${customer.name}'s billing defaults.`,
566
571
  variant: 'success',
567
- icon: 'lucide:circle-check',
568
572
  });
569
573
  };
570
574
 
@@ -613,13 +617,11 @@ export function provideInvoiceForm(): InvoiceFormContext {
613
617
  toast({
614
618
  title: 'Some fields need attention.',
615
619
  variant: 'destructive',
616
- icon: 'lucide:circle-x',
617
620
  });
618
621
  } else {
619
622
  toast({
620
623
  title: 'Something went wrong. Try again.',
621
624
  variant: 'destructive',
622
- icon: 'lucide:circle-x',
623
625
  });
624
626
  }
625
627
  return null;
@@ -635,7 +637,6 @@ export function provideInvoiceForm(): InvoiceFormContext {
635
637
  toast({
636
638
  title: `Invoice ${saved.number} saved.`,
637
639
  variant: 'success',
638
- icon: 'lucide:circle-check',
639
640
  });
640
641
  await navigateTo(`/invoices/${saved.id}`);
641
642
  };
@@ -646,7 +647,6 @@ export function provideInvoiceForm(): InvoiceFormContext {
646
647
  toast({
647
648
  title: `Draft ${saved.number} saved.`,
648
649
  variant: 'success',
649
- icon: 'lucide:circle-check',
650
650
  });
651
651
  // Swap the URL to the edit route. Nuxt remounts the component there, so it
652
652
  // comes back up in edit mode against the freshly-created invoice — no
@@ -673,7 +673,6 @@ export function provideInvoiceForm(): InvoiceFormContext {
673
673
  toast({
674
674
  title: `${invoiceNumber.value} deleted.`,
675
675
  variant: 'success',
676
- icon: 'lucide:circle-check',
677
676
  });
678
677
  await navigateTo('/invoices');
679
678
  };
@@ -864,8 +863,7 @@ const trail = computed(() => [
864
863
 
865
864
  ### DetailsSection.vue
866
865
 
867
- The Customer select is `required`: with `bitboss: { requiredAsterisk: true }` in the build
868
- config it shows the asterisk and carries `aria-required`. It does not block
866
+ The Customer select is `required`: it shows the asterisk and carries `aria-required`. It does not block
869
867
  submission (a select posts through hidden inputs, which the browser never
870
868
  validates); the server's 422 on `customerId` is what stops an empty save.
871
869
 
@@ -888,6 +886,7 @@ validates); the server's 422 on `customerId` is what stops an empty save.
888
886
  v-model="ctx.draft.customerId"
889
887
  autocomplete="off"
890
888
  :errors="ctx.errors.value.customerId"
889
+ :filter-by="false"
891
890
  item-text="name"
892
891
  item-value="id"
893
892
  :items="ctx.fetchCustomers"
@@ -1173,9 +1172,9 @@ const currency = new Intl.NumberFormat('en-US', {
1173
1172
  <template>
1174
1173
  <BbTextarea
1175
1174
  v-if="editing"
1176
- ref="inputRef"
1177
1175
  v-model="value"
1178
1176
  auto-grow
1177
+ autofocus
1179
1178
  compact
1180
1179
  :errors="ctx.lineItemError(line, 'description')"
1181
1180
  hide-label
@@ -1201,7 +1200,7 @@ const currency = new Intl.NumberFormat('en-US', {
1201
1200
  </template>
1202
1201
 
1203
1202
  <script setup lang="ts">
1204
- import { computed, nextTick, ref } from 'vue';
1203
+ import { computed, ref } from 'vue';
1205
1204
  import { BbTextarea } from 'bitboss-ui';
1206
1205
  import { useInvoiceForm } from './context';
1207
1206
  import type { LineItemDraft } from '~/types';
@@ -1213,21 +1212,12 @@ const ctx = useInvoiceForm();
1213
1212
  // Rung 1 of the ladder: only this cell reads or writes its editing state.
1214
1213
  const editing = ref(false);
1215
1214
  const value = ref<string | null>(null);
1216
- const inputRef = ref<{ $el?: HTMLElement } | null>(null);
1217
1215
 
1218
1216
  const hasError = computed(() => !!ctx.lineItemError(props.line, 'description'));
1219
1217
 
1220
- /** Focus the native textarea after the editor mounts — HTML `autofocus` only
1221
- * runs on page load, not on later mounts. */
1222
- const focusInput = async () => {
1223
- await nextTick();
1224
- inputRef.value?.$el?.querySelector('textarea')?.focus();
1225
- };
1226
-
1227
1218
  const start = () => {
1228
1219
  value.value = props.line.description;
1229
1220
  editing.value = true;
1230
- void focusInput();
1231
1221
  };
1232
1222
 
1233
1223
  // Commit on blur, revert on Esc (inline-editing table). Enter inserts a newline (textarea),
@@ -1252,8 +1242,8 @@ const revert = () => {
1252
1242
  <template>
1253
1243
  <BbNumberInput
1254
1244
  v-if="editing"
1255
- ref="inputRef"
1256
1245
  v-model="value"
1246
+ autofocus
1257
1247
  class="[&_input]:text-right"
1258
1248
  compact
1259
1249
  :errors="ctx.lineItemError(line, 'quantity')"
@@ -1302,7 +1292,7 @@ const revert = () => {
1302
1292
  </template>
1303
1293
 
1304
1294
  <script setup lang="ts">
1305
- import { computed, nextTick, ref } from 'vue';
1295
+ import { computed, ref } from 'vue';
1306
1296
  import { BbButton, BbNumberInput } from 'bitboss-ui';
1307
1297
  import { useInvoiceForm } from './context';
1308
1298
  import type { LineItemDraft } from '~/types';
@@ -1313,21 +1303,12 @@ const ctx = useInvoiceForm();
1313
1303
 
1314
1304
  const editing = ref(false);
1315
1305
  const value = ref<number | null>(null);
1316
- const inputRef = ref<{ $el?: HTMLElement } | null>(null);
1317
1306
 
1318
1307
  const hasError = computed(() => !!ctx.lineItemError(props.line, 'quantity'));
1319
1308
 
1320
- /** Focus the native input after the editor mounts — HTML `autofocus` only
1321
- * runs on page load, not on later mounts. */
1322
- const focusInput = async () => {
1323
- await nextTick();
1324
- inputRef.value?.$el?.querySelector('input')?.focus();
1325
- };
1326
-
1327
1309
  const start = () => {
1328
1310
  value.value = props.line.quantity;
1329
1311
  editing.value = true;
1330
- void focusInput();
1331
1312
  };
1332
1313
 
1333
1314
  const commit = () => {
@@ -1351,8 +1332,8 @@ const revert = () => {
1351
1332
  <template>
1352
1333
  <BbNumberInput
1353
1334
  v-if="editing"
1354
- ref="inputRef"
1355
1335
  v-model="value"
1336
+ autofocus
1356
1337
  class="[&_input]:text-right"
1357
1338
  compact
1358
1339
  :errors="ctx.lineItemError(line, 'unitPrice')"
@@ -1379,7 +1360,7 @@ const revert = () => {
1379
1360
  </template>
1380
1361
 
1381
1362
  <script setup lang="ts">
1382
- import { computed, nextTick, ref } from 'vue';
1363
+ import { computed, ref } from 'vue';
1383
1364
  import { BbNumberInput } from 'bitboss-ui';
1384
1365
  import { useInvoiceForm } from './context';
1385
1366
  import type { LineItemDraft } from '~/types';
@@ -1390,7 +1371,6 @@ const ctx = useInvoiceForm();
1390
1371
 
1391
1372
  const editing = ref(false);
1392
1373
  const value = ref<number | null>(null);
1393
- const inputRef = ref<{ $el?: HTMLElement } | null>(null);
1394
1374
 
1395
1375
  const hasError = computed(() => !!ctx.lineItemError(props.line, 'unitPrice'));
1396
1376
 
@@ -1399,17 +1379,9 @@ const currency = new Intl.NumberFormat('en-US', {
1399
1379
  currency: 'USD',
1400
1380
  });
1401
1381
 
1402
- /** Focus the native input after the editor mounts — HTML `autofocus` only
1403
- * runs on page load, not on later mounts. */
1404
- const focusInput = async () => {
1405
- await nextTick();
1406
- inputRef.value?.$el?.querySelector('input')?.focus();
1407
- };
1408
-
1409
1382
  const start = () => {
1410
1383
  value.value = props.line.unitPrice;
1411
1384
  editing.value = true;
1412
- void focusInput();
1413
1385
  };
1414
1386
 
1415
1387
  const commit = () => {