bitboss-ui 3.0.0-beta.48 → 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 (356) hide show
  1. package/README.md +24 -7
  2. package/bin/bitboss-ui-mcp.mjs +15 -3
  3. package/bin/bitboss-ui.mjs +115 -13
  4. package/dist/ai/BbAvatar.md +1 -1
  5. package/dist/ai/BbBreadcrumbs.md +65 -65
  6. package/dist/ai/BbButton.md +16 -5
  7. package/dist/ai/BbCheckbox.md +0 -2
  8. package/dist/ai/BbCheckboxGroup.md +13 -20
  9. package/dist/ai/BbDatePickerInput.md +4 -2
  10. package/dist/ai/BbDialog.md +1 -8
  11. package/dist/ai/BbDropdown.md +231 -220
  12. package/dist/ai/BbDropdownButton.md +65 -65
  13. package/dist/ai/BbDropdownGroup.md +2 -2
  14. package/dist/ai/BbDropzone.md +10 -10
  15. package/dist/ai/BbForm.md +43 -52
  16. package/dist/ai/BbHoverCard.md +4 -2
  17. package/dist/ai/BbNumberInput.md +88 -21
  18. package/dist/ai/BbPopover.md +29 -23
  19. package/dist/ai/BbProgress.md +48 -22
  20. package/dist/ai/BbRadioGroup.md +13 -19
  21. package/dist/ai/BbSelect.md +16 -36
  22. package/dist/ai/BbSelectPopover.md +14 -30
  23. package/dist/ai/BbSmoothHeight.md +0 -2
  24. package/dist/ai/BbSwitchGroup.md +13 -20
  25. package/dist/ai/BbTable.md +11 -10
  26. package/dist/ai/BbTabs.md +106 -105
  27. package/dist/ai/BbTabsList.md +2 -2
  28. package/dist/ai/BbTabsPanels.md +1 -1
  29. package/dist/ai/BbTabsRoot.md +2 -2
  30. package/dist/ai/BbTooltip.md +24 -10
  31. package/dist/ai/BbTree.md +14 -11
  32. package/dist/ai/changelog.json +256 -5
  33. package/dist/ai/components.json +36 -34
  34. package/dist/ai/composables/useBbDropdownContext.md +16 -16
  35. package/dist/ai/composables/useBbFormField.md +5 -1
  36. package/dist/ai/composables/useBbTabsContext.md +14 -14
  37. package/dist/ai/guides/agent-contract.md +27 -27
  38. package/dist/ai/guides/ai-router.md +1 -1
  39. package/dist/ai/guides/component-picker.md +3 -3
  40. package/dist/ai/guides/fetch-items-playbook.md +1 -1
  41. package/dist/ai/guides/icons-policy.md +10 -10
  42. package/dist/ai/guides/inertia-helpers.md +120 -67
  43. package/dist/ai/guides/installation-and-plugin-setup.md +43 -15
  44. package/dist/ai/guides/migration/components/bb-breadcrumbs.md +3 -2
  45. package/dist/ai/guides/migration/components/bb-checkbox-group.md +16 -16
  46. package/dist/ai/guides/migration/components/bb-dropdown-button.md +9 -8
  47. package/dist/ai/guides/migration/components/bb-dropdown.md +15 -14
  48. package/dist/ai/guides/migration/components/bb-radio-group.md +2 -1
  49. package/dist/ai/guides/migration/components/bb-select-popover.md +6 -1
  50. package/dist/ai/guides/migration/components/bb-select.md +10 -2
  51. package/dist/ai/guides/migration/components/bb-switch-group.md +2 -1
  52. package/dist/ai/guides/migration/components/bb-tabs.md +9 -8
  53. package/dist/ai/guides/migration/components/bb-tooltip.md +1 -1
  54. package/dist/ai/guides/migration/v2-to-v3.md +114 -17
  55. package/dist/ai/guides/migration/v3-beta-tooling.md +11 -0
  56. package/dist/ai/guides/options-items-playbook.md +30 -24
  57. package/dist/ai/guides/passthrough.md +2 -2
  58. package/dist/ai/guides/preset-components.md +18 -3
  59. package/dist/ai/guides/typescript-generic-components.md +1 -1
  60. package/dist/ai/guides/validated-forms.md +11 -22
  61. package/dist/ai/guides/validation-providers.md +4 -3
  62. package/dist/ai/helpers/inertia/manifest.json +636 -0
  63. package/dist/ai/helpers/inertia/types.ts +15 -0
  64. package/dist/ai/helpers/inertia/useAsyncFn.ts +110 -0
  65. package/dist/ai/helpers/inertia/useConfirmOnRouteLeave.ts +102 -0
  66. package/dist/ai/helpers/inertia/useDeleteCmd.ts +30 -0
  67. package/dist/ai/helpers/inertia/useHasChanged.ts +36 -0
  68. package/dist/ai/helpers/inertia/useIndexById.ts +23 -0
  69. package/dist/ai/helpers/inertia/useLazyProp.ts +148 -0
  70. package/dist/ai/helpers/inertia/useLazyPropGetter.ts +50 -0
  71. package/dist/ai/helpers/inertia/useLoading.ts +20 -0
  72. package/dist/ai/helpers/inertia/usePaginatedResponseContext.ts +88 -0
  73. package/dist/ai/helpers/inertia/usePromiseForm.ts +62 -0
  74. package/dist/ai/helpers/inertia/useProp.ts +63 -0
  75. package/dist/ai/helpers/inertia/useQuery.ts +19 -0
  76. package/dist/ai/helpers/inertia/useQueryObject.ts +116 -0
  77. package/dist/ai/helpers/inertia/useResourceContext.ts +69 -0
  78. package/dist/ai/helpers/inertia/useRouteQuery.ts +54 -0
  79. package/dist/ai/helpers/inertia/useScreenSizes.ts +23 -0
  80. package/dist/ai/helpers/inertia/useTableContext.ts +34 -0
  81. package/dist/ai/helpers/inertia/useTableSelectionContext.ts +48 -0
  82. package/dist/ai/helpers/inertia/useUntil.ts +33 -0
  83. package/dist/ai/helpers/inertia/utils.ts +24 -0
  84. package/dist/ai/index.md +6 -6
  85. package/dist/ai/manifest/components/BbBreadcrumbs.json +10 -6
  86. package/dist/ai/manifest/components/BbBreadcrumbs.tree.json +1 -1
  87. package/dist/ai/manifest/components/BbButton.json +1 -1
  88. package/dist/ai/manifest/components/BbCheckboxGroup.json +2 -2
  89. package/dist/ai/manifest/components/BbDropdown.json +23 -20
  90. package/dist/ai/manifest/components/BbDropdown.tree.json +2 -2
  91. package/dist/ai/manifest/components/BbDropdownButton.json +22 -19
  92. package/dist/ai/manifest/components/BbDropdownButton.tree.json +1 -1
  93. package/dist/ai/manifest/components/BbDropdownGroup.json +2 -2
  94. package/dist/ai/manifest/components/BbForm.json +1 -0
  95. package/dist/ai/manifest/components/BbNumberInput.json +6 -1
  96. package/dist/ai/manifest/components/BbNumberInput.tree.json +2 -1
  97. package/dist/ai/manifest/components/BbPopover.json +1 -0
  98. package/dist/ai/manifest/components/BbProgress.json +6 -6
  99. package/dist/ai/manifest/components/BbProgress.tree.json +1 -0
  100. package/dist/ai/manifest/components/BbRadioGroup.json +2 -2
  101. package/dist/ai/manifest/components/BbSelect.json +2 -2
  102. package/dist/ai/manifest/components/BbSelectPopover.json +2 -2
  103. package/dist/ai/manifest/components/BbSwitchGroup.json +2 -2
  104. package/dist/ai/manifest/components/BbTabs.json +7 -6
  105. package/dist/ai/manifest/components/BbTabsList.json +3 -3
  106. package/dist/ai/manifest/components/BbTabsPanels.json +1 -1
  107. package/dist/ai/manifest/components/BbTabsRoot.json +5 -4
  108. package/dist/ai/manifest/components/BbTooltip.json +1 -1
  109. package/dist/ai/manifest/index.json +2 -2
  110. package/dist/ai/manifest/meta.json +2 -0
  111. package/dist/ai/manifest/types.advanced.json +10 -9
  112. package/dist/ai/manifest/types.api.json +5 -4
  113. package/dist/ai/recipes/inertia/approvals-inbox.md +16 -18
  114. package/dist/ai/recipes/inertia/inline-edit-workspace.md +23 -33
  115. package/dist/ai/recipes/inertia/layout-scaffold.md +16 -16
  116. package/dist/ai/recipes/inertia/onboarding.md +6 -10
  117. package/dist/ai/recipes/inertia/ownership-atlas.md +15 -18
  118. package/dist/ai/recipes/inertia/record-form.md +11 -11
  119. package/dist/ai/recipes/inertia/records-workspace.md +38 -41
  120. package/dist/ai/recipes/inertia/settings-workspace.md +26 -38
  121. package/dist/ai/recipes/inertia/upload-center.md +31 -39
  122. package/dist/ai/recipes/inertia/wizard-form.md +10 -19
  123. package/dist/ai/recipes/nuxt/approvals-inbox.md +7 -8
  124. package/dist/ai/recipes/nuxt/inline-edit-workspace.md +14 -24
  125. package/dist/ai/recipes/nuxt/layout-scaffold.md +16 -16
  126. package/dist/ai/recipes/nuxt/onboarding.md +2 -6
  127. package/dist/ai/recipes/nuxt/ownership-atlas.md +7 -9
  128. package/dist/ai/recipes/nuxt/record-form.md +5 -5
  129. package/dist/ai/recipes/nuxt/records-workspace.md +29 -31
  130. package/dist/ai/recipes/nuxt/settings-workspace.md +22 -34
  131. package/dist/ai/recipes/nuxt/upload-center.md +22 -29
  132. package/dist/ai/recipes/nuxt/wizard-form.md +3 -11
  133. package/dist/ai/recipes/vue/approvals-inbox.md +7 -8
  134. package/dist/ai/recipes/vue/inline-edit-workspace.md +14 -24
  135. package/dist/ai/recipes/vue/layout-scaffold.md +16 -16
  136. package/dist/ai/recipes/vue/onboarding.md +2 -6
  137. package/dist/ai/recipes/vue/ownership-atlas.md +7 -9
  138. package/dist/ai/recipes/vue/record-form.md +5 -5
  139. package/dist/ai/recipes/vue/records-workspace.md +29 -31
  140. package/dist/ai/recipes/vue/settings-workspace.md +22 -34
  141. package/dist/ai/recipes/vue/upload-center.md +22 -29
  142. package/dist/ai/recipes/vue/wizard-form.md +3 -11
  143. package/dist/ai/source/BbAccordion.md +1 -1
  144. package/dist/ai/source/BbAlert.md +3 -3
  145. package/dist/ai/source/BbBadge.md +2 -2
  146. package/dist/ai/source/BbBadgeButton.md +5 -4
  147. package/dist/ai/source/BbBaseButton.md +1 -1
  148. package/dist/ai/source/BbBaseRadioIcon.md +1 -0
  149. package/dist/ai/source/BbBaseSwitchIcon.md +1 -0
  150. package/dist/ai/source/BbBreadcrumbs.md +63 -42
  151. package/dist/ai/source/BbButton.md +71 -33
  152. package/dist/ai/source/BbCalendar.md +17 -16
  153. package/dist/ai/source/BbCheckbox.md +3 -2
  154. package/dist/ai/source/BbCheckboxGroup.md +11 -4
  155. package/dist/ai/source/BbColorInput.md +10 -9
  156. package/dist/ai/source/BbConfirm.md +1 -1
  157. package/dist/ai/source/BbConfirmPortal.md +1 -1
  158. package/dist/ai/source/BbDatePicker.md +2 -2
  159. package/dist/ai/source/BbDatePickerInput.md +47 -20
  160. package/dist/ai/source/BbDialog.md +5 -5
  161. package/dist/ai/source/BbDropdown.md +230 -158
  162. package/dist/ai/source/BbDropdownButton.md +19 -12
  163. package/dist/ai/source/BbDropdownGroup.md +126 -93
  164. package/dist/ai/source/BbForm.md +25 -1
  165. package/dist/ai/source/BbIndicator.md +4 -0
  166. package/dist/ai/source/BbNumberInput.md +855 -19
  167. package/dist/ai/source/BbOffCanvas.md +27 -11
  168. package/dist/ai/source/BbPagination.md +3 -3
  169. package/dist/ai/source/BbPopover.md +152 -8
  170. package/dist/ai/source/BbPopoverPortal.md +11 -0
  171. package/dist/ai/source/BbProgress.md +82 -18
  172. package/dist/ai/source/BbRadioGroup.md +12 -5
  173. package/dist/ai/source/BbRating.md +11 -9
  174. package/dist/ai/source/BbSelect.md +16 -10
  175. package/dist/ai/source/BbSelectPopover.md +29 -23
  176. package/dist/ai/source/BbSlider.md +12 -6
  177. package/dist/ai/source/BbSwitch.md +3 -2
  178. package/dist/ai/source/BbSwitchGroup.md +5 -2
  179. package/dist/ai/source/BbTable.md +102 -18
  180. package/dist/ai/source/BbTabs.md +27 -23
  181. package/dist/ai/source/BbTabsList.md +26 -22
  182. package/dist/ai/source/BbTabsPanels.md +26 -22
  183. package/dist/ai/source/BbTabsRoot.md +25 -21
  184. package/dist/ai/source/BbTag.md +10 -9
  185. package/dist/ai/source/BbTextInput.md +5 -4
  186. package/dist/ai/source/BbTextarea.md +6 -5
  187. package/dist/ai/source/BbTimePicker.md +1 -1
  188. package/dist/ai/source/BbTimePickerInput.md +46 -9
  189. package/dist/ai/source/BbToast.md +10 -7
  190. package/dist/ai/source/BbToastPortal.md +10 -7
  191. package/dist/ai/source/BbTooltip.md +54 -8
  192. package/dist/ai/source/BbTree.md +21 -3
  193. package/dist/ai/source/CommonField.md +6 -4
  194. package/dist/ai/source/CommonFieldInput.md +15 -10
  195. package/dist/ai/source/CommonPopover.md +6 -0
  196. package/dist/ai/source/CommonTimeSelector.md +5 -4
  197. package/dist/components/BbBadge/BbBadgeButton.vue_vue_type_script_setup_true_lang.js +10 -8
  198. package/dist/components/BbBaseButton/BbBaseButton.vue_vue_type_script_setup_true_lang.js +8 -8
  199. package/dist/components/BbBreadcrumbs/BbBreadcrumbs.vue_vue_type_script_setup_true_lang.js +45 -45
  200. package/dist/components/BbBreadcrumbs/types.d.ts +25 -17
  201. package/dist/components/BbButton/BbButton.vue_vue_type_script_setup_true_lang.js +84 -71
  202. package/dist/components/BbButton/toggleRoving.d.ts +6 -0
  203. package/dist/components/BbButton/toggleRoving.js +45 -0
  204. package/dist/components/BbButton/types.d.ts +4 -1
  205. package/dist/components/BbCalendar/BbCalendar.vue_vue_type_script_setup_true_lang.js +178 -178
  206. package/dist/components/BbCalendar/CalendarMonthPanel.vue_vue_type_script_setup_true_lang.js +15 -15
  207. package/dist/components/BbCalendar/CalendarYearPanel.vue_vue_type_script_setup_true_lang.js +28 -28
  208. package/dist/components/BbCalendar/useCalendarGrid.js +141 -139
  209. package/dist/components/BbCalendar/useDayjsLocale.d.ts +38 -15
  210. package/dist/components/BbCalendar/useDayjsLocale.js +31 -30
  211. package/dist/components/BbCheckbox/BbCheckbox.vue_vue_type_script_setup_true_lang.js +48 -48
  212. package/dist/components/BbCheckboxGroup/BbCheckboxGroup.vue_vue_type_script_setup_true_lang.js +81 -80
  213. package/dist/components/BbCheckboxGroup/types.d.ts +6 -2
  214. package/dist/components/BbColorInput/BbColorInput.vue_vue_type_script_setup_true_lang.js +69 -69
  215. package/dist/components/BbDatePickerInput/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +363 -349
  216. package/dist/components/BbDropdown/AdaptiveDropdown.vue_vue_type_script_setup_true_lang.js +91 -86
  217. package/dist/components/BbDropdown/BbDropdown.vue_vue_type_script_setup_true_lang.js +298 -289
  218. package/dist/components/BbDropdown/BbDropdownList.vue_vue_type_script_setup_true_lang.js +322 -356
  219. package/dist/components/BbDropdown/DropdownPipelineResolver.vue_vue_type_script_setup_true_lang.js +17 -15
  220. package/dist/components/BbDropdown/DropdownRow.vue.d.ts +40 -0
  221. package/dist/components/BbDropdown/DropdownRow.vue.js +5 -0
  222. package/dist/components/BbDropdown/DropdownRow.vue_vue_type_script_setup_true_lang.js +60 -0
  223. package/dist/components/BbDropdown/normalizeGroups.d.ts +8 -2
  224. package/dist/components/BbDropdown/normalizeGroups.js +60 -46
  225. package/dist/components/BbDropdown/types.d.ts +119 -88
  226. package/dist/components/BbDropdownButton/BbDropdownButton.vue_vue_type_script_setup_true_lang.js +11 -2
  227. package/dist/components/BbDropdownButton/types.d.ts +2 -2
  228. package/dist/components/BbForm/BbForm.vue.d.ts +9 -0
  229. package/dist/components/BbForm/BbForm.vue_vue_type_script_setup_true_lang.js +114 -105
  230. package/dist/components/BbForm/BbFormCustomField.js +1 -1
  231. package/dist/components/BbForm/bindFormField.js +2 -1
  232. package/dist/components/BbForm/formFields.d.ts +5 -0
  233. package/dist/components/BbNumberInput/BbNumberInput.vue.d.ts +0 -1
  234. package/dist/components/BbNumberInput/BbNumberInput.vue_vue_type_script_setup_true_lang.js +452 -125
  235. package/dist/components/BbNumberInput/numberDisplay.d.ts +256 -0
  236. package/dist/components/BbNumberInput/numberDisplay.js +499 -0
  237. package/dist/components/BbNumberInput/types.d.ts +54 -1
  238. package/dist/components/BbNumberInput/warroom/corpus.d.ts +58 -0
  239. package/dist/components/BbNumberInput/warroom/currency-verify.rows.d.ts +28 -0
  240. package/dist/components/BbNumberInput/warroom/currency.rows.d.ts +2 -0
  241. package/dist/components/BbNumberInput/warroom/harness.d.ts +217 -0
  242. package/dist/components/BbNumberInput/warroom/oracle.d.ts +150 -0
  243. package/dist/components/BbPagination/BbPagination.vue_vue_type_script_setup_true_lang.js +7 -7
  244. package/dist/components/BbPopover/BbPopover.vue.d.ts +1 -0
  245. package/dist/components/BbPopover/BbPopover.vue_vue_type_script_setup_true_lang.js +207 -164
  246. package/dist/components/BbPopover/types.d.ts +11 -0
  247. package/dist/components/BbProgress/BbProgress.vue_vue_type_script_setup_true_lang.js +15 -7
  248. package/dist/components/BbProgress/types.d.ts +23 -7
  249. package/dist/components/BbProgress/types.js +1 -1
  250. package/dist/components/BbRadioGroup/BbRadioGroup.vue_vue_type_script_setup_true_lang.js +102 -101
  251. package/dist/components/BbRadioGroup/types.d.ts +6 -2
  252. package/dist/components/BbRating/BbRating.vue_vue_type_script_setup_true_lang.js +63 -63
  253. package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +156 -154
  254. package/dist/components/BbSelect/types.d.ts +6 -2
  255. package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +2 -1
  256. package/dist/components/BbSelectPopover/types.d.ts +6 -2
  257. package/dist/components/BbSlider/BbSlider.vue_vue_type_script_setup_true_lang.js +153 -153
  258. package/dist/components/BbSwitch/BbSwitch.vue_vue_type_script_setup_true_lang.js +62 -62
  259. package/dist/components/BbSwitchGroup/BbSwitchGroup.vue_vue_type_script_setup_true_lang.js +131 -130
  260. package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +711 -676
  261. package/dist/components/BbTabs/BbTabs.vue_vue_type_script_setup_true_lang.js +1 -1
  262. package/dist/components/BbTabs/BbTabsList.vue_vue_type_script_setup_true_lang.js +1 -1
  263. package/dist/components/BbTabs/types.d.ts +25 -21
  264. package/dist/components/BbTag/BbTag.vue_vue_type_script_setup_true_lang.js +76 -76
  265. package/dist/components/BbTextInput/BbTextInput.vue_vue_type_script_setup_true_lang.js +58 -58
  266. package/dist/components/BbTextarea/BbTextarea.vue_vue_type_script_setup_true_lang.js +82 -82
  267. package/dist/components/BbTimePickerInput/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +246 -236
  268. package/dist/components/BbTooltip/BbTooltip.vue_vue_type_script_setup_true_lang.js +102 -97
  269. package/dist/components/BbTooltip/tooltipWarmup.d.ts +23 -0
  270. package/dist/components/BbTooltip/tooltipWarmup.js +7 -0
  271. package/dist/components/BbTooltip/types.d.ts +7 -2
  272. package/dist/components/BbTree/BbTree.vue_vue_type_script_setup_true_lang.js +29 -21
  273. package/dist/components/BbTree/BbTreeLevel.vue_vue_type_script_setup_true_lang.js +10 -7
  274. package/dist/components/CommonFieldInput/CommonFieldInput.vue_vue_type_script_setup_true_lang.js +37 -36
  275. package/dist/components/CommonTimeSelector/CommonTimeSelector.vue_vue_type_script_setup_true_lang.js +9 -9
  276. package/dist/composables/formSubmitLock.d.ts +6 -0
  277. package/dist/composables/formSubmitLock.js +4 -0
  278. package/dist/composables/useBaseOptions.d.ts +7 -1
  279. package/dist/composables/useBaseOptions.js +32 -32
  280. package/dist/composables/useBbDropdownContext.d.ts +8 -8
  281. package/dist/composables/useBbFormField.d.ts +9 -0
  282. package/dist/composables/useBbFormField.js +5 -3
  283. package/dist/composables/useBbTabsContext.d.ts +10 -10
  284. package/dist/composables/useBbTabsContext.js +18 -18
  285. package/dist/composables/useFormBinding.d.ts +11 -0
  286. package/dist/composables/useFormBinding.js +15 -13
  287. package/dist/composables/useItemText.d.ts +5 -1
  288. package/dist/composables/useItemText.js +8 -3
  289. package/dist/composables/useItemValue.d.ts +5 -1
  290. package/dist/composables/useItemValue.js +8 -3
  291. package/dist/composables/useLocale.js +10 -9
  292. package/dist/deprecation/ai-deprecations.json.d.ts +130 -0
  293. package/dist/deprecation/ai-deprecations.json.js +1 -1
  294. package/dist/deprecation/removedProps.js +1 -1
  295. package/dist/directives/bbDropdown.js +1 -1
  296. package/dist/i18n/index.d.ts +7 -12
  297. package/dist/i18n/locales/cs.json +11 -14
  298. package/dist/i18n/locales/da.json +13 -16
  299. package/dist/i18n/locales/de-CH.json +137 -0
  300. package/dist/i18n/locales/de.json +14 -17
  301. package/dist/i18n/locales/el.json +10 -13
  302. package/dist/i18n/locales/en-GB.json +137 -0
  303. package/dist/i18n/locales/en.json +8 -11
  304. package/dist/i18n/locales/es-MX.json +137 -0
  305. package/dist/i18n/locales/es.json +16 -19
  306. package/dist/i18n/locales/fi.json +8 -11
  307. package/dist/i18n/locales/fr.json +23 -26
  308. package/dist/i18n/locales/hu.json +8 -11
  309. package/dist/i18n/locales/it.json +12 -15
  310. package/dist/i18n/locales/ja.json +13 -16
  311. package/dist/i18n/locales/ko.json +10 -13
  312. package/dist/i18n/locales/nb.json +13 -16
  313. package/dist/i18n/locales/nl.json +21 -24
  314. package/dist/i18n/locales/pl.json +10 -13
  315. package/dist/i18n/locales/{pt.json → pt-BR.json} +19 -22
  316. package/dist/i18n/locales/pt-PT.json +137 -0
  317. package/dist/i18n/locales/ro.json +22 -25
  318. package/dist/i18n/locales/ru.json +11 -14
  319. package/dist/i18n/locales/sv.json +16 -19
  320. package/dist/i18n/locales/tr.json +14 -17
  321. package/dist/i18n/locales/uk.json +11 -14
  322. package/dist/i18n/locales/{zh-cn.json → zh-CN.json} +10 -13
  323. package/dist/i18n/locales/zh-HK.json +137 -0
  324. package/dist/i18n/locales/zh-TW.json +137 -0
  325. package/dist/i18n/regionHints.d.ts +16 -0
  326. package/dist/i18n/regionHints.js +49 -0
  327. package/dist/i18n/regions.d.ts +286 -0
  328. package/dist/i18n/regions.js +265 -0
  329. package/dist/index.d.ts +1 -1
  330. package/dist/index.js +4 -4
  331. package/dist/llms-full.txt +1785 -1637
  332. package/dist/llms-medium.txt +74 -46
  333. package/dist/llms.txt +7 -7
  334. package/dist/locale-blueprint.json +16 -13
  335. package/dist/styles.css +2 -2
  336. package/dist/types/ptComponentMap.d.ts +1 -1
  337. package/dist/utilities/functions/slotKey.d.ts +2 -2
  338. package/dist/utils/versionCheck.js +1 -1
  339. package/dist/vite-plugin.d.ts +22 -19
  340. package/dist/vite.js +309 -297
  341. package/llms.txt +7 -7
  342. package/package.json +5 -3
  343. package/scripts/lib/agent-manifest.mjs +2 -1
  344. package/scripts/lib/eslint-disable.mjs +12 -4
  345. package/scripts/lib/eslint-plugin.d.ts +5 -1
  346. package/scripts/lib/eslint-plugin.mjs +187 -6
  347. package/scripts/lib/helper-canon.mjs +176 -0
  348. package/scripts/lib/helpers-add.mjs +1303 -0
  349. package/scripts/lib/local-components.mjs +33 -4
  350. package/scripts/lib/locale-check.mjs +165 -0
  351. package/scripts/lib/redundant-item-accessor.mjs +398 -0
  352. package/scripts/lib/renamed-item-field.mjs +343 -0
  353. package/scripts/lib/slot-key.mjs +2 -2
  354. package/scripts/lib/slot-renames.mjs +1 -1
  355. package/scripts/lib/validate-bb-markup.mjs +123 -56
  356. package/dist/i18n/index.js +0 -27
