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
@@ -35,7 +35,7 @@ Each `pt` part now has a class with the same name, on the same element:
35
35
 
36
36
  <!-- generated:count -->
37
37
 
38
- In numbers: **85** classes renamed, **23** added beside an existing class, and **7** new state classes and elements.
38
+ In numbers: **86** classes renamed, **23** added beside an existing class, and **7** new state classes and elements.
39
39
 
40
40
  <!-- /generated:count -->
41
41
 
@@ -75,7 +75,7 @@ bash and zsh. On Windows, use Git Bash or WSL.
75
75
 
76
76
  ```sh
77
77
  rg -nP --glob '!node_modules' --glob '!dist' --glob '!rename-bb-classes.mjs' \
78
- '(?<![\w-])(bb-checkbox-group-item__description|bb-switch-group-item__description|bb-radio-group-item__description|bb-dropdown-button__dropdown-btn|bb-segmented-field__trigger-btn|bb-select-popover__search-input|bb-select-popover__search-clear|bb-listbox__option-description|bb-dropzone__interactive-label|bb-time-picker-input-offcanvas|bb-checkbox-group-item__label|bb-dropdown__items-container|bb-dropdown-button__main-btn|bb-pagination__page-chevron|bb-switch-group-item__label|bb-table-column-ghost__icon|bb-select-popover-offcanvas|bb-radio-group-item__label|bb-color-palette-offcanvas|bb-checkbox-group__no-data|bb-segmented-field__field|bb-time-selector__readout|bb-toast-message__content|bb-toast-message__actions|bb-color-palette__popover|bb-commabox-item--focused|bb-listbox__option-label|bb-calendar__header-cell|bb-calendar__date-button|bb-time-selector__header|bb-date-picker-offcanvas|bb-time-picker-offcanvas|bb-calendar__date-append|bb-switch-group__no-data|bb-indicator__indicator|bb-toast-message__title|bb-toast-message__close|bb-date-picker__popover|bb-time-picker__popover|bb-toast-message__inner|bb-radio-group__no-data|bb-badge__clear-button|bb-checkbox-group-item|bb-toast-message__icon|bb-toast-message__text|bb-table-no-data__cell|bb-table-no-data__text|bb-select__comma-item|bb-calendar__controls|bb-time-selector__btn|bb-tabs-list__tablist|bb-table-no-data__row|bb-calendar__nav-btn|bb-switch-group-item|bb-popover-offcanvas|bb-field__hint-text|bb-tooltip__content|bb-radio-group-item|bb-table-header-row|bb-table-sort__icon|bb-table-data__cell|bb-listbox--no-data|bb-listbox__no-data|bb-tag__text-input|bb-button__content|bb-table-data__row|bb-offcanvas__body|bb-calendar__month|bb-badge__content|bb-calendar__date|item__description|bb-rating__option|bb-badge--focused|bb-chipsbox-item|bb-commabox-item|bb-table-caption|bb-tabs__trigger|bb-toast-message|bb-select__chip|bb-table-header|bb-dialog__body|bb-tree__node|bb-tabs-panes|bb-tabs__pane|item__text)(?![\w]|-(?!-))'
78
+ '(?<![\w-])(bb-checkbox-group-item__description|bb-switch-group-item__description|bb-radio-group-item__description|bb-dropdown-button__dropdown-btn|bb-segmented-field__trigger-btn|bb-select-popover__search-input|bb-select-popover__search-clear|bb-listbox__option-description|bb-dropzone__interactive-label|bb-time-picker-input-offcanvas|bb-checkbox-group-item__label|bb-dropdown__items-container|bb-dropdown-button__main-btn|bb-pagination__page-chevron|bb-switch-group-item__label|bb-table-column-ghost__icon|bb-select-popover-offcanvas|bb-radio-group-item__label|bb-color-palette-offcanvas|bb-checkbox-group__no-data|bb-segmented-field__field|bb-time-selector__readout|bb-toast-message__content|bb-toast-message__actions|bb-color-palette__popover|bb-commabox-item--focused|bb-listbox__option-label|bb-calendar__header-cell|bb-calendar__date-button|bb-time-selector__header|bb-date-picker-offcanvas|bb-time-picker-offcanvas|bb-calendar__date-append|bb-switch-group__no-data|bb-indicator__indicator|bb-toast-message__title|bb-toast-message__close|bb-date-picker__popover|bb-time-picker__popover|bb-toast-message__inner|bb-radio-group__no-data|bb-badge__clear-button|bb-checkbox-group-item|bb-toast-message__icon|bb-toast-message__text|bb-table-no-data__cell|bb-table-no-data__text|bb-select__comma-item|bb-calendar__controls|bb-time-selector__btn|bb-tabs-list__tablist|bb-table-no-data__row|bb-calendar__nav-btn|bb-switch-group-item|bb-popover-offcanvas|bb-field__hint-text|bb-tooltip__content|bb-radio-group-item|bb-table-header-row|bb-table-sort__icon|bb-table-data__cell|bb-listbox--no-data|bb-listbox__no-data|bb-tag__text-input|bb-button__content|bb-table-data__row|bb-offcanvas__body|bb-calendar__month|bb-badge__content|bb-calendar__date|item__description|bb-rating__option|bb-badge--focused|bb-button--active|bb-chipsbox-item|bb-commabox-item|bb-table-caption|bb-tabs__trigger|bb-toast-message|bb-select__chip|bb-table-header|bb-dialog__body|bb-tree__node|bb-tabs-panes|bb-tabs__pane|item__text)(?![\w]|-(?!-))'
79
79
  ```
