bitboss-ui 3.0.0-beta.43 → 3.0.0-beta.44

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 (407) hide show
  1. package/README.md +10 -7
  2. package/bin/bitboss-ui-mcp.mjs +119 -15
  3. package/bin/bitboss-ui.mjs +163 -32
  4. package/dist/ai/BbAlert.md +8 -2
  5. package/dist/ai/BbAvatar.md +8 -3
  6. package/dist/ai/BbBadge.md +4 -1
  7. package/dist/ai/BbBreadcrumbs.md +1 -1
  8. package/dist/ai/BbButton.md +10 -6
  9. package/dist/ai/BbCalendar.md +9 -9
  10. package/dist/ai/BbCheckbox.md +8 -1
  11. package/dist/ai/BbCheckboxGroup.md +25 -14
  12. package/dist/ai/BbColorInput.md +4 -1
  13. package/dist/ai/BbDatePicker.md +8 -8
  14. package/dist/ai/BbDatePickerInput.md +24 -18
  15. package/dist/ai/BbDialog.md +6 -4
  16. package/dist/ai/BbDropdown.md +62 -38
  17. package/dist/ai/BbDropdownButton.md +4 -4
  18. package/dist/ai/BbDropdownGroup.md +3 -3
  19. package/dist/ai/BbDropzone.md +232 -28
  20. package/dist/ai/BbForm.md +16 -3
  21. package/dist/ai/BbIcon.md +25 -9
  22. package/dist/ai/BbNumberInput.md +4 -1
  23. package/dist/ai/BbOffCanvas.md +6 -4
  24. package/dist/ai/BbPagination.md +2 -2
  25. package/dist/ai/BbPopover.md +1 -1
  26. package/dist/ai/BbRadio.md +8 -1
  27. package/dist/ai/BbRadioGroup.md +25 -19
  28. package/dist/ai/BbRating.md +6 -3
  29. package/dist/ai/BbSelect.md +421 -154
  30. package/dist/ai/BbSelectPopover.md +239 -57
  31. package/dist/ai/BbSlider.md +4 -1
  32. package/dist/ai/BbSpinner.md +1 -1
  33. package/dist/ai/BbSwitch.md +21 -1
  34. package/dist/ai/BbSwitchGroup.md +31 -20
  35. package/dist/ai/BbTable.md +259 -129
  36. package/dist/ai/BbTabs.md +8 -8
  37. package/dist/ai/BbTabsList.md +2 -2
  38. package/dist/ai/BbTag.md +6 -2
  39. package/dist/ai/BbTextInput.md +41 -4
  40. package/dist/ai/BbTextarea.md +96 -42
  41. package/dist/ai/BbTimePicker.md +3 -2
  42. package/dist/ai/BbTimePickerInput.md +8 -3
  43. package/dist/ai/BbToast.md +2 -1
  44. package/dist/ai/BbTooltip.md +1 -1
  45. package/dist/ai/BbTree.md +1 -1
  46. package/dist/ai/CommonField.md +5 -2
  47. package/dist/ai/CommonPopover.md +1 -1
  48. package/dist/ai/CommonTimeSelector.md +1 -1
  49. package/dist/ai/FlatListBox.md +2 -1
  50. package/dist/ai/GroupedListBox.md +2 -1
  51. package/dist/ai/ListBox.md +3 -2
  52. package/dist/ai/OptionsContainer.md +5 -1
  53. package/dist/ai/changelog.json +284 -8
  54. package/dist/ai/components.json +64 -55
  55. package/dist/ai/design-tokens.json +4 -4
  56. package/dist/ai/guides/agent-contract.md +26 -24
  57. package/dist/ai/guides/ai-router.md +23 -21
  58. package/dist/ai/guides/coherence-playbook.md +24 -20
  59. package/dist/ai/guides/component-picker.md +4 -4
  60. package/dist/ai/guides/design-language.md +2 -1
  61. package/dist/ai/guides/design-tokens.md +15 -7
  62. package/dist/ai/guides/fetch-items-playbook.md +127 -87
  63. package/dist/ai/guides/icons-policy.md +2 -2
  64. package/dist/ai/guides/inertia-helpers.md +88 -25
  65. package/dist/ai/guides/installation-and-plugin-setup.md +16 -3
  66. package/dist/ai/guides/migration/components/bb-checkbox-group.md +1 -1
  67. package/dist/ai/guides/migration/components/bb-date-picker-input.md +10 -10
  68. package/dist/ai/guides/migration/components/bb-select-popover.md +5 -0
  69. package/dist/ai/guides/migration/components/bb-select.md +8 -2
  70. package/dist/ai/guides/migration/components/bb-table.md +31 -19
  71. package/dist/ai/guides/migration/components/bb-tabs.md +17 -17
  72. package/dist/ai/guides/migration/v2-to-v3.md +207 -69
  73. package/dist/ai/guides/migration/v3-beta-tooling.md +5 -1
  74. package/dist/ai/guides/page-shell.md +12 -6
  75. package/dist/ai/guides/passthrough.md +6 -5
  76. package/dist/ai/guides/preset-components.md +10 -2
  77. package/dist/ai/index.md +7 -8
  78. package/dist/ai/manifest/components/BbAlert.json +1 -1
  79. package/dist/ai/manifest/components/BbAvatar.json +1 -1
  80. package/dist/ai/manifest/components/BbBreadcrumbs.tree.json +1 -1
  81. package/dist/ai/manifest/components/BbCalendar.json +5 -3
  82. package/dist/ai/manifest/components/BbCheckbox.json +2 -0
  83. package/dist/ai/manifest/components/BbCheckbox.tree.json +1 -1
  84. package/dist/ai/manifest/components/BbCheckboxGroup.json +9 -3
  85. package/dist/ai/manifest/components/BbCheckboxGroup.tree.json +10 -1
  86. package/dist/ai/manifest/components/BbColorInput.json +3 -1
  87. package/dist/ai/manifest/components/BbColorInput.tree.json +1 -1
  88. package/dist/ai/manifest/components/BbColorPalette.json +2 -2
  89. package/dist/ai/manifest/components/BbDatePicker.json +8 -6
  90. package/dist/ai/manifest/components/BbDatePickerInput.json +8 -4
  91. package/dist/ai/manifest/components/BbDatePickerInput.tree.json +1 -1
  92. package/dist/ai/manifest/components/BbDialog.json +3 -3
  93. package/dist/ai/manifest/components/BbDropdown.json +9 -8
  94. package/dist/ai/manifest/components/BbDropdown.tree.json +3 -1
  95. package/dist/ai/manifest/components/BbDropdownButton.json +6 -6
  96. package/dist/ai/manifest/components/BbDropdownButton.tree.json +1 -1
  97. package/dist/ai/manifest/components/BbDropdownGroup.json +3 -3
  98. package/dist/ai/manifest/components/BbDropzone.json +3 -1
  99. package/dist/ai/manifest/components/BbDropzone.tree.json +1 -0
  100. package/dist/ai/manifest/components/BbForm.json +1 -1
  101. package/dist/ai/manifest/components/BbIcon.json +1 -1
  102. package/dist/ai/manifest/components/BbNumberInput.json +2 -0
  103. package/dist/ai/manifest/components/BbNumberInput.tree.json +1 -1
  104. package/dist/ai/manifest/components/BbOffCanvas.json +2 -2
  105. package/dist/ai/manifest/components/BbPopover.json +3 -3
  106. package/dist/ai/manifest/components/BbRadio.json +2 -0
  107. package/dist/ai/manifest/components/BbRadio.tree.json +1 -1
  108. package/dist/ai/manifest/components/BbRadioGroup.json +9 -3
  109. package/dist/ai/manifest/components/BbRadioGroup.tree.json +10 -1
  110. package/dist/ai/manifest/components/BbRating.json +4 -2
  111. package/dist/ai/manifest/components/BbRating.tree.json +1 -1
  112. package/dist/ai/manifest/components/BbSelect.json +9 -5
  113. package/dist/ai/manifest/components/BbSelect.tree.json +2 -2
  114. package/dist/ai/manifest/components/BbSelectPopover.json +9 -7
  115. package/dist/ai/manifest/components/BbSelectPopover.tree.json +5 -1
  116. package/dist/ai/manifest/components/BbSlider.json +2 -0
  117. package/dist/ai/manifest/components/BbSlider.tree.json +1 -1
  118. package/dist/ai/manifest/components/BbSpinner.json +1 -1
  119. package/dist/ai/manifest/components/BbSwitch.json +2 -0
  120. package/dist/ai/manifest/components/BbSwitch.tree.json +1 -1
  121. package/dist/ai/manifest/components/BbSwitchGroup.json +9 -3
  122. package/dist/ai/manifest/components/BbSwitchGroup.tree.json +10 -1
  123. package/dist/ai/manifest/components/BbTable.json +28 -15
  124. package/dist/ai/manifest/components/BbTable.tree.json +5 -0
  125. package/dist/ai/manifest/components/BbTabs.json +4 -3
  126. package/dist/ai/manifest/components/BbTabsList.json +4 -3
  127. package/dist/ai/manifest/components/BbTag.json +2 -0
  128. package/dist/ai/manifest/components/BbTag.tree.json +1 -1
  129. package/dist/ai/manifest/components/BbTextInput.json +8 -2
  130. package/dist/ai/manifest/components/BbTextInput.tree.json +1 -1
  131. package/dist/ai/manifest/components/BbTextarea.json +8 -2
  132. package/dist/ai/manifest/components/BbTextarea.tree.json +1 -1
  133. package/dist/ai/manifest/components/BbTimePicker.json +3 -3
  134. package/dist/ai/manifest/components/BbTimePickerInput.json +3 -1
  135. package/dist/ai/manifest/components/BbTimePickerInput.tree.json +1 -1
  136. package/dist/ai/manifest/components/BbTooltip.json +2 -2
  137. package/dist/ai/manifest/components/BbTree.json +1 -1
  138. package/dist/ai/manifest/components/CommonField.json +4 -1
  139. package/dist/ai/manifest/components/CommonField.tree.json +18 -0
  140. package/dist/ai/manifest/components/CommonPopover.json +2 -2
  141. package/dist/ai/manifest/components/CommonTimeSelector.json +1 -1
  142. package/dist/ai/manifest/components/FlatListBox.json +1 -0
  143. package/dist/ai/manifest/components/FlatListBox.tree.json +2 -1
  144. package/dist/ai/manifest/components/GroupedListBox.json +1 -0
  145. package/dist/ai/manifest/components/GroupedListBox.tree.json +2 -1
  146. package/dist/ai/manifest/components/ListBox.json +1 -0
  147. package/dist/ai/manifest/components/ListBox.tree.json +2 -2
  148. package/dist/ai/manifest/components/OptionsContainer.json +5 -1
  149. package/dist/ai/manifest/index.json +2 -2
  150. package/dist/ai/manifest/meta.json +9 -0
  151. package/dist/ai/manifest/types.advanced.json +10 -4
  152. package/dist/ai/manifest/types.api.json +7 -4
  153. package/dist/ai/recipes/inertia/approvals-inbox.md +160 -109
  154. package/dist/ai/recipes/inertia/inline-edit-workspace.md +151 -82
  155. package/dist/ai/recipes/inertia/layout-scaffold.md +71 -40
  156. package/dist/ai/recipes/inertia/onboarding.md +80 -71
  157. package/dist/ai/recipes/inertia/ownership-atlas.md +251 -271
  158. package/dist/ai/recipes/inertia/record-form.md +356 -201
  159. package/dist/ai/recipes/inertia/records-workspace.md +466 -234
  160. package/dist/ai/recipes/inertia/settings-workspace.md +317 -1046
  161. package/dist/ai/recipes/inertia/upload-center.md +115 -106
  162. package/dist/ai/recipes/inertia/wizard-form.md +144 -86
  163. package/dist/ai/recipes/nuxt/approvals-inbox.md +237 -140
  164. package/dist/ai/recipes/nuxt/inline-edit-workspace.md +218 -92
  165. package/dist/ai/recipes/nuxt/layout-scaffold.md +72 -41
  166. package/dist/ai/recipes/nuxt/onboarding.md +148 -105
  167. package/dist/ai/recipes/nuxt/ownership-atlas.md +1408 -0
  168. package/dist/ai/recipes/nuxt/record-form.md +446 -207
  169. package/dist/ai/recipes/nuxt/records-workspace.md +532 -234
  170. package/dist/ai/recipes/nuxt/settings-workspace.md +336 -1065
  171. package/dist/ai/recipes/nuxt/upload-center.md +254 -166
  172. package/dist/ai/recipes/nuxt/wizard-form.md +168 -95
  173. package/dist/ai/recipes/vue/approvals-inbox.md +211 -126
  174. package/dist/ai/recipes/vue/inline-edit-workspace.md +197 -82
  175. package/dist/ai/recipes/vue/layout-scaffold.md +71 -40
  176. package/dist/ai/recipes/vue/onboarding.md +80 -71
  177. package/dist/ai/recipes/vue/ownership-atlas.md +1362 -0
  178. package/dist/ai/recipes/vue/record-form.md +175 -81
  179. package/dist/ai/recipes/vue/records-workspace.md +486 -215
  180. package/dist/ai/recipes/vue/settings-workspace.md +316 -1042
  181. package/dist/ai/recipes/vue/upload-center.md +200 -151
  182. package/dist/ai/recipes/vue/wizard-form.md +108 -78
  183. package/dist/ai/source/BbButton.md +13 -1
  184. package/dist/ai/source/BbCalendar.md +43 -18
  185. package/dist/ai/source/BbCheckbox.md +21 -2
  186. package/dist/ai/source/BbCheckboxGroup.md +153 -15
  187. package/dist/ai/source/BbCollapsible.md +1 -1
  188. package/dist/ai/source/BbColorInput.md +17 -1
  189. package/dist/ai/source/BbDatePicker.md +11 -9
  190. package/dist/ai/source/BbDatePickerInput.md +101 -48
  191. package/dist/ai/source/BbDialog.md +21 -4
  192. package/dist/ai/source/BbDropdown.md +230 -51
  193. package/dist/ai/source/BbDropdownGroup.md +268 -73
  194. package/dist/ai/source/BbDropzone.md +80 -9
  195. package/dist/ai/source/BbForm.md +2 -2
  196. package/dist/ai/source/BbIcon.md +5 -0
  197. package/dist/ai/source/BbNumberInput.md +23 -3
  198. package/dist/ai/source/BbOffCanvas.md +24 -6
  199. package/dist/ai/source/BbPagination.md +7 -1
  200. package/dist/ai/source/BbPopover.md +1 -1
  201. package/dist/ai/source/BbRadio.md +21 -2
  202. package/dist/ai/source/BbRadioGroup.md +133 -15
  203. package/dist/ai/source/BbRating.md +23 -4
  204. package/dist/ai/source/BbSelect.md +72 -9
  205. package/dist/ai/source/BbSelectPopover.md +327 -100
  206. package/dist/ai/source/BbSlider.md +21 -2
  207. package/dist/ai/source/BbSwitch.md +6 -1
  208. package/dist/ai/source/BbSwitchGroup.md +73 -12
  209. package/dist/ai/source/BbTable.md +431 -166
  210. package/dist/ai/source/BbTabs.md +5 -5
  211. package/dist/ai/source/BbTabsList.md +3 -3
  212. package/dist/ai/source/BbTabsPanels.md +3 -3
  213. package/dist/ai/source/BbTabsRoot.md +3 -3
  214. package/dist/ai/source/BbTag.md +26 -3
  215. package/dist/ai/source/BbTextInput.md +56 -7
  216. package/dist/ai/source/BbTextarea.md +56 -7
  217. package/dist/ai/source/BbTimePickerInput.md +55 -12
  218. package/dist/ai/source/BbTooltip.md +1 -1
  219. package/dist/ai/source/BbTree.md +2 -2
  220. package/dist/ai/source/CommonField.md +191 -17
  221. package/dist/ai/source/CommonFieldInput.md +6 -0
  222. package/dist/ai/source/CommonPopover.md +1 -1
  223. package/dist/ai/source/CommonTimeSelector.md +12 -5
  224. package/dist/ai/source/FlatListBox.md +27 -2
  225. package/dist/ai/source/GroupedListBox.md +27 -2
  226. package/dist/ai/source/ListBox.md +7 -0
  227. package/dist/ai/source/OptionsContainer.md +62 -5
  228. package/dist/components/BbAlert/BbAlert.vue.d.ts +1 -3
  229. package/dist/components/BbAvatar/BbAvatar.vue.d.ts +1 -3
  230. package/dist/components/BbCalendar/BbCalendar.vue_vue_type_script_setup_true_lang.js +143 -140
  231. package/dist/components/BbCalendar/types.d.ts +5 -5
  232. package/dist/components/BbCalendar/useCalendarGrid.js +143 -137
  233. package/dist/components/BbCalendar/useDayGrid.js +164 -122
  234. package/dist/components/BbCalendar/useDayjsLocale.d.ts +31 -0
  235. package/dist/components/BbCalendar/useDayjsLocale.js +34 -0
  236. package/dist/components/BbCheckbox/BbCheckbox.vue_vue_type_script_setup_true_lang.js +6 -0
  237. package/dist/components/BbCheckbox/types.d.ts +13 -1
  238. package/dist/components/BbCheckboxGroup/BbCheckboxGroup.vue_vue_type_script_setup_true_lang.js +41 -51
  239. package/dist/components/BbCheckboxGroup/types.d.ts +59 -5
  240. package/dist/components/BbColorInput/BbColorInput.vue_vue_type_script_setup_true_lang.js +6 -0
  241. package/dist/components/BbColorInput/types.d.ts +13 -1
  242. package/dist/components/BbDatePicker/BbDatePicker.vue_vue_type_script_setup_true_lang.js +96 -93
  243. package/dist/components/BbDatePicker/types.d.ts +4 -4
  244. package/dist/components/BbDatePickerInput/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +328 -306
  245. package/dist/components/BbDatePickerInput/dateFieldLayout.d.ts +23 -0
  246. package/dist/components/BbDatePickerInput/dateFieldLayout.js +38 -0
  247. package/dist/components/BbDatePickerInput/types.d.ts +16 -4
  248. package/dist/components/BbDialog/BbDialog.vue_vue_type_script_setup_true_lang.js +126 -121
  249. package/dist/components/BbDialog/types.d.ts +6 -1
  250. package/dist/components/BbDropdown/AdaptiveDropdown.vue_vue_type_script_setup_true_lang.js +76 -68
  251. package/dist/components/BbDropdown/BbDropdown.vue_vue_type_script_setup_true_lang.js +249 -216
  252. package/dist/components/BbDropdown/BbDropdownGroup.vue.d.ts +11 -4
  253. package/dist/components/BbDropdown/BbDropdownGroup.vue_vue_type_script_setup_true_lang.js +48 -19
  254. package/dist/components/BbDropdown/BbDropdownList.vue_vue_type_script_setup_true_lang.js +245 -239
  255. package/dist/components/BbDropdown/DropdownPipelineResolver.vue_vue_type_script_setup_true_lang.js +120 -103
  256. package/dist/components/BbDropdown/types.d.ts +84 -39
  257. package/dist/components/BbDropdown/useDropdownContext.d.ts +2 -0
  258. package/dist/components/BbDropdown/useDropdownGroupRegistry.d.ts +61 -0
  259. package/dist/components/BbDropzone/BbDropzone.vue_vue_type_script_setup_true_lang.js +149 -123
  260. package/dist/components/BbDropzone/types.d.ts +18 -3
  261. package/dist/components/BbDropzone/types.js +1 -0
  262. package/dist/components/BbForm/BbForm.vue.d.ts +2 -2
  263. package/dist/components/BbIcon/BbIcon.vue.d.ts +1 -3
  264. package/dist/components/BbNumberInput/BbNumberInput.vue_vue_type_script_setup_true_lang.js +7 -1
  265. package/dist/components/BbNumberInput/types.d.ts +13 -1
  266. package/dist/components/BbOffCanvas/BbOffCanvas.vue.d.ts +1 -3
  267. package/dist/components/BbOffCanvas/BbOffCanvas.vue_vue_type_script_setup_true_lang.js +197 -192
  268. package/dist/components/BbOffCanvas/hostCloseLabel.d.ts +3 -0
  269. package/dist/components/BbOffCanvas/hostCloseLabel.js +8 -0
  270. package/dist/components/BbOffCanvas/types.d.ts +6 -1
  271. package/dist/components/BbPagination/BbPagination.vue_vue_type_script_setup_true_lang.js +101 -100
  272. package/dist/components/BbRadio/BbRadio.vue_vue_type_script_setup_true_lang.js +6 -0
  273. package/dist/components/BbRadio/types.d.ts +13 -1
  274. package/dist/components/BbRadioGroup/BbRadioGroup.vue_vue_type_script_setup_true_lang.js +38 -48
  275. package/dist/components/BbRadioGroup/types.d.ts +58 -5
  276. package/dist/components/BbRating/BbRating.vue_vue_type_script_setup_true_lang.js +6 -0
  277. package/dist/components/BbRating/types.d.ts +17 -3
  278. package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +196 -215
  279. package/dist/components/BbSelect/types.d.ts +58 -4
  280. package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +404 -352
  281. package/dist/components/BbSelectPopover/types.d.ts +46 -6
  282. package/dist/components/BbSlider/BbSlider.vue_vue_type_script_setup_true_lang.js +7 -0
  283. package/dist/components/BbSlider/types.d.ts +13 -1
  284. package/dist/components/BbSpinner/BbSpinner.vue.d.ts +1 -3
  285. package/dist/components/BbSwitch/BbSwitch.vue_vue_type_script_setup_true_lang.js +6 -0
  286. package/dist/components/BbSwitchGroup/BbSwitchGroup.vue_vue_type_script_setup_true_lang.js +138 -148
  287. package/dist/components/BbSwitchGroup/types.d.ts +7 -2
  288. package/dist/components/BbTable/BbTable.vue.d.ts +10 -50
  289. package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +1187 -1087
  290. package/dist/components/BbTable/BbTableEdgeRow.d.ts +110 -0
  291. package/dist/components/BbTable/BbTableEdgeRow.js +65 -0
  292. package/dist/components/BbTable/types.d.ts +125 -55
  293. package/dist/components/BbTable/types.js +2 -0
  294. package/dist/components/BbTabs/types.d.ts +3 -3
  295. package/dist/components/BbTag/BbTag.vue_vue_type_script_setup_true_lang.js +140 -134
  296. package/dist/components/BbTag/types.d.ts +13 -1
  297. package/dist/components/BbTextInput/BbTextInput.vue_vue_type_script_setup_true_lang.js +129 -106
  298. package/dist/components/BbTextInput/types.d.ts +29 -7
  299. package/dist/components/BbTextInput/types.js +9 -5
  300. package/dist/components/BbTextarea/BbTextarea.vue_vue_type_script_setup_true_lang.js +124 -100
  301. package/dist/components/BbTextarea/types.d.ts +29 -7
  302. package/dist/components/BbTextarea/types.js +9 -5
  303. package/dist/components/BbTimePickerInput/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +245 -239
  304. package/dist/components/BbTimePickerInput/types.d.ts +13 -1
  305. package/dist/components/BbTree/types.d.ts +1 -1
  306. package/dist/components/CommonField/CommonField.vue.d.ts +1 -1
  307. package/dist/components/CommonField/CommonField.vue_vue_type_script_setup_true_lang.js +114 -78
  308. package/dist/components/CommonField/types.d.ts +22 -3
  309. package/dist/components/CommonFieldInput/CommonFieldInput.vue_vue_type_script_setup_true_lang.js +4 -4
  310. package/dist/components/CommonTimeSelector/CommonTimeSelector.vue.d.ts +1 -1
  311. package/dist/components/CommonTimeSelector/CommonTimeSelector.vue_vue_type_script_setup_true_lang.js +97 -92
  312. package/dist/components/CommonTimeSelector/useMeridiem.d.ts +19 -0
  313. package/dist/components/CommonTimeSelector/useMeridiem.js +41 -0
  314. package/dist/components/FlatListBox/FlatListBox.vue_vue_type_script_setup_true_lang.js +70 -62
  315. package/dist/components/FlatListBox/types.d.ts +5 -0
  316. package/dist/components/GroupedListBox/GroupedListBox.vue_vue_type_script_setup_true_lang.js +142 -134
  317. package/dist/components/GroupedListBox/types.d.ts +5 -0
  318. package/dist/components/ListBox/ListBox.vue_vue_type_script_setup_true_lang.js +5 -0
  319. package/dist/components/ListBox/types.d.ts +5 -0
  320. package/dist/components/OptionsContainer/OptionsContainer.vue_vue_type_script_setup_true_lang.js +73 -65
  321. package/dist/components/OptionsContainer/types.d.ts +28 -3
  322. package/dist/composables/useBbTabsContext.d.ts +1 -1
  323. package/dist/composables/useBbTabsContext.js +1 -1
  324. package/dist/composables/useCharacterCounter.d.ts +33 -0
  325. package/dist/composables/useCharacterCounter.js +29 -0
  326. package/dist/composables/useHydrated.d.ts +16 -4
  327. package/dist/composables/useHydrated.js +27 -9
  328. package/dist/composables/useItemsGetter.d.ts +41 -9
  329. package/dist/composables/useItemsGetter.js +67 -45
  330. package/dist/composables/usePrefill.d.ts +4 -3
  331. package/dist/composables/usePrefill.js +2 -2
  332. package/dist/deprecation/ai-deprecations.json.d.ts +143 -0
  333. package/dist/deprecation/ai-deprecations.json.js +1 -1
  334. package/dist/directives/createPopoverDirective.js +17 -7
  335. package/dist/i18n/locales/cs.json +12 -3
  336. package/dist/i18n/locales/da.json +12 -3
  337. package/dist/i18n/locales/de.json +12 -3
  338. package/dist/i18n/locales/el.json +12 -3
  339. package/dist/i18n/locales/en.json +10 -1
  340. package/dist/i18n/locales/es.json +10 -1
  341. package/dist/i18n/locales/fi.json +12 -3
  342. package/dist/i18n/locales/fr.json +10 -1
  343. package/dist/i18n/locales/hu.json +12 -3
  344. package/dist/i18n/locales/it.json +10 -1
  345. package/dist/i18n/locales/ja.json +12 -3
  346. package/dist/i18n/locales/ko.json +12 -3
  347. package/dist/i18n/locales/nb.json +12 -3
  348. package/dist/i18n/locales/nl.json +12 -3
  349. package/dist/i18n/locales/pl.json +12 -3
  350. package/dist/i18n/locales/pt.json +10 -1
  351. package/dist/i18n/locales/ro.json +12 -3
  352. package/dist/i18n/locales/ru.json +12 -3
  353. package/dist/i18n/locales/sv.json +12 -3
  354. package/dist/i18n/locales/tr.json +12 -3
  355. package/dist/i18n/locales/uk.json +12 -3
  356. package/dist/i18n/locales/zh-cn.json +12 -3
  357. package/dist/index.d.ts +9 -0
  358. package/dist/llms-full.txt +23236 -19924
  359. package/dist/llms-medium.txt +71 -53
  360. package/dist/llms.txt +5 -6
  361. package/dist/locale-blueprint.json +10 -1
  362. package/dist/plugin.js +6 -4
  363. package/dist/runtime/nuxt-plugin.js +2 -2
  364. package/dist/styles.css +2 -2
  365. package/dist/types/CommonProps.d.ts +13 -3
  366. package/dist/types/FieldLayout.d.ts +7 -0
  367. package/dist/types/FieldLayout.js +8 -0
  368. package/dist/types/ItemsProvider.d.ts +91 -0
  369. package/dist/types/passthrough.d.ts +17 -1
  370. package/dist/types/passthrough.js +8 -8
  371. package/dist/types/ptComponentMap.d.ts +4 -4
  372. package/dist/utilities/functions/animationsSettled.d.ts +7 -0
  373. package/dist/utilities/functions/animationsSettled.js +6 -0
  374. package/dist/utilities/functions/elementLabel.d.ts +8 -0
  375. package/dist/utilities/functions/elementLabel.js +6 -0
  376. package/dist/utilities/functions/parseSize.d.ts +2 -1
  377. package/dist/utilities/functions/readableValue.d.ts +6 -0
  378. package/dist/utilities/functions/readableValue.js +4 -0
  379. package/dist/utilities/functions/settlesVisible.d.ts +20 -0
  380. package/dist/utilities/functions/settlesVisible.js +18 -0
  381. package/dist/utilities/functions/throttle.d.ts +1 -4
  382. package/dist/utilities/functions/throttle.js +1 -4
  383. package/dist/utilities/functions/warnRemovedAttrs.d.ts +12 -0
  384. package/dist/utilities/functions/warnRemovedAttrs.js +12 -12
  385. package/dist/utils/versionCheck.js +1 -1
  386. package/dist/vite.js +1 -1
  387. package/llms.txt +5 -6
  388. package/package.json +28 -17
  389. package/scripts/README.md +35 -33
  390. package/scripts/lib/css-class-check.mjs +4 -1
  391. package/scripts/lib/css-local-check.mjs +198 -33
  392. package/scripts/lib/ensure-manifest.mjs +80 -7
  393. package/scripts/lib/eslint-disable.mjs +4 -0
  394. package/scripts/lib/eslint-plugin.d.ts +5 -1
  395. package/scripts/lib/eslint-plugin.mjs +180 -2
  396. package/scripts/lib/example-checks.mjs +337 -0
  397. package/scripts/lib/guide-claims.mjs +452 -0
  398. package/scripts/lib/hand-imported-styles.mjs +7 -2
  399. package/scripts/lib/items-provider-context.mjs +842 -0
  400. package/scripts/lib/linked-target.mjs +30 -0
  401. package/scripts/lib/mcp-config.mjs +6 -0
  402. package/scripts/lib/slot-renames.mjs +5 -6
  403. package/scripts/lib/toolchain-check.mjs +224 -0
  404. package/scripts/lib/validate-bb-markup.mjs +452 -25
  405. package/dist/ai/recipes/inertia/command-palette.md +0 -311
  406. package/dist/ai/recipes/nuxt/command-palette.md +0 -300
  407. package/dist/ai/recipes/vue/command-palette.md +0 -297
