bitboss-ui 3.0.0-beta.56 → 3.0.0-beta.58

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 (300) hide show
  1. package/README.md +24 -0
  2. package/bin/bitboss-ui-mcp.mjs +115 -19
  3. package/bin/bitboss-ui.mjs +49 -10
  4. package/dist/ai/BbBreadcrumbs.md +1 -1
  5. package/dist/ai/BbCheckbox.md +1 -1
  6. package/dist/ai/BbCheckboxGroup.md +1 -1
  7. package/dist/ai/BbColorInput.md +2 -2
  8. package/dist/ai/BbColorPalette.md +1 -1
  9. package/dist/ai/BbConfirm.md +1 -1
  10. package/dist/ai/BbDatePicker.md +1 -1
  11. package/dist/ai/BbDatePickerInput.md +2 -2
  12. package/dist/ai/BbDialog.md +580 -207
  13. package/dist/ai/BbDropdown.md +3 -3
  14. package/dist/ai/BbDropdownButton.md +149 -99
  15. package/dist/ai/BbDropzone.md +1 -1
  16. package/dist/ai/BbForm.md +84 -10
  17. package/dist/ai/BbHost.md +1 -1
  18. package/dist/ai/BbNumberInput.md +1 -1
  19. package/dist/ai/BbOffCanvas.md +341 -190
  20. package/dist/ai/BbPopover.md +1 -1
  21. package/dist/ai/BbRadio.md +1 -1
  22. package/dist/ai/BbRadioGroup.md +1 -1
  23. package/dist/ai/BbRating.md +1 -1
  24. package/dist/ai/BbSelect.md +2 -2
  25. package/dist/ai/BbSelectPopover.md +8 -9
  26. package/dist/ai/BbSlider.md +1 -1
  27. package/dist/ai/BbSwitch.md +1 -1
  28. package/dist/ai/BbSwitchGroup.md +1 -1
  29. package/dist/ai/BbTable.md +9 -1
  30. package/dist/ai/BbTag.md +1 -1
  31. package/dist/ai/BbTextInput.md +1 -1
  32. package/dist/ai/BbTextarea.md +1 -1
  33. package/dist/ai/BbTimePicker.md +1 -1
  34. package/dist/ai/BbTimePickerInput.md +2 -2
  35. package/dist/ai/changelog.json +2122 -6
  36. package/dist/ai/components.json +89 -86
  37. package/dist/ai/composables/useBbDialogContext.md +26 -18
  38. package/dist/ai/composables/useBbFormContext.md +9 -9
  39. package/dist/ai/composables/useBbOffCanvasContext.md +6 -3
  40. package/dist/ai/guides/agent-contract.md +1 -1
  41. package/dist/ai/guides/ai-router.md +2 -1
  42. package/dist/ai/guides/eslint-rules.md +4 -2
  43. package/dist/ai/guides/icons-policy.md +6 -7
  44. package/dist/ai/guides/installation-and-plugin-setup.md +1 -0
  45. package/dist/ai/guides/migration/components/bb-dialog.md +13 -12
  46. package/dist/ai/guides/migration/components/bb-dropdown-button.md +32 -9
  47. package/dist/ai/guides/migration/components/bb-offcanvas.md +10 -9
  48. package/dist/ai/guides/migration/v2-to-v3.md +85 -2
  49. package/dist/ai/guides/migration/v3-beta-tooling.md +36 -9
  50. package/dist/ai/helpers/inertia/manifest.json +1 -1
  51. package/dist/ai/index.md +2 -2
  52. package/dist/ai/manifest/common.json +119 -0
  53. package/dist/ai/manifest/components/BbAccordion.json +9 -10
  54. package/dist/ai/manifest/components/BbAlert.json +14 -15
  55. package/dist/ai/manifest/components/BbAsterisk.json +1 -2
  56. package/dist/ai/manifest/components/BbAvatar.json +8 -9
  57. package/dist/ai/manifest/components/BbBadge.json +10 -11
  58. package/dist/ai/manifest/components/BbBadgeButton.json +41 -42
  59. package/dist/ai/manifest/components/BbBaseButton.json +43 -44
  60. package/dist/ai/manifest/components/BbBaseCheckboxIcon.json +9 -10
  61. package/dist/ai/manifest/components/BbBaseRadioIcon.json +8 -9
  62. package/dist/ai/manifest/components/BbBaseSwitchIcon.json +9 -10
  63. package/dist/ai/manifest/components/BbBreadcrumbs.json +10 -11
  64. package/dist/ai/manifest/components/BbBreadcrumbs.tree.json +1 -1
  65. package/dist/ai/manifest/components/BbButton.json +52 -53
  66. package/dist/ai/manifest/components/BbCalendar.json +29 -30
  67. package/dist/ai/manifest/components/BbCheckbox.json +42 -43
  68. package/dist/ai/manifest/components/BbCheckboxGroup.json +61 -62
  69. package/dist/ai/manifest/components/BbCollapsible.json +6 -7
  70. package/dist/ai/manifest/components/BbColorInput.json +67 -68
  71. package/dist/ai/manifest/components/BbColorInput.tree.json +1 -1
  72. package/dist/ai/manifest/components/BbColorPalette.json +22 -23
  73. package/dist/ai/manifest/components/BbColorPalette.tree.json +1 -1
  74. package/dist/ai/manifest/components/BbConfirm.json +1 -2
  75. package/dist/ai/manifest/components/BbConfirm.tree.json +1 -1
  76. package/dist/ai/manifest/components/BbDatePicker.json +42 -43
  77. package/dist/ai/manifest/components/BbDatePicker.tree.json +1 -1
  78. package/dist/ai/manifest/components/BbDatePickerInput.json +74 -75
  79. package/dist/ai/manifest/components/BbDatePickerInput.tree.json +1 -1
  80. package/dist/ai/manifest/components/BbDialog.json +37 -28
  81. package/dist/ai/manifest/components/BbDialog.tree.json +1 -1
  82. package/dist/ai/manifest/components/BbDropdown.json +33 -34
  83. package/dist/ai/manifest/components/BbDropdown.tree.json +1 -1
  84. package/dist/ai/manifest/components/BbDropdownButton.json +72 -33
  85. package/dist/ai/manifest/components/BbDropdownButton.tree.json +1 -1
  86. package/dist/ai/manifest/components/BbDropdownGroup.json +4 -4
  87. package/dist/ai/manifest/components/BbDropzone.json +21 -22
  88. package/dist/ai/manifest/components/BbForm.json +10 -9
  89. package/dist/ai/manifest/components/BbHost.tree.json +1 -1
  90. package/dist/ai/manifest/components/BbHoverCard.json +16 -17
  91. package/dist/ai/manifest/components/BbIcon.json +4 -5
  92. package/dist/ai/manifest/components/BbIndicator.json +8 -9
  93. package/dist/ai/manifest/components/BbNumberInput.json +66 -67
  94. package/dist/ai/manifest/components/BbOffCanvas.json +37 -28
  95. package/dist/ai/manifest/components/BbOffCanvas.tree.json +10 -0
  96. package/dist/ai/manifest/components/BbPagination.json +14 -15
  97. package/dist/ai/manifest/components/BbPopover.json +21 -22
  98. package/dist/ai/manifest/components/BbPopover.tree.json +1 -1
  99. package/dist/ai/manifest/components/BbProgress.json +6 -7
  100. package/dist/ai/manifest/components/BbPtScope.json +1 -1
  101. package/dist/ai/manifest/components/BbRadio.json +37 -38
  102. package/dist/ai/manifest/components/BbRadioGroup.json +62 -63
  103. package/dist/ai/manifest/components/BbRating.json +40 -41
  104. package/dist/ai/manifest/components/BbSelect.json +77 -78
  105. package/dist/ai/manifest/components/BbSelect.tree.json +1 -1
  106. package/dist/ai/manifest/components/BbSelectPopover.json +51 -52
  107. package/dist/ai/manifest/components/BbSelectPopover.tree.json +1 -1
  108. package/dist/ai/manifest/components/BbSlider.json +40 -41
  109. package/dist/ai/manifest/components/BbSmoothHeight.json +7 -8
  110. package/dist/ai/manifest/components/BbSpinner.json +3 -4
  111. package/dist/ai/manifest/components/BbSwitch.json +42 -43
  112. package/dist/ai/manifest/components/BbSwitchGroup.json +62 -63
  113. package/dist/ai/manifest/components/BbTable.json +68 -69
  114. package/dist/ai/manifest/components/BbTabs.json +27 -28
  115. package/dist/ai/manifest/components/BbTabsList.json +2 -3
  116. package/dist/ai/manifest/components/BbTabsPanels.json +1 -2
  117. package/dist/ai/manifest/components/BbTabsRoot.json +26 -26
  118. package/dist/ai/manifest/components/BbTag.json +48 -49
  119. package/dist/ai/manifest/components/BbTextInput.json +64 -65
  120. package/dist/ai/manifest/components/BbTextarea.json +59 -60
  121. package/dist/ai/manifest/components/BbTimePicker.json +26 -27
  122. package/dist/ai/manifest/components/BbTimePicker.tree.json +1 -1
  123. package/dist/ai/manifest/components/BbTimePickerInput.json +56 -57
  124. package/dist/ai/manifest/components/BbTimePickerInput.tree.json +1 -1
  125. package/dist/ai/manifest/components/BbToast.json +1 -2
  126. package/dist/ai/manifest/components/BbTooltip.json +16 -17
  127. package/dist/ai/manifest/components/BbTree.json +4 -5
  128. package/dist/ai/manifest/components/ChipsBox.json +3 -3
  129. package/dist/ai/manifest/components/ClearableButton.json +1 -1
  130. package/dist/ai/manifest/components/CommaBox.json +1 -1
  131. package/dist/ai/manifest/components/CommonField.json +32 -32
  132. package/dist/ai/manifest/components/CommonFieldInput.json +15 -15
  133. package/dist/ai/manifest/components/CommonPopover.json +17 -17
  134. package/dist/ai/manifest/components/CommonTimeSelector.json +9 -9
  135. package/dist/ai/manifest/components/FlatListBox.json +14 -14
  136. package/dist/ai/manifest/components/GroupedListBox.json +15 -15
  137. package/dist/ai/manifest/components/ListBox.json +17 -17
  138. package/dist/ai/manifest/components/OptionsContainer.json +16 -16
  139. package/dist/ai/manifest/index.json +89 -85
  140. package/dist/ai/manifest/meta.json +43 -2
  141. package/dist/ai/manifest/types.advanced.json +10 -10
  142. package/dist/ai/manifest/types.api.json +51 -48
  143. package/dist/ai/recipes/inertia/approvals-inbox.md +19 -12
  144. package/dist/ai/recipes/inertia/inline-edit-workspace.md +6 -0
  145. package/dist/ai/recipes/inertia/onboarding.md +6 -0
  146. package/dist/ai/recipes/inertia/ownership-atlas.md +6 -0
  147. package/dist/ai/recipes/inertia/record-form.md +6 -33
  148. package/dist/ai/recipes/inertia/records-workspace.md +6 -1
  149. package/dist/ai/recipes/inertia/settings-workspace.md +113 -137
  150. package/dist/ai/recipes/inertia/upload-center.md +6 -0
  151. package/dist/ai/recipes/nuxt/approvals-inbox.md +13 -12
  152. package/dist/ai/recipes/nuxt/record-form.md +6 -33
  153. package/dist/ai/recipes/nuxt/records-workspace.md +0 -1
  154. package/dist/ai/recipes/nuxt/settings-workspace.md +107 -138
  155. package/dist/ai/recipes/vue/approvals-inbox.md +13 -12
  156. package/dist/ai/recipes/vue/record-form.md +6 -33
  157. package/dist/ai/recipes/vue/records-workspace.md +0 -1
  158. package/dist/ai/recipes/vue/settings-workspace.md +107 -138
  159. package/dist/ai/source/BbButton.md +23 -3
  160. package/dist/ai/source/BbCheckbox.md +3 -1
  161. package/dist/ai/source/BbCheckboxGroup.md +3 -1
  162. package/dist/ai/source/BbColorInput.md +3 -1
  163. package/dist/ai/source/BbDatePickerInput.md +3 -1
  164. package/dist/ai/source/BbDialog.md +207 -32
  165. package/dist/ai/source/BbDropdownButton.md +103 -112
  166. package/dist/ai/source/BbDropzone.md +3 -1
  167. package/dist/ai/source/BbForm.md +76 -13
  168. package/dist/ai/source/BbNumberInput.md +3 -1
  169. package/dist/ai/source/BbOffCanvas.md +761 -33
  170. package/dist/ai/source/BbRadio.md +6 -2
  171. package/dist/ai/source/BbRadioGroup.md +3 -1
  172. package/dist/ai/source/BbRating.md +3 -1
  173. package/dist/ai/source/BbSelect.md +3 -1
  174. package/dist/ai/source/BbSlider.md +7 -4
  175. package/dist/ai/source/BbSwitch.md +2 -0
  176. package/dist/ai/source/BbSwitchGroup.md +2 -0
  177. package/dist/ai/source/BbTag.md +3 -1
  178. package/dist/ai/source/BbTextInput.md +3 -1
  179. package/dist/ai/source/BbTextarea.md +3 -1
  180. package/dist/ai/source/BbTimePickerInput.md +3 -1
  181. package/dist/components/BbBaseButton/BbBaseButton.vue_vue_type_script_setup_true_lang.js +5 -5
  182. package/dist/components/BbButton/BbButton.vue_vue_type_script_setup_true_lang.js +75 -74
  183. package/dist/components/BbButton/types.d.ts +6 -0
  184. package/dist/components/BbCheckbox/BbCheckbox.vue_vue_type_script_setup_true_lang.js +90 -89
  185. package/dist/components/BbCheckbox/types.d.ts +1 -1
  186. package/dist/components/BbCheckboxGroup/BbCheckboxGroup.vue_vue_type_script_setup_true_lang.js +91 -90
  187. package/dist/components/BbCheckboxGroup/types.d.ts +1 -1
  188. package/dist/components/BbColorInput/BbColorInput.vue_vue_type_script_setup_true_lang.js +69 -68
  189. package/dist/components/BbColorInput/types.d.ts +1 -1
  190. package/dist/components/BbDatePickerInput/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +288 -287
  191. package/dist/components/BbDatePickerInput/types.d.ts +1 -1
  192. package/dist/components/BbDialog/BbDialog.vue.d.ts +11 -2
  193. package/dist/components/BbDialog/BbDialog.vue_vue_type_script_setup_true_lang.js +243 -189
  194. package/dist/components/BbDialog/types.d.ts +75 -14
  195. package/dist/components/BbDropdownButton/BbDropdownButton.vue_vue_type_script_setup_true_lang.js +143 -100
  196. package/dist/components/BbDropdownButton/types.d.ts +25 -15
  197. package/dist/components/BbDropzone/BbDropzone.vue_vue_type_script_setup_true_lang.js +150 -149
  198. package/dist/components/BbDropzone/types.d.ts +1 -1
  199. package/dist/components/BbForm/BbForm.vue.d.ts +3 -3
  200. package/dist/components/BbForm/BbForm.vue_vue_type_script_setup_true_lang.js +186 -173
  201. package/dist/components/BbForm/formSchema.d.ts +9 -0
  202. package/dist/components/BbHost/BbHostOpening.js +1 -1
  203. package/dist/components/BbNumberInput/BbNumberInput.vue_vue_type_script_setup_true_lang.js +143 -142
  204. package/dist/components/BbNumberInput/types.d.ts +1 -1
  205. package/dist/components/BbOffCanvas/BbOffCanvas.vue.d.ts +12 -2
  206. package/dist/components/BbOffCanvas/BbOffCanvas.vue_vue_type_script_setup_true_lang.js +518 -270
  207. package/dist/components/BbOffCanvas/sheetSnap.d.ts +64 -0
  208. package/dist/components/BbOffCanvas/sheetSnap.js +58 -0
  209. package/dist/components/BbOffCanvas/types.d.ts +76 -14
  210. package/dist/components/BbPagination/BbPagination.vue_vue_type_script_setup_true_lang.js +68 -68
  211. package/dist/components/BbRadio/BbRadio.vue_vue_type_script_setup_true_lang.js +66 -65
  212. package/dist/components/BbRadio/types.d.ts +1 -1
  213. package/dist/components/BbRadioGroup/BbRadioGroup.vue_vue_type_script_setup_true_lang.js +96 -95
  214. package/dist/components/BbRadioGroup/types.d.ts +1 -1
  215. package/dist/components/BbRating/BbRating.vue_vue_type_script_setup_true_lang.js +79 -78
  216. package/dist/components/BbRating/types.d.ts +1 -1
  217. package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +153 -152
  218. package/dist/components/BbSelect/types.d.ts +1 -1
  219. package/dist/components/BbSlider/BbSlider.vue_vue_type_script_setup_true_lang.js +106 -105
  220. package/dist/components/BbSlider/types.d.ts +1 -1
  221. package/dist/components/BbSwitch/BbSwitch.vue_vue_type_script_setup_true_lang.js +86 -85
  222. package/dist/components/BbSwitchGroup/BbSwitchGroup.vue_vue_type_script_setup_true_lang.js +131 -130
  223. package/dist/components/BbTag/BbTag.vue_vue_type_script_setup_true_lang.js +64 -63
  224. package/dist/components/BbTag/types.d.ts +1 -1
  225. package/dist/components/BbTextInput/BbTextInput.vue_vue_type_script_setup_true_lang.js +71 -70
  226. package/dist/components/BbTextInput/types.d.ts +1 -1
  227. package/dist/components/BbTextarea/BbTextarea.vue_vue_type_script_setup_true_lang.js +81 -80
  228. package/dist/components/BbTextarea/types.d.ts +1 -1
  229. package/dist/components/BbTimePickerInput/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +169 -168
  230. package/dist/components/BbTimePickerInput/types.d.ts +1 -1
  231. package/dist/composables/formSubmitLock.d.ts +6 -1
  232. package/dist/composables/hostOpenings.d.ts +10 -4
  233. package/dist/composables/hostOpenings.js +2 -2
  234. package/dist/composables/overlayRegistry.d.ts +56 -8
  235. package/dist/composables/overlayRegistry.js +219 -110
  236. package/dist/composables/useBbDialogContext.d.ts +42 -10
  237. package/dist/composables/useBbDialogContext.js +41 -29
  238. package/dist/composables/useBbFormContext.d.ts +15 -3
  239. package/dist/composables/useBbFormContext.js +43 -36
  240. package/dist/composables/useBbTabsContext.js +140 -171
  241. package/dist/composables/useKeyboardInset.js +10 -20
  242. package/dist/composables/useOnDemandOpener.d.ts +6 -13
  243. package/dist/composables/useOnDemandOpener.js +47 -22
  244. package/dist/composables/useOverlayNavigation.d.ts +37 -0
  245. package/dist/composables/useOverlayNavigation.js +89 -0
  246. package/dist/composables/useUrlQueryParam.d.ts +21 -0
  247. package/dist/composables/useUrlQueryParam.js +48 -0
  248. package/dist/directives/overlayTrigger.d.ts +4 -2
  249. package/dist/directives/overlayTrigger.js +42 -41
  250. package/dist/i18n/locales/cs.json +4 -1
  251. package/dist/i18n/locales/da.json +4 -1
  252. package/dist/i18n/locales/de-CH.json +4 -1
  253. package/dist/i18n/locales/de.json +4 -1
  254. package/dist/i18n/locales/el.json +4 -1
  255. package/dist/i18n/locales/en-GB.json +4 -1
  256. package/dist/i18n/locales/en.json +4 -1
  257. package/dist/i18n/locales/es-MX.json +4 -1
  258. package/dist/i18n/locales/es.json +4 -1
  259. package/dist/i18n/locales/fi.json +4 -1
  260. package/dist/i18n/locales/fr.json +4 -1
  261. package/dist/i18n/locales/hu.json +4 -1
  262. package/dist/i18n/locales/it.json +4 -1
  263. package/dist/i18n/locales/ja.json +4 -1
  264. package/dist/i18n/locales/ko.json +4 -1
  265. package/dist/i18n/locales/nb.json +4 -1
  266. package/dist/i18n/locales/nl.json +4 -1
  267. package/dist/i18n/locales/pl.json +4 -1
  268. package/dist/i18n/locales/pt-BR.json +4 -1
  269. package/dist/i18n/locales/pt-PT.json +4 -1
  270. package/dist/i18n/locales/ro.json +4 -1
  271. package/dist/i18n/locales/ru.json +4 -1
  272. package/dist/i18n/locales/sv.json +4 -1
  273. package/dist/i18n/locales/tr.json +4 -1
  274. package/dist/i18n/locales/uk.json +4 -1
  275. package/dist/i18n/locales/zh-CN.json +4 -1
  276. package/dist/i18n/locales/zh-HK.json +4 -1
  277. package/dist/i18n/locales/zh-TW.json +4 -1
  278. package/dist/index.d.ts +3 -3
  279. package/dist/index.js +73 -73
  280. package/dist/llms-full.txt +1851 -1178
  281. package/dist/llms-medium.txt +4 -2
  282. package/dist/llms.txt +2 -2
  283. package/dist/locale-blueprint.json +4 -1
  284. package/dist/plugin.js +28 -27
  285. package/dist/styles.css +2 -2
  286. package/dist/utilities/functions/isTextEntry.d.ts +5 -0
  287. package/dist/utilities/functions/isTextEntry.js +15 -0
  288. package/dist/utilities/misc/autofocus.d.ts +20 -0
  289. package/dist/utilities/misc/autofocus.js +11 -0
  290. package/dist/utils/copyData.d.ts +8 -5
  291. package/dist/utils/copyData.js +6 -6
  292. package/dist/utils/versionCheck.js +1 -1
  293. package/llms.txt +2 -2
  294. package/package.json +1 -1
  295. package/scripts/lib/agent-manifest.mjs +231 -18
  296. package/scripts/lib/eslint-disable.mjs +19 -0
  297. package/scripts/lib/eslint-plugin.d.ts +2 -0
  298. package/scripts/lib/eslint-plugin.mjs +57 -0
  299. package/scripts/lib/prefer-v-bb-dialog.mjs +455 -0
  300. package/scripts/lib/validate-bb-markup.mjs +64 -10