package/dist/ai/BbTabs.md CHANGED
@@ -44,18 +44,18 @@ shared context:
44
44
  can place arbitrary markup between the strip and the panels. Reach for it only
45
45
  when the layout demands it.
46
46
 
47
- ### Tabs with a panel per key
47
+ ### Tabs with a panel per value
48
48
 
49
- Pass `items` (`{ key, label }`), bind the active key with `v-model`, and provide
50
- one slot named for each item `key` — that is the panel. Slot names go through
49
+ Pass `items` (`{ value, label }`), bind the active value with `v-model`, and
50
+ provide one slot named for each item's `value` — that is the panel. Slot names go through
51
51
  `slotKey`, which is kebab-case: words split at separators, camelCase humps and
52
- digits, lowercased, joined by `-`. So key `'Billing info'` or `'billing_info'`
52
+ digits, lowercased, joined by `-`. So the value `'Billing info'` or `'billing_info'`
53
53
  is the panel `#billing-info` (and its label `#billing-info:label`), `'inReview'`
54
54
  is `#in-review`, and `'2026-10-06'` stays `#2026-10-06`. A computed name needs
55
55
  the same treatment: a `<template v-for="stage in stages" #[stage]>` over
56
56
  `'inReview'` fills `#inReview` while the tab reads `#in-review`, so the panel