@@ -278,7 +278,13 @@ genuine brand art; everything semantic stays a provider icon.
278
278
 
279
279
  <script setup lang="ts">
280
280
  import { BbAlert, BbIcon } from 'bitboss-ui';
281
- import acmeMark from './acme-mark.svg?raw';
281
+
282
+ // A partner's brand mark as a full `<svg>` string. In an app it usually comes
283
+ // from a file: `import acmeMark from './acme-mark.svg?raw'`.
284
+ const acmeMark = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
285
+ <rect width="32" height="32" rx="8" fill="#4f46e5" />
286
+ <path d="M17.5 5 8 18h6.5L14.5 27 24 14h-6.5z" fill="#fff" />
287
+ </svg>`;
282
288
  </script>
283
289
  ```
284
290
 
@@ -462,7 +468,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
462
468
  | `closeLabel` | `string \| undefined` | | | Visually hidden string used to label the close button. |
463
469
  | `hideClose` | `boolean \| undefined` | `false` | | Defines whether to hide the close button. |
464
470
  | `icon` | `string \| undefined` | | | Name of a registered icon to use, or a full raw `<svg>` string (e.g. an SVG file imported with `?raw`). |
465
- | `iconSize` | `number \| ({ size?: any; } & string) \| keyof Sizes \| undefined` | `"16"` | | Size of the icon to use. |
471
+ | `iconSize` | `number \| CssSize \| keyof Sizes \| undefined` | `"16"` | | Size of the icon to use. |
466
472
  | `modelValue` | `boolean \| undefined` | `true` | | Used by v-model. Alerts are visible on mount; the model dismisses them. |