package/README.md CHANGED
@@ -599,6 +599,30 @@ script, a switch bound to the same ref and your own components are never
599
599
  reported. `BbAccordion` wires all of it for you.
600
600
  `bitboss-ui check` reports the same as `collapsible-trigger-aria`.
601
601
 
602
+ #### A dialog opened through a ref: `prefer-v-bb-dialog`
603
+
604
+ A `ref(false)` whose only jobs are a `BbDialog` / `BbOffCanvas` `v-model` and
605
+ `@click="open = true"` is wiring the library does for you.
606
+ `bitboss-ui/prefer-v-bb-dialog` (warn, a suggestion) reports it and points at
607
+ the id form, where the trigger also gets `aria-haspopup`, `aria-expanded`,
608
+ `aria-controls` and focus back:
609
+
610
+ ```vue
611
+ <template>
612
+ <BbButton v-bb-dialog="'create-label'">New label</BbButton>
613
+ <BbDialog id="create-label" title="Create label">…</BbDialog>
614
+ </template>
615
+ ```
616
+
617
+ `--fix` rewrites it only when nothing else uses the ref: it drops the
618
+ declaration (and the `ref` import once unused), turns the `v-model` into an
619
+ `id` and each click into `v-bb-dialog` (`v-bb-off-canvas` on a `BbOffCanvas`).
620
+ A ref the code also writes (`open = false` in a Cancel, `open.value = false`
621
+ after a save) is reported without a fix: those closes become the slots'
622
+ `close` / `complete`. A ref anything reads (`v-if="open"`, `watch(open)`, a
623
+ toggle) is never reported, since the page needs the state.
624
+ `bitboss-ui check` reports the same as `prefer-v-bb-dialog` (a warning).
625
+
602
626
  #### A rule nobody registered: `no-unregistered-rule`