57
57
  stays empty. Write `#[slotKey(stage)]` (`slotKey` is exported from
58
- `bitboss-ui`), which is also the safe spelling for any key with accents,
58
+ `bitboss-ui`), which is also the safe spelling for any value with accents,
59
59
  non-Latin letters or punctuation; `bitboss-ui check` flags the raw form when
60
60
  `stages` is a literal array in the same file. With no
61
61
  `v-model` the
@@ -119,14 +119,14 @@ import { ref } from 'vue';
119
119
  import { BbTabs } from 'bitboss-ui';
120
120
  import type { BbTabsItem } from 'bitboss-ui';
121
121
 
122
- // `v-model` binds the active tab to a plain key ref. Seed it with a starting
123
- // key; drop the binding entirely and BbTabs selects the first enabled tab.
122
+ // `v-model` binds the active tab to a plain value ref. Seed it with a starting
123
+ // value; drop the binding entirely and BbTabs selects the first enabled tab.
124
124
  type Section = 'overview' | 'activity' | 'members';
125
125
 
126
126
  const tabs: Array<BbTabsItem<Section>> = [
127
- { key: 'overview', label: 'Overview' },
128
- { key: 'activity', label: 'Activity' },
129
- { key: 'members', label: 'Members' },
127
+ { value: 'overview', label: 'Overview' },
128
+ { value: 'activity', label: 'Activity' },
129
+ { value: 'members', label: 'Members' },
130
130
  ];