467
473
  | `role` | `"alert" \| "status" \| undefined` | | | Accessibility role for the alert container. Defaults to `'alert'` for destructive/warning variants, otherwise `'status'`. |
468
474
  | `text` | `string \| undefined` | | | Text content of the alert body. |
@@ -427,8 +427,13 @@ it for you.
427
427
  import { BbAvatar, BbIcon } from 'bitboss-ui';
428
428
  // A raw `<svg>` string is a valid `icon` for BbIcon — the escape hatch for
429
429
  // brand art that lives in no icon collection. It paints in `currentColor`,
430
- // so on the avatar's fallback surface it inherits `--bb-primary-fg`.
431
- import releaseBotMark from '@/assets/icons/sparkles.svg?raw';
430
+ // so on the avatar's fallback surface it inherits `--bb-primary-fg`. In an app
431
+ // it usually comes from a file: `import releaseBotMark from './bot.svg?raw'`.
432
+ const releaseBotMark = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
433
+ <path d="M12 4L13.6 8.4L18 10L13.6 11.6L12 16L10.4 11.6L6 10L10.4 8.4L12 4Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round" />
434
+ <path d="M19 3L19.7 4.8L21.5 5.5L19.7 6.2L19 8L18.3 6.2L16.5 5.5L18.3 4.8L19 3Z" fill="currentColor" />
435
+ <path d="M5 16L5.7 17.8L7.5 18.5L5.7 19.2L5 21L4.3 19.2L2.5 18.5L4.3 17.8L5 16Z" fill="currentColor" />
436
+ </svg>`;
432
437
 
433
438
  // Self-contained demo data: each portrait is an inline SVG data URI, so the
434
439
  // example loads nothing over the network. Any image URL works here; swap in
@@ -603,7 +608,7 @@ available in visible text or an adjacent label.
603
608
  | --- | --- | --- | --- | --- |
604
609
  | `pt:<part>`, `pt:<part>:<state>`, `pt` | `PtValue` | | | Passthrough — a class list, or `{ class, style, attrs }`, bound to one named part of the component; the state form applies only while that state is on. Parts: `icon`, `root`. States: —. What each one is: _Passthrough parts and states_ below. `pt` is the object form with the same keys minus the prefix (`{ icon: '…', 'icon:loading': '…' }`). See `guides/passthrough.md`. In `<script>` a `pt` value is typed `BbAvatarProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
605
610
  | `alt` | `string \| undefined` | `""` | | Alternative text for the image, used for accessibility. |
