bitboss-ui 3.0.0-beta.62 → 3.0.0-beta.64

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 (393) hide show
  1. package/README.md +25 -20
  2. package/bin/bitboss-ui.mjs +73 -7
  3. package/dist/ai/BbAlert.md +10 -1
  4. package/dist/ai/BbBadge.md +35 -3
  5. package/dist/ai/BbBadgeButton.md +4 -2
  6. package/dist/ai/BbBaseButton.md +9 -3
  7. package/dist/ai/BbBreadcrumbs.md +2 -2
  8. package/dist/ai/BbButton.md +113 -8
  9. package/dist/ai/BbCheckbox.md +1 -1
  10. package/dist/ai/BbCheckboxGroup.md +94 -6
  11. package/dist/ai/BbColorInput.md +4 -1
  12. package/dist/ai/BbColorPalette.md +2 -1
  13. package/dist/ai/BbConfirm.md +53 -25
  14. package/dist/ai/BbDatePicker.md +2 -1
  15. package/dist/ai/BbDatePickerInput.md +4 -1
  16. package/dist/ai/BbDialog.md +12 -11
  17. package/dist/ai/BbDropdown.md +189 -38
  18. package/dist/ai/BbDropdownButton.md +27 -7
  19. package/dist/ai/BbForm.md +121 -26
  20. package/dist/ai/BbHost.md +12 -14
  21. package/dist/ai/BbHoverCard.md +7 -3
  22. package/dist/ai/BbIcon.md +12 -6
  23. package/dist/ai/BbIndicator.md +11 -1
  24. package/dist/ai/BbNumberInput.md +4 -1
  25. package/dist/ai/BbOffCanvas.md +37 -3
  26. package/dist/ai/BbPopover.md +2 -1
  27. package/dist/ai/BbPtScope.md +6 -4
  28. package/dist/ai/BbRadio.md +1 -1
  29. package/dist/ai/BbRadioGroup.md +102 -10
  30. package/dist/ai/BbSelect.md +52 -17
  31. package/dist/ai/BbSelectPopover.md +93 -26
  32. package/dist/ai/BbSwitch.md +1 -1
  33. package/dist/ai/BbSwitchGroup.md +30 -3
  34. package/dist/ai/BbTable.md +81 -14
  35. package/dist/ai/BbTabs.md +8 -3
  36. package/dist/ai/BbTabsList.md +4 -1
  37. package/dist/ai/BbTag.md +5 -2
  38. package/dist/ai/BbTextInput.md +4 -1
  39. package/dist/ai/BbTextarea.md +4 -1
  40. package/dist/ai/BbTimePicker.md +2 -1
  41. package/dist/ai/BbTimePickerInput.md +4 -1
  42. package/dist/ai/BbToast.md +9 -3
  43. package/dist/ai/BbTooltip.md +71 -9
  44. package/dist/ai/ChipsBox.md +1 -1
  45. package/dist/ai/CommonField.md +1 -1
  46. package/dist/ai/OptionsContainer.md +42 -0
  47. package/dist/ai/changelog.json +440 -6
  48. package/dist/ai/components.json +51 -49
  49. package/dist/ai/composables/useConfirm.md +47 -6
  50. package/dist/ai/design-tokens.json +6 -6
  51. package/dist/ai/guides/agent-contract.md +5 -4
  52. package/dist/ai/guides/ai-router.md +24 -23
  53. package/dist/ai/guides/app-layout.md +5 -0
  54. package/dist/ai/guides/component-picker.md +9 -2
  55. package/dist/ai/guides/design-language.md +24 -24
  56. package/dist/ai/guides/design-tokens.md +15 -8
  57. package/dist/ai/guides/icons-policy.md +9 -2
  58. package/dist/ai/guides/inertia-helpers.md +79 -49
  59. package/dist/ai/guides/installation-and-plugin-setup.md +12 -2
  60. package/dist/ai/guides/migration/adoption-checklist.md +235 -0
  61. package/dist/ai/guides/migration/components/bb-checkbox-group.md +16 -15
  62. package/dist/ai/guides/migration/components/bb-dialog.md +9 -9
  63. package/dist/ai/guides/migration/components/bb-dropdown.md +7 -2
  64. package/dist/ai/guides/migration/components/bb-host.md +4 -2
  65. package/dist/ai/guides/migration/components/bb-popover.md +4 -2
  66. package/dist/ai/guides/migration/components/bb-select.md +19 -0
  67. package/dist/ai/guides/migration/components/bb-table.md +1 -0
  68. package/dist/ai/guides/migration/components/bb-toast.md +4 -0
  69. package/dist/ai/guides/migration/components/bb-tooltip.md +15 -12
  70. package/dist/ai/guides/migration/components/use-confirm.md +39 -16
  71. package/dist/ai/guides/migration/v2-to-v3.md +172 -9
  72. package/dist/ai/guides/migration/v3-beta-css-classes.md +7 -3
  73. package/dist/ai/guides/options-items-playbook.md +2 -1
  74. package/dist/ai/guides/passthrough.md +147 -85
  75. package/dist/ai/guides/preset-components.md +140 -15
  76. package/dist/ai/guides/validated-forms.md +5 -0
  77. package/dist/ai/helpers/definePreset.json +7 -0
  78. package/dist/ai/helpers/definePreset.ts +123 -11
  79. package/dist/ai/helpers/inertia/manifest.json +15 -9
  80. package/dist/ai/helpers/inertia/useConfirmOnRouteLeave.ts +4 -4
  81. package/dist/ai/helpers/inertia/usePaginatedResponseContext.ts +39 -24
  82. package/dist/ai/helpers/inertia/useRouteQuery.ts +10 -4
  83. package/dist/ai/index.md +1 -0
  84. package/dist/ai/manifest/common.json +0 -1
  85. package/dist/ai/manifest/components/BbAlert.json +7 -2
  86. package/dist/ai/manifest/components/BbBadge.json +13 -4
  87. package/dist/ai/manifest/components/BbBadge.tree.json +2 -0
  88. package/dist/ai/manifest/components/BbBadgeButton.json +4 -2
  89. package/dist/ai/manifest/components/BbBaseButton.json +4 -2
  90. package/dist/ai/manifest/components/BbBreadcrumbs.tree.json +1 -1
  91. package/dist/ai/manifest/components/BbButton.json +14 -3
  92. package/dist/ai/manifest/components/BbButton.tree.json +5 -1
  93. package/dist/ai/manifest/components/BbCheckboxGroup.json +13 -8
  94. package/dist/ai/manifest/components/BbCheckboxGroup.tree.json +11 -1
  95. package/dist/ai/manifest/components/BbColorInput.json +18 -15
  96. package/dist/ai/manifest/components/BbColorPalette.json +1 -1
  97. package/dist/ai/manifest/components/BbConfirm.json +4 -2
  98. package/dist/ai/manifest/components/BbConfirm.tree.json +1 -1
  99. package/dist/ai/manifest/components/BbDatePicker.json +1 -1
  100. package/dist/ai/manifest/components/BbDatePickerInput.json +17 -14
  101. package/dist/ai/manifest/components/BbDialog.tree.json +2 -1
  102. package/dist/ai/manifest/components/BbDropdown.json +24 -19
  103. package/dist/ai/manifest/components/BbDropdown.tree.json +9 -2
  104. package/dist/ai/manifest/components/BbDropdownButton.json +33 -20
  105. package/dist/ai/manifest/components/BbDropdownButton.tree.json +2 -2
  106. package/dist/ai/manifest/components/BbForm.json +2 -2
  107. package/dist/ai/manifest/components/BbHost.tree.json +1 -2
  108. package/dist/ai/manifest/components/BbHoverCard.json +1 -1
  109. package/dist/ai/manifest/components/BbIndicator.json +8 -2
  110. package/dist/ai/manifest/components/BbNumberInput.json +5 -2
  111. package/dist/ai/manifest/components/BbOffCanvas.json +2 -2
  112. package/dist/ai/manifest/components/BbOffCanvas.tree.json +1 -1
  113. package/dist/ai/manifest/components/BbPopover.json +1 -1
  114. package/dist/ai/manifest/components/BbRadioGroup.json +17 -12
  115. package/dist/ai/manifest/components/BbRadioGroup.tree.json +8 -1
  116. package/dist/ai/manifest/components/BbSelect.json +21 -18
  117. package/dist/ai/manifest/components/BbSelect.tree.json +2 -2
  118. package/dist/ai/manifest/components/BbSelectPopover.json +10 -10
  119. package/dist/ai/manifest/components/BbSelectPopover.tree.json +3 -2
  120. package/dist/ai/manifest/components/BbSwitchGroup.json +1 -1
  121. package/dist/ai/manifest/components/BbSwitchGroup.tree.json +3 -1
  122. package/dist/ai/manifest/components/BbTable.json +2 -0
  123. package/dist/ai/manifest/components/BbTable.tree.json +14 -1
  124. package/dist/ai/manifest/components/BbTabs.json +9 -6
  125. package/dist/ai/manifest/components/BbTabs.tree.json +1 -1
  126. package/dist/ai/manifest/components/BbTabsList.json +6 -3
  127. package/dist/ai/manifest/components/BbTag.json +19 -16
  128. package/dist/ai/manifest/components/BbTag.tree.json +1 -1
  129. package/dist/ai/manifest/components/BbTextInput.json +6 -3
  130. package/dist/ai/manifest/components/BbTextarea.json +6 -3
  131. package/dist/ai/manifest/components/BbTimePicker.json +1 -1
  132. package/dist/ai/manifest/components/BbTimePickerInput.json +10 -7
  133. package/dist/ai/manifest/components/BbToast.json +7 -2
  134. package/dist/ai/manifest/components/BbToast.tree.json +4 -2
  135. package/dist/ai/manifest/components/BbTooltip.json +6 -5
  136. package/dist/ai/manifest/components/ChipsBox.tree.json +1 -1
  137. package/dist/ai/manifest/components/CommonField.json +1 -1
  138. package/dist/ai/manifest/components/OptionsContainer.json +3 -1
  139. package/dist/ai/manifest/components/OptionsContainer.tree.json +38 -0
  140. package/dist/ai/manifest/index.json +3 -3
  141. package/dist/ai/manifest/meta.json +5 -3
  142. package/dist/ai/manifest/types.advanced.json +6 -3
  143. package/dist/ai/manifest/types.api.json +9 -7
  144. package/dist/ai/recipes/inertia/layout-scaffold.md +19 -6
  145. package/dist/ai/recipes/inertia/records-workspace.md +49 -13
  146. package/dist/ai/recipes/nuxt/layout-scaffold.md +19 -6
  147. package/dist/ai/recipes/nuxt/records-workspace.md +42 -12
  148. package/dist/ai/recipes/vue/layout-scaffold.md +19 -6
  149. package/dist/ai/recipes/vue/records-workspace.md +42 -12
  150. package/dist/ai/source/BbAlert.md +94 -76
  151. package/dist/ai/source/BbBadge.md +174 -72
  152. package/dist/ai/source/BbBadgeButton.md +130 -65
  153. package/dist/ai/source/BbBaseButton.md +46 -124
  154. package/dist/ai/source/BbBaseCheckboxIcon.md +38 -0
  155. package/dist/ai/source/BbBaseRadioIcon.md +18 -0
  156. package/dist/ai/source/BbBaseSwitchIcon.md +51 -0
  157. package/dist/ai/source/BbButton.md +153 -36
  158. package/dist/ai/source/BbCheckboxGroup.md +142 -18
  159. package/dist/ai/source/BbColorInput.md +240 -204
  160. package/dist/ai/source/BbColorPalette.md +7 -4
  161. package/dist/ai/source/BbConfirm.md +67 -32
  162. package/dist/ai/source/BbConfirmPortal.md +31 -25
  163. package/dist/ai/source/BbDatePicker.md +11 -7
  164. package/dist/ai/source/BbDatePickerInput.md +306 -269
  165. package/dist/ai/source/BbDialog.md +49 -14
  166. package/dist/ai/source/BbDropdown.md +314 -197
  167. package/dist/ai/source/BbDropdownButton.md +197 -31
  168. package/dist/ai/source/BbDropdownGroup.md +274 -176
  169. package/dist/ai/source/BbForm.md +50 -6
  170. package/dist/ai/source/BbHost.md +3 -3
  171. package/dist/ai/source/BbHoverCard.md +12 -5
  172. package/dist/ai/source/BbIcon.md +4 -3
  173. package/dist/ai/source/BbIndicator.md +73 -52
  174. package/dist/ai/source/BbNumberInput.md +293 -257
  175. package/dist/ai/source/BbOffCanvas.md +55 -29
  176. package/dist/ai/source/BbPopover.md +14 -10
  177. package/dist/ai/source/BbRadioGroup.md +413 -297
  178. package/dist/ai/source/BbSelect.md +549 -435
  179. package/dist/ai/source/BbSelectPopover.md +128 -33
  180. package/dist/ai/source/BbSwitchGroup.md +70 -10
  181. package/dist/ai/source/BbTable.md +406 -46
  182. package/dist/ai/source/BbTabs.md +115 -39
  183. package/dist/ai/source/BbTabsList.md +106 -38
  184. package/dist/ai/source/BbTabsPanels.md +96 -36
  185. package/dist/ai/source/BbTabsRoot.md +96 -36
  186. package/dist/ai/source/BbTag.md +267 -233
  187. package/dist/ai/source/BbTextInput.md +261 -225
  188. package/dist/ai/source/BbTextarea.md +251 -215
  189. package/dist/ai/source/BbTimePicker.md +11 -7
  190. package/dist/ai/source/BbTimePickerInput.md +257 -220
  191. package/dist/ai/source/BbToast.md +73 -32
  192. package/dist/ai/source/BbToastPortal.md +65 -30
  193. package/dist/ai/source/BbTooltip.md +148 -113
  194. package/dist/ai/source/CommonPopover.md +6 -1
  195. package/dist/ai/source/FlatListBox.md +19 -9
  196. package/dist/ai/source/GroupedListBox.md +19 -9
  197. package/dist/ai/source/OptionsContainer.md +25 -9
  198. package/dist/components/BbAlert/BbAlert.vue_vue_type_script_setup_true_lang.js +61 -36
  199. package/dist/components/BbAlert/types.d.ts +9 -5
  200. package/dist/components/BbAlert/types.js +8 -3
  201. package/dist/components/BbBadge/BadgeBodyContent.vue.d.ts +3 -3
  202. package/dist/components/BbBadge/BadgeBodyContent.vue_vue_type_script_setup_true_lang.js +26 -17
  203. package/dist/components/BbBadge/BbBadge.vue_vue_type_script_setup_true_lang.js +103 -50
  204. package/dist/components/BbBadge/BbBadgeButton.vue_vue_type_script_setup_true_lang.js +20 -15
  205. package/dist/components/BbBadge/badgeButtonContext.d.ts +12 -1
  206. package/dist/components/BbBadge/types.d.ts +45 -15
  207. package/dist/components/BbBadge/types.js +12 -3
  208. package/dist/components/BbBaseButton/BbBaseButton.vue_vue_type_script_setup_true_lang.js +89 -126
  209. package/dist/components/BbBaseButton/types.d.ts +23 -4
  210. package/dist/components/BbBaseButton/types.js +7 -1
  211. package/dist/components/BbBaseButton/useLinkState.d.ts +41 -0
  212. package/dist/components/BbBaseButton/useLinkState.js +70 -0
  213. package/dist/components/BbButton/BbButton.vue_vue_type_script_setup_true_lang.js +130 -74
  214. package/dist/components/BbButton/types.d.ts +50 -13
  215. package/dist/components/BbButton/types.js +10 -3
  216. package/dist/components/BbCheckboxGroup/BbCheckboxGroup.vue_vue_type_script_setup_true_lang.js +148 -95
  217. package/dist/components/BbCheckboxGroup/types.d.ts +34 -11
  218. package/dist/components/BbCheckboxGroup/types.js +9 -4
  219. package/dist/components/BbCollapsible/BbCollapsible.vue.d.ts +1 -1
  220. package/dist/components/BbColorInput/BbColorInput.vue_vue_type_script_setup_true_lang.js +134 -93
  221. package/dist/components/BbColorInput/types.d.ts +11 -4
  222. package/dist/components/BbColorInput/types.js +9 -3
  223. package/dist/components/BbConfirm/BbConfirm.vue_vue_type_script_setup_true_lang.js +120 -88
  224. package/dist/components/BbConfirm/BbConfirmHost.d.ts +10 -0
  225. package/dist/components/BbConfirm/BbConfirmHost.js +32 -0
  226. package/dist/components/BbConfirm/BbConfirmPortal.vue_vue_type_script_setup_true_lang.js +8 -12
  227. package/dist/components/BbConfirm/confirmEntry.d.ts +4 -0
  228. package/dist/components/BbConfirm/confirmEntry.js +4 -0
  229. package/dist/components/BbConfirm/types.d.ts +11 -6
  230. package/dist/components/BbConfirm/types.js +8 -3
  231. package/dist/components/BbDatePicker/BbDatePicker.vue.d.ts +1 -1
  232. package/dist/components/BbDatePicker/BbDatePicker.vue_vue_type_script_setup_true_lang.js +68 -67
  233. package/dist/components/BbDatePickerInput/BbDatePickerInput.vue.d.ts +1 -1
  234. package/dist/components/BbDatePickerInput/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +259 -215
  235. package/dist/components/BbDatePickerInput/types.d.ts +12 -5
  236. package/dist/components/BbDatePickerInput/types.js +9 -3
  237. package/dist/components/BbDialog/BbDialog.vue_vue_type_script_setup_true_lang.js +223 -219
  238. package/dist/components/BbDialog/useDialogStack.d.ts +1 -1
  239. package/dist/components/BbDropdown/AdaptiveDropdown.vue_vue_type_script_setup_true_lang.js +104 -89
  240. package/dist/components/BbDropdown/BbDropdown.vue.d.ts +1 -0
  241. package/dist/components/BbDropdown/BbDropdown.vue_vue_type_script_setup_true_lang.js +323 -285
  242. package/dist/components/BbDropdown/BbDropdownList.vue.d.ts +1 -0
  243. package/dist/components/BbDropdown/BbDropdownList.vue_vue_type_script_setup_true_lang.js +411 -319
  244. package/dist/components/BbDropdown/DropdownPipelineResolver.vue_vue_type_script_setup_true_lang.js +100 -98
  245. package/dist/components/BbDropdown/DropdownRow.vue.d.ts +4 -3
  246. package/dist/components/BbDropdown/DropdownRow.vue_vue_type_script_setup_true_lang.js +49 -28
  247. package/dist/components/BbDropdown/normalizeGroups.d.ts +6 -0
  248. package/dist/components/BbDropdown/normalizeGroups.js +21 -15
  249. package/dist/components/BbDropdown/types.d.ts +59 -12
  250. package/dist/components/BbDropdown/types.js +16 -3
  251. package/dist/components/BbDropdown/useDropdownContext.d.ts +6 -0
  252. package/dist/components/BbDropdownButton/BbDropdownButton.vue.d.ts +2 -1
  253. package/dist/components/BbDropdownButton/BbDropdownButton.vue_vue_type_script_setup_true_lang.js +179 -68
  254. package/dist/components/BbDropdownButton/types.d.ts +44 -16
  255. package/dist/components/BbDropdownButton/types.js +28 -3
  256. package/dist/components/BbForm/BbForm.vue_vue_type_script_setup_true_lang.js +111 -89
  257. package/dist/components/BbForm/formSchema.d.ts +13 -0
  258. package/dist/components/BbHost/BbHost.vue_vue_type_script_setup_true_lang.js +2 -2
  259. package/dist/components/BbHoverCard/BbHoverCard.vue_vue_type_script_setup_true_lang.js +100 -100
  260. package/dist/components/BbIndicator/BbIndicator.vue_vue_type_script_setup_true_lang.js +40 -25
  261. package/dist/components/BbIndicator/types.d.ts +9 -5
  262. package/dist/components/BbIndicator/types.js +8 -3
  263. package/dist/components/BbNumberInput/BbNumberInput.vue_vue_type_script_setup_true_lang.js +243 -202
  264. package/dist/components/BbNumberInput/types.d.ts +12 -5
  265. package/dist/components/BbNumberInput/types.js +9 -3
  266. package/dist/components/BbOffCanvas/BbOffCanvas.vue.d.ts +1 -1
  267. package/dist/components/BbOffCanvas/BbOffCanvas.vue_vue_type_script_setup_true_lang.js +401 -399
  268. package/dist/components/BbOffCanvas/types.d.ts +6 -2
  269. package/dist/components/BbPopover/BbPopover.vue_vue_type_script_setup_true_lang.js +81 -80
  270. package/dist/components/BbRadioGroup/BbRadioGroup.vue_vue_type_script_setup_true_lang.js +158 -105
  271. package/dist/components/BbRadioGroup/types.d.ts +21 -7
  272. package/dist/components/BbRadioGroup/types.js +9 -4
  273. package/dist/components/BbSelect/BbSelect.vue.d.ts +4 -3
  274. package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +181 -137
  275. package/dist/components/BbSelect/types.d.ts +36 -22
  276. package/dist/components/BbSelect/types.js +22 -3
  277. package/dist/components/BbSelectPopover/BbSelectPopover.vue.d.ts +4 -4
  278. package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +543 -532
  279. package/dist/components/BbSelectPopover/knownItems.d.ts +5 -0
  280. package/dist/components/BbSelectPopover/types.d.ts +46 -12
  281. package/dist/components/BbSmoothHeight/BbSmoothHeight.vue.d.ts +1 -1
  282. package/dist/components/BbSwitchGroup/BbSwitchGroup.vue_vue_type_script_setup_true_lang.js +2 -2
  283. package/dist/components/BbSwitchGroup/types.d.ts +14 -4
  284. package/dist/components/BbSwitchGroup/types.js +8 -3
  285. package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +1152 -999
  286. package/dist/components/BbTable/BbTableDataRow.js +17 -12
  287. package/dist/components/BbTable/BbTableSelectToggle.d.ts +1 -1
  288. package/dist/components/BbTable/estimatedFloors.golden.d.ts +25 -0
  289. package/dist/components/BbTable/measuredFloors.d.ts +46 -0
  290. package/dist/components/BbTable/measuredFloors.js +322 -0
  291. package/dist/components/BbTable/measuredFloorsTestKit.d.ts +27 -0
  292. package/dist/components/BbTable/textRuler.d.ts +71 -0
  293. package/dist/components/BbTable/textRuler.js +121 -0
  294. package/dist/components/BbTable/types.d.ts +14 -3
  295. package/dist/components/BbTable/types.js +2 -0
  296. package/dist/components/BbTable/utils.d.ts +113 -6
  297. package/dist/components/BbTable/utils.js +118 -65
  298. package/dist/components/BbTabs/BbTabs.vue_vue_type_script_setup_true_lang.js +53 -35
  299. package/dist/components/BbTabs/BbTabsList.vue_vue_type_script_setup_true_lang.js +62 -45
  300. package/dist/components/BbTabs/types.d.ts +26 -11
  301. package/dist/components/BbTabs/types.js +23 -8
  302. package/dist/components/BbTag/BbTag.vue_vue_type_script_setup_true_lang.js +205 -164
  303. package/dist/components/BbTag/types.d.ts +11 -4
  304. package/dist/components/BbTag/types.js +9 -3
  305. package/dist/components/BbTextInput/BbTextInput.vue_vue_type_script_setup_true_lang.js +98 -57
  306. package/dist/components/BbTextInput/types.d.ts +12 -5
  307. package/dist/components/BbTextInput/types.js +9 -3
  308. package/dist/components/BbTextarea/BbTextarea.vue_vue_type_script_setup_true_lang.js +137 -96
  309. package/dist/components/BbTextarea/types.d.ts +12 -5
  310. package/dist/components/BbTextarea/types.js +9 -3
  311. package/dist/components/BbTimePicker/BbTimePicker.vue_vue_type_script_setup_true_lang.js +105 -104
  312. package/dist/components/BbTimePickerInput/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +241 -197
  313. package/dist/components/BbTimePickerInput/types.d.ts +12 -5
  314. package/dist/components/BbTimePickerInput/types.js +9 -3
  315. package/dist/components/BbToast/BbToast.vue_vue_type_script_setup_true_lang.js +74 -32
  316. package/dist/components/BbToast/BbToastMessage.vue_vue_type_script_setup_true_lang.js +47 -47
  317. package/dist/components/BbToast/types.d.ts +10 -5
  318. package/dist/components/BbToast/types.js +18 -3
  319. package/dist/components/BbTooltip/BbTooltip.vue_vue_type_script_setup_true_lang.js +85 -71
  320. package/dist/components/BbTooltip/types.d.ts +13 -8
  321. package/dist/components/BbTooltip/types.js +8 -3
  322. package/dist/components/CommonField/CommonField.vue.d.ts +1 -1
  323. package/dist/components/CommonPopover/CommonPopover.vue.d.ts +1 -1
  324. package/dist/components/CommonPopover/CommonPopover.vue_vue_type_script_setup_true_lang.js +69 -69
  325. package/dist/components/FlatListBox/FlatListBox.vue_vue_type_script_setup_true_lang.js +53 -50
  326. package/dist/components/GroupedListBox/GroupedListBox.vue_vue_type_script_setup_true_lang.js +146 -143
  327. package/dist/components/OptionsContainer/OptionsContainer.vue_vue_type_script_setup_true_lang.js +7 -2
  328. package/dist/components/OptionsContainer/types.d.ts +14 -3
  329. package/dist/composables/useBbFormContext.d.ts +11 -6
  330. package/dist/composables/useBbTabsContext.js +99 -85
  331. package/dist/composables/useChoiceIndicator.d.ts +58 -0
  332. package/dist/composables/useChoiceIndicator.js +197 -0
  333. package/dist/composables/useConfirm.d.ts +327 -33
  334. package/dist/composables/useConfirm.js +93 -71
  335. package/dist/composables/usePassthrough.d.ts +54 -1
  336. package/dist/composables/usePassthrough.js +100 -71
  337. package/dist/directives/bbTooltip.d.ts +12 -6
  338. package/dist/directives/createPopoverDirective.js +1 -1
  339. package/dist/index.d.ts +3 -1
  340. package/dist/llms-full.txt +2535 -612
  341. package/dist/llms-medium.txt +74 -55
  342. package/dist/llms.txt +2 -1
  343. package/dist/passthrough-deduper.js +6 -3
  344. package/dist/project-dts.d.ts +24 -0
  345. package/dist/project-dts.js +43 -17
  346. package/dist/styles.css +2 -2
  347. package/dist/types/AlertVariant.d.ts +14 -0
  348. package/dist/types/AlertVariant.js +9 -0
  349. package/dist/types/BadgeVariant.d.ts +14 -0
  350. package/dist/types/BadgeVariant.js +9 -0
  351. package/dist/types/ButtonVariant.d.ts +16 -0
  352. package/dist/types/ButtonVariant.js +11 -0
  353. package/dist/types/CheckboxVariant.d.ts +38 -0
  354. package/dist/types/CheckboxVariant.js +4 -0
  355. package/dist/types/CommonProps.d.ts +4 -3
  356. package/dist/types/Config.d.ts +7 -0
  357. package/dist/types/ConfirmVariant.d.ts +12 -0
  358. package/dist/types/ConfirmVariant.js +4 -0
  359. package/dist/types/DropdownItemVariant.d.ts +12 -0
  360. package/dist/types/DropdownItemVariant.js +4 -0
  361. package/dist/types/IndicatorVariant.d.ts +15 -0
  362. package/dist/types/IndicatorVariant.js +10 -0
  363. package/dist/types/InputVariant.d.ts +13 -0
  364. package/dist/types/InputVariant.js +8 -0
  365. package/dist/types/RadioVariant.d.ts +38 -0
  366. package/dist/types/RadioVariant.js +4 -0
  367. package/dist/types/TabsVariant.d.ts +13 -0
  368. package/dist/types/TabsVariant.js +8 -0
  369. package/dist/types/ToastVariant.d.ts +15 -0
  370. package/dist/types/ToastVariant.js +10 -0
  371. package/dist/types/TooltipVariant.d.ts +12 -0
  372. package/dist/types/TooltipVariant.js +4 -0
  373. package/dist/types/passthrough.d.ts +83 -15
  374. package/dist/types/passthrough.js +2 -2
  375. package/dist/types/ptComponentMap.d.ts +36 -24
  376. package/dist/utilities/functions/extractDomContainer.d.ts +20 -1
  377. package/dist/utilities/functions/extractDomContainer.js +8 -3
  378. package/dist/utils/focusVisibility.d.ts +6 -0
  379. package/dist/utils/focusVisibility.js +4 -1
  380. package/dist/utils/passthroughDeduper.d.ts +14 -0
  381. package/dist/utils/versionCheck.js +1 -1
  382. package/dist/vite-plugin.d.ts +64 -7
  383. package/dist/vite.js +385 -259
  384. package/llms.txt +2 -1
  385. package/package.json +3 -3
  386. package/scripts/lib/adoption-checklist.json +312 -0
  387. package/scripts/lib/eslint-plugin.d.ts +13 -0
  388. package/scripts/lib/eslint-plugin.mjs +75 -11
  389. package/scripts/lib/idiom-scan.mjs +65 -0
  390. package/scripts/lib/mcp-config.mjs +203 -9
  391. package/scripts/lib/migrate-fix.mjs +42 -1
  392. package/scripts/lib/project-variant-dts.mjs +18 -0
  393. package/scripts/lib/validate-bb-markup.mjs +99 -2
