bitboss-ui 3.0.0-beta.47 → 3.0.0-beta.49

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 (398) hide show
  1. package/README.md +24 -7
  2. package/bin/bitboss-ui-mcp.mjs +15 -3
  3. package/bin/bitboss-ui.mjs +167 -14
  4. package/dist/ai/BbAccordion.md +1 -1
  5. package/dist/ai/BbAvatar.md +1 -1
  6. package/dist/ai/BbBreadcrumbs.md +65 -65
  7. package/dist/ai/BbButton.md +28 -8
  8. package/dist/ai/BbCheckbox.md +0 -2
  9. package/dist/ai/BbCheckboxGroup.md +13 -20
  10. package/dist/ai/BbCollapsible.md +1 -1
  11. package/dist/ai/BbColorPalette.md +1 -1
  12. package/dist/ai/BbConfirm.md +8 -0
  13. package/dist/ai/BbConfirmPortal.md +1 -1
  14. package/dist/ai/BbDatePickerInput.md +4 -2
  15. package/dist/ai/BbDialog.md +1 -8
  16. package/dist/ai/BbDropdown.md +231 -220
  17. package/dist/ai/BbDropdownButton.md +65 -65
  18. package/dist/ai/BbDropdownGroup.md +2 -2
  19. package/dist/ai/BbDropzone.md +10 -10
  20. package/dist/ai/BbForm.md +43 -52
  21. package/dist/ai/BbHoverCard.md +19 -7
  22. package/dist/ai/BbHoverCardPortal.md +1 -1
  23. package/dist/ai/BbNumberInput.md +88 -21
  24. package/dist/ai/BbPopover.md +47 -40
  25. package/dist/ai/BbPopoverPortal.md +1 -1
  26. package/dist/ai/BbProgress.md +48 -22
  27. package/dist/ai/BbRadioGroup.md +13 -19
  28. package/dist/ai/BbSelect.md +16 -36
  29. package/dist/ai/BbSelectPopover.md +14 -30
  30. package/dist/ai/BbSmoothHeight.md +0 -2
  31. package/dist/ai/BbSwitchGroup.md +13 -20
  32. package/dist/ai/BbTable.md +11 -10
  33. package/dist/ai/BbTabs.md +107 -106
  34. package/dist/ai/BbTabsList.md +2 -2
  35. package/dist/ai/BbTabsPanels.md +1 -1
  36. package/dist/ai/BbTabsRoot.md +3 -3
  37. package/dist/ai/BbTooltip.md +29 -13
  38. package/dist/ai/BbTree.md +14 -11
  39. package/dist/ai/CommonPopover.md +1 -1
  40. package/dist/ai/changelog.json +297 -6
  41. package/dist/ai/components.json +50 -45
  42. package/dist/ai/composables/useBbDropdownContext.md +16 -16
  43. package/dist/ai/composables/useBbFormField.md +5 -1
  44. package/dist/ai/composables/useBbTabsContext.md +14 -14
  45. package/dist/ai/guides/agent-contract.md +27 -27
  46. package/dist/ai/guides/ai-router.md +1 -1
  47. package/dist/ai/guides/component-picker.md +3 -3
  48. package/dist/ai/guides/fetch-items-playbook.md +1 -1
  49. package/dist/ai/guides/icons-policy.md +10 -10
  50. package/dist/ai/guides/inertia-helpers.md +120 -67
  51. package/dist/ai/guides/installation-and-plugin-setup.md +45 -15
  52. package/dist/ai/guides/migration/components/bb-breadcrumbs.md +3 -2
  53. package/dist/ai/guides/migration/components/bb-checkbox-group.md +16 -16
  54. package/dist/ai/guides/migration/components/bb-dropdown-button.md +9 -8
  55. package/dist/ai/guides/migration/components/bb-dropdown.md +15 -14
  56. package/dist/ai/guides/migration/components/bb-radio-group.md +2 -1
  57. package/dist/ai/guides/migration/components/bb-select-popover.md +6 -1
  58. package/dist/ai/guides/migration/components/bb-select.md +10 -2
  59. package/dist/ai/guides/migration/components/bb-switch-group.md +2 -1
  60. package/dist/ai/guides/migration/components/bb-tabs.md +9 -8
  61. package/dist/ai/guides/migration/components/bb-tooltip.md +1 -1
  62. package/dist/ai/guides/migration/v2-to-v3.md +143 -28
  63. package/dist/ai/guides/migration/v3-beta-css-classes.md +29 -27
  64. package/dist/ai/guides/migration/v3-beta-tooling.md +11 -0
  65. package/dist/ai/guides/options-items-playbook.md +30 -24
  66. package/dist/ai/guides/passthrough.md +4 -4
  67. package/dist/ai/guides/preset-components.md +18 -3
  68. package/dist/ai/guides/typescript-generic-components.md +1 -1
  69. package/dist/ai/guides/validated-forms.md +11 -22
  70. package/dist/ai/guides/validation-providers.md +4 -3
  71. package/dist/ai/helpers/inertia/manifest.json +636 -0
  72. package/dist/ai/helpers/inertia/types.ts +15 -0
  73. package/dist/ai/helpers/inertia/useAsyncFn.ts +110 -0
  74. package/dist/ai/helpers/inertia/useConfirmOnRouteLeave.ts +102 -0
  75. package/dist/ai/helpers/inertia/useDeleteCmd.ts +30 -0
  76. package/dist/ai/helpers/inertia/useHasChanged.ts +36 -0
  77. package/dist/ai/helpers/inertia/useIndexById.ts +23 -0
  78. package/dist/ai/helpers/inertia/useLazyProp.ts +148 -0
  79. package/dist/ai/helpers/inertia/useLazyPropGetter.ts +50 -0
  80. package/dist/ai/helpers/inertia/useLoading.ts +20 -0
  81. package/dist/ai/helpers/inertia/usePaginatedResponseContext.ts +88 -0
  82. package/dist/ai/helpers/inertia/usePromiseForm.ts +62 -0
  83. package/dist/ai/helpers/inertia/useProp.ts +63 -0
  84. package/dist/ai/helpers/inertia/useQuery.ts +19 -0
  85. package/dist/ai/helpers/inertia/useQueryObject.ts +116 -0
  86. package/dist/ai/helpers/inertia/useResourceContext.ts +69 -0
  87. package/dist/ai/helpers/inertia/useRouteQuery.ts +54 -0
  88. package/dist/ai/helpers/inertia/useScreenSizes.ts +23 -0
  89. package/dist/ai/helpers/inertia/useTableContext.ts +34 -0
  90. package/dist/ai/helpers/inertia/useTableSelectionContext.ts +48 -0
  91. package/dist/ai/helpers/inertia/useUntil.ts +33 -0
  92. package/dist/ai/helpers/inertia/utils.ts +24 -0
  93. package/dist/ai/index.md +6 -6
  94. package/dist/ai/manifest/components/BbAccordion.json +1 -1
  95. package/dist/ai/manifest/components/BbBreadcrumbs.json +10 -6
  96. package/dist/ai/manifest/components/BbBreadcrumbs.tree.json +1 -1
  97. package/dist/ai/manifest/components/BbButton.json +2 -1
  98. package/dist/ai/manifest/components/BbButton.tree.json +1 -1
  99. package/dist/ai/manifest/components/BbCheckboxGroup.json +2 -2
  100. package/dist/ai/manifest/components/BbCollapsible.json +1 -1
  101. package/dist/ai/manifest/components/BbColorPalette.json +1 -1
  102. package/dist/ai/manifest/components/BbConfirmPortal.json +5 -2
  103. package/dist/ai/manifest/components/BbDropdown.json +23 -20
  104. package/dist/ai/manifest/components/BbDropdown.tree.json +2 -2
  105. package/dist/ai/manifest/components/BbDropdownButton.json +22 -19
  106. package/dist/ai/manifest/components/BbDropdownButton.tree.json +1 -1
  107. package/dist/ai/manifest/components/BbDropdownGroup.json +2 -2
  108. package/dist/ai/manifest/components/BbForm.json +1 -0
  109. package/dist/ai/manifest/components/BbHoverCard.json +1 -1
  110. package/dist/ai/manifest/components/BbHoverCardPortal.json +2 -2
  111. package/dist/ai/manifest/components/BbNumberInput.json +6 -1
  112. package/dist/ai/manifest/components/BbNumberInput.tree.json +2 -1
  113. package/dist/ai/manifest/components/BbPopover.json +2 -1
  114. package/dist/ai/manifest/components/BbPopoverPortal.json +2 -2
  115. package/dist/ai/manifest/components/BbProgress.json +6 -6
  116. package/dist/ai/manifest/components/BbProgress.tree.json +1 -0
  117. package/dist/ai/manifest/components/BbRadioGroup.json +2 -2
  118. package/dist/ai/manifest/components/BbSelect.json +2 -2
  119. package/dist/ai/manifest/components/BbSelect.tree.json +2 -2
  120. package/dist/ai/manifest/components/BbSelectPopover.json +2 -2
  121. package/dist/ai/manifest/components/BbSelectPopover.tree.json +1 -1
  122. package/dist/ai/manifest/components/BbSwitchGroup.json +2 -2
  123. package/dist/ai/manifest/components/BbTabs.json +8 -7
  124. package/dist/ai/manifest/components/BbTabsList.json +3 -3
  125. package/dist/ai/manifest/components/BbTabsPanels.json +1 -1
  126. package/dist/ai/manifest/components/BbTabsRoot.json +6 -5
  127. package/dist/ai/manifest/components/BbTag.tree.json +1 -1
  128. package/dist/ai/manifest/components/BbTooltip.json +2 -2
  129. package/dist/ai/manifest/components/ChipsBox.tree.json +1 -1
  130. package/dist/ai/manifest/components/CommonPopover.json +1 -1
  131. package/dist/ai/manifest/index.json +2 -2
  132. package/dist/ai/manifest/meta.json +5 -0
  133. package/dist/ai/manifest/types.advanced.json +10 -9
  134. package/dist/ai/manifest/types.api.json +8 -5
  135. package/dist/ai/manifest/types.wrapper.json +1 -0
  136. package/dist/ai/recipes/inertia/approvals-inbox.md +16 -18
  137. package/dist/ai/recipes/inertia/inline-edit-workspace.md +23 -33
  138. package/dist/ai/recipes/inertia/layout-scaffold.md +16 -16
  139. package/dist/ai/recipes/inertia/onboarding.md +6 -10
  140. package/dist/ai/recipes/inertia/ownership-atlas.md +15 -18
  141. package/dist/ai/recipes/inertia/record-form.md +11 -11
  142. package/dist/ai/recipes/inertia/records-workspace.md +38 -41
  143. package/dist/ai/recipes/inertia/settings-workspace.md +26 -38
  144. package/dist/ai/recipes/inertia/upload-center.md +31 -39
  145. package/dist/ai/recipes/inertia/wizard-form.md +10 -19
  146. package/dist/ai/recipes/nuxt/approvals-inbox.md +7 -8
  147. package/dist/ai/recipes/nuxt/inline-edit-workspace.md +14 -24
  148. package/dist/ai/recipes/nuxt/layout-scaffold.md +16 -16
  149. package/dist/ai/recipes/nuxt/onboarding.md +2 -6
  150. package/dist/ai/recipes/nuxt/ownership-atlas.md +7 -9
  151. package/dist/ai/recipes/nuxt/record-form.md +5 -5
  152. package/dist/ai/recipes/nuxt/records-workspace.md +29 -31
  153. package/dist/ai/recipes/nuxt/settings-workspace.md +22 -34
  154. package/dist/ai/recipes/nuxt/upload-center.md +22 -29
  155. package/dist/ai/recipes/nuxt/wizard-form.md +3 -11
  156. package/dist/ai/recipes/vue/approvals-inbox.md +7 -8
  157. package/dist/ai/recipes/vue/inline-edit-workspace.md +14 -24
  158. package/dist/ai/recipes/vue/layout-scaffold.md +16 -16
  159. package/dist/ai/recipes/vue/onboarding.md +2 -6
  160. package/dist/ai/recipes/vue/ownership-atlas.md +7 -9
  161. package/dist/ai/recipes/vue/record-form.md +5 -5
  162. package/dist/ai/recipes/vue/records-workspace.md +29 -31
  163. package/dist/ai/recipes/vue/settings-workspace.md +22 -34
  164. package/dist/ai/recipes/vue/upload-center.md +22 -29
  165. package/dist/ai/recipes/vue/wizard-form.md +3 -11
  166. package/dist/ai/source/BbAccordion.md +1 -1
  167. package/dist/ai/source/BbAlert.md +3 -3
  168. package/dist/ai/source/BbBadge.md +14 -10
  169. package/dist/ai/source/BbBadgeButton.md +17 -12
  170. package/dist/ai/source/BbBaseButton.md +1 -1
  171. package/dist/ai/source/BbBaseRadioIcon.md +1 -0
  172. package/dist/ai/source/BbBaseSwitchIcon.md +1 -0
  173. package/dist/ai/source/BbBreadcrumbs.md +63 -42
  174. package/dist/ai/source/BbButton.md +84 -38
  175. package/dist/ai/source/BbCalendar.md +17 -16
  176. package/dist/ai/source/BbCheckbox.md +3 -2
  177. package/dist/ai/source/BbCheckboxGroup.md +11 -4
  178. package/dist/ai/source/BbCollapsible.md +2 -1
  179. package/dist/ai/source/BbColorInput.md +10 -9
  180. package/dist/ai/source/BbColorPalette.md +2 -1
  181. package/dist/ai/source/BbConfirm.md +18 -1
  182. package/dist/ai/source/BbConfirmPortal.md +20 -6
  183. package/dist/ai/source/BbDatePicker.md +2 -2
  184. package/dist/ai/source/BbDatePickerInput.md +47 -20
  185. package/dist/ai/source/BbDialog.md +5 -5
  186. package/dist/ai/source/BbDropdown.md +231 -158
  187. package/dist/ai/source/BbDropdownButton.md +19 -12
  188. package/dist/ai/source/BbDropdownGroup.md +127 -93
  189. package/dist/ai/source/BbForm.md +25 -1
  190. package/dist/ai/source/BbHoverCard.md +30 -3
  191. package/dist/ai/source/BbHoverCardPortal.md +18 -3
  192. package/dist/ai/source/BbIndicator.md +4 -0
  193. package/dist/ai/source/BbNumberInput.md +855 -19
  194. package/dist/ai/source/BbOffCanvas.md +27 -11
  195. package/dist/ai/source/BbPagination.md +3 -3
  196. package/dist/ai/source/BbPopover.md +185 -12
  197. package/dist/ai/source/BbPopoverPortal.md +30 -3
  198. package/dist/ai/source/BbProgress.md +82 -18
  199. package/dist/ai/source/BbRadioGroup.md +12 -5
  200. package/dist/ai/source/BbRating.md +11 -9
  201. package/dist/ai/source/BbSelect.md +16 -10
  202. package/dist/ai/source/BbSelectPopover.md +29 -23
  203. package/dist/ai/source/BbSlider.md +12 -6
  204. package/dist/ai/source/BbSwitch.md +3 -2
  205. package/dist/ai/source/BbSwitchGroup.md +5 -2
  206. package/dist/ai/source/BbTable.md +102 -18
  207. package/dist/ai/source/BbTabs.md +30 -24
  208. package/dist/ai/source/BbTabsList.md +29 -23
  209. package/dist/ai/source/BbTabsPanels.md +29 -23
  210. package/dist/ai/source/BbTabsRoot.md +28 -22
  211. package/dist/ai/source/BbTag.md +10 -9
  212. package/dist/ai/source/BbTextInput.md +5 -4
  213. package/dist/ai/source/BbTextarea.md +6 -5
  214. package/dist/ai/source/BbTimePicker.md +1 -1
  215. package/dist/ai/source/BbTimePickerInput.md +46 -9
  216. package/dist/ai/source/BbToast.md +10 -7
  217. package/dist/ai/source/BbToastPortal.md +10 -7
  218. package/dist/ai/source/BbTooltip.md +88 -11
  219. package/dist/ai/source/BbTree.md +21 -3
  220. package/dist/ai/source/CommonField.md +6 -4
  221. package/dist/ai/source/CommonFieldInput.md +15 -10
  222. package/dist/ai/source/CommonPopover.md +8 -1
  223. package/dist/ai/source/CommonTimeSelector.md +5 -4
  224. package/dist/components/BbBadge/BbBadgeButton.vue_vue_type_script_setup_true_lang.js +10 -8
  225. package/dist/components/BbBaseButton/BbBaseButton.vue_vue_type_script_setup_true_lang.js +8 -8
  226. package/dist/components/BbBreadcrumbs/BbBreadcrumbs.vue_vue_type_script_setup_true_lang.js +45 -45
  227. package/dist/components/BbBreadcrumbs/types.d.ts +25 -17
  228. package/dist/components/BbButton/BbButton.vue_vue_type_script_setup_true_lang.js +88 -70
  229. package/dist/components/BbButton/toggleRoving.d.ts +6 -0
  230. package/dist/components/BbButton/toggleRoving.js +45 -0
  231. package/dist/components/BbButton/types.d.ts +12 -4
  232. package/dist/components/BbButton/types.js +5 -1
  233. package/dist/components/BbCalendar/BbCalendar.vue_vue_type_script_setup_true_lang.js +178 -178
  234. package/dist/components/BbCalendar/CalendarMonthPanel.vue_vue_type_script_setup_true_lang.js +15 -15
  235. package/dist/components/BbCalendar/CalendarYearPanel.vue_vue_type_script_setup_true_lang.js +28 -28
  236. package/dist/components/BbCalendar/useCalendarGrid.js +141 -139
  237. package/dist/components/BbCalendar/useDayjsLocale.d.ts +38 -15
  238. package/dist/components/BbCalendar/useDayjsLocale.js +31 -30
  239. package/dist/components/BbCheckbox/BbCheckbox.vue_vue_type_script_setup_true_lang.js +48 -48
  240. package/dist/components/BbCheckboxGroup/BbCheckboxGroup.vue_vue_type_script_setup_true_lang.js +81 -80
  241. package/dist/components/BbCheckboxGroup/types.d.ts +6 -2
  242. package/dist/components/BbCollapsible/types.d.ts +2 -1
  243. package/dist/components/BbColorInput/BbColorInput.vue_vue_type_script_setup_true_lang.js +69 -69
  244. package/dist/components/BbColorPalette/types.d.ts +2 -1
  245. package/dist/components/BbConfirm/BbConfirmPortal.vue.d.ts +2 -5
  246. package/dist/components/BbConfirm/types.d.ts +15 -0
  247. package/dist/components/BbDatePickerInput/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +363 -349
  248. package/dist/components/BbDropdown/AdaptiveDropdown.vue_vue_type_script_setup_true_lang.js +91 -86
  249. package/dist/components/BbDropdown/BbDropdown.vue_vue_type_script_setup_true_lang.js +298 -289
  250. package/dist/components/BbDropdown/BbDropdownList.vue_vue_type_script_setup_true_lang.js +322 -356
  251. package/dist/components/BbDropdown/DropdownPipelineResolver.vue_vue_type_script_setup_true_lang.js +17 -15
  252. package/dist/components/BbDropdown/DropdownRow.vue.d.ts +40 -0
  253. package/dist/components/BbDropdown/DropdownRow.vue.js +5 -0
  254. package/dist/components/BbDropdown/DropdownRow.vue_vue_type_script_setup_true_lang.js +60 -0
  255. package/dist/components/BbDropdown/normalizeGroups.d.ts +8 -2
  256. package/dist/components/BbDropdown/normalizeGroups.js +60 -46
  257. package/dist/components/BbDropdown/types.d.ts +120 -88
  258. package/dist/components/BbDropdownButton/BbDropdownButton.vue_vue_type_script_setup_true_lang.js +11 -2
  259. package/dist/components/BbDropdownButton/types.d.ts +2 -2
  260. package/dist/components/BbForm/BbForm.vue.d.ts +9 -0
  261. package/dist/components/BbForm/BbForm.vue_vue_type_script_setup_true_lang.js +114 -105
  262. package/dist/components/BbForm/BbFormCustomField.js +1 -1
  263. package/dist/components/BbForm/bindFormField.js +2 -1
  264. package/dist/components/BbForm/formFields.d.ts +5 -0
  265. package/dist/components/BbHoverCard/BbHoverCard.vue_vue_type_script_setup_true_lang.js +145 -142
  266. package/dist/components/BbHoverCard/BbHoverCardPortal.vue.d.ts +2 -2
  267. package/dist/components/BbHoverCard/types.d.ts +14 -1
  268. package/dist/components/BbNumberInput/BbNumberInput.vue.d.ts +0 -1
  269. package/dist/components/BbNumberInput/BbNumberInput.vue_vue_type_script_setup_true_lang.js +452 -125
  270. package/dist/components/BbNumberInput/numberDisplay.d.ts +256 -0
  271. package/dist/components/BbNumberInput/numberDisplay.js +499 -0
  272. package/dist/components/BbNumberInput/types.d.ts +54 -1
  273. package/dist/components/BbNumberInput/warroom/corpus.d.ts +58 -0
  274. package/dist/components/BbNumberInput/warroom/currency-verify.rows.d.ts +28 -0
  275. package/dist/components/BbNumberInput/warroom/currency.rows.d.ts +2 -0
  276. package/dist/components/BbNumberInput/warroom/harness.d.ts +217 -0
  277. package/dist/components/BbNumberInput/warroom/oracle.d.ts +150 -0
  278. package/dist/components/BbPagination/BbPagination.vue_vue_type_script_setup_true_lang.js +7 -7
  279. package/dist/components/BbPopover/BbPopover.vue.d.ts +1 -0
  280. package/dist/components/BbPopover/BbPopover.vue_vue_type_script_setup_true_lang.js +207 -162
  281. package/dist/components/BbPopover/BbPopoverPortal.vue.d.ts +2 -2
  282. package/dist/components/BbPopover/types.d.ts +26 -1
  283. package/dist/components/BbProgress/BbProgress.vue_vue_type_script_setup_true_lang.js +15 -7
  284. package/dist/components/BbProgress/types.d.ts +23 -7
  285. package/dist/components/BbProgress/types.js +1 -1
  286. package/dist/components/BbRadioGroup/BbRadioGroup.vue_vue_type_script_setup_true_lang.js +102 -101
  287. package/dist/components/BbRadioGroup/types.d.ts +6 -2
  288. package/dist/components/BbRating/BbRating.vue_vue_type_script_setup_true_lang.js +63 -63
  289. package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +156 -154
  290. package/dist/components/BbSelect/types.d.ts +6 -2
  291. package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +2 -1
  292. package/dist/components/BbSelectPopover/types.d.ts +6 -2
  293. package/dist/components/BbSlider/BbSlider.vue_vue_type_script_setup_true_lang.js +153 -153
  294. package/dist/components/BbSwitch/BbSwitch.vue_vue_type_script_setup_true_lang.js +62 -62
  295. package/dist/components/BbSwitchGroup/BbSwitchGroup.vue_vue_type_script_setup_true_lang.js +131 -130
  296. package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +711 -676
  297. package/dist/components/BbTabs/BbTabs.vue_vue_type_script_setup_true_lang.js +1 -1
  298. package/dist/components/BbTabs/BbTabsList.vue_vue_type_script_setup_true_lang.js +1 -1
  299. package/dist/components/BbTabs/types.d.ts +28 -22
  300. package/dist/components/BbTag/BbTag.vue_vue_type_script_setup_true_lang.js +76 -76
  301. package/dist/components/BbTextInput/BbTextInput.vue_vue_type_script_setup_true_lang.js +58 -58
  302. package/dist/components/BbTextarea/BbTextarea.vue_vue_type_script_setup_true_lang.js +82 -82
  303. package/dist/components/BbTimePickerInput/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +246 -236
  304. package/dist/components/BbTooltip/BbTooltip.vue_vue_type_script_setup_true_lang.js +99 -86
  305. package/dist/components/BbTooltip/tooltipWarmup.d.ts +23 -0
  306. package/dist/components/BbTooltip/tooltipWarmup.js +7 -0
  307. package/dist/components/BbTooltip/types.d.ts +10 -3
  308. package/dist/components/BbTree/BbTree.vue_vue_type_script_setup_true_lang.js +29 -21
  309. package/dist/components/BbTree/BbTreeLevel.vue_vue_type_script_setup_true_lang.js +10 -7
  310. package/dist/components/CommonFieldInput/CommonFieldInput.vue_vue_type_script_setup_true_lang.js +37 -36
  311. package/dist/components/CommonPopover/types.d.ts +2 -1
  312. package/dist/components/CommonTimeSelector/CommonTimeSelector.vue_vue_type_script_setup_true_lang.js +9 -9
  313. package/dist/composables/formSubmitLock.d.ts +6 -0
  314. package/dist/composables/formSubmitLock.js +4 -0
  315. package/dist/composables/useBaseOptions.d.ts +7 -1
  316. package/dist/composables/useBaseOptions.js +32 -32
  317. package/dist/composables/useBbDropdownContext.d.ts +8 -8
  318. package/dist/composables/useBbFormField.d.ts +9 -0
  319. package/dist/composables/useBbFormField.js +5 -3
  320. package/dist/composables/useBbTabsContext.d.ts +10 -10
  321. package/dist/composables/useBbTabsContext.js +18 -18
  322. package/dist/composables/useFormBinding.d.ts +11 -0
  323. package/dist/composables/useFormBinding.js +15 -13
  324. package/dist/composables/useItemText.d.ts +5 -1
  325. package/dist/composables/useItemText.js +8 -3
  326. package/dist/composables/useItemValue.d.ts +5 -1
  327. package/dist/composables/useItemValue.js +8 -3
  328. package/dist/composables/useLocale.js +10 -9
  329. package/dist/deprecation/ai-deprecations.json.d.ts +130 -0
  330. package/dist/deprecation/ai-deprecations.json.js +1 -1
  331. package/dist/deprecation/removedProps.js +1 -1
  332. package/dist/directives/bbDropdown.js +1 -1
  333. package/dist/directives/directivePortal.d.ts +13 -7
  334. package/dist/directives/directivePortal.js +1 -4
  335. package/dist/i18n/index.d.ts +7 -12
  336. package/dist/i18n/locales/cs.json +11 -14
  337. package/dist/i18n/locales/da.json +13 -16
  338. package/dist/i18n/locales/de-CH.json +137 -0
  339. package/dist/i18n/locales/de.json +14 -17
  340. package/dist/i18n/locales/el.json +10 -13
  341. package/dist/i18n/locales/en-GB.json +137 -0
  342. package/dist/i18n/locales/en.json +8 -11
  343. package/dist/i18n/locales/es-MX.json +137 -0
  344. package/dist/i18n/locales/es.json +16 -19
  345. package/dist/i18n/locales/fi.json +8 -11
  346. package/dist/i18n/locales/fr.json +23 -26
  347. package/dist/i18n/locales/hu.json +8 -11
  348. package/dist/i18n/locales/it.json +12 -15
  349. package/dist/i18n/locales/ja.json +13 -16
  350. package/dist/i18n/locales/ko.json +10 -13
  351. package/dist/i18n/locales/nb.json +13 -16
  352. package/dist/i18n/locales/nl.json +21 -24
  353. package/dist/i18n/locales/pl.json +10 -13
  354. package/dist/i18n/locales/{pt.json → pt-BR.json} +19 -22
  355. package/dist/i18n/locales/pt-PT.json +137 -0
  356. package/dist/i18n/locales/ro.json +22 -25
  357. package/dist/i18n/locales/ru.json +11 -14
  358. package/dist/i18n/locales/sv.json +16 -19
  359. package/dist/i18n/locales/tr.json +14 -17
  360. package/dist/i18n/locales/uk.json +11 -14
  361. package/dist/i18n/locales/{zh-cn.json → zh-CN.json} +10 -13
  362. package/dist/i18n/locales/zh-HK.json +137 -0
  363. package/dist/i18n/locales/zh-TW.json +137 -0
  364. package/dist/i18n/regionHints.d.ts +16 -0
  365. package/dist/i18n/regionHints.js +49 -0
  366. package/dist/i18n/regions.d.ts +286 -0
  367. package/dist/i18n/regions.js +265 -0
  368. package/dist/index.d.ts +4 -4
  369. package/dist/index.js +4 -4
  370. package/dist/llms-full.txt +1914 -1714
  371. package/dist/llms-medium.txt +76 -46
  372. package/dist/llms.txt +7 -7
  373. package/dist/locale-blueprint.json +16 -13
  374. package/dist/styles.css +2 -2
  375. package/dist/types/passthrough.d.ts +1 -1
  376. package/dist/types/ptComponentMap.d.ts +2 -2
  377. package/dist/utilities/functions/slotKey.d.ts +2 -2
  378. package/dist/utils/versionCheck.js +1 -1
  379. package/dist/vite-plugin.d.ts +22 -19
  380. package/dist/vite.js +309 -297
  381. package/llms.txt +7 -7
  382. package/package.json +5 -3
  383. package/scripts/lib/agent-manifest.mjs +2 -1
  384. package/scripts/lib/eslint-disable.mjs +17 -4
  385. package/scripts/lib/eslint-plugin.d.ts +9 -1
  386. package/scripts/lib/eslint-plugin.mjs +256 -6
  387. package/scripts/lib/helper-canon.mjs +176 -0
  388. package/scripts/lib/helpers-add.mjs +1303 -0
  389. package/scripts/lib/local-components.mjs +33 -4
  390. package/scripts/lib/locale-check.mjs +165 -0
  391. package/scripts/lib/portal-names.mjs +458 -0
  392. package/scripts/lib/redundant-item-accessor.mjs +398 -0
  393. package/scripts/lib/renamed-item-field.mjs +343 -0
  394. package/scripts/lib/slot-key.mjs +2 -2
  395. package/scripts/lib/slot-renames.mjs +1 -1
  396. package/scripts/lib/unimported-components.mjs +5 -2
  397. package/scripts/lib/validate-bb-markup.mjs +123 -56
  398. package/dist/i18n/index.js +0 -27