80
80
 
81
81
  <!-- /generated:find -->
@@ -98,7 +98,7 @@ List the nested selectors that may spell an old name:
98
98
 
99
99
  ```sh
100
100
  rg -nP --glob '*.{css,scss,sass,less,styl,pcss,postcss,vue,svelte,astro}' --glob '!node_modules' --glob '!dist' \
101
- '(?:&|#\{&\})(-picker-input-offcanvas|__option-description|__interactive-label|-popover-offcanvas|-palette-offcanvas|__items-container|-picker-offcanvas|-input-offcanvas|__dropdown-btn|__search-input|__search-clear|__page-chevron|-item--focused|__option-label|__clear-button|__description|__trigger-btn|-column-ghost|__header-cell|__date-button|__date-append|-description|__comma-item|__text-input|-group-item|__indicator|__hint-text|-header-row|-offcanvas|-container|__main-btn|__controls|__no-data|__readout|-selector|__content|__actions|__popover|--focused|__tablist|__nav-btn|--no-data|__trigger|-popover|-chevron|-message|-palette|-focused|__header|-no-data|__option|-caption|-button|__label|__field|-append|__title|__close|-picker|__inner|__month|-header|-field|-input|-clear|-label|__icon|-ghost|-group|__text|__cell|__body|__date|__chip|__node|-panes|__pane|-item|-data|-cell|__btn|-list|__row|-text|-sort|-btn|-row)(?=[\s,{:.>+~\[)]|__|--|$)'
101
+ '(?:&|#\{&\})(-picker-input-offcanvas|__option-description|__interactive-label|-popover-offcanvas|-palette-offcanvas|__items-container|-picker-offcanvas|-input-offcanvas|__dropdown-btn|__search-input|__search-clear|__page-chevron|-item--focused|__option-label|__clear-button|__description|__trigger-btn|-column-ghost|__header-cell|__date-button|__date-append|-description|__comma-item|__text-input|-group-item|__indicator|__hint-text|-header-row|-offcanvas|-container|__main-btn|__controls|__no-data|__readout|-selector|__content|__actions|__popover|--focused|__tablist|__nav-btn|--no-data|__trigger|-popover|-chevron|-message|-palette|-focused|__header|-no-data|__option|--active|-caption|-button|__label|__field|-append|__title|__close|-picker|__inner|__month|-active|-header|-field|-input|-clear|-label|__icon|-ghost|-group|__text|__cell|__body|__date|__chip|__node|-panes|__pane|-item|-data|-cell|__btn|-list|__row|-text|-sort|-btn|-row)(?=[\s,{:.>+~\[)]|__|--|$)'
102
102
  ```
103
103
 
104
104
  <!-- /generated:nested -->