@@ -396,6 +396,22 @@ a `local:` file in your `iconDir`, not a hand-made icon component wrapped in a
396
396
  </div>
397
397
  ```
398
398
 
399
+ To change the glyph with the button's state (a filled star while a toggle is
400
+ on, a solid icon on the current page's link), use the slot named after the
401
+ prop: `#icon`, `#prepend:icon`, `#append:icon`. The slot replaces the prop and
402
+ renders inside the `icon` part, so `pt:icon`, `--icon-size` and the loading
403
+ spinner work as they do on the prop's glyph. Its scope is the button's states:
404
+ `{ activeLink, exactActiveLink, pressed, loading, disabled }`. What you put in
405
+ it is yours: a `BbIcon` takes the part's size, anything else you size.
406
+
407
+ ```vue
408
+ <BbButton v-model="starred" text="Star">
409
+ <template #prepend:icon="{ pressed }">
410
+ <BbIcon :icon="pressed ? 'lucide:star' : 'lucide:star-off'" />
411
+ </template>
412
+ </BbButton>
413
+ ```
414
+
399
415
  ### Toggle buttons
400
416
 
401
417
  Binding `v-model` turns the button into a toggle: each click flips the model
@@ -787,6 +803,84 @@ by `to`, by Inertia `href`, or by a plain `href`.
787
803
  </style>
