bitboss-ui 3.0.0-beta.50 → 3.0.0-beta.52

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 (355) hide show
  1. package/README.md +79 -0
  2. package/bin/bitboss-ui-mcp.mjs +3 -2
  3. package/bin/bitboss-ui.mjs +25 -5
  4. package/dist/ai/BbAccordion.md +1 -1
  5. package/dist/ai/BbAlert.md +1 -1
  6. package/dist/ai/BbAsterisk.md +4 -2
  7. package/dist/ai/BbBadge.md +2 -2
  8. package/dist/ai/BbBadgeButton.md +3 -3
  9. package/dist/ai/BbBaseButton.md +8 -3
  10. package/dist/ai/BbBaseCheckboxIcon.md +48 -13
  11. package/dist/ai/BbBaseRadioIcon.md +49 -14
  12. package/dist/ai/BbBaseSwitchIcon.md +48 -13
  13. package/dist/ai/BbButton.md +6 -3
  14. package/dist/ai/BbCalendar.md +7 -5
  15. package/dist/ai/BbCheckbox.md +3 -3
  16. package/dist/ai/BbCheckboxGroup.md +8 -8
  17. package/dist/ai/BbCollapsible.md +4 -2
  18. package/dist/ai/BbColorInput.md +12 -9
  19. package/dist/ai/BbColorPalette.md +1 -1
  20. package/dist/ai/BbDatePicker.md +4 -4
  21. package/dist/ai/BbDatePickerInput.md +18 -12
  22. package/dist/ai/BbDialog.md +8 -6
  23. package/dist/ai/BbDropdown.md +10 -6
  24. package/dist/ai/BbDropdownButton.md +5 -5
  25. package/dist/ai/BbDropzone.md +4 -4
  26. package/dist/ai/BbForm.md +246 -11
  27. package/dist/ai/BbHoverCard.md +1 -1
  28. package/dist/ai/BbNumberInput.md +15 -9
  29. package/dist/ai/BbOffCanvas.md +3 -3
  30. package/dist/ai/BbPagination.md +2 -2
  31. package/dist/ai/BbPopover.md +3 -3
  32. package/dist/ai/BbProgress.md +1 -1
  33. package/dist/ai/BbRadio.md +3 -3
  34. package/dist/ai/BbRadioGroup.md +24 -16
  35. package/dist/ai/BbRating.md +3 -3
  36. package/dist/ai/BbSelect.md +16 -15
  37. package/dist/ai/BbSelectPopover.md +12 -11
  38. package/dist/ai/BbSlider.md +3 -3
  39. package/dist/ai/BbSwitch.md +3 -3
  40. package/dist/ai/BbSwitchGroup.md +8 -8
  41. package/dist/ai/BbTable.md +312 -74
  42. package/dist/ai/BbTabs.md +3 -3
  43. package/dist/ai/BbTabsRoot.md +3 -3
  44. package/dist/ai/BbTag.md +6 -6
  45. package/dist/ai/BbTextInput.md +12 -10
  46. package/dist/ai/BbTextarea.md +6 -6
  47. package/dist/ai/BbTimePicker.md +8 -4
  48. package/dist/ai/BbTimePickerInput.md +10 -9
  49. package/dist/ai/BbTooltip.md +2 -2
  50. package/dist/ai/CommonField.md +4 -4
  51. package/dist/ai/CommonFieldInput.md +2 -2
  52. package/dist/ai/CommonPopover.md +5 -5
  53. package/dist/ai/CommonTimeSelector.md +1 -1
  54. package/dist/ai/OptionsContainer.md +1 -1
  55. package/dist/ai/changelog.json +41 -3
  56. package/dist/ai/components.json +55 -52
  57. package/dist/ai/composables/useBbFormField.md +44 -10
  58. package/dist/ai/guides/agent-contract.md +4 -1
  59. package/dist/ai/guides/ai-router.md +23 -23
  60. package/dist/ai/guides/component-picker.md +4 -3
  61. package/dist/ai/guides/design-language.md +4 -2
  62. package/dist/ai/guides/installation-and-plugin-setup.md +34 -2
  63. package/dist/ai/guides/migration/components/bb-table.md +32 -31
  64. package/dist/ai/guides/migration/from-async-validator.md +1252 -0
  65. package/dist/ai/guides/migration/v2-to-v3.md +36 -0
  66. package/dist/ai/guides/migration/v3-beta-tooling.md +14 -9
  67. package/dist/ai/guides/passthrough.md +2 -2
  68. package/dist/ai/guides/validated-forms.md +78 -5
  69. package/dist/ai/guides/validation-libraries.md +5 -0
  70. package/dist/ai/helpers/inertia/manifest.json +1 -1
  71. package/dist/ai/index.md +2 -1
  72. package/dist/ai/manifest/components/BbAccordion.json +1 -1
  73. package/dist/ai/manifest/components/BbAlert.json +1 -5
  74. package/dist/ai/manifest/components/BbAlert.removed.json +7 -0
  75. package/dist/ai/manifest/components/BbAvatar.json +0 -3
  76. package/dist/ai/manifest/components/BbAvatar.removed.json +6 -0
  77. package/dist/ai/manifest/components/BbBadge.json +2 -5
  78. package/dist/ai/manifest/components/BbBadge.removed.json +6 -0
  79. package/dist/ai/manifest/components/BbBadgeButton.json +3 -3
  80. package/dist/ai/manifest/components/BbBaseButton.json +3 -3
  81. package/dist/ai/manifest/components/BbBaseCheckboxIcon.json +0 -3
  82. package/dist/ai/manifest/components/BbBaseCheckboxIcon.removed.json +6 -0
  83. package/dist/ai/manifest/components/BbBaseRadioIcon.json +0 -3
  84. package/dist/ai/manifest/components/BbBaseRadioIcon.removed.json +6 -0
  85. package/dist/ai/manifest/components/BbBaseSwitchIcon.json +0 -3
  86. package/dist/ai/manifest/components/BbBaseSwitchIcon.removed.json +6 -0
  87. package/dist/ai/manifest/components/BbBreadcrumbs.json +0 -4
  88. package/dist/ai/manifest/components/BbBreadcrumbs.removed.json +7 -0
  89. package/dist/ai/manifest/components/BbButton.json +2 -9
  90. package/dist/ai/manifest/components/BbButton.removed.json +10 -0
  91. package/dist/ai/manifest/components/BbCalendar.json +4 -9
  92. package/dist/ai/manifest/components/BbCalendar.removed.json +8 -0
  93. package/dist/ai/manifest/components/BbCheckbox.json +3 -10
  94. package/dist/ai/manifest/components/BbCheckbox.removed.json +10 -0
  95. package/dist/ai/manifest/components/BbCheckboxGroup.json +8 -19
  96. package/dist/ai/manifest/components/BbCheckboxGroup.removed.json +14 -0
  97. package/dist/ai/manifest/components/BbCollapsible.json +1 -1
  98. package/dist/ai/manifest/components/BbColorInput.json +8 -17
  99. package/dist/ai/manifest/components/BbColorInput.removed.json +12 -0
  100. package/dist/ai/manifest/components/BbColorPalette.json +1 -11
  101. package/dist/ai/manifest/components/BbColorPalette.removed.json +13 -0
  102. package/dist/ai/manifest/components/BbDatePicker.json +4 -10
  103. package/dist/ai/manifest/components/BbDatePicker.removed.json +9 -0
  104. package/dist/ai/manifest/components/BbDatePickerInput.json +9 -24
  105. package/dist/ai/manifest/components/BbDatePickerInput.removed.json +18 -0
  106. package/dist/ai/manifest/components/BbDialog.json +5 -12
  107. package/dist/ai/manifest/components/BbDialog.removed.json +10 -0
  108. package/dist/ai/manifest/components/BbDropdown.json +6 -15
  109. package/dist/ai/manifest/components/BbDropdown.removed.json +12 -0
  110. package/dist/ai/manifest/components/BbDropdownButton.json +5 -15
  111. package/dist/ai/manifest/components/BbDropdownButton.removed.json +13 -0
  112. package/dist/ai/manifest/components/BbDropzone.json +4 -9
  113. package/dist/ai/manifest/components/BbDropzone.removed.json +8 -0
  114. package/dist/ai/manifest/components/BbForm.json +5 -8
  115. package/dist/ai/manifest/components/BbForm.removed.json +6 -0
  116. package/dist/ai/manifest/components/BbHoverCard.json +1 -1
  117. package/dist/ai/manifest/components/BbIcon.json +0 -4
  118. package/dist/ai/manifest/components/BbIcon.removed.json +7 -0
  119. package/dist/ai/manifest/components/BbNumberInput.json +9 -17
  120. package/dist/ai/manifest/components/BbNumberInput.removed.json +11 -0
  121. package/dist/ai/manifest/components/BbOffCanvas.json +3 -8
  122. package/dist/ai/manifest/components/BbOffCanvas.removed.json +8 -0
  123. package/dist/ai/manifest/components/BbPagination.json +2 -8
  124. package/dist/ai/manifest/components/BbPagination.removed.json +9 -0
  125. package/dist/ai/manifest/components/BbPopover.json +3 -16
  126. package/dist/ai/manifest/components/BbPopover.removed.json +16 -0
  127. package/dist/ai/manifest/components/BbProgress.json +1 -1
  128. package/dist/ai/manifest/components/BbRadio.json +3 -8
  129. package/dist/ai/manifest/components/BbRadio.removed.json +8 -0
  130. package/dist/ai/manifest/components/BbRadioGroup.json +9 -20
  131. package/dist/ai/manifest/components/BbRadioGroup.removed.json +14 -0
  132. package/dist/ai/manifest/components/BbRating.json +3 -10
  133. package/dist/ai/manifest/components/BbRating.removed.json +10 -0
  134. package/dist/ai/manifest/components/BbSelect.json +14 -27
  135. package/dist/ai/manifest/components/BbSelect.removed.json +16 -0
  136. package/dist/ai/manifest/components/BbSelectPopover.json +10 -20
  137. package/dist/ai/manifest/components/BbSelectPopover.removed.json +13 -0
  138. package/dist/ai/manifest/components/BbSlider.json +3 -12
  139. package/dist/ai/manifest/components/BbSlider.removed.json +12 -0
  140. package/dist/ai/manifest/components/BbSpinner.json +0 -3
  141. package/dist/ai/manifest/components/BbSpinner.removed.json +6 -0
  142. package/dist/ai/manifest/components/BbSwitch.json +3 -10
  143. package/dist/ai/manifest/components/BbSwitch.removed.json +10 -0
  144. package/dist/ai/manifest/components/BbSwitchGroup.json +8 -19
  145. package/dist/ai/manifest/components/BbSwitchGroup.removed.json +14 -0
  146. package/dist/ai/manifest/components/BbTable.json +23 -32
  147. package/dist/ai/manifest/components/BbTable.removed.json +16 -0
  148. package/dist/ai/manifest/components/BbTable.tree.json +19 -1
  149. package/dist/ai/manifest/components/BbTabs.json +3 -12
  150. package/dist/ai/manifest/components/BbTabs.removed.json +12 -0
  151. package/dist/ai/manifest/components/BbTabsList.json +0 -5
  152. package/dist/ai/manifest/components/BbTabsList.removed.json +8 -0
  153. package/dist/ai/manifest/components/BbTabsRoot.json +3 -13
  154. package/dist/ai/manifest/components/BbTabsRoot.removed.json +13 -0
  155. package/dist/ai/manifest/components/BbTag.json +6 -16
  156. package/dist/ai/manifest/components/BbTag.removed.json +13 -0
  157. package/dist/ai/manifest/components/BbTextInput.json +8 -19
  158. package/dist/ai/manifest/components/BbTextInput.removed.json +14 -0
  159. package/dist/ai/manifest/components/BbTextarea.json +6 -14
  160. package/dist/ai/manifest/components/BbTextarea.removed.json +11 -0
  161. package/dist/ai/manifest/components/BbTimePicker.json +3 -3
  162. package/dist/ai/manifest/components/BbTimePickerInput.json +8 -16
  163. package/dist/ai/manifest/components/BbTimePickerInput.removed.json +11 -0
  164. package/dist/ai/manifest/components/BbToast.json +0 -6
  165. package/dist/ai/manifest/components/BbToast.removed.json +9 -0
  166. package/dist/ai/manifest/components/BbTooltip.json +2 -8
  167. package/dist/ai/manifest/components/BbTooltip.removed.json +9 -0
  168. package/dist/ai/manifest/components/BbTree.json +0 -5
  169. package/dist/ai/manifest/components/BbTree.removed.json +8 -0
  170. package/dist/ai/manifest/components/CommonField.json +4 -4
  171. package/dist/ai/manifest/components/CommonFieldInput.json +2 -2
  172. package/dist/ai/manifest/components/CommonPopover.json +5 -5
  173. package/dist/ai/manifest/components/CommonTimeSelector.json +1 -1
  174. package/dist/ai/manifest/components/OptionsContainer.json +1 -1
  175. package/dist/ai/manifest/index.json +6 -5
  176. package/dist/ai/manifest/meta.json +51 -1
  177. package/dist/ai/manifest/types.advanced.json +2 -2
  178. package/dist/ai/recipes/inertia/record-form.md +15 -7
  179. package/dist/ai/recipes/nuxt/record-form.md +1 -0
  180. package/dist/ai/recipes/vue/record-form.md +1 -0
  181. package/dist/ai/source/BbAccordion.md +4 -5
  182. package/dist/ai/source/BbAlert.md +3 -6
  183. package/dist/ai/source/BbBadge.md +6 -14
  184. package/dist/ai/source/BbBadgeButton.md +6 -14
  185. package/dist/ai/source/BbBaseButton.md +11 -25
  186. package/dist/ai/source/BbButton.md +8 -17
  187. package/dist/ai/source/BbCalendar.md +14 -29
  188. package/dist/ai/source/BbCheckbox.md +7 -10
  189. package/dist/ai/source/BbCheckboxGroup.md +42 -69
  190. package/dist/ai/source/BbCollapsible.md +2 -7
  191. package/dist/ai/source/BbColorInput.md +21 -51
  192. package/dist/ai/source/BbColorPalette.md +4 -18
  193. package/dist/ai/source/BbDatePicker.md +15 -43
  194. package/dist/ai/source/BbDatePickerInput.md +26 -60
  195. package/dist/ai/source/BbDialog.md +16 -47
  196. package/dist/ai/source/BbDropdown.md +70 -54
  197. package/dist/ai/source/BbDropdownButton.md +4 -8
  198. package/dist/ai/source/BbDropdownGroup.md +22 -46
  199. package/dist/ai/source/BbDropzone.md +11 -16
  200. package/dist/ai/source/BbForm.md +19 -46
  201. package/dist/ai/source/BbHoverCard.md +3 -5
  202. package/dist/ai/source/BbHoverCardPortal.md +3 -5
  203. package/dist/ai/source/BbNumberInput.md +43 -46
  204. package/dist/ai/source/BbOffCanvas.md +11 -21
  205. package/dist/ai/source/BbPagination.md +7 -15
  206. package/dist/ai/source/BbPopover.md +27 -28
  207. package/dist/ai/source/BbPopoverPortal.md +11 -28
  208. package/dist/ai/source/BbProgress.md +3 -4
  209. package/dist/ai/source/BbRadio.md +10 -16
  210. package/dist/ai/source/BbRadioGroup.md +78 -76
  211. package/dist/ai/source/BbRating.md +7 -10
  212. package/dist/ai/source/BbSelect.md +45 -112
  213. package/dist/ai/source/BbSelectPopover.md +35 -101
  214. package/dist/ai/source/BbSlider.md +7 -10
  215. package/dist/ai/source/BbSwitchGroup.md +48 -13
  216. package/dist/ai/source/BbTable.md +722 -293
  217. package/dist/ai/source/BbTabs.md +12 -30
  218. package/dist/ai/source/BbTabsList.md +12 -30
  219. package/dist/ai/source/BbTabsPanels.md +12 -30
  220. package/dist/ai/source/BbTabsRoot.md +12 -30
  221. package/dist/ai/source/BbTag.md +15 -28
  222. package/dist/ai/source/BbTextInput.md +21 -36
  223. package/dist/ai/source/BbTextarea.md +16 -30
  224. package/dist/ai/source/BbTimePicker.md +12 -28
  225. package/dist/ai/source/BbTimePickerInput.md +25 -51
  226. package/dist/ai/source/BbTooltip.md +6 -14
  227. package/dist/ai/source/CommonField.md +14 -21
  228. package/dist/ai/source/CommonFieldInput.md +7 -8
  229. package/dist/ai/source/CommonPopover.md +18 -28
  230. package/dist/ai/source/CommonTimeSelector.md +4 -5
  231. package/dist/ai/source/OptionsContainer.md +4 -7
  232. package/dist/components/BbAccordion/types.d.ts +4 -5
  233. package/dist/components/BbAlert/types.d.ts +3 -6
  234. package/dist/components/BbBadge/types.d.ts +6 -14
  235. package/dist/components/BbBaseButton/types.d.ts +11 -25
  236. package/dist/components/BbButton/types.d.ts +8 -17
  237. package/dist/components/BbCalendar/CalendarMonthPanel.vue_vue_type_script_setup_true_lang.js +64 -62
  238. package/dist/components/BbCalendar/types.d.ts +14 -29
  239. package/dist/components/BbCalendar/useDayGrid.js +131 -130
  240. package/dist/components/BbCheckbox/types.d.ts +7 -10
  241. package/dist/components/BbCheckboxGroup/types.d.ts +28 -58
  242. package/dist/components/BbCollapsible/types.d.ts +2 -7
  243. package/dist/components/BbColorInput/types.d.ts +21 -51
  244. package/dist/components/BbColorPalette/types.d.ts +4 -18
  245. package/dist/components/BbDatePicker/types.d.ts +15 -43
  246. package/dist/components/BbDatePickerInput/types.d.ts +26 -60
  247. package/dist/components/BbDialog/types.d.ts +16 -47
  248. package/dist/components/BbDropdown/AdaptiveDropdown.vue_vue_type_script_setup_true_lang.js +6 -3
  249. package/dist/components/BbDropdown/BbDropdown.vue_vue_type_script_setup_true_lang.js +267 -261
  250. package/dist/components/BbDropdown/BbDropdownList.vue.d.ts +2 -2
  251. package/dist/components/BbDropdown/BbDropdownList.vue_vue_type_script_setup_true_lang.js +298 -301
  252. package/dist/components/BbDropdown/types.d.ts +22 -46
  253. package/dist/components/BbDropdown/useDropdownContext.d.ts +2 -0
  254. package/dist/components/BbDropdownButton/types.d.ts +4 -8
  255. package/dist/components/BbDropzone/types.d.ts +11 -16
  256. package/dist/components/BbForm/BbForm.vue.d.ts +19 -46
  257. package/dist/components/BbForm/BbFormCustomField.js +40 -34
  258. package/dist/components/BbForm/bindFormField.d.ts +16 -2
  259. package/dist/components/BbForm/bindFormField.js +53 -53
  260. package/dist/components/BbHoverCard/types.d.ts +3 -5
  261. package/dist/components/BbNumberInput/BbNumberInput.vue_vue_type_script_setup_true_lang.js +137 -134
  262. package/dist/components/BbNumberInput/platform.d.ts +7 -0
  263. package/dist/components/BbNumberInput/platform.js +7 -0
  264. package/dist/components/BbNumberInput/types.d.ts +28 -45
  265. package/dist/components/BbOffCanvas/types.d.ts +11 -21
  266. package/dist/components/BbPagination/types.d.ts +7 -15
  267. package/dist/components/BbPopover/BbPopover.vue_vue_type_script_setup_true_lang.js +23 -20
  268. package/dist/components/BbPopover/types.d.ts +11 -28
  269. package/dist/components/BbProgress/types.d.ts +3 -4
  270. package/dist/components/BbRadio/types.d.ts +10 -16
  271. package/dist/components/BbRadioGroup/types.d.ts +30 -63
  272. package/dist/components/BbRating/types.d.ts +7 -10
  273. package/dist/components/BbSelect/types.d.ts +45 -112
  274. package/dist/components/BbSelectPopover/types.d.ts +35 -101
  275. package/dist/components/BbSlider/types.d.ts +7 -10
  276. package/dist/components/BbTable/BbTable.vue.d.ts +5 -6
  277. package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +1070 -953
  278. package/dist/components/BbTable/BbTableDataRow.d.ts +6 -0
  279. package/dist/components/BbTable/BbTableDataRow.js +67 -29
  280. package/dist/components/BbTable/BbTableEdgeRow.d.ts +2 -0
  281. package/dist/components/BbTable/BbTableEdgeRow.js +2 -2
  282. package/dist/components/BbTable/types.d.ts +97 -179
  283. package/dist/components/BbTable/types.js +1 -0
  284. package/dist/components/BbTable/useRowReorder.d.ts +60 -0
  285. package/dist/components/BbTable/useRowReorder.js +429 -0
  286. package/dist/components/BbTable/utils.d.ts +9 -1
  287. package/dist/components/BbTable/utils.js +33 -29
  288. package/dist/components/BbTable/warroom/harness.d.ts +253 -0
  289. package/dist/components/BbTabs/types.d.ts +12 -30
  290. package/dist/components/BbTag/types.d.ts +15 -28
  291. package/dist/components/BbTextInput/types.d.ts +21 -36
  292. package/dist/components/BbTextarea/types.d.ts +16 -30
  293. package/dist/components/BbTimePicker/types.d.ts +12 -28
  294. package/dist/components/BbTimePickerInput/types.d.ts +25 -51
  295. package/dist/components/BbTooltip/types.d.ts +6 -14
  296. package/dist/components/CommonField/types.d.ts +14 -21
  297. package/dist/components/CommonFieldInput/types.d.ts +7 -8
  298. package/dist/components/CommonPopover/types.d.ts +18 -28
  299. package/dist/components/CommonTimeSelector/CommonTimeSelector.vue.d.ts +4 -5
  300. package/dist/components/OptionsContainer/types.d.ts +4 -7
  301. package/dist/composables/useBbFormField.d.ts +9 -0
  302. package/dist/composables/useBbFormField.js +1 -0
  303. package/dist/composables/useBbTableContext.js +1 -0
  304. package/dist/composables/useFormBinding.d.ts +5 -8
  305. package/dist/i18n/locales/cs.json +8 -1
  306. package/dist/i18n/locales/da.json +8 -1
  307. package/dist/i18n/locales/de-CH.json +8 -1
  308. package/dist/i18n/locales/de.json +8 -1
  309. package/dist/i18n/locales/el.json +8 -1
  310. package/dist/i18n/locales/en-GB.json +8 -1
  311. package/dist/i18n/locales/en.json +8 -1
  312. package/dist/i18n/locales/es-MX.json +8 -1
  313. package/dist/i18n/locales/es.json +8 -1
  314. package/dist/i18n/locales/fi.json +8 -1
  315. package/dist/i18n/locales/fr.json +8 -1
  316. package/dist/i18n/locales/hu.json +8 -1
  317. package/dist/i18n/locales/it.json +8 -1
  318. package/dist/i18n/locales/ja.json +8 -1
  319. package/dist/i18n/locales/ko.json +8 -1
  320. package/dist/i18n/locales/nb.json +8 -1
  321. package/dist/i18n/locales/nl.json +8 -1
  322. package/dist/i18n/locales/pl.json +8 -1
  323. package/dist/i18n/locales/pt-BR.json +8 -1
  324. package/dist/i18n/locales/pt-PT.json +8 -1
  325. package/dist/i18n/locales/ro.json +8 -1
  326. package/dist/i18n/locales/ru.json +8 -1
  327. package/dist/i18n/locales/sv.json +8 -1
  328. package/dist/i18n/locales/tr.json +8 -1
  329. package/dist/i18n/locales/uk.json +8 -1
  330. package/dist/i18n/locales/zh-CN.json +8 -1
  331. package/dist/i18n/locales/zh-HK.json +8 -1
  332. package/dist/i18n/locales/zh-TW.json +8 -1
  333. package/dist/llms-full.txt +2520 -434
  334. package/dist/llms-medium.txt +69 -31
  335. package/dist/llms.txt +3 -2
  336. package/dist/locale-blueprint.json +8 -1
  337. package/dist/styles.css +2 -2
  338. package/dist/types/ptComponentMap.d.ts +1 -1
  339. package/dist/utilities/functions/toggleInput.d.ts +1 -1
  340. package/dist/utilities/functions/toggleInput.js +2 -2
  341. package/dist/utils/focusVisibility.d.ts +9 -0
  342. package/dist/utils/focusVisibility.js +12 -0
  343. package/dist/utils/versionCheck.js +1 -1
  344. package/llms.txt +3 -2
  345. package/package.json +3 -2
  346. package/scripts/lib/agent-manifest.mjs +44 -11
  347. package/scripts/lib/collapsible-trigger-aria.mjs +116 -0
  348. package/scripts/lib/dropdown-default-slot.mjs +118 -0
  349. package/scripts/lib/eslint-disable.mjs +6 -0
  350. package/scripts/lib/eslint-plugin.d.ts +7 -1
  351. package/scripts/lib/eslint-plugin.mjs +309 -0
  352. package/scripts/lib/project-variant-dts.mjs +79 -15
  353. package/scripts/lib/recipe-excerpts.mjs +98 -0
  354. package/scripts/lib/required-in-form.mjs +240 -0
  355. package/scripts/lib/validate-bb-markup.mjs +16 -0