@@ -243,6 +243,7 @@ const MAP = {
243
243
  'bb-calendar__month': 'bb-calendar__month-grid',
244
244
  'bb-toast-message__inner': 'bb-toast__inner',
245
245
  'bb-badge--focused': 'bb-badge--highlighted',
246
+ 'bb-button--active': 'bb-button--pressed',
246
247
  'bb-commabox-item--focused': 'bb-tag__comma--highlighted',
247
248
  'bb-tabs-list__tablist': 'bb-tabs-list__list',
248
249
  'bb-tabs-panes': 'bb-tabs-panels',
@@ -723,29 +724,30 @@ consistent.
723
724
 
724
725
  ### Everything else
725
726
 
726
- | Before | After | Part | Note |
727
- | ----------------------------------- | -------------------------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
728
- | `.bb-badge__content` | `.bb-badge__text` | `text` | |
729
- | `.bb-badge__clear-button` | `.bb-badge__clear` | `clear` | |
730
- | `.bb-button__content` | `.bb-button__text` | `text` | |
731
- | `.bb-dropdown__items-container` | `.bb-dropdown__list` | `list` | |
732
- | `.item__text` | `.bb-dropdown__item-text` | `itemText` | No `bb-` prefix: the script only reports it. Rename it where it is the dropdown menu row's (inside a `.bb-dropdown` / `.bb-dropdown-button` selector); an `item__text` of your own stays. |
733
- | `.item__description` | `.bb-dropdown__item-description` | `itemDescription` | As above. |
734
- | `.bb-dropzone__interactive-label` | `.bb-dropzone__content` | `content` | |
735
- | `.bb-indicator__indicator` | `.bb-indicator__bubble` | `bubble` | |
736
- | `.bb-pagination__page-chevron` | `.bb-pagination__icon` | `icon` | |
737
- | `.bb-rating__option` | `.bb-rating__item` | `item` | |
738
- | `.bb-tooltip__content` | `.bb-tooltip__panel` | `panel` | |
739
- | `.bb-tree__node` | `.bb-tree__item` | `item` | |
740
- | `.bb-tabs__trigger` | `.bb-tabs-list__item` | `item` | The tab button is drawn by BbTabsList, so it takes BbTabsList's block. |
741
- | `.bb-badge--focused` | `.bb-badge--highlighted` | BbTag `badge`, state `highlighted` | The arrow-key cursor on a BbTag chip. It was never real focus (focus stays in the input), hence the new name. |
742
- | `.bb-tabs-list__tablist` | `.bb-tabs-list__list` | `list` | The sliding indicator is no longer this list's `::before`: it is an element, `.bb-tabs-list__indicator`, the list's first child. Move a `::before` override there. |
743
- | `.bb-tabs-panes` | `.bb-tabs-panels` | BbTabs `panels` (the BbTabsPanels root) | The component is renamed too: `BbTabsPanes` → `BbTabsPanels`. |
744
- | `.bb-tabs__pane` | `.bb-tabs__panel` | `panel` | Drawn by BbTabsPanels; the class keeps the tabs' own word for the part. |
745
- | `.bb-dropdown-button__main-btn` | `.bb-dropdown-button__main` | `main` | The main half of the split button (the `main` part). |
746
- | `.bb-dropdown-button__dropdown-btn` | `.bb-dropdown-button__toggle` | `toggle` | The chevron half that opens the menu (the `toggle` part). |
747
- | `.bb-checkbox-group__no-data` | `.bb-checkbox-group__empty` | `empty` | |
748
- | `.bb-radio-group__no-data` | `.bb-radio-group__empty` | `empty` | |
749
- | `.bb-switch-group__no-data` | `.bb-switch-group__empty` | `empty` | |
727
+ | Before | After | Part | Note |
728
+ | ----------------------------------- | -------------------------------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
729
+ | `.bb-badge__content` | `.bb-badge__text` | `text` | |
730
+ | `.bb-badge__clear-button` | `.bb-badge__clear` | `clear` | |
731
+ | `.bb-button__content` | `.bb-button__text` | `text` | |
732
+ | `.bb-dropdown__items-container` | `.bb-dropdown__list` | `list` | |
733
+ | `.item__text` | `.bb-dropdown__item-text` | `itemText` | No `bb-` prefix: the script only reports it. Rename it where it is the dropdown menu row's (inside a `.bb-dropdown` / `.bb-dropdown-button` selector); an `item__text` of your own stays. |
734
+ | `.item__description` | `.bb-dropdown__item-description` | `itemDescription` | As above. |
735
+ | `.bb-dropzone__interactive-label` | `.bb-dropzone__content` | `content` | |
736
+ | `.bb-indicator__indicator` | `.bb-indicator__bubble` | `bubble` | |
737
+ | `.bb-pagination__page-chevron` | `.bb-pagination__icon` | `icon` | |
738
+ | `.bb-rating__option` | `.bb-rating__item` | `item` | |
739
+ | `.bb-tooltip__content` | `.bb-tooltip__panel` | `panel` | |
740
+ | `.bb-tree__node` | `.bb-tree__item` | `item` | |
741
+ | `.bb-tabs__trigger` | `.bb-tabs-list__item` | `item` | The tab button is drawn by BbTabsList, so it takes BbTabsList's block. |
742
+ | `.bb-badge--focused` | `.bb-badge--highlighted` | BbTag `badge`, state `highlighted` | The arrow-key cursor on a BbTag chip. It was never real focus (focus stays in the input), hence the new name. |
743
+ | `.bb-button--active` | `.bb-button--pressed` | `root` | A toggle `BbButton` (`v-model`) that is on: it is pressed (`aria-pressed="true"`), not "active". Style it with `pt:root:pressed`, or keep a selector on `.bb-button--pressed`. A pointer press is the `:active` pseudo-class (Tailwind `active:`). |
744
+ | `.bb-tabs-list__tablist` | `.bb-tabs-list__list` | `list` | The sliding indicator is no longer this list's `::before`: it is an element, `.bb-tabs-list__indicator`, the list's first child. Move a `::before` override there. |
745
+ | `.bb-tabs-panes` | `.bb-tabs-panels` | BbTabs `panels` (the BbTabsPanels root) | The component is renamed too: `BbTabsPanes` → `BbTabsPanels`. |
746
+ | `.bb-tabs__pane` | `.bb-tabs__panel` | `panel` | Drawn by BbTabsPanels; the class keeps the tabs' own word for the part. |
747
+ | `.bb-dropdown-button__main-btn` | `.bb-dropdown-button__main` | `main` | The main half of the split button (the `main` part). |
748
+ | `.bb-dropdown-button__dropdown-btn` | `.bb-dropdown-button__toggle` | `toggle` | The chevron half that opens the menu (the `toggle` part). |
749
+ | `.bb-checkbox-group__no-data` | `.bb-checkbox-group__empty` | `empty` | |
750
+ | `.bb-radio-group__no-data` | `.bb-radio-group__empty` | `empty` | |
751
+ | `.bb-switch-group__no-data` | `.bb-switch-group__empty` | `empty` | |
750
752
 
751
753
  <!-- /generated:renames -->
@@ -118,6 +118,17 @@ All of these land in 3.0.0-beta.41.
118
118
  - A new `warnings` array (never fails the run), with `severity: "warning"`:
119
119
  `likely-squashed-slot` and `local-bb-component`.
120
120
 
121
+ In 3.0.0-beta.49 the dropdown kinds follow the item fields (Q64.2):
122
+ `missing-key` is `missing-value` (a row in a selectable group without a
123
+ `value`) or `missing-id` (a selectable group without an `id`), and
124
+ `duplicate-row-text` is `duplicate-row-label`. A new `renamed-item-field`
125
+ reports an item field spelled the old way (a dropdown row's `key` / `text`, a
126
+ dropdown group's `key`, a tab's `key`, a crumb's `key` / `text`) and
127
+ `check --fix` rewrites it; its ESLint twin is
128
+ `bitboss-ui/no-renamed-item-field` (`error` in `recommended`). A script that
129
+ matches the old kind names in `check --json` output needs the new ones;
130
+ `eslint-disable` comments name rules, which did not change.
131
+
121
132
  After 3.0.0-beta.41, `check` alone (not MCP `validate`: it needs the project's
122
133
  build config) adds `kind: "hand-imported-styles"`: `bitboss-ui/styles.css`
123
134
  imported in a CSS file, a script, a `.vue` block or Nuxt's `css: [...]` while
@@ -19,12 +19,12 @@ Companion playbooks: [Fetch Items](./fetch-items-playbook.md) (async providers),
19
19
  `items` means two different things in this library, and picking the wrong one is
20
20
  the most common early mistake. Ask **whose data is it?**
21
21
 
22
- | | **Accessor mode** — _your data_ | **Authored mode** — _your UI_ |
23
- | --------------------- | --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
24
- | Components | `BbSelect`, `BbSelectPopover`, `BbCheckboxGroup`, `BbRadioGroup`, `BbSwitchGroup` | `BbDropdown`, `BbDropdownButton`, `BbTabs`, `BbBreadcrumbs`, `BbTree` |
25
- | Shape | any shape — raw API rows | entries you write, each carrying its own caption (`text` on dropdown items and breadcrumbs, `label` on tabs); `BbTree` nodes carry your `meta` and render through its default slot |
26
- | Caption | you point at a field: `item-text`, `item-value` | it is on the entry itself |
27
- | Rest of this playbook | **applies** | mostly does **not** — no accessors, no hash-matching |
22
+ | | **Accessor mode** — _your data_ | **Authored mode** — _your UI_ |
23
+ | --------------------- | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
24
+ | Components | `BbSelect`, `BbSelectPopover`, `BbCheckboxGroup`, `BbRadioGroup`, `BbSwitchGroup` | `BbDropdown`, `BbDropdownButton`, `BbTabs`, `BbBreadcrumbs`, `BbTree` |
25
+ | Shape | any shape — raw API rows | entries you write, each carrying its own `label` and, where it has one, its identity in `value` (dropdown rows, tabs, breadcrumbs); `BbTree` nodes carry your `meta` and render through its default slot |
26
+ | Caption | read from `label` (else `text`) and `value`; other fields: `item-text`, `item-value` | it is on the entry itself |
27
+ | Rest of this playbook | **applies** | mostly does **not** — no accessors, no hash-matching |
28
28
 
29
29
  ```vue
30
30
  <!-- Accessor mode: customers came from an API, keep their field names. -->
@@ -37,15 +37,17 @@ the most common early mistake. Ask **whose data is it?**
37
37
  />
38
38
 
39
39
  <!-- Authored mode: a menu you typed out. The caption lives on the entry. -->
40
- <BbDropdown :items="[{ key: 'edit', text: 'Edit' }]" />
40
+ <BbDropdown :items="[{ value: 'edit', label: 'Edit' }]" />
41
41
  ```
42
42
 
43
43
  **Why two, deliberately.** A picker lists records that arrive with their own
44
- field names (`full_name`, `uuid`), so forcing them into `{ text, value }` would
44
+ field names (`full_name`, `uuid`), so forcing them into `{ label, value }` would
45
45
  mean a pointless `.map()` on every list — and it cannot work at all for the
46
46
  async form, where the component fetches the items itself and never sees your
47
47
  array. A dropdown or a tab strip is the opposite: you are writing those captions
48
48
  by hand anyway, so an accessor would be indirection with nothing to point at.
49
+ Rows that already carry `label` (or `text`) and `value` need no accessor in
50
+ either mode: both vocabularies use the same words.
49
51
 
50
52
  `BbTable` sits between the two: rows stay **raw data** (accessor mode —
51
53
  `item-value` is row identity), but the captions live on `columns[].label`, not
@@ -61,18 +63,22 @@ Pass backend/domain items **as-is** to `items` and resolve text/value declarativ
61
63
  - `item-text="path.to.label"` or `:item-text="(item) => ..."` — display text
62
64
  - `item-value="path.to.id"` or `:item-value="(item) => ..."` — the value stored in `v-model`
63
65
 
66
+ `{ label, value }` and `{ text, value }` items work as they are; any other shape
67
+ needs `item-text` / `item-value`.
68
+
64
69
  A **string** item is its own text and value: `item-text` / `item-value` do not
65
70
  run on it, so `:item-text="(code) => labels[code]"` over `string[]` still shows
66
71
  the raw codes. Give such lists objects (`{ code, label }`) and point the
67
72
  accessors at their fields.
68
73
 
69
- Never pre-map accessor-mode items into `{ label, value }` arrays. Matching is hash-based on the extracted value, so component-native extraction stays robust and the raw item remains available to slots (`#option`, cell slots) untouched.
74
+ Never pre-map accessor-mode items into `{ label, value }` arrays: point `item-text` / `item-value` at the fields they already have. Matching is hash-based on the extracted value, so component-native extraction stays robust and the raw item remains available to slots (`#option`, cell slots) untouched.
70
75
 
71
76
  ### Mapping modes
72
77
 
73
- 1. **Primitive items** (`string[]`, `number[]`): omit both props; the value is the primitive itself.
74
- 2. **Dot paths** for nested objects: `item-text="profile.fullName"`, `item-value="profile.id"`.
75
- 3. **Extractor functions** only when a path can't express it:
78
+ 1. **`{ label, value }` objects** (or `{ text, value }`): omit both props; the text is the own `label` (else `text`), the value the own `value`.
79
+ 2. **Primitive items** (`string[]`, `number[]`): omit both props; the value is the primitive itself.
80
+ 3. **Dot paths** for nested objects: `item-text="profile.fullName"`, `item-value="profile.id"`.
81
+ 4. **Extractor functions** only when a path can't express it:
76
82
 
77
83
  ```vue
78
84
  <script setup lang="ts">
@@ -137,11 +143,11 @@ prop, `item-props`, and from nowhere else.
137
143
 
138
144
  Anything else is a type error.
139
145
 
140
- | Component | Fields | Notes |
141
- | -------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
142
- | `BbCheckboxGroup`, `BbRadioGroup`, `BbSwitchGroup` | `description` | Under the option label, beside the control; may wrap. No icons — the `#icon` slot already means the control glyph. |
143
- | `BbSelect`, `BbSelectPopover` | `description`, `prepend:icon`, `append:icon` | A description makes every row a fixed two lines tall (virtualized) and ellipsizes on one line. The check replaces the append icon on the selected row. |
144
- | `BbDropdown` fetched (pipeline) groups | every hand-written row field except `key`, `text`, `items`, `group`, `disabled` | `description`, icons, `variant`, `onClick`, `href` / `to` and the link / Inertia options. Declared in the group config, camelCase: `itemProps`. |
146
+ | Component | Fields | Notes |
147
+ | -------------------------------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
148
+ | `BbCheckboxGroup`, `BbRadioGroup`, `BbSwitchGroup` | `description` | Under the option label, beside the control; may wrap. No icons — the `#icon` slot already means the control glyph. |
149
+ | `BbSelect`, `BbSelectPopover` | `description`, `prepend:icon`, `append:icon` | A description makes every row a fixed two lines tall (virtualized) and ellipsizes on one line. The check replaces the append icon on the selected row. |
150
+ | `BbDropdown` fetched (pipeline) groups | every hand-written row field except `value`, `label`, `items`, `group`, `disabled` | `description`, icons, `variant`, `onClick`, `href` / `to` and the link / Inertia options. Declared in the group config, camelCase: `itemProps`. |
145
151
 
146
152
  Everywhere, the description is announced as the row's description (never part
147
153
  of its name), the search matches it along with the text when `filter-by` is
@@ -155,7 +161,7 @@ descriptions_, BbDropdown _Fetched assignees_ and _Fetched links_.
155
161
 
156
162
  ## How options resolve (verified semantics)
157
163
 
158
- - Default `item-value` is the **whole item**; default `itemText` is the string itself for strings, `JSON.stringify(item)` otherwise. For object items, always set both props.
164
+ - With no `item-text`, an object option reads its own `label`, else its own `text`, else `JSON.stringify(item)`; a string is its own text. With no `item-value`, an object option's value is its own `value` (whatever it holds, `null` included), else the **whole item**. So `{ label, value }` and `{ text, value }` items need neither prop; any other shape needs both. An explicit accessor always wins. (BbTable rows keep the whole row: set `item-value` there.)
159
165
  - Selection matching compares `hash(itemValue(item))` against `hash(modelValue entry)` — a **deep value** comparison, not reference identity. Object values match structurally, but prefer primitive ids: they are stable across refetches and cheap to submit.
160
166
  - Items resolving to a **duplicate value are silently dropped** (first occurrence wins). Guarantee unique `item-value` per option.
161
167
  - `modelValue` holds the resolved value(s), never the option wrapper. Slots receive the raw `item` plus resolved `text` / `value`.
@@ -222,14 +228,14 @@ A `disabled` field on the item object (`{ id: 1, label: '…', disabled: true }`
222
228
  - `selectable` prop — per-option gating on `BbCheckboxGroup`, `BbRadioGroup`, `BbSwitchGroup`, `BbSelect`, `BbSelectPopover` and `BbTable`. Either a global boolean (`false` disables every option) or a predicate `(item) => boolean`; options the predicate rejects render disabled. Defaults to `true` on the option components; on `BbTable` it is unset until you pass it — and an unset `selectable` there means "no selection column", not "every row selectable".
223
229
  - `max` — caps a multiple selection: at the cap, unselected options auto-disable while **selected options never disable**, so the user can always deselect.
224
230
  - `BbDropdown` **hand-written** items are buttons, not options — `disabled` there is a regular button prop and stays supported.
225
- - `BbDropdown` **fetched (pipeline) group** rows have no `disabled` field: fetched groups are for selection, so gate rows with the group's `selectable` predicate — `selectable: (item) => !item.archived` — which receives the raw fetched item. A raw item's own `disabled` (or `href`, icons, `variant`, …) is data; row fields beyond text and value come only from the group's `itemProps`. Hand-written dropdown groups accept the same predicate, receiving the row object.
231
+ - `BbDropdown` **fetched (pipeline) group** rows have no `disabled` field: fetched groups are for selection, so gate rows with the group's `selectable` predicate — `selectable: (item) => !item.archived` — which receives the raw fetched item. A raw item's own `disabled` (or `href`, icons, `variant`, …) is data; row fields beyond label and value come only from the group's `itemProps`. Hand-written dropdown groups accept the same predicate, receiving the row object.
226
232
 
227
233
  If your domain data carries an availability flag, feed it to the predicate — e.g. `:selectable="(item) => !item.disabled"` or `:selectable="(user) => user.active"` — or filter the items out entirely when a dead row would add noise.
228
234
 
229
235
  ## Component-specific notes
230
236
 
231
237
  - **`BbTable`** — always set `item-value`: selection, expansion (`v-model:expanded-items`) and highlight track rows by that value, so state survives refetches where object references change.
232
- - **`BbDropdown` pipeline groups** — the group is fully declared in the host's `items` (getter + `itemText` / `itemValue` / `max`, camelCase — it's data, not template props). The `<BbDropdownGroup>` companion is only `id` + `v-model`; its `id` matches the group's `key`:
238
+ - **`BbDropdown` pipeline groups** — the group is fully declared in the host's `items` (getter + `itemText` / `itemValue` (optional when the fetched rows carry `label` and `value`) / `max`, camelCase — it's data, not template props). The `<BbDropdownGroup>` companion is only `id` + `v-model`; its `id` matches the group's `id`:
233
239
 