788
804
  ```
789
805
 
806
+ ##### Styling the current page's entry
807
+
808
+ The same match is a `pt` state and a slot prop, so a sidebar entry can change
809
+ more than one class. `activeLink` is on whenever `active-class` is (the page
810
+ or one below it), `exactActiveLink` whenever `exact-active-class` is; every
811
+ part takes them (`pt:root:active-link`, `pt:icon:exact-active-link`, …), and
812
+ the default slot and the icon slots get `{ activeLink, exactActiveLink }`.
813
+ `#prepend:icon` picks what the classes cannot (a solid glyph on the current
814
+ page) and the states style the rest:
815
+
816
+ **Sidebar: solid icon and bold label on the current page**
817
+
818
+ ```vue
819
+ <template>
820
+ <nav aria-label="Main" class="grid w-full max-w-xs gap-0.5">
821
+ <!-- `#prepend:icon` picks the glyph: solid on the current page's entry,
822
+ still the button's icon (size, gap, spinner). The `active-link`
823
+ states style the rest — no class of your own, no second matcher. -->
824
+ <BbButton
825
+ v-for="item in items"
826
+ :key="item.label"
827
+ block
828
+ class="justify-start"
829
+ :href="item.href"
830
+ pt:root:active-link="bg-(--bb-muted) text-(--bb-text)"
831
+ pt:text:active-link="font-semibold"
832
+ :text="item.label"
833
+ variant="ghost"
834
+ >
835
+ <template #prepend:icon="{ activeLink }">
836
+ <BbIcon :icon="activeLink ? item.current : item.icon" />
837
+ </template>
838
+ </BbButton>
839
+ </nav>
840
+ </template>
841
+
842
+ <script setup lang="ts">
843
+ import { BbButton, BbIcon } from 'bitboss-ui';
844
+
845
+ // This demo runs router-free, so each href is matched against
846
+ // `window.location`: "Home" points at the page you are viewing. In your app
847
+ // the entries are real paths, and a `to` link takes the router's own answer.
848
+ // The hash hrefs keep the preview from navigating (never active).
849
+ const here =
850
+ typeof window !== 'undefined' ? window.location.pathname : '/dashboard';
851
+
852
+ const items = [
853
+ {
854
+ label: 'Home',
855
+ href: here,
856
+ icon: 'heroicons:home',
857
+ current: 'heroicons:home-solid',
858
+ },
859
+ {
860
+ label: 'Team',
861
+ href: '#team',
862
+ icon: 'heroicons:users',
863
+ current: 'heroicons:users-solid',
864
+ },
865
+ {
866
+ label: 'Settings',
867
+ href: '#settings',
868
+ icon: 'heroicons:cog-6-tooth',
869
+ current: 'heroicons:cog-6-tooth-solid',
870
+ },
871
+ ] as const;
872
+ </script>
873
+ ```
874
+
875
+ The classes, the states and the slot props are one answer: a `to` link takes
876
+ vue-router's own (`useLink`, as `RouterLink` does — so `/users` lights up on
877
+ `/users/5` when `/users/:id` is a child route of `/users`), an `href` link the
878
+ path match above. They rank below the real states: a `pressed`, `disabled` or
879
+ `loading` entry styles as that. `BbDropdownButton`'s main button, a `BbBadge`
880
+ whose `BbBadgeButton` is a link (the whole chip), and `BbDropdown` link entries
881
+ (`pt:item:active-link`, and the row slots' `activeLink` / `exactActiveLink`)
882
+ get the same states.
883
+
790
884
  #### Inertia visits
791
885
 
792
886
  Under Inertia, `href` accepts the full visit surface as props, grouped by
@@ -860,11 +954,11 @@ label span). Typography inherits from `root`, so reach for `text` only when a
860
954
  class must apply to the label ALONE — `truncate` on a long label that must not
861
955
  clip the icons beside it. That span also carries the margin the label slides by
862
956
  while the spinner is in, so a margin of your own fights the slide. States:
863
- `loading`, `disabled`, `pressed` (a `v-model` toggle that is on). A name
864
- outside that list is a type error and an ESLint error. There is no `active`
865
- state: a pointer press is Tailwind's `active:` variant (`pt:root="active:scale-95"`).
866
- There is no `current` state either: a link to the current route is
867
- `active-class` / `exact-active-class` (see Active state above).
957
+ `loading`, `disabled`, `pressed` (a `v-model` toggle that is on), and on a
958
+ link `activeLink` / `exactActiveLink` (it points at the current page: see
959
+ Active state above). A name outside that list is a type error and an ESLint
960
+ error. There is no `active` state: a pointer press is Tailwind's `active:`
961
+ variant (`pt:root="active:scale-95"`).
868
962
 
869
963
  **pt: a part, a part while loading, the object form**
870
964
 
@@ -1123,7 +1217,7 @@ Anti-patterns:
1123
1217
 
1124
1218
  | Prop | Type | Default | Required | Description |
1125
1219
  | --- | --- | --- | --- | --- |
1126
- | `pt:<part>`, `pt:<part>:<state>`, `pt` | `PtValue` | | | Passthrough — a class list, or `{ class, style, attrs }`, bound to one named part of the component; the state form applies only while that state is on. Parts: `icon`, `root`, `spinner`, `text`. States: `disabled`, `loading`, `pressed`. 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 `BbButtonProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
1220
+ | `pt:<part>`, `pt:<part>:<state>`, `pt` | `PtValue` | | | Passthrough — a class list, or `{ class, style, attrs }`, bound to one named part of the component; the state form applies only while that state is on. Parts: `icon`, `root`, `spinner`, `text`. States: `activeLink`, `destructive`, `disabled`, `exactActiveLink`, `ghost`, `link`, `loading`, `outline`, `pressed`, `primary`, `secondary`. 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 `BbButtonProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
1127
1221
  | `activeClass` | `string \| undefined` | | | Class to apply when the link is active. |
1128
1222
  | `append:icon` | `string \| undefined` | | | Icon to be added on the right of the text. |
1129
1223
  | `ariaCurrentValue` | `"page" \| "step" \| "location" \| "date" \| "time" \| "true" \| "false" \| undefined` | `'page'` | | Value passed to the attribute `aria-current` when the link is exact active. |
@@ -1193,9 +1287,17 @@ States are listed in precedence order: when two are on at once and their entries
1193
1287
 
1194
1288
  | State | When it is on |
1195
1289
  | --- | --- |
1290
+ | `activeLink` | Component-wide: a link to the current page or one of its ancestors (`/users` on `/users/5`) — exactly when `activeClass` is on. The weakest state: `pressed`, `disabled` and `loading` win a conflict. |
1291
+ | `exactActiveLink` | Component-wide: a link to the current page itself — exactly when `exactActiveClass` is on (`activeLink` is on too, so its entries apply first and these win). |
1196
1292
  | `pressed` | Component-wide: a toggle button (`v-model`) is on — `aria-pressed="true"`, `--pressed` on the root. |
1197
1293
  | `disabled` | Component-wide: the button is `disabled`. |
1198
1294
  | `loading` | Component-wide: `loading` is on — the spinner shows and the button ignores the pointer. |
1295
+ | `destructive` | Component-wide: `variant="destructive"`. Keeps the red under a base `pt`: `pt:root:destructive`. |
1296
+ | `ghost` | Component-wide: `variant="ghost"`. Below the real states, like every variant. |
1297
+ | `link` | Component-wide: `variant="link"`. Below the real states, like every variant. |
1298
+ | `outline` | Component-wide: `variant="outline"`. Below the real states, like every variant. |
1299
+ | `primary` | Component-wide: `variant="primary"`. Merged after the part's base entry and before its states, so `disabled` / `loading` still win. |
1300
+ | `secondary` | Component-wide: `variant="secondary"`. Below the real states, like every variant. |
1199
1301
 
1200
1302
  ## Events
1201
1303
 
@@ -1203,7 +1305,10 @@ States are listed in precedence order: when two are on at once and their entries
1203
1305
 
1204
1306
  ## Slots
1205
1307
 
1206
- - `default` — scope: `object` — Primary content rendered inside the button. Falls back to the `text` prop when empty.
1308
+ - `append:icon` — scope: `BbButtonIconSlotProps` `{ activeLink: boolean; exactActiveLink: boolean; pressed: boolean; loading: boolean; disabled: boolean }` — The trailing icon, replacing `append:icon`; inside the `icon` part.
1309
+ - `default` — scope: `BbLinkSlotProps` `{ activeLink: boolean; exactActiveLink: boolean }` — Primary content rendered inside the button. Falls back to the `text` prop when empty. A link's slot gets `{ activeLink, exactActiveLink }`: whether it points at the current page (both `false` on a button).
1310
+ - `icon` — scope: `BbButtonIconSlotProps` `{ activeLink: boolean; exactActiveLink: boolean; pressed: boolean; loading: boolean; disabled: boolean }` — The icon of an icon-only button, replacing the `icon` prop. Renders inside the `icon` part: `pt:icon`, `--icon-size` and the loading spinner apply.
1311
+ - `prepend:icon` — scope: `BbButtonIconSlotProps` `{ activeLink: boolean; exactActiveLink: boolean; pressed: boolean; loading: boolean; disabled: boolean }` — The leading icon, replacing `prepend:icon`; inside the `icon` part.
1207
1312
 
1208
1313
  ## Exposed (template ref)
1209
1314
 
@@ -1285,7 +1390,7 @@ Set these on the element, or on a class you put on it, to retune this component
1285
1390
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbButton`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
1286
1391
  - Listed nodes are the ones `BbButton`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbButton.tree.json`.
1287
1392
 
1288
- - `BbButton` _(this component)_ — its own template binds: `root` → `BbBaseButton`, `spinner` → `BbSpinner`, `icon` → `BbIcon`, `text` → `span.bb-button__text`
1393
+ - `BbButton` _(this component)_ — its own template binds: `root` → `BbBaseButton`, `spinner` → `BbSpinner`, `icon` → `span.bb-button__icon`, `icon` → `BbIcon`, `icon` → `span.bb-button__prepend-icon`, `text` → `span.bb-button__text`, `icon` → `span.bb-button__append-icon`
1289
1394
  - `BbBaseButton` _(public — [contract](./BbBaseButton.md))_ — its own pt parts (`BbBaseButton`): `root` → `RouterComponent`, `root` → `a`, `root` → `component`; also mounts `RouterComponent`
1290
1395
  - Also mounts `BbIcon`, `BbSpinner`
1291
1396
 
@@ -646,7 +646,7 @@ const onSave = async () => {
646
646
  </script>
647
647
  ```