606
- | `size` | `number \| ({ size?: any; } & string) \| keyof Sizes \| undefined` | `"md"` | | Defines the component size. Accepted values: - A key from the provided size map (`keyof T`), e.g. `'sm' \| 'md' \| 'lg'` - A custom CSS size string (e.g. `'20px'`, `'1.5rem'`, `'2em'`) - A number, typically interpreted as pixels by size parsers |
611
+ | `size` | `number \| CssSize \| keyof Sizes \| undefined` | `"md"` | | Defines the component size. Accepted values: - A key from the provided size map (`keyof T`), e.g. `'sm' \| 'md' \| 'lg'` - A custom CSS size string (e.g. `'20px'`, `'1.5rem'`, `'2em'`) - A number, typically interpreted as pixels by size parsers |
607
612
  | `sizes` | `string \| undefined` | | | Sizes attribute for the image, used with `srcset`. |
608
613
  | `src` | `string \| undefined` | | | Source URL of the avatar image. |
609
614
  | `srcset` | `string \| undefined` | | | Responsive image source set. |
@@ -836,7 +836,10 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
836
836
  as a screen-reader-only label — never leave it empty. In button mode that
837
837
  label is also the **button's accessible name**, so it is doubly required.
838
838
  `bitboss-ui check` and the ESLint rule `bitboss-ui/require-accessible-name`
839
- report an empty one as an error.
839
+ report an empty one as an error. The exception is a purely decorative tile
840
+ hidden from assistive tech with `aria-hidden="true"` (it lands on the root),
841
+ e.g. `<BbBadge aria-hidden="true" icon="lucide:star" />`: nothing to name,
842
+ so neither tool reports it.
840
843
  - The `clearable` button's accessible name is composed by default: the
841
844
  localized `badge.clearLabel` verb plus the badge body's text ("Remove
842
845
  Italy"). `clearable-label` replaces the whole name; with a `BbBadgeButton`
@@ -747,7 +747,7 @@ States are listed in precedence order: when two are on at once and their entries
747
747
  - `BbBreadcrumbs` _(this component)_ — its own template binds: `item` → `li.bb-breadcrumbs__item`, `icon` → `BbIcon`, `text` → `span.bb-breadcrumbs__text`
748
748
  - `BbBaseButton` _(public — [contract](./BbBaseButton.md))_ — its own pt parts (`BbBaseButton`): `root` → `RouterComponent`, `root` → `a`, `root` → `component`; also mounts `RouterComponent`
749
749
  - `BbDropdown` _(public — [contract](./BbDropdown.md))_ — its own pt parts (`BbDropdown`): `panel` → `CommonPopover`, `root` → `CommonPopover`, `header` → `div.bb-dropdown__header`, `list` → `span.bb-dropdown__list`, `footer` → `div.bb-dropdown__footer`; documented CSS variables: `--menu-inset`; also mounts `CommonPopover`, `DropdownPipelineResolver`
750
- - `BbDropdownList` _(internal — not importable, reach it through `BbDropdown`)_ — also mounts `BbBaseButton`, `BbIcon`, `CommonPopover`, `BbDropdownList`
750
+ - `BbDropdownList` _(internal — not importable, reach it through `BbDropdown`)_ — also mounts `BbBaseButton`, `BbIcon`, `ErrorIcon`, `CommonPopover`, `BbDropdownList`
751
751
  - `BbBadge` _(public — [contract](./BbBadge.md))_ — its own pt parts (`BbBadge`): `spinner` → `BbSpinner`, `icon` → `BbIcon`, `clear` → `button.bb-badge__clear`; documented CSS variables: `--bg`, `--fg`, `--bw`, `--ring-color`, `--ring-size`, `--min-size-md`, `--min-size`, `--elev`, `--r`, `--fs`, `--icon-size`, `--gap`, `--px`, `--clear-size`, `--bg-disabled`, `--fg-disabled`, `--border-disabled`, `--pad-left`; also mounts `BbIcon`, `BbSpinner`, `BadgeBodyContent`
752
752
  - `AdaptiveDropdown` _(internal — not importable, reach it through `BbDropdown`)_ — hands `BbOffCanvas` the pt map `{ header: 'header', footer: 'footer', panel: 'root', sheet: 'root' }` (ours → theirs); also mounts `BbSmoothHeight`, `BbDropdownList`
753
753
  - `BbOffCanvas` _(public — [contract](./BbOffCanvas.md))_ — its own pt parts (`BbOffCanvas`): `header` → `div.bb-offcanvas__header`, `title` → `span.bb-offcanvas__title`, `description` → `p.bb-offcanvas__description`, `close` → `CloseButton`, `content` → `div.bb-offcanvas__content`, `footer` → `div.bb-offcanvas__footer`; documented CSS variables: `--stack-x`, `--stack-fill`, `--stack-transition-duration`, `--px`, `--handle-w`, `--handle-h`, `--handle-bg`, `--safe-top`, `--close-size`