@@ -235,7 +235,9 @@ plus seconds with `seconds` and an AM/PM column with `ampm`; `step` sets the
235
235
  minute granularity. With `floating` the day stays plain and the time travels
236
236
  only through `v-model:time` (`HH:mm` / `HH:mm:ss`); otherwise the time lives
237
237
  inside `modelValue` and `time` mirrors it. In `range` + `datetime`
238
- `v-model:active-segment` says which end the rail edits.
238
+ `v-model:active-segment` says which end the rail edits. A `min` / `max` with
239
+ a time (`YYYY-MM-DDTHH:mm`) disables the days outside it and, on its own day,
240
+ the times before `min` / after `max` on the rail.
239
241
 
240
242
  The calendar takes its natural width (grid plus rail, about 335px; wider with
241
243
  seconds or AM/PM) or the room it is given, whichever is less. When its own box
@@ -594,16 +596,16 @@ the page is `BbDatePicker`.
594
596
  | `firstDayOfWeek` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| undefined` | `the locale's week start` | | First day of the week (0 = Sunday … 6 = Saturday). Omitted, the active locale's week start: Monday for `it`, `de`, `fr`, `en-gb`…, Sunday for bare `en` (US) and `pt` (Brazil). |
595
597
  | `floating` | `boolean \| undefined` | `false` | | Emit plain calendar strings instead of zoned ISO instants. Implied (and forced) by `type="month"` and `type="year"`. |