648
648
 
649
- An attribute in `attrs` wins over ours. The visually hidden native input is
649
+ An attribute in `attrs` wins over ours. The invisible native input under the glyph is
650
650
  not a part — plain attributes on the component land on the root. A listener in `attrs` runs after the control's own
651
651
  handler, never instead of it. The full grammar, the merge rules and the global
652
652
  map are in the [passthrough guide](./guides/passthrough.md).
@@ -39,6 +39,27 @@
39
39
  | `--bg` | `pt:icon` | `BbBaseCheckboxIcon` | The glyph plate. DECLARED here, not consumed bare, because this glyph renders inside surfaces that declare `--bg` themselves — a table row or header cell, a dialog, an off-canvas sheet. Without the declaration it would inherit that surface's fill, which happens to match at the shipped default and would diverge the moment anyone writes `.my-table { --bg: … }`. Identical to the raw tokens it replaces at every theme. |
40
40
  | `--border-color` | `pt:icon` | `BbBaseCheckboxIcon` | Resting border colour of the glyph; re-pointed by error and warning states. |
41
41
  | `--ctrl-line` | `pt:label` | `CommonField` | Where the control's first line is centred, from the top of the control column (half the box height by default); the label's first line aligns to it in side-by-side layouts. |
42
+ | `--list-bg` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | The strip behind the triggers |
43
+ | `--list-border` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | The strip's edge line, --bb-border-w thick, painted inside the strip: under the triggers (beside them when vertical). `pill` draws none; `line` sets it to --bb-border |
44
+ | `--p` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | strip inner padding — the gutter the indicator sits in, and the scroll inset |
45
+ | `--list-r` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | strip corners |
46
+ | `--list-h` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | strip min height |
47
+ | `--fs` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | trigger label size |
48
+ | `--trigger-gap` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | space between triggers |
49
+ | `--trigger-px` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | trigger side padding |
50
+ | `--trigger-r` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | Trigger corners, concentric inside --list-r |
51
+ | `--trigger-min-h` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | Trigger height inside the padded strip |
52
+ | `--list-fg` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | unchecked trigger label |
53
+ | `--hover-fg` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | hovered trigger label |
54
+ | `--active-fg` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | checked trigger label |
55
+ | `--active-fw` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | checked trigger label weight (unchecked labels are 500) |
56
+ | `--indicator-bg` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | the indicator's fill |
57
+ | `--indicator-border` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | The indicator's edge |
58
+ | `--indicator-r` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | The indicator's corners — the pill's, concentric inside --list-r |
59
+ | `--indicator-h` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | The indicator's thickness: its height, its width on a vertical strip. `initial` fills the whole trigger box — the pill; a bar is `2px`, on the trigger's bottom edge (inline-end edge when vertical) |
60
+ | `--indicator-inset` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | Inset of the indicator from the trigger box — shrinks the pill; a bar keeps its thickness, shortens by it at both ends and floats it above the edge |
61
+ | `--elev` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | The theme's resting lift, composed UNDER the indicator's own shadow |
62
+ | `--indicator-shadow` | `pt:list`, `pt:item`, `pt:label`, `pt:itemDescription` | `OptionsContainer` | Indicator lift, painted on top of --elev |
42
63
 