603
627
 
604
628
  A string rule is a vee-validate rule name, and vee-validate knows only the
@@ -1161,6 +1161,19 @@ function getComponent({
1161
1161
  const type = (manifest.types ?? []).find((t) => t.name === name);
1162
1162
  if (type) {
1163
1163
  const use = type.usedBy?.[0];
1164
+ // Q74.1: a component's own Props type is that component's props.
1165
+ const propsOf =
1166
+ type.component && name === `${type.component}Props`
1167
+ ? type.component
1168
+ : null;
1169
+ // Q74.2: `fields` stand in for a declaration that adds nothing.
1170
+ const shape = type.definition
1171
+ ? '`definition` above is the type itself'
1172
+ : type.fields
1173
+ ? '`fields` above are its shape'
1174
+ : propsOf
1175
+ ? `Its fields are ${possessive(propsOf)} props: get_component('${propsOf}')`
1176
+ : 'It is described above';
1164
1177
  return {
1165
1178
  found: true,
1166
1179
  kind: 'type',
@@ -1179,9 +1192,10 @@ function getComponent({
1179
1192
  ...(type.fields ? { fields: type.fields } : {}),
1180
1193
  // A union of private members: each member's fields (Q51.21).
1181
1194
  ...(type.members ? { members: type.members } : {}),
1195
+ ...(propsOf ? { propsOf } : {}),
1182
1196
  import: `import type { ${type.replacedBy ?? name} } from 'bitboss-ui';`,
1183
1197
  hint: use
1184
- ? `A type, not a component: it types ${possessive(use.component)} \`${use.name}\` ${use.surface}. \`definition\` above is the type itself; call get_component('${use.component}') to see it in use.`
1198
+ ? `A type, not a component: it types ${possessive(use.component)} \`${use.name}\` ${use.surface}. ${shape}; call get_component('${use.component}') to see it in use.`
1185
1199
  : 'A type, not a component — import it for the value you pass, never write it as a tag.',
1186
1200
  };
1187
1201
  }
@@ -2124,7 +2138,11 @@ function docIndex() {
2124
2138
  ? `accepted values ${type.values.join(' | ')}`
2125
2139
  : type.fields
2126
2140
  ? `object shape, fields ${type.fields.join('; ')}`
2127
- : String(type.definition ?? '')) +
2141
+ : type.definition
2142
+ ? String(type.definition)
2143
+ : type.component && type.name === `${type.component}Props`
2144
+ ? `the props of ${type.component}`
2145
+ : '') +
2128
2146
  `. import type { ${type.name} } from 'bitboss-ui'.`,
2129
2147
  read: { tool: 'get_component', args: { name: type.name } },
2130
2148
  });
@@ -2533,6 +2551,8 @@ const ROW_FIELDS =
2533
2551
  * as their hand-written `summary`; `detail: 'rows'` → the full rows as before.
2534
2552
  */
2535
2553
  const CHANGES_PAGE = 60;
2554
+ /** The lines' share of a page (the envelope adds ~1K): keeps it under 8K. */
2555
+ const CHANGES_PAGE_CHARS = 6000;
2536
2556
 
2537
2557
  function changeLine(row, focus) {
2538
2558
  // 16 form controls in full is ~250 chars of the line; the component filter
@@ -2554,6 +2574,66 @@ function changeLine(row, focus) {
2554
2574
  return `${row.id} ${row.summary ?? firstSentence(row.description, 160)}`;
2555
2575
  }
2556
2576
 
2577
+ /**
2578
+ * One page of `[release, line]` pairs, grouped by release: it ends at
2579
+ * CHANGES_PAGE lines or CHANGES_PAGE_CHARS of them, so its size holds however
2580
+ * long the lines grow; the rest is a cursor away.
2581
+ */
2582
+ function pageLines(lines, cursor) {
2583
+ const start = Math.max(0, Number(cursor ?? 0) || 0);
2584
+ let end = start;
2585
+ for (let used = 0; end < lines.length && end - start < CHANGES_PAGE; end++) {
2586
+ used += lines[end][1].length + 3;
2587
+ if (used > CHANGES_PAGE_CHARS && end > start) break;
2588
+ }
2589
+ const byRelease = {};
2590
+ for (const [release, line] of lines.slice(start, end))
2591
+ (byRelease[release] ??= []).push(line);
2592
+ return {
2593
+ byRelease,
2594
+ more:
2595
+ end < lines.length
2596
+ ? { nextCursor: String(end), remaining: lines.length - end }
2597
+ : {},
2598
+ };
2599
+ }
2600
+
2601
+ /**
2602
+ * Q74.4: what the releases in range ADDED, as `[release, "area · what"]`,
2603
+ * oldest first; `unreleased` only when `until` is open. A component keeps
2604
+ * the lines of its own area (BbDialog → `dialog`) and those whose commits
2605
+ * touched its folder (a family scope: `inputs`).
2606
+ */
2607
+ function addedPairs(doc, { since, until, component }) {
2608
+ const area = component
2609
+ ? String(component).replace(/^Bb/, '').toLowerCase()
2610
+ : null;
2611
+ return Object.entries(doc.added ?? {})
2612
+ .filter(([at]) => {
2613
+ if (at === 'unreleased') return until == null;
2614
+ if (since != null && compareVersions(at, String(since)) <= 0)
2615
+ return false;
2616
+ if (until != null && compareVersions(at, String(until)) > 0) return false;
2617
+ return true;
2618
+ })
2619
+ .flatMap(([at, entries]) =>
2620
+ entries
2621
+ .map((entry) =>
2622
+ typeof entry === 'string' ? { text: entry, components: [] } : entry
2623
+ )
2624
+ .filter(
2625
+ ({ text, components }) =>
2626
+ !area ||
2627
+ text.split(' · ')[0] === area ||
2628
+ components.includes(String(component))
2629
+ )
2630
+ .map(({ text }) => [at, text])
2631
+ );
2632
+ }
2633
+
2634
+ const ADDED_HINT =
2635
+ 'Fixes are not tracked. What the range added, one line per feature: list_changes({ since, kind: "added" }).';
2636
+
2557
2637
  function changeLines(rows, cursor, withClassMap = false, focus) {
2558
2638
  const lines = [];
2559
2639
  const classRenames = {};
@@ -2574,18 +2654,12 @@ function changeLines(rows, cursor, withClassMap = false, focus) {
2574
2654
  ? -1
2575
2655
  : compareVersions(a, b)
2576
2656
  );
2657
+ const page = pageLines(lines, cursor);
2658
+ // The class map rides on the first page only.
2577
2659
  const start = Math.max(0, Number(cursor ?? 0) || 0);
2578
- const page = lines.slice(start, start + CHANGES_PAGE);
2579
- const byRelease = {};
2580
- for (const [release, line] of page) (byRelease[release] ??= []).push(line);
2581
2660
  return {
2582
- changes: byRelease,
2583
- ...(start + CHANGES_PAGE < lines.length
2584
- ? {
2585
- nextCursor: String(start + CHANGES_PAGE),
2586
- remaining: lines.length - start - CHANGES_PAGE,
2587
- }
2588
- : {}),
2661
+ changes: page.byRelease,
2662
+ ...page.more,
2589
2663
  ...(Object.keys(classRenames).length && start === 0 && !withClassMap
2590
2664
  ? {
2591
2665
  classRenames: `${Object.keys(classRenames).length} .bb-* class renames (the beta.36 sweep): the map with surface: 'class'`,
@@ -2683,6 +2757,24 @@ function listChanges({
2683
2757
  }
2684
2758
  }
2685
2759
 
2760
+ if (kind === 'added') {
2761
+ const pairs = addedPairs(doc, { since, until, component });
2762
+ const page = pageLines(pairs, cursor);
2763
+ return {
2764
+ version: doc.version,
2765
+ since: since ?? null,
2766
+ until: until ?? doc.version,
2767
+ ...(component ? { filteredBy: { component } } : {}),
2768
+ count: pairs.length,
2769
+ added: page.byRelease,
2770
+ ...page.more,
2771
+ hint:
2772
+ pairs.length === 0
2773
+ ? 'Nothing added in that range (fixes are not tracked).'
2774
+ : 'One "area · what" line per feature, grouped by release, from its feat commit. Breaking changes: the same call without kind. Next page: cursor: nextCursor.',
2775
+ };
2776
+ }
2777
+
2686
2778
  const rows = detail === 'rows';
2687
2779
  const filtered = (doc.breaking ?? []).filter(
2688
2780
  (row) =>
@@ -2742,7 +2834,8 @@ function listChanges({
2742
2834
  Object.fromEntries(Object.entries(bucket).filter(([, n]) => n > 0)),
2743
2835
  ])
2744
2836
  ),
2745
- hint: 'Counts only (a missing count is 0). What a bump breaks: list_changes({ since: "<your version>" }), one line per change; from v2: since: "2". One component: { component: "BbSelect" }. Full rows: detail: "rows".',
2837
+ added: addedPairs(doc, {}).length,
2838
+ hint: 'Counts only (a missing count is 0). What a bump breaks: list_changes({ since: "<your version>" }), one line per change; from v2: since: "2". One component: { component: "BbSelect" }. Full rows: detail: "rows". `added`: features, kind: "added".',
2746
2839
  };
2747
2840
  }
2748
2841
 
@@ -2799,10 +2892,11 @@ function listChanges({
2799
2892
  count: inRange.length,
2800
2893
  ...changeLines(inRange, cursor, surface === 'class', component),
2801
2894
  guide: doc.guide,
2895
+ added: addedPairs(doc, { since, until, component }).length,
2802
2896
  hint:
2803
2897
  inRange.length === 0
2804
- ? 'No breaking changes recorded in that range — features and fixes are deliberately not tracked here, so an empty result means nothing BREAKS, not that nothing changed.'
2805
- : 'One line per change, grouped by the release that shipped it (id, components, old → new, or the break in one sentence). Whole rows: detail: "rows". The `guide` page explains each. Next page: cursor: nextCursor.',
2898
+ ? `No breaking changes recorded in that range: nothing BREAKS. ${ADDED_HINT}`
2899
+ : `One line per change, grouped by the release that shipped it (id, components, old → new, or the break in one sentence). Whole rows: detail: "rows". The \`guide\` page explains each. Next page: cursor: nextCursor. \`added\`: features, kind: "added".`,
2806
2900
  };
2807
2901
  }
2808
2902
 
@@ -2815,7 +2909,7 @@ function listChanges({
2815
2909
  guide: doc.guide,
2816
2910
  hint:
2817
2911
  inRange.length === 0
2818
- ? 'No breaking changes recorded in that range — features and fixes are deliberately not tracked here, so an empty result means nothing BREAKS, not that nothing changed.'
2912
+ ? `No breaking changes recorded in that range: nothing BREAKS. ${ADDED_HINT}`
2819
2913
  : `Each entry names the component and the new spelling; \`guide\` is the migration page with the full explanation. ${ROW_FIELDS}`,
2820
2914
  };
2821
2915
  }
@@ -3009,7 +3103,7 @@ function buildServer() {
3009
3103
  'list_changes',
3010
3104
  {
3011
3105
  description:
3012
- 'Breaking changes between bitboss-ui releases — what breaks if you bump. Call with since=<the version you are on>: one line per change, grouped by release. No arguments: counts per release. Narrow with component / surface / kind; detail: "rows" for the full records. Only BREAKING changes are tracked; features and fixes are not.',
3106
+ 'Breaking changes between bitboss-ui releases — what breaks if you bump. Call with since=<the version you are on>: one line per change, grouped by release. No arguments: counts per release. Narrow with component / surface / kind; detail: "rows" for the full records. kind: "added" lists what the range added (features); fixes are not tracked.',
3013
3107
  inputSchema: {
3014
3108
  since: z
3015
3109
  .string()
@@ -3044,9 +3138,11 @@ function buildServer() {
3044
3138
  'Only renames of this surface (`item` = a field of an `items` entry, e.g. a dropdown row `key` → `value`).'
3045
3139
  ),
3046
3140
  kind: z
3047
- .enum(['rename', 'behaviour'])
3141
+ .enum(['rename', 'behaviour', 'added'])
3048
3142
  .optional()
3049
- .describe('Only renames, or only behaviour changes.'),
3143
+ .describe(
3144
+ "Only renames, or only behaviour changes; 'added': what the range added (features), one line each."
3145
+ ),
3050
3146
  detail: z
3051
3147
  .enum(['lines', 'rows'])
3052
3148
  .optional()
@@ -40,8 +40,8 @@
40
40
  * add Copy Inertia helpers into the app as files it owns
41
41
  * (scripts/lib/helpers-add.mjs); `helpers list|diff|update`
42
42
  * reports on them and refreshes the ones the app has not edited.
43
- * changelog Breaking changes between two releases — `--since <version>`
44
- * answers "what breaks if I bump", without MCP. Reads the
43
+ * changelog Breaking changes between two releases, then what they added —
44
+ * `--since <version>` answers "what breaks if I bump", without MCP. Reads the
45
45
  * installed `dist/ai/changelog.json`.
46
46
  * mcp Start a stdio MCP server exposing the dist/ai knowledge base
47
47
  * (search_docs, search_components, get_component, get_composable,
@@ -167,7 +167,7 @@ function coreRules(version) {
167
167
  1. **Start at the AI Router**: \`${ROUTER}\` — which file to open next (do not dump the full catalogue into context).
168
168
  2. **Obey the agent contract**: \`${CONTRACT}\`.
169
169
  3. **Prefer \`Bb*\` consumer components**; never use entries marked "Reference Only - Internal" unless the user explicitly asks for internals. (\`BbBaseButton\` and the \`BbBase*Icon\` glyphs are consumer API; the \`Common*\` building blocks are not.)
170
- 4. **Never invent prop/event/slot names** — open \`${KNOWLEDGE_BASE}/<ComponentName>.md\` (Usage & Guidelines first) or its API file \`${KNOWLEDGE_BASE}/manifest/components/<ComponentName>.json\` (one member per line; the list is \`${KNOWLEDGE_BASE}/manifest/index.json\`). Never read \`components.json\` whole: it is the 1.2 MB file the tools use.
170
+ 4. **Never invent prop/event/slot names** — open \`${KNOWLEDGE_BASE}/<ComponentName>.md\` (Usage & Guidelines first) or its API file \`${KNOWLEDGE_BASE}/manifest/components/<ComponentName>.json\` (one member per line; a row marked \`common: true\` is whole in \`${KNOWLEDGE_BASE}/manifest/common.json\`; the list is \`${KNOWLEDGE_BASE}/manifest/index.json\`). Never read \`components.json\` whole: it is the 1.2 MB file the tools use.
171
171
  5. **Icons**: discover names first; never invent them (\`${KNOWLEDGE_BASE}/guides/icons-policy.md\`).
172
172
  6. **Item-driven components**: declarative \`items\` (an object row reads its own \`label\` and \`value\`; \`item-text\` / \`item-value\` only for other field names, never to restate those two), \`dependencies\`, \`enforce-coherence\` — no manual watchers for coherence.
173
173
  7. **Whole pages**: one recipe under \`${KNOWLEDGE_BASE}/recipes/{vue|nuxt|inertia}/\` (see the router table).
@@ -780,7 +780,7 @@ function printFindingLegend(findings) {
780
780
  */
781
781
  /**
782
782
  * `changelog [--since <v>] [--until <v>] [--json]` — what breaks between two
783
- * releases, for anyone not driving the MCP server (a human at a terminal, CI,
783
+ * releases, then what they added (Q74.4: one line per feature), for anyone not driving the MCP server (a human at a terminal, CI,
784
784
  * or an agent whose harness has no MCP). Same data and same range rules as the
785
785
  * `list_changes` tool; this is the transport-free path to it.
786
786
  */
@@ -823,6 +823,22 @@ function changelogCommand({ since, until, json: jsonMode }) {
823
823
  if (until != null && compareReleaseVersions(at, until) > 0) return false;
824
824
  return true;
825
825
  });
826
+ // Q74.4: what the range ADDED (feat commits, one line each), oldest first.
827
+ const inRange = (at) => {
828
+ if (!ranged) return true;
829
+ if (at === 'unreleased') return until == null;
830
+ if (since != null && compareReleaseVersions(at, since) <= 0) return false;
831
+ if (until != null && compareReleaseVersions(at, until) > 0) return false;
832
+ return true;
833
+ };
834
+ const added = Object.entries(doc.added ?? {})
835
+ .filter(([at]) => inRange(at))
836
+ .flatMap(([at, entries]) =>
837
+ entries.map((entry) => ({
838
+ at,
839
+ line: typeof entry === 'string' ? entry : entry.text,
840
+ }))
841
+ );
826
842
 
827
843
  if (jsonMode) {
828
844
  console.log(
@@ -833,6 +849,7 @@ function changelogCommand({ since, until, json: jsonMode }) {
833
849
  until: until ?? doc.version,
834
850
  count: rows.length,
835
851
  breaking: rows,
852
+ added: added.map(({ at, line }) => `[${at}] ${line}`),
836
853
  guide: doc.guide,
837
854
  },
838
855
  null,
@@ -845,13 +862,26 @@ function changelogCommand({ since, until, json: jsonMode }) {
845
862
  const range = ranged
846
863
  ? `${since ?? 'the start of v3'} → ${until ?? doc.version}`
847
864
  : `the whole v2 → v3 upgrade`;
865
+ const printAdded = () => {
866
+ if (!added.length) return;
867
+ // Compact by default: the whole v3 line is hundreds of lines.
868
+ if (!ranged) {
869
+ console.log(
870
+ `\n${added.length} addition(s) over ${range}: list one hop with --since <your version>.`
871
+ );
872
+ return;
873
+ }
874
+ console.log(`\n${added.length} addition(s), ${range}:\n`);
875
+ for (const { at, line } of added) console.log(` [${at}] ${line}`);
876
+ };
848
877
  if (rows.length === 0) {
849
878
  // "Nothing breaks" and "I could not tell you" must not look alike.
850
879
  console.log(
851
880
  `[bitboss-ui] changelog: no BREAKING changes in ${range}.\n` +
852
- ' Features and fixes are deliberately not tracked here, so this\n' +
853
- ' means nothing breaks — not that nothing changed.'
881
+ ' Fixes are not tracked here, so this means nothing\n' +
882
+ ' breaks — not that nothing changed.'
854
883
  );
884
+ printAdded();
855
885
  return;
856
886
  }
857
887
  console.log(
@@ -874,6 +904,7 @@ function changelogCommand({ since, until, json: jsonMode }) {
874
904
  }
875
905
  if (entry.guide) console.log(` ${entry.guide}`);
876
906
  }
907
+ printAdded();
877
908
  console.log(`\nFull migration guide: ${doc.guide}`);
878
909
  }
879
910
 
@@ -1651,7 +1682,8 @@ Commands:
1651
1682
  \`bitboss-ui/validated\`, retired: everything is in
1652
1683
  \`bitboss-ui\`; \`--fix\` rewrites it in .vue files),
1653
1684
  \`unregistered-rule\` (a string or object rule no
1654
- \`defineRule\` in the project registers; a
1685
+ \`defineRule\` in the project registers (in a .md
1686
+ page, also one the page's own fences show); a
1655
1687
  registration it cannot read is named, never skipped:
1656
1688
  list such names under \`registeredRules\` in
1657
1689
  bitboss-ui.check.json),
@@ -1711,13 +1743,20 @@ Commands:
1711
1743
  \`<…Portal name>\` nothing opens: no call site and the
1712
1744
  name in no string of the project), \`vue-tsc-major\`
1713
1745
  (\`vue-tsc\` below 3 in package.json: the generic
1714
- components' props go unchecked).
1746
+ components' props go unchecked), \`prefer-v-bb-dialog\`
1747
+ (a \`ref(false)\` only a BbDialog / BbOffCanvas
1748
+ \`v-model\` and \`@click="x = true"\` use: give the
1749
+ dialog an \`id\` and put \`v-bb-dialog\` on the
1750
+ trigger; ESLint's \`--fix\` rewrites it when nothing
1751
+ else uses the ref).
1715
1752
  changelog [--since <version>] [--until <version>] [--json]
1716
1753
  Breaking changes between two releases — "what breaks if I
1717
1754
  bump". \`--since\` is the version you are ON, and is
1718
1755
  exclusive. With no range, every break in the v2 → v3
1719
- upgrade. Only BREAKING changes are tracked, so an empty
1720
- result means nothing breaks, not that nothing changed.
1756
+ upgrade. Then what the range added, one line per feature
1757
+ (with no range, only their count). Fixes are not tracked,
1758
+ so no breaking changes means nothing breaks, not that
1759
+ nothing changed.
1721
1760
  npx bitboss-ui changelog --since 3.0.0-beta.20
1722
1761
  Pair it with \`check --manifest\` to turn the list into the
1723
1762
  files in YOUR app that break.
@@ -750,7 +750,7 @@ States are listed in precedence order: when two are on at once and their entries
750
750
  - `BbDropdownList` _(internal — not importable, reach it through `BbDropdown`)_ — also mounts `BbIcon`, `ErrorIcon`, `CommonPopover`, `BbDropdownList`
751
751
  - `BbBadge` _(public — [contract](./BbBadge.md))_ — its own pt parts (`BbBadge`): `spinner` → `BbSpinner`, `icon` → `BbIcon`, `clear` → `button.bb-badge__clear`; documented CSS variables: `--bg`, `--fg`, `--bw`, `--ring-color`, `--ring-size`, `--min-size-md`, `--min-size`, `--elev`, `--r`, `--fs`, `--icon-size`, `--gap`, `--px`, `--clear-size`, `--bg-disabled`, `--fg-disabled`, `--border-disabled`, `--pad-left`; also mounts `BbIcon`, `BbSpinner`, `BadgeBodyContent`
752
752
  - `AdaptiveDropdown` _(internal — not importable, reach it through `BbDropdown`)_ — hands `BbOffCanvas` the pt map `{ header: 'header', footer: 'footer', panel: 'root', sheet: 'root' }` (ours → theirs); also mounts `BbSmoothHeight`, `BbDropdownList`
753
- - `BbOffCanvas` _(public — [contract](./BbOffCanvas.md))_ — its own pt parts (`BbOffCanvas`): `header` → `div.bb-offcanvas__header`, `title` → `span.bb-offcanvas__title`, `description` → `p.bb-offcanvas__description`, `close` → `CloseButton`, `content` → `div.bb-offcanvas__content`, `footer` → `div.bb-offcanvas__footer`; documented CSS variables: `--stack-x`, `--stack-fill`, `--stack-transition-duration`, `--px`, `--handle-w`, `--handle-h`, `--handle-bg`, `--safe-top`, `--close-size`
753
+ - `BbOffCanvas` _(public — [contract](./BbOffCanvas.md))_ — its own pt parts (`BbOffCanvas`): `header` → `div.bb-offcanvas__header`, `title` → `span.bb-offcanvas__title`, `description` → `p.bb-offcanvas__description`, `close` → `CloseButton`, `content` → `div.bb-offcanvas__content`, `footer` → `div.bb-offcanvas__footer`; documented CSS variables: `--stack-x`, `--snap-y`, `--stack-fill`, `--stack-transition-duration`, `--px`, `--handle-w`, `--handle-h`, `--handle-bg`, `--safe-top`, `--close-size`
754
754
  - `CloseButton` _(internal — not importable, reach it through `BbOffCanvas`)_ — documented CSS variables: `--size`, `--p`
755
755
  - `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`, `BbBaseButton`, `BbSpinner`
756
756
  - Also mounts `BbIcon`
@@ -709,7 +709,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
709
709
  | Prop | Type | Default | Required | Description |
710
710
  | --- | --- | --- | --- | --- |
711
711
  | `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`, `label`, `message`, `root`. States: `checked`, `disabled`, `errors`, `focused`, `focusVisible`, `indeterminate`, `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 `BbCheckboxProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
712
- | `autofocus` | `Booleanish \| undefined` | | | Sets autofocus on page load. |
712
+ | `autofocus` | `Booleanish \| undefined` | | | Focuses the field when it mounts (a dialog already open included), unless the user is typing in another field. |
713
713
  | `checked` | `boolean \| undefined` | `undefined` | | Defines the input as checked. |
714
714
  | `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. |
715
715
  | `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`). |
@@ -983,7 +983,7 @@ for a preset that fits any row type (never `<any>`), not an imported
983
983
  | Prop | Type | Default | Required | Description |
984
984
  | --- | --- | --- | --- | --- |
985
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>`. |
986
- | `autofocus` | `Booleanish \| undefined` | | | Sets autofocus on page load. |
986
+ | `autofocus` | `Booleanish \| undefined` | | | Focuses the field when it mounts (a dialog already open included), unless the user is typing in another field. |
987
987
  | `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
988
  | `dependencies` | `unknown[] \| undefined` | | | Defines an array of dependencies that will trigger actions in the component upon change. |
989
989
  | `depsDebounceTime` | `number \| undefined` | | | Timeout used to debounce response to changes to dependencies. |
@@ -687,7 +687,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
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. |
689
689
  | `autocomplete` | `string \| undefined` | `"off"` | | Guides the browser as to the type of information expected in the field. |
690
- | `autofocus` | `Booleanish \| undefined` | | | Sets autofocus on page load. |
690
+ | `autofocus` | `Booleanish \| undefined` | | | Focuses the field when it mounts (a dialog already open included), unless the user is typing in another field. |
691
691
  | `clearable` | `boolean \| undefined` | `false` | | Displays a clear button when the input has a value and is being interacted with. |
692
692
  | `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. |
693
693
  | `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`). |
@@ -811,7 +811,7 @@ Set these on the element, or on a class you put on it, to retune this component
811
811
  - `CommonField` _(internal — not importable, reach it through `BbColorInput`)_ — `BbColorInput`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `counter` → `span.bb-field__counter`, `message` → `div.bb-field__message`; documented CSS variables: `--ctrl-line`; also mounts `BbAsterisk`
812
812
  - `CommonFieldInput` _(internal — not importable, reach it through `BbColorInput`)_ — `BbColorInput`'s pt parts land here: `box` → `span.bb-field-input__box`, `prefix` → `span.bb-field-input__prefix`, `icon` → `BbIcon`, `clear` → `ClearableButton`, `spinner` → `BbSpinner`, `suffix` → `span.bb-field-input__suffix`; documented CSS variables: `--bg`, `--bg-hover`, `--bg-focus`, `--bg-disabled`, `--fg-disabled`, `--border-color`, `--border-focus`, `--ring-size`, `--ring-color`, `--elev`, `--frost`, `--inside-label-clearance`; also mounts `ErrorIcon`, `WarningIcon`, `ClearableButton`, `BbIcon`, `BbSpinner`
813
813
  - `BbColorPalette` _(public — [contract](./BbColorPalette.md))_ — its own pt parts (`BbColorPalette`): `swatch` → `button.bb-color-palette__swatch`, `panel` → `div`, `panel` → `CommonPopover`; hands `BbOffCanvas` the pt map `{ panel: 'root', sheet: 'root' }` (ours → theirs); documented CSS variables: `--edge`; also mounts `CommonPopover`
814
- - `BbOffCanvas` _(public — [contract](./BbOffCanvas.md))_ — its own pt parts (`BbOffCanvas`): `header` → `div.bb-offcanvas__header`, `title` → `span.bb-offcanvas__title`, `description` → `p.bb-offcanvas__description`, `close` → `CloseButton`, `content` → `div.bb-offcanvas__content`, `footer` → `div.bb-offcanvas__footer`; documented CSS variables: `--stack-x`, `--stack-fill`, `--stack-transition-duration`, `--px`, `--handle-w`, `--handle-h`, `--handle-bg`, `--safe-top`, `--close-size`
814
+ - `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`
815
815
  - `CloseButton` _(internal — not importable, reach it through `BbOffCanvas`)_ — documented CSS variables: `--size`, `--p`
816
816
 
817
817
  ## See Also
@@ -821,7 +821,7 @@ Set these on the element, or on a class you put on it, to retune this component
821
821
  - Listed nodes are the ones `BbColorPalette`'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/BbColorPalette.tree.json`.
822
822
 
823
823
  - `BbColorPalette` _(this component)_ — its own template binds: `swatch` → `button.bb-color-palette__swatch`, `panel` → `div`, `panel` → `CommonPopover`; hands `BbOffCanvas` the pt map `{ panel: 'root', sheet: 'root' }` (ours → theirs)
824
- - `BbOffCanvas` _(public — [contract](./BbOffCanvas.md))_ — its own pt parts (`BbOffCanvas`): `header` → `div.bb-offcanvas__header`, `title` → `span.bb-offcanvas__title`, `description` → `p.bb-offcanvas__description`, `close` → `CloseButton`, `content` → `div.bb-offcanvas__content`, `footer` → `div.bb-offcanvas__footer`; documented CSS variables: `--stack-x`, `--stack-fill`, `--stack-transition-duration`, `--px`, `--handle-w`, `--handle-h`, `--handle-bg`, `--safe-top`, `--close-size`
824
+ - `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`
825
825
  - `CloseButton` _(internal — not importable, reach it through `BbOffCanvas`)_ — documented CSS variables: `--size`, `--p`
826
826
  - Also mounts `CommonPopover`
827
827
 
@@ -821,7 +821,7 @@ States are listed in precedence order: when two are on at once and their entries
821
821
  - `BbConfirm` _(this component)_ — its own template binds: `text` → `div.bb-confirm__text`, `action` → `BbButton`; hands `BbDialog` the pt map `passthrough.forward(DIALOG_PARTS, BB_DIALOG_PT.states)` (ours → theirs)
822
822
  - `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
823
  - `CloseButton` _(internal — not importable, reach it through `BbDialog`)_ — documented CSS variables: `--size`, `--p`
824
- - `BbOffCanvas` _(public — [contract](./BbOffCanvas.md))_ — its own pt parts (`BbOffCanvas`): `header` → `div.bb-offcanvas__header`, `title` → `span.bb-offcanvas__title`, `description` → `p.bb-offcanvas__description`, `close` → `CloseButton`, `content` → `div.bb-offcanvas__content`, `footer` → `div.bb-offcanvas__footer`; documented CSS variables: `--stack-x`, `--stack-fill`, `--stack-transition-duration`, `--px`, `--handle-w`, `--handle-h`, `--handle-bg`, `--safe-top`, `--close-size`; also mounts `CloseButton`
824
+ - `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
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`
826
826
  - `BbBaseButton` _(public — [contract](./BbBaseButton.md))_ — its own pt parts (`BbBaseButton`): `root` → `RouterComponent`, `root` → `a`, `root` → `component`; also mounts `RouterComponent`
827
827
 
@@ -540,7 +540,7 @@ Set these on the element, or on a class you put on it, to retune this component
540
540
  - `BbCalendar` _(public — [contract](./BbCalendar.md))_ — its own pt parts (`BbCalendar`): `header` → `div.bb-calendar__header`, `arrow` → `BbBaseButton`, `month` → `BbBaseButton`, `year` → `BbBaseButton`, `day` → `div.bb-calendar__day`, `dayButton` → `button.bb-calendar__day-button`; documented CSS variables: `--cell`, `--unit-row`; also mounts `ScaleFade`, `Slide`, `CalendarMonthPanel`, `CalendarYearPanel`
541
541
  - `BbBaseButton` _(public — [contract](./BbBaseButton.md))_ — its own pt parts (`BbBaseButton`): `root` → `RouterComponent`, `root` → `a`, `root` → `component`; also mounts `RouterComponent`
542
542
  - `CommonTimeSelector` _(internal — not importable, reach it through `BbCalendar`)_ — its own pt parts (`BbCalendar`): `header` → `div.bb-time-selector__header`, `cellColumnHeader` → `div.bb-time-selector__cell-column-header`, `item` → `BbBaseButton`; documented CSS variables: `--time-mark`; also mounts `BbBaseButton`
543
- - `BbOffCanvas` _(public — [contract](./BbOffCanvas.md))_ — its own pt parts (`BbOffCanvas`): `header` → `div.bb-offcanvas__header`, `title` → `span.bb-offcanvas__title`, `description` → `p.bb-offcanvas__description`, `close` → `CloseButton`, `content` → `div.bb-offcanvas__content`, `footer` → `div.bb-offcanvas__footer`; documented CSS variables: `--stack-x`, `--stack-fill`, `--stack-transition-duration`, `--px`, `--handle-w`, `--handle-h`, `--handle-bg`, `--safe-top`, `--close-size`
543
+ - `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`
544
544
  - `CloseButton` _(internal — not importable, reach it through `BbOffCanvas`)_ — documented CSS variables: `--size`, `--p`
545
545
  - Also mounts `CommonPopover`
546
546
 
@@ -883,7 +883,7 @@ label>')` matches nothing; query each segment by its own label instead. See
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. |
885
885
  | `autocomplete` | `string \| undefined` | `"off"` | | Guides the browser as to the type of information expected in the field. |
886
- | `autofocus` | `Booleanish \| undefined` | | | Sets autofocus on page load. |
886
+ | `autofocus` | `Booleanish \| undefined` | | | Focuses the field when it mounts (a dialog already open included), unless the user is typing in another field. |
887
887
  | `clearable` | `boolean \| undefined` | `false` | | Displays a clear button when the input has a value and is being interacted with. |
888
888
  | `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. |
889
889
  | `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`). |
@@ -1033,7 +1033,7 @@ Set these on the element, or on a class you put on it, to retune this component
1033
1033
  - `BbCalendar` _(public — [contract](./BbCalendar.md))_ — its own pt parts (`BbCalendar`): `header` → `div.bb-calendar__header`, `arrow` → `BbBaseButton`, `month` → `BbBaseButton`, `year` → `BbBaseButton`, `day` → `div.bb-calendar__day`, `dayButton` → `button.bb-calendar__day-button`; documented CSS variables: `--cell`, `--unit-row`; also mounts `ScaleFade`, `Slide`, `CalendarMonthPanel`, `CalendarYearPanel`
1034
1034
  - `BbBaseButton` _(public — [contract](./BbBaseButton.md))_ — its own pt parts (`BbBaseButton`): `root` → `RouterComponent`, `root` → `a`, `root` → `component`; also mounts `RouterComponent`
1035
1035
  - `CommonTimeSelector` _(internal — not importable, reach it through `BbCalendar`)_ — its own pt parts (`BbCalendar`): `header` → `div.bb-time-selector__header`, `cellColumnHeader` → `div.bb-time-selector__cell-column-header`, `item` → `BbBaseButton`; documented CSS variables: `--time-mark`; also mounts `BbBaseButton`
1036
- - `BbOffCanvas` _(public — [contract](./BbOffCanvas.md))_ — its own pt parts (`BbOffCanvas`): `header` → `div.bb-offcanvas__header`, `title` → `span.bb-offcanvas__title`, `description` → `p.bb-offcanvas__description`, `close` → `CloseButton`, `content` → `div.bb-offcanvas__content`, `footer` → `div.bb-offcanvas__footer`; documented CSS variables: `--stack-x`, `--stack-fill`, `--stack-transition-duration`, `--px`, `--handle-w`, `--handle-h`, `--handle-bg`, `--safe-top`, `--close-size`
1036
+ - `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`
1037
1037
  - `CloseButton` _(internal — not importable, reach it through `BbOffCanvas`)_ — documented CSS variables: `--size`, `--p`
1038
1038
  - `CommonField` _(internal — not importable, reach it through `BbDatePickerInput`)_ — `BbDatePickerInput`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `counter` → `span.bb-field__counter`, `message` → `div.bb-field__message`; documented CSS variables: `--ctrl-line`; also mounts `BbAsterisk`
1039
1039
  - `CommonFieldInput` _(internal — not importable, reach it through `BbDatePickerInput`)_ — `BbDatePickerInput`'s pt parts land here: `box` → `span.bb-field-input__box`, `prefix` → `span.bb-field-input__prefix`, `icon` → `BbIcon`, `clear` → `ClearableButton`, `spinner` → `BbSpinner`, `suffix` → `span.bb-field-input__suffix`; documented CSS variables: `--bg`, `--bg-hover`, `--bg-focus`, `--bg-disabled`, `--fg-disabled`, `--border-color`, `--border-focus`, `--ring-size`, `--ring-color`, `--elev`, `--frost`, `--inside-label-clearance`; also mounts `ErrorIcon`, `WarningIcon`, `ClearableButton`, `BbIcon`, `BbSpinner`