131
131
 
132
132
  const active = ref<Section>('overview');
@@ -146,12 +146,12 @@ const members = [
146
146
  ```
147
147
 
148
148
  `v-model` is the whole event surface: the component emits `update:modelValue`
149
- with the new key whenever the selection changes — from a click, a keyboard move,
149
+ with the new value whenever the selection changes — from a click, a keyboard move,
150
150
  URL navigation, or the companion composable — and it emits once on mount when a
151
- URL query or the first-enabled fallback resolves a key the parent didn't set, so
151
+ URL query or the first-enabled fallback resolves a value the parent didn't set, so
152
152
  your binding starts aligned. You rarely listen to the event directly; bind
153
153
  `v-model` and read it. When `items` is generated, drive the panels with a
154
- dynamic-name slot instead of writing one block per key:
154
+ dynamic-name slot instead of writing one block per value:
155
155
 
156
156
  **Dynamic panel slots from generated items**
157
157
 
@@ -160,9 +160,9 @@ dynamic-name slot instead of writing one block per key:
160
160
  <BbTabs
161
161
  compact
162
162
  :items="[
163
- { key: 'draft', label: 'Draft' },
164
- { key: 'review', label: 'In review' },
165
- { key: 'published', label: 'Published' },
163
+ { value: 'draft', label: 'Draft' },
164
+ { value: 'review', label: 'In review' },
165
+ { value: 'published', label: 'Published' },
166
166
  ]"
167
167
  >
168
168
  <template
@@ -178,9 +178,9 @@ dynamic-name slot instead of writing one block per key:
178
178
 
179
179
  ### Rich labels and badges
180
180
 
181
- Replace a tab's plain text with the `<key>:label` slot (one specific tab) or the
182
- `label` slot (the fallback for every tab). Both receive the tab's state — `text`
183
- (the item's `label`), `value` (its `key`), `selected`, `disabled`, plus the
181
+ Replace a tab's plain text with the `<value>:label` slot (one specific tab) or
182
+ the `label` slot (the fallback for every tab). Both receive the tab's state —
183
+ `label`, `value`, `selected`, `disabled`, plus the
184
184
  group's `current` / `currentIndex` / `isFirst` / `isLast` and a `goTo` callback —
185
185
  so a label can carry a count pill, an icon, or a status dot. Keep the whole
186
186
  trigger the interactive target; put only presentation in the slot (do not nest a
@@ -192,9 +192,9 @@ button or link inside a label — the trigger is already the control).
192
192
  <template>
193
193
  <div class="max-w-md rounded-(--bb-radius) border border-(--bb-border) p-3">
194
194
  <BbTabs v-model="active" compact :items="tabs">
195
- <template #inbox:label="{ text }">
195
+ <template #inbox:label="{ label }">
196
196
  <span class="inline-flex items-center gap-1.5">
197
- {{ text }}
197
+ {{ label }}
198
198
  <BbBadge size="sm" variant="soft-blue">{{ unread }}</BbBadge>
199
199
  </span>
200
200
  </template>
@@ -230,14 +230,14 @@ import { ref } from 'vue';
230
230
  import { BbBadge, BbTabs } from 'bitboss-ui';
231
231
  import type { BbTabsItem } from 'bitboss-ui';
232
232
 
233
- // Count pills ride in `<key>:label` — presentation only; the trigger stays the
233
+ // Count pills ride in `<value>:label` — presentation only; the trigger stays the
234
234
  // control. Soft badge palette from design-language.md § Using color.
235
235
  type Folder = 'inbox' | 'sent' | 'spam';
236
236
 
237
237
  const tabs: Array<BbTabsItem<Folder>> = [
238
- { key: 'inbox', label: 'Inbox' },
239
- { key: 'sent', label: 'Sent' },
240
- { key: 'spam', label: 'Spam' },
238
+ { value: 'inbox', label: 'Inbox' },
239
+ { value: 'sent', label: 'Sent' },
240
+ { value: 'spam', label: 'Spam' },
241
241
  ];
242
242
 
243
243
  const active = ref<Folder>('inbox');
@@ -279,7 +279,7 @@ const inbox = [
279
279
  </style>
280
280
  ```
281
281
 
282
- Use `<key>:label` when only some tabs need decoration and `label` when every tab
282
+ Use `<value>:label` when only some tabs need decoration and `label` when every tab
283
283
  follows one template (an icon + count for all). A badge that changes size after
284
284
  mount — a count ticking up — is fine: the strip re-measures the sliding pill and
285
285
  equal-width fit when label content resizes, so the layout keeps up on its own.
@@ -298,7 +298,7 @@ inactive. Two reasons to reach for it:
298
298
  - **SEO / SSR** — content in inactive panels is in the server-rendered HTML.
299
299
 
300
300
  `eager` works at two granularities: on the component (every panel eager) or on a
301
- single `items` entry (`{ key, label, eager: true }`) when only one panel is
301
+ single `items` entry (`{ value, label, eager: true }`) when only one panel is
302
302
  expensive to lose. The example keeps a draft message alive while the user checks
303
303
  the Audience and Schedule tabs:
304
304
 
@@ -361,9 +361,9 @@ import type { BbTabsItem } from 'bitboss-ui';
361
361
  type Section = 'message' | 'audience' | 'schedule';
362
362
 
363
363
  const tabs: Array<BbTabsItem<Section>> = [
364
- { key: 'message', label: 'Message' },
365
- { key: 'audience', label: 'Audience' },
366
- { key: 'schedule', label: 'Schedule' },
364
+ { value: 'message', label: 'Message' },
365
+ { value: 'audience', label: 'Audience' },
366
+ { value: 'schedule', label: 'Schedule' },
367
367
  ];
368
368
 
369
369
  const active = ref<Section>('message');
@@ -438,8 +438,8 @@ import type { BbTabsItem } from 'bitboss-ui';
438
438
  type Mode = 'code' | 'preview';
439
439
 
440
440
  const tabs: Array<BbTabsItem<Mode>> = [
441
- { key: 'code', label: 'Code' },
442
- { key: 'preview', label: 'Preview' },
441
+ { value: 'code', label: 'Code' },
442
+ { value: 'preview', label: 'Preview' },
443
443
  ];
444
444
 
445
445
  const draft = ref<string | null>(
@@ -564,9 +564,9 @@ import type { BbTabsItem } from 'bitboss-ui';
564
564
  type Section = 'general' | 'members' | 'billing';
565
565
 
566
566
  const tabs: Array<BbTabsItem<Section>> = [
567
- { key: 'general', label: 'General' },
568
- { key: 'members', label: 'Members' },
569
- { key: 'billing', label: 'Billing' },
567
+ { value: 'general', label: 'General' },
568
+ { value: 'members', label: 'Members' },
569
+ { value: 'billing', label: 'Billing' },
570
570
  ];
571
571
 
572
572
  const section = ref<Section>('general');
@@ -591,9 +591,9 @@ const onSaveGeneral = async () => {
591
591
  block
592
592
  compact
593
593
  :items="[
594
- { key: 'summary', label: 'Summary' },
595
- { key: 'integrations', label: 'Integrations' },
596
- { key: 'billing', label: 'Billing', disabled: true },
594
+ { value: 'summary', label: 'Summary' },
595
+ { value: 'integrations', label: 'Integrations' },
596
+ { value: 'billing', label: 'Billing', disabled: true },
597
597
  ]"
598
598
  >
599
599
  <template #summary><p class="pt-3 text-sm text-(--bb-text-muted)">Environment status at a glance.</p></template>
@@ -611,9 +611,9 @@ const onSaveGeneral = async () => {
611
611
  compact
612
612
  direction="vertical"
613
613
  :items="[
614
- { key: 'general', label: 'General' },
615
- { key: 'security', label: 'Security' },
616
- { key: 'api', label: 'API keys' },
614
+ { value: 'general', label: 'General' },
615
+ { value: 'security', label: 'Security' },
616
+ { value: 'api', label: 'API keys' },
617
617
  ]"
618
618
  >
619
619
  <template #general><p class="px-3 text-sm text-(--bb-text-muted)">Workspace basics.</p></template>
@@ -653,9 +653,9 @@ every variant. Three ship:
653
653
  <div class="max-w-md rounded-(--bb-radius) border border-(--bb-border) p-3">
654
654
  <BbTabs
655
655
  :items="[
656
- { key: 'board', label: 'Board' },
657
- { key: 'table', label: 'Table' },
658
- { key: 'calendar', label: 'Calendar' },
656
+ { value: 'board', label: 'Board' },
657
+ { value: 'table', label: 'Table' },
658
+ { value: 'calendar', label: 'Calendar' },
659
659
  ]"
660
660
  >
661
661
  <template #board><p class="pt-3 text-sm text-(--bb-text-muted)">Cards by status.</p></template>
@@ -671,9 +671,9 @@ every variant. Three ship:
671
671
  <div class="max-w-md rounded-(--bb-radius) border border-(--bb-border) p-3">
672
672
  <BbTabs
673
673
  :items="[
674
- { key: 'overview', label: 'Overview' },
675
- { key: 'activity', label: 'Activity' },
676
- { key: 'settings', label: 'Settings' },
674
+ { value: 'overview', label: 'Overview' },
675
+ { value: 'activity', label: 'Activity' },
676
+ { value: 'settings', label: 'Settings' },
677
677
  ]"