43
64
  ## Usage & Guidelines
44
65
 
@@ -487,7 +508,7 @@ checked day painted, the hint reading the choice back:
487
508
  name="reminder-days"
488
509
  persistent-hint
489
510
  pt:icon="hidden"
490
- pt:item="justify-items-center gap-0 rounded-(--bb-radius) border py-2 hover:bg-(--bb-muted)"
511
+ pt:item="justify-items-center rounded-(--bb-radius) border py-2 hover:bg-(--bb-muted)"
491
512
  pt:item:checked="border-(--bb-primary) bg-(--bb-primary) hover:bg-(--bb-primary-hover)"
492
513
  pt:item:focus-visible="ring-2 ring-(--bb-primary-ring)"
493
514
  pt:label="text-sm font-medium"
@@ -626,6 +647,60 @@ const total = computed(() =>
626
647
  </script>
627
648
  ```
628
649
 
650
+ #### Pick values with the tabs look
651
+
652
+ `variant="pill"` or `variant="line"` gives the group a tab strip's look, for a
653
+ multi-pick that reads as a strip (opening days, channels, filters). `pill`
654
+ draws one pill per run of adjacent picks, so Mon–Wed reads as one block, and
655
+ each pill then lives on: ticking a neighbour stretches it, unticking an end
656
+ option shortens it, unticking a middle option splits it (the hole opens in
657
+ place), a lone pick pops a new pill in, and a pill whose options are all
658
+ unticked shrinks to its centre and fades. Two pills that come to touch stay
659
+ two pills, drawn as one shape. `line` draws a bar under each pick across a baseline that spans the field;
660
+ adjacent bars join. The strip and its triggers measure exactly as BbTabs'.
661
+ It is still a checkbox group (native checkboxes, `max`, forms, validation);
662
+ the box is hidden (an `icon` slot shows before the label) and the strip
663
+ never wraps (it scrolls); `list-layout="vertical"` stacks it into a column
664
+ (runs stack on the Y axis), `"vertical-stretch"` spans the field, and the
665
+ other layouts and `item-layout` do not apply. `pt:indicator` reaches every
666
+ pill or bar, and `pt:<part>:pill` / `pt:<part>:line` style a part in one look
667
+ only. The strip's tokens are its own, named and valued as a tab strip's; a
668
+ registered `checkboxVariants: ['brand']` sets them on
669
+ `.bb-checkbox-group__list--brand` and draws pills per run, as `pill` does.
670
+
671
+ **Pick values with the tabs look**
672
+
673
+ ```vue
674
+ <template>
675
+ <div class="flex flex-col gap-4">
676
+ <BbCheckboxGroup
677
+ v-model="days"
678
+ :items="weekdays"
679
+ legend="Open on"
680
+ variant="pill"
681
+ />
682
+ <BbCheckboxGroup
683
+ v-model="channels"
684
+ :items="['Email', 'SMS', 'Push']"
685
+ legend="Notify by"
686
+ variant="line"
687
+ />
688
+ </div>
689
+ </template>
690
+
691
+ <script setup lang="ts">
692
+ import { ref } from 'vue';
693
+ import { BbCheckboxGroup } from 'bitboss-ui';
694
+
695
+ // BbTabs' looks on a multi-pick. `pill`: one pill per run of adjacent picks,
696
+ // so Mon–Wed reads as one block; tick Thu and the pill grows, untick Tue and
697
+ // it splits. `line`: a bar under each pick, adjacent bars join.
698
+ const weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
699
+ const days = ref(['Mon', 'Tue', 'Wed', 'Fri']);
700
+ const channels = ref(['Email', 'Push']);
701
+ </script>
702
+ ```
703
+
629
704
  ### Legend, description and validation
630
705
 
631
706
  The `legend` is the group's accessible name — always set it. `description` is
@@ -868,6 +943,15 @@ list already spans the field, so the tiles do too.
868
943
  slot does not remove it: the default box is the slot's fallback and renders
869
944
  whenever the slot is empty.
870
945
 
946
+ A side hidden with the library's or Tailwind's hiding classes takes its gap
947
+ with it: a box hidden with `pt:icon="hidden"` (or `sr-only`), or a label
948
+ hidden with `hide-label` or `pt:label="sr-only"`, leaves the other side
949
+ centred, no `gap-0` needed. In `list-layout="tiles"` the whole tile is the
950
+ click and hover target, padding included (a tooltip whose activator is the
951
+ row's input shows anywhere on it); a link or a button inside a tile keeps its
952
+ own click. List rows keep the box as the target, beside a label that selects
953
+ too.
954
+
871
955
  **pt:item — cadence tiles, the selected ones accented**
872
956
 
873
957
  ```vue
@@ -918,7 +1002,7 @@ ours, an attribute in `attrs` wins over ours. The full grammar, the merge rules
918
1002
  and the global map are in the [passthrough guide](./guides/passthrough.md).
919
1003
 
920
1004
  A `pt` value written in `<script>` (a constant, a preset, a wrapper's
921
- `pt` prop) is typed as `BbCheckboxGroupProps<Row>['pt']`, or `BbCheckboxGroupProps['pt']`
1005
+ `pt` prop) is typed as `BbCheckboxGroupProps<Row>['pt']`, or `BbCheckboxGroupProps<object>['pt']`
922
1006
  for a preset that fits any row type (never `<any>`), not an imported