@@ -95,16 +95,16 @@ const last = ref('Unsaved changes');
95
95
 
96
96
  /** `items[0]` is the primary action; later rows open from the chevron. */
97
97
  const items: BbDropdownItem[] = [
98
- { key: 'save', text: 'Save', onClick: () => (last.value = 'Saved') },
98
+ { value: 'save', label: 'Save', onClick: () => (last.value = 'Saved') },
99
99
  {
100
- key: 'draft',
101
- text: 'Save as draft',
100
+ value: 'draft',
101
+ label: 'Save as draft',
102
102
  'prepend:icon': 'lucide:pencil',
103
103
  onClick: () => (last.value = 'Saved as draft'),
104
104
  },
105
105
  {
106
- key: 'template',
107
- text: 'Save as template',
106
+ value: 'template',
107
+ label: 'Save as template',
108
108
  'prepend:icon': 'lucide:copy',
109
109
  onClick: () => (last.value = 'Saved as template'),
110
110
  },
@@ -149,25 +149,25 @@ const last = ref('Not exported yet');
149
149
  /** Primary Export (default CSV) plus format alternates via `href`. */
150
150
  const items: BbDropdownItem[] = [
151
151
  {
152
- key: 'export',
153
- text: 'Export',
152
+ value: 'export',
153
+ label: 'Export',
154
154
  onClick: () => (last.value = 'Exported as CSV'),
155
155
  },
156
156
  {
157
- key: 'csv',
158
- text: 'Export as CSV',
157
+ value: 'csv',
158
+ label: 'Export as CSV',
159
159
  'prepend:icon': 'lucide:file-spreadsheet',
160
160
  href: '#export-csv',
161
161
  },
162
162
  {
163
- key: 'json',
164
- text: 'Export as JSON',
163
+ value: 'json',
164
+ label: 'Export as JSON',
165
165
  'prepend:icon': 'lucide:braces',
166
166
  href: '#export-json',
167
167
  },
168
168
  {
169
- key: 'pdf',
170
- text: 'Export as PDF',
169
+ value: 'pdf',
170
+ label: 'Export as PDF',
171
171
  'prepend:icon': 'lucide:file-text',
172
172
  href: '#export-pdf',
173
173
  },
@@ -192,17 +192,17 @@ both halves at once.
192
192
  <BbDropdownButton
193
193
  variant="outline"
194
194
  :items="[
195
- { key: 'export', text: 'Export', href: '#export' },
196
- { key: 'csv', text: 'Export as CSV', href: '#csv' },
197
- { key: 'json', text: 'Export as JSON', href: '#json' },
195
+ { value: 'export', label: 'Export', href: '#export' },
196
+ { value: 'csv', label: 'Export as CSV', href: '#csv' },
197
+ { value: 'json', label: 'Export as JSON', href: '#json' },
198
198
  ]"
199
199
  />
200
200
  <BbDropdownButton
201
201
  :size="{ sm: 'sm', lg: 'md' }"
202
202
  variant="secondary"
203
203
  :items="[
204
- { key: 'invite', text: 'Invite member', href: '#invite' },
205
- { key: 'link', text: 'Copy invite link', href: '#link' },
204
+ { value: 'invite', label: 'Invite member', href: '#invite' },
205
+ { value: 'link', label: 'Copy invite link', href: '#link' },
206
206
  ]"