234
240
  ```vue
235
241
  <script setup lang="ts">
@@ -238,9 +244,9 @@ import { BbButton, BbDropdown, BbDropdownGroup } from 'bitboss-ui';
238
244
 
239
245
  const assignee = ref<string | null>(null);
240
246
  const items = [
241
- { key: 'edit', text: 'Edit invoice', href: '/invoices/42/edit' },
247
+ { value: 'edit', label: 'Edit invoice', href: '/invoices/42/edit' },
242
248
  {
243
- key: 'assignee',
249
+ id: 'assignee',
244
250
  label: 'Assign to',
245
251
  selectable: true,
246
252
  items: () => api.members.list(),
@@ -347,7 +353,7 @@ The same rules hold for `BbCheckboxGroup`, `BbRadioGroup` and
347
353
 
348
354
  ## Items that navigate
349
355
 
350
- When an item is a link, the component navigates — never your code. `BbDropdown` items take `href` (anchor / Inertia visit with `method`, `data`, …) or `to` (vue-router); table row links are a `BbButton` with `href`/`to` in a cell or `#actions` slot. Never `onClick: () => router.push(...)` on an item, and never a row `@click` that sets `window.location`.
356
+ When an item is a link, the component navigates — never your code. `BbDropdown` rows take `href` (anchor / Inertia visit with `method`, `data`, …) or `to` (vue-router); table row links are a `BbButton` with `href`/`to` in a cell or `#actions` slot. Never `onClick: () => router.push(...)` on an item, and never a row `@click` that sets `window.location`.
351
357
 