923
1007
  `PtValue`: see
924
1008
  [passthrough § Typing `pt` in `<script>`](./guides/passthrough.md#typing-pt-in-script).
@@ -982,7 +1066,7 @@ for a preset that fits any row type (never `<any>`), not an imported
982
1066
 
983
1067
  | Prop | Type | Default | Required | Description |
984
1068
  | --- | --- | --- | --- | --- |
985
- | `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: `description`, `hint`, `icon`, `item`, `itemDescription`, `label`, `legend`, `list`, `message`, `root`. States: `disabled`, `errors`, `hasValue`, `loading`, `readonly`, `warnings`, `checked`, `focused`, `focusVisible`. 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 `BbCheckboxGroupProps<Row>['pt']` (`BbCheckboxGroupProps['pt']` for a preset that fits any row type, never `<any>`) (`PtValue` is not exported): § Typing `pt` in `<script>`. |
1069
+ | `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: `description`, `hint`, `icon`, `indicator`, `item`, `itemDescription`, `label`, `legend`, `list`, `message`, `root`. States: `disabled`, `errors`, `hasValue`, `line`, `loading`, `pill`, `readonly`, `warnings`, `checked`, `focused`, `focusVisible`. 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 `BbCheckboxGroupProps<Row>['pt']` (`BbCheckboxGroupProps<object>['pt']` for a preset that fits any row type, never `<any>`) (`PtValue` is not exported): § Typing `pt` in `<script>`. |
986
1070
  | `autofocus` | `Booleanish \| undefined` | | | Focuses the field when it mounts (a dialog already open included), unless the user is typing in another field. |
987
1071
  | `compact` | `boolean \| undefined` | `false` | | Compact density. Swaps `--bb-label-spacing-y` for `--bb-label-spacing-y-compact`, so tune a compact group's label gap with the `-compact` token, not the base one. |
988
1072
  | `dependencies` | `unknown[] \| undefined` | | | Defines an array of dependencies that will trigger actions in the component upon change. |
@@ -1029,6 +1113,7 @@ for a preset that fits any row type (never `<any>`), not an imported
1029
1113
  | `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. |
1030
1114
  | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; never the `name`. Set it when the label is hidden or reads badly in a sentence (icon-only, a question). `BbForm` only. |
1031
1115
  | `validationMode` | `'aggressive'` \| `'balanced'` \| `'lazy'` \| `'submit-only'` \| `'submit-live'` | | | When the field validates: `aggressive` (each change), `balanced` (on leave, then live while in error), `lazy` (on leave), `submit-only`, `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). `BbForm` only. |
1116
+ | `variant` | `'pill'` \| `'line'` | | | A tab-strip look (Q76.11 d): `'pill'` (a pill per run of adjacent picks) or `'line'` (a bar under each pick). `list-layout="vertical"` stacks it. Register more with `checkboxVariants`. Unset: the group's own rows. |
1032
1117
  | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the field, a string or array: amber, in their own `aria-live` region and in the control's `aria-describedby` after the errors. Non-empty turns on the warning state; errors win when both are set. |
1033
1118
 
1034
1119
  ## Passthrough parts and states
@@ -1042,7 +1127,8 @@ for a preset that fits any row type (never `<any>`), not an imported
1042
1127
  | `description` | The muted line under the legend (the `description` prop). |
1043
1128
  | `message` | The errors / warnings line. A node of its own: it can show at the same time as `hint`. |
1044
1129
  | `hint` | The helper line (the `hint` prop), shown on focus, or always with `persistent-hint`. |
1045
- | `list` | The node that lays the rows out (flex + wrap, gaps on `--gap` / `--row-gap`): `pt:list="grid grid-cols-3"` re-lays them, `pt:list="[--gap:8px]"` tightens them. Takes the group-wide states only. |
1130
+ | `list` | The node that lays the rows out (flex + wrap, gaps on `--gap` / `--row-gap`): `pt:list="grid grid-cols-3"` re-lays them, `pt:list="[--gap:8px]"` tightens them. With a `variant`, the tab strip. Takes the group-wide states only. |
1131
+ | `indicator` | With a `variant`: the shape under the checked option, BbTabs' indicator — the sliding pill or bar of a radio group, a checkbox group's pill per run of adjacent picks (or bar per pick). Takes the group-wide states only. |
1046
1132
  | `item` | One option row — a broadcast, resolved per option with its own `checked` / `disabled` / focus. Takes a per-item function. |
1047
1133
  | `icon` | One row's drawn glyph — the default one: a consumer `icon` slot replaces it. Takes a per-item function. |
1048
1134
  | `label` | One option's label text (the `label` slot's default). Takes a per-item function. |
@@ -1061,6 +1147,8 @@ States are listed in precedence order: when two are on at once and their entries
1061
1147
  | `focused` | Per row, on the row parts: that option's input has focus — any focus, mouse included. |
1062
1148
  | `focusVisible` | Per row, on the row parts: that option's focus is keyboard-visible — where a focus ring belongs. |
1063
1149
  | `loading` | Component-wide: the items are being fetched. |
1150
+ | `line` | On every part: `variant: 'line'`. Below the real states, like every variant. |
1151
+ | `pill` | On every part: `variant: 'pill'`. Merged after the part's base entry and before its states, so the real states still win. |
1064
1152
 
1065
1153
  ## Events
1066
1154
 
@@ -1106,9 +1194,9 @@ Set these on the element, or on a class you put on it, to retune this component
1106
1194
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbCheckboxGroup`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
1107
1195
  - Listed nodes are the ones `BbCheckboxGroup`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbCheckboxGroup.tree.json`.
1108
1196
 
1109
- - `BbCheckboxGroup` _(this component)_ — its own template binds: `icon` → `BbBaseCheckboxIcon`
1197
+ - `BbCheckboxGroup` _(this component)_ — its own template binds: `indicator` → `span.bb-checkbox-group__indicator`, `icon` → `BbBaseCheckboxIcon`
1110
1198
  - `CommonField` _(internal — not importable, reach it through `BbCheckboxGroup`)_ — `BbCheckboxGroup`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `counter` → `span.bb-field__counter`, `message` → `div.bb-field__message`; documented CSS variables: `--ctrl-line`; also mounts `BbAsterisk`
1111
- - `OptionsContainer` _(internal — not importable, reach it through `BbCheckboxGroup`)_ — `BbCheckboxGroup`'s pt parts land here: `list` → `span`, `item` → `label`, `label` → `span`, `itemDescription` → `span`
1199
+ - `OptionsContainer` _(internal — not importable, reach it through `BbCheckboxGroup`)_ — `BbCheckboxGroup`'s pt parts land here: `list` → `span`, `item` → `label`, `label` → `span`, `itemDescription` → `span`; documented CSS variables: `--list-bg`, `--list-border`, `--p`, `--list-r`, `--list-h`, `--fs`, `--trigger-gap`, `--trigger-px`, `--trigger-r`, `--trigger-min-h`, `--list-fg`, `--hover-fg`, `--active-fg`, `--active-fw`, `--indicator-bg`, `--indicator-border`, `--indicator-r`, `--indicator-h`, `--indicator-inset`, `--elev`, `--indicator-shadow`
1112
1200
  - Also mounts `BbBaseCheckboxIcon`
1113
1201
 
1114
1202
  ## See Also
@@ -682,7 +682,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
682
682
 
683
683
  | Prop | Type | Default | Required | Description |
684
684
  | --- | --- | --- | --- | --- |