596
598
  | `max` | `string \| undefined` | | | Maximum selectable value, in this `type`'s shape. A finer bound is accepted and ceiled to the unit, with a warning. With `datetime`, on its own day the time rail disables the times after it. |
597
- | `min` | `string \| undefined` | | | Minimum selectable value, in this `type`'s shape — `YYYY-MM-DD` (`YYYY-MM-DDTHH:mm` with `datetime`, `YYYY-MM` with `month`, `YYYY` with `year`). A finer bound is accepted and floored to the unit, with a warning. With `datetime`, the grid disables the days before it and, on its own day, the time rail disables the times before it. |
598
- | `modelValue` | `string \| string[] \| null` | | yes | v-model value. `null` for empty, a single string for single selection, or a two-element `[start, end]` array when `range` is true (a sorted array under `multiple`). The string shape follows `type`: `YYYY-MM-DD` when `floating` (`YYYY-MM` for `month`, `YYYY` for `year`), otherwise a zoned ISO instant carrying the time inline with `type="datetime"`. |
599
- | `multiple` | `boolean \| undefined` | `false` | | Enables multi-selection: every pick toggles a value in or out of a sorted array. Works in whatever `type` selects — days, months or years — and requires an array `modelValue` (use `[]` for empty, never `null`). Mutually exclusive with `range` (two different selection models) and with `type="datetime"` (the time rail edits one value; with several there is no one it could mean). Both combinations throw. |
599
+ | `min` | `string \| undefined` | | | Minimum selectable value in this `type`'s shape (`YYYY-MM-DD`; `YYYY-MM-DDTHH:mm` with `datetime`, `YYYY-MM` with `month`, `YYYY` with `year`). A finer bound is floored to the unit, with a warning. With `datetime` the rail also disables the earlier times on its day. |
600
+ | `modelValue` | `string \| string[] \| null` | | yes | v-model: `null` when empty, a string, a `[start, end]` pair with `range`, or a sorted array with `multiple`. The string is `YYYY-MM-DD` when `floating` (`YYYY-MM` / `YYYY` for `month` / `year`), otherwise a zoned ISO instant (carrying the time under `datetime`). |
601
+ | `multiple` | `boolean \| undefined` | `false` | | Multi-selection: each pick toggles a value in a sorted array (days, months or years). Needs an array `modelValue` (`[]` when empty, never `null`). Throws with `range` or `type="datetime"`. |
600
602
  | `range` | `boolean \| undefined` | `false` | | Enables range selection (`[start, end]`). |
601
603
  | `readonly` | `boolean \| undefined` | `false` | | Shows the calendar and lets the user page through it, but no pick changes the value. |
602
604
  | `seconds` | `boolean \| undefined` | `false` | | Adds the seconds column (requires `type="datetime"`). |
603
605
  | `selectable` | `((date: string) => boolean) \| undefined` | | | Predicate invoked per candidate; return `false` to disable it. Receives the value in this `type`'s shape — `YYYY-MM` under `month`, `YYYY` under `year`. |
604
606
  | `step` | `number \| undefined` | `1` | | Minute-column granularity and arrow stepping (requires `type="datetime"`). |
605
607
  | `time` | `string \| string[] \| null \| undefined` | | | Companion time model (`v-model:time`), 24-hour `HH:mm` / `HH:mm:ss`. With `floating` it is the only carrier of the time; otherwise it mirrors the time inside `modelValue`. Requires `type="datetime"`. |
606
- | `type` | `'date'` \| `'month'` \| `'year'` \| `'datetime'` | `"date"` | | What the calendar selects, and therefore what it emits. - `date` (default) — a day. - `datetime` — a day plus a time rail beside the grid. Non-floating values carry the time inside `modelValue`; with `floating` the time travels only through `time`. - `month` — a month grid emitting `YYYY-MM`. - `year` — a year list emitting `YYYY`. `month`/`year` are calendar labels, not instants: they force `floating` and ignore `utc`, and the time props (`seconds`, `ampm`, `step`, `time`) are inert outside `datetime`. |
608
+ | `type` | `'date'` \| `'month'` \| `'year'` \| `'datetime'` | `"date"` | | What the calendar selects and emits: `date` (a day), `datetime` (a day plus a time rail), `month` (`YYYY-MM`) or `year` (`YYYY`). `month` / `year` force `floating`, ignore `utc`, and leave the time props inert. |
607
609
  | `utc` | `boolean \| undefined` | `false` | | Emit UTC (`...Z`) instead of the local offset. Ignored with `floating`, and therefore with `type="month"`/`type="year"`. |
608
610
 
609
611
  ## Passthrough parts and states
@@ -695,7 +695,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
695
695
  | `compact` | `boolean \| undefined` | `false` | | Compact density. Swaps `--bb-label-spacing-y` for `--bb-label-spacing-y-compact`, so tune a compact field's label gap with the `-compact` token, not the base one. The same meaning as on the checkbox, radio and switch groups. |
696
696
  | `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`). |
697
697
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component. |
698
- | `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. |
698
+ | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or string array. They render in an `aria-live="polite"` region and are referenced first from the control's `aria-describedby`, so they are re-read when it regains focus. |
699
699
  | `falseValue` | `any` | | | Value of the input when unchecked. It handles any kind of serializable object. |
700
700
  | `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). |
701
701
  | `hasErrors` | `boolean \| undefined` | `false` | | Define if the component should be in an error state. It usually attaches a CSS class for styling purposes. |
@@ -720,8 +720,8 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
720
720
  | `submitWhenFalse` | `boolean \| undefined` | `false` | | Will submit "falseValue" if the input is not checked. Otherwise "trueValue" will be submitted. |
721
721
  | `trueValue` | `any` | | | Value of the input when checked. It handles any kind of serializable object. |
722
722
  | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; the field's `name` never shows. Set it when the label is not a good noun for a sentence (an icon-only label, a question) or is hidden. Only inside a `BbForm`. |
723
- | `validationMode` | `ValidationMode \| undefined` | | | When this field checks itself while the user works: `aggressive` (every change), `balanced` (on leave, then every change while it shows an error), `lazy` (on leave only), `submit-only` (on submit only) or `submit-live` (on submit, then every change while it shows an error). "Leave" is blur for a text-like control, and focus leaving the whole control for a picker or a group; a checkbox or switch commits on click. Unset, the enclosing `BbForm`'s `validation-mode` applies, then the app's `formControls.validationMode` (`'balanced'`). Only inside a `BbForm`. |
724
- | `warnings` | `string \| string[] \| undefined` | | | Warning messages to display beneath the field, in their own `aria-live` region and amber (`--bb-text-warn`). A string or array; a non-empty list implies the warning state. Errors suppress warnings when both are set. While displayed they are also referenced from the control's `aria-describedby`, after any errors and before the description/hint. |
723
+ | `validationMode` | `ValidationMode \| undefined` | | | When this field validates as the user works: `aggressive` (every change), `balanced` (on leave, then live while it shows an error), `lazy` (on leave), `submit-only` or `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). Only in a `BbForm`. |
724
+ | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the field, a string or string array: amber, in their own `aria-live` region, and in the control's `aria-describedby` after the errors. A non-empty list implies the warning state; errors win when both are set. |
725
725
 
726
726
  ## Passthrough parts and states
727
727
 
@@ -979,8 +979,8 @@ for a preset that fits any row type (never `<any>`), not an imported
979
979
  | `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`). |
980
980
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component. |
981
981
  | `emptyText` | `string \| undefined` | | | String displayed when there are no items to display. |
982
- | `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. |
983
- | `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. |
982
+ | `enforceCoherence` | `boolean \| undefined` | `false` | | After every applied, successful load (an empty one included), drops the model values the options no longer contain (a single value resets to `null`). A failed load never prunes. |
983
+ | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or string array. They render in an `aria-live="polite"` region and are referenced first from the control's `aria-describedby`, so they are re-read when it regains focus. |
984
984
  | `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