678
678
  variant="line"
679
679
  >
@@ -696,9 +696,9 @@ and the bar keeps sliding — it is the same measured element as the pill.
696
696
  compact
697
697
  direction="vertical"
698
698
  :items="[
699
- { key: 'profile', label: 'Profile' },
700
- { key: 'sessions', label: 'Sessions' },
701
- { key: 'tokens', label: 'API tokens' },
699
+ { value: 'profile', label: 'Profile' },
700
+ { value: 'sessions', label: 'Sessions' },
701
+ { value: 'tokens', label: 'API tokens' },
702
702
  ]"
703
703
  variant="line"
704
704
  >
@@ -719,9 +719,9 @@ active through `pt:item:active`:
719
719
  <div class="max-w-md rounded-(--bb-radius) border border-(--bb-border) p-3">
720
720
  <BbTabs
721
721
  :items="[
722
- { key: 'week', label: 'This week' },
723
- { key: 'month', label: 'This month' },
724
- { key: 'year', label: 'This year' },
722
+ { value: 'week', label: 'This week' },
723
+ { value: 'month', label: 'This month' },
724
+ { value: 'year', label: 'This year' },
725
725
  ]"
726
726
  pt:item="border-b-2 border-transparent text-(--bb-text-muted) uppercase tracking-wide text-xs"
727
727
  pt:item:active="border-(--bb-text) text-(--bb-text)"
@@ -772,14 +772,14 @@ look in the example's `sideNav` object:
772
772
  :pt="sideNav"
773
773
  variant="none"
774
774
  >
775
- <template #label="{ value, text }">
775
+ <template #label="{ value, label }">
776
776
  <span class="flex items-center gap-2">
777
777
  <BbIcon
778
778
  aria-hidden="true"
779
779
  :icon="icons[value as Section]"
780
780
  size="16"
781
781
  />
782
- {{ text }}
782
+ {{ label }}
783
783
  </span>
784
784
  </template>
785
785
  <template #profile>
@@ -809,10 +809,10 @@ import type { BbTabsItem, BbTabsProps } from 'bitboss-ui';
809
809
  type Section = 'profile' | 'notifications' | 'members' | 'billing';
810
810
 
811
811
  const sections: Array<BbTabsItem<Section>> = [
812
- { key: 'profile', label: 'Profile' },
813
- { key: 'notifications', label: 'Notifications' },
814
- { key: 'members', label: 'Members' },
815
- { key: 'billing', label: 'Billing' },
812
+ { value: 'profile', label: 'Profile' },
813
+ { value: 'notifications', label: 'Notifications' },
814
+ { value: 'members', label: 'Members' },
815
+ { value: 'billing', label: 'Billing' },
816
816
  ];
