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
@@ -659,9 +659,9 @@ export function useInvoicesWorkspace(): InvoicesWorkspaceContext {
659
659
  <BbBreadcrumbs
660
660
  class="min-w-0 flex-auto"
661
661
  :items="[
662
- { key: 'dashboard', text: 'Dashboard', to: '/dashboard' },
663
- { key: 'billing', text: 'Billing', to: '/billing' },
664
- { key: 'invoices', text: 'Invoices' },
662
+ { value: 'dashboard', label: 'Dashboard', to: '/dashboard' },
663
+ { value: 'billing', label: 'Billing', to: '/billing' },
664
+ { value: 'invoices', label: 'Invoices' },
665
665
  ]"
666
666
  />
667
667
  <div class="flex shrink-0 items-center gap-2">
@@ -696,22 +696,22 @@ export function useInvoicesWorkspace(): InvoicesWorkspaceContext {
696
696
  compact
697
697
  :items="[
698
698
  {
699
- key: 'all',
699
+ value: 'all',
700
700
  label: `All · ${ctx.tabCounts.value.all}`,
701
701
  href: '?tab=all',
702
702
  },
703
703
  {
704
- key: 'outstanding',
704
+ value: 'outstanding',
705
705
  label: `Outstanding · ${ctx.tabCounts.value.outstanding}`,
706
706
  href: '?tab=outstanding',
707
707
  },
708
708
  {
709
- key: 'paid',
709
+ value: 'paid',
710
710
  label: `Paid · ${ctx.tabCounts.value.paid}`,
711
711
  href: '?tab=paid',
712
712
  },
713
713
  {
714
- key: 'archived',
714
+ value: 'archived',
715
715
  label: `Archived · ${ctx.tabCounts.value.archived}`,
716
716
  href: '?tab=archived',
717
717
  },
@@ -1027,16 +1027,16 @@ const searchCustomers = async ({
1027
1027
  // Static enum facet: item text resolves synchronously, so its chip reads
1028
1028
  // `useBbDropdownContext` (in FilterChip.vue) with zero extra fetch.
1029
1029
  const statusGroup: BbDropdownItem = {
1030
- key: 'status',
1030
+ id: 'status',
1031
1031
  label: 'Status',
1032
1032
  hideLabel: true,
1033
1033
  selectable: true,
1034
1034
  multiple: true,
1035
1035
  items: [
1036
- { key: 'draft', text: INVOICE_STATUS_LABEL.draft },
1037
- { key: 'pending', text: INVOICE_STATUS_LABEL.pending },
1038
- { key: 'paid', text: INVOICE_STATUS_LABEL.paid },
1039
- { key: 'overdue', text: INVOICE_STATUS_LABEL.overdue },
1036
+ { value: 'draft', label: INVOICE_STATUS_LABEL.draft },
1037
+ { value: 'pending', label: INVOICE_STATUS_LABEL.pending },
1038
+ { value: 'paid', label: INVOICE_STATUS_LABEL.paid },
1039
+ { value: 'overdue', label: INVOICE_STATUS_LABEL.overdue },
1040
1040
  ],
1041
1041
  };
1042
1042
 
@@ -1048,7 +1048,7 @@ const statusGroup: BbDropdownItem = {
1048
1048
  // redeclaring `prefill: true` would fetch every seeded facet twice on page
1049
1049
  // load for nothing.
1050
1050
  const customerGroup: BbDropdownItem = {
1051
- key: 'customer',
1051
+ id: 'customer',
1052
1052
  label: 'Customer',
1053
1053
  hideLabel: true,
1054
1054
  selectable: true,
@@ -1065,14 +1065,14 @@ const customerGroup: BbDropdownItem = {
1065
1065
  // the category row already names the facet.
1066
1066
  const menu = computed<BbDropdownItem[]>(() => [
1067
1067
  {
1068
- key: 'status-category',
1069
- text: 'Status',
1068
+ value: 'status-category',
1069
+ label: 'Status',
1070
1070
  'prepend:icon': 'lucide:circle-dot',
1071
1071
  items: [statusGroup],
1072
1072
  },
1073
1073
  {
1074
- key: 'customer-category',
1075
- text: 'Customer',
1074
+ value: 'customer-category',
1075
+ label: 'Customer',
1076
1076
  'prepend:icon': 'lucide:building-2',
1077
1077
  items: [customerGroup],
1078
1078
  },
@@ -1122,7 +1122,7 @@ import {
1122
1122
  import type { BbDropdownItem } from 'bitboss-ui';
1123
1123
 
1124
1124
  const props = defineProps<{
1125
- /** Matches the group's `key` in the Filters menu, and its key in
1125
+ /** Matches the group's `id` in the Filters menu, and its entry in
1126
1126
  * `useBbDropdownContext('invoice-filters').groups`. */
1127
1127
  groupKey: string;
1128
1128
  /** Static fallback/prefix text — the group itself sets `hideLabel`. */
@@ -1159,7 +1159,7 @@ const chipText = computed(() => {
1159
1159
  dropdownFilters.groups.value[props.groupKey]?.selectedOptions ?? [];
1160
1160
  if (!options.length) return props.label;
1161
1161
  return `${props.label}: ${options
1162
- .map((option) => option.text ?? String(option.value))
1162
+ .map((option) => option.label ?? String(option.value))
1163
1163
  .join(', ')}`;
1164
1164
  });
1165
1165
 
@@ -1175,7 +1175,6 @@ const onClear = () =>
1175
1175
  <template>
1176
1176
  <BbSelectPopover
1177
1177
  item-text="text"
1178
- item-value="value"
1179
1178
  :items="INVOICE_STATUS_OPTIONS"
1180
1179
  :model-value="invoice.status"
1181
1180
  width="180"
@@ -1391,32 +1390,32 @@ const pillLabel = computed(() =>
1391
1390
  :boundary="boundary"
1392
1391
  :items="[
1393
1392
  {
1394
- key: 'edit',
1395
- text: 'Edit',
1393
+ value: 'edit',
1394
+ label: 'Edit',
1396
1395
  'prepend:icon': 'lucide:pencil',
1397
1396
  to: `/invoices/${invoice.id}/edit`,
1398
1397
  },
1399
1398
  {
1400
- key: 'duplicate',
1401
- text: 'Duplicate',
1399
+ value: 'duplicate',
1400
+ label: 'Duplicate',
1402
1401
  'prepend:icon': 'lucide:copy',
1403
1402
  onClick: () => ctx.duplicateInvoice(invoice),
1404
1403
  },
1405
1404
  {
1406
- key: 'payment',
1407
- text: 'Record payment',
1405
+ value: 'payment',
1406
+ label: 'Record payment',
1408
1407
  'prepend:icon': 'lucide:banknote',
1409
1408
  onClick: () => (ctx.dialogs.recordPayment.value = invoice),
1410
1409
  },
1411
1410
  {
1412
- key: 'archive',
1413
- text: 'Archive',
1411
+ value: 'archive',
1412
+ label: 'Archive',
1414
1413
  'prepend:icon': 'lucide:archive',
1415
1414
  onClick: () => ctx.archiveInvoice(invoice),
1416
1415
  },
1417
1416
  {
1418
- key: 'delete',
1419
- text: 'Delete',
1417
+ value: 'delete',
1418
+ label: 'Delete',
1420
1419
  'prepend:icon': 'lucide:trash-2',
1421
1420
  variant: 'destructive',
1422
1421
  onClick: () => ctx.deleteInvoice(invoice),
@@ -1824,7 +1823,6 @@ const currency = new Intl.NumberFormat('en-US', {
1824
1823
  <BbSelect
1825
1824
  v-model="draft.method"
1826
1825
  item-text="text"
1827
- item-value="value"
1828
1826
  :items="PAYMENT_METHOD_OPTIONS"
1829
1827
  label="Method"
1830
1828
  label-mode="outside"
@@ -79,7 +79,7 @@ per field, and never mix both inside one card.
79
79
  | ---------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
80
80
  | What it is | Typed text, several fields that belong together | One discrete choice: a switch, a checkbox, a role, a file |
81
81
  | Commit | A **Save** button in the card footer, disabled until something changed | The change itself. No button anywhere |
82
- | While saving | The button spins (`isSubmitting`); the fields stay editable | The control goes `readonly` so a second flip cannot race the first |
82
+ | While saving | The button spins and the fields go read-only until the save settles (the form's save lock) | The control goes `readonly` so a second flip cannot race the first |
83
83
  | On success | A toast; the dirty state rebaselines to what was saved | A quiet toast (`Delivery channels saved.`) |
84
84
  | On failure | Server messages land on their fields (`field-errors`); focus moves to the first one; nothing is lost | The control **snaps back** and the toast says why (`Slack needs reconnecting…`) |
85
85
  | Leaving | Unsaved work raises a dot on the section tab, and leaving asks first | Nothing can be unsaved, so nothing asks |
@@ -932,9 +932,9 @@ export function useSettingsWorkspace(): SettingsWorkspaceContext {
932
932
  <BbBreadcrumbs
933
933
  class="min-w-0"
934
934
  :items="[
935
- { key: 'workspace', text: 'Fennel & Hart', to: '/' },
936
- { key: 'settings', text: 'Settings', to: '/settings' },
937
- { key: 'section', text: currentLabel },
935
+ { value: 'workspace', label: 'Fennel & Hart', to: '/' },
936
+ { value: 'settings', label: 'Settings', to: '/settings' },
937
+ { value: 'section', label: currentLabel },
938
938
  ]"
939
939
  style="--flex-grow: 1"
940
940
  />
@@ -974,7 +974,7 @@ export function useSettingsWorkspace(): SettingsWorkspaceContext {
974
974
  replace
975
975
  variant="none"
976
976
  >
977
- <template #label="{ value, text }">
977
+ <template #label="{ value, label }">
978
978
  <!-- In the side column every label is one width, so the counts line
979
979
  up on the right edge. -->
980
980
  <span
@@ -982,7 +982,7 @@ export function useSettingsWorkspace(): SettingsWorkspaceContext {
982
982
  :class="{ 'min-w-[11.5rem]': !isMobile }"
983
983
  >
984
984
  <BbIcon aria-hidden="true" :icon="SECTION_ICONS[value]" size="16" />
985
- <span>{{ text }}</span>
985
+ <span>{{ label }}</span>
986
986
  <!-- Unsaved marker: a dot, not a word, so the label does not jump. -->
987
987
  <span
988
988
  v-if="value === 'profile' && ctx.profileDirty.value"
@@ -1046,12 +1046,12 @@ const { isMobile } = useMobile();
1046
1046
 
1047
1047
  // `eager` on Profile: a half-edited draft must survive a look at Billing.
1048
1048
  const sections: Array<BbTabsItem<SettingsSection>> = [
1049
- { key: 'profile', label: 'Profile', eager: true },
1050
- { key: 'notifications', label: 'Notifications' },
1051
- { key: 'members', label: 'Members' },
1052
- { key: 'billing', label: 'Billing' },
1053
- { key: 'api-keys', label: 'API keys' },
1054
- { key: 'danger-zone', label: 'Danger zone' },
1049
+ { value: 'profile', label: 'Profile', eager: true },
1050
+ { value: 'notifications', label: 'Notifications' },
1051
+ { value: 'members', label: 'Members' },
1052
+ { value: 'billing', label: 'Billing' },
1053
+ { value: 'api-keys', label: 'API keys' },
1054
+ { value: 'danger-zone', label: 'Danger zone' },
1055
1055
  ];
1056
1056
 
1057
1057
  // Full literals: the production icon scanner only bundles names it can see.
@@ -1237,7 +1237,6 @@ The explicit-save section: Zod schema, 422s, dirty footer.
1237
1237
  not "differs from the values this form mounted with". -->
1238
1238
  <BbForm
1239
1239
  :id="PROFILE_FORM"
1240
- v-slot="{ isSubmitting }"
1241
1240
  :field-errors="ctx.serverErrors.profile.value"
1242
1241
  :model="ctx.profileDraft"
1243
1242
  :schema="profileSchema"
@@ -1267,8 +1266,6 @@ The explicit-save section: Zod schema, 422s, dirty footer.
1267
1266
  />
1268
1267
  <BbSelect
1269
1268
  description="Due dates and reminders follow this zone."
1270
- item-text="label"
1271
- item-value="value"
1272
1269
  :items="TIMEZONES"
1273
1270
  label="Time zone"
1274
1271
  name="timezone"
@@ -1302,7 +1299,6 @@ The explicit-save section: Zod schema, 422s, dirty footer.
1302
1299
  it says why, so the state is never a mystery. -->
1303
1300
  <BbButton
1304
1301
  :disabled="!ctx.profileDirty.value"
1305
- :loading="isSubmitting"
1306
1302
  type="submit"
1307
1303
  variant="primary"
1308
1304
  >
@@ -1946,8 +1942,6 @@ One-click role picker (BbSelectPopover).
1946
1942
  <BbSelectPopover
1947
1943
  v-else
1948
1944
  :item-props="{ description: 'description' }"
1949
- item-text="label"
1950
- item-value="value"
1951
1945
  :items="ROLE_OPTIONS"
1952
1946
  :model-value="member.role"
1953
1947
  width="280"
@@ -2032,21 +2026,21 @@ const items = computed<BbDropdownItem[]>(() => {
2032
2026
  if (m.status === 'invited')
2033
2027
  return [
2034
2028
  {
2035
- key: 'resend',
2036
- text: 'Resend invitation',
2029
+ value: 'resend',
2030
+ label: 'Resend invitation',
2037
2031
  'prepend:icon': 'lucide:send',
2038
2032
  onClick: () => ctx.resendInvite(m),
2039
2033
  },
2040
2034
  {
2041
- key: 'copy',
2042
- text: 'Copy email',
2035
+ value: 'copy',
2036
+ label: 'Copy email',
2043
2037
  'prepend:icon': 'lucide:copy',
2044
2038
  onClick: () => ctx.copy(m.email, 'Email address'),
2045
2039
  },
2046
2040
  [
2047
2041
  {
2048
- key: 'revoke',
2049
- text: 'Revoke invitation',
2042
+ value: 'revoke',
2043
+ label: 'Revoke invitation',
2050
2044
  'prepend:icon': 'lucide:user-x',
2051
2045
  variant: 'destructive',
2052
2046
  onClick: () => ctx.removeMember(m),
@@ -2055,15 +2049,15 @@ const items = computed<BbDropdownItem[]>(() => {
2055
2049
  ];
2056
2050
  return [
2057
2051
  {
2058
- key: 'copy',
2059
- text: 'Copy email',
2052
+ value: 'copy',
2053
+ label: 'Copy email',
2060
2054
  'prepend:icon': 'lucide:copy',
2061
2055
  onClick: () => ctx.copy(m.email, 'Email address'),
2062
2056
  },
2063
2057
  [
2064
2058
  {
2065
- key: 'remove',
2066
- text: 'Remove from workspace',
2059
+ value: 'remove',
2060
+ label: 'Remove from workspace',
2067
2061
  'prepend:icon': 'lucide:user-minus',
2068
2062
  variant: 'destructive',
2069
2063
  onClick: () => ctx.removeMember(m),
@@ -2109,8 +2103,6 @@ Invite by email: BbTag + role radios, footer submits from outside.
2109
2103
  />
2110
2104
  <BbRadioGroup
2111
2105
  :item-props="{ description: 'description' }"
2112
- item-text="label"
2113
- item-value="value"
2114
2106
  :items="ROLE_OPTIONS"
2115
2107
  legend="Role"
2116
2108
  list-layout="vertical"
@@ -2575,8 +2567,6 @@ Create, then reveal once (persistent while shown).
2575
2567
  <BbTextInput label="Name" name="name" placeholder="Production server" />
2576
2568
  <BbRadioGroup
2577
2569
  :item-props="{ description: 'description' }"
2578
- item-text="label"
2579
- item-value="value"
2580
2570
  :items="SCOPES"
2581
2571
  legend="Access"
2582
2572
  list-layout="vertical"
@@ -2584,8 +2574,6 @@ Create, then reveal once (persistent while shown).
2584
2574
  />
2585
2575
  <BbSelect
2586
2576
  description="Short-lived keys limit the damage of a leak."
2587
- item-text="label"
2588
- item-value="value"
2589
2577
  :items="EXPIRIES"
2590
2578
  label="Expires"
2591
2579
  name="expiresIn"
@@ -698,9 +698,9 @@ export function useUploadCenter(): UploadCenterContext {
698
698
  <BbBreadcrumbs
699
699
  class="min-w-0 flex-auto"
700
700
  :items="[
701
- { key: 'dashboard', text: 'Dashboard', to: '/dashboard' },
702
- { key: 'expenses', text: 'Expenses', to: '/expenses' },
703
- { key: 'receipts', text: 'Receipts' },
701
+ { value: 'dashboard', label: 'Dashboard', to: '/dashboard' },
702
+ { value: 'expenses', label: 'Expenses', to: '/expenses' },
703
+ { value: 'receipts', label: 'Receipts' },
704
704
  ]"
705
705
  />
706
706
  <div class="flex shrink-0 items-center gap-2">
@@ -742,17 +742,17 @@ export function useUploadCenter(): UploadCenterContext {
742
742
  compact
743
743
  :items="[
744
744
  {
745
- key: 'drafts',
745
+ value: 'drafts',
746
746
  label: `Drafts · ${ctx.tabCounts.value.drafts}`,
747
747
  href: '?tab=drafts',
748
748
  },
749
749
  {
750
- key: 'submitted',
750
+ value: 'submitted',
751
751
  label: `Submitted · ${ctx.tabCounts.value.submitted}`,
752
752
  href: '?tab=submitted',
753
753
  },
754
754
  {
755
- key: 'reimbursed',
755
+ value: 'reimbursed',
756
756
  label: `Reimbursed · ${ctx.tabCounts.value.reimbursed}`,
757
757
  href: '?tab=reimbursed',
758
758
  },
@@ -1376,6 +1376,7 @@ const categoryName = computed(
1376
1376
  label="Amount"
1377
1377
  :max-precision="2"
1378
1378
  :min="0"
1379
+ :min-precision="2"
1379
1380
  placeholder="0.00"
1380
1381
  variant="ghost"
1381
1382
  @change="commit"
@@ -1395,32 +1396,24 @@ const props = defineProps<{ receipt: Receipt }>();
1395
1396
 
1396
1397
  const ctx = useUploadCenter();
1397
1398
 
1398
- /** Money cells always show two decimals so the column optically aligns. */
1399
- const formatMoney = (value: number | null): string | null =>
1400
- value === null || Number.isNaN(value) ? null : value.toFixed(2);
1401
-
1402
- // Same commit/revert contract as the merchant cell, on the number model —
1403
- // commit on @change, not @blur + @keydown.enter (see MerchantCell.vue).
1404
- const draft = ref<number | string | null>(formatMoney(props.receipt.amount));
1399
+ // Money cells always show two decimals (`min-precision`), so the column
1400
+ // optically aligns. Same commit/revert contract as the merchant cell, on the
1401
+ // number model — commit on @change, not @blur + @keydown.enter (see
1402
+ // MerchantCell.vue).
1403
+ const draft = ref<number | null>(props.receipt.amount);
1405
1404
  watch(
1406
1405
  () => props.receipt.amount,
1407
1406
  (value) => {
1408
- draft.value = formatMoney(value);
1407
+ draft.value = value;
1409
1408
  }
1410
1409
  );
1411
1410
 
1412
1411
  const commit = () => {
1413
- const amount =
1414
- draft.value === null || draft.value === '' ? null : Number(draft.value);
1415
- if (amount === props.receipt.amount) {
1416
- draft.value = formatMoney(props.receipt.amount);
1417
- return;
1418
- }
1419
- void ctx.updateReceipt(props.receipt, { amount });
1420
- draft.value = formatMoney(amount);
1412
+ if (draft.value === props.receipt.amount) return;
1413
+ void ctx.updateReceipt(props.receipt, { amount: draft.value });
1421
1414
  };
1422
1415
  const revert = () => {
1423
- draft.value = formatMoney(props.receipt.amount);
1416
+ draft.value = props.receipt.amount;
1424
1417
  };
1425
1418
  </script>
1426
1419
  ```
@@ -1503,8 +1496,8 @@ const items = computed(() => {
1503
1496
  ...(isDraft
1504
1497
  ? [
1505
1498
  {
1506
- key: 'submit',
1507
- text: 'Submit for approval',
1499
+ value: 'submit',
1500
+ label: 'Submit for approval',
1508
1501
  'prepend:icon': 'lucide:send',
1509
1502
  onClick: () => ctx.submitReceipt(receipt),
1510
1503
  },
@@ -1514,16 +1507,16 @@ const items = computed(() => {
1514
1507
  // A real file download, not a Nuxt page — a raw `href` triggers a
1515
1508
  // normal browser navigation instead of being intercepted by the
1516
1509
  // router, which is what a client-side `to` would otherwise do.
1517
- key: 'download',
1518
- text: 'Download original',
1510
+ value: 'download',
1511
+ label: 'Download original',
1519
1512
  'prepend:icon': 'lucide:download',
1520
1513
  href: `/receipts/${receipt.id}/file`,
1521
1514
  },
1522
1515
  ...(isDraft
1523
1516
  ? [
1524
1517
  {
1525
- key: 'remove',
1526
- text: 'Remove',
1518
+ value: 'remove',
1519
+ label: 'Remove',
1527
1520
  'prepend:icon': 'lucide:trash-2',
1528
1521
  variant: 'destructive' as const,
1529
1522
  onClick: () => ctx.deleteReceipt(receipt),
@@ -804,9 +804,9 @@ onMounted(() => {
804
804
  });
805
805
 
806
806
  const crumbs = computed(() => [
807
- { key: 'dashboard', text: 'Dashboard', to: '/dashboard' },
808
- { key: 'campaigns', text: 'Campaigns', to: '/campaigns' },
809
- { key: 'setup', text: ctx.campaign.value?.name ?? 'New campaign' },
807
+ { value: 'dashboard', label: 'Dashboard', to: '/dashboard' },
808
+ { value: 'campaigns', label: 'Campaigns', to: '/campaigns' },
809
+ { value: 'setup', label: ctx.campaign.value?.name ?? 'New campaign' },
810
810
  ]);
811
811
 
812
812
  // The summary shows only the CURRENT step's issues, and only once the user
@@ -950,8 +950,6 @@ const status = (key: StepKey) => ctx.stepStatus(key);
950
950
 
951
951
  <BbSelect
952
952
  v-model="ctx.draft.countries"
953
- item-text="label"
954
- item-value="value"
955
953
  :items="COUNTRIES"
956
954
  label="Limit to countries"
957
955
  label-mode="outside"
@@ -1115,8 +1113,6 @@ const errorsFor = (field: string) => ctx.fieldErrors('content', field);
1115
1113
 
1116
1114
  <BbRadioGroup
1117
1115
  v-model="ctx.draft.sendMode"
1118
- item-text="label"
1119
- item-value="value"
1120
1116
  :items="[
1121
1117
  {
1122
1118
  label: 'Send now — goes out as soon as you confirm on Review',
@@ -1146,8 +1142,6 @@ const errorsFor = (field: string) => ctx.fieldErrors('content', field);
1146
1142
  <BbSelect
1147
1143
  v-model="ctx.draft.timezone"
1148
1144
  :errors="errorsFor('timezone')"
1149
- item-text="label"
1150
- item-value="value"
1151
1145
  :items="TIMEZONES"
1152
1146
  label="Timezone"
1153
1147
  label-mode="outside"
@@ -1645,8 +1639,6 @@ the file is unchanged, plus `BbCalendar` in its import):
1645
1639
  <BbSelect
1646
1640
  v-model="ctx.draft.timezone"
1647
1641
  :errors="errorsFor('timezone')"
1648
- item-text="label"
1649
- item-value="value"
1650
1642
  :items="TIMEZONES"
1651
1643
  label="Timezone"
1652
1644
  label-mode="outside"
@@ -552,9 +552,9 @@ export function useApprovalsInbox(): ApprovalsInboxContext {
552
552
  <BbBreadcrumbs
553
553
  class="min-w-0 flex-auto"
554
554
  :items="[
555
- { key: 'dashboard', text: 'Dashboard', to: '/dashboard' },
556
- { key: 'finance', text: 'Finance', to: '/finance' },
557
- { key: 'approvals', text: 'Approvals' },
555
+ { value: 'dashboard', label: 'Dashboard', to: '/dashboard' },
556
+ { value: 'finance', label: 'Finance', to: '/finance' },
557
+ { value: 'approvals', label: 'Approvals' },
558
558
  ]"
559
559
  />
560
560
  <BbTextInput
@@ -581,22 +581,22 @@ export function useApprovalsInbox(): ApprovalsInboxContext {
581
581
  compact
582
582
  :items="[
583
583
  {
584
- key: 'needsApproval',
584
+ value: 'needsApproval',
585
585
  label: `Needs approval · ${ctx.tabCounts.value.needsApproval}`,
586
586
  href: '?tab=needsApproval',
587
587
  },
588
588
  {
589
- key: 'approved',
589
+ value: 'approved',
590
590
  label: `Approved · ${ctx.tabCounts.value.approved}`,
591
591
  href: '?tab=approved',
592
592
  },
593
593
  {
594
- key: 'rejected',
594
+ value: 'rejected',
595
595
  label: `Rejected · ${ctx.tabCounts.value.rejected}`,
596
596
  href: '?tab=rejected',
597
597
  },
598
598
  {
599
- key: 'all',
599
+ value: 'all',
600
600
  label: `All · ${ctx.tabCounts.value.all}`,
601
601
  href: '?tab=all',
602
602
  },
@@ -791,7 +791,6 @@ const rowClass = (item: Expense) =>
791
791
  <BbSelectPopover
792
792
  v-model="ctx.filters.categories"
793
793
  item-text="text"
794
- item-value="value"
795
794
  :items="CATEGORY_OPTIONS"
796
795
  multiple
797
796
  >
@@ -731,9 +731,9 @@ export function useBacklogWorkspace(): BacklogWorkspaceContext {
731
731
  <BbBreadcrumbs
732
732
  class="min-w-0 flex-auto"
733
733
  :items="[
734
- { key: 'product', text: 'Product', to: '/product' },
735
- { key: 'sprints', text: 'Sprints', to: '/sprints' },
736
- { key: 'sprint-24', text: 'Sprint 24' },
734
+ { value: 'product', label: 'Product', to: '/product' },
735
+ { value: 'sprints', label: 'Sprints', to: '/sprints' },
736
+ { value: 'sprint-24', label: 'Sprint 24' },
737
737
  ]"
738
738
  />
739
739
  <div class="flex shrink-0 items-center gap-2">
@@ -770,17 +770,17 @@ export function useBacklogWorkspace(): BacklogWorkspaceContext {
770
770
  compact
771
771
  :items="[
772
772
  {
773
- key: 'backlog',
773
+ value: 'backlog',
774
774
  label: `Backlog · ${ctx.tabCounts.value.backlog}`,
775
775
  href: '?tab=backlog',
776
776
  },
777
777
  {
778
- key: 'current',
778
+ value: 'current',
779
779
  label: `Current sprint · ${ctx.tabCounts.value.current}`,
780
780
  href: '?tab=current',
781
781
  },
782
782
  {
783
- key: 'done',
783
+ value: 'done',
784
784
  label: `Done · ${ctx.tabCounts.value.done}`,
785
785
  href: '?tab=done',
786
786
  },
@@ -985,8 +985,6 @@ const rowClass = (item: Issue) =>
985
985
  <BbSelectPopover
986
986
  v-model="ctx.filters.status"
987
987
  disable-writing
988
- item-text="label"
989
- item-value="value"
990
988
  :items="STATUS_OPTIONS"
991
989
  multiple
992
990
  >
@@ -1019,8 +1017,6 @@ const rowClass = (item: Issue) =>
1019
1017
  <BbSelectPopover
1020
1018
  v-model="ctx.filters.priority"
1021
1019
  disable-writing
1022
- item-text="label"
1023
- item-value="value"
1024
1020
  :items="PRIORITY_OPTIONS"
1025
1021
  multiple
1026
1022
  >
@@ -1186,8 +1182,6 @@ const commit = (event: Event) => {
1186
1182
  <BbSelectPopover
1187
1183
  compact
1188
1184
  disable-writing
1189
- item-text="label"
1190
- item-value="value"
1191
1185
  :items="STATUS_OPTIONS"
1192
1186
  :model-value="status"
1193
1187
  width="180px"
@@ -1264,8 +1258,6 @@ const label = computed(
1264
1258
  <BbSelectPopover
1265
1259
  compact
1266
1260
  disable-writing
1267
- item-text="label"
1268
- item-value="value"
1269
1261
  :items="PRIORITY_OPTIONS"
1270
1262
  :model-value="priority"
1271
1263
  width="160px"
@@ -1330,8 +1322,8 @@ const label = computed(
1330
1322
  <template>
1331
1323
  <!-- Provider-backed people picker. The provider is the ONE shared
1332
1324
  `searchMembers` — lazy per instance, so a row nobody opens never fetches.
1333
- The whole member is the value (no item-value), matching how the row
1334
- stores it. -->
1325
+ The whole member is the value (no item-value, and a Member has no `value`
1326
+ of its own), matching how the row stores it. -->
1335
1327
  <BbSelectPopover
1336
1328
  compact
1337
1329
  item-text="name"
@@ -1397,20 +1389,20 @@ const assignee = computed(() => ctx.valueOf(props.issue, 'assignee'));
1397
1389
  :boundary="boundary"
1398
1390
  :items="[
1399
1391
  {
1400
- key: 'duplicate',
1401
- text: 'Duplicate',
1392
+ value: 'duplicate',
1393
+ label: 'Duplicate',
1402
1394
  'prepend:icon': 'lucide:copy',
1403
1395
  onClick: () => ctx.duplicateIssue(issue),
1404
1396
  },
1405
1397
  {
1406
- key: 'next-sprint',
1407
- text: 'Move to next sprint',
1398
+ value: 'next-sprint',
1399
+ label: 'Move to next sprint',
1408
1400
  'prepend:icon': 'lucide:arrow-right',
1409
1401
  onClick: () => ctx.moveToNextSprint(issue),
1410
1402
  },
1411
1403
  {
1412
- key: 'delete',
1413
- text: 'Delete',
1404
+ value: 'delete',
1405
+ label: 'Delete',
1414
1406
  'prepend:icon': 'lucide:trash-2',
1415
1407
  variant: 'destructive',
1416
1408
  onClick: () => ctx.deleteIssue(issue),
@@ -1455,8 +1447,6 @@ const ctx = useBacklogWorkspace();
1455
1447
  menu clears the bar. -->
1456
1448
  <BbSelectPopover
1457
1449
  disable-writing
1458
- item-text="label"
1459
- item-value="value"
1460
1450
  :items="STATUS_OPTIONS"
1461
1451
  :model-value="null"
1462
1452
  :offset="8"