985
  | `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
986
  | `hasErrors` | `boolean \| undefined` | `false` | | Define if the component should be in an error state. It usually attaches a CSS class for styling purposes. |
@@ -993,10 +993,10 @@ for a preset that fits any row type (never `<any>`), not an imported
993
993
  | `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. |
994
994
  | `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. |
995
995
  | `itemLabelAlign` | `'top'` \| `'center'` \| `'bottom'` | | | Vertical position of each option's label in its row. Omitted, it stays as it is. |
996
- | `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. |
997
- | `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`. |
996
+ | `itemLayout` | `FieldLayout \| undefined` | `'auto'` | | How each row's input and label sit together, in the `layout` keywords: `'auto'`, `'vertical'`, `'horizontal'`, `'label-fill'`, `'input-fill'`, or a two-word ratio pattern like `'xx xxxxx'`. |
997
+ | `itemProps` | `BbOptionGroupItemProps<T> \| undefined` | | | ADDITIONAL row fields, never the text or value: `description`, a muted line under the label (it may wrap; announced as the option's description). An object of paths or getters, or a function of the item; nothing is read implicitly. |
998
998
  | `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. |
999
- | `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). |
999
+ | `items` | `T[] \| ((context: BbCheckboxGroupItemsContext) => T[] \| Promise<T[]>)` | | yes | The options: an array, or a provider called with a `BbCheckboxGroupItemsContext` (`BbSwitchGroupItemsContext` on a switch group) (`reason`, `modelValue`, `signal`), sync or async. A provider fails by THROWING, never by returning `[]`: the rows clear and `#empty` gets the `error`. |
1000
1000
  | `itemText` | `ItemAccessor<T, string> \| undefined` | `own `label`, else `text`, else `JSON.stringify(item)`` | | Defines a path that returns a property of the object to use as text or a function that returns a string. Unset: own `label`, else `text` (`{ label, value }` needs no accessor). |
1001
1001
  | `itemValue` | `ItemAccessor<T> \| undefined` | `own `value`, else the whole item` | | Defines a path that returns a property of the object to use as value or a function that returns any value. Unset: own `value`, even `null`. |
1002
1002
  | `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. |
@@ -1004,7 +1004,7 @@ for a preset that fits any row type (never `<any>`), not an imported
1004
1004
  | `legend` | `string` | | yes | Text content of the legend. |
1005
1005
  | `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. |
1006
1006
  | `legendPosition` | `"left" \| "center" \| "right" \| undefined` | | | Sets the text alignment of the label. |
1007
- | `listLayout` | `'horizontal'` \| `'vertical'` \| `'vertical-stretch'` \| `'tiles'` | `'horizontal'` | | How the rows sit inside the list: `'horizontal'` (on a line, wrapping, each row its own size), `'vertical'` (stacked, each row its own size), `'vertical-stretch'` (stacked, each row as wide as the list) or `'tiles'` (equal-size boxes, wrapping onto new lines as the field narrows; `--tile-min-width` on `pt:list` sets how narrow a tile gets). |
1007
+ | `listLayout` | `'horizontal'` \| `'vertical'` \| `'vertical-stretch'` \| `'tiles'` | `'horizontal'` | | How the rows sit in the list: `'horizontal'` (on a line, wrapping), `'vertical'` (stacked), `'vertical-stretch'` (stacked, as wide as the list) or `'tiles'` (equal boxes; `--tile-min-width` on `pt:list` sets the narrowest). |
1008
1008
  | `loadingText` | `string \| undefined` | | | String displayed while items are being loaded. |
1009
1009
  | `max` | `number \| undefined` | | | Maximum number of selected items. |
1010
1010
  | `modelValue` | `any` | | | Used by v-model. Can be an array of any serializable type. |
@@ -1017,8 +1017,8 @@ for a preset that fits any row type (never `<any>`), not an imported
1017
1017
  | `rules` | `RuleExpression<any>` | | | vee-validate rules for this field. Only inside a `BbForm`. |
1018
1018
  | `selectable` | `boolean \| ((item: T) => boolean) \| undefined` | `true` | | Defines whether options are selectable. Can be a global boolean that affects all options or a function that accepts an item and returns a boolean that only affects that item. Non-selectable options are rendered disabled. |
1019
1019
  | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; the field's `name` never shows. Set it when the label is not a good noun for a sentence (an icon-only label, a question) or is hidden. Only inside a `BbForm`. |
1020
- | `validationMode` | `'aggressive'` \| `'balanced'` \| `'lazy'` \| `'submit-only'` \| `'submit-live'` | | | When this field checks itself while the user works: `aggressive` (every change), `balanced` (on leave, then every change while it shows an error), `lazy` (on leave only), `submit-only` (on submit only) or `submit-live` (on submit, then every change while it shows an error). "Leave" is blur for a text-like control, and focus leaving the whole control for a picker or a group; a checkbox or switch commits on click. Unset, the enclosing `BbForm`'s `validation-mode` applies, then the app's `formControls.validationMode` (`'balanced'`). Only inside a `BbForm`. |
1021
- | `warnings` | `string \| string[] \| undefined` | | | Warning messages to display beneath the field, in their own `aria-live` region and amber (`--bb-text-warn`). A string or array; a non-empty list implies the warning state. Errors suppress warnings when both are set. While displayed they are also referenced from the control's `aria-describedby`, after any errors and before the description/hint. |
1020
+ | `validationMode` | `'aggressive'` \| `'balanced'` \| `'lazy'` \| `'submit-only'` \| `'submit-live'` | | | When this field validates as the user works: `aggressive` (every change), `balanced` (on leave, then live while it shows an error), `lazy` (on leave), `submit-only` or `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). Only in a `BbForm`. |
1021
+ | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the field, a string or string array: amber, in their own `aria-live` region, and in the control's `aria-describedby` after the errors. A non-empty list implies the warning state; errors win when both are set. |
1022
1022
 
1023
1023
  ## Passthrough parts and states
1024
1024
 
@@ -503,7 +503,9 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
503
503
  - **Don't skip the trigger ARIA** — the component only manages
504
504
  `aria-hidden`/`inert` on its content; `aria-expanded`/`aria-controls` on the
505
505
  trigger (and a `role="region"` if you want one) are yours — or use
506
- `BbAccordion`, which wires all of it.
506
+ `BbAccordion`, which wires all of it. A trigger with
507
+ `@click="open = !open"` and no `aria-expanded` is reported by
508
+ `bitboss-ui/collapsible-trigger-aria` and `check`.
507
509
  - **Don't use it as a pure height animator** — if nothing is ever hidden,
508
510
  `BbSmoothHeight` is the right tool.
509
511
  - **Initialize the model** — an omitted or `undefined` binding silently
@@ -526,7 +528,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
526
528
  | --- | --- | --- | --- | --- |
527
529
  | `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: `content`, `root`. States: `open`. 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 `BbCollapsibleProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
528
530
  | `eager` | `boolean \| undefined` | `false` | | Renders the content at mount, while closed, instead of on the first open. Closed content is `inert` and `aria-hidden` either way. |
529
- | `modelValue` | `boolean \| undefined` | `false` | | Used by v-model to trigger opening / closing the collapsible. Optional, matching the runtime: `withDefaults` supplies `false`, so an omitted binding renders closed and Vue never warns. It was typed required while carrying that default, which made the manifest publish a row that was `required: true` AND `default: false` — a contradiction that read as a generator bug. |
531
+ | `modelValue` | `boolean \| undefined` | `false` | | Used by v-model to open or close the collapsible. Optional: omitted, it renders closed. |
530
532
  | `tag` | `'div'` \| `'span'` | `"span"` | | Element rendered as the root, and mirrored by the inner animating element — so the pair is span-in-span or div-in-div, both valid. Keep the default inside phrasing content (a `<p>`); use `'div'` when the body is block content (paragraphs, lists, forms), which a `span` may not contain. |
531
533
  | `transitionDuration` | `number \| undefined` | `250` | | How long the transition has to last in milliseconds |
532
534
 
@@ -462,7 +462,10 @@ The sheet is titled by your `label`, can be dragged down to dismiss, and has no
462
462
  never drag it — dragging there picks a colour. Tune the sheet through
463
463
  `offCanvasProps`, spread over those defaults:
464
464
  `:off-canvas-props="{ hideClose: false }"` brings the ✕ back, and an explicit
465
- `title` replaces the label.
465
+ `title` replaces the label (`size`, `persistent` pass straight through). It is
466
+ also the only way to style the sheet's header, title and ✕: none of the
467
+ input's own parts reach inside the sheet, so put a `pt` in `offCanvasProps`
468
+ (passthrough guide § Inside the sheet).
466
469
 
467
470
  ### Events
468
471
 
@@ -687,7 +690,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
687
690
  | `compact` | `boolean \| undefined` | `false` | | Compact density. Swaps `--bb-input-h`, `--bb-input-py` and `--bb-label-spacing-y` for their `-compact` twins on the field, so a `--bb-input-h` you set on the component is ignored while `compact` is on: size a compact field with `--bb-input-h-compact` (and `--bb-input-py-compact`) instead. |
688
691
  | `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`). |
689
692
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component. |
690
- | `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. |
693
+ | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or string array. They render in an `aria-live="polite"` region and are referenced first from the control's `aria-describedby`, so they are re-read when it regains focus. |
691
694
  | `eyeDropper` | `boolean \| undefined` | `false` | | Show an eyedropper button to sample any color on screen. Uses the native EyeDropper API — hidden automatically on unsupported browsers. |
692
695
  | `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). |
693
696
  | `hasErrors` | `boolean \| undefined` | `false` | | Define if the component should be in an error state. It usually attaches a CSS class for styling purposes. |
@@ -704,9 +707,9 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
704
707
  | `loading` | `boolean \| undefined` | `false` | | Sets the component in a loading state, usually triggering some visual styles. |
705
708
  | `modelValue` | `string \| null \| undefined` | `null` | | Used by v-model. |
706
709
  | `name` | `string \| undefined` | | | Defines the name of the input. |
707
- | `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. `size`, `persistent`). Spread over the defaults: the sheet's `title` is the field `label`, it is `draggable` (the colour square and sliders never drag it) and it hides its ✕; 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 ✕: none of its own parts reach inside the sheet. |
710
+ | `offCanvasProps` | `Partial<BbOffCanvasProps> \| undefined` | | | Props for the phone sheet (the `BbOffCanvas` that `adaptive` renders on mobile), spread over its defaults. A `pt` inside it styles only the sheet (passthrough guide § Inside the sheet). The sheet hides its ✕; `{ hideClose: false }` brings it back. |
708
711
  | `persistentHint` | `boolean \| undefined` | `false` | | Keeps the hint displayed. |
709
- | `placeholder` | `string \| undefined` | | | String displayed when there's no data. |
712
+ | `placeholder` | `string \| undefined` | | | Text shown while the field is empty. |
710
713
  | `prepend:icon` | `string \| undefined` | | | Name of the icon to be added at the start of the input. |
711
714
  | `readonly` | `boolean \| undefined` | `false` | | Sets the input in a readonly state. |
712
715
  | `required` | `boolean \| undefined` | `false` | | Sets the input as required. |
@@ -714,9 +717,9 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
714
717
  | `rules` | `RuleExpression<string \| null>` | | | vee-validate rules for this field. Only inside a `BbForm`. |
715
718
  | `swatches` | `boolean \| string[][] \| undefined` | | | Controls swatches display in the picker: - `true` — show the built-in Material-palette swatches - `string[][]` — show custom swatches (each inner array = a column of shades) - `false` / omitted — no swatches section |