817
817
  const icons: Record<Section, string> = {
818
818
  profile: 'lucide:user',
@@ -938,9 +938,9 @@ import type { BbTabsItem } from 'bitboss-ui';
938
938
  type Filter = 'all' | 'unread' | 'starred';
939
939
 
940
940
  const filters: Array<BbTabsItem<Filter>> = [
941
- { key: 'all', label: 'All' },
942
- { key: 'unread', label: 'Unread' },
943
- { key: 'starred', label: 'Starred' },
941
+ { value: 'all', label: 'All' },
942
+ { value: 'unread', label: 'Unread' },
943
+ { value: 'starred', label: 'Starred' },
944
944
  ];
945
945
  const filter = ref<Filter>('unread');
946
946
  </script>
@@ -1001,9 +1001,9 @@ import type { BbTabsItem } from 'bitboss-ui';
1001
1001
  type Panel = 'code' | 'preview' | 'diff';
1002
1002
 
1003
1003
  const panels: Array<BbTabsItem<Panel>> = [
1004
- { key: 'code', label: 'Code' },
1005
- { key: 'preview', label: 'Preview' },
1006
- { key: 'diff', label: 'Diff' },
1004
+ { value: 'code', label: 'Code' },
1005
+ { value: 'preview', label: 'Preview' },
1006
+ { value: 'diff', label: 'Diff' },
1007
1007
  ];
1008
1008
  const panel = ref<Panel>('code');
1009
1009
  </script>
@@ -1083,16 +1083,16 @@ ends.
1083
1083
  />
1084
1084
  </template>
1085
1085
  <!--
1086
- `slotKey(...)`, never the raw key. A panel's slot name is the
1087
- NORMALIZED key: `v3.0` becomes `v3_0`, so `#[release.key]` would
1086
+ `slotKey(...)`, never the raw value. A panel's slot name is the
1087
+ NORMALIZED value: `v3.0` becomes `v-3-0`, so `#[release.value]` would
1088
1088
  name a slot that never matches and every panel would silently render
1089
- empty. The keys here carry a dot on purpose — with slug-safe keys
1089
+ empty. The values here carry a dot on purpose — with slug-safe values
1090
1090
  (`v1`…`v9`) the mistake is invisible.
1091
1091
  -->
1092
1092
  <template
1093
1093
  v-for="release in releases"
1094
- :key="release.key"
1095
- #[slotKey(release.key)]
1094
+ :key="release.value"
1095
+ #[slotKey(release.value)]
1096
1096
  >
1097
1097
  <p class="pt-3 text-sm text-(--bb-text-muted)">
1098
1098
  {{ release.label }} shipped the design-token overhaul and the tabs
@@ -1124,7 +1124,7 @@ const months = [
1124
1124
  // Realistic release tags: `v3.0` … `v3.8`. The dot is what makes the
1125
1125
  // `slotKey` call in the template load-bearing (see the note there).
1126
1126
  const releases: BbTabsItem[] = months.map((label, index) => ({
1127
- key: `v3.${index}`,
1127
+ value: `v3.${index}`,
1128
1128
  label: `${label} · v3.${index}`,
1129
1129
  }));
1130
1130
 
@@ -1218,9 +1218,9 @@ import type { BbTabsItem } from 'bitboss-ui';
1218
1218
  type Section = 'overview' | 'activity' | 'members';
1219
1219
 
1220
1220
  const tabs: Array<BbTabsItem<Section>> = [
1221
- { key: 'overview', label: 'Overview' },
1222
- { key: 'activity', label: 'Activity' },
1223
- { key: 'members', label: 'Members' },
1221
+ { value: 'overview', label: 'Overview' },
1222
+ { value: 'activity', label: 'Activity' },
1223
+ { value: 'members', label: 'Members' },
1224
1224
  ];
1225
1225
 
1226
1226
  const active = ref<Section>('overview');
@@ -1238,13 +1238,14 @@ are only relocating the list and the panels.
1238
1238
  Give a tab group an explicit `id` and read or steer it from any component on the
1239
1239
  client with `useBbTabsContext(id)` — no template ref, no shared subtree, no
1240
1240
  being inside the tabs' tree. Pass the same `id` you gave the component (auto-
1241
- generated ids are not addressable) and optionally the key union to type
1241
+ generated ids are not addressable) and optionally the value union to type
1242
1242
  `current` / `select`. The returned handle is safe to destructure:
1243
1243
 
1244
- - `current` — a **writable** ref: reading it gives the active key (`null` until
1245
- the tabs mount), and assigning a key selects it, exactly like `select(key)`.
1244
+ - `current` — a **writable** ref: reading it gives the active value (`null`
1245
+ until the tabs mount), and assigning a value selects it, exactly like
1246
+ `select(value)`.
1246
1247
  Assigning `null` warns and is ignored — a tab is always selected.
1247
- - `select(key)` — select by key; unknown keys warn and leave the selection
1248
+ - `select(value)` — select by value; unknown values warn and leave the selection
1248
1249
  untouched.
1249
1250
  - `goTo('first' | 'previous' | 'next' | 'last')` — relative navigation, skipping
1250
1251
  disabled tabs.
@@ -1345,9 +1346,9 @@ import type { BbTabsItem } from 'bitboss-ui';
1345
1346
  type SectionKey = 'profile' | 'security' | 'notifications';
1346
1347
 
1347
1348
  const tabs: Array<BbTabsItem<SectionKey>> = [
1348
- { key: 'profile', label: 'Profile' },
1349
- { key: 'security', label: 'Security' },
1350
- { key: 'notifications', label: 'Notifications' },
1349
+ { value: 'profile', label: 'Profile' },
1350
+ { value: 'security', label: 'Security' },
1351
+ { value: 'notifications', label: 'Notifications' },
1351
1352
  ];
1352
1353
 
1353
1354
  const section = ref<SectionKey>('profile');
@@ -1357,7 +1358,7 @@ const profile = reactive({
1357
1358
  });
1358
1359
 
1359
1360
  // The alert banner lives OUTSIDE the tabs subtree: it reaches the group purely
1360
- // by id. `current` is a readable/writable ref, `select` jumps straight to a key.
1361
+ // by id. `current` is a readable/writable ref, `select` jumps straight to a value.
1361
1362
  const { current, select } = useBbTabsContext<SectionKey>(
1362
1363
  'account-settings-tabs'
1363
1364
  );
@@ -1393,9 +1394,9 @@ programmatic "go there", not the keyboard.
1393
1394
  <BbTabs
1394
1395
  manual-activation
1395
1396
  :items="[
1396
- { key: 'summary', label: 'Summary' },
1397
- { key: 'invoices', label: 'Invoices' },
1398
- { key: 'audit', label: 'Audit log' },
1397
+ { value: 'summary', label: 'Summary' },
1398
+ { value: 'invoices', label: 'Invoices' },
1399
+ { value: 'audit', label: 'Audit log' },
1399
1400
  ]"
1400
1401
  >
1401
1402
  <template #summary>Summary panel</template>
@@ -1410,22 +1411,22 @@ Set `navigation` to keep the active tab in the URL query (`query-key`, default
1410
1411
  `tab`) so a tab is deep-linkable and survives reload. On load the query wins over
1411
1412
  `modelValue`; thereafter switching writes the query.
1412
1413
 
1413
- **The URL carries a normalized slug, never the raw tab key.** The query value
1414
+ **The URL carries a normalized slug, never the raw tab value.** The query value
1414
1415
  goes through `slotKey`, the same kebab-case rule as the slot names, so a tab
1415
- keyed `'In Review'` (or `inReview`, or `in_review`) appears in the URL as
1416
+ whose value is `'In Review'` (or `inReview`, or `in_review`) appears in the URL as
1416
1417
  `in-review`. The component round-trips this itself; the surprise lands on
1417
1418
  anything ELSE reading the query — a server matching `?tab=` against camelCase
1418
- keys silently never matches. Compare against `slotKey(key)` server-side, or
1419
- use lowercase kebab keys for server-matched tabs.
1419
+ values silently never matches. Compare against `slotKey(value)` server-side, or
1420
+ use lowercase kebab values for server-matched tabs.
1420
1421
 
1421
1422
  #### URL values changed in 3.0.0-beta.41
1422
1423
 
1423
1424
  Before the slot-naming reset the slug rule was "non-word runs become `_`,
1424
1425
  lowercased": `?tab=in_review`, `?tab=reviewstatus`. It is now kebab-case:
1425
1426
  `?tab=in-review`, `?tab=review-status`. One rule for slot names and URLs, and
1426
- camelCase keys stay readable instead of squashed.
1427
+ camelCase values stay readable instead of squashed.
1427
1428
 
1428
- | Tab key | Old URL value | New URL value |
1429
+ | Tab value | Old URL value | New URL value |
1429
1430
  | ---------------- | -------------- | --------------- |
1430
1431
  | `'In Review'` | `in_review` | `in-review` |
1431
1432
  | `'reviewStatus'` | `reviewstatus` | `review-status` |
@@ -1442,7 +1443,7 @@ app writes a tab value: search for `BbTabs` with `navigation` or `query-key`,
1442
1443
  hard-coded `?tab=` / `?<queryKey>=` links, `router.push` / `visit` / `href`
1443
1444
  calls that build a tab value, server redirects, and emails or notifications
1444
1445
  that link to a tab, and rewrite each legacy (underscore or squashed) value to
1445
- its kebab form — `slotKey(key)` gives it.
1446
+ its kebab form — `slotKey(value)` gives it.
1446
1447
 
1447
1448
  **Back/forward re-selects the tab, on every platform.** On Vue Router/Nuxt the
1448
1449
  re-selection watcher tracks the route's own query (`$route.query[queryKey]`),