685
- | `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: `box`, `clear`, `description`, `hint`, `icon`, `indicator`, `input`, `label`, `message`, `panel`, `prefix`, `root`, `sheet`, `spinner`, `suffix`, `swatch`. States: `disabled`, `errors`, `hasValue`, `loading`, `readonly`, `warnings`, `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 `BbColorInputProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
685
+ | `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: `box`, `clear`, `description`, `hint`, `icon`, `indicator`, `input`, `label`, `message`, `panel`, `prefix`, `root`, `sheet`, `spinner`, `suffix`, `swatch`. States: `disabled`, `errors`, `ghost`, `hasValue`, `loading`, `outline`, `readonly`, `secondary`, `warnings`, `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 `BbColorInputProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
686
686
  | `adaptive` | `boolean \| undefined` | ``config.adaptive` (`true`)` | | When `true`, the color palette opens as a bottom off-canvas sheet on mobile viewports instead of a floating popover; on desktop it stays a popover. Mirrors the adaptive behaviour of `BbSelect`/`BbDatePickerInput`. When unset, falls back to the global `config.adaptive`. |
687
687
  | `alpha` | `boolean \| undefined` | `false` | | Enable the alpha channel. Shows an opacity slider and uses `#RRGGBBAA` hex8 format. |
688
688
  | `append:icon` | `string \| undefined` | | | Name of the icon to be added at the end of the input. |
@@ -757,6 +757,9 @@ States are listed in precedence order: when two are on at once and their entries
757
757
  | `warnings` | Component-wide: the control is in its warning state (`warnings` / `has-warnings`) and not in an error state — errors win, so the two are never on together. |
758
758
  | `errors` | Component-wide: the control is in its error state (`errors` / `has-errors`, or its validation) — the message line and the box turn red. |
759
759
  | `loading` | Component-wide: `loading` is on; the box shows its `spinner`. |
760
+ | `ghost` | On the field's parts: `variant: 'ghost'`. Below the real states, like every variant. |
761
+ | `outline` | On the field's parts: `variant: 'outline'`. Merged after the part's base entry and before its states, so the real states still win. |
762
+ | `secondary` | On the field's parts: `variant: 'secondary'`. Below the real states, like every variant. |
760
763
 
761
764
  ## Events
762
765
 
@@ -444,7 +444,8 @@ The float itself is tuned with the popover props:
444
444
 
445
445
  - `placement` (`'bottom'`, `'bottom-start'`, `'top-end'`, …) — the preferred
446
446
  side; the popover **auto-flips** to the opposite side when it would overflow,
447
- unless you set `disable-flip`.
447
+ unless you set `disable-flip`. Read at open: a change while open applies at
448
+ the next open.
448
449
  - `offset` (default 4) — gap between anchor and popover; `padding` (default 6) —
449
450
  minimum space kept from the viewport edge.
450
451
  - `boundary` — keep the popover inside an element (ref or CSS selector)
@@ -72,23 +72,21 @@ first — this is that gate.
72
72
  Mount `<BbHost />` **exactly once, at the app root** (`App.vue` under Vue,
73
73
  `app.vue` under Nuxt, the `createInertiaApp` render root under Inertia) — a
74
74
  single instance serves the whole app, and `confirm()` can then be called from