716
719
  | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; the field's `name` never shows. Set it when the label is not a good noun for a sentence (an icon-only label, a question) or is hidden. Only inside a `BbForm`. |
717
- | `validationMode` | `ValidationMode \| undefined` | | | When this field checks itself while the user works: `aggressive` (every change), `balanced` (on leave, then every change while it shows an error), `lazy` (on leave only), `submit-only` (on submit only) or `submit-live` (on submit, then every change while it shows an error). "Leave" is blur for a text-like control, and focus leaving the whole control for a picker or a group; a checkbox or switch commits on click. Unset, the enclosing `BbForm`'s `validation-mode` applies, then the app's `formControls.validationMode` (`'balanced'`). Only inside a `BbForm`. |
718
- | `variant` | `InputVariantType \| undefined` | `'outline'` | | Visual variant of the field box — the same names and tokens as the `BbButton` variants. Colours only: height, padding and border width are identical across variants, so a form never reflows when one changes. `'ghost'` has no border in any state (errors and warnings show through the icon and the messages); every variant keeps the focus ring. Register extra names with the plugin's `inputVariants` option. `'none'` is a blank starting point: the field keeps its structure and behaviour but takes no look, so your own classes don't fight a built-in one. You then own hover, focus, disabled and the error / warning states. Fine for a one-off; keep inline styling short, and register a real variant (`inputVariants`) when the look recurs. |
719
- | `warnings` | `string \| string[] \| undefined` | | | Warning messages to display beneath the field, in their own `aria-live` region and amber (`--bb-text-warn`). A string or array; a non-empty list implies the warning state. Errors suppress warnings when both are set. While displayed they are also referenced from the control's `aria-describedby`, after any errors and before the description/hint. |
720
+ | `validationMode` | `ValidationMode \| undefined` | | | When this field validates as the user works: `aggressive` (every change), `balanced` (on leave, then live while it shows an error), `lazy` (on leave), `submit-only` or `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). Only in a `BbForm`. |
721
+ | `variant` | `InputVariantType \| undefined` | `'outline'` | | Visual variant of the field box, with the `BbButton` names and tokens. Colours only, so a form never reflows; `'ghost'` has no border in any state, and `'none'` takes no look at all (you own hover, focus and the states). Register more with the plugin's `inputVariants`. |
722
+ | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the field, a string or string array: amber, in their own `aria-live` region, and in the control's `aria-describedby` after the errors. A non-empty list implies the warning state; errors win when both are set. |
720
723
 
721
724
  ## Passthrough parts and states
722
725
 
@@ -775,14 +778,14 @@ States are listed in precedence order: when two are on at once and their entries
775
778
 
776
779
  ## Slots
777
780
 
778
- - `append` — scope: `Record<string, never>` — Content rendered after the color picker indicator button, at the end of the inner container. Mutually exclusive with `suffix`: the `suffix` slot renders inside this slot's default content, so providing `append` replaces the suffix rendering entirely and any `suffix` content is silently dropped. This slot receives no scoped props.
781
+ - `append` — scope: `Record<string, never>` — Content after the colour indicator button, at the end of the inner container. It replaces the `suffix` wrapper, so with `append` any `suffix` content is dropped. No scoped props.
779
782
  - `append:outer` — scope: `Record<string, never>` — Content rendered after the entire input control, outside the input chrome. This slot receives no scoped props.
780
783
  - `description` — scope: `BbColorInputDescriptionSlotProps` `{ 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`.
781
784
  - `label` — scope: `BbColorInputLabelSlotProps` `{ hasErrors: boolean; hasWarnings: boolean; text: string }` — Replaces the default label text rendered above the color input.
782
785
  - `prefix` — scope: `Record<string, never>` — Inline content rendered at the start of the input field area, before the typed text. This slot receives no scoped props.
783
786
  - `prepend` — scope: `Record<string, never>` — Content rendered before the text input, at the start of the inner container. This slot receives no scoped props.
784
787
  - `prepend:outer` — scope: `Record<string, never>` — Content rendered before the entire input control, outside the input chrome. This slot receives no scoped props.
785
- - `suffix` — scope: `Record<string, never>` — Inline content rendered at the end of the input field area, after the typed text. Renders inside the default `append` area's suffix wrapper — mutually exclusive with `append`: if an `append` slot is provided it replaces this wrapper and the `suffix` content is not rendered. This slot receives no scoped props.
788
+ - `suffix` — scope: `Record<string, never>` — Inline content at the end of the field, after the typed text, inside the default `append` area: an `append` slot replaces it. No scoped props.
786
789
 
787
790
  ## CSS custom properties
788
791
 
@@ -764,7 +764,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
764
764
  | `eyeDropper` | `boolean \| undefined` | `false` | | Show an eyedropper button inside the palette to sample any color on screen. Uses the native EyeDropper API — hidden automatically on unsupported browsers. |
765
765
  | `label` | `string \| undefined` | | | Accessible label. The activator is named by it followed by the activator's own text, through `aria-labelledby`. Defaults to the locale string for "Open color picker" when omitted. |
766
766
  | `modelValue` | `string \| null` | | yes | v-model: the current color as a `#RRGGBB` hex string (or `#RRGGBBAA` when `alpha` is enabled), or `null` when empty. |
767
- | `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 colour square and sliders never drag it) and hides its ✕ (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 ✕: none of its own parts reach inside the sheet. |
767
+ | `offCanvasProps` | `Partial<BbOffCanvasProps> \| undefined` | | | Props for the phone sheet (the `BbOffCanvas` that `adaptive` renders on mobile), spread over its defaults. A `pt` inside it styles only the sheet (passthrough guide § Inside the sheet). The sheet hides its ✕; `{ hideClose: false }` brings it back. |
768
768
  | `offset` | `number \| undefined` | `4` | | Space the floating container will maintain from the activator. |
769
769
  | `padding` | `number \| undefined` | `6` | | Minimum empty space to keep from the edge of the page |
770
770
  | `placement` | `Placement \| undefined` | | | Position of the overlay in respect to the related activator. |
@@ -425,9 +425,9 @@ and digit typeahead; the time rail exposes labelled columns. Always pass a
425
425
  | `label` | `string \| undefined` | | | Accessible label. The activator is named by it followed by the activator's own text ("Due date 12 Sep"), through `aria-labelledby`. |
426
426
  | `max` | `string \| undefined` | | | Maximum selectable value, in this `type`'s shape. A finer bound is accepted and ceiled to the unit, with a warning. |
427
427
  | `min` | `string \| undefined` | | | Minimum selectable value, in this `type`'s shape — `YYYY-MM-DD` (`YYYY-MM-DDTHH:mm` with `datetime`, `YYYY-MM` with `month`, `YYYY` with `year`). A finer bound is accepted and floored to the unit, with a warning. |
428
- | `modelValue` | `string \| string[] \| null` | | yes | v-model value. `null` for empty, a single string for single selection, or a two-element `[start, end]` array when `range` is true. The string shape follows `type`: `YYYY-MM-DD` when `floating` (`YYYY-MM` for `month`, `YYYY` for `year`), otherwise a zoned ISO instant carrying the time inline with `type="datetime"`. |
429
- | `multiple` | `boolean \| undefined` | `false` | | Enables multi-selection: every pick toggles a value in or out of a sorted array, and the panel stays open until it is dismissed. Works in whatever `type` selects — days, months or years — and requires an array `modelValue` (use `[]` for empty, never `null`). Mutually exclusive with `range` (two different selection models) and with `type="datetime"` (the time rail edits one value; with several there is no one it could mean). Both combinations throw. |
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. |
428
+ | `modelValue` | `string \| string[] \| null` | | yes | v-model: `null` when empty, a string, a `[start, end]` pair with `range`, or a sorted array with `multiple`. The string is `YYYY-MM-DD` when `floating` (`YYYY-MM` / `YYYY` for `month` / `year`), otherwise a zoned ISO instant (carrying the time under `datetime`). |
429
+ | `multiple` | `boolean \| undefined` | `false` | | Multi-selection: each pick toggles a value in a sorted array (days, months or years), and the panel stays open until dismissed. Needs an array `modelValue` (`[]` when empty, never `null`). Throws with `range` or `type="datetime"`. |
430
+ | `offCanvasProps` | `Partial<BbOffCanvasProps> \| undefined` | | | Props for the phone sheet (the `BbOffCanvas` that `adaptive` renders on mobile), spread over its defaults. A `pt` inside it styles only the sheet (passthrough guide § Inside the sheet). The sheet hides its ✕; `{ hideClose: false }` brings it back. |
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
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. |
@@ -438,7 +438,7 @@ and digit typeahead; the time rail exposes labelled columns. Always pass a
438
438
  | `step` | `number \| undefined` | `1` | | Minute-column granularity and arrow stepping (requires `type="datetime"`). |
439
439
  | `time` | `string \| string[] \| null \| undefined` | | | Companion time model (`v-model:time`), 24-hour `HH:mm` / `HH:mm:ss`. With `floating` it is the only carrier of the time; otherwise it mirrors the time inside `modelValue`. Requires `type="datetime"`. |
440
440
  | `transitionDuration` | `number \| undefined` | `250` | | Popover/sheet transition duration in milliseconds. |
441
- | `type` | `'date'` \| `'month'` \| `'year'` \| `'datetime'` | `"date"` | | What the picker selects, and therefore what it emits. - `date` (default) — a day. - `datetime` — a day plus a time rail beside the calendar. Non-floating values carry the time inside `modelValue`; with `floating` the time travels only through `time`. - `month` — a month grid emitting `YYYY-MM`. - `year` — a year list emitting `YYYY`. `month`/`year` are calendar labels, not instants: they force `floating` and ignore `utc`, and the time props (`seconds`, `ampm`, `step`, `time`) are inert outside `datetime`. |
441
+ | `type` | `'date'` \| `'month'` \| `'year'` \| `'datetime'` | `"date"` | | What the picker selects and emits: `date` (a day), `datetime` (a day plus a time rail), `month` (`YYYY-MM`) or `year` (`YYYY`). `month` / `year` force `floating`, ignore `utc`, and leave the time props inert. |
442
442
  | `utc` | `boolean \| undefined` | `false` | | Emit UTC (`...Z`) instead of the local offset. Ignored with `floating`, and therefore with `type="month"`/`type="year"`. |
443
443
 
444
444
  ## Passthrough parts and states
@@ -180,8 +180,12 @@ The value is edited as three separate inputs — day, month, year — not one fr
180
180
  string. Their **order and separator follow `config.locale`**, read from the
181
181
  locale's own format hint: `en` renders `MM/DD/YYYY`, `it` `DD/MM/YYYY`, `de`
182
182
  `TT.MM.JJJJ`, `ja` `YYYY/MM/DD`. A region writes its own order with its
183
- language's letters: `en-GB` `DD/MM/YYYY`, `fr-CA` `AAAA-MM-JJ`. Typing is
184
- forgiving:
183
+ language's letters: `en-GB` `DD/MM/YYYY`, `fr-CA` `AAAA-MM-JJ`. So an
184
+ English app that wants DD/MM/YYYY sets `locale: 'en-GB'`. If that is a type
185
+ error (`Type '"en-GB"' is not assignable to type 'keyof LocaleRegistry'`), the
186
+ locale ships but is not enabled in this build: add it to `enabledLocales`
187
+ ([Installation and Plugin Setup](./guides/installation-and-plugin-setup.md) §
188
+ `enabledLocales`). Typing is forgiving:
185
189
 
186
190
  - digits **auto-advance** to the next segment when a segment fills (or can't
187
191
  take another digit — e.g. `4` in a day segment becomes `04` and moves on);
@@ -549,7 +553,9 @@ The picker adapts to touch vs pointer, and you can steer that explicitly:
549
553
  swaps a live popover into a sheet. The sheet drags down to dismiss and shows
550
554
  no ✕ (the time wheels and the year list never drag it). Forward sheet options
551
555
  via `offCanvasProps`, spread over those defaults (e.g. `title`, `size`,
552
- `persistent`, `{ hideClose: false }` to bring the ✕ back). Set `:adaptive="false"` to
556
+ `persistent`, `{ hideClose: false }` to bring the ✕ back); a `pt` inside it is
557
+ the only way to style the sheet's header, title and ✕ (the input's own
558
+ `pt:header` is the calendar's navigation bar). Set `:adaptive="false"` to
553
559
  force the floating popover on every viewport (deterministic in tests).
554
560
  - **`disableWriting`**: block typing so the calendar is the only way in. Use
555
561
  `'mobile'` / `'desktop'` to disable typing on just one platform. Where
@@ -875,7 +881,7 @@ label>')` matches nothing; query each segment by its own label instead. See
875
881
  | `disableCalendar` | `boolean \| "mobile" \| "desktop" \| undefined` | `false` | | Disables the calendar: hides the trigger button and prevents the popover from opening. Use `'desktop'` to disable it on desktop only (keeping the calendar for mobile, complementing `disableWriting: 'mobile'`) or `'mobile'` to disable it on mobile only. |
876
882
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component. |
877
883
  | `disableWriting` | `boolean \| "mobile" \| "desktop" \| undefined` | `false` | | Disables typing into the input. Use `'mobile'` to disable typing only on mobile, `'desktop'` to disable typing only on desktop. |
878
- | `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. |
884
+ | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or string array. They render in an `aria-live="polite"` region and are referenced first from the control's `aria-describedby`, so they are re-read when it regains focus. |
879
885
  | `firstDayOfWeek` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| undefined` | `the locale's week start` | | First day of the week (0 = Sunday … 6 = Saturday). Omitted, the active locale's week start: Monday for `it`, `de`, `fr`, `en-gb`…, Sunday for bare `en` (US) and `pt` (Brazil). |
880
886
  | `floating` | `boolean \| undefined` | `false` | | If true the date will have a format YYYY-MM-DD instead of the default ISO string. |
881
887
  | `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). |
@@ -895,9 +901,9 @@ label>')` matches nothing; query each segment by its own label instead. See
895
901
  | `min` | `string \| undefined` | | | Minimum selectable date in `YYYY-MM-DD` format — or, with `type="datetime"`, `YYYY-MM-DDTHH:mm` to tighten the boundary day to a minute. Values outside both patterns throw during setup to surface configuration mistakes. |
896
902
  | `modelValue` | `string \| string[] \| null \| undefined` | | | Used by v-model. Can be null, a single string, or an array of strings based on whether a range or single date is needed. |
897
903
  | `name` | `string \| undefined` | | | Defines the name of the input. |
898
- | `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. |
904
+ | `offCanvasProps` | `Partial<BbOffCanvasProps> \| undefined` | | | Props for the phone sheet (the `BbOffCanvas` that `adaptive` renders on mobile), spread over its defaults. A `pt` inside it styles only the sheet (passthrough guide § Inside the sheet). The sheet hides its ✕; `{ hideClose: false }` brings it back. |
899
905
  | `persistentHint` | `boolean \| undefined` | `false` | | Keeps the hint displayed. |
900
- | `placeholder` | `string \| undefined` | | | String displayed when there's no data. |
906
+ | `placeholder` | `string \| undefined` | | | Text shown while the field is empty. |
901
907
  | `prepend:icon` | `string \| undefined` | | | Name of the icon to be added at the start of the input. |
902
908
  | `range` | `boolean \| undefined` | `false` | | Selects a range of dates between two dates. It selects all of the days between start and end. |
903
909
  | `readonly` | `boolean \| undefined` | `false` | | Sets the input in a readonly state. |
@@ -907,14 +913,14 @@ label>')` matches nothing; query each segment by its own label instead. See
907
913
  | `seconds` | `boolean \| undefined` | `false` | | Adds the seconds segment (requires `type="datetime"`). Without it, an incoming value carrying seconds displays truncated and is left untouched until the user commits an edit, at which point seconds zero out. |
908
914
  | `selectable` | `((date: string) => boolean) \| undefined` | | | Function that accepts a `string` object and returns a boolean. `false` meaning the date cannot be selected. |
909
915
  | `step` | `number \| undefined` | `1` | | Minute granularity for the calendar's minute column and arrow stepping (requires `type="datetime"`). Constrains what the component produces, never what it accepts: a typed off-grid value (e.g. `10:07` with `step: 15`) is emitted verbatim, and no column row highlights for it. |
910
- | `time` | `string \| string[] \| null \| undefined` | | | Companion model for the time part (`v-model:time`), always 24-hour `HH:mm` / `HH:mm:ss` regardless of display. With `floating` it is the only carrier of the time; otherwise it mirrors the time inside `modelValue` (same digits) and writing it rewrites the model's time part. Requires `type="datetime"`. |
916
+ | `time` | `string \| string[] \| null \| undefined` | | | `v-model:time`: the time part, always 24-hour `HH:mm` / `HH:mm:ss`. With `floating` it is the only carrier of the time; otherwise it mirrors `modelValue`'s, and writing it rewrites that. Requires `type="datetime"`. |
911
917
  | `transitionDuration` | `number \| undefined` | | | Transition duration, in milliseconds, for the popover appearance. |
912
- | `type` | `'date'` \| `'month'` \| `'year'` \| `'datetime'` | `"date"` | | What the field edits, and therefore its segments and emitted shape. - `date` (default) — `DD/MM/YYYY`. - `datetime` — adds the time segments and the calendar's time rail. - `month` — `MM/YYYY`, emitting `YYYY-MM`. - `year` — `YYYY`, emitting `YYYY`. `month`/`year` are calendar labels: they force `floating`, ignore `utc`, and make the time props (`seconds`, `ampm`, `step`, `v-model:time`) inert. |
913
- | `utc` | `boolean \| undefined` | `false` | | Emits values as UTC ISO strings (`...Z`) instead of ISO strings carrying the local offset (`...+01:00`). Emission-only: incoming values are parsed identically either way, so the prop can be added or removed without touching stored values. Fields always display local time — UTC is a backend concern. Ignored when `floating` is set (a plain date has no zone). |
918
+ | `type` | `'date'` \| `'month'` \| `'year'` \| `'datetime'` | `"date"` | | What the field edits, and so its segments and emitted shape: `date` (`DD/MM/YYYY`), `datetime` (adds the time segments and rail), `month` (`MM/YYYY`, emits `YYYY-MM`) or `year` (`YYYY`). `month` / `year` force `floating`, ignore `utc`, and leave the time props inert. |
919
+ | `utc` | `boolean \| undefined` | `false` | | Emits UTC ISO strings (`…Z`) instead of the local offset (`…+01:00`). Emission only: incoming values parse the same either way, and the field always displays local time. Ignored with `floating`. |
914
920
  | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; the field's `name` never shows. Set it when the label is not a good noun for a sentence (an icon-only label, a question) or is hidden. Only inside a `BbForm`. |
915
- | `validationMode` | `'aggressive'` \| `'balanced'` \| `'lazy'` \| `'submit-only'` \| `'submit-live'` | | | When this field checks itself while the user works: `aggressive` (every change), `balanced` (on leave, then every change while it shows an error), `lazy` (on leave only), `submit-only` (on submit only) or `submit-live` (on submit, then every change while it shows an error). "Leave" is blur for a text-like control, and focus leaving the whole control for a picker or a group; a checkbox or switch commits on click. Unset, the enclosing `BbForm`'s `validation-mode` applies, then the app's `formControls.validationMode` (`'balanced'`). Only inside a `BbForm`. |
916
- | `variant` | `'outline'` \| `'secondary'` \| `'none'` \| `'ghost'` | `'outline'` | | Visual variant of the field box — the same names and tokens as the `BbButton` variants. Colours only: height, padding and border width are identical across variants, so a form never reflows when one changes. `'ghost'` has no border in any state (errors and warnings show through the icon and the messages); every variant keeps the focus ring. Register extra names with the plugin's `inputVariants` option. `'none'` is a blank starting point: the field keeps its structure and behaviour but takes no look, so your own classes don't fight a built-in one. You then own hover, focus, disabled and the error / warning states. Fine for a one-off; keep inline styling short, and register a real variant (`inputVariants`) when the look recurs. |
917
- | `warnings` | `string \| string[] \| undefined` | | | Warning messages to display beneath the field, in their own `aria-live` region and amber (`--bb-text-warn`). A string or array; a non-empty list implies the warning state. Errors suppress warnings when both are set. While displayed they are also referenced from the control's `aria-describedby`, after any errors and before the description/hint. |
921
+ | `validationMode` | `'aggressive'` \| `'balanced'` \| `'lazy'` \| `'submit-only'` \| `'submit-live'` | | | When this field validates as the user works: `aggressive` (every change), `balanced` (on leave, then live while it shows an error), `lazy` (on leave), `submit-only` or `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). Only in a `BbForm`. |
922
+ | `variant` | `'outline'` \| `'secondary'` \| `'none'` \| `'ghost'` | `'outline'` | | Visual variant of the field box, with the `BbButton` names and tokens. Colours only, so a form never reflows; `'ghost'` has no border in any state, and `'none'` takes no look at all (you own hover, focus and the states). Register more with the plugin's `inputVariants`. |
923
+ | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the field, a string or string array: amber, in their own `aria-live` region, and in the control's `aria-describedby` after the errors. A non-empty list implies the warning state; errors win when both are set. |
918
924
 
919
925
  ## Passthrough parts and states
920
926
 
@@ -916,7 +916,9 @@ so a mid-flow resize never swaps modal ↔ sheet.
916
916
  `fullscreen`, `stack` and `transition-duration` carry over; the four
917
917
  lifecycle events fire the same either way.
918
918
  - `off-canvas-props` merges last over the sheet's props — use it to change
919
- the `side`, the size, `stack-gap`, or disable dragging on the mobile surface only.
919
+ the `side`, the size, `stack-gap`, or disable dragging on the mobile surface only,
920
+ or to override a shared prop whose meaning differs on the drawer (`stack`).
921
+ It is ignored on the desktop dialog.
920
922
  A `pt` inside it is **sheet-only styling**:
921
923
  `:off-canvas-props="{ 'pt:header': 'pt-10' }"` next to
922
924
  `pt:header="bg-(--bb-muted) pt-1"` keeps `pt-1` on the desktop dialog and
@@ -1123,15 +1125,15 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
1123
1125
  | Prop | Type | Default | Required | Description |
1124
1126
  | --- | --- | --- | --- | --- |
1125
1127
  | `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: `close`, `content`, `description`, `footer`, `header`, `root`, `sheet`, `title`. States: `fullscreen`, `open`. 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 `BbDialogProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
1126
- | `adaptive` | `boolean \| undefined` | ``config.adaptive` (`true`)` | | Adapt the surface to the viewport: render as a `BbOffCanvas` drawer on mobile instead of a centered dialog. The surface is resolved when the dialog opens and stays fixed for that session: resizing across the mobile breakpoint while open never swaps it. When unset, falls back to the global `config.adaptive`. |
1127
- | `description` | `string \| undefined` | | | One short line under the title, in the header — the shadcn `DialogDescription` shape: same block as the title, lower hierarchy, muted. It is also what `aria-describedby` points at. That wiring was dropped in v3 along with the old `description` prop, on the reasoning that pointing it at arbitrary body content would read whole forms aloud — true, and the reason it aims at THIS element only. Keep it to a sentence; anything longer belongs in the body. |
1128
- | `disabled` | `boolean \| undefined` | `false` | | Disable EVERY user-initiated dismissal: backdrop click, Escape AND the header close (×) button (denied attempts play the deny nudge). Use it while an operation is in flight (e.g. a save) so the dialog cannot be dismissed mid-work. Compare `persistent`, which blocks backdrop/Escape but leaves the × working. Programmatic close (v-model) is still allowed. |
1128
+ | `adaptive` | `boolean \| undefined` | ``config.adaptive` (`true`)` | | On mobile, renders as a `BbOffCanvas` drawer instead of a centred dialog; the surface is chosen when the dialog opens and kept until it closes. Unset: the global `config.adaptive`. |
1129
+ | `description` | `string \| undefined` | | | One short line under the title, muted (the shadcn `DialogDescription` shape), and the only element `aria-describedby` points at. Keep it to a sentence; anything longer belongs in the body. |
1130
+ | `disabled` | `boolean \| undefined` | `false` | | Blocks EVERY user dismissal (backdrop, Escape and the ✕; a denied attempt plays the deny nudge), e.g. while a save runs. `persistent` blocks only the backdrop and Escape. Closing through `v-model` still works. |
1129
1131
  | `eager` | `boolean \| undefined` | `false` | | Render dialog content immediately instead of waiting for the first open. |
1130
1132
  | `focusTarget` | `string \| undefined` | | | CSS selector of the element to focus after opening. Defaults to the first tabbable element. |
1131
1133
  | `fullscreen` | `boolean \| "mobile" \| undefined` | | | Display the dialog fullscreen. Use `'mobile'` to restrict fullscreen to small devices. |
1132
1134
  | `hideClose` | `boolean \| undefined` | `false` | | Hide the default close (×) button. The button is shown by default; set this to remove it (e.g. for a `persistent` dialog you don't want dismissible — the × otherwise still closes a persistent dialog). |
1133
1135
  | `modelValue` | `boolean \| undefined` | `false` | | Used by v-model to open / close the dialog. A dialog with no `v-model` starts closed. |
1134
- | `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. |
1136
+ | `offCanvasProps` | `Partial<BbOffCanvasProps> \| undefined` | | | Props for the phone sheet (the `BbOffCanvas` that `adaptive` renders on mobile), spread over its defaults. A `pt` inside it styles only the sheet (passthrough guide § Inside the sheet). |
1135
1137
  | `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. |
1136
1138
  | `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. |
1137
1139
  | `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. |
@@ -1173,7 +1175,7 @@ States are listed in precedence order: when two are on at once and their entries
1173
1175
  - `default` — scope: `BbDialogDefaultSlotProps` `{ close: () => void }` — Primary body content of the dialog, rendered in the scrollable body area.
1174
1176
  - `description` — scope: `BbDialogDescriptionSlotProps` `{ text: string }` — Replaces the description text under the title. Renders the header even when `title` and `description` are unset — a slotted description is a description, the same rule `#title` follows.
1175
1177
  - `footer` — scope: `BbDialogFooterSlotProps` `{ close: () => void }` — Content rendered in the dialog footer, below the body area. Typically used for action buttons.
1176
- - `header` — scope: `BbDialogHeaderSlotProps` `{ titleId: string; close: () => void; title: string }` — Replaces the entire dialog header section (title + close button) on both surfaces — the desktop `<dialog>` and the mobile off-canvas. Because it replaces the default close (✕), the slot owns closing: render your own control wired to the `close` prop, and wire `titleId` onto your title element to keep `aria-labelledby` intact. Providing this slot renders a header even when `title` is unset. Layout: the header container is a flex row (`justify-content: space-between`), so your root element is a flex item and shrinks to its content by default — give it `flex: auto` (Tailwind `flex-1`) to fill the width, or it renders squeezed against the left edge.
1178
+ - `header` — scope: `BbDialogHeaderSlotProps` `{ titleId: string; close: () => void; title: string }` — Replaces the whole header (title and ✕) on both surfaces, so it owns closing: wire your control to `close`, and `titleId` onto your title. It renders even without `title`. Its root is a flex item: give it `flex-1` to fill the width.
1177
1179
  - `title` — scope: `BbDialogTitleSlotProps` `{ text: string }` — Replaces the default title text inside the header. Remains linked to the dialog through `aria-labelledby`. Providing this slot renders the header even when `title` is unset — a slotted title is a title.
1178
1180
 
1179
1181
  ## CSS custom properties
@@ -2084,6 +2084,10 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
2084
2084
  land on the floating menu, like every floating component: its box on desktop,
2085
2085
  the sheet on a phone (`class` rides `pt:root`, which has no node on a sheet).
2086
2086
  To hide or style the trigger, put the class on your element in `#activator`.
2087
+ - **The trigger never goes in the default slot.** That slot holds
2088
+ `<BbDropdownGroup>` companions; a button there opens nothing. Use
2089
+ `<template #activator="{ props }">` + `v-bind="props"`, or `v-bb-dropdown`
2090
+ (`bitboss-ui/dropdown-default-slot` and `check` report it).
2087
2091
  - **There is no open flag to bind.** The menu keeps its open state internal
2088
2092
  (no `v-model:open`, by design): the activator opens it, a pick or an outside
2089
2093
  press closes it, and `@show` / `@hide` tell you when. Don't reopen it from a
@@ -2163,20 +2167,20 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
2163
2167
  | Prop | Type | Default | Required | Description |
2164
2168
  | --- | --- | --- | --- | --- |
2165
2169
  | `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: `footer`, `header`, `input`, `item`, `itemDescription`, `itemIcon`, `itemText`, `list`, `panel`, `root`, `sheet`. States: `disabled`, `open`, `selected`. 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 `BbDropdownProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
2166
- | `activator` | `Record<string, any> \| HTMLElement \| null \| undefined` | | | External activator element or component ref. When provided, the activator slot is not rendered and event listeners are attached programmatically to the referenced element. ARIA (`aria-haspopup`/`aria-expanded`/`aria-controls`) is attached programmatically too — don't add your own, or you get a double-set conflict. |
2167
- | `adaptive` | `boolean \| undefined` | ``config.adaptive` (`true`)` | | On mobile viewports (below `config.mobileMaxWidth`), render the dropdown as a bottom-anchored, auto-sized off-canvas sheet that **navigates** through nested submenus (drilling one level at a time with a back control) instead of showing hover flyouts. Slots and selection behave exactly as on desktop. When unset, falls back to the global `config.adaptive`. |
2168
- | `anchor` | `Record<string, any> \| HTMLElement \| null \| undefined` | `the activator element` | | Element the panel positions itself against, when it should differ from the activator — e.g. a wrapper that the activator is only a part of, so the menu aligns to the whole control while a single button opens it. Accepts an HTMLElement or a Vue component ref. Also drives a percentage `width`. Ignored when `placement` is `'cursor'`. |
2170
+ | `activator` | `Record<string, any> \| HTMLElement \| null \| undefined` | | | An external activator element or component ref: the activator slot is not rendered, and the listeners and ARIA (`aria-haspopup` / `aria-expanded` / `aria-controls`) are attached to it; don't add your own. |
2171
+ | `adaptive` | `boolean \| undefined` | ``config.adaptive` (`true`)` | | On mobile (below `config.mobileMaxWidth`), renders the menu as a bottom sheet that drills into submenus one level at a time instead of hover flyouts; slots and selection are unchanged. Unset: the global `config.adaptive`. |
2172
+ | `anchor` | `Record<string, any> \| HTMLElement \| null \| undefined` | `the activator element` | | The element the panel positions against when it should differ from the activator (a wrapper the activator is part of); an HTMLElement or component ref. It also drives a percentage `width`. Ignored with `placement="cursor"`. |
2169
2173
  | `boundary` | `string \| Record<string, any> \| HTMLElement \| null \| undefined` | | | Constrains the dropdown within a bounding element. Accepts an HTMLElement, a Vue component ref, or a CSS selector string. |
2170
- | `compact` | `boolean \| undefined` | `false` | | Apply the compact density variant — the same ladder `BbSelect` uses, on both surfaces: flyout rows go 28px → 24px, sheet rows 44px → 36px. The label size does not change; density here is height, as it is for a select. A menu row is a touch target in a way a select option is not quite — a mis-tap fires the neighbouring COMMAND rather than picking the wrong value — so the compact sheet stops at 36px and never follows the flyout down to 24px. That is the same floor the select's sheet holds. |
2174
+ | `compact` | `boolean \| undefined` | `false` | | Compact density, the `BbSelect` ladder: flyout rows 28px → 24px, sheet rows 44px → 36px (a sheet row stays a touch target). The label size does not change. |
2171
2175
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component |
2172
2176
  | `eager` | `boolean \| undefined` | `false` | | Renders the menu panel at mount instead of on the first open (the phone sheet's too), and keeps its rows after a close. Without it the rows mount on each open and go once the menu has closed. |
2173
2177
  | `emptyText` | `string \| undefined` | | | Default placeholder text shown when a pipeline group resolves to no items. A group's own `emptyText` overrides this; both fall back to the localized `common.emptyText` (`'No data to display'`). |
2174
2178
  | `enforceCoherence` | `boolean \| undefined` | `false` | | Default for pipeline groups: drop selections that are no longer present in a group's current items (e.g. after a `dependencies` re-fetch) from the selection and `v-model`. A group's own `enforceCoherence` overrides this. |
2175
2179
  | `failedText` | `string \| undefined` | | | Default placeholder text shown when a pipeline group's latest load FAILED (its `items` getter threw). A group's own `failedText` overrides this; both fall back to the localized `common.failedText` (`"Couldn't load items"`). |
2176
2180
  | `id` | `string \| undefined` | | | Names this dropdown: the activator's id (unless it already has one), the menu's `menu_<id>`, and the key `useBbDropdownContext(id)` and a companion `BbDropdownGroup` pair by. Generated when omitted. |
2177
- | `items` | `BbDropdownItem[]` | `[]` | yes | Array used to render each dropdown button. They can act as `button`, as `a`, or as `router-link` as they are based on the functionality provided by `BbBaseButton`. Pass a flat array for a single group, nest arrays for divider-separated groups, or pass {@link InternalGroup} objects for titled / selectable sections. An item may carry its own `items` to open a submenu. The shapes can be mixed. |
2181
+ | `items` | `BbDropdownItem[]` | `[]` | yes | The menu rows, each a `BbBaseButton` (`button`, `a` or `router-link`): a flat array for one group, nested arrays for divider-separated groups, or `InternalGroup` objects for titled / selectable sections. A row's own `items` opens a submenu. |
2178
2182
  | `loadingText` | `string \| undefined` | | | Default placeholder text shown while a pipeline group's async items load. A group's own `loadingText` overrides this; both fall back to the localized `common.loadingText` (`'Loading...'`). |
2179
- | `offCanvasProps` | `Partial<BbOffCanvasProps> \| undefined` | | | Props for the phone sheet. A `pt` inside it, object or colon keys, styles only that sheet. Overrides forwarded to the underlying `BbOffCanvas` when `adaptive` renders the sheet on mobile. Merged over the adaptive defaults (`side: 'bottom'`, `size: 'auto'`, `draggable: true`). Ignored when `adaptive` is `false`. 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. |
2183
+ | `offCanvasProps` | `Partial<BbOffCanvasProps> \| undefined` | | | Props for the phone sheet (the `BbOffCanvas` that `adaptive` renders on mobile), spread over its defaults. A `pt` inside it styles only the sheet (passthrough guide § Inside the sheet). The sheet hides its ✕; `{ hideClose: false }` brings it back. |
2180
2184
  | `offset` | `number \| undefined` | `4` | | Space the floating container will maintain from the activator. |
2181
2185
  | `padding` | `number \| undefined` | `10` | | Minimum empty space to keep from the edge of the page |
2182
2186
  | `placement` | `'top'` \| `'bottom'` \| `'left'` \| `'right'` \| `'top-start'` \| `'top-end'` \| `'right-start'` \| `'right-end'` \| `'bottom-start'` \| `'bottom-end'` \| `'left-start'` \| `'left-end'` \| `'cursor'` | `"bottom"` | | Position of the dropdown relative to the activator. Use `'cursor'` to anchor at the mouse/touch coordinates. (No arrow is drawn either way — arrows are tooltip-only in v3.) |
@@ -631,17 +631,17 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
631
631
  | Prop | Type | Default | Required | Description |
632
632
  | --- | --- | --- | --- | --- |
633
633
  | `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: `footer`, `header`, `icon`, `input`, `item`, `itemDescription`, `itemIcon`, `itemText`, `main`, `panel`, `root`, `sheet`, `spinner`, `text`, `toggle`. States: `disabled`, `loading`, `open`, `selected`. 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 `BbDropdownButtonProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
634
- | `adaptive` | `boolean \| undefined` | ``config.adaptive` (`true`)` | | On mobile viewports (below `config.mobileMaxWidth`), render the dropdown as a bottom-anchored, auto-sized off-canvas sheet that **navigates** through nested submenus (drilling one level at a time with a back control) instead of showing hover flyouts. Slots and selection behave exactly as on desktop. When unset, falls back to the global `config.adaptive`. |
634
+ | `adaptive` | `boolean \| undefined` | ``config.adaptive` (`true`)` | | On mobile (below `config.mobileMaxWidth`), renders the menu as a bottom sheet that drills into submenus one level at a time instead of hover flyouts; slots and selection are unchanged. Unset: the global `config.adaptive`. |
635
635
  | `append:icon` | `string \| undefined` | | | Icon to be added on the right of the text. |
636
636
  | `block` | `boolean \| undefined` | `false` | | Displays the component as full width. |
637
- | `compact` | `boolean \| undefined` | `false` | | Apply the compact density variant — the same ladder `BbSelect` uses, on both surfaces: flyout rows go 28px → 24px, sheet rows 44px → 36px. The label size does not change; density here is height, as it is for a select. A menu row is a touch target in a way a select option is not quite — a mis-tap fires the neighbouring COMMAND rather than picking the wrong value — so the compact sheet stops at 36px and never follows the flyout down to 24px. That is the same floor the select's sheet holds. |
637
+ | `compact` | `boolean \| undefined` | `false` | | Compact density, the `BbSelect` ladder: flyout rows 28px → 24px, sheet rows 44px → 36px (a sheet row stays a touch target). The label size does not change. |
638
638
  | `disableAutoLoading` | `boolean \| undefined` | `false` | | Disables the automatic loading state that tracks async actions (enabled by default). Only affects the main action button: the split toggle half still mirrors the dropdown's internal async-action loading state. |
639
639
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component |
640
640
  | `eager` | `boolean \| undefined` | `false` | | Renders the menu panel at mount instead of on the first open (the phone sheet's too), and keeps its rows after a close. Without it the rows mount on each open and go once the menu has closed. |
641
641
  | `id` | `string \| undefined` | | | Names this dropdown: the activator's id (unless it already has one), the menu's `menu_<id>`, and the key `useBbDropdownContext(id)` and a companion `BbDropdownGroup` pair by. Generated when omitted. |
642
- | `items` | `BbDropdownItem[]` | `[]` | yes | Array used to render each dropdown button. They can act as `button`, as `a`, or as `router-link` as they are based on the functionality provided by `BbBaseButton`. Pass a flat array for a single group, nest arrays for divider-separated groups, or pass {@link InternalGroup} objects for titled / selectable sections. An item may carry its own `items` to open a submenu. The shapes can be mixed. |
642
+ | `items` | `BbDropdownItem[]` | `[]` | yes | The menu rows, each a `BbBaseButton` (`button`, `a` or `router-link`): a flat array for one group, nested arrays for divider-separated groups, or `InternalGroup` objects for titled / selectable sections. A row's own `items` opens a submenu. |
643
643
  | `loading` | `boolean \| undefined` | `false` | | Triggers a loading indicator. |
644
- | `offCanvasProps` | `Partial<BbOffCanvasProps> \| undefined` | | | Props for the phone sheet. A `pt` inside it, object or colon keys, styles only that sheet. Overrides forwarded to the underlying `BbOffCanvas` when `adaptive` renders the sheet on mobile. Merged over the adaptive defaults (`side: 'bottom'`, `size: 'auto'`, `draggable: true`). Ignored when `adaptive` is `false`. 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. |
644
+ | `offCanvasProps` | `Partial<BbOffCanvasProps> \| undefined` | | | Props for the phone sheet (the `BbOffCanvas` that `adaptive` renders on mobile), spread over its defaults. A `pt` inside it styles only the sheet (passthrough guide § Inside the sheet). The sheet hides its ✕; `{ hideClose: false }` brings it back. |
645
645
  | `offset` | `number \| undefined` | `4` | | Space the floating container will maintain from the activator. |
646
646
  | `padding` | `number \| undefined` | `10` | | Minimum empty space to keep from the edge of the page |
647
647
  | `placement` | `'top'` \| `'bottom'` \| `'left'` \| `'right'` \| `'top-start'` \| `'top-end'` \| `'right-start'` \| `'right-end'` \| `'bottom-start'` \| `'bottom-end'` \| `'left-start'` \| `'left-end'` \| `'cursor'` | `'bottom'` | | Position of the dropdown relative to the activator. Use `'cursor'` to anchor at the mouse/touch coordinates. (No arrow is drawn either way — arrows are tooltip-only in v3.) |
@@ -649,7 +649,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
649
649
  | `size` | `Responsive<Sizes> \| undefined` | `"md"` | | Sets the size of the button. When the value is a string, it will be applied to all screen sizes. Otherwise, it will be applied to the screen size specified by the object. |
650
650
  | `toggle:icon` | `string \| undefined` | | | Replaces the chevron shown inside the dropdown toggle button. A constrained alternative to a slot: only the toggle's icon changes, so the button keeps its semantics. Named after the part it sits in (the `toggle`), the way `prepend:icon` / `append:icon` name theirs. |
651
651
  | `transitionDuration` | `number \| undefined` | `150` | | How long the transition has to last in milliseconds. Menus use the fast transition (150) rather than the medium one (250) the other popovers default to: a menu is opened to pick one command and is gone again, so it answers faster than a panel the user reads or edits in. |
652
- | `variant` | `'outline'` \| `'primary'` \| `'destructive'` \| `'secondary'` \| `'none'` \| `'ghost'` \| `'link'` | `"primary"` | | Visual variant shared by both buttons of the split control. `'none'` is a blank starting point: the button keeps its structure and behaviour but takes no look, so your own classes don't fight a built-in one. You then own hover, focus and disabled. Fine for a one-off; keep inline styling short, and register a real variant when the look recurs: the plugin's `buttonVariants` option types the name, and you style `.bb-button--<name>` (the library ships no CSS for it). |
652
+ | `variant` | `'outline'` \| `'primary'` \| `'destructive'` \| `'secondary'` \| `'none'` \| `'ghost'` \| `'link'` | `"primary"` | | Visual variant shared by both buttons of the split control. `'none'` takes no look (you own hover, focus and disabled); register a real one with the plugin's `buttonVariants` and style `.bb-button--<name>`. |
653
653
  | `width` | `string \| number \| undefined` | `'auto'` | | Width of the dropdown in pixels, percentage, or 'auto' to fit content. |
654
654
 
655
655
  ## Passthrough parts and states
@@ -1617,10 +1617,10 @@ button, grows with every file added, and changes mid-drag. So:
1617
1617
  | Prop | Type | Default | Required | Description |
1618
1618
  | --- | --- | --- | --- | --- |
1619
1619
  | `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: `content`, `message`, `root`. States: `active`, `disabled`, `errors`, `readonly`, `warnings`. 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 `BbDropzoneProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
1620
- | `accept` | `string[] \| undefined` | | | Array of MIME types (`'image/png'`), wildcards (`'image/*'`), extensions (`'.png'`) or bare tokens (`'png'`) to filter selectable files. A bare token upgrades to its extension instantly and is enriched with its MIME type from the lazily-imported `mime` database; validation of files that arrive before the database resolves is queued until the rules are complete. |
1620
+ | `accept` | `string[] \| undefined` | | | File filter: MIME types (`'image/png'`), wildcards (`'image/*'`), extensions (`'.png'`) or bare tokens (`'png'`, upgraded to the extension and its MIME type from the lazily imported `mime` database; files that arrive earlier wait for it). |
1621
1621
  | `autofocus` | `Booleanish \| undefined` | | | Sets autofocus on page load. |
1622
1622
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component |
1623
- | `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. |
1623
+ | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or string array. They render in an `aria-live="polite"` region and are referenced first from the control's `aria-describedby`, so they are re-read when it regains focus. |
1624
1624
  | `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). |
1625
1625
  | `hasErrors` | `boolean \| undefined` | `false` | | Define if the component should be in an error state. It usually attaches a CSS class for styling purposes. |
1626
1626
  | `hasWarnings` | `boolean \| undefined` | `false` | | Define if the component should be in a warning state. Same chrome as errors with `--bb-warn`; errors take priority. |
@@ -1634,8 +1634,8 @@ button, grows with every file added, and changes mid-drag. So:
1634
1634
  | `rules` | `RuleExpression<File \| File[] \| null>` | | | vee-validate rules for this field. Only inside a `BbForm`. |
1635
1635
  | `tag` | `'div'` \| `'span'` | `"div"` | | Element rendered as the component's wrapper. |
1636
1636
  | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; the field's `name` never shows. Set it when the label is not a good noun for a sentence (an icon-only label, a question) or is hidden. Only inside a `BbForm`. |
1637
- | `validationMode` | `'aggressive'` \| `'balanced'` \| `'lazy'` \| `'submit-only'` \| `'submit-live'` | | | When this field checks itself while the user works: `aggressive` (every change), `balanced` (on leave, then every change while it shows an error), `lazy` (on leave only), `submit-only` (on submit only) or `submit-live` (on submit, then every change while it shows an error). "Leave" is blur for a text-like control, and focus leaving the whole control for a picker or a group; a checkbox or switch commits on click. Unset, the enclosing `BbForm`'s `validation-mode` applies, then the app's `formControls.validationMode` (`'balanced'`). Only inside a `BbForm`. |
1638
- | `warnings` | `string \| string[] \| undefined` | | | Warning messages to display beneath the dropzone, in their own `aria-live` region and amber (`--bb-text-warn`). A string or array; a non-empty list implies the warning state. Errors suppress warnings when both are set. While displayed they are also referenced from the control's `aria-describedby`, after any errors and before the description/hint. |
1637
+ | `validationMode` | `'aggressive'` \| `'balanced'` \| `'lazy'` \| `'submit-only'` \| `'submit-live'` | | | When this field validates as the user works: `aggressive` (every change), `balanced` (on leave, then live while it shows an error), `lazy` (on leave), `submit-only` or `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). Only in a `BbForm`. |
1638
+ | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the dropzone, a string or string array: amber, in their own `aria-live` region, and in the control's `aria-describedby` after the errors. A non-empty list implies the warning state; errors win when both are set. |
1639
1639
 
1640
1640
  ## Passthrough parts and states
1641
1641