352
358
  ## Anti-patterns
353
359
 
@@ -361,7 +367,7 @@ When an item is a link, the component navigates — never your code. `BbDropdown
361
367
 
362
368
  ## Validation checklist
363
369
 
364
- - [ ] Object items set both `item-text` and `item-value` (dot-path first, function only when needed).
370
+ - [ ] Object items without their own `label`/`text` and `value` set both `item-text` and `item-value` (dot-path first, function only when needed); no accessor restates the default (`item-text="label"`, `item-value="value"`).
365
371
  - [ ] `item-value` resolves to a stable, unique, preferably primitive identity.
366
372
  - [ ] Multiple-mode `v-model` refs are seeded with arrays.
367
373
  - [ ] No manual option mapping or template-level reshaping.
@@ -217,7 +217,7 @@ the dialog closing; it observes it.
217
217
  one in this list wins, on every component:
218
218
 
219
219
  ```
220
- hasValue → nearLimit → atLimit → empty → outside → today → inRange → sorted → sortedDesc → selected → rangeStart → rangeEnd → checked → indeterminate → readonly → disabled → warnings → errors → active → expanded → open → fullscreen → focused → focusVisible → highlighted → loading
220
+ hasValue → nearLimit → atLimit → empty → outside → today → inRange → sorted → sortedDesc → selected → rangeStart → rangeEnd → checked → indeterminate → pressed → readonly → disabled → warnings → errors → active → expanded → open → fullscreen → focused → focusVisible → highlighted → loading
221
221
  ```
222
222
 
223
223
  It is ordered by meaning — the more temporary state wins: a spinner replaces
@@ -316,7 +316,7 @@ part accepts a function** on the instance, beside a plain value:
316
316
 
317
317
  ```vue