@@ -1522,9 +1523,9 @@ to roll back:
1522
1523
  ```vue
1523
1524
  <BbTabs
1524
1525
  :items="[
1525
- { key: 'overview', label: 'Overview', href: '/project/overview' },
1526
+ { value: 'overview', label: 'Overview', href: '/project/overview' },
1526
1527
  {
1527
- key: 'activity',
1528
+ value: 'activity',
1528
1529
  label: 'Activity',
1529
1530
  href: '/project/activity',
1530
1531
  server: true,
@@ -1651,9 +1652,9 @@ import type { BbTabsItem } from 'bitboss-ui';
1651
1652
  type Section = 'general' | 'members' | 'billing';
1652
1653
 
1653
1654
  const tabs: Array<BbTabsItem<Section>> = [
1654
- { key: 'general', label: 'General' },
1655
- { key: 'members', label: 'Members' },
1656
- { key: 'billing', label: 'Billing' },
1655
+ { value: 'general', label: 'General' },
1656
+ { value: 'members', label: 'Members' },
1657
+ { value: 'billing', label: 'Billing' },
1657
1658
  ];
1658
1659
 
1659
1660
  const section = ref<Section>('general');
@@ -1725,9 +1726,9 @@ import type { BbTabsItem } from 'bitboss-ui';
1725
1726
  type Section = 'profile' | 'notifications' | 'security';
1726
1727
 
1727
1728
  const sections: Array<BbTabsItem<Section>> = [
1728
- { key: 'profile', label: 'Profile' },
1729
- { key: 'notifications', label: 'Notifications' },
1730
- { key: 'security', label: 'Security' },
1729
+ { value: 'profile', label: 'Profile' },
1730
+ { value: 'notifications', label: 'Notifications' },
1731
+ { value: 'security', label: 'Security' },
1731
1732
  ];
1732
1733
 
1733
1734
  const section = ref<Section>('profile');
@@ -1744,7 +1745,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
1744
1745
  ### Works well with
1745
1746
 
1746
1747
  - **`BbBadge` / count pills in `label` slots** — status dots and unread counts
1747
- ride in the `<key>:label` or `label` slot; the strip re-measures when they
1748
+ ride in the `<value>:label` or `label` slot; the strip re-measures when they
1748
1749
  resize.
1749
1750
  - **`BbButton` for Prev/Next** — feed `goTo` from the `BbTabsRoot` default slot
1750
1751
  or from `useBbTabsContext`, binding `:disabled` to `isFirst`/`isLast`.
@@ -1839,7 +1840,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
1839
1840
  | `id` | `string \| undefined` | | | The root's `id`, and the key `useBbTabsContext(id)` pairs by. Generated when omitted. |
1840
1841
  | `items` | `BbTabsItem<K>[]` | | yes | Array of items that define the tabs in the component. |
1841
1842
  | `manualActivation` | `boolean \| undefined` | ``undefined` (on when `server` is set on the strip or an item…` | | Arrow keys only move focus; Enter or Space opens the tab (APG manual activation). Home and End move focus too; a click still opens a tab at once. When unset it is on for a strip that makes server visits (`server` on the strip or on any item), where opening a tab on every arrow press would fire a visit per tab passed, and off everywhere else (automatic activation: the arrow keys open the tab they land on). `href` alone does not turn it on: that is a client-side URL rewrite. `true` / `false` override either way. The Radix / Reka / Ark spelling of the same thing is `activationMode="manual"` / `"automatic"`. |
1842
- | `modelValue` | `K \| null \| undefined` | | | The current tab key. Used by v-model. |
1843
+ | `modelValue` | `K \| null \| undefined` | | | The active tab's `value`. Used by v-model. |
1843
1844
  | `navigation` | `boolean \| undefined` | `false` | | Synchronizes the current tab with the URL query parameter. Pair it with `replace` unless a tab is genuinely a separate destination — see the `replace` prop. |
1844
1845
  | `onBefore` | `(() => boolean \| void) \| undefined` | | | Inertia lifecycle hook — fired just before the request is sent. Return `false` to cancel the visit. |
1845
1846
  | `onCancel` | `(() => void) \| undefined` | | | Inertia lifecycle hook — fired when the request is cancelled. |
@@ -1883,11 +1884,11 @@ States are listed in precedence order: when two are on at once and their entries
1883
1884
 
1884
1885
  ## Slots
1885
1886
 
1886
- - `label` — scope: `BbTabsSlotProps<K>` `{ current: K \| null; currentIndex: number; disabled: boolean; isFirst: boolean; isLast: boolean; selected: boolean; text: string; value: K; goTo: (target: "first" \| "previous" \| "next" \| "last") => void }` — Fallback slot used for all tab labels when no per-tab `<key>:label` slot is provided.
1887
+ - `label` — scope: `BbTabsSlotProps<K>` `{ current: K \| null; currentIndex: number; disabled: boolean; isFirst: boolean; isLast: boolean; selected: boolean; label: string; value: K; goTo: (target: "first" \| "previous" \| "next" \| "last") => void }` — Fallback slot used for all tab labels when no per-tab `<value>:label` slot is provided.
1887
1888
  - `wrapper:append` — scope: `BbTabsScrollSlotProps` `{ isScrolling: boolean; canScrollLeft: boolean; canScrollRight: boolean; scroll: (direction: "left" \| "right") => void }` — Content rendered after the scrollable tab label list (e.g. a right scroll arrow).
1888
1889
  - `wrapper:prepend` — scope: `BbTabsScrollSlotProps` `{ isScrolling: boolean; canScrollLeft: boolean; canScrollRight: boolean; scroll: (direction: "left" \| "right") => void }` — Content rendered before the scrollable tab label list (e.g. a left scroll arrow).
1889
- - `#<key>` (named from data) — scope: `BbTabsSlotProps<K>` — One tab's content panel, by the tab `key` through `slotKey`; no fallback (an empty panel). Reserved keys (their slot is one of this component's own, so a key spelled like them is an error): `label`.
1890
- - `#<key>:label` (named from data) — scope: `BbTabsSlotProps<K>` — One tab trigger's label, by the tab `key` through `slotKey`; beats `label`, which beats the item's `label` text.
1890
+ - `#<value>` (named from data) — scope: `BbTabsSlotProps<K>` — One tab's content panel, by the tab's `value` through `slotKey`; no fallback (an empty panel). Reserved names (their slot is one of this component's own, so an item value or column key spelled like them is an error): `label`.
1891
+ - `#<value>:label` (named from data) — scope: `BbTabsSlotProps<K>` — One tab trigger's label, by the tab's `value` through `slotKey`; beats `label`, which beats the item's `label` text.
1891
1892
 
1892
1893
  ## CSS custom properties
1893
1894
 
@@ -47,10 +47,10 @@ States are listed in precedence order: when two are on at once and their entries
47
47
 
48
48
  ## Slots
49
49
 
50
- - `label` — scope: `BbTabsSlotProps<string>` `{ current: K \| null; currentIndex: number; disabled: boolean; isFirst: boolean; isLast: boolean; selected: boolean; text: string; value: K; goTo: (target: "first" \| "previous" \| "next" \| "last") => void }` — Fallback slot used for all tab labels when no per-tab `<key>:label` slot is provided.
50
+ - `label` — scope: `BbTabsSlotProps<string>` `{ current: K \| null; currentIndex: number; disabled: boolean; isFirst: boolean; isLast: boolean; selected: boolean; label: string; value: K; goTo: (target: "first" \| "previous" \| "next" \| "last") => void }` — Fallback slot used for all tab labels when no per-tab `<value>:label` slot is provided.
51
51
  - `wrapper:append` — scope: `BbTabsScrollSlotProps` `{ isScrolling: boolean; canScrollLeft: boolean; canScrollRight: boolean; scroll: (direction: "left" \| "right") => void }` — Content rendered after the scrollable tab label list (e.g. a right scroll arrow).
52
52
  - `wrapper:prepend` — scope: `BbTabsScrollSlotProps` `{ isScrolling: boolean; canScrollLeft: boolean; canScrollRight: boolean; scroll: (direction: "left" \| "right") => void }` — Content rendered before the scrollable tab label list (e.g. a left scroll arrow).
53
- - `#<key>:label` (named from data) — scope: `BbTabsSlotProps<K>` — One tab trigger's label, by the tab `key` through `slotKey`; beats `label`, which beats the item's `label` text.
53
+ - `#<value>:label` (named from data) — scope: `BbTabsSlotProps<K>` — One tab trigger's label, by the tab's `value` through `slotKey`; beats `label`, which beats the item's `label` text.
54
54
 
55
55
  ## CSS custom properties
56
56
 
@@ -36,7 +36,7 @@ States are listed in precedence order: when two are on at once and their entries
36
36
 
37
37
  ## Slots
38
38
 
39
- - `#<key>` (named from data) — scope: `BbTabsSlotProps<K>` — One tab's content panel, by the tab `key` through `slotKey`; no fallback (an empty panel).
39
+ - `#<value>` (named from data) — scope: `BbTabsSlotProps<K>` — One tab's content panel, by the tab's `value` through `slotKey`; no fallback (an empty panel).
40
40
 
41
41
  ## CSS custom properties
42
42
 
@@ -27,7 +27,7 @@
27
27
  | `id` | `string \| undefined` | | | The root's `id`, and the key `useBbTabsContext(id)` pairs by. Generated when omitted. |
28
28
  | `items` | `BbTabsItem<K>[]` | | yes | Array of items that define the tabs in the component. |
29
29
  | `manualActivation` | `boolean \| undefined` | ``undefined` (on when `server` is set on the strip or an item…` | | Arrow keys only move focus; Enter or Space opens the tab (APG manual activation). Home and End move focus too; a click still opens a tab at once. When unset it is on for a strip that makes server visits (`server` on the strip or on any item), where opening a tab on every arrow press would fire a visit per tab passed, and off everywhere else (automatic activation: the arrow keys open the tab they land on). `href` alone does not turn it on: that is a client-side URL rewrite. `true` / `false` override either way. The Radix / Reka / Ark spelling of the same thing is `activationMode="manual"` / `"automatic"`. |
30
- | `modelValue` | `K \| null \| undefined` | | | The current tab key. Used by v-model. |
30
+ | `modelValue` | `K \| null \| undefined` | | | The active tab's `value`. Used by v-model. |
31
31
  | `navigation` | `boolean \| undefined` | `false` | | Synchronizes the current tab with the URL query parameter. Pair it with `replace` unless a tab is genuinely a separate destination — see the `replace` prop. |
32
32
  | `onBefore` | `(() => boolean \| void) \| undefined` | | | Inertia lifecycle hook — fired just before the request is sent. Return `false` to cancel the visit. |
33
33
  | `onCancel` | `(() => void) \| undefined` | | | Inertia lifecycle hook — fired when the request is cancelled. |
@@ -50,7 +50,7 @@
50
50
 
51
51
  ## Slots
52
52
 
53
- - `default` — scope: `BbTabsRootSlotProps<K>` `{ current: K \| null; currentIndex: number; isFirst: boolean; isLast: boolean; goTo: (target: "first" \| "previous" \| "next" \| "last") => void; select: (key: K) => void }` — Arbitrary layout hosting `BbTabsList` / `BbTabsPanels` anywhere in its subtree.
53
+ - `default` — scope: `BbTabsRootSlotProps<K>` `{ current: K \| null; currentIndex: number; isFirst: boolean; isLast: boolean; goTo: (target: "first" \| "previous" \| "next" \| "last") => void; select: (value: K) => void }` — Arbitrary layout hosting `BbTabsList` / `BbTabsPanels` anywhere in its subtree.
54
54
 
55
55
  ## See Also
56
56
 
@@ -131,7 +131,8 @@ bitbossUi({ tooltipVariants: ['info', 'success'] });
131
131
  The most common real use: a compact row of icon-only actions, each named by a
132
132
  tooltip. This companion frames a shared-document chrome — title, muted meta, and
133
133
  `size="xs"` ghost buttons grouped with thin dividers. A `:delay="400"` keeps the
134
- bubbles from flickering while the pointer crosses the dense toolbar.
134
+ bubbles from flickering while the pointer crosses the dense toolbar; once one
135
+ hint shows, its neighbours open at once (the skip delay, below).
135
136
 
136
137
  **Icon toolbar with tooltips**
137
138
 
@@ -248,10 +249,21 @@ is concerned — the whole label (shortcut included) is flattened into the
248
249
 
249
250
  - `placement` — as above; the `top`/`right`/`bottom`/`left` families with
250
251
  `-start`/`-end` variants, auto-flipping near an edge.
251
- - `delay` (ms, default `0`) holds the tooltip back until the pointer settles —
252
- useful on dense toolbars to avoid a flicker of bubbles while the cursor passes
253
- over. It delays only the **open**; the close is always a short debounce (so the
254
- pointer can travel from the trigger into the bubble without it vanishing).
252
+ - `delay` (ms, default `100`) holds the tooltip back until the pointer settles,
253
+ so a cursor passing over a row of buttons doesn't flash a bubble at each one;
254
+ raise it on dense toolbars. It delays only the **open**, and only for a
255
+ pointer; the close is always a short debounce (so the pointer can travel from
256
+ the trigger into the bubble without it vanishing).
257
+ - **Keyboard focus shows the hint at once**, whatever `delay` says: a Tab onto a
258
+ control is never an accident.
259
+ - **The skip delay:** while a tooltip shows, or for 300 ms after one closes, the
260
+ next tooltip the pointer reaches opens at once. Run the pointer along a
261
+ toolbar and every hint after the first appears without a wait. It is shared by
262
+ every `BbTooltip` and `v-bb-tooltip`, needs no setup, and leaves hover cards
263
+ alone (they keep their own 350 ms). A tooltip that hid because a menu or
264
+ dialog opened doesn't count.
265
+ - `:delay="0"` shows the tooltip on hover at once (the default before
266
+ 3.0.0-beta.49).
255
267
  - `width` caps the bubble so long hints wrap instead of stretching across the
256
268
  screen. It is a **maximum, not a fixed width** — the bubble still shrinks to
257
269
  short text, so a one-line hint never sits in an oversized box. A bare number
@@ -510,7 +522,8 @@ type ToolbarAction = {
510
522
  // Same document-toolbar hints as `IconButtonTooltips.vue`, restyled through
511
523
  // passthrough: a muted wash on `pt:panel` (the bubble — default is the
512
524
  // inverted primary), `pt:root:open` adds a drop shadow while showing. Hover
513
- // a glyph to see the pt; delay 400 matches dense toolbars.
525
+ // a glyph to see the pt; `delay` 400 (the default is 100) holds the first hint
526
+ // back in a dense toolbar, and the next glyph's hint opens at once (skip delay).
514
527
  const actions: ToolbarAction[] = [
515
528
  { label: 'Undo', icon: 'lucide:undo-2' },
516
529
  { label: 'Redo', icon: 'lucide:redo-2' },
@@ -564,9 +577,10 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
564
577
  The node it points at is `hidden`: read as the activator's description, never
565
578
  as page text of its own, and still read inside an open `BbDialog` (the
566
579
  directive's node lives at the end of `<body>`, which a modal makes inert).
567
- - The tooltip opens on keyboard focus (`:focus-visible`) and on hover, and closes
568
- on blur, mouse-leave, or `Escape`. A mouse click does not open it (hover
569
- already covers the pointer), so it never pops over the thing you just clicked.
580
+ - The tooltip opens on keyboard focus (`:focus-visible`, at once) and on hover
581
+ (after `delay`), and closes on blur, mouse-leave, or `Escape`. A mouse click
582
+ does not open it (hover already covers the pointer), so it never pops over the
583
+ thing you just clicked.
570
584
  - Because the bubble is not focusable and holds no interactive content, never
571
585
  place a link or button inside it — use `BbPopover` for that.
572
586
  - The tooltip supplements an accessible name; it does not provide one. Icon-only
@@ -584,7 +598,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
584
598
  | `activator` | `ElementOrComponentRef \| undefined` | | | External activator element or component ref. When provided, the activator slot is not rendered and event listeners are attached programmatically to the referenced element. |
585
599
  | `arrowPadding` | `number \| undefined` | `10` | | Space the arrow will maintain to the edge of the tooltip bubble. Useful when the floating element has border radius so it won't appear broken |
586
600
  | `boundary` | `ElementOrComponentRefOrSelector \| undefined` | | | Constrains the tooltip within a bounding element. When provided, the tooltip will not overflow this container's bounds (e.g. a sidebar). Accepts an HTMLElement, a Vue component ref, or a CSS selector string. |
587
- | `delay` | `number \| undefined` | `0` | | The delay in milliseconds before the tooltip is shown. |
601
+ | `delay` | `number \| undefined` | `100` | | How long, in milliseconds, a pointer has to rest on the activator before the tooltip shows; it keeps hints from flashing under a pointer passing by. Keyboard focus shows it at once whatever this says, and so does a pointer arriving while another tooltip shows or within 300 ms of one closing (the skip delay, shared by every tooltip). `0` shows it on hover at once. |
588
602
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component |
589
603
  | `eager` | `boolean \| undefined` | `false` | | Renders the tooltip's popover and content at mount instead of on the first open. The description screen readers hear exists from mount either way. |
590
604
  | `hideArrow` | `boolean \| undefined` | `false` | | Hides the tooltip arrow. A tooltip shows its arrow by default (it's the one popover-family surface where an arrow is meaningful — a speech bubble pointing at its anchor); set this to drop it. |