207
207
  />
208
208
  </div>
@@ -251,8 +251,8 @@ const status = ref('Draft');
251
251
  */
252
252
  const items: BbDropdownItem[] = [
253
253
  {
254
- key: 'publish',
255
- text: 'Publish',
254
+ value: 'publish',
255
+ label: 'Publish',
256
256
  onClick: async () => {
257
257
  status.value = 'Publishing…';
258
258
  await new Promise((resolve) => setTimeout(resolve, 700));
@@ -260,14 +260,14 @@ const items: BbDropdownItem[] = [
260
260
  },
261
261
  },
262
262
  {
263
- key: 'schedule',
264
- text: 'Schedule…',
263
+ value: 'schedule',
264
+ label: 'Schedule…',
265
265
  'prepend:icon': 'lucide:clock',
266
266
  href: '#schedule',
267
267
  },
268
268
  {
269
- key: 'draft',
270
- text: 'Revert to draft',
269
+ value: 'draft',
270
+ label: 'Revert to draft',
271
271
  onClick: () => (status.value = 'Draft'),
272
272
  },
273
273
  ];
@@ -324,18 +324,18 @@ const { confirm } = useConfirm();
324
324
  /** Dangerous alternate stays behind the chevron, gated by `useConfirm`. */
325
325
  const items: BbDropdownItem[] = [
326
326
  {
327
- key: 'redeploy',
328
- text: 'Redeploy',
327
+ value: 'redeploy',
328
+ label: 'Redeploy',
329
329
  onClick: async () => {
330
330
  status.value = 'Rebuilding…';
331
331
  await new Promise((resolve) => setTimeout(resolve, 700));
332
332
  status.value = 'dpl_9m4a · deployed just now';
333
333
  },
334
334
  },
335
- { key: 'logs', text: 'View build logs', href: '#logs' },
335
+ { value: 'logs', label: 'View build logs', href: '#logs' },
336
336
  {
337
- key: 'delete',
338
- text: 'Delete deployment',
337
+ value: 'delete',
338
+ label: 'Delete deployment',
339
339
  variant: 'destructive',
340
340
  'prepend:icon': 'lucide:trash-2',
341
341
  onClick: async () => {
@@ -367,9 +367,9 @@ activator slot: the toggle button is part of the component's contract.
367
367
  toggle:icon="lucide:ellipsis"
368
368
  variant="outline"
369
369
  :items="[
370
- { key: 'open', text: 'Open', href: '#open' },
371
- { key: 'rename', text: 'Rename', href: '#rename' },
372
- { key: 'archive', text: 'Archive', href: '#archive' },
370
+ { value: 'open', label: 'Open', href: '#open' },
371
+ { value: 'rename', label: 'Rename', href: '#rename' },
372
+ { value: 'archive', label: 'Archive', href: '#archive' },
373
373
  ]"
374
374
  />
375
375
  ```
@@ -421,18 +421,18 @@ const status = ref('2 approvals · all checks passed');
421
421
  */
422
422
  const items = computed<BbDropdownItem[]>(() => [
423
423
  {
424
- key: 'merge-pr',
425
- text: labels[method.value],
424
+ value: 'merge-pr',
425
+ label: labels[method.value],
426
426
  onClick: () => (status.value = `Merged into main (${method.value})`),
427
427
  },
428
428
  {
429
- key: 'method',
429
+ id: 'method',
430
430
  label: 'Merge method',
431
431
  selectable: true,
432
432
  items: [
433
- { key: 'merge', text: 'Create a merge commit' },
434
- { key: 'squash', text: 'Squash and merge' },
435
- { key: 'rebase', text: 'Rebase and merge' },
433
+ { value: 'merge', label: 'Create a merge commit' },
434
+ { value: 'squash', label: 'Squash and merge' },
435
+ { value: 'rebase', label: 'Rebase and merge' },
436
436
  ],
437
437
  },
438
438
  ]);
@@ -448,10 +448,10 @@ reaching for the inner dropdown.
448
448
  Every slot except `activator` is forwarded into the inner `BbDropdown`:
449
449
  `header` / `footer` pin content around the scrolling items, `item:prepend` /
450
450
  `item:append` replace every row's icons, and named slots replace one row's
451
- content (`#<key>`) or edges (`#<key>:prepend` / `:append`) — see the
451
+ content (`#<value>`) or edges (`#<value>:prepend` / `:append`) — see the
452
452
  [BbDropdown guide](./BbDropdown.md) for payloads, naming and which slot wins.
453
453
  A `#activator` you pass is ignored: the toggle is part of this component
454
- (`toggle:icon` swaps its glyph). One caveat: a per-key slot for `items[0]` does nothing — that
454
+ (`toggle:icon` swaps its glyph). One caveat: a per-row slot for `items[0]` does nothing — that
455
455
  item is promoted into the main button and never renders as a menu row.
456
456
 
457
457
  The dropdown's positioning surface passes through as props: `placement`,
@@ -471,9 +471,9 @@ click), `anchor` (hard-wired to the split control) and `boundary`.
471
471
  variant="outline"
472
472
  :width="230"
473
473
  :items="[
474
- { key: 'new-doc', text: 'New document', href: '#new' },
475
- { key: 'from-template', text: 'From template…', href: '#template' },
476
- { key: 'import', text: 'Import file', href: '#import' },
474
+ { value: 'new-doc', label: 'New document', href: '#new' },
475
+ { value: 'from-template', label: 'From template…', href: '#template' },
476
+ { value: 'import', label: 'Import file', href: '#import' },
477
477
  ]"
478
478
  >
479
479
  <template #item:prepend>
@@ -552,16 +552,16 @@ import type { BbDropdownItem } from 'bitboss-ui';
552
552
  const last = ref('Unsaved changes');
553
553
 
554
554
  const items: BbDropdownItem[] = [
555
- { key: 'save', text: 'Save', onClick: () => (last.value = 'Saved') },
555
+ { value: 'save', label: 'Save', onClick: () => (last.value = 'Saved') },
556
556
  {
557
- key: 'draft',
558
- text: 'Save as draft',
557
+ value: 'draft',
558
+ label: 'Save as draft',
559
559
  'prepend:icon': 'lucide:pencil',
560
560
  onClick: () => (last.value = 'Saved as draft'),
561
561
  },
562
562
  {
563
- key: 'template',
564
- text: 'Save as template',
563
+ value: 'template',
564
+ label: 'Save as template',
565
565
  'prepend:icon': 'lucide:copy',
566
566
  disabled: true,
567
567
  },
@@ -637,7 +637,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
637
637
  | `compact` | `boolean \| undefined` | `false` | | Apply the compact density variant — the same ladder `BbSelect` uses, on both surfaces: flyout rows go 28px → 24px, sheet rows 44px → 36px. The label size does not change; density here is height, as it is for a select. A menu row is a touch target in a way a select option is not quite — a mis-tap fires the neighbouring COMMAND rather than picking the wrong value — so the compact sheet stops at 36px and never follows the flyout down to 24px. That is the same floor the select's sheet holds. |
638
638
  | `disableAutoLoading` | `boolean \| undefined` | `false` | | Disables the automatic loading state that tracks async actions (enabled by default). Only affects the main action button: the split toggle half still mirrors the dropdown's internal async-action loading state. |
639
639
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component |
640
- | `eager` | `boolean \| undefined` | `false` | | Prevents rendering content before it's made visible. |
640
+ | `eager` | `boolean \| undefined` | `false` | | Renders the menu panel at mount instead of on the first open (the phone sheet's too), and keeps its rows after a close. Without it the rows mount on each open and go once the menu has closed. |
641
641
  | `id` | `string \| undefined` | | | Names this dropdown: the activator's id (unless it already has one), the menu's `menu_<id>`, and the key `useBbDropdownContext(id)` and a companion `BbDropdownGroup` pair by. Generated when omitted. |
642
642
  | `items` | `BbDropdownItem[]` | `[]` | yes | Array used to render each dropdown button. They can act as `button`, as `a`, or as `router-link` as they are based on the functionality provided by `BbBaseButton`. Pass a flat array for a single group, nest arrays for divider-separated groups, or pass {@link InternalGroup} objects for titled / selectable sections. An item may carry its own `items` to open a submenu. The shapes can be mixed. |
643
643
  | `loading` | `boolean \| undefined` | `false` | | Triggers a loading indicator. |
@@ -670,9 +670,9 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
670
670
  | `footer` | The band around your `#footer` slot: at the bottom of the menu on desktop, the sheet's footer on a phone — handed to the `BbDropdown`. |
671
671
  | `input` | A searchable group's search field in the menu — a broadcast, every searchable group's field — handed to the `BbDropdown` as its own `pt:input`. |
672
672
  | `item` | One menu entry, submenus included — a broadcast resolved per entry. Also takes a per-item function, called with the entry. |
673
- | `itemText` | An entry's label (its `text`) — resolved with that entry's states. A per-entry `#<key>` slot replaces it. Also takes a per-item function. |
673
+ | `itemText` | An entry's label (its `label`) — resolved with that entry's states. A per-entry `#<value>` slot replaces it. Also takes a per-item function. |
674
674
  | `itemIcon` | An entry's prepend / append icons — resolved with that entry's states. Also takes a per-item function. |
675
- | `itemDescription` | An entry's muted second line (its `description`) — resolved with that entry's states. A per-entry `#<key>` slot replaces it. Also takes a per-item function. |
675
+ | `itemDescription` | An entry's muted second line (its `description`) — resolved with that entry's states. A per-entry `#<value>` slot replaces it. Also takes a per-item function. |
676
676
 
677
677
  States are listed in precedence order: when two are on at once and their entries conflict, the later one wins.
678
678
 
@@ -695,21 +695,21 @@ States are listed in precedence order: when two are on at once and their entries
695
695
  ## Slots
696
696
 
697
697
  - `default` — scope: `any` — Companion content forwarded into the dropdown (e.g. `<BbDropdownGroup>`).
698
- - `empty` — scope: `BbDropdownPlaceholderSlotProps` `{ groupKey?: string; text: string; error?: unknown }` — Replaces the default "no data" placeholder row shown in a pipeline group that resolved to no items. Rendered once per empty group. Forwarded to the underlying `BbDropdown`.
698
+ - `empty` — scope: `BbDropdownPlaceholderSlotProps` `{ groupId?: string; text: string; error?: unknown }` — Replaces the default "no data" placeholder row shown in a pipeline group that resolved to no items. Rendered once per empty group. Forwarded to the underlying `BbDropdown`.
699
699
  - `footer` — scope: `BbDropdownButtonEdgeSlotProps` `{ disabled?: boolean; open: boolean; placement: Placement \| "cursor" }` — Content pinned to the bottom of the dropdown panel, outside the scroll area.
700
700
  - `header` — scope: `BbDropdownButtonEdgeSlotProps` `{ disabled?: boolean; open: boolean; placement: Placement \| "cursor" }` — Content pinned to the top of the dropdown panel, outside the scroll area.
701
- - `item:append` — scope: `BbDropdownButtonItemSlotProps` `{ disabled?: boolean; index: number; item: InternalItem; open: boolean; placement: Placement \| "cursor"; text: string }` — The trailing region of every menu row, replacing its `append:icon`; the submenu chevron and the check on a selected row take its place (BbDropdown's rules).
702
- - `item:prepend` — scope: `BbDropdownButtonItemSlotProps` `{ disabled?: boolean; index: number; item: InternalItem; open: boolean; placement: Placement \| "cursor"; text: string }` — The leading region of every menu row, replacing its `prepend:icon` (BbDropdown's rules).
703
- - `loading` — scope: `BbDropdownPlaceholderSlotProps` `{ groupKey?: string; text: string; error?: unknown }` — Replaces the default loading placeholder row shown in a pipeline group while its async items load. Rendered once per loading group. Forwarded to the underlying `BbDropdown`.
704
- - `#<key>` (named from data) — scope: `BbDropdownItemSlotProps` — One row's content (text and description), by its key; in a fetched group, by its resolved `itemValue`. Reserved keys (their slot is one of this component's own, so a key spelled like them is an error): `default`, `empty`, `footer`, `header`, `item`, `loading`.
705
- - `#<key>:prepend` (named from data) — scope: `BbDropdownItemSlotProps` — One row's leading region; replaces its `prepend:icon`.
706
- - `#<key>:append` (named from data) — scope: `BbDropdownItemSlotProps` — One row's trailing region; replaces its `append:icon` and its submenu chevron. The check takes its place on the selected row.
707
- - `#<groupKey>:item` (named from data) — scope: `BbDropdownItemSlotProps` — The content of every row of that group, and no other; a row's own `#<key>` still wins.
708
- - `#<groupKey>:item:prepend` (named from data) — scope: `BbDropdownItemSlotProps` — The leading region of every row of that group — e.g. an avatar per record, drawn from `item.meta`, while other rows keep their `prepend:icon`.
709
- - `#<groupKey>:item:append` (named from data) — scope: `BbDropdownItemSlotProps` — The trailing region of every row of that group; replaces their `append:icon`. The check takes its place on the selected row.
710
- - `#<groupKey>` (named from data) — scope: `BbDropdownItemSlotProps` — That group's title line (the group is passed as `item`, `groupTitle` is `true`). Reserved keys (their slot is one of this component's own, so a key spelled like them is an error): `default`, `empty`, `footer`, `header`, `item`, `loading`.
711
- - `#<groupKey>:prepend` (named from data) — scope: `BbDropdownItemSlotProps` — The leading region of that group's title line.
712
- - `#<groupKey>:append` (named from data) — scope: `BbDropdownItemSlotProps` — The trailing region of that group's title line.
701
+ - `item:append` — scope: `BbDropdownButtonItemSlotProps` `{ disabled?: boolean; index: number; item: InternalItem; open: boolean; placement: Placement \| "cursor"; label: string }` — The trailing region of every menu row, replacing its `append:icon`; the submenu chevron and the check on a selected row take its place (BbDropdown's rules).
702
+ - `item:prepend` — scope: `BbDropdownButtonItemSlotProps` `{ disabled?: boolean; index: number; item: InternalItem; open: boolean; placement: Placement \| "cursor"; label: string }` — The leading region of every menu row, replacing its `prepend:icon` (BbDropdown's rules).
703
+ - `loading` — scope: `BbDropdownPlaceholderSlotProps` `{ groupId?: string; text: string; error?: unknown }` — Replaces the default loading placeholder row shown in a pipeline group while its async items load. Rendered once per loading group. Forwarded to the underlying `BbDropdown`.
704
+ - `#<value>` (named from data) — scope: `BbDropdownItemSlotProps` — One row's content (label and description), by its value; in a fetched group, by its resolved `itemValue`. Reserved names (their slot is one of this component's own, so an item value or column key spelled like them is an error): `default`, `empty`, `footer`, `header`, `item`, `loading`.
705
+ - `#<value>:prepend` (named from data) — scope: `BbDropdownItemSlotProps` — One row's leading region; replaces its `prepend:icon`.
706
+ - `#<value>:append` (named from data) — scope: `BbDropdownItemSlotProps` — One row's trailing region; replaces its `append:icon` and its submenu chevron. The check takes its place on the selected row.
707
+ - `#<groupId>:item` (named from data) — scope: `BbDropdownItemSlotProps` — The content of every row of that group, and no other; a row's own `#<value>` still wins.
708
+ - `#<groupId>:item:prepend` (named from data) — scope: `BbDropdownItemSlotProps` — The leading region of every row of that group — e.g. an avatar per record, drawn from `item.meta`, while other rows keep their `prepend:icon`.
709
+ - `#<groupId>:item:append` (named from data) — scope: `BbDropdownItemSlotProps` — The trailing region of every row of that group; replaces their `append:icon`. The check takes its place on the selected row.
710
+ - `#<groupId>` (named from data) — scope: `BbDropdownItemSlotProps` — That group's title line (the group is passed as `item`, `groupTitle` is `true`). Reserved names (their slot is one of this component's own, so an item value or column key spelled like them is an error): `default`, `empty`, `footer`, `header`, `item`, `loading`.
711
+ - `#<groupId>:prepend` (named from data) — scope: `BbDropdownItemSlotProps` — The leading region of that group's title line.
712
+ - `#<groupId>:append` (named from data) — scope: `BbDropdownItemSlotProps` — The trailing region of that group's title line.
713
713
 
714
714
  ## Component tree
715
715
 
@@ -724,7 +724,7 @@ States are listed in precedence order: when two are on at once and their entries
724
724
  - `BbButton` _(public — [contract](./BbButton.md))_ — its own pt parts (`BbButton`): `root` → `BbBaseButton`, `spinner` → `BbSpinner`, `icon` → `BbIcon`, `text` → `span.bb-button__text`; documented CSS variables: `--h-xs`, `--h`, `--icon-size`, `--px`, `--fs`, `--r`, `--gap`, `--bg`, `--bg-hover`, `--bg-pressed`, `--fg`, `--border-color`, `--ring-color`, `--ring-size`, `--bw`, `--fg-hover`, `--border-hover`, `--fg-pressed`, `--border-pressed`, `--bg-disabled`, `--fg-disabled`, `--border-disabled`, `--opacity-disabled`, `--elev-tier`, `--elev`; also mounts `BbIcon`, `BbSpinner`
725
725
  - `BbBaseButton` _(public — [contract](./BbBaseButton.md))_ — its own pt parts (`BbBaseButton`): `root` → `RouterComponent`, `root` → `a`, `root` → `component`; also mounts `RouterComponent`
726
726
  - `BbDropdown` _(public — [contract](./BbDropdown.md))_ — its own pt parts (`BbDropdown`): `panel` → `CommonPopover`, `root` → `CommonPopover`, `header` → `div.bb-dropdown__header`, `list` → `span.bb-dropdown__list`, `footer` → `div.bb-dropdown__footer`; documented CSS variables: `--menu-inset`; also mounts `CommonPopover`, `DropdownPipelineResolver`
727
- - `BbDropdownList` _(internal — not importable, reach it through `BbDropdown`)_ — also mounts `BbBaseButton`, `BbIcon`, `ErrorIcon`, `CommonPopover`, `BbDropdownList`
727
+ - `BbDropdownList` _(internal — not importable, reach it through `BbDropdown`)_ — also mounts `BbIcon`, `ErrorIcon`, `CommonPopover`, `BbDropdownList`
728
728
  - `BbBadge` _(public — [contract](./BbBadge.md))_ — its own pt parts (`BbBadge`): `spinner` → `BbSpinner`, `icon` → `BbIcon`, `clear` → `button.bb-badge__clear`; documented CSS variables: `--bg`, `--fg`, `--bw`, `--ring-color`, `--ring-size`, `--min-size-md`, `--min-size`, `--elev`, `--r`, `--fs`, `--icon-size`, `--gap`, `--px`, `--clear-size`, `--bg-disabled`, `--fg-disabled`, `--border-disabled`, `--pad-left`; also mounts `BbIcon`, `BbSpinner`, `BadgeBodyContent`
729
729
  - `AdaptiveDropdown` _(internal — not importable, reach it through `BbDropdown`)_ — hands `BbOffCanvas` the pt map `{ header: 'header', footer: 'footer', panel: 'root', sheet: 'root' }` (ours → theirs); also mounts `BbSmoothHeight`, `BbButton`, `BbDropdownList`
730
730
  - `BbOffCanvas` _(public — [contract](./BbOffCanvas.md))_ — its own pt parts (`BbOffCanvas`): `header` → `div.bb-offcanvas__header`, `title` → `span.bb-offcanvas__title`, `description` → `p.bb-offcanvas__description`, `close` → `CloseButton`, `content` → `div.bb-offcanvas__content`, `footer` → `div.bb-offcanvas__footer`; documented CSS variables: `--stack-x`, `--stack-fill`, `--stack-transition-duration`, `--px`, `--handle-w`, `--handle-h`, `--handle-bg`, `--safe-top`, `--close-size`
@@ -16,12 +16,12 @@
16
16
 
17
17
  | Prop | Type | Default | Required | Description |
18
18
  | --- | --- | --- | --- | --- |
19
- | `id` | `string` | | yes | Identifier of the group to bind to — must match the `key` of a group declared in the host `BbDropdown`'s `items`. |
19
+ | `id` | `string` | | yes | Identifier of the group to bind to — must match the `id` of a group declared in the host `BbDropdown`'s `items`. |
20
20
  | `modelValue` | `any` | | | The group's selection: one value for a single group, an array for a `multiple` one. Read by the owning BbDropdown through the group's `id`. |
21
21
 
22
22
  ## Events
23
23
 
24
- - `item:selected` — `(value: any): void` — The user picked a row, at the click, a pick you then refuse included — with the item's resolved value (its `item-value` for pipeline groups, else its `key`), symmetric with `BbTable`. Your own `v-model` changes fire none.
24
+ - `item:selected` — `(value: any): void` — The user picked a row, at the click, a pick you then refuse included — with the row's value (its `item-value` for pipeline groups, else its `value`), symmetric with `BbTable`. Your own `v-model` changes fire none.
25
25
  - `item:unselected` — `(value: any): void` — The user unpicked a row (or a single pick replaced it), with its resolved value.
26
26
  - `update:modelValue` — `(value: any): void` — The value a user change asks for (a pick, a chip ×, a coherence prune). With a listener the group is controlled: the rows tick when you write the value, and ignoring it leaves them as they are.
27
27
 
@@ -264,9 +264,9 @@ const onError = (error: DropZoneError) => {
264
264
  display: flex;
265
265
  gap: 0.5rem;
266
266
  justify-content: center;
267
+ padding-inline-end: 0.75rem;
268
+ padding-inline-start: 0.75rem;
267
269
  padding-bottom: 0.5rem;
268
- padding-left: 0.75rem;
269
- padding-right: 0.75rem;
270
270
  padding-top: 0.5rem;
271
271
  transition:
272
272
  border-color var(--bb-transition-fast) var(--bb-ease),
@@ -462,9 +462,9 @@ const remove = (file: File) => {
462
462
  border-radius: var(--bb-radius);
463
463
  display: flex;
464
464
  gap: 0.5rem;
465
+ padding-inline-end: 0.75rem;
466
+ padding-inline-start: 0.75rem;
465
467
  padding-bottom: 0.375rem;
466
- padding-left: 0.75rem;
467
- padding-right: 0.75rem;
468
468
  padding-top: 0.375rem;
469
469
  }
470
470
  </style>
@@ -697,9 +697,9 @@ const onError = (error: DropZoneError) => {
697
697
  border-radius: var(--bb-radius-sm);
698
698
  color: var(--bb-text-muted);
699
699
  font-size: 0.75rem;
700
+ padding-inline-end: 0.375rem;
701
+ padding-inline-start: 0.375rem;
700
702
  padding-bottom: 0.125rem;
701
- padding-left: 0.375rem;
702
- padding-right: 0.375rem;
703
703
  padding-top: 0.125rem;
704
704
  }
705
705
 
@@ -954,8 +954,8 @@ const remove = (file: File) => {
954
954
  display: flex;
955
955
  gap: 0.5rem;
956
956
  min-height: 2.75rem;
957
- padding-left: 0.75rem;
958
- padding-right: 0.25rem;
957
+ padding-inline-end: 0.25rem;
958
+ padding-inline-start: 0.75rem;
959
959
  }
960
960
  </style>
961
961
  ```
@@ -1358,9 +1358,9 @@ const submit = () => {
1358
1358
  border-radius: var(--bb-radius);
1359
1359
  display: flex;
1360
1360
  gap: 0.5rem;
1361
+ padding-inline-end: 0.75rem;
1362
+ padding-inline-start: 0.75rem;
1361
1363
  padding-bottom: 0.375rem;
1362
- padding-left: 0.75rem;
1363
- padding-right: 0.75rem;
1364
1364
  padding-top: 0.375rem;
1365
1365
  }
1366
1366
 
package/dist/ai/BbForm.md CHANGED
@@ -82,7 +82,6 @@ covers Zod 3.24+ and 4, Valibot 1, ArkType 2 and Yup 1.7+.
82
82
  -->
83
83
  <BbForm
84
84
  id="signup"
85
- v-slot="{ isSubmitting }"
86
85
  class="grid max-w-md gap-3 rounded-(--bb-radius) border p-4"
87
86
  :schema="signup"
88
87
  @submit="createAccount"
@@ -105,9 +104,7 @@ covers Zod 3.24+ and 4, Valibot 1, ArkType 2 and Yup 1.7+.
105
104
  </div>
106
105
  <BbCheckbox label="I accept the terms" name="terms" />
107
106
 
108
- <BbButton :loading="isSubmitting" type="submit" variant="primary">
109
- Create account
110
- </BbButton>
107
+ <BbButton type="submit" variant="primary"> Create account </BbButton>
111
108
 
112
109
  <p v-if="created" class="text-sm" data-testid="created" role="status">
113
110
  Welcome, {{ created.name }} ({{ created.email }}).
@@ -175,8 +172,8 @@ What you get from the one prop:
175
172
  handler as `(values: z.output<typeof schema>) => …` (or
176
173
  `v.InferOutput<…>`) and it checks. Joi has no static types, so with a Joi
177
174
  schema the payload is `any`: annotate the handler yourself.
178
- - **`isSubmitting` still covers your handler**: return its promise and the
179
- button spins until it settles.
175
+ - **Return the handler's promise** and the form locks while it runs: fields
176
+ read-only, the submit button spinning ([While it saves](#while-it-saves)).
180
177
 
181
178
  The same form in Valibot, with array rows:
182
179
 
@@ -191,7 +188,6 @@ The same form in Valibot, with array rows:
191
188
  also what a native form post (and PHP / Laravel) nests correctly.
192
189
  -->
193
190
  <BbForm
194
- v-slot="{ isSubmitting }"
195
191
  class="grid max-w-lg gap-3 rounded-(--bb-radius) border p-4"
196
192
  :model="draft"
197
193
  :schema="order"
@@ -239,9 +235,7 @@ The same form in Valibot, with array rows:
239
235
  </BbButton>
240
236
  </fieldset>
241
237
 
242
- <BbButton :loading="isSubmitting" type="submit" variant="primary">
243
- Save order
244
- </BbButton>
238
+ <BbButton type="submit" variant="primary"> Save order </BbButton>
245
239
 
246
240
  <pre
247
241
  v-if="saved"
@@ -360,12 +354,10 @@ const save = async (values: Record<string, unknown>) => {
360
354
  </script>
361
355
 
362
356
  <template>
363
- <BbForm v-slot="{ isSubmitting }" @submit="save">
357
+ <BbForm @submit="save">
364
358
  <BbTextInput label="Full name" rules="required" />
365
359
  <BbTextInput label="Email" rules="required|email" type="email" />
366
- <BbButton :loading="isSubmitting" type="submit" variant="primary">
367
- Save
368
- </BbButton>
360
+ <BbButton type="submit" variant="primary"> Save </BbButton>
369
361
  </BbForm>
370
362
  </template>
371
363
  ```
@@ -400,10 +392,10 @@ const send = async (values: Record<string, unknown>) => {
400
392
 
401
393
  <template>
402
394
  <p>Inviting {{ who }}</p>
403
- <BbForm id="invite" v-slot="{ values, isSubmitting }" @submit="send">
395
+ <BbForm id="invite" v-slot="{ values }" @submit="send">
404
396
  <BbTextInput label="Email" name="email" rules="required|email" />
405
397
  <p>{{ values.email ? `Send to ${values.email}` : 'Type an email' }}</p>
406
- <BbButton :loading="isSubmitting" type="submit">Invite</BbButton>
398
+ <BbButton type="submit">Invite</BbButton>
407
399
  </BbForm>
408
400
  </template>
409
401
  ```
@@ -538,7 +530,6 @@ step you cannot leave is simply a submit that does not pass.
538
530
  a step you cannot leave is a submit that does not pass.
539
531
  -->
540
532
  <BbForm
541
- v-slot="{ isSubmitting }"
542
533
  class="grid max-w-md gap-4 rounded-(--bb-radius) border p-4"
543
534
  keep-values-on-unmount
544
535
  :model="checkout"
@@ -606,12 +597,7 @@ step you cannot leave is simply a submit that does not pass.
606
597
  <BbButton v-if="step > 0" variant="ghost" @click="go(step - 1)">
607
598
  Back
608
599
  </BbButton>
609
- <BbButton
610
- class="ms-auto"
611
- :loading="isSubmitting"
612
- type="submit"
613
- variant="primary"
614
- >
600
+ <BbButton class="ms-auto" type="submit" variant="primary">
615
601
  {{ step < steps.length - 1 ? 'Next' : 'Place order' }}
616
602
  </BbButton>
617
603
  </footer>
@@ -841,33 +827,46 @@ const bodyRules = computed(() => (publishing.value ? 'required' : ''));
841
827
  Both switch live: the next validation uses the new schema or rules, and
842
828
  switching back lets a submit through that was blocked a moment ago.
843
829
 
844
- ### `isSubmitting` covers your submit, not just validation
830
+ ### While it saves
845
831
 
846
- Bind a button's `loading` to `isSubmitting` (or to `submitting` from
847
- `useBbFormContext`) and it stays on for as long as your handler is actually
848
- working — **return the promise** and the form waits for it:
832
+ **Return the promise** from `@submit` and the form treats the save as running
833
+ until it settles:
849
834
 
850
835
  ```vue
851
- <!-- the spinner runs until save() settles -->
852
836
  <BbForm
853
837
  @submit="
854
838
  async (values) => {
855
839
  await api.save(values);
856
840
  }
857
841
  "
858
- />
842
+ >
843
+ <BbTextInput label="Name" name="name" />
844
+ <BbButton type="submit">Save</BbButton>
845
+ </BbForm>
859
846
  ```
860
847
 
861
- A synchronous handler resolves immediately, as you would expect. If your
862
- handler throws or rejects, the flag still clears (so the button never spins
863
- forever) and the error is routed to `app.config.errorHandler`, the same place
864
- Vue sends any other event-handler failure — so a global reporter keeps seeing
865
- it.
866
-
867
- > Fixed in 3.0.0-beta.15 (Q18.3). Before that, `isSubmitting` cleared as soon
868
- > as _validation_ resolved, so the spinner flashed for a frame and the user
869
- > could double-submit a save still in flight. If you worked around it with your
870
- > own `saving` ref, you can drop it.
848
+ While it runs:
849
+
850
+ - **Every field joined to the form is read-only**, never disabled: values stay
851
+ visible, focus stays where it was, nothing greys out, and assistive tech
852
+ hears `aria-readonly`. A `useBbFormField` control reads the same state from
853
+ its handle's `readonly` (its `controlAttrs` carry `aria-readonly`, and writes
854
+ to `value` are ignored).
855
+ - **Every `type="submit"` BbButton inside the form spins**, so it cannot be
856
+ pressed twice. Other buttons (Cancel, a row action) are untouched. A submit
857
+ button outside the form (a dialog footer's `form="…"`) binds
858
+ `:loading="useBbFormContext(id).submitting.value"` itself.
859
+ - When the promise settles each field goes back to its own `readonly`, so a
860
+ field that was read-only stays read-only.
861
+
862
+ A synchronous handler never locks. A handler that throws or rejects still ends
863
+ the save (nothing spins forever), and the error goes to
864
+ `app.config.errorHandler`, where Vue sends any other event-handler failure.
865
+ `isSubmitting` (slot) and `submitting` (`useBbFormContext`) follow the same
866
+ save, for anything else you show meanwhile.
867
+
868
+ To keep the fields editable during the save, set `disable-submit-lock` on the
869
+ form.
871
870
 
872
871
  ### Saving in place: `snapshot()`
873
872
 
@@ -1089,11 +1088,7 @@ const save = async (values: Record<string, unknown>) => {
1089
1088
  </script>
1090
1089
 
1091
1090
  <template>
1092
- <BbForm
1093
- id="signup"
1094
- v-slot="{ errors, unmatchedErrors, isSubmitting }"
1095
- @submit="save"
1096
- >
1091
+ <BbForm id="signup" v-slot="{ errors, unmatchedErrors }" @submit="save">
1097
1092
  <!-- Every error in one summary: the two maps never share a path. -->
1098
1093
  <BbAlert
1099
1094
  v-if="Object.keys({ ...errors, ...unmatchedErrors }).length"
@@ -1108,7 +1103,7 @@ const save = async (values: Record<string, unknown>) => {
1108
1103
  </BbAlert>
1109
1104
  <BbTextInput label="Email" name="email" type="email" />
1110
1105
  <BbTextInput label="City" name="address[city]" />
1111
- <BbButton :loading="isSubmitting" type="submit">Create account</BbButton>
1106
+ <BbButton type="submit">Create account</BbButton>
1112
1107
  </BbForm>
1113
1108
  </template>
1114
1109
  ```
@@ -1259,7 +1254,7 @@ lifting state into the page. It carries `values`, `isSubmitting`, `submitCount`,
1259
1254
 
1260
1255
  ```vue
1261
1256
  <template>
1262
- <BbForm v-slot="{ dirty, valid, isSubmitting, resetForm }" @submit="save">
1257
+ <BbForm v-slot="{ dirty, valid, resetForm }" @submit="save">
1263
1258
  <BbTextInput label="Display name" rules="required" />
1264
1259
  <BbTextarea label="Bio" rules="max:280" />
1265
1260
 
@@ -1267,12 +1262,7 @@ lifting state into the page. It carries `values`, `isSubmitting`, `submitCount`,
1267
1262
  <BbButton :disabled="!dirty" variant="ghost" @click="resetForm()">
1268
1263
  Discard
1269
1264
  </BbButton>
1270
- <BbButton
1271
- :disabled="!valid"
1272
- :loading="isSubmitting"
1273
- type="submit"
1274
- variant="primary"
1275
- >
1265
+ <BbButton :disabled="!valid" type="submit" variant="primary">
1276
1266
  Save changes
1277
1267
  </BbButton>
1278
1268
  </footer>
@@ -1435,6 +1425,7 @@ marker stays consistent with the rules.
1435
1425
 
1436
1426
  | Prop | Type | Default | Required | Description |
1437
1427
  | --- | --- | --- | --- | --- |
1428
+ | `disableSubmitLock` | `boolean \| undefined` | `false` | | Keep the fields editable while a save runs. By default, while a `@submit` that returned a promise is pending, every field joined to the form is read-only (never disabled: values stay readable and focusable) and every `type="submit"` BbButton inside the form shows its spinner; both end when the promise settles. A `@submit` that returns nothing never locks. |
1438
1429
  | `fieldErrors` | `Record<string, unknown> \| null \| undefined` | | | A server's validation errors, shown on the fields they name, for as long as they are in the object: `form.errors` from Inertia's `useForm()`, `$page.props.errors`, a Laravel 422 body you kept in a `ref`. Keys are field paths (`email`, `address.city`, `address[city]`, `lines.0.qty`); a value is a message or a list of them; a nested object reads as dot paths. `null`, `undefined` and anything that is not a message show nothing. A key no field on the form has is in `unmatchedErrors`. The page owns them: editing the field does not hide its message, the next object you pass does. They never block a submit, and a field's own rule errors show first. When new messages arrive after a submit, the first field that has one takes focus. For a one-off message the form drops once the user edits the field, call `setErrors` instead. |
1439
1430
  | `id` | `string \| undefined` | | | Explicit id, so anything outside the form can read and drive it through `useBbFormContext(id)` — a dialog footer's submit button, a page toolbar, a leave guard. It is also the `<form>`'s own id, so a native `<button form="id" type="submit">` outside it submits it. Omit it when the form is self-contained: the slot scope already carries the same state for chrome that lives inside. |
1440
1431
  | `keepValuesOnUnmount` | `boolean \| Ref<boolean, boolean> \| undefined` | | | Keep a field's value (and its place in `@submit`) when it unmounts — the `v-if` wizard step you left, a collapsed section. Off, an unmounted field drops out of the values. |
@@ -214,10 +214,12 @@ const events = [
214
214
 
215
215
  ### Timing and the safe zone
216
216
 
217
- `delay` (default `350` ms, the same prop name as `BbTooltip`'s) is how long the
217
+ `delay` (default `350` ms, the same prop name as `BbTooltip`'s, whose default
218
+ is `100`) is how long the
218
219
  pointer has to rest on the activator before the card opens — long enough that a
219
220
  pointer passing over a list of names doesn't flash a card for each. Keyboard
220
- focus opens it after `delay` too. Closing has no prop: once the pointer has left
221
+ focus opens it after `delay` too, and there is no skip delay: unlike a
222
+ tooltip, each card waits its full `delay`. Closing has no prop: once the pointer has left
221
223
  both the activator and the card, the card waits a fixed 200 ms, the time the
222
224
  pointer needs to cross the gap into the card.
223
225
 
@@ -292,7 +294,8 @@ A directive has no slot, so the card's body is a **portal**, as in
292
294
  `person-card` is `person` minus `card`, and nothing opens (`check` flags it).
293
295
  The portal's slot gets `{ props, close }`.
294
296
  - **A component:** `v-bb-hover-card="PersonCard"` renders `PersonCard` in the
295
- card. It can close the card with `emit('close')`.
297
+ card, with `portalProps` as its real props. It gets no `close`: content that
298
+ needs one is a named portal, or the `BbHoverCard` component.
296
299
  - **The object form** takes either one as `portal`, data for it as
297
300
  `portalProps` (the named portal's `props`, or the component's real props),
298
301
  and any `BbHoverCard` prop: `{ portal: 'person-card', portalProps: { person },
@@ -302,6 +305,15 @@ The portal's content sees the page around it, as if it were written inline:
302
305
  a component portal injects from where the trigger is, a named portal from
303
306
  where its `<BbHoverCardPortal>` is declared.
304
307
 
308
+ **Names are checked.** A name is a string on one side and a `<BbHoverCardPortal
309
+ name>` on the other, so `bitboss-ui check` and the ESLint rules (in
310
+ `recommended`) read both across the project: `bitboss-ui/portal-names`
311
+ fails on a name no file declares, with a did-you-mean (`'renam'` → `rename`),
312
+ and on a popover portal opened by `v-bb-hover-card` (it names the family the portal belongs to); `bitboss-ui/unused-portal` warns on a
313
+ `<BbHoverCardPortal>` nothing opens. Only literal names are judged: a `:name`
314
+ binding or a name held in a variable is never reported. The slot's `props`
315
+ is `any` per key, so `props.person.name` needs no cast.
316
+
305
317
  **A card per row, from the directive**
306
318
 
307
319
  ```vue
@@ -328,11 +340,11 @@ where its `<BbHoverCardPortal>` is declared.
328
340
  <BbHoverCardPortal v-slot="{ props }" name="person-card">
329
341
  <div class="grid gap-0.5">
330
342
  <div class="font-medium text-(--bb-text)">
331
- {{ (props.person as Person).name }}
343
+ {{ props.person.name }}
332
344
  </div>
333
345
  <div class="text-xs text-(--bb-text-muted)">
334
- {{ (props.person as Person).team }} ·
335
- {{ (props.person as Person).city }}
346
+ {{ props.person.team }} ·
347
+ {{ props.person.city }}
336
348
  </div>
337
349
  </div>
338
350
  </BbHoverCardPortal>
@@ -454,7 +466,7 @@ value written in `<script>` is typed as `BbHoverCardProps['pt']`.
454
466
  | `boundary` | `ElementOrComponentRefOrSelector \| undefined` | | | Constrains the card within a bounding element. When provided, the card will not overflow this container's bounds (e.g. a sidebar). Accepts an HTMLElement, a Vue component ref, or a CSS selector string. |
455
467
  | `delay` | `number \| undefined` | `350` | | The delay in milliseconds before the card is shown: how long the pointer rests on the activator, or keyboard focus stays on it. BbTooltip's name; a different default, because a card that opened on every pass of the pointer would be in the way. Closing has a fixed grace instead (see the guide § Timing and the safe zone). |
456
468
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component. Disabling an open card closes it. |
457
- | `eager` | `boolean \| undefined` | `false` | | Prevents rendering content before it's made visible. |
469
+ | `eager` | `boolean \| undefined` | `false` | | Renders the card's content at mount instead of on the first open. |
458
470
  | `id` | `string \| undefined` | | | The activator's id (the card is `bbhc_<id>`, and is labelled by it once it holds a control). Generated when omitted. |
459
471
  | `modelValue` | `boolean \| undefined` | `false` | | Used by v-model to open / close the card. A card with no `v-model` starts closed and is driven by hover and keyboard focus. |
460
472
  | `offset` | `number \| undefined` | `4` | | Space the floating container will maintain from the activator. |