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
@@ -506,7 +506,7 @@ export type BbAlertSlots = {
506
506
  letter-spacing: -0.01em;
507
507
  line-height: var(--title-lh);
508
508
  margin-bottom: 2px;
509
- padding-right: calc(var(--close-size) + var(--gap));
509
+ padding-inline-end: calc(var(--close-size) + var(--gap));
510
510
  }
511
511
 
512
512
  .bb-alert__text {
@@ -526,9 +526,9 @@ export type BbAlertSlots = {
526
526
  );
527
527
  --right-p: var(--top-p); /* same inset on the right edge */
528
528
  color: var(--fg-muted);
529
+ inset-inline-end: var(--right-p);
529
530
  padding: 2px;
530
531
  position: absolute;
531
- right: var(--right-p);
532
532
  top: var(--top-p);
533
533
  .bb-icon {
534
534
  --size: var(--close-size);
@@ -569,8 +569,8 @@ export type BbAlertSlots = {
569
569
  --hit: 44px;
570
570
  content: '';
571
571
  height: var(--hit);
572
+ inset-inline-end: calc(-1 * var(--right-p));
572
573
  position: absolute;
573
- right: calc(-1 * var(--right-p));
574
574
  top: calc(-1 * var(--top-p));
575
575
  width: var(--hit);
576
576
  }
@@ -632,7 +632,7 @@ export type BbBadgeButtonSlots = {
632
632
  &:has(> .bb-badge__trailing) {
633
633
  .bb-badge__body {
634
634
  border-radius: var(--r) 0 0 var(--r);
635
- padding-right: 0;
635
+ padding-inline-end: 0;
636
636
  }
637
637
  }
638
638
 
@@ -659,7 +659,7 @@ export type BbBadgeButtonSlots = {
659
659
  /* Overlap the (hidden) clear button onto the append icon so they share the
660
660
  trailing slot and cross-fade in place on hover/focus. */
661
661
  &:has(+ .bb-badge__clear) {
662
- margin-right: calc(
662
+ margin-inline-end: calc(
663
663
  (
664
664
  var(--gap) + (var(--clear-size) - var(--icon-size)) / 2 +
665
665
  var(--icon-size)
@@ -88,8 +88,9 @@ const bindings = computed(() => {
88
88
  .concat(onClick ?? [])
89
89
  .filter((fn): fn is ClickListener => typeof fn === 'function');
90
90
  return mergeProps(rest, props as Record<string, unknown>, {
91
- 'aria-disabled': loading.value ? true : undefined,
92
- tabindex: loading.value ? -1 : undefined,
91
+ // Only while loading: an `undefined` here would erase the consumer's own
92
+ // `aria-disabled` / `tabindex`, which `rest` carries.
93
+ ...(loading.value ? { 'aria-disabled': true, tabindex: -1 } : {}),
93
94
  onClick: (event: MouseEvent) => {
94
95
  if (loading.value) {
95
96
  // A link or submit body must not act either.
@@ -506,7 +507,7 @@ export type BbBadgeButtonSlots = {
506
507
  &:has(> .bb-badge__trailing) {
507
508
  .bb-badge__body {
508
509
  border-radius: var(--r) 0 0 var(--r);
509
- padding-right: 0;
510
+ padding-inline-end: 0;
510
511
  }
511
512
  }
512
513
 
@@ -533,7 +534,7 @@ export type BbBadgeButtonSlots = {
533
534
  /* Overlap the (hidden) clear button onto the append icon so they share the
534
535
  trailing slot and cross-fade in place on hover/focus. */
535
536
  &:has(+ .bb-badge__clear) {
536
- margin-right: calc(
537
+ margin-inline-end: calc(
537
538
  (
538
539
  var(--gap) + (var(--clear-size) - var(--icon-size)) / 2 +
539
540
  var(--icon-size)
@@ -883,7 +883,7 @@ export const BB_BASE_BUTTON_PROP_KEYS = Object.keys(baseButtonPropMap) as Array<
883
883
  cursor: pointer;
884
884
  outline: 2px solid transparent;
885
885
  outline-offset: 2px;
886
- text-align: left;
886
+ text-align: start;
887
887
  transition-duration: var(--bb-transition-fast);
888
888
  transition-property:
889
889
  color, background-color, border-color, text-decoration-color, box-shadow;
@@ -205,6 +205,7 @@ export type BbBaseRadioIconProps = {
205
205
  /* Inner disc inset must track the glyph stroke, not a leftover 2px,
206
206
  or a 3px plate theme clips the checked dot. */
207
207
  height: calc(100% - 2 * var(--bb-border-w-sm) - var(--space));
208
+ /* stylelint-disable-next-line property-disallowed-list -- geometry: centred with a physical translate */
208
209
  left: 50%;
209
210
  position: absolute;
210
211
  top: 50%;
@@ -234,6 +234,7 @@ export type BbBaseSwitchIconProps = {
234
234
  border-radius: calc(var(--r) * 0.8);
235
235
  display: inline-block;
236
236
  height: var(--thumb);
237
+ /* stylelint-disable-next-line property-disallowed-list -- geometry: the thumb travels by a physical translate */
237
238
  left: var(--inset);
238
239
  position: absolute;
239
240
  top: var(--inset);
@@ -80,7 +80,7 @@
80
80
  <!-- Visible breadcrumb items (index >= overflowCount) -->
81
81
  <template
82
82
  v-for="(item, index) in items"
83
- :key="item.key ?? `:keyless-${index}`"
83
+ :key="item.value ?? `:keyless-${index}`"
84
84
  >
85
85
  <template v-if="index >= overflowCount">
86
86
  <li
@@ -109,13 +109,13 @@
109
109
  :disabled="item.disabled || disabled"
110
110
  :tag="isCurrent(item, index) ? 'span' : undefined"
111
111
  >
112
- <!-- prepend: <key>:prepend | item:prepend | inline prepend:icon -->
112
+ <!-- prepend: <value>:prepend | item:prepend | inline prepend:icon -->
113
113
  <slot
114
114
  :disabled="!!(item.disabled || disabled)"
115
115
  :index="index"
116
116
  :item="item"
117
+ :label="item.label"
117
118
  :name="edgeSlot(item, 'prepend').name"
118
- :text="item.text"
119
119
  />
120
120
  <BbIcon
121
121
  v-if="
@@ -135,7 +135,7 @@
135
135
  class="bb-breadcrumbs__text"
136
136
  :title="
137
137
  items.length > 1 && overflowCount === items.length - 1
138
- ? item.text
138
+ ? item.label
139
139
  : undefined
140
140
  "
141
141
  v-bind="
@@ -149,18 +149,18 @@
149
149
  :disabled="!!(item.disabled || disabled)"
150
150
  :index="index"
151
151
  :item="item"
152
+ :label="item.label"
152
153
  :name="itemSlotBase(item)"
153
- :text="item.text"
154
- >{{ item.text }}</slot
154
+ >{{ item.label }}</slot
155
155
  >
156
156
  </span>
157
- <!-- append: <key>:append | item:append | inline append:icon -->
157
+ <!-- append: <value>:append | item:append | inline append:icon -->
158
158
  <slot
159
159
  :disabled="!!(item.disabled || disabled)"
160
160
  :index="index"
161
161
  :item="item"
162
+ :label="item.label"
162
163
  :name="edgeSlot(item, 'append').name"
163
- :text="item.text"
164
164
  />
165
165
  <BbIcon
166
166
  v-if="!edgeSlot(item, 'append').exists && item['append:icon']"
@@ -233,12 +233,12 @@ const props = withDefaults(defineProps<BbBreadcrumbsProps>(), {
233
233
 
234
234
  defineSlots<BbBreadcrumbsSlots>();
235
235
 
236
- // Per-crumb slots are named after each item's `key` through `slotKey`, so a
236
+ // Per-crumb slots are named after each item's `value` through `slotKey`, so a
237
237
  // removed prop or a slot spelled the pre-reset way is reported, as on BbTable
238
238
  // / BbTabs (Q56.28).
239
239
  if (process.env.NODE_ENV !== 'production')
240
240
  warnRemovedAttrs('BbBreadcrumbs', removedPropsFor('BbBreadcrumbs'), {
241
- slotKeys: () => props.items.map((item) => item.key),
241
+ slotKeys: () => props.items.map((item) => item.value),
242
242
  });
243
243
  /**
244
244
  * Passthrough (plans/passthrough/BbBreadcrumbs.md). `item` is resolved per crumb (`active` = the current page: the last crumb, when it has no target).
@@ -291,14 +291,16 @@ const STRUCTURAL_SLOTS = new Set([
291
291
  ]);
292
292
 
293
293
  /**
294
- * Normalized slot base for an item (`slotKey(key)`), shared with every family
295
- * component. A crumb without a `key` gets `:keyless` — a name `slotKey` never
294
+ * Normalized slot base for an item (`slotKey(value)`), shared with every family
295
+ * component. A crumb without a `value` gets `:keyless` — a name `slotKey` never
296
296
  * produces and no template can write — so it has no slot of its own and falls
297
297
  * back to the generic ones (Q53.16 / owner doctrine 2026-09-24: slot names are
298
- * written, never derived from the text).
298
+ * written, never derived from the label).
299
299
  */
300
300
  const itemSlotBase = (item: Item) =>
301
- item.key == null || item.key === '' ? ':keyless' : slotKey(String(item.key));
301
+ item.value == null || item.value === ''
302
+ ? ':keyless'
303
+ : slotKey(String(item.value));
302
304
 
303
305
  /**
304
306
  * Item props forwarded to the inner `BbBaseButton`, minus the edge-icon fields
@@ -324,14 +326,20 @@ const isCurrent = (item: Item, index: number) =>
324
326
  !item.onClick;
325
327
 
326
328
  const buttonProps = (item: Item, index: number) => {
327
- const { ['prepend:icon']: _p, ['append:icon']: _a, ...rest } = item;
329
+ const {
330
+ ['prepend:icon']: _p,
331
+ ['append:icon']: _a,
332
+ value: _value,
333
+ label: _label,
334
+ ...rest
335
+ } = item;
328
336
  return isCurrent(item, index)
329
337
  ? { ...rest, 'aria-current': 'page' as const }
330
338
  : rest;
331
339
  };
332
340
 
333
341
  /**
334
- * Resolves an edge region's precedence — `<key>:suffix` (per-item) →
342
+ * Resolves an edge region's precedence — `<value>:suffix` (per-item) →
335
343
  * `item:suffix` (generic) → inline `prepend:icon`/`append:icon`. Returns the
336
344
  * winning slot `name` plus whether a slot actually `exists`; when it doesn't,
337
345
  * `name` is the (absent) per-key name so the outlet renders nothing and the
@@ -369,7 +377,7 @@ const resolvedEllipsisAriaLabel = computed(
369
377
  * Estimates one breadcrumb item width using weighted character categories.
370
378
  */
371
379
  const estimateItemWidth = (item: Item) => {
372
- const label = item.text ?? String(item.key);
380
+ const label = item.label ?? '';
373
381
  return estimateBreadcrumbItemWidth(label, {
374
382
  estimationBias: resolvedEstimationBias.value,
375
383
  fontWidth: FONT_WIDTH,
@@ -492,7 +500,9 @@ const recompute = (availableWidth: number) => {
492
500
  // Observe this component width so overflow is based on real allocated space.
493
501
  const breadcrumbsEl = computed(() => navRef.value);
494
502
  const itemsWidthSignature = computed(() =>
495
- props.items.map((item) => `${String(item.key)}::${item.text ?? ''}`).join('|')
503
+ props.items
504
+ .map((item) => `${String(item.value)}::${item.label ?? ''}`)
505
+ .join('|')
496
506
  );
497
507
  // --- Recompute scheduling + runaway-loop guard ------------------------------
498
508
  // The ResizeObserver watches this element, but a recompute can flip
@@ -641,15 +651,15 @@ onBeforeUnmount(() => {
641
651
  }
642
652
  });
643
653
 
644
- // Map hidden items to BbDropdown item format. `prepend:icon` / `append:icon`
645
- // carry over verbatim (same field names as a dropdown item), and per-item slots
646
- // are forwarded below, so an overflowed item renders the same content.
647
- const overflowDropdownItems = computed<DropdownItem[]>(() => {
648
- return props.items.slice(0, overflowCount.value).map((item) => ({
649
- ...item,
650
- text: item.text ?? item.key ?? '',
651
- }));
652
- });
654
+ // Hidden crumbs ARE dropdown rows: the same `{ label, value }` shape and the
655
+ // same `prepend:icon` / `append:icon`, so they pass straight through, and the
656
+ // per-crumb slots are forwarded below, so an overflowed crumb renders the same
657
+ // content. A crumb without a label is a row without one.
658
+ const overflowDropdownItems = computed<DropdownItem[]>(() =>
659
+ props.items
660
+ .slice(0, overflowCount.value)
661
+ .map((item) => ({ ...item, label: item.label ?? '' }) as DropdownItem)
662
+ );
653
663
  </script>
654
664
 
655
665
  <style lang="postcss">
@@ -664,27 +674,38 @@ import type { BbBaseButtonProps } from '../BbBaseButton/types';
664
674
  import type { PtMap, PtValue } from '@/types/passthrough';
665
675
  import type { IconType } from '@/types/Icon';
666
676
 
667
- export type Item = Omit<BbBaseButtonProps, 'block' | 'tag' | 'type'> & {
677
+ export type Item = Omit<
678
+ BbBaseButtonProps,
679
+ 'block' | 'tag' | 'type' | 'text'
680
+ > & {
668
681
  /**
669
682
  * Click handler of the button.
670
683
  */
671
684
  onClick?: (event: MouseEvent) => void | Promise<void>;
685
+ /** The crumb's text. */
686
+ label?: string;
672
687
  /**
673
- * Key that uniquely identifies the breadcrumb, and the base for its own
674
- * named slots (`slotKey(key)`, kebab-case). Optional unless the crumb has a
675
- * slot of its own: a keyless crumb renders with the generic slots only
676
- * (Q53.17 — slot names are written, never derived from the text).
688
+ * Identifies the crumb, and names its own slots (`slotKey(value)`,
689
+ * kebab-case: `#<value>`, `#<value>:prepend`, `#<value>:append`). Optional
690
+ * unless the crumb has a slot of its own: a crumb without one renders with
691
+ * the generic slots only (Q53.17 — slot names are written, never derived
692
+ * from the label). A crumb hidden in the overflow menu is a dropdown row with
693
+ * the same `label` and `value`.
677
694
  */
678
- key?: string;
695
+ value?: string;
696
+ /** Crumbs have no `key` (that is `value`). Guards against the old shape. */
697
+ key?: never;
698
+ /** Crumbs have no `text` (that is `label`). Guards against the old shape. */
699
+ text?: never;
679
700
  /**
680
701
  * Icon rendered before the breadcrumb label, in the leading edge region
681
702
  * (outside the link, so it never inherits the link's text styling). Acts as
682
- * the fallback when no `<key>:prepend` / `item:prepend` slot is provided.
703
+ * the fallback when no `<value>:prepend` / `item:prepend` slot is provided.
683
704
  */
684
705
  'prepend:icon'?: IconType;
685
706
  /**
686
707
  * Icon rendered after the breadcrumb label, in the trailing edge region.
687
- * Fallback when no `<key>:append` / `item:append` slot is provided.
708
+ * Fallback when no `<value>:append` / `item:append` slot is provided.
688
709
  */
689
710
  'append:icon'?: IconType;
690
711
  };
@@ -786,8 +807,8 @@ export type BbBreadcrumbsItemSlotProps = {
786
807
  index: number;
787
808
  /** The raw item object from the `items` prop. */
788
809
  item: Item;
789
- /** The resolved display text for this item. */
790
- text?: string;
810
+ /** The crumb's label. */
811
+ label?: string;
791
812
  };
792
813
 
793
814
  /** Props exposed by the `ellipsis` slot. */
@@ -806,9 +827,9 @@ export type BbBreadcrumbsEllipsisSlotProps = {
806
827
  };
807
828
 
808
829
  /**
809
- * @dynamicSlot `<key>` {BbBreadcrumbsItemSlotProps} - One crumb's label, by its `key` through `slotKey`; falls back to `item.text`. A crumb folded into the overflow menu follows BbDropdown's slot rules instead.
810
- * @dynamicSlot `<key>:prepend` {BbBreadcrumbsItemSlotProps} - The glyph before one crumb's label; beats `item:prepend`, which beats its `prepend:icon`.
811
- * @dynamicSlot `<key>:append` {BbBreadcrumbsItemSlotProps} - The glyph after one crumb's label; beats `item:append`, which beats its `append:icon`.
830
+ * @dynamicSlot `<value>` {BbBreadcrumbsItemSlotProps} - One crumb's label, by its `value` through `slotKey`; falls back to `item.label`. A crumb folded into the overflow menu follows BbDropdown's slot rules instead (the same `#<value>` names).
831
+ * @dynamicSlot `<value>:prepend` {BbBreadcrumbsItemSlotProps} - The glyph before one crumb's label; beats `item:prepend`, which beats its `prepend:icon`.
832
+ * @dynamicSlot `<value>:append` {BbBreadcrumbsItemSlotProps} - The glyph after one crumb's label; beats `item:append`, which beats its `append:icon`.
812
833
  */
813
834
  export type BbBreadcrumbsSlots = {
814
835
  /**
@@ -821,14 +842,14 @@ export type BbBreadcrumbsSlots = {
821
842
  append?: (props: BbBreadcrumbsEdgeSlotProps) => any;
822
843
  /**
823
844
  * Content rendered before **every** breadcrumb item's link/button, in the
824
- * leading edge region. Generic fallback: a per-item `<key>:prepend` slot
845
+ * leading edge region. Generic fallback: a per-item `<value>:prepend` slot
825
846
  * takes precedence, and the item's `prepend:icon` is used when neither slot
826
847
  * is present.
827
848
  */
828
849
  'item:prepend'?: (props: BbBreadcrumbsItemSlotProps) => any;
829
850
  /**
830
851
  * Content rendered after **every** breadcrumb item's link/button. Generic
831
- * fallback below a per-item `<key>:append` slot and above the item's
852
+ * fallback below a per-item `<value>:append` slot and above the item's
832
853
  * `append:icon`.
833
854
  */
834
855
  'item:append'?: (props: BbBreadcrumbsItemSlotProps) => any;
@@ -69,7 +69,8 @@
69
69
  <script setup lang="ts">
70
70
  import { BbBaseButton, BbSpinner } from '@/index';
71
71
  import BbIcon from '../BbIcon/BbIcon.vue';
72
- import { computed, mergeProps, ref, useAttrs, watchEffect } from 'vue';
72
+ import { computed, inject, mergeProps, ref, useAttrs, watchEffect } from 'vue';
73
+ import { BB_FORM_SUBMIT_LOCK } from '@/composables/formSubmitLock';
73
74
  import { pickBy } from '@/utilities/functions/pickBy';
74
75
  import { noop } from '@/utilities/functions/noop';
75
76
  import { useLocale } from '@/composables/useLocale';
@@ -81,6 +82,7 @@ import { extractDomContainer } from '@/utilities/functions/extractDomContainer';
81
82
  import { isEqual } from '@/utilities/functions/isEqual';
82
83
  import { usePassthrough } from '@/composables/usePassthrough';
83
84
  import { BB_BUTTON_PT, type BbButtonProps, type BbButtonSlots } from './types';
85
+ import { useToggleRoving } from './toggleRoving';
84
86
  import type { Sizes as SizeMap } from '@/types/SizeScale';
85
87
  type Sizes = keyof SizeMap;
86
88
 
@@ -143,8 +145,16 @@ const forwardedAttrs = computed(() => {
143
145
 
144
146
  const internalLoading = ref(0);
145
147
 
148
+ // Q60.17: a `type="submit"` button inside a BbForm spins while the form's
149
+ // save runs (unless the form sets `disable-submit-lock`). Other buttons in
150
+ // the form (Cancel, a row action) are untouched.
151
+ const formLock = inject(BB_FORM_SUBMIT_LOCK, null);
152
+
146
153
  const loading = computed(
147
- () => props.loading || (!!internalLoading.value && !props.disableAutoLoading)
154
+ () =>
155
+ props.loading ||
156
+ (!!internalLoading.value && !props.disableAutoLoading) ||
157
+ (props.type === 'submit' && !!formLock?.locked())
148
158
  );
149
159
 
150
160
  /** Latches on the first load; gates the spinner's <Transition> — see the template. */
@@ -289,11 +299,35 @@ const softDisabled = computed(
289
299
  () => loading.value && !props.interactiveWhileLoading
290
300
  );
291
301
 
302
+ /**
303
+ * Adjacent `group` toggles are one Tab stop with arrow keys inside
304
+ * (Q44.25-001, see `toggleRoving.ts`). A consumer `tabindex` opts a button out.
305
+ */
306
+ const roving = useToggleRoving(
307
+ buttonDom,
308
+ computed(() => !!props.group && isToggle.value && !('tabindex' in attrs)),
309
+ () => [isPressed.value, props.disabled, softDisabled.value]
310
+ );
311
+
312
+ /**
313
+ * The `tabindex` / `aria-disabled` we mean, or nothing. Written as `undefined`
314
+ * they used to reach `mergeProps` after the forwarded attrs and erase a
315
+ * consumer's own `tabindex` / `aria-disabled`: an explicit attr wins unless we
316
+ * mean one (loading takes the button out of the tab order either way).
317
+ */
318
+ const managedFocus = computed(() => {
319
+ const tabindex = softDisabled.value ? -1 : roving.tabindex.value;
320
+ return {
321
+ ...(softDisabled.value ? { 'aria-disabled': true } : {}),
322
+ ...(tabindex === undefined ? {} : { tabindex }),
323
+ };
324
+ });
325
+
292
326
  const rootBindings = computed(() =>
293
327
  mergeProps(
294
328
  propsToPass.value,
295
329
  {
296
- 'aria-disabled': softDisabled.value ? true : undefined,
330
+ ...managedFocus.value,
297
331
  'aria-pressed': isToggle.value ? isPressed.value : undefined,
298
332
  class: [
299
333
  'bb-button',
@@ -308,8 +342,9 @@ const rootBindings = computed(() =>
308
342
  },
309
343
  ],
310
344
  disabled: props.disabled,
311
- tabindex: softDisabled.value ? -1 : undefined,
312
345
  onClick,
346
+ onFocusin: roving.onFocusin,
347
+ onKeydown: roving.onKeydown,
313
348
  },
314
349
  passthrough.root
315
350
  )
@@ -463,7 +498,10 @@ export type BbButtonProps = {
463
498
  exactActiveClass?: string;
464
499
 
465
500
  /**
466
- * Identifies the button as part of a button group.
501
+ * Identifies the button as part of a button group: adjacent `group`
502
+ * buttons fuse into one segment (shared borders and radius). Adjacent
503
+ * `group` toggles (each with a `v-model`) are also one Tab stop, with
504
+ * ArrowLeft / ArrowRight / Home / End moving between them.
467
505
  */
468
506
  group?: boolean;
469
507
 
@@ -885,15 +923,6 @@ export type BbButtonSlots = {
885
923
  border-radius: var(--r);
886
924
  border-style: solid;
887
925
  border-width: var(--bw);
888
- /* Resting lift, but only on a PLATE — primary, secondary, outline and
889
- destructive opt in below. Ghost, link and `none` stay flat whatever the
890
- theme asks for, because a lift on a transparent box reads as a bug.
891
-
892
- The plates read `--elev-tier`, not `--bb-elev` directly, so the size
893
- blocks can drop xs and sm to the small tier without handing a shadow to
894
- the flat variants. */
895
- --elev-tier: var(--bb-elev); /* the shadow a plate variant may take */
896
- --elev: 0 0 0 0 transparent; /* the shadow painted; flat variants keep this */
897
926
  box-shadow:
898
927
  var(--elev),
899
928
  0px 0px 0px 0px var(--ring-color);
@@ -905,14 +934,23 @@ export type BbButtonSlots = {
905
934
  justify-content: center;
906
935
  line-height: var(--fs);
907
936
  min-height: var(--h);
908
- padding-left: var(--px);
909
- padding-right: var(--px);
937
+ padding-inline-end: var(--px);
938
+ padding-inline-start: var(--px);
910
939
  transition-duration: var(--bb-transition-fast);
911
940
  transition-property:
912
941
  box-shadow, color, background-color, border-color, min-height, font-size,
913
942
  padding-left;
914
943
  transition-timing-function: var(--bb-ease);
915
944
  vertical-align: top;
945
+ /* Resting lift, but only on a PLATE — primary, secondary, outline and
946
+ destructive opt in below. Ghost, link and `none` stay flat whatever the
947
+ theme asks for, because a lift on a transparent box reads as a bug.
948
+
949
+ The plates read `--elev-tier`, not `--bb-elev` directly, so the size
950
+ blocks can drop xs and sm to the small tier without handing a shadow to
951
+ the flat variants. */
952
+ --elev-tier: var(--bb-elev); /* the shadow a plate variant may take */
953
+ --elev: 0 0 0 0 transparent; /* the shadow painted; flat variants keep this */
916
954
 
917
955
  &:hover:not(.bb-base-button--disabled) {
918
956
  background-color: var(--bg-hover);
@@ -1012,7 +1050,7 @@ export type BbButtonSlots = {
1012
1050
  rules above, which paint `border-color` on the button and would
1013
1051
  otherwise take the left edge with them. */
1014
1052
  & + .bb-button.bb-button--group {
1015
- border-left-color: color-mix(
1053
+ border-inline-start-color: color-mix(
1016
1054
  in oklab,
1017
1055
  var(--bb-primary) 60%,
1018
1056
  var(--bb-border)
@@ -1030,7 +1068,7 @@ export type BbButtonSlots = {
1030
1068
  --elev: var(--elev-tier);
1031
1069
 
1032
1070
  & + .bb-button.bb-button--group {
1033
- border-left-color: var(--bb-secondary-pressed);
1071
+ border-inline-start-color: var(--bb-secondary-pressed);
1034
1072
  }
1035
1073
  }
1036
1074
 
@@ -1100,19 +1138,19 @@ export type BbButtonSlots = {
1100
1138
 
1101
1139
  &.bb-button--icon {
1102
1140
  min-width: var(--h);
1103
- padding-left: 0;
1104
- padding-right: 0;
1141
+ padding-inline-end: 0;
1142
+ padding-inline-start: 0;
1105
1143
  }
1106
1144
 
1107
1145
  &:has(.bb-button__prepend-icon),
1108
1146
  &.bb-button--loading:not(.bb-button--icon):not(
1109
1147
  :has(.bb-button__append-icon)
1110
1148
  ) {
1111
- padding-left: calc(var(--px) * 0.65);
1149
+ padding-inline-start: calc(var(--px) * 0.65);
1112
1150
  }
1113
1151
 
1114
1152
  &:has(.bb-button__append-icon) {
1115
- padding-right: calc(var(--px) * 0.65);
1153
+ padding-inline-end: calc(var(--px) * 0.65);
1116
1154
  }
1117
1155
 
1118
1156
  &.bb-button--soft-disabled {
@@ -1133,7 +1171,7 @@ export type BbButtonSlots = {
1133
1171
 
1134
1172
  /* No icon to hide behind: carve the spinner's slot out of the label. */
1135
1173
  + .bb-button__text {
1136
- margin-left: calc(var(--gap) + var(--icon-size));
1174
+ margin-inline-start: calc(var(--gap) + var(--icon-size));
1137
1175
  }
1138
1176
  }
1139
1177
 
@@ -1145,21 +1183,21 @@ export type BbButtonSlots = {
1145
1183
  }
1146
1184
 
1147
1185
  .bb-spinner + .bb-button__text {
1148
- margin-left: 0;
1186
+ margin-inline-start: 0;
1149
1187
  }
1150
1188
  }
1151
1189
  }
1152
1190
 
1153
1191
  &.bb-button--group {
1154
1192
  &:has(+ .bb-button--group) {
1155
- border-bottom-right-radius: 0;
1156
- border-right-width: 0;
1157
- border-top-right-radius: 0;
1193
+ border-end-end-radius: 0;
1194
+ border-inline-end-width: 0;
1195
+ border-start-end-radius: 0;
1158
1196
  }
1159
1197
 
1160
1198
  & + .bb-button--group {
1161
- border-bottom-left-radius: 0;
1162
- border-top-left-radius: 0;
1199
+ border-end-start-radius: 0;
1200
+ border-start-start-radius: 0;
1163
1201
  }
1164
1202
  }
1165
1203
 
@@ -1229,7 +1267,7 @@ export type BbButtonSlots = {
1229
1267
  --elev-tier: var(--bb-elev);
1230
1268
  }
1231
1269
  .bb-button__text {
1232
- margin-left: 0;
1270
+ margin-inline-start: 0;
1233
1271
  transition: margin-left var(--bb-transition-medium) var(--bb-ease);
1234
1272
 
1235
1273
  /* Optical centering, as on BbBadge's label. Flex centers the LINE BOX,
@@ -1273,7 +1311,7 @@ export type BbButtonSlots = {
1273
1311
  by an equal negative margin, so it lands exactly on top of the neighbour
1274
1312
  it stands in for. The fade itself is the Vue <Transition> below. */
1275
1313
  .bb-spinner {
1276
- margin-right: calc((var(--gap) + var(--icon-size)) * -1);
1314
+ margin-inline-end: calc((var(--gap) + var(--icon-size)) * -1);
1277
1315
  }
1278
1316
 
1279
1317
  /* <Transition name="bb-button-spinner"> endpoints; the duration comes from
@@ -1288,8 +1326,8 @@ export type BbButtonSlots = {
1288
1326
  it overlays the append icon by the same zero-cost trick. */
1289
1327
  &:has(.bb-button__append-icon):not(:has(.bb-button__prepend-icon)) {
1290
1328
  .bb-spinner {
1291
- margin-left: calc((var(--gap) + var(--icon-size)) * -1);
1292
- margin-right: 0;
1329
+ margin-inline-end: 0;
1330
+ margin-inline-start: calc((var(--gap) + var(--icon-size)) * -1);
1293
1331
  order: 1;
1294
1332
  }
1295
1333
  }