75
- anywhere, components and stores alike. **Calls do not queue — a new
76
- `confirm()` supersedes the open one**, and the superseded promise settles
77
- `false` (an implicit dismiss; no callback runs). So two `confirm()` calls in a
78
- row show only the second, and the first silently answers "no". If you need both
79
- questions asked, `await` the first before opening the second.
75
+ anywhere, components and stores alike. **Every call opens its own dialog**,
76
+ and a new one covers the open one, which stays pending and comes back when
77
+ the newer one closes (see [Several confirms at once](#several-confirms-at-once)).
80
78
  A second host renders nothing (a dev-mode console warning says so). With no
81
79
  host, `await confirm(...)` resolves `false` after one second, with a dev
82
80
  warning. A host that unmounts while its dialog is open (a layout the user
83
81
  navigated out of) gets the same second to come back; after that the open
84
82
  confirm resolves `false` without running a callback, so it never hangs.
85
83
 
86
- **Areas with their own look.** The dialog takes the passthrough scope and the
87
- tokens of the place its HOST is mounted. When the app is split into areas that
88
- each wrap their pages in `<BbPtScope>` ([passthrough guide](./guides/passthrough.md) § Named scopes),
89
- mount one `<BbHost />` inside each area's layout, within its scope, and none
90
- at the app root — which holds only if **every** page renders inside exactly one
91
- of those layouts, so there is still one host at a time.
84
+ **Areas with their own look.** A confirm takes the passthrough scope and the
85
+ tokens of the component that called `useConfirm()`, wherever the host is
86
+ mounted: a page inside a `<BbPtScope>` ([passthrough guide](./guides/passthrough.md) § Named scopes)
87
+ gets confirms in its area's look with nothing to set up. A component portal
88
+ injects from that component's tree too. A `useConfirm()` called outside a
89
+ component (a store, module level) takes the host's.
92
90
 
93
91
  ```vue
94
92
  <template>
@@ -105,10 +103,9 @@ import { BbHost } from 'bitboss-ui';
105
103
  standalone example has no app root to mount it in.** In a real app the host is
106
104
  already mounted at the root; a page that calls `confirm()` mounts nothing.
107
105
 
108
- The component itself takes almost no props: everything — content, buttons,
109
- behavior — travels in the message you pass to `confirm()`. The one exception is
110
- `size`, a host-wide default width every confirm inherits unless its message
111
- sets its own (see [Size, fullscreen and focus](#size-fullscreen-and-focus)).
106
+ Everything — content, buttons, behavior — travels in the message you pass to
107
+ `confirm()`; the width every confirm defaults to is the plugin's
108
+ `confirm.defaultSize` (see [Size, fullscreen and focus](#size-fullscreen-and-focus)).
112
109
  At least one of `title`, `text`, `portal` should be set (dev warning
113
110
  otherwise).
114
111
 
@@ -219,7 +216,9 @@ promise runs, the opposite button is disabled, the X is hidden and dismissal
219
216
  is blocked until it settles. Add `returning: true` to resolve with the
220
217
  callback's own return value rather than a plain boolean. One sharp edge:
221
218
  `confirm()` **rejects** when a button's `onClick` throws — wrap the await in
222
- `try/catch` when the work can fail.
219
+ `try/catch` when the work can fail. An Inertia visit returns no promise: wrap
220
+ it, as in `ai/composables/useConfirm.md` § async work, rather than calling
221
+ `close()` from its callbacks.
223
222
 
224
223
  **Async publish with a spinner**
225
224
 
@@ -402,7 +401,7 @@ the promise `false`, so your `if (ok)` branch is never reached accidentally.
402
401
  decline-only behavior in `no.onClick`, not in the `if (!ok)` branch. The rule
403
402
  that decides whether `no.onClick` runs: **user-initiated** dismissals
404
403
  (backdrop, `Escape`, the X) honor `dismissAsNo`; **system-initiated** ones
405
- (`duration` timeout, owner unmount, a superseding `confirm()`, `dismissAll()`)
404
+ (`duration` timeout, owner unmount, `dismissAll()`)
406
405
  always resolve quietly, never running any callback. The knobs:
407
406
 
408
407
  - `dismissAsNo` (default `true`) — user-initiated implicit dismissals also run
@@ -435,7 +434,7 @@ the peek closes. For app-lifetime confirms that survive any unmount, call
435
434
  `useConfirm()` outside a component scope (app setup, a store, module level).
436
435
 
437
436
  `useConfirm()` also returns `dismissAll()` — an imperative escape hatch that
438
- quietly dismisses the open dialog regardless of owner, for
437
+ quietly dismisses every open confirm regardless of owner, for
439
438
  app-level events like logout or a global error boundary.
440
439
 
441
440
  The classic case for `persistent` is the unsaved-changes prompt: an accidental
@@ -511,6 +510,8 @@ By default the dialog closes as soon as the promise settles. Set
511
510
  - `close()` only hides the dialog; **it never resolves anything**. Calling it
512
511
  on a dialog whose buttons haven't run yet leaves that `confirm()` promise
513
512
  pending forever — it is a flow terminator, not a substitute for the buttons.
513
+ - `close()` hides the newest open confirm opened through the **same**
514
+ `useConfirm()`, never another component's.
514
515
 
515
516
  **Keep the dialog open across steps**
516
517
 
@@ -585,6 +586,31 @@ const exportWorkspace = async () => {
585
586
  </script>
586
587
  ```
587
588
 
589
+ ### Several confirms at once
590
+
591
+ Confirms stack. A `confirm()` while another is open (from a button's
592
+ `onClick`, or two calls without an `await` between them) covers the open one
593
+ in place; the one beneath stays pending, and comes back, still waiting for
594
+ its answer, when the newer one closes. Escape and the backdrop answer only
595
+ the one on top. Two un-awaited calls are therefore both asked, newest first:
596
+ `await` each one when the order matters.
597
+
598
+ `stack` picks the `BbDialog` stack a confirm joins (every confirm joins the
599
+ confirms' own by default). Name a dialog's `stack` and the confirm replaces
600
+ that dialog's view while it is open, as a drill-in step would ([BbDialog](./BbDialog.md)
601
+ § Stacked dialogs); a name no other dialog uses shows it on top of the other
602
+ confirms, each dimming the one beneath.
603
+
604
+ ```ts
605
+ // An unsaved-changes question that takes the editor's place, not a layer on it.
606
+ const discard = await confirm({
607
+ title: 'Discard your changes?',
608
+ stack: 'editor', // the editor's <BbDialog stack="editor">
609
+ variant: 'destructive',
610
+ yes: 'Discard',
611
+ });
612
+ ```
613
+
588
614
  ### Rich content with portals
589
615
 
590
616
  When plain `text` isn't enough, render custom content in the dialog body via a
@@ -740,9 +766,9 @@ The map is typed where you write it by `definePt`, never with an imported
740
766
 
741
767
  - **Don't hand-build a yes/no dialog** out of `BbDialog` + buttons — busy
742
768
  states, dismissal semantics, ownership and focus handling already live here.
743
- - **Don't fire two `confirm()` calls without awaiting the first.** The second
744
- supersedes the first, which settles `false` — so a "delete these two things"
745
- flow written as two un-awaited confirms deletes nothing and asks once.
769
+ - **Two `confirm()` calls without an `await` between them ask both, newest
770
+ first** — the second covers the first. `await` each one when the questions
771
+ must come in order.
746
772
  - **Don't forget the `await`** — `confirm(...)` without it never gates
747
773
  anything.
748
774
  - **Don't call `close()` to "cancel"** a dialog whose buttons haven't run —
@@ -753,8 +779,8 @@ The map is typed where you write it by `definePt`, never with an imported
753
779
  - With `returning: true`, an implicit dismiss under the default
754
780
  `dismissAsNo: true` resolves with `no.onClick`'s return value — give No a
755
781
  callback that returns a sensible "declined" value.
756
- System dismissals (`duration`, `dismissAll()`, a superseding `confirm()`,
757
- owner unmount) still resolve `false`, so handle `false` too.
782
+ System dismissals (`duration`, `dismissAll()`, owner unmount) still resolve
783
+ `false`, so handle `false` too.
758
784
  - `confirm()` rejects keys `BbConfirmMessage` doesn't declare, also on a
759
785
  message built in a variable first: build it from `BbConfirmMessage` fields
760
786
  only (spread a wider object and the extra keys fail to type-check).
@@ -777,7 +803,7 @@ The map is typed where you write it by `definePt`, never with an imported
777
803
 
778
804
  | Prop | Type | Default | Required | Description |
779
805
  | --- | --- | --- | --- | --- |
780
- | `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: `action`, `close`, `content`, `footer`, `header`, `root`, `sheet`, `text`, `title`. 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 `BbConfirmProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
806
+ | `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: `action`, `close`, `content`, `footer`, `header`, `root`, `sheet`, `text`, `title`. States: `default`, `destructive`, `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 `BbConfirmProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
781
807
 
782
808
  ## Passthrough parts and states
783
809
 
@@ -800,6 +826,8 @@ States are listed in precedence order: when two are on at once and their entries
800
826
  | State | When it is on |
801
827
  | --- | --- |
802
828
  | `open` | Component-wide: a confirm is showing. |
829
+ | `default` | Component-wide, from the message: `variant: 'default'`. Merged after the part's base entry and before its states, so the real states still win. |
830
+ | `destructive` | Component-wide, from the message: `variant: 'destructive'`. Below the real states, like every variant. |
803
831
 
804
832
  ## Events
805
833
 
@@ -822,7 +850,7 @@ States are listed in precedence order: when two are on at once and their entries
822
850
  - `BbDialog` _(public — [contract](./BbDialog.md))_ — its own pt parts (`BbDialog`): `header` → `div.bb-dialog__header`, `title` → `span.bb-dialog__title`, `description` → `p.bb-dialog__description`, `close` → `CloseButton`, `content` → `div.bb-dialog__content`, `footer` → `div.bb-dialog__footer`; hands `BbOffCanvas` the pt map `{ root: 'root', header: 'header', title: 'title', description: 'description', content: 'content', footer: 'footer', close: 'close', sheet: 'root', }` (ours → theirs); documented CSS variables: `--px`, `--close-size`
823
851
  - `CloseButton` _(internal — not importable, reach it through `BbDialog`)_ — documented CSS variables: `--size`, `--p`
824
852
  - `BbOffCanvas` _(public — [contract](./BbOffCanvas.md))_ — its own pt parts (`BbOffCanvas`): `header` → `div.bb-offcanvas__header`, `title` → `span.bb-offcanvas__title`, `description` → `p.bb-offcanvas__description`, `close` → `CloseButton`, `content` → `div.bb-offcanvas__content`, `footer` → `div.bb-offcanvas__footer`; documented CSS variables: `--stack-x`, `--snap-y`, `--stack-fill`, `--stack-transition-duration`, `--px`, `--handle-w`, `--handle-h`, `--handle-bg`, `--safe-top`, `--close-size`; also mounts `CloseButton`
825
- - `BbButton` _(public — [contract](./BbButton.md))_ — its own pt parts (`BbButton`): `root` → `BbBaseButton`, `spinner` → `BbSpinner`, `icon` → `BbIcon`, `text` → `span.bb-button__text`; documented CSS variables: `--h-xs`, `--h`, `--icon-size`, `--px`, `--fs`, `--r`, `--gap`, `--bg`, `--bg-hover`, `--bg-pressed`, `--fg`, `--border-color`, `--ring-color`, `--ring-size`, `--bw`, `--fg-hover`, `--border-hover`, `--fg-pressed`, `--border-pressed`, `--bg-disabled`, `--fg-disabled`, `--border-disabled`, `--opacity-disabled`, `--elev-tier`, `--elev`; also mounts `BbIcon`, `BbSpinner`
853
+ - `BbButton` _(public — [contract](./BbButton.md))_ — its own pt parts (`BbButton`): `root` → `BbBaseButton`, `spinner` → `BbSpinner`, `icon` → `span.bb-button__icon`, `icon` → `BbIcon`, `icon` → `span.bb-button__prepend-icon`, `text` → `span.bb-button__text`, `icon` → `span.bb-button__append-icon`; documented CSS variables: `--h-xs`, `--h`, `--icon-size`, `--px`, `--fs`, `--r`, `--gap`, `--bg`, `--bg-hover`, `--bg-pressed`, `--fg`, `--border-color`, `--ring-color`, `--ring-size`, `--bw`, `--fg-hover`, `--border-hover`, `--fg-pressed`, `--border-pressed`, `--bg-disabled`, `--fg-disabled`, `--border-disabled`, `--opacity-disabled`, `--elev-tier`, `--elev`; also mounts `BbIcon`, `BbSpinner`
826
854
  - `BbBaseButton` _(public — [contract](./BbBaseButton.md))_ — its own pt parts (`BbBaseButton`): `root` → `RouterComponent`, `root` → `a`, `root` → `component`; also mounts `RouterComponent`
827
855
 
828
856
  ## See Also
@@ -251,7 +251,8 @@ On mobile the calendar opens in a bottom off-canvas sheet instead of a floating
251
251
  popover (`adaptive`, on by default via `config.adaptive`; forward extra sheet
252
252
  props with `offCanvasProps`). Position the desktop popover with `placement`,
253
253
  `offset`, `padding`, `boundary`, and `disableFlip` — the same knobs as the other
254
- overlays. Escape and backdrop clicks close it; focus returns to the activator.
254
+ overlays (`placement` is read at open: a change while open applies at the next
255
+ open). Escape and backdrop clicks close it; focus returns to the activator.
255
256
 
256
257
  The sheet can be **dragged down to dismiss** and shows **no ✕** — picking,
257
258
  drag, backdrop tap and Escape close it. The time wheels and the year list are
@@ -878,7 +878,7 @@ label>')` matches nothing; query each segment by its own label instead. See
878
878
 
879
879
  | Prop | Type | Default | Required | Description |
880
880
  | --- | --- | --- | --- | --- |
881
- | `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: `activator`, `arrow`, `box`, `cellColumnHeader`, `clear`, `day`, `dayButton`, `description`, `header`, `hint`, `icon`, `input`, `item`, `label`, `message`, `month`, `monthItem`, `panel`, `prefix`, `root`, `sheet`, `spinner`, `suffix`, `year`, `yearItem`. States: `active`, `disabled`, `errors`, `hasValue`, `highlighted`, `inRange`, `loading`, `open`, `outside`, `rangeEnd`, `rangeStart`, `readonly`, `selected`, `today`, `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 `BbDatePickerInputProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
881
+ | `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: `activator`, `arrow`, `box`, `cellColumnHeader`, `clear`, `day`, `dayButton`, `description`, `header`, `hint`, `icon`, `input`, `item`, `label`, `message`, `month`, `monthItem`, `panel`, `prefix`, `root`, `sheet`, `spinner`, `suffix`, `year`, `yearItem`. States: `active`, `disabled`, `errors`, `ghost`, `hasValue`, `highlighted`, `inRange`, `loading`, `open`, `outline`, `outside`, `rangeEnd`, `rangeStart`, `readonly`, `secondary`, `selected`, `today`, `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 `BbDatePickerInputProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
882
882
  | `adaptive` | `boolean \| undefined` | ``config.adaptive` (`true`)` | | On mobile the calendar opens inside a bottom off-canvas sheet instead of a floating popover, mirroring the adaptive behaviour of `BbPopover`/`BbSelect`. When unset, falls back to the global `config.adaptive`. |
883
883
  | `ampm` | `boolean \| undefined` | `false` | | 12-hour display with an AM/PM segment (requires `type="datetime"`). Purely a field-composition concern: `modelValue` and the `time` model stay 24-hour regardless. Type `A`/`P` (or ArrowUp/Down) to set the meridiem. |
884
884
  | `append:icon` | `string \| undefined` | | | Name of the icon to be added at the end of the input. |
@@ -982,6 +982,9 @@ States are listed in precedence order: when two are on at once and their entries
982
982
  | `open` | Component-wide: the calendar is showing — `pt:activator:open` styles the trigger while it is. |
983
983
  | `highlighted` | Per node, on the cells: the keyboard cursor. |
984
984
  | `loading` | Component-wide: `loading` is on; the box shows its `spinner`. |
985
+ | `ghost` | On the field's parts: `variant: 'ghost'`. Below the real states, like every variant. |
986
+ | `outline` | On the field's parts: `variant: 'outline'`. Merged after the part's base entry and before its states, so the real states still win. |
987
+ | `secondary` | On the field's parts: `variant: 'secondary'`. Below the real states, like every variant. |
985
988
 
986
989
  ## Events
987
990