318
318
  <!-- a dropdown: the entry's own data says it is destructive —
319
- actions = [{ key: 'delete', text: 'Delete', variant: 'destructive' }, …] -->
319
+ actions = [{ value: 'delete', label: 'Delete', variant: 'destructive' }, …] -->
320
320
  <BbDropdown
321
321
  :items="actions"
322
322
  :pt:item="
@@ -906,7 +906,7 @@ _Passthrough parts and states_ table in that component's contract
906
906
  | `BbBaseRadioIcon` | `root` | `errors`, `warnings`, `disabled`, `readonly`, `checked`, `focused`, `focusVisible` |
907
907
  | `BbBaseSwitchIcon` | `root` | `errors`, `warnings`, `disabled`, `readonly`, `checked`, `indeterminate`, `focused`, `focusVisible` |
908
908
  | `BbBreadcrumbs` | `root`, `item`, `icon`, `text` | `active`, `disabled` _(per crumb)_ |
909
- | `BbButton` | `root`, `icon`, `spinner`, `text` | `loading`, `disabled` |
909
+ | `BbButton` | `root`, `icon`, `spinner`, `text` | `loading`, `disabled`, `pressed` |
910
910
  | `BbCalendar` | `root`, `header`, `arrow`, `month`, `year`, `cellColumnHeader`, `day`, `dayButton`, `monthItem`, `yearItem`, `item` _(the time rail's entries)_ | `outside`, `today`, `inRange`, `selected`, `rangeStart`, `rangeEnd`, `disabled`, `highlighted` _(per cell)_, `active` _(month / year)_ |
911
911
  | `BbCheckbox` | `root`, `label`, `description`, `message`, `hint`, `icon` | `errors`, `warnings`, `disabled`, `readonly`, `checked`, `indeterminate`, `focused`, `focusVisible` |
912
912
  | `BbCheckboxGroup` | `root`, `legend`, `description`, `message`, `hint`, `list`, `item`, `icon`, `label`, `itemDescription` | `errors`, `warnings`, `disabled`, `readonly`, `loading`, `hasValue`; `checked`, `focused`, `focusVisible` _(row parts only)_ |
@@ -927,7 +927,7 @@ _Passthrough parts and states_ table in that component's contract
927
927
  | `BbOffCanvas` | `root`, `header`, `title`, `description`, `content`, `footer`, `close` | `open`, `fullscreen` |
928
928
  | `BbPagination` | `root`, `item`, `arrow`, `ellipsis`, `icon` | `active` _(the current page)_, `disabled` _(per control)_ |
929
929
  | `BbPopover` | `root`, `panel`, `sheet`, `header`, `content`, `footer` | `open` |
930
- | `BbProgress` | `root`, `bar` | — |
930
+ | `BbProgress` | `root`, `bar` | `indeterminate` |
931
931
  | `BbRadio` | `root`, `label`, `description`, `message`, `hint`, `icon` | `errors`, `warnings`, `disabled`, `readonly`, `checked`, `focused`, `focusVisible` |
932
932
  | `BbRadioGroup` | `root`, `legend`, `description`, `message`, `hint`, `list`, `item`, `icon`, `label`, `itemDescription` | `errors`, `warnings`, `disabled`, `readonly`, `loading`, `hasValue`; `checked`, `focused`, `focusVisible` _(row parts only)_ |
933
933
  | `BbRating` | `root`, `label`, `description`, `message`, `hint`, `item` | `errors`, `warnings`, `disabled`, `readonly`, `hasValue`, `selected` _(per star)_ |
@@ -145,9 +145,23 @@ type RowOf<P> = P extends { items?: infer I }
145
145
  ? Extract<NonNullable<I>, readonly unknown[]>[number]
146
146
  : never;
147
147
 
148
+ /**
149
+ * With no `itemValue`, an option surface (a component with `itemText`) emits
150
+ * a row's own `value` when it has one, else the row (Q60.24). BbTable keeps
151
+ * the row.
152
+ */
153
+ type DefaultValueOf<P> = P extends { itemText?: unknown }
154
+ ? RowOf<P> extends infer R
155
+ ? R extends { value: infer V }
156
+ ? V
157
+ : R
158
+ : never
159
+ : RowOf<P>;
160
+
148
161
  /**
149
162
  * The value type when the preset decides it: a fixed key or getter as
150
- * `itemValue`, or fixed `items` with no `itemValue` (the value is the row).
163
+ * `itemValue`, or fixed `items` with no `itemValue` (the row's own `value`,
164
+ * else the row).
151
165
  * `never` = not decided (a dotted path, or `itemValue` left to the caller):
152
166
  * the component keeps its own model type.
153
167
  */
@@ -160,7 +174,7 @@ type ValueOf<P, F> = [RowOf<P>] extends [never]
160
174
  ? R
161
175
  : never
162
176
  : F extends { items: unknown }
163
- ? RowOf<P>
177
+ ? DefaultValueOf<P>
164
178
  : never;
165
179
 
166
180
  type ModelProps<V, F> = F extends { multiple: true }
@@ -346,7 +360,8 @@ is a `.ts` module, not an `.vue` file.
346
360
  2. **What defines the data is fixed; what a page may change is a default.**
347
361
  `items`, `itemText`, `itemValue`, `multiple` go in the second argument;
348
362
  `label`, `placeholder`, `clearable` in `defaults`.
349
- 3. **A key (or a getter) as `itemValue` types the model.** A dotted path
363
+ 3. **A key (or a getter) as `itemValue` types the model.** Rows that carry
364
+ their own `value` need no `itemValue`: the model is that `value`. A dotted path
350
365
  (`'meta.code'`) cannot be typed, so the model keeps `BbSelect`'s own loose
351
366
  type. Prefer a getter: `itemValue: (c: Customer) => c.meta.code`.
352
367
  4. **`multiple` is fixed or left to the caller**, never a default (the helper
@@ -6,7 +6,7 @@ summary: Which bitboss-ui components are generic, and the four places their type
6
6
  # TypeScript and Generic Components
7
7
 
8
8
  Some components are **generic**: their types follow what you pass in. The
9
- row type of `items`, the tab keys, and the empty value a text field emits
9
+ row type of `items`, the tab values, and the empty value a text field emits
10
10
  (`null-value`) all flow into the slots and events. In templates this costs
11
11
  nothing. In `<script>`, a generic component's type is a **function**
12
12
  (`<T>(props, ctx) => VNode`), not a component class, and four everyday
@@ -40,12 +40,10 @@ async function createAccount(values: z.output<typeof signup>) {
40
40
  </script>
41
41
 
42
42
  <template>
43
- <BbForm v-slot="{ isSubmitting }" :schema="signup" @submit="createAccount">
43
+ <BbForm :schema="signup" @submit="createAccount">
44
44
  <BbTextInput label="Email" name="email" type="email" />
45
45
  <BbCheckbox label="I accept the terms" name="terms" />
46
- <BbButton :loading="isSubmitting" type="submit" variant="primary">
47
- Create account
48
- </BbButton>
46
+ <BbButton type="submit" variant="primary"> Create account </BbButton>
49
47
  </BbForm>
50
48
  </template>
51
49
  ```
@@ -77,8 +75,9 @@ That is the whole pattern. The rules that keep a form this small:
77
75
  undeclared keys from `@submit`'s values, so a switch or a hidden field the
78
76
  schema does not name vanishes (declare it: `separateShipping: z.boolean()`).
79
77
  - **`@submit` fires only when the form is valid**, with the values (the
80
- schema's output, typed). The slot's `isSubmitting` drives the button. No
81
- `saving` ref, no `@submit.prevent`, no `<form>` of your own.
78
+ schema's output, typed). Return the handler's promise: while it runs the
79
+ fields are read-only and the `type="submit"` button spins on its own. No
80
+ `saving` ref, no `:loading`, no `@submit.prevent`, no `<form>` of your own.
82
81
  - **A server's 422** goes to the form in one call:
83
82
  `useBbFormContext(id).setErrors(body.errors)` (§ 4). No `:errors` ref per
84
83
  field. Call `useBbFormContext(id)` once, at the top of `<script setup>`
@@ -173,7 +172,7 @@ async function order(values: Record<string, unknown>) {
173
172
  </script>
174
173
 
175
174
  <template>
176
- <BbForm v-slot="{ isSubmitting }" @submit="order">
175
+ <BbForm @submit="order">
177
176
  <BbTextInput label="Email" name="email" rules="required|email" />
178
177
  <BbNumberInput
179
178
  label="Quantity"
@@ -181,7 +180,7 @@ async function order(values: Record<string, unknown>) {
181
180
  rules="required|min_value:1"
182
181
  />
183
182
  <BbCheckbox label="Accept terms" name="terms" rules="required" />
184
- <BbButton :loading="isSubmitting" type="submit">Order</BbButton>
183
+ <BbButton type="submit">Order</BbButton>
185
184
  </BbForm>
186
185
  </template>
187
186
  ```
@@ -276,16 +275,11 @@ const save = async (values: z.output<typeof schema>) => {
276
275
  </script>
277
276
 
278
277
  <template>
279
- <BbForm
280
- v-slot="{ isSubmitting }"
281
- :model="order"
282
- :schema="schema"
283
- @submit="save"
284
- >
278
+ <BbForm :model="order" :schema="schema" @submit="save">
285
279
  <BbTextInput label="Email" name="email" type="email" />
286
280
  <BbTextInput label="City" name="address[city]" />
287
281
  <BbNumberInput label="Quantity" name="quantity" />
288
- <BbButton :loading="isSubmitting" type="submit">Save</BbButton>
282
+ <BbButton type="submit">Save</BbButton>
289
283
  </BbForm>
290
284
  </template>
291
285
  ```
@@ -396,7 +390,7 @@ async function save(values: z.output<typeof schema>) {
396
390
  <p>{{ profile.name }}: {{ profile.bio }}</p>
397
391
  <BbForm
398
392
  id="profile"
399
- v-slot="{ dirty, isSubmitting }"
393
+ v-slot="{ dirty }"
400
394
  :model="profile"
401
395
  :schema="schema"
402
396
  @submit="save"
@@ -406,12 +400,7 @@ async function save(values: z.output<typeof schema>) {
406
400
  <BbButton :disabled="!dirty" variant="ghost" @click="form.reset()">
407
401
  Discard
408
402
  </BbButton>
409
- <BbButton
410
- :disabled="!dirty"
411
- :loading="isSubmitting"
412
- type="submit"
413
- variant="primary"
414
- >
403
+ <BbButton :disabled="!dirty" type="submit" variant="primary">
415
404
  Save
416
405
  </BbButton>
417
406
  </BbForm>
@@ -102,9 +102,10 @@ there ([BbForm § Server errors](../BbForm.md#server-errors-seterrors-and-fields
102
102
  - **Inertia `useForm`** → keep Inertia for the request (`router.post` or
103
103
  `useForm().post`), move the fields into `BbForm` with `name`s equal to the
104
104
  Laravel keys, and replace `:errors="form.errors.email"` on each input with
105
- one `:field-errors="form.errors"` on the `BbForm`. `form.processing` → the slot's
106
- `isSubmitting`. Client-side checks move to `rules` or a
107
- `schema`.
105
+ one `:field-errors="form.errors"` on the `BbForm`. `form.processing` → return
106
+ the visit's promise from `@submit`: the fields lock and the submit button
107
+ spins while it runs (the slot's `isSubmitting` for anything else). Client-side
108
+ checks move to `rules` or a `schema`.
108
109
  - **Inertia router with an error bag** → `:field-errors="$page.props.errors.<bag>"`.
109
110
  `$page.props.errors.<bag>` readers become `errors` / `fields`.
110
111
  - **Laravel 422 over fetch / axios** → `if (status === 422) errors.value =