@@ -234,6 +234,12 @@ not `:text="'Save'"`. The `text` prop renders identically (`<slot>{{ text }}</sl
234
234
  under the hood) and exists mainly for `:items`-style loops that spread a config
235
235
  object; when both are present the slot wins. Reach for `text` only when a string
236
236
  is all you have; otherwise the slot reads cleaner and lets you compose markup.
237
+ Several children in the slot — a label and a status dot, a label and a count —
238
+ are spaced like shadcn/ui's button: in a row, centred, the icon gap apart, with
239
+ no wrapper of your own (`<BbButton>Synced <span class="dot" /></BbButton>`).
240
+ A plain text label is untouched. Wrap rich text in one element
241
+ (`<span>Save <b>all</b></span>`) to keep it one sentence; unwrapped, the `<b>`
242
+ is a child of its own and sits the gap away.
237
243
  `type` defaults to `'button'`, so a `BbButton` inside a form never submits by
238
244
  accident; set `type="submit"` for the one that should, and let the form's
239
245
  `@submit` handler own the logic:
@@ -328,14 +334,12 @@ Just don't ship an icon-only button with neither. When `icon` is set,
328
334
  from an installed provider set (e.g. `lucide:*`) or from your own SVGs as
329
335
  `local:<file-name>` (see the icons policy) — a brand mark or a custom glyph is
330
336
  a `local:` file in your `iconDir`, not a hand-made icon component wrapped in a
331
- `BbBaseButton`. The `local:` name below is one of _this repository's_ fixture
332
- SVGs: in your project it resolves only if `<file-name>.svg` sits in your own
333
- `iconDir`.
334
-
335
- **A local: icon from your own SVGs**
337
+ `BbBaseButton`. The name below stands for your own file: it resolves only if
338
+ `brand-mark.svg` sits in your `iconDir` (BbIcon's guide renders a live
339
+ `local:` demo).
336
340
 
337
341
  ```vue
338
- <BbButton variant="outline" prepend:icon="local:sparkles">Generate</BbButton>
342
+ <BbButton variant="outline" prepend:icon="local:brand-mark">Generate</BbButton>
339
343
  ```
340
344
 
341
345
  **Icons and icon-only**
@@ -397,14 +397,14 @@ object).
397
397
  | Slot | Renders |
398
398
  | ---------------------- | ------------------------------------------- |
399
399
  | `#day` | every day's label, **replacing** the number |
400
- | `#append:day` | under every day (dots, prices, badges) |
400
+ | `#day:append` | under every day (dots, prices, badges) |
401
401
  | `#<YYYY-MM-DD>` | one date's label, e.g. `#2026-12-25` |
402
- | `#append:<YYYY-MM-DD>` | under one date, e.g. `#append:2026-12-25` |
402
+ | `#<YYYY-MM-DD>:append` | under one date, e.g. `#2026-12-25:append` |
403
403
 
404
404
  A date's slot name is its local `YYYY-MM-DD`, exactly as written, and it wins over
405
405
  the matching every-day slot for that date. Per-date slots suit a few fixed
406
406
  dates (holidays, a launch day); for data-driven marks — events from an API —
407
- use `#append:day` and look the day up from `item`. The per-date slots cover the
407
+ use `#day:append` and look the day up from `item`. The per-date slots cover the
408
408
  day grid only, not the month and year panels.
409
409
 
410
410
  The rows grow to fit what you put under a day, with nothing to configure:
@@ -418,7 +418,7 @@ scheduler.
418
418
  ```vue
419
419
  <template>
420
420
  <BbCalendar v-model="value" aria-label="Team calendar">
421
- <template #append:day="{ item, outside }">
421
+ <template #day:append="{ item, outside }">
422
422
  <span
423
423
  v-if="!outside && busy.has(item.format('YYYY-MM-DD'))"
424
424
  aria-hidden="true"
@@ -461,13 +461,13 @@ const busy = new Set(
461
461
  :selectable="isOpen"
462
462
  >
463
463
  <!-- One slot per date: its `YYYY-MM-DD`, exactly as written. -->
464
- <template #append:2026-12-24>
464
+ <template #2026-12-24:append>
465
465
  <span class="holiday-note">Half day</span>
466
466
  </template>
467
- <template #append:2026-12-25>
467
+ <template #2026-12-25:append>
468
468
  <span class="holiday-note">Closed</span>
469
469
  </template>
470
- <template #append:2026-12-26>
470
+ <template #2026-12-26:append>
471
471
  <span class="holiday-note">Closed</span>
472
472
  </template>
473
473
  </BbCalendar>
@@ -637,10 +637,10 @@ States are listed in precedence order: when two are on at once and their entries
637
637
 
638
638
  ## Slots
639
639
 
640
- - `append:day` — scope: `BbCalendarDaySlotProps` `{ first: boolean; item: any; label: string; last: boolean; middle: boolean; outside: boolean; selected: boolean }` — Appends content below each calendar day.
641
640
  - `day` — scope: `BbCalendarDaySlotProps` `{ first: boolean; item: any; label: string; last: boolean; middle: boolean; outside: boolean; selected: boolean }` — Replaces the day button label inside each calendar day.
641
+ - `day:append` — scope: `BbCalendarDaySlotProps` `{ first: boolean; item: any; label: string; last: boolean; middle: boolean; outside: boolean; selected: boolean }` — Appends content below each calendar day.
642
642
  - `#<YYYY-MM-DD>` (named from data) — scope: `BbCalendarDaySlotProps` — One date's button label (e.g. `#2024-03-15`: the local `YYYY-MM-DD`, which `slotKey` leaves as it is); beats `day`. Day grid only.
643
- - `#append:<YYYY-MM-DD>` (named from data) — scope: `BbCalendarDaySlotProps` — Content under one date's cell; beats `append:day`.
643
+ - `#<YYYY-MM-DD>:append` (named from data) — scope: `BbCalendarDaySlotProps` — Content under one date's cell; beats `day:append`.
644
644
 
645
645
  ## CSS custom properties
646
646
 
@@ -19,6 +19,7 @@
19
19
  | `pt:label` | `component` | `CommonField` _(internal)_ |
20
20
  | `pt:description` | `span.bb-field__description` | `CommonField` _(internal)_ |
21
21
  | `pt:hint` | `span.bb-field__hint` | `CommonField` _(internal)_ |
22
+ | `pt:counter` | `span.bb-field__counter` | `CommonField` _(internal)_ |
22
23
  | `pt:message` | `div.bb-field__message` | `CommonField` _(internal)_ |
23
24
 
24
25
  **CSS variables you can set through those parts** — declared deeper in the tree, so set one on the part that reads it (`pt:<part>="[--name:value]"`), never on `BbCheckbox`'s root:
@@ -502,6 +503,10 @@ const toggleAll = (checked: boolean) => {
502
503
  negation as a consumer-facing quirk — it is not.)
503
504
  - `input-position` / `label-position` (`'left' | 'center' | 'right'`) align box
504
505
  and label text inside their columns — useful with ratio layouts.
506
+ - `input-align` / `label-align` (`'top' | 'center' | 'bottom'`) are the
507
+ vertical axis of a side-by-side row. Omitted, the box sits on the label's
508
+ first line; `input-align="center"` puts it on the middle of a described
509
+ label.
505
510
  - `hide-label` keeps the label for screen readers but hides it visually — only
506
511
  for dense composites where visible text lives elsewhere.
507
512
  - `compact` tightens the field's label spacing (`--bb-label-spacing-y-compact` instead of `--bb-label-spacing-y`), the same as on the groups — for dense forms and settings panels.
@@ -701,8 +706,10 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
701
706
  | `hint` | `string \| undefined` | | | Text box to be displayed near the input, usually to indicate instructions. |
702
707
  | `id` | `string \| undefined` | | | The `id` of the native control; the label's `for` and the description and message ids derive from it. Generated when omitted. |
703
708
  | `indeterminate` | `boolean \| undefined` | `false` | | Sets the input in an indeterminate state. |
709
+ | `inputAlign` | `FieldCrossAlign \| undefined` | | | Vertical position of the control in a side-by-side row; not `inputPosition`, the horizontal one. Omitted, the control's first line meets the label's. |
704
710
  | `inputPosition` | `"left" \| "center" \| "right" \| undefined` | `"left"` | | Sets the alignment of the input. Since inputs are inline block they can be aligned just as text can. |
705
711
  | `label` | `string` | | yes | Text content of the label of the element. |
712
+ | `labelAlign` | `FieldCrossAlign \| undefined` | | | Vertical position of the label block in a side-by-side row; not `labelPosition`, the horizontal one. Omitted, the label's first line meets the control's. |
706
713
  | `labelPosition` | `"left" \| "center" \| "right" \| undefined` | | | Sets the text alignment of the label. |
707
714
  | `layout` | `FieldLayout \| undefined` | `"auto"` | | How the label and the input sit together: `'vertical'`, `'horizontal'` (50/50), `'auto'`, `'label-fill'` (the label takes the free space, the input keeps its size), `'input-fill'` (the other way round), or a two-word ratio pattern like `'xx xxxxx'`. |
708
715
  | `modelValue` | `any` | | | Used by v-model. Can be any serializable type. |
@@ -772,7 +779,7 @@ States are listed in precedence order: when two are on at once and their entries
772
779
  - Listed nodes are the ones `BbCheckbox`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbCheckbox.tree.json`.
773
780
 
774
781
  - `BbCheckbox` _(this component)_ — its own template binds: `icon` → `BbBaseCheckboxIcon`
775
- - `CommonField` _(internal — not importable, reach it through `BbCheckbox`)_ — `BbCheckbox`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `message` → `div.bb-field__message`; documented CSS variables: `--ctrl-line`; also mounts `BbAsterisk`
782
+ - `CommonField` _(internal — not importable, reach it through `BbCheckbox`)_ — `BbCheckbox`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `counter` → `span.bb-field__counter`, `message` → `div.bb-field__message`; documented CSS variables: `--ctrl-line`; also mounts `BbAsterisk`
776
783
  - Also mounts `BbBaseCheckboxIcon`
777
784
 
778
785
  ## See Also
@@ -19,6 +19,7 @@
19
19
  | `pt:label` | `component` | `CommonField` _(internal)_ |
20
20
  | `pt:description` | `span.bb-field__description` | `CommonField` _(internal)_ |
21
21
  | `pt:hint` | `span.bb-field__hint` | `CommonField` _(internal)_ |
22
+ | `pt:counter` | `span.bb-field__counter` | `CommonField` _(internal)_ |
22
23
  | `pt:message` | `div.bb-field__message` | `CommonField` _(internal)_ |
23
24
  | `pt:list` | `span` | `OptionsContainer` _(internal)_ |
24
25
  | `pt:item` | `label` | `OptionsContainer` _(internal)_ |
@@ -377,6 +378,9 @@ disabling it.
377
378
  same keywords as `layout`; `item-reverse` swaps the two. A settings list is
378
379
  `list-layout="vertical-stretch" item-layout="label-fill" item-reverse`: the
379
380
  label takes the row, the input sits at the trailing edge.
381
+ `item-input-align` / `item-label-align` (`top | center | bottom`) aim each
382
+ row's cells vertically, as in the switch group's settings list; the field's
383
+ `input-align` / `label-align` move the options against the legend.
380
384
  - `layout` arranges the **legend against the options block** (the outer
381
385
  split): `'auto'`, `'horizontal'`, `'vertical'`, `'label-fill'`,
382
386
  `'input-fill'`, or a proportional pattern like `'xx xxxxxx'`.
@@ -695,11 +699,14 @@ above.
695
699
 
696
700
  ### Async items, loading and coherence
697
701
 
698
- `items` also accepts a provider function (`(prefill, modelValue) => T[] |
699
- Promise<T[]>`) for options fetched from an API. The group calls it on mount with
700
- `prefill = true`; every dependency-driven refetch passes `prefill = false`.
702
+ `items` also accepts a provider function for options fetched from an API. It is
703
+ called with one context object — `BbCheckboxGroupItemsContext`: `reason`
704
+ (`'initial'` on mount, `'dependencies'` on a dependency-driven refetch,
705
+ `'model'` when the model changed from outside and the options cannot resolve
706
+ it), `modelValue` and `signal`; a group has no search field, so no `query`.
701
707
  While it resolves, `loading-text` (or the `#loading` slot) shows; `empty-text`
702
- (or `#empty`) covers the empty result. Loading and race protection are
708
+ (or `#empty`) covers the empty result, and `failed-text` (or `#empty` with its
709
+ `error` prop) a load that threw. Loading, cancellation and race protection are
703
710
  built in — don't wrap the provider in your own `loading` ref or debounce.
704
711
 
705
712
  Tie the option set to external state with `dependencies` (debounced by
@@ -791,12 +798,11 @@ const allScopes: Scope[] = [
791
798
  const role = ref<Role>('developer');
792
799
  const scopes = ref<string[]>(['repo:read', 'repo:write']);
793
800
 
794
- // Non-query group provider: (prefill, modelValue). Groups always pass
795
- // `prefill = true` — mount load and dependency refetches alike.
796
- const loadScopes = (
797
- _prefill: boolean,
798
- _modelValue?: string[]
799
- ): Promise<Scope[]> =>
801
+ // The group calls the provider with one context object (`reason`,
802
+ // `modelValue`, `signal`); this one needs none of it — the role it filters by
803
+ // is read from the ref — so it takes no parameter. `reason` would read
804
+ // `'initial'` on the mount load and `'dependencies'` on a role change.
805
+ const loadScopes = (): Promise<Scope[]> =>
800
806
  new Promise((resolve) => {
801
807
  setTimeout(
802
808
  () =>
@@ -980,8 +986,9 @@ for a preset that fits any row type (never `<any>`), not an imported
980
986
  | `description` | `string \| undefined` | | | Descriptive text displayed below the label and above the input. Unlike the hint it is always visible, and it is linked to the input via `aria-describedby` (after any `errors` / `warnings`, before the `hint`). |
981
987
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component. |
982
988
  | `emptyText` | `string \| undefined` | | | String displayed when there are no items to display. |
983
- | `enforceCoherence` | `boolean \| undefined` | `false` | | If coherence is enforced the input cannot have a modelValue that is incoherent with its current items. e.g. You cannot set v-model to a user that is not present in the items passed. modelValue will be reset upon incoherence. |
989
+ | `enforceCoherence` | `boolean \| undefined` | `false` | | If coherence is enforced the input cannot have a modelValue that is incoherent with its current items. e.g. You cannot set v-model to a user that is not present in the items passed. modelValue will be reset upon incoherence. Checked after every applied, successful load (an empty one included); a failed load never prunes. |
984
990
  | `errors` | `string \| string[] \| undefined` | | | Can be a string or an array of string containing the messages to display. They render in an `aria-live="polite"` region (announced when they appear) and, while the list is non-empty, are referenced FIRST from the control's `aria-describedby`, so the reason the field is invalid is re-read whenever the control regains focus. |
991
+ | `failedText` | `string \| undefined` | `the localized `common.failedText` ("Couldn't load items")` | | String displayed in the empty state while the latest load FAILED (the `items` provider threw): the twin of `emptyText` for that case. |
985
992
  | `formless` | `boolean \| undefined` | `false` | | Keep this control out of the enclosing `BbForm` entirely: not submitted, not dirty, not reset, not validated. For a control that is not form data (a filter, a "show advanced" switch). |
986
993
  | `hasErrors` | `boolean \| undefined` | `false` | | Define if the component should be in an error state. It usually attaches a CSS class for styling purposes. |
987
994
  | `hasWarnings` | `boolean \| undefined` | `false` | | Define if the component should be in a warning state. Same chrome as errors with `--bb-warn`; errors take priority. |
@@ -989,13 +996,17 @@ for a preset that fits any row type (never `<any>`), not an imported
989
996
  | `hideLegend` | `boolean \| undefined` | `false` | | Visually hides the legend of the fieldset while maintaining accessibility. |
990
997
  | `hint` | `string \| undefined` | | | Text box to be displayed near the input, usually to indicate instructions. |
991
998
  | `id` | `string \| undefined` | | | Prefix for the ids of each option's input and of the label, description and message. Generated when omitted. |
999
+ | `inputAlign` | `'top'` \| `'center'` \| `'bottom'` | | | Vertical position of the control in a side-by-side row; not `inputPosition`, the horizontal one. Omitted, the control's first line meets the label's. |
992
1000
  | `inputPosition` | `"left" \| "center" \| "right" \| undefined` | `"left"` | | Sets the alignment of the input. Since inputs are inline block they can be aligned just as text can. |
1001
+ | `itemInputAlign` | `'top'` \| `'center'` \| `'bottom'` | | | Vertical position of each option's control in its row; `'center'` is the middle of the label plus its description. Omitted, it sits on the label's first line. |
1002
+ | `itemLabelAlign` | `'top'` \| `'center'` \| `'bottom'` | | | Vertical position of each option's label in its row. Omitted, it stays as it is. |
993
1003
  | `itemLayout` | `FieldLayout \| undefined` | `'auto'` | | How each row's input and label sit together — the keywords of `layout`: `'auto'`, `'vertical'` (the input above the label), `'horizontal'` (50/50), `'label-fill'` (the label takes the row's free space — pair it with `list-layout="vertical-stretch"` and `item-reverse` for a settings list), `'input-fill'`, or a two-word ratio pattern like `'xx xxxxx'`, read in on-screen order. |
994
1004
  | `itemProps` | `BbOptionGroupItemProps<T> \| undefined` | | | ADDITIONAL row fields resolved from each item — never its text or value (those stay on `itemText` / `itemValue`). Option groups accept one field: - `description` — a muted line under the option label, beside the control; it may wrap. Either an object with a path or getter per field (`{ description: 'email' }`) or a function returning the fields (`(item) => ({ description: item.email })`). Without it no field renders — an item's own `description` is never read implicitly — and an empty value renders nothing for that item. The description is announced as the option's description, never part of its name. To disable individual options use `selectable`. |
995
1005
  | `itemReverse` | `boolean \| undefined` | `false` | | Swaps each row's input and label from their natural order (input first), in every `item-layout`. `reverse` swaps the legend and the options instead. |
996
- | `items` | `T[] \| ((prefill: boolean, modelValue?: any) => T[] \| Promise<T[]>)` | | yes | Used to retrieve items; can be an array or a function. |
1006
+ | `items` | `T[] \| ((context: BbCheckboxGroupItemsContext) => T[] \| Promise<T[]>)` | | yes | The options: an array, or a provider function called with ONE context object and returning the rows, sync or async. The context carries: - `reason` — why this call happened: `'initial'` (the first load, on mount), `'dependencies'` (a `dependencies` entry or the `items` function changed; a retry arrives this way) or `'model'` (the model changed from outside and the options cannot resolve it). The group has no search field, so it never passes `query`; - `modelValue` — the `v-model` as-is; - `signal` — an `AbortSignal`, aborted when a newer call starts or the group is disposed; pass it to every request. A provider signals a failure by THROWING, never by returning `[]`: the rows are cleared, nothing is pruned, and `#empty` receives the `error` (`failed-text` is shown). Zero-argument providers keep working. Annotate the parameter `BbCheckboxGroupItemsContext` (`BbSwitchGroupItemsContext` on a switch group, the same shape). |
997
1007
  | `itemText` | `ItemAccessor<T, string> \| undefined` | `JSON.stringify(item)` | | Defines a path that returns a property of the object to use as text or a function that returns a string. |
998
1008
  | `itemValue` | `ItemAccessor<T> \| undefined` | `the whole item` | | Defines a path that returns a property of the object to use as value or a function that returns any value. |
1009
+ | `labelAlign` | `'top'` \| `'center'` \| `'bottom'` | | | Vertical position of the label block in a side-by-side row; not `labelPosition`, the horizontal one. Omitted, the label's first line meets the control's. |
999
1010
  | `layout` | `FieldLayout \| undefined` | | | How the label and the input sit together: `'vertical'`, `'horizontal'` (50/50), `'auto'`, `'label-fill'` (the label takes the free space, the input keeps its size), `'input-fill'` (the other way round), or a two-word ratio pattern like `'xx xxxxx'`. |
1000
1011
  | `legend` | `string` | | yes | Text content of the legend. |
1001
1012
  | `legendMode` | `"outside" \| "inside" \| undefined` | | | Legend rendering mode. `'outside'` renders the legend above the fieldset in the normal flow; `'inside'` overlays the legend inside the fieldset border. Floating mode is not supported for option groups (checkbox, radio or switch) — there is no single field for the legend to float against. |
@@ -1065,7 +1076,7 @@ States are listed in precedence order: when two are on at once and their entries
1065
1076
 
1066
1077
  - `append` — scope: `object` — Content rendered after the last option, inside the options container.
1067
1078
  - `description` — scope: `BbCheckboxGroupDescriptionSlotProps` `{ text: string; hasErrors: boolean; hasWarnings: boolean }` — Replaces the description text. Provided alone (no `description` prop) it still renders the description region and wires it into `aria-describedby`.
1068
- - `empty` — scope: `object` — Content shown when no options are available (replaces the default "no data" text).
1079
+ - `empty` — scope: `{ error: unknown; }` — Content shown when no options are available (replaces the default "no data" text). `error` is what the latest failed load rejected with, untouched, and `null` when nothing failed — a failed load clears the rows, so this slot is where it shows.
1069
1080
  - `icon` — scope: `BbCheckboxGroupIconSlotProps<T>` `{ disabled: boolean; readonly: boolean; checked: boolean; indeterminate?: boolean; focused: boolean; focusVisible: boolean; id: string; name: string; falseValue: any; hasErrors: boolean; hasWarnings: boolean; parsedValue: string; trueValue: any; value: any; item: T; text: string }` — Replaces the default checkmark icon for each checkbox option.
1070
1081
  - `label` — scope: `BbCheckboxGroupLabelSlotProps<T>` `{ item: T; text: string; checked: boolean; description: string }` — Replaces the default label text for each option.
1071
1082
  - `legend` — scope: `BbCheckboxGroupLegendSlotProps` `{ text: string; hasErrors: boolean; hasWarnings: boolean }` — Replaces the default fieldset legend text for the group.
@@ -1092,7 +1103,7 @@ Set these on the element, or on a class you put on it, to retune this component
1092
1103
  - Listed nodes are the ones `BbCheckboxGroup`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbCheckboxGroup.tree.json`.
1093
1104
 
1094
1105
  - `BbCheckboxGroup` _(this component)_ — its own template binds: `icon` → `BbBaseCheckboxIcon`
1095
- - `CommonField` _(internal — not importable, reach it through `BbCheckboxGroup`)_ — `BbCheckboxGroup`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `message` → `div.bb-field__message`; documented CSS variables: `--ctrl-line`; also mounts `BbAsterisk`
1106
+ - `CommonField` _(internal — not importable, reach it through `BbCheckboxGroup`)_ — `BbCheckboxGroup`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `counter` → `span.bb-field__counter`, `message` → `div.bb-field__message`; documented CSS variables: `--ctrl-line`; also mounts `BbAsterisk`
1096
1107
  - `OptionsContainer` _(internal — not importable, reach it through `BbCheckboxGroup`)_ — `BbCheckboxGroup`'s pt parts land here: `list` → `span`, `item` → `label`, `label` → `span`, `itemDescription` → `span`
1097
1108
  - Also mounts `BbBaseCheckboxIcon`
1098
1109
 
@@ -21,6 +21,7 @@
21
21
  | `pt:label` | `component` | `CommonField` _(internal)_ |
22
22
  | `pt:description` | `span.bb-field__description` | `CommonField` _(internal)_ |
23
23
  | `pt:hint` | `span.bb-field__hint` | `CommonField` _(internal)_ |
24
+ | `pt:counter` | `span.bb-field__counter` | `CommonField` _(internal)_ |
24
25
  | `pt:message` | `div.bb-field__message` | `CommonField` _(internal)_ |
25
26
  | `pt:box` | `span.bb-field-input__box` | `CommonFieldInput` _(internal)_ |
26
27
  | `pt:prefix` | `span.bb-field-input__prefix` | `CommonFieldInput` _(internal)_ |
@@ -694,7 +695,9 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
694
695
  | `hideLabel` | `boolean \| undefined` | `false` | | Visually hides the label of the input while maintaining accessibility. |
695
696
  | `hint` | `string \| undefined` | | | Text box to be displayed near the input, usually to indicate instructions. |
696
697
  | `id` | `string \| undefined` | | | The `id` of the native control; the label's `for` and the description and message ids derive from it. Generated when omitted. |
698
+ | `inputAlign` | `FieldCrossAlign \| undefined` | | | Vertical position of the control in a side-by-side row; not `inputPosition`, the horizontal one. Omitted, the control's first line meets the label's. |
697
699
  | `label` | `string` | | yes | Text content of the label of the element. |
700
+ | `labelAlign` | `FieldCrossAlign \| undefined` | | | Vertical position of the label block in a side-by-side row; not `labelPosition`, the horizontal one. Omitted, the label's first line meets the control's. |
698
701
  | `labelMode` | `"outside" \| "floating" \| "inside" \| undefined` | | | Label rendering mode: `outside` places the label above the input, `floating` overlays it on the field and shrinks it when a value is set, `inside` keeps it inside the field. |
699
702
  | `labelPosition` | `"left" \| "center" \| "right" \| undefined` | | | Sets the text alignment of the label. |
700
703
  | `layout` | `FieldLayout \| undefined` | | | How the label and the input sit together: `'vertical'`, `'horizontal'` (50/50), `'auto'`, `'label-fill'` (the label takes the free space, the input keeps its size), `'input-fill'` (the other way round), or a two-word ratio pattern like `'xx xxxxx'`. |
@@ -800,7 +803,7 @@ Set these on the element, or on a class you put on it, to retune this component
800
803
  - Listed nodes are the ones `BbColorInput`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbColorInput.tree.json`.
801
804
 
802
805
  - `BbColorInput` _(this component)_ — its own template binds: `controlAttrs` → `input.bb-color-input__input`, `input` → `input.bb-color-input__input`, `indicator` → `button.bb-color-input__indicator`, `suffix` → `span.bb-field-input__suffix`; hands `BbColorPalette` the pt map `{ panel: 'panel', sheet: 'sheet', swatch: 'swatch' }` (ours → theirs)
803
- - `CommonField` _(internal — not importable, reach it through `BbColorInput`)_ — `BbColorInput`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `message` → `div.bb-field__message`; documented CSS variables: `--ctrl-line`; also mounts `BbAsterisk`
806
+ - `CommonField` _(internal — not importable, reach it through `BbColorInput`)_ — `BbColorInput`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `counter` → `span.bb-field__counter`, `message` → `div.bb-field__message`; documented CSS variables: `--ctrl-line`; also mounts `BbAsterisk`
804
807
  - `CommonFieldInput` _(internal — not importable, reach it through `BbColorInput`)_ — `BbColorInput`'s pt parts land here: `box` → `span.bb-field-input__box`, `prefix` → `span.bb-field-input__prefix`, `icon` → `BbIcon`, `clear` → `ClearableButton`, `spinner` → `BbSpinner`, `suffix` → `span.bb-field-input__suffix`; documented CSS variables: `--bg`, `--bg-hover`, `--bg-focus`, `--bg-disabled`, `--fg-disabled`, `--border-color`, `--border-focus`, `--ring-size`, `--ring-color`, `--elev`, `--frost`, `--inside-label-clearance`; also mounts `ErrorIcon`, `WarningIcon`, `ClearableButton`, `BbIcon`, `BbSpinner`
805
808
  - `BbColorPalette` _(public — [contract](./BbColorPalette.md))_ — its own pt parts (`BbColorPalette`): `swatch` → `button.bb-color-palette__swatch`, `panel` → `div`, `panel` → `CommonPopover`; hands `BbOffCanvas` the pt map `{ panel: 'root', sheet: 'root' }` (ours → theirs); documented CSS variables: `--edge`; also mounts `CommonPopover`
806
809
  - `BbOffCanvas` _(public — [contract](./BbOffCanvas.md))_ — its own pt parts (`BbOffCanvas`): `header` → `div.bb-offcanvas__header`, `title` → `span.bb-offcanvas__title`, `description` → `p.bb-offcanvas__description`, `close` → `CloseButton`, `content` → `div.bb-offcanvas__content`, `footer` → `div.bb-offcanvas__footer`; documented CSS variables: `--stack-x`, `--stack-fill`, `--stack-transition-duration`, `--px`, `--handle-w`, `--handle-h`, `--handle-bg`, `--safe-top`, `--close-size`
@@ -209,11 +209,11 @@ const time = ref<string | null>(null);
209
209
  The picker passes its day slots straight to the calendar inside it, so the four
210
210
  day-grid slots work here unchanged:
211
211
 
212
- - `#day` replaces every day's number and `#append:day` adds under every day
212
+ - `#day` replaces every day's number and `#day:append` adds under every day
213
213
  (event dots, prices). Both receive `label`, `selected`, `outside`,
214
214
  `first` / `middle` / `last` and `item` (the day as a dayjs object).
215
- - `#<YYYY-MM-DD>` and `#append:<YYYY-MM-DD>` do the same for one date, e.g.
216
- `#append:2026-12-25`: its local `YYYY-MM-DD`, exactly as written. A date's
215
+ - `#<YYYY-MM-DD>` and `#<YYYY-MM-DD>:append` do the same for one date, e.g.
216
+ `#2026-12-25:append`: its local `YYYY-MM-DD`, exactly as written. A date's
217
217
  slot wins over the every-day one.
218
218
 
219
219
  ```vue
@@ -221,12 +221,12 @@ day-grid slots work here unchanged:
221
221
  <template #activator="{ props, value }">
222
222
  <BbButton v-bind="props" variant="outline">{{ value ?? 'Pickup day' }}</BbButton>
223
223
  </template>
224
- <template #append:2026-12-25><span class="text-[10px]">Closed</span></template>
224
+ <template #2026-12-25:append><span class="text-[10px]">Closed</span></template>
225
225
  </BbDatePicker>
226
226
  ```
227
227
 
228
228
  Use per-date slots for a few fixed dates; mark data-driven days through
229
- `#append:day` and a lookup on `item`. The [BbCalendar](./BbCalendar.md) guide
229
+ `#day:append` and a lookup on `item`. The [BbCalendar](./BbCalendar.md) guide
230
230
  has a worked example.
231
231
 
232
232
  ### Adaptive and positioning
@@ -430,7 +430,7 @@ and digit typeahead; the time rail exposes labelled columns. Always pass a
430
430
  | `offCanvasProps` | `Partial<BbOffCanvasProps> \| undefined` | | | Props for the phone sheet. A `pt` inside it, object or colon keys, styles only that sheet. Extra props forwarded to the `BbOffCanvas` sheet when `adaptive` is active on mobile (e.g. `title`, `size`, `persistent`). Spread over the defaults: the sheet is `draggable` (the time wheels and the year list never drag it) and hides its ✕ (picking, backdrop, Escape and drag close it); pass `{ hideClose: false }` to bring the ✕ back. A `pt` inside it styles ONLY the sheet, in `BbOffCanvas`'s part words (`root`, `header`, `title`, `description`, `content`, `footer`, `close`; state `open`), object (`{ pt: { header: '…' } }`) or colon keys (`{ 'pt:header': '…' }`) alike. It merges after what this component forwards to its sheet, so it wins a conflict and drops nothing — see the passthrough guide § Inside the sheet. For this component it is the only way to style the sheet's header, title and ✕: its own `pt:header` is the calendar's navigation bar. |
431
431
  | `offset` | `number \| undefined` | `4` | | Space the popover keeps from the activator. |
432
432
  | `padding` | `number \| undefined` | | | Minimum empty space to keep from the edge of the page. |
433
- | `placement` | `'left'` \| `'right'` \| `'top'` \| `'top-start'` \| `'top-end'` \| `'right-start'` \| `'right-end'` \| `'bottom'` \| `'bottom-start'` \| `'bottom-end'` \| `'left-start'` \| `'left-end'` | | | Position of the popover relative to the activator/anchor. |
433
+ | `placement` | `'top'` \| `'bottom'` \| `'left'` \| `'right'` \| `'top-start'` \| `'top-end'` \| `'right-start'` \| `'right-end'` \| `'bottom-start'` \| `'bottom-end'` \| `'left-start'` \| `'left-end'` | | | Position of the popover relative to the activator/anchor. |
434
434
  | `range` | `boolean \| undefined` | `false` | | Enables range selection (`[start, end]`). |
435
435
  | `readonly` | `boolean \| undefined` | `false` | | Prevents opening while keeping the activator visible. |
436
436
  | `seconds` | `boolean \| undefined` | `false` | | Adds the seconds column (requires `type="datetime"`). |
@@ -491,10 +491,10 @@ States are listed in precedence order: when two are on at once and their entries
491
491
  ## Slots
492
492
 
493
493
  - `activator` — scope: `BbDatePickerActivatorSlotProps` `{ props: { ref: (el: unknown) => void; 'aria-haspopup': "dialog"; 'aria-expanded': "true" \| "false"; 'aria-labelledby': string; }; anchorProps: { ref: (el: unknown) => void; }; open: boolean; value: string \| string[] \| null; disabled: boolean }` — Custom activator element. Apply `v-bind="props"` to your trigger.
494
- - `append:day` — scope: `BbCalendarDaySlotProps` `{ first: boolean; item: any; label: string; last: boolean; middle: boolean; outside: boolean; selected: boolean }` — Appends content below each calendar day.
495
494
  - `day` — scope: `BbCalendarDaySlotProps` `{ first: boolean; item: any; label: string; last: boolean; middle: boolean; outside: boolean; selected: boolean }` — Replaces the day button label inside each calendar day.
495
+ - `day:append` — scope: `BbCalendarDaySlotProps` `{ first: boolean; item: any; label: string; last: boolean; middle: boolean; outside: boolean; selected: boolean }` — Appends content below each calendar day.
496
496
  - `#<YYYY-MM-DD>` (named from data) — scope: `BbCalendarDaySlotProps` — One date's button label (e.g. `#2024-03-15`: the local `YYYY-MM-DD`, which `slotKey` leaves as it is); beats `day`. Day grid only.
497
- - `#append:<YYYY-MM-DD>` (named from data) — scope: `BbCalendarDaySlotProps` — Content under one date's cell; beats `append:day`.
497
+ - `#<YYYY-MM-DD>:append` (named from data) — scope: `BbCalendarDaySlotProps` — Content under one date's cell; beats `day:append`.
498
498
 
499
499
  ## CSS custom properties
500
500
 
@@ -18,6 +18,7 @@
18
18
  | `pt:label` | `component` | `CommonField` _(internal)_ |
19
19
  | `pt:description` | `span.bb-field__description` | `CommonField` _(internal)_ |
20
20
  | `pt:hint` | `span.bb-field__hint` | `CommonField` _(internal)_ |
21
+ | `pt:counter` | `span.bb-field__counter` | `CommonField` _(internal)_ |
21
22
  | `pt:message` | `div.bb-field__message` | `CommonField` _(internal)_ |
22
23
  | `pt:box` | `span.bb-field-input__box` | `CommonFieldInput` _(internal)_ |
23
24
  | `pt:prefix` | `span.bb-field-input__prefix` | `CommonFieldInput` _(internal)_ |
@@ -176,12 +177,13 @@ entirely, reach for `disableWriting` (below), not `range`.
176
177
  ### The segmented field & typing
177
178
 
178
179
  The value is edited as three separate inputs — day, month, year — not one free
179
- string. Their **order follows `config.locale`**: `en` renders `MM / DD / YYYY`,
180
- every other locale (e.g. `it`) renders `DD / MM / YYYY`. Typing is forgiving:
180
+ string. Their **order and separator follow `config.locale`**, read from the
181
+ locale's own format hint: `en` renders `MM/DD/YYYY`, `it` `DD/MM/YYYY`, `de`
182
+ `TT.MM.JJJJ`, `ja` `YYYY/MM/DD`. Typing is forgiving:
181
183
 
182
184
  - digits **auto-advance** to the next segment when a segment fills (or can't
183
185
  take another digit — e.g. `4` in a day segment becomes `04` and moves on);
184
- - `/`, `-` or space also advances; **Backspace** at the start of a segment (and
186
+ - `/`, `-`, `.` or space also advances; **Backspace** at the start of a segment (and
185
187
  **←** / **→** at the edges) moves between segments;
186
188
  - **↑** / **↓** step the focused segment by one, wrapping at its bounds (day
187
189
  `31` → `01`, month `12` → `01`, a 24-hour `23` → `00` — and back the other
@@ -215,7 +217,7 @@ disable that day. `firstDayOfWeek` shifts the calendar grid (`0` = Sunday …
215
217
  `6` = Saturday).
216
218
 
217
219
  The example below combines a rolling `min`/`max` window, a weekdays-only
218
- predicate, `floating` output, and the `append:day` slot to dot specific days.
220
+ predicate, `floating` output, and the `day:append` slot to dot specific days.
219
221
 
220
222
  **Bounded, weekdays-only, with event dots**
221
223
 
@@ -241,7 +243,7 @@ predicate, `floating` output, and the `append:day` slot to dot specific days.
241
243
  prepend:icon="lucide:calendar-check"
242
244
  :selectable="isWeekday"
243
245
  >
244
- <template #append:day="{ item }">
246
+ <template #day:append="{ item }">
245
247
  <span
246
248
  v-if="hasOpenSlots(item)"
247
249
  class="mx-auto mt-0.5 block h-1 w-1 rounded-full bg-current opacity-70"
@@ -263,7 +265,7 @@ const appointment = ref<string | null>(null);
263
265
  const min = dayjs().format('YYYY-MM-DD');
264
266
  const max = dayjs().add(30, 'day').format('YYYY-MM-DD');
265
267
 
266
- // Days that still have open demo slots — dotted via the `append:day` slot.
268
+ // Days that still have open demo slots — dotted via the `day:append` slot.
267
269
  const openSlots = [3, 5, 8, 12].map((offset) =>
268
270
  dayjs().add(offset, 'day').format('YYYY-MM-DD')
269
271
  );
@@ -383,7 +385,7 @@ const setPreset = (days: number) => {
383
385
  ```
384
386
 
385
387
  There is no day segment to tab through under `month`, no month segment under
386
- `year`, and the placeholder/format hint follows suit (`MM/YYYY`, localized) —
388
+ `year`, and the placeholder/format hint follows suit (`MM/YYYY`, `MM.JJJJ` in `de`: the locale's words and separator) —
387
389
  promising `DD/MM/YYYY` to a two-segment field would be worse than no hint at
388
390
  all. The calendar button opens the matching terminal grid, so typing and
389
391
  picking always produce the same shape.
@@ -427,8 +429,9 @@ Tuning knobs, all inert without `type="datetime"` (DEV warning):
427
429
  renders 00/15/30/45 — and constrains what the panel _produces_, never what
428
430
  the field _accepts_: a typed `10:07` is emitted verbatim, and no column row
429
431
  highlights for it.
430
- - **`ampm`** switches the display to 12-hour with an AM/PM segment (type `A` /
431
- `P`, or cycle with ArrowUp/Down). Purely visual: the model stays 24-hour.
432
+ - **`ampm`** switches the display to 12-hour with an AM/PM segment in the
433
+ locale's words (`午前` / `午後` in `ja`; type `A` / `P` or the word, or cycle
434
+ with ArrowUp/Down). Purely visual: the model stays 24-hour.
432
435
  - **`min` / `max`** additionally accept `YYYY-MM-DDTHH:mm` to tighten the
433
436
  boundary day to a minute; date-only bounds keep working day-granular, so any
434
437
  time inside the boundary day is fine.
@@ -573,18 +576,18 @@ during setup** — every platform must keep at least one interaction method.
573
576
 
574
577
  ### Decorating days
575
578
 
576
- The `day` slot **replaces** a day's contents; the `append:day` slot **adds**
579
+ The `day` slot **replaces** a day's contents; the `day:append` slot **adds**
577
580
  below it (badges, event dots, price tags). Both receive the day's state — `label`
578
581
  (the day number), `selected`, `outside` (a day of the previous or next month),
579
582
  `first` / `middle` / `last` (range edges) and `item` (the underlying dayjs object, for formatting or lookups). Keep
580
583
  decorations lightweight; they render for every visible cell. The appointment
581
- example above uses `append:day` for event dots.
584
+ example above uses `day:append` for event dots.
582
585
 
583
586
  One date can have its own slot: `#<YYYY-MM-DD>` replaces that date's number and
584
- `#append:<YYYY-MM-DD>` adds under it, e.g. `#append:2026-12-25` — the local
585
- `YYYY-MM-DD`, exactly as written. A date's slot wins over `day` / `append:day` for
587
+ `#<YYYY-MM-DD>:append` adds under it, e.g. `#2026-12-25:append` — the local
588
+ `YYYY-MM-DD`, exactly as written. A date's slot wins over `day` / `day:append` for
586
589
  that date. Use them for a few fixed dates (holidays); mark data-driven days with
587
- `append:day` and a lookup on `item`.
590
+ `day:append` and a lookup on `item`.
588
591
 
589
592
  ### Calendar keyboard navigation
590
593
 
@@ -675,7 +678,8 @@ sheet), its events differ from a plain input:
675
678
  `config.defaultInputLabelMode`) the label is embedded in the field, so the
676
679
  layout is forced vertical and `layout` is ignored — same rule as
677
680
  `BbTextInput`/`BbSelect`/`BbNumberInput`.
678
- - **`config.locale`** drives both the segment order (`en` → month-first) and the
681
+ - **`config.locale`** drives both the segment order and separator (from the
682
+ locale's `datePickerInput.dateFormatSingle` hint) and the
679
683
  calendar's month/weekday names via dayjs (a dayjs pack is bundled for each of
680
684
  your `enabledLocales` — see
681
685
  [Installation and Plugin Setup](./guides/installation-and-plugin-setup.md) §
@@ -876,7 +880,9 @@ label>')` matches nothing; query each segment by its own label instead. See
876
880
  | `hideLabel` | `boolean \| undefined` | `false` | | Visually hides the label of the input while maintaining accessibility. |
877
881
  | `hint` | `string \| undefined` | | | Text box to be displayed near the input, usually to indicate instructions. |
878
882
  | `id` | `string \| undefined` | | | The `id` of the native control; the label's `for` and the description and message ids derive from it. Generated when omitted. |
883
+ | `inputAlign` | `'top'` \| `'center'` \| `'bottom'` | | | Vertical position of the control in a side-by-side row; not `inputPosition`, the horizontal one. Omitted, the control's first line meets the label's. |
879
884
  | `label` | `string` | | yes | Text content of the label of the element. |
885
+ | `labelAlign` | `'top'` \| `'center'` \| `'bottom'` | | | Vertical position of the label block in a side-by-side row; not `labelPosition`, the horizontal one. Omitted, the label's first line meets the control's. |
880
886
  | `labelMode` | `"outside" \| "floating" \| "inside" \| undefined` | | | Label rendering mode. |
881
887
  | `labelPosition` | `"left" \| "center" \| "right" \| undefined` | | | Sets the text alignment of the label. |
882
888
  | `layout` | `FieldLayout \| undefined` | | | How the label and the input sit together: `'vertical'`, `'horizontal'` (50/50), `'auto'`, `'label-fill'` (the label takes the free space, the input keeps its size), `'input-fill'` (the other way round), or a two-word ratio pattern like `'xx xxxxx'`. |
@@ -974,9 +980,9 @@ States are listed in precedence order: when two are on at once and their entries
974
980
  ## Slots
975
981
 
976
982
  - `append` — scope: `object` — Content rendered after the date fields, at the end of the field box (before the calendar toggle button).
977
- - `append:day` — scope: `{ first: boolean; item: Dayjs; label: string; last: boolean; middle: boolean; outside: boolean; selected: boolean; }` — Appends content below each calendar day.
978
983
  - `append:outer` — scope: `object` — Content rendered after the entire date picker control, outside the input chrome.
979
984
  - `day` — scope: `{ first: boolean; item: Dayjs; label: string; last: boolean; middle: boolean; outside: boolean; selected: boolean; }` — Replaces the day button label inside each calendar day.
985
+ - `day:append` — scope: `{ first: boolean; item: Dayjs; label: string; last: boolean; middle: boolean; outside: boolean; selected: boolean; }` — Appends content below each calendar day.
980
986
  - `description` — scope: `BbDatePickerInputDescriptionSlotProps` `{ text: string; hasErrors: boolean; hasWarnings: boolean }` — Replaces the description text. Provided alone (no `description` prop) it still renders the description region and wires it into `aria-describedby`.
981
987
  - `label` — scope: `BbDatePickerInputLabelSlotProps` `{ text: string; hasErrors: boolean; hasWarnings: boolean }` — Replaces the default label text rendered above the date picker.
982
988
  - `prefix` — scope: `object` — Inline content rendered at the start of the input field area, before the date fields.
@@ -984,7 +990,7 @@ States are listed in precedence order: when two are on at once and their entries
984
990
  - `prepend:outer` — scope: `object` — Content rendered before the entire date picker control, outside the input chrome.
985
991
  - `suffix` — scope: `object` — Inline content rendered at the end of the input field area, after the date fields.
986
992
  - `#<YYYY-MM-DD>` (named from data) — scope: `BbCalendarDaySlotProps` — One date's button label (e.g. `#2024-03-15`: the local `YYYY-MM-DD`, which `slotKey` leaves as it is); beats `day`. Day grid only.
987
- - `#append:<YYYY-MM-DD>` (named from data) — scope: `BbCalendarDaySlotProps` — Content under one date's cell; beats `append:day`.
993
+ - `#<YYYY-MM-DD>:append` (named from data) — scope: `BbCalendarDaySlotProps` — Content under one date's cell; beats `day:append`.
988
994
 
989
995
  ## CSS custom properties
990
996
 
@@ -1010,7 +1016,7 @@ Set these on the element, or on a class you put on it, to retune this component
1010
1016
  - `CommonTimeSelector` _(internal — not importable, reach it through `BbCalendar`)_ — its own pt parts (`BbCalendar`): `header` → `div.bb-time-selector__header`, `cellColumnHeader` → `div.bb-time-selector__cell-column-header`, `item` → `BbBaseButton`; documented CSS variables: `--time-mark`; also mounts `BbBaseButton`
1011
1017
  - `BbOffCanvas` _(public — [contract](./BbOffCanvas.md))_ — its own pt parts (`BbOffCanvas`): `header` → `div.bb-offcanvas__header`, `title` → `span.bb-offcanvas__title`, `description` → `p.bb-offcanvas__description`, `close` → `CloseButton`, `content` → `div.bb-offcanvas__content`, `footer` → `div.bb-offcanvas__footer`; documented CSS variables: `--stack-x`, `--stack-fill`, `--stack-transition-duration`, `--px`, `--handle-w`, `--handle-h`, `--handle-bg`, `--safe-top`, `--close-size`
1012
1018
  - `CloseButton` _(internal — not importable, reach it through `BbOffCanvas`)_ — documented CSS variables: `--size`, `--p`
1013
- - `CommonField` _(internal — not importable, reach it through `BbDatePickerInput`)_ — `BbDatePickerInput`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `message` → `div.bb-field__message`; documented CSS variables: `--ctrl-line`; also mounts `BbAsterisk`
1019
+ - `CommonField` _(internal — not importable, reach it through `BbDatePickerInput`)_ — `BbDatePickerInput`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `counter` → `span.bb-field__counter`, `message` → `div.bb-field__message`; documented CSS variables: `--ctrl-line`; also mounts `BbAsterisk`
1014
1020
  - `CommonFieldInput` _(internal — not importable, reach it through `BbDatePickerInput`)_ — `BbDatePickerInput`'s pt parts land here: `box` → `span.bb-field-input__box`, `prefix` → `span.bb-field-input__prefix`, `icon` → `BbIcon`, `clear` → `ClearableButton`, `spinner` → `BbSpinner`, `suffix` → `span.bb-field-input__suffix`; documented CSS variables: `--bg`, `--bg-hover`, `--bg-focus`, `--bg-disabled`, `--fg-disabled`, `--border-color`, `--border-focus`, `--ring-size`, `--ring-color`, `--elev`, `--frost`, `--inside-label-clearance`; also mounts `ErrorIcon`, `WarningIcon`, `ClearableButton`, `BbIcon`, `BbSpinner`
1015
1021
  - Also mounts `BbIcon`
1016
1022
 
@@ -479,8 +479,10 @@ Three rules keep dialog forms honest:
479
479
  ### Lifecycle events and lazy content
480
480
 
481
481
  Four events bracket the transitions — `show` fires as the model turns `true`,
482
- `shown` after the native `showModal()` call and initial focus, `hide` as the
483
- model turns `false`, and `hidden` after the close transition completes. Use
482
+ `shown` after the open transition completes (focus has already moved in at
483
+ `showModal()`), `hide` as the model turns `false`, and `hidden` after the close
484
+ transition completes. A surface closed before it finished opening fires no
485
+ `shown`. Use
484
486
  `@show` to (re)seed form state, `@hidden` to drop a draft and tear down
485
487
  expensive content.
486
488
 
@@ -1136,7 +1138,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
1136
1138
  | `modelValue` | `boolean \| undefined` | `false` | | Used by v-model to open / close the dialog. A dialog with no `v-model` starts closed. |
1137
1139
  | `offCanvasProps` | `Partial<BbOffCanvasProps> \| undefined` | | | Props for the phone sheet. A `pt` inside it, object or colon keys, styles only that sheet. Overrides merged over the offcanvas (mobile) surface's props. The drawer defaults to a bottom, draggable, content-sized sheet (`side: 'bottom'`, `draggable: true`, `size: 'auto'`); use this to override those, set other drawer-only options (`stackGap`), or override shared props whose meaning differs on the drawer (`stack`). Ignored on the desktop dialog surface. A `pt` inside it styles ONLY the sheet, in `BbOffCanvas`'s part words (`root`, `header`, `title`, `description`, `content`, `footer`, `close`; state `open`), object (`{ pt: { header: '…' } }`) or colon keys (`{ 'pt:header': '…' }`) alike. It merges after what this component forwards to its sheet, so it wins a conflict and drops nothing — see the passthrough guide § Inside the sheet. |
1138
1140
  | `persistent` | `boolean \| undefined` | `false` | | Prevent closing via outside clicks or Escape key. The header close (×) button STILL closes a persistent dialog — that is the documented escape hatch; combine with `hideClose` to remove it, or use `disabled` to block every dismissal. Programmatic close is still allowed. |
1139
- | `size` | `Responsive<NonNullable<number \| ({ size?: any; } & string) \| keyof BbDialogSizes \| undefined>> \| undefined` | `"sm"` | | Controls the maximum width of the dialog. Accepts named presets from `'xs'` to `'2xl'`, a custom CSS width string, or a numeric pixel value — or a per-breakpoint map (e.g. `{ default: 'sm', lg: 'lg' }`) to switch width responsively. |
1141
+ | `size` | `Responsive<NonNullable<number \| CssSize \| keyof BbDialogSizes \| undefined>> \| undefined` | `"sm"` | | Controls the maximum width of the dialog. Accepts named presets from `'xs'` to `'2xl'`, a custom CSS width string, or a numeric pixel value — or a per-breakpoint map (e.g. `{ default: 'sm', lg: 'lg' }`) to switch width responsively. |
1140
1142
  | `stack` | `string \| undefined` | | | Name of the stack this dialog belongs to. Dialogs sharing the same `stack` value replace one another: only the most recently opened stays visible while the others in the stack are hidden beneath it. Dialogs in different stacks — or with no `stack` — never affect each other and remain fully visible. |
1141
1143
  | `title` | `string \| undefined` | | | Title text announced to assistive technologies. If omitted, no header is rendered (unless a `header` slot is supplied) and accessibility must be handled manually. |
1142
1144
  | `transitionDuration` | `number \| undefined` | `250` | | Controls the duration of the open and close animations. |
@@ -1168,7 +1170,7 @@ States are listed in precedence order: when two are on at once and their entries
1168
1170
  - `hidden` — `(): void` — Emitted after the close transition completes and the dialog is fully dismissed.
1169
1171
  - `hide` — `(): void` — Emitted as soon as the dialog starts to close (model becomes false).
1170
1172
  - `show` — `(): void` — Emitted as soon as the dialog starts to open (model becomes true).
1171
- - `shown` — `(): void` — Emitted after the dialog is fully opened via `showModal()`.
1173
+ - `shown` — `(): void` — Emitted once the open transition has run (symmetric with `hidden`): the dialog is settled, so code that measures or anchors to its content sees the final layout. Not emitted for a dialog closed before it finished opening.
1172
1174
  - `update:modelValue` — `(value: boolean): void` — Emitted with the new value whenever `v-model` changes.
1173
1175
 
1174
1176
  ## Slots