bitboss-ui 3.0.0-beta.2 → 3.0.0-beta.21
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.
- package/README.md +72 -33
- package/dist/ai/BbAccordion.md +3 -3
- package/dist/ai/BbAlert.md +9 -5
- package/dist/ai/BbAsterisk.md +17 -0
- package/dist/ai/BbAvatar.md +12 -3
- package/dist/ai/BbBadge.md +15 -10
- package/dist/ai/BbBadgeButton.md +16 -16
- package/dist/ai/BbBaseButton.md +16 -16
- package/dist/ai/BbBaseCheckbox.md +8 -8
- package/dist/ai/BbBaseCheckboxGroup.md +13 -13
- package/dist/ai/BbBaseCheckboxIcon.md +26 -9
- package/dist/ai/BbBaseColorInput.md +11 -11
- package/dist/ai/BbBaseDatePicker.md +6 -6
- package/dist/ai/BbBaseDatePickerInput.md +15 -15
- package/dist/ai/BbBaseInputContainer.md +12 -12
- package/dist/ai/BbBaseNumberInput.md +8 -8
- package/dist/ai/BbBaseRadio.md +5 -5
- package/dist/ai/BbBaseRadioGroup.md +7 -7
- package/dist/ai/BbBaseRadioIcon.md +25 -9
- package/dist/ai/BbBaseRating.md +5 -5
- package/dist/ai/BbBaseSelect.md +22 -21
- package/dist/ai/BbBaseSlider.md +9 -9
- package/dist/ai/BbBaseSwitch.md +8 -8
- package/dist/ai/BbBaseSwitchGroup.md +13 -13
- package/dist/ai/BbBaseSwitchIcon.md +28 -10
- package/dist/ai/BbBaseTag.md +10 -10
- package/dist/ai/BbBaseTextInput.md +9 -9
- package/dist/ai/BbBaseTextarea.md +9 -9
- package/dist/ai/BbBaseTimePickerInput.md +13 -13
- package/dist/ai/BbBreadcrumbs.md +2 -2
- package/dist/ai/BbButton.md +15 -15
- package/dist/ai/BbCheckbox.md +18 -17
- package/dist/ai/BbCheckboxGroup.md +15 -14
- package/dist/ai/BbCollapsible.md +11 -9
- package/dist/ai/BbColorInput.md +15 -15
- package/dist/ai/BbColorPalette.md +12 -6
- package/dist/ai/BbConfirm.md +12 -5
- package/dist/ai/BbDatePicker.md +13 -13
- package/dist/ai/BbDatePickerInput.md +20 -20
- package/dist/ai/BbDialog.md +78 -12
- package/dist/ai/BbDropdown.md +132 -22
- package/dist/ai/BbDropdownButton.md +12 -12
- package/dist/ai/BbDropdownGroup.md +1 -1
- package/dist/ai/BbDropzone.md +4 -4
- package/dist/ai/BbForm.md +49 -14
- package/dist/ai/BbIcon.md +6 -0
- package/dist/ai/BbIndicator.md +5 -5
- package/dist/ai/BbNumberInput.md +11 -11
- package/dist/ai/BbOffCanvas.md +90 -20
- package/dist/ai/BbPagination.md +3 -3
- package/dist/ai/BbPopover.md +32 -17
- package/dist/ai/BbProgress.md +7 -4
- package/dist/ai/BbRadio.md +16 -15
- package/dist/ai/BbRadioGroup.md +20 -17
- package/dist/ai/BbRating.md +11 -11
- package/dist/ai/BbSelect.md +138 -37
- package/dist/ai/BbSelectPopover.md +40 -41
- package/dist/ai/BbSlider.md +37 -22
- package/dist/ai/BbSmoothHeight.md +1 -1
- package/dist/ai/BbSwitch.md +25 -10
- package/dist/ai/BbSwitchGroup.md +17 -14
- package/dist/ai/BbTable.md +920 -109
- package/dist/ai/BbTabs.md +28 -14
- package/dist/ai/BbTabsList.md +1 -1
- package/dist/ai/BbTabsPanes.md +1 -1
- package/dist/ai/BbTabsRoot.md +10 -10
- package/dist/ai/BbTag.md +14 -14
- package/dist/ai/BbTextInput.md +16 -15
- package/dist/ai/BbTextarea.md +13 -13
- package/dist/ai/BbTimePicker.md +10 -10
- package/dist/ai/BbTimePickerInput.md +17 -17
- package/dist/ai/BbToast.md +1 -1
- package/dist/ai/BbToastPortal.md +1 -1
- package/dist/ai/BbTooltip.md +12 -10
- package/dist/ai/BbTree.md +1 -1
- package/dist/ai/ChipsBox.md +1 -1
- package/dist/ai/CommonInputWrapper.md +10 -10
- package/dist/ai/CommonPopover.md +6 -6
- package/dist/ai/FlatListBox.md +5 -5
- package/dist/ai/GroupedListBox.md +5 -5
- package/dist/ai/ListBox.md +4 -4
- package/dist/ai/OptionsContainer.md +4 -4
- package/dist/ai/changelog.json +128 -2
- package/dist/ai/components.json +917 -100
- package/dist/ai/composables/useBbConfig.md +72 -11
- package/dist/ai/composables/useConfirm.md +5 -3
- package/dist/ai/guides/ai-router.md +9 -4
- package/dist/ai/guides/component-picker.md +18 -18
- package/dist/ai/guides/design-language.md +14 -14
- package/dist/ai/guides/design-tokens.md +25 -18
- package/dist/ai/guides/fetch-items-playbook.md +1 -1
- package/dist/ai/guides/icons-policy.md +11 -5
- package/dist/ai/guides/installation-and-plugin-setup.md +85 -23
- package/dist/ai/guides/migration/components/bb-checkbox-group.md +30 -0
- package/dist/ai/guides/migration/components/bb-checkbox.md +37 -3
- package/dist/ai/guides/migration/components/bb-collapsible.md +5 -5
- package/dist/ai/guides/migration/components/bb-dialog.md +62 -34
- package/dist/ai/guides/migration/components/bb-offcanvas.md +29 -13
- package/dist/ai/guides/migration/components/bb-rating.md +8 -2
- package/dist/ai/guides/migration/components/bb-select.md +5 -2
- package/dist/ai/guides/migration/components/bb-table.md +560 -28
- package/dist/ai/guides/migration/components/bb-text-input.md +6 -6
- package/dist/ai/guides/migration/v2-to-v3.md +260 -89
- package/dist/ai/guides/ssr-prefill.md +120 -0
- package/dist/ai/index.md +10 -9
- package/dist/ai/recipes/inertia/approvals-inbox.md +0 -1
- package/dist/ai/recipes/inertia/inline-edit-workspace.md +0 -1
- package/dist/ai/recipes/inertia/layout-scaffold.md +5 -1
- package/dist/ai/recipes/inertia/ownership-atlas.md +49 -29
- package/dist/ai/recipes/inertia/record-form.md +0 -1
- package/dist/ai/recipes/inertia/records-workspace.md +26 -8
- package/dist/ai/recipes/inertia/upload-center.md +0 -1
- package/dist/ai/recipes/nuxt/approvals-inbox.md +0 -1
- package/dist/ai/recipes/nuxt/inline-edit-workspace.md +0 -1
- package/dist/ai/recipes/nuxt/layout-scaffold.md +5 -1
- package/dist/ai/recipes/nuxt/record-form.md +0 -1
- package/dist/ai/recipes/nuxt/records-workspace.md +26 -8
- package/dist/ai/recipes/nuxt/upload-center.md +0 -1
- package/dist/ai/recipes/vue/approvals-inbox.md +0 -1
- package/dist/ai/recipes/vue/inline-edit-workspace.md +0 -1
- package/dist/ai/recipes/vue/layout-scaffold.md +5 -1
- package/dist/ai/recipes/vue/records-workspace.md +26 -8
- package/dist/ai/recipes/vue/upload-center.md +0 -1
- package/dist/ai/source/BbAlert.md +60 -2
- package/dist/ai/source/BbAvatar.md +3 -3
- package/dist/ai/source/BbBadge.md +60 -15
- package/dist/ai/source/BbBadgeButton.md +8 -2
- package/dist/ai/source/BbBaseButton.md +3 -1
- package/dist/ai/source/BbBaseCheckboxGroup.md +6 -2
- package/dist/ai/source/BbBaseDatePicker.md +3 -1
- package/dist/ai/source/BbBaseDatePickerInput.md +5 -1
- package/dist/ai/source/BbBaseInputContainer.md +52 -1
- package/dist/ai/source/BbBaseRadioGroup.md +4 -0
- package/dist/ai/source/BbBaseRating.md +3 -1
- package/dist/ai/source/BbBaseSelect.md +71 -16
- package/dist/ai/source/BbBaseSwitchGroup.md +4 -0
- package/dist/ai/source/BbBaseTimePickerInput.md +5 -1
- package/dist/ai/source/BbBreadcrumbs.md +31 -0
- package/dist/ai/source/BbButton.md +51 -24
- package/dist/ai/source/BbCheckbox.md +15 -1
- package/dist/ai/source/BbCheckboxGroup.md +2 -1
- package/dist/ai/source/BbCollapsible.md +7 -1
- package/dist/ai/source/BbColorInput.md +3 -4
- package/dist/ai/source/BbColorPalette.md +3 -4
- package/dist/ai/source/BbDatePicker.md +5 -1
- package/dist/ai/source/BbDatePickerInput.md +5 -1
- package/dist/ai/source/BbDialog.md +175 -19
- package/dist/ai/source/BbDropdown.md +376 -69
- package/dist/ai/source/BbDropdownGroup.md +330 -59
- package/dist/ai/source/BbForm.md +93 -5
- package/dist/ai/source/BbIcon.md +46 -36
- package/dist/ai/source/BbNumberInput.md +3 -4
- package/dist/ai/source/BbOffCanvas.md +474 -194
- package/dist/ai/source/BbPopover.md +24 -17
- package/dist/ai/source/BbProgress.md +2 -2
- package/dist/ai/source/BbRadio.md +15 -1
- package/dist/ai/source/BbRadioGroup.md +3 -1
- package/dist/ai/source/BbSelect.md +50 -2
- package/dist/ai/source/BbSelectPopover.md +171 -23
- package/dist/ai/source/BbSlider.md +3 -4
- package/dist/ai/source/BbSwitch.md +15 -1
- package/dist/ai/source/BbSwitchGroup.md +8 -5
- package/dist/ai/source/BbTable.md +5092 -1446
- package/dist/ai/source/BbTabs.md +6 -7
- package/dist/ai/source/BbTabsList.md +6 -7
- package/dist/ai/source/BbTabsPanes.md +6 -7
- package/dist/ai/source/BbTabsRoot.md +6 -7
- package/dist/ai/source/BbTag.md +3 -4
- package/dist/ai/source/BbTextInput.md +3 -4
- package/dist/ai/source/BbTextarea.md +3 -4
- package/dist/ai/source/BbTimePicker.md +4 -1
- package/dist/ai/source/BbTimePickerInput.md +5 -1
- package/dist/ai/source/BbToast.md +3 -1
- package/dist/ai/source/BbTooltip.md +5 -1
- package/dist/ai/source/CommonInputWrapper.md +4 -0
- package/dist/ai/source/CommonPopover.md +6 -0
- package/dist/ai/source/FlatListBox.md +11 -5
- package/dist/ai/source/GroupedListBox.md +7 -5
- package/dist/components/BbAlert/BbAlert.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/BbAlert/types.d.ts +10 -1
- package/dist/components/BbAvatar/BbAvatar.vue.d.ts +1 -1
- package/dist/components/BbAvatar/BbAvatar.vue_vue_type_script_setup_true_lang.js +33 -33
- package/dist/components/BbBadge/BadgeBodyContent.vue_vue_type_script_setup_true_lang.js +22 -16
- package/dist/components/BbBadge/BbBadge.vue_vue_type_script_setup_true_lang.js +36 -15
- package/dist/components/BbBadge/badgeButtonContext.d.ts +21 -8
- package/dist/components/BbBadge/types.d.ts +8 -2
- package/dist/components/BbBaseButton/BbBaseButton.vue_vue_type_script_setup_true_lang.js +47 -47
- package/dist/components/BbBaseButton/RouterComponent.vue_vue_type_script_setup_true_lang.js +14 -14
- package/dist/components/BbBaseCheckboxGroup/BbBaseCheckboxGroup.vue_vue_type_script_setup_true_lang.js +30 -28
- package/dist/components/BbBaseCheckboxGroup/types.d.ts +2 -2
- package/dist/components/BbBaseDatePicker/BbBaseDatePicker.vue_vue_type_script_setup_true_lang.js +167 -167
- package/dist/components/BbBaseDatePicker/BbBaseDatePickerInputDaySelector.vue.d.ts +9 -9
- package/dist/components/BbBaseDatePicker/BbBaseDatePickerInputDaySelector.vue_vue_type_script_setup_true_lang.js +78 -78
- package/dist/components/BbBaseDatePicker/BbBaseDatePickerMonthSelector.vue_vue_type_script_setup_true_lang.js +64 -64
- package/dist/components/BbBaseDatePickerInput/BbBaseDatePickerInput.vue.d.ts +1 -1
- package/dist/components/BbBaseDatePickerInput/BbBaseDatePickerInput.vue_vue_type_script_setup_true_lang.js +138 -138
- package/dist/components/BbBaseInputContainer/BbBaseInputContainer.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/BbBaseRadioGroup/BbBaseRadioGroup.vue_vue_type_script_setup_true_lang.js +24 -22
- package/dist/components/BbBaseRating/BbBaseRating.vue_vue_type_script_setup_true_lang.js +40 -40
- package/dist/components/BbBaseSelect/BbBaseSelect.vue_vue_type_script_setup_true_lang.js +74 -65
- package/dist/components/BbBaseSelect/types.d.ts +22 -0
- package/dist/components/BbBaseSlider/BbBaseSlider.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/BbBaseSwitchGroup/BbBaseSwitchGroup.vue_vue_type_script_setup_true_lang.js +30 -28
- package/dist/components/BbBaseTimePickerInput/BbBaseTimePickerInput.vue.d.ts +1 -1
- package/dist/components/BbBaseTimePickerInput/BbBaseTimePickerInput.vue_vue_type_script_setup_true_lang.js +104 -104
- package/dist/components/BbBreadcrumbs/BbBreadcrumbs.vue_vue_type_script_setup_true_lang.js +35 -35
- package/dist/components/BbButton/BbButton.vue_vue_type_script_setup_true_lang.js +85 -81
- package/dist/components/BbCheckboxGroup/types.d.ts +2 -1
- package/dist/components/BbCollapsible/types.d.ts +7 -1
- package/dist/components/BbColorInput/BbColorInput.vue.d.ts +1 -1
- package/dist/components/BbColorInput/BbColorInput.vue_vue_type_script_setup_true_lang.js +18 -18
- package/dist/components/BbColorPalette/BbColorPalette.vue.d.ts +2 -2
- package/dist/components/BbColorPalette/BbColorPalette.vue_vue_type_script_setup_true_lang.js +50 -50
- package/dist/components/BbConfirm/BbConfirm.vue_vue_type_script_setup_true_lang.js +17 -17
- package/dist/components/BbDatePicker/BbDatePicker.vue.d.ts +1 -1
- package/dist/components/BbDatePicker/BbDatePicker.vue_vue_type_script_setup_true_lang.js +100 -100
- package/dist/components/BbDatePickerInput/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +21 -21
- package/dist/components/BbDialog/BbDialog.vue.d.ts +1 -1
- package/dist/components/BbDialog/BbDialog.vue_vue_type_script_setup_true_lang.js +133 -107
- package/dist/components/BbDialog/types.d.ts +29 -2
- package/dist/components/BbDropdown/AdaptiveDropdown.vue.d.ts +2 -0
- package/dist/components/BbDropdown/AdaptiveDropdown.vue_vue_type_script_setup_true_lang.js +99 -100
- package/dist/components/BbDropdown/BbDropdown.vue.d.ts +2 -2
- package/dist/components/BbDropdown/BbDropdown.vue_vue_type_script_setup_true_lang.js +208 -201
- package/dist/components/BbDropdown/BbDropdownList.vue_vue_type_script_setup_true_lang.js +225 -208
- package/dist/components/BbDropdown/DropdownPipelineResolver.vue_vue_type_script_setup_true_lang.js +21 -21
- package/dist/components/BbDropdown/types.d.ts +20 -5
- package/dist/components/BbDropdownButton/BbDropdownButton.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/BbIcon/BbIcon.vue_vue_type_script_setup_true_lang.js +46 -46
- package/dist/components/BbIcon/iconCache.d.ts +33 -0
- package/dist/components/BbIcon/iconCache.js +17 -0
- package/dist/components/BbNumberInput/BbNumberInput.vue.d.ts +1 -1
- package/dist/components/BbNumberInput/BbNumberInput.vue_vue_type_script_setup_true_lang.js +15 -15
- package/dist/components/BbOffCanvas/BbOffCanvas.vue.d.ts +1 -1
- package/dist/components/BbOffCanvas/BbOffCanvas.vue_vue_type_script_setup_true_lang.js +254 -208
- package/dist/components/BbOffCanvas/types.d.ts +30 -5
- package/dist/components/BbPagination/BbPagination.vue.d.ts +1 -1
- package/dist/components/BbPopover/BbPopover.vue.d.ts +2 -2
- package/dist/components/BbPopover/BbPopover.vue_vue_type_script_setup_true_lang.js +149 -146
- package/dist/components/BbPopover/types.d.ts +3 -2
- package/dist/components/BbRadioGroup/types.d.ts +3 -1
- package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +27 -23
- package/dist/components/BbSelect/types.d.ts +32 -0
- package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +221 -213
- package/dist/components/BbSlider/BbSlider.vue.d.ts +1 -1
- package/dist/components/BbSlider/BbSlider.vue_vue_type_script_setup_true_lang.js +20 -20
- package/dist/components/BbTable/BbTable.vue.d.ts +10 -4
- package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +1433 -600
- package/dist/components/BbTable/BbTableDataRow.d.ts +162 -0
- package/dist/components/BbTable/BbTableDataRow.js +136 -0
- package/dist/components/BbTable/BbTableExpandRow.d.ts +73 -0
- package/dist/components/BbTable/BbTableExpandRow.js +52 -0
- package/dist/components/BbTable/types.d.ts +324 -111
- package/dist/components/BbTable/utils.d.ts +92 -4
- package/dist/components/BbTable/utils.js +71 -36
- package/dist/components/BbTabs/types.d.ts +0 -8
- package/dist/components/BbTag/BbTag.vue.d.ts +1 -1
- package/dist/components/BbTag/BbTag.vue_vue_type_script_setup_true_lang.js +18 -18
- package/dist/components/BbTextInput/BbTextInput.vue.d.ts +1 -1
- package/dist/components/BbTextInput/BbTextInput.vue_vue_type_script_setup_true_lang.js +18 -18
- package/dist/components/BbTextarea/BbTextarea.vue.d.ts +1 -1
- package/dist/components/BbTextarea/BbTextarea.vue_vue_type_script_setup_true_lang.js +54 -54
- package/dist/components/BbTimePicker/BbTimePicker.vue.d.ts +1 -1
- package/dist/components/BbTimePicker/BbTimePicker.vue_vue_type_script_setup_true_lang.js +80 -80
- package/dist/components/BbTimePickerInput/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +61 -61
- package/dist/components/BbToast/BbToast.vue_vue_type_script_setup_true_lang.js +17 -17
- package/dist/components/BbToast/BbToastMessage.vue_vue_type_script_setup_true_lang.js +13 -13
- package/dist/components/BbTooltip/types.d.ts +5 -1
- package/dist/components/ChipsBox/ChipsBox.vue_vue_type_script_setup_true_lang.js +17 -17
- package/dist/components/ClearableButton/ClearableButton.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/CommonPopover/CommonPopover.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/components/FlatListBox/FlatListBox.vue_vue_type_script_setup_true_lang.js +83 -83
- package/dist/components/GroupedListBox/GroupedListBox.vue_vue_type_script_setup_true_lang.js +56 -56
- package/dist/composables/useBaseOptions.js +30 -20
- package/dist/composables/useBbConfig.d.ts +27 -6
- package/dist/composables/useBbConfig.js +8 -2
- package/dist/composables/useConfig.d.ts +59 -0
- package/dist/composables/useConfig.js +9 -0
- package/dist/composables/useItemsGetter.d.ts +11 -0
- package/dist/composables/useItemsGetter.js +44 -18
- package/dist/composables/useLocale.js +10 -7
- package/dist/composables/useMobile.js +5 -5
- package/dist/composables/usePrefill.d.ts +21 -2
- package/dist/composables/usePrefill.js +25 -19
- package/dist/composables/useSsrState.d.ts +20 -0
- package/dist/composables/useSsrState.js +13 -0
- package/dist/composables/useTableWidthContext.d.ts +24 -4
- package/dist/composables/useTableWidthContext.js +31 -28
- package/dist/composables/useToast.js +5 -5
- package/dist/deprecation/ai-deprecations.json.d.ts +121 -11
- package/dist/deprecation/ai-deprecations.json.js +1 -1
- package/dist/directives/bbDropdown.d.ts +15 -4
- package/dist/directives/bbDropdown.js +31 -9
- package/dist/directives/createPopoverDirective.d.ts +62 -0
- package/dist/directives/createPopoverDirective.js +63 -23
- package/dist/i18n/locales/cs.json +4 -1
- package/dist/i18n/locales/da.json +4 -1
- package/dist/i18n/locales/de.json +4 -1
- package/dist/i18n/locales/el.json +4 -1
- package/dist/i18n/locales/en.json +4 -1
- package/dist/i18n/locales/es.json +4 -1
- package/dist/i18n/locales/fi.json +4 -1
- package/dist/i18n/locales/fr.json +4 -1
- package/dist/i18n/locales/hu.json +4 -1
- package/dist/i18n/locales/it.json +4 -1
- package/dist/i18n/locales/ja.json +4 -1
- package/dist/i18n/locales/ko.json +4 -1
- package/dist/i18n/locales/nb.json +4 -1
- package/dist/i18n/locales/nl.json +4 -1
- package/dist/i18n/locales/pl.json +4 -1
- package/dist/i18n/locales/pt.json +4 -1
- package/dist/i18n/locales/ro.json +4 -1
- package/dist/i18n/locales/ru.json +4 -1
- package/dist/i18n/locales/sv.json +4 -1
- package/dist/i18n/locales/tr.json +4 -1
- package/dist/i18n/locales/uk.json +4 -1
- package/dist/i18n/locales/zh-cn.json +4 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.js +69 -67
- package/dist/llms-full.txt +3997 -1458
- package/dist/llms-medium.txt +140 -73
- package/dist/llms.txt +7 -6
- package/dist/locale-blueprint.json +4 -1
- package/dist/nuxt-auto-imports.d.ts +100 -0
- package/dist/nuxt-auto-imports.js +55 -0
- package/dist/nuxt-module.d.ts +22 -1
- package/dist/nuxt.js +22 -8
- package/dist/plugin.d.ts +10 -1
- package/dist/plugin.js +20 -19
- package/dist/runtime/nuxt-plugin.js +28 -21
- package/dist/styles.css +1 -1
- package/dist/utilities/misc/listboxMetrics.d.ts +3 -3
- package/dist/utilities/misc/listboxMetrics.js +2 -2
- package/dist/utilities/misc/ssrStateInjectionKey.d.ts +42 -0
- package/dist/utilities/misc/ssrStateInjectionKey.js +4 -0
- package/dist/validated/BbForm.vue_vue_type_script_setup_true_lang.js +45 -27
- package/dist/validated/BbSelect.vue.d.ts +2 -0
- package/dist/validated/BbSelect.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/validated/useValidatedField.js +25 -23
- package/dist/vite.js +7 -3
- package/llms.txt +8 -7
- package/package.json +2 -2
- package/scripts/lib/eslint-plugin.d.ts +19 -1
- package/scripts/lib/eslint-plugin.mjs +155 -14
- package/scripts/lib/html-attributes.mjs +91 -0
- package/scripts/lib/validate-bb-markup.mjs +59 -11
- package/dist/assets/svgs/sort.svg_raw.js +0 -4
- package/dist/components/BbBadge/BadgeAppendIcon.vue.d.ts +0 -3
- package/dist/components/BbBadge/BadgeAppendIcon.vue.js +0 -5
- package/dist/components/BbBadge/BadgeAppendIcon.vue_vue_type_script_setup_true_lang.js +0 -22
|
@@ -34,17 +34,78 @@ declare function setConfig(patch: Partial<DynamicConfig>): void;
|
|
|
34
34
|
// DynamicConfig = { locale: 'it' | 'en' }
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
Merges the patch into
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
the
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
37
|
+
Merges the patch into **this app's** config. The change is immediate and
|
|
38
|
+
reactive — every mounted component in that app which reads the key updates.
|
|
39
|
+
|
|
40
|
+
### Per-request locale under SSR
|
|
41
|
+
|
|
42
|
+
The config is held **per Vue app**, and SSR gives every request its own app,
|
|
43
|
+
so a per-visitor locale is correct on the server's first paint. Set it where
|
|
44
|
+
the app is created:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
// server entry — one app per request, so this is per-request
|
|
48
|
+
const app = createSSRApp(App);
|
|
49
|
+
app.use(bitbossUiPlugin, { locale: localeFor(request) });
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
That is the route to prefer. It is right before hydration, so it is what
|
|
53
|
+
crawlers index, what a prerendered search index reads, and what a reader with
|
|
54
|
+
JS disabled keeps.
|
|
55
|
+
|
|
56
|
+
#### Nuxt
|
|
57
|
+
|
|
58
|
+
**Do not call `app.use(bitbossUiPlugin)` in Nuxt** — the `bitboss-ui/nuxt`
|
|
59
|
+
module registers the runtime plugin for you, and that plugin provides the
|
|
60
|
+
per-app config itself. `defineNuxtPlugin` runs per request on the server and
|
|
61
|
+
Nuxt builds one Vue app per request, so your own plugin is the per-request
|
|
62
|
+
seam:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
// plugins/bitboss-locale.ts
|
|
66
|
+
import { useBbConfig } from 'bitboss-ui';
|
|
67
|
+
|
|
68
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
69
|
+
const locale = localeFor(useRequestEvent());
|
|
70
|
+
// A plugin has an APP but no component instance, so hand it the app's
|
|
71
|
+
// injection context — otherwise the write cannot find this app's config
|
|
72
|
+
// and lands on the process-global defaults.
|
|
73
|
+
nuxtApp.vueApp.runWithContext(() => {
|
|
74
|
+
useBbConfig().setConfig({ locale });
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Calling `setConfig` from a component's `setup` works in Nuxt too, and is
|
|
80
|
+
per-request for the same reason. `runWithContext` is only needed where no
|
|
81
|
+
component exists yet.
|
|
82
|
+
|
|
83
|
+
> Fixed in 3.0.0-beta.19 (Q20.4). Before that the Nuxt runtime plugin never
|
|
84
|
+
> provided the config, so **every** `setConfig` under Nuxt — including from a
|
|
85
|
+
> component's `setup`, the path this page prescribed — wrote the process-global
|
|
86
|
+
> and leaked across concurrent visitors, silently. If you worked around it,
|
|
87
|
+
> you can stop.
|
|
88
|
+
|
|
89
|
+
#### The rule, and what the dev warning means
|
|
90
|
+
|
|
91
|
+
**`setConfig` during a server render needs an app to address.** From a
|
|
92
|
+
component's `setup` (or a composable a component calls), or inside
|
|
93
|
+
`app.runWithContext`, it resolves the current app and the write is
|
|
94
|
+
per-visitor. With neither — module scope, say — there is no app, the write
|
|
95
|
+
lands on the process-global build-time defaults, and it leaks into other
|
|
96
|
+
visitors being served concurrently.
|
|
97
|
+
|
|
98
|
+
The dev warning fires on exactly that: it compares where the write actually
|
|
99
|
+
landed against the build-time object, rather than guessing from the call site.
|
|
100
|
+
So it stays silent for a correct per-app write, and it still fires for a
|
|
101
|
+
global one made from inside a component — which is what a missing plugin (or,
|
|
102
|
+
before beta.19, Nuxt) produced.
|
|
103
|
+
|
|
104
|
+
On the client none of this matters: one process is one user, and `setConfig`
|
|
105
|
+
from anywhere is fine.
|
|
106
|
+
|
|
107
|
+
_(Changed in 3.0.0-beta.15 — Q18.2. Before it, the config was a single
|
|
108
|
+
process-global object and a per-visitor locale genuinely was impossible.)_
|
|
48
109
|
|
|
49
110
|
## Usage example
|
|
50
111
|
|
|
@@ -9,7 +9,9 @@ type: composable
|
|
|
9
9
|
## Summary
|
|
10
10
|
|
|
11
11
|
`useConfirm` opens a modal confirm dialog and returns a promise that resolves
|
|
12
|
-
with the user's decision.
|
|
12
|
+
with the user's decision. **A new `confirm()` replaces the open dialog**: the
|
|
13
|
+
superseded promise resolves `false` and no callback runs. Dialogs do not queue,
|
|
14
|
+
so `await` one before opening the next.
|
|
13
15
|
Per the design language, every `destructive` action must pass through a confirm.
|
|
14
16
|
|
|
15
17
|
**Requires exactly one `<BbConfirm />` host, mounted at the app root** (`App.vue`
|
|
@@ -28,7 +30,7 @@ const { confirm, close, dismissAll } = useConfirm();
|
|
|
28
30
|
|
|
29
31
|
**Ownership** — when called inside a component (any effect scope), the
|
|
30
32
|
returned `confirm`'s dialogs are tied to that scope: if it is disposed while a
|
|
31
|
-
dialog is open
|
|
33
|
+
dialog is open (browser Back, route change, the component unmounts),
|
|
32
34
|
the dialog is dismissed quietly — promise resolved `false`, no callback runs.
|
|
33
35
|
Call `useConfirm()` outside a component scope (app setup, store, module level)
|
|
34
36
|
for app-lifetime confirms.
|
|
@@ -71,7 +73,7 @@ promise pending.
|
|
|
71
73
|
declare function dismissAll(): void;
|
|
72
74
|
```
|
|
73
75
|
|
|
74
|
-
Quietly dismisses the open dialog
|
|
76
|
+
Quietly dismisses the open dialog, regardless of owner:
|
|
75
77
|
pending promises resolve `false`, no callback runs. An imperative escape hatch
|
|
76
78
|
for app-level events — logout, a global error boundary, or router wiring in
|
|
77
79
|
apps that want route-based dismissal.
|
|
@@ -14,13 +14,18 @@ Knowledge base root (installed package):
|
|
|
14
14
|
Package export entry: `bitboss-ui/ai` → `dist/ai/index.md`.
|
|
15
15
|
Subpaths: `bitboss-ui/ai/components.json`, `bitboss-ui/ai/guides/…`, etc.
|
|
16
16
|
|
|
17
|
-
**Not installed, or can only fetch URLs?** The same files are served
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
[
|
|
17
|
+
**Not installed, or can only fetch URLs?** The same files are served at
|
|
18
|
+
`https://llms-bitboss-ui.bitboss.it/dist/ai/…`. If you can make only one
|
|
19
|
+
request, fetch
|
|
20
|
+
[`/dist/llms-medium.txt`](https://llms-bitboss-ui.bitboss.it/dist/llms-medium.txt)
|
|
21
21
|
— this router plus the agent contract, setup, component picker, design language
|
|
22
22
|
and the full component catalogue, in ~110 KB.
|
|
23
23
|
|
|
24
|
+
That host is a thin proxy in front of the published npm tarball. If it is ever
|
|
25
|
+
unreachable, the same paths work directly against
|
|
26
|
+
`https://cdn.jsdelivr.net/npm/bitboss-ui@beta/…` — one hop further from us, and
|
|
27
|
+
pinned to the prerelease channel rather than following it.
|
|
28
|
+
|
|
24
29
|
---
|
|
25
30
|
|
|
26
31
|
## Mandatory order (every UI task)
|
|
@@ -231,24 +231,24 @@ a composable you want is not in this corpus's `composables/` folder — it is no
|
|
|
231
231
|
here.** Check this list before inventing a name; if the need is genuinely absent,
|
|
232
232
|
compose it or write it yourself.
|
|
233
233
|
|
|
234
|
-
| Assumed component or composable | Reality
|
|
235
|
-
| -------------------------------------------------------------- |
|
|
236
|
-
| `BbColumnManager` — show/hide/reorder columns | Does not exist.
|
|
237
|
-
| `BbKanban` / drag-and-drop board | Does not exist. There is no DnD primitive in the library
|
|
238
|
-
| `BbModal` | It is [BbDialog](../BbDialog.md).
|
|
239
|
-
| `BbDrawer` / `BbSheet` | It is [BbOffCanvas](../BbOffCanvas.md).
|
|
240
|
-
| `BbCombobox` / `BbAutocomplete` | It is [BbSelect](../BbSelect.md) / [BbSelectPopover](../BbSelectPopover.md) — search is built in, see `disable-writing`.
|
|
241
|
-
| `BbToggle` / `BbToggleGroup` | It is [BbButton](../BbButton.md) with `v-model` (+ `true-value` / `false-value`), which owns `aria-pressed` and the active class.
|
|
242
|
-
| `TagChip` / colored, read-only tag chip | It is [BbBadge](../BbBadge.md) — [BbTag](../BbTag.md) is a tags-_input_ only, not a display component. Use `BbBadge` with a registered `soft-*` variant for a fixed palette, or a one-off `--bg`/`--color` override per row for arbitrary/data-driven colors (BbBadge.md § One-off colors) — not a registered variant per distinct color.
|
|
243
|
-
| `BbTab` (singular) | The consumer API is [BbTabs](../BbTabs.md) / `BbTabsRoot`. `BbTab` appears only as the **v2 "before" side** of the migration diffs.
|
|
244
|
-
| `BbCard` | Does not exist — a card is a `<div>` with tokens. See [design-language](./design-language.md).
|
|
245
|
-
| `BbList` / `BbListItem` / `BbDescriptionList` | Do not exist — a list row is an `<li>` with tokens, and [BbBaseButton](../BbBaseButton.md) makes the whole row navigable. See the note under Data Display.
|
|
246
|
-
| `useLiveFeed` / any polling or cross-tab feed helper | Does not exist, and neither does a cross-tab helper — `useBroadcastChannelInstance` was removed (cross-tab messaging is not a UI concern). Use `useBroadcastChannel` from `@vueuse/core`; the polling and the merge are yours.
|
|
247
|
-
| `BbStepper` / `BbWizard` | Does not exist as a component; the wizard-form recipe composes one.
|
|
248
|
-
| `BbSkeleton` (standalone) | Only `BbTable` ships skeletons, via the column `skeleton` field.
|
|
249
|
-
| `BbCommand` / command palette | Does not exist. Compose `BbDialog` + `BbSelectPopover`.
|
|
250
|
-
| `BbCalendar` (month / scheduling view) | Does not exist. [BbDatePicker](../BbDatePicker.md) is a picker, not a calendar surface.
|
|
251
|
-
| `BbChart` / `BbGraph`, `BbCarousel`, `BbTimeline`, `BbDivider` | Do not exist. No charting, carousel or timeline primitive ships here.
|
|
234
|
+
| Assumed component or composable | Reality |
|
|
235
|
+
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
236
|
+
| `BbColumnManager` — show/hide/reorder columns | Does not exist as a component. Order is `v-model:order` on `BbTable` (an array of keys any panel can write; `reorderable` adds the built-in header drag + keyboard handle); visibility is `hidden: true` on the column definition (the column stays declared and keeps its slot in the order; header slots get a `hideColumn()` that fires `hide:column`). Compose the panel from `BbPopover` + `BbCheckbox`. |
|
|
237
|
+
| `BbKanban` / drag-and-drop board | Does not exist. There is no reusable DnD primitive in the library (`BbTable`'s header drag is internal to the table) — compose the board from `BbTable` (a table/list view of the same data) or hand-roll the drag-and-drop interaction yourself. |
|
|
238
|
+
| `BbModal` | It is [BbDialog](../BbDialog.md). |
|
|
239
|
+
| `BbDrawer` / `BbSheet` | It is [BbOffCanvas](../BbOffCanvas.md). |
|
|
240
|
+
| `BbCombobox` / `BbAutocomplete` | It is [BbSelect](../BbSelect.md) / [BbSelectPopover](../BbSelectPopover.md) — search is built in, see `disable-writing`. |
|
|
241
|
+
| `BbToggle` / `BbToggleGroup` | It is [BbButton](../BbButton.md) with `v-model` (+ `true-value` / `false-value`), which owns `aria-pressed` and the active class. |
|
|
242
|
+
| `TagChip` / colored, read-only tag chip | It is [BbBadge](../BbBadge.md) — [BbTag](../BbTag.md) is a tags-_input_ only, not a display component. Use `BbBadge` with a registered `soft-*` variant for a fixed palette, or a one-off `--bg`/`--color` override per row for arbitrary/data-driven colors (BbBadge.md § One-off colors) — not a registered variant per distinct color. |
|
|
243
|
+
| `BbTab` (singular) | The consumer API is [BbTabs](../BbTabs.md) / `BbTabsRoot`. `BbTab` appears only as the **v2 "before" side** of the migration diffs. |
|
|
244
|
+
| `BbCard` | Does not exist — a card is a `<div>` with tokens. See [design-language](./design-language.md). |
|
|
245
|
+
| `BbList` / `BbListItem` / `BbDescriptionList` | Do not exist — a list row is an `<li>` with tokens, and [BbBaseButton](../BbBaseButton.md) makes the whole row navigable. See the note under Data Display. |
|
|
246
|
+
| `useLiveFeed` / any polling or cross-tab feed helper | Does not exist, and neither does a cross-tab helper — `useBroadcastChannelInstance` was removed (cross-tab messaging is not a UI concern). Use `useBroadcastChannel` from `@vueuse/core`; the polling and the merge are yours. |
|
|
247
|
+
| `BbStepper` / `BbWizard` | Does not exist as a component; the wizard-form recipe composes one. |
|
|
248
|
+
| `BbSkeleton` (standalone) | Only `BbTable` ships skeletons, via the column `skeleton` field. |
|
|
249
|
+
| `BbCommand` / command palette | Does not exist. Compose `BbDialog` + `BbSelectPopover`. |
|
|
250
|
+
| `BbCalendar` (month / scheduling view) | Does not exist. [BbDatePicker](../BbDatePicker.md) is a picker, not a calendar surface. |
|
|
251
|
+
| `BbChart` / `BbGraph`, `BbCarousel`, `BbTimeline`, `BbDivider` | Do not exist. No charting, carousel or timeline primitive ships here. |
|
|
252
252
|
|
|
253
253
|
App chrome — an app shell, sidebar, page header, selection dock — is
|
|
254
254
|
deliberately **not** a component: it is yours to own. The per-platform
|
|
@@ -53,20 +53,20 @@ naming rules, the emphasis ladder) lives in
|
|
|
53
53
|
|
|
54
54
|
### Surfaces & structure
|
|
55
55
|
|
|
56
|
-
| Token | Meaning
|
|
57
|
-
| --------------------- |
|
|
58
|
-
| `--bb-panel` | Surface/background color of panels, popovers, dialogs
|
|
59
|
-
| `--bb-muted` | Subtle/disabled surface (derived, neutral)
|
|
60
|
-
| `--bb-hover` | Hover fill for **affordances** (buttons, links, controls)
|
|
61
|
-
| `--bb-surface-hover` | Hover fill for **passive surfaces** (rows, cells, days) — fainter
|
|
62
|
-
| `--bb-pressed` | Neutral pressed/active fill
|
|
63
|
-
| `--bb-border` | Border color; pair with `--bb-border-w` (1px)
|
|
64
|
-
| `--bb-radius` | Corner radius of controls (8px)
|
|
65
|
-
| `--bb-radius-surface` | Corner radius of large surfaces (derived, ×1.8)
|
|
66
|
-
| `--bb-radius-sm` | Corner radius of small nested elements (derived)
|
|
67
|
-
| `--bb-shadow` | Global elevation shadow
|
|
68
|
-
| `--bb-panel-p` | Content padding of large surfaces (dialog, off-canvas)
|
|
69
|
-
| `--bb-z-overlay` | Z-index for overlays (10)
|
|
56
|
+
| Token | Meaning |
|
|
57
|
+
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
58
|
+
| `--bb-panel` | Surface/background color of panels, popovers, dialogs |
|
|
59
|
+
| `--bb-muted` | Subtle/disabled surface (derived, neutral) |
|
|
60
|
+
| `--bb-hover` | Hover fill for **affordances** (buttons, links, controls) |
|
|
61
|
+
| `--bb-surface-hover` | Hover fill for **passive surfaces** (rows, cells, days) — fainter |
|
|
62
|
+
| `--bb-pressed` | Neutral pressed/active fill |
|
|
63
|
+
| `--bb-border` | Border color; pair with `--bb-border-w` (1px) |
|
|
64
|
+
| `--bb-radius` | Corner radius of controls (8px) |
|
|
65
|
+
| `--bb-radius-surface` | Corner radius of large surfaces (derived, ×1.8) |
|
|
66
|
+
| `--bb-radius-sm` | Corner radius of small nested elements (derived) |
|
|
67
|
+
| `--bb-shadow` | Global elevation shadow |
|
|
68
|
+
| `--bb-panel-p` | Content padding of large surfaces (dialog, off-canvas); axis split via the locals `--px`/`--py` on `.bb-dialog` / `.bb-offcanvas` |
|
|
69
|
+
| `--bb-z-overlay` | Z-index for overlays (10) |
|
|
70
70
|
|
|
71
71
|
### Color semantics
|
|
72
72
|
|
|
@@ -190,11 +190,11 @@ multipliers — never literals.
|
|
|
190
190
|
|
|
191
191
|
### Scale
|
|
192
192
|
|
|
193
|
-
| Token | Default | Notes
|
|
194
|
-
| ---------------- | ------- |
|
|
195
|
-
| `--bb-control-h` | `32px` | Master control height. Inputs are exactly this; buttons/tabs derive their size scale from it via `calc()` offsets
|
|
196
|
-
| `--bb-fs` | `14px` | Master font size. Component font sizes derive via `calc()` offsets
|
|
197
|
-
| `--bb-panel-p` | `16px` | Content padding of large surfaces (dialog, off-canvas; header/footer paddings derive from it)
|
|
193
|
+
| Token | Default | Notes |
|
|
194
|
+
| ---------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
195
|
+
| `--bb-control-h` | `32px` | Master control height. Inputs are exactly this; buttons/tabs derive their size scale from it via `calc()` offsets |
|
|
196
|
+
| `--bb-fs` | `14px` | Master font size. Component font sizes derive via `calc()` offsets |
|
|
197
|
+
| `--bb-panel-p` | `16px` | Content padding of large surfaces (dialog, off-canvas; header/footer paddings derive from it). Axis split via the component locals `--px`/`--py` on `.bb-dialog` / `.bb-offcanvas`, each branching off `var(--bb-panel-p)`; set the pair (on the component's class) only when the axes differ |
|
|
198
198
|
|
|
199
199
|
### Motion
|
|
200
200
|
|
|
@@ -272,10 +272,13 @@ Rules:
|
|
|
272
272
|
component seals itself.
|
|
273
273
|
3. **Short names are for self-consumption only.** `--h`, `--px`, `--gap`,
|
|
274
274
|
`--fs`, `--r` are fine while the rules using them target the component's
|
|
275
|
-
own boxes. If a value must be read _inside a nested foreign component_
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
275
|
+
own boxes. If a value must be read _inside a nested foreign component_,
|
|
276
|
+
prefer moving the formula to an element the component owns, or a
|
|
277
|
+
distinctive name. One ruled exception (2026-08-25): the dialog/off-canvas
|
|
278
|
+
padding pair `--px`/`--py` is read by the nested close button's inset
|
|
279
|
+
formula — safe because `BbCloseButton` declares neither, a constraint that
|
|
280
|
+
component must keep (minting `--px`/`--py` there would silently mask the
|
|
281
|
+
surface's value and break the inset).
|
|
279
282
|
4. **Mint only what varies.** A size variant that overrides four locals is
|
|
280
283
|
four tokens, not four × six sizes. Per-size lookup tables
|
|
281
284
|
(`--h-xs … --h-2xl`) are allowed only when a responsive matrix genuinely
|
|
@@ -443,19 +446,22 @@ every derivation that mixes it. It is also the trap. Write
|
|
|
443
446
|
} /* wrong: not a <percentage> */
|
|
444
447
|
```
|
|
445
448
|
|
|
446
|
-
and nothing errors — not the build, not the console. The
|
|
447
|
-
|
|
448
|
-
|
|
449
|
+
and nothing errors — not the build, not the console. The declaration is
|
|
450
|
+
discarded and the token lands on the registered `initial-value: 15%` — which
|
|
451
|
+
happens to be the very value this override asked for, so a light page looks
|
|
452
|
+
right by accident. Write `0.4` on a dark page instead and the ring quietly
|
|
453
|
+
drops from the shipped `40%` to `15%` (opacity is the ring's strength; its
|
|
454
|
+
thickness is `--bb-ring-size`).
|
|
449
455
|
Percentages need the `%`; colors must be a `<color>` (`transparent` and
|
|
450
456
|
`currentColor` qualify, `none` and a mistyped hex do not). Nothing in the
|
|
451
457
|
toolchain catches it either: `bitboss-ui check` reads `.vue`/`.md`, never
|
|
452
458
|
stylesheets.
|
|
453
459
|
|
|
454
460
|
Fail-soft is only soft when the initial value is close to the real one. Every
|
|
455
|
-
|
|
456
|
-
renders the library's own light theme.
|
|
457
|
-
|
|
458
|
-
|
|
461
|
+
registered knob — `--bb-ring-opacity` included — is registered at its light
|
|
462
|
+
default, so a rejected override renders the library's own light theme. On a
|
|
463
|
+
dark page that is still visible: a rejected `--bb-ring-opacity` lands on the
|
|
464
|
+
light `15%` against the shipped dark `40%`.
|
|
459
465
|
|
|
460
466
|
Typed knobs are also **animatable**. Add `.theme-animated`
|
|
461
467
|
(main.css) to the element that carries the scheme class or theme overrides:
|
|
@@ -609,9 +615,10 @@ escape the host dialog's `overflow: hidden` and centering transform.
|
|
|
609
615
|
| `--bb-overlay-color` + `--bb-overlay-opacity` | `--bb-overlay` (one color with alpha) |
|
|
610
616
|
| `--bb-overlay-z-index` | `--bb-z-overlay` |
|
|
611
617
|
| inline ring `color-mix()` formulas | `--bb-ring` / `--bb-ring-danger` (strength knob: `--bb-ring-opacity`) |
|
|
612
|
-
| `--bb-dialog-px/pt/pb/gap/…` | `--bb-panel-p`
|
|
618
|
+
| `--bb-dialog-px/pt/pb/gap/…` | `--bb-panel-p` + the local axis pair `--px`/`--py` on the surface roots |
|
|
613
619
|
| `--bb-button-*`, `--bb-tabs-*`, `--bb-checkbox-*`, `--bb-radio-*`, `--bb-switch-*`, `--bb-rating-*`, `--bb-slider-*`, `--bb-table-cell-h`, `--bb-progress-track` | unprefixed locals in each component's CSS |
|
|
614
|
-
| `--bb-table-offset
|
|
620
|
+
| `--bb-table-offset-*` (JS plumbing) | unprefixed locals on `.bb-table` (`--offset-*`) |
|
|
621
|
+
| `--bb-table-fill`, `--bb-table-natural-width` | **removed** with the grid substrate — nothing publishes them any more (v3.0) |
|
|
615
622
|
| `--bb-table-{id}-track-{key}` (parent→nested width bridge) | `--table-{id}-track-{key}` (distinctive cross-component name, rule 3) |
|
|
616
623
|
| `--bb-select-option-*`, `--bb-primary-base`, all `--x-light`/`--x-dark` shadows | deleted (dead) |
|
|
617
624
|
|
|
@@ -58,7 +58,7 @@ The corollary: **`prefill` cannot tell you an initial load from a dependency ref
|
|
|
58
58
|
|
|
59
59
|
### The `prefill` prop (`BbSelect` / `BbSelectPopover`)
|
|
60
60
|
|
|
61
|
-
`prefill` controls **when** the initial load happens: `'interaction'` (default) waits for the first user interaction, `true` loads on mount (SSR-friendly — it also runs in `onServerPrefetch`), `false` is **search-first** — nothing loads until the user types, so opening the panel fetches nothing and the list shows a "search to begin" hint until the first query. Groups and tables always load on mount.
|
|
61
|
+
`prefill` controls **when** the initial load happens: `'interaction'` (default) waits for the first user interaction, `true` loads on mount (SSR-friendly — under `bitboss-ui/nuxt` it also runs in `onServerPrefetch` and the result is transferred to the client; see [SSR prefill](./ssr-prefill.md)), `false` is **search-first** — nothing loads until the user types, so opening the panel fetches nothing and the list shows a "search to begin" hint until the first query. Groups and tables always load on mount.
|
|
62
62
|
|
|
63
63
|
Reach for `false` when the result set is too large or expensive to browse and the query is the only sensible entry point. Note that `false` and `'interaction'` differ **only** on this point: both skip the mount load, but `'interaction'` fetches on open and `false` waits for a query.
|
|
64
64
|
|
|
@@ -36,9 +36,13 @@ The `bitbossUi` Vite plugin (`iconDir` option) — or the Nuxt module (config ke
|
|
|
36
36
|
`lucide:<name>` available; removing it makes them all errors. Nothing to
|
|
37
37
|
configure.
|
|
38
38
|
- **Dev**: all icons of installed sets are registered. Referencing an
|
|
39
|
-
uninstalled prefix or a non-existent name fails loudly
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
uninstalled prefix or a non-existent name fails loudly in the Vite error
|
|
40
|
+
overlay with an actionable message. A typo inside an installed set reads
|
|
41
|
+
"does not exist in the lucide icon set — did you mean `lucide:…`?"; a set
|
|
42
|
+
that is not installed reads "no installed icon set has the prefix `mdi`
|
|
43
|
+
(installed sets: lucide) … run: `npm install -D @iconify-json/mdi`". Read
|
|
44
|
+
the message: a typo wants a different name, a missing set wants an install,
|
|
45
|
+
never a guess.
|
|
42
46
|
- **Build**: source files (`.vue`/`.ts`/`.js`/`.tsx`/`.jsx`; tests and stories
|
|
43
47
|
excluded) are scanned for static `provider:name` literals; each referenced
|
|
44
48
|
icon is emitted as its own lazy chunk. This is why rule 4 exists — and why an
|
|
@@ -235,8 +239,10 @@ markup) yourself:
|
|
|
235
239
|
- Decorative icon next to visible text (affixes, button prepend/append,
|
|
236
240
|
dropdown items): no label — the text already announces it; a label would
|
|
237
241
|
duplicate.
|
|
238
|
-
- Meaningful standalone icon: give `BbIcon` a `label` — it adds `role="img"
|
|
239
|
-
`aria-label
|
|
242
|
+
- Meaningful standalone icon: give `BbIcon` a `label` — it adds `role="img"`
|
|
243
|
+
and `aria-label`. Deliberately **no `title`**: that renders a native browser
|
|
244
|
+
tooltip, which double-tooltips any icon also carrying `v-bb-tooltip` (owner
|
|
245
|
+
ruling 2026-07-30, `BbIcon.vue:200`). For a visible tip, add `v-bb-tooltip`.
|
|
240
246
|
- Icon-only `BbButton` (the `icon` prop): supply the accessible name through the
|
|
241
247
|
label (default slot, or `text`) — it renders `sr-only` but is still announced.
|
|
242
248
|
`aria-label` is only an override; the one hard rule is that the button must
|
|
@@ -31,19 +31,16 @@ goes stable, so never reach for it here.
|
|
|
31
31
|
|
|
32
32
|
Peer dependency: `vue ^3.5.12` — the only required one. `@inertiajs/vue3` is an **optional** peer, needed only in Inertia apps.
|
|
33
33
|
|
|
34
|
-
`@iconify/collections
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
mean …?" suggestion for a mistyped icon name) never fire — a wrong provider
|
|
45
|
-
icon then surfaces only as `BbIcon`'s generic runtime `Icon "…" does not exist.`
|
|
46
|
-
Nothing else changes: icons that resolve still render, in dev and in production.
|
|
34
|
+
You do **not** need `@iconify/collections`. It is declared as an optional peer
|
|
35
|
+
for one reason only: when it happens to be installed, the dev-overlay message
|
|
36
|
+
for an unknown icon prefix can say for certain whether that prefix is a real
|
|
37
|
+
Iconify set ("requires `@iconify-json/mdi`, run …") or not ("neither an
|
|
38
|
+
installed set nor a known Iconify prefix"). Without it the same overlay fires
|
|
39
|
+
with a hedged wording ("no installed icon set has the prefix `mdi`; if it is an
|
|
40
|
+
Iconify set, run …"). A mistyped name inside a set you **have** installed
|
|
41
|
+
(`lucide:eye-misspelled`) is diagnosed from the set's own data in both cases,
|
|
42
|
+
with a "did you mean …?" suggestion. Nothing else changes: icons that resolve
|
|
43
|
+
still render, in dev and in production.
|
|
47
44
|
|
|
48
45
|
**Known-good toolchain:** TypeScript **5.x or 6.x** if your build gate runs
|
|
49
46
|
`vue-tsc`. Both type-check cleanly against the shipped `.d.ts`; the library
|
|
@@ -150,6 +147,45 @@ export default defineNuxtConfig({
|
|
|
150
147
|
|
|
151
148
|
All options below go under the `bitboss` config key. `nuxtLinkName` controls which globally registered component renders router links (default `'NuxtLink'`).
|
|
152
149
|
|
|
150
|
+
This module supersedes the standalone `@bitboss-dev/bitboss-ui-nuxt` package, which was the v2 Nuxt integration — uninstall it (see [Migration v2 → v3](./migration/v2-to-v3.md)).
|
|
151
|
+
|
|
152
|
+
### `autoImport?: boolean | { components?: boolean; composables?: boolean; validated?: boolean }` (default: `false`, Nuxt only)
|
|
153
|
+
|
|
154
|
+
Registers the library's components and composables with Nuxt's auto-import system, so templates write `<BbButton>` and `useToast()` with no import line:
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
// nuxt.config.ts
|
|
158
|
+
export default defineNuxtConfig({
|
|
159
|
+
modules: ['bitboss-ui/nuxt'],
|
|
160
|
+
bitboss: {
|
|
161
|
+
iconDir: './assets/icons',
|
|
162
|
+
autoImport: true,
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
`true` means `{ components: true, composables: true }`. Pass the object form to
|
|
168
|
+
narrow it, or to add `validated: true` — which resolves the form controls from
|
|
169
|
+
[`bitboss-ui/validated`](./validated-forms.md) instead of `bitboss-ui`, so
|
|
170
|
+
`<BbTextInput>` is the vee-validate-bound wrapper and takes `rules`, and adds
|
|
171
|
+
`BbForm`, `BbAsterisk`, `useBbFormContext` and `useValidatedField`. It needs the
|
|
172
|
+
`vee-validate` peer installed.
|
|
173
|
+
|
|
174
|
+
**It is off by default on purpose, and leaving it off is the better setup.**
|
|
175
|
+
Explicit imports are what make `vueCompilerOptions.checkUnknownComponents` (see
|
|
176
|
+
section 9) able to fail the build on a mistyped or unimported `Bb*` tag; with
|
|
177
|
+
auto-imports on, every `Bb*` tag resolves and that gate goes quiet. Reach for it
|
|
178
|
+
when you are moving an app off `@bitboss-dev/bitboss-ui-nuxt`, whose templates
|
|
179
|
+
were written against auto-imported components, and adding the imports is a
|
|
180
|
+
separate commit from the upgrade.
|
|
181
|
+
|
|
182
|
+
Two things it deliberately does not do. It never overrides your own components:
|
|
183
|
+
a `~/components/BbButton.vue` in the app keeps winning, and the library only
|
|
184
|
+
fills names the app has not claimed. And it never registers the library's
|
|
185
|
+
`useId` — Nuxt already auto-imports Vue's, and shadowing it would silently
|
|
186
|
+
redirect every existing `useId()` call in the app; import that one explicitly if
|
|
187
|
+
you want it.
|
|
188
|
+
|
|
153
189
|
## 4) Inertia
|
|
154
190
|
|
|
155
191
|
Inertia apps are Vite apps: configure `bitboss-ui/vite` exactly as in section 2, install `@inertiajs/vue3`, then install the runtime plugin in `createInertiaApp`:
|
|
@@ -269,7 +305,7 @@ utilities. (Same trap as the scoped-`<style>` case above, one level up.)
|
|
|
269
305
|
## 6) Icons
|
|
270
306
|
|
|
271
307
|
- `iconDir` (required) is scanned recursively for `.svg` files; each file becomes `local:<basename>`.
|
|
272
|
-
- Provider icons (`lucide:pencil`, `mdi:home`, …) require the matching `@iconify-json/<prefix>` package installed in the consumer app.
|
|
308
|
+
- Provider icons (`lucide:pencil`, `mdi:home`, …) require the matching `@iconify-json/<prefix>` package installed in the consumer app. In dev, every `prefix:name` the registry does not know produces a Vite error overlay with the fix: a mistyped name inside an installed set gets a "did you mean …?" hint, and an uninstalled prefix gets the list of installed sets plus the `npm install -D @iconify-json/<prefix>` command (the optional `@iconify/collections` peer only sharpens that wording, see [Install](#1-install)). A missing `local:` icon is a missing file in `iconDir` and surfaces as `BbIcon`'s runtime error naming it. Production builds report none of this — the scan simply drops what does not resolve, so a wrong name fails at runtime there.
|
|
273
309
|
- Production builds bundle **only statically referenced** provider icons — write icon names as literal strings (`icon="lucide:trash-2"`), never assemble them dynamically.
|
|
274
310
|
- The plugin also writes `node_modules/.bitboss-ui/local-icons.json` and (in dev, unless `vscodeSettings: false`) wires `.vscode/settings.json` so the Iconify editor extension previews local icons.
|
|
275
311
|
|
|
@@ -363,11 +399,12 @@ bitbossUi({
|
|
|
363
399
|
|
|
364
400
|
This is a **single global default baked in at build time** (it comes from the
|
|
365
401
|
Vite plugin config), so it is the same for every request — it is _not_ a
|
|
366
|
-
per-request value. There is no per-request/per-visitor override
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
audience.
|
|
402
|
+
per-request value. There is no per-request/per-visitor override: the viewport
|
|
403
|
+
signal is a process-wide singleton, so a mobile layout that must be correct on
|
|
404
|
+
the server's first paint (e.g. a modal already open on load) needs a client
|
|
405
|
+
adjustment after hydration, or a fixed `ssrViewportWidth` matching your
|
|
406
|
+
audience. (Unlike `locale`, which **is** per-request — see below. A width
|
|
407
|
+
cannot be derived from a request without UA sniffing; a locale can.)
|
|
371
408
|
|
|
372
409
|
### `defaultInputLabelMode?: 'outside' | 'floating' | 'inside'` (default: `'outside'`)
|
|
373
410
|
|
|
@@ -385,9 +422,32 @@ labels, screen-reader announcements, confirm buttons, …). The library ships
|
|
|
385
422
|
pl, tr, ru, uk, cs, ro, hu, el, sv, da, nb, fi, ja, ko, zh-cn — but shipping ≠
|
|
386
423
|
bundling: only the **enabled** locales enter your build (next option). Runtime
|
|
387
424
|
switching: `useBbConfig().setConfig({ locale })` — to a locale you enabled.
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
per
|
|
425
|
+
|
|
426
|
+
**Per-request locale under SSR** is supported as of 3.0.0-beta.15: the config
|
|
427
|
+
is held per Vue app, and SSR builds one app per request, so pass it where you
|
|
428
|
+
create the app — `app.use(bitbossUiPlugin, { locale: localeFor(request) })`.
|
|
429
|
+
That is correct on the server's first paint, which is what crawlers index and
|
|
430
|
+
what a JS-disabled reader keeps.
|
|
431
|
+
|
|
432
|
+
**In Nuxt, do not call `app.use`** — the module registers the runtime plugin,
|
|
433
|
+
which provides the per-app config itself (fixed in 3.0.0-beta.19, Q20.4;
|
|
434
|
+
before that Nuxt had no per-app config at all and every `setConfig` wrote the
|
|
435
|
+
process-global). Set a per-request locale from your own Nuxt plugin, which
|
|
436
|
+
runs per request on the server:
|
|
437
|
+
`nuxtApp.vueApp.runWithContext(() => useBbConfig().setConfig({ locale }))` —
|
|
438
|
+
the `runWithContext` is what hands the write this app's injection context,
|
|
439
|
+
since a plugin has an app but no component instance.
|
|
440
|
+
|
|
441
|
+
`setConfig` still works for runtime switching; during a server render call it
|
|
442
|
+
from a component's `setup` (or inside `runWithContext`), where it can resolve
|
|
443
|
+
the current app. With neither there is no app to address, the write lands on
|
|
444
|
+
the build-time defaults, and it leaks between concurrent visitors — it warns in
|
|
445
|
+
dev when it sees that, keyed off where the write actually landed rather than
|
|
446
|
+
the call site. See [useBbConfig](../composables/useBbConfig.md).
|
|
447
|
+
|
|
448
|
+
Note this is a **different rule** from `ssrViewportWidth` above, which really
|
|
449
|
+
is a build-time global: a width cannot be known per request without sniffing,
|
|
450
|
+
a locale can.
|
|
391
451
|
|
|
392
452
|
### `enabledLocales?: BuiltinLocaleKey[]` (default: your `locale` + `'en'`)
|
|
393
453
|
|
|
@@ -506,7 +566,7 @@ template emits are already styled by the public `bitboss-ui/styles.css`.
|
|
|
506
566
|
|
|
507
567
|
Add `--mcp` to also register a live MCP server (`npx bitboss-ui@<installed version> mcp`, pinned so npx can never fetch a different version from the registry) the harness launches on demand — it merges the entry (never overwriting other servers) into `.mcp.json` (Claude Code), `.cursor/mcp.json` (Cursor), `.vscode/mcp.json` (VS Code / Copilot), and `~/.codeium/windsurf/mcp_config.json` (Windsurf). **Windsurf's config is global** — it has no per-project scope, so registering it affects every project on the machine; that is why only the explicit `ai-init --mcp` command writes it, while the plugin's `mcp: true` dev-server flag (§7) auto-registers the project-scoped harnesses only. Install the server's optional peers first — `npm i -D @modelcontextprotocol/sdk zod` — they are not dependencies of the library (~12 MB used only by the MCP server); the command warns if they are absent. **`--mcp` is optional and skipping it loses you nothing but the transport** — the server only reads the `dist/ai/` files listed above, so run plain `ai-init` and let the agent read that directory if you cannot add the peers (see `mcp?: boolean` in §7).
|
|
508
568
|
|
|
509
|
-
For a human-in-the-loop (and agent) safety net, add the `bitboss-ui/eslint-plugin` flat-config plugin (`...bitbossUi.configs.recommended`) so unknown/removed `Bb*` props surface as ESLint errors in the editor and CI — the same manifest checks as `bitboss-ui check`, reusing your `eslint-plugin-vue` parser. Real HTML attributes fall through untouched; escape hatches are the standard `<!-- eslint-disable-next-line bitboss-ui/no-unknown-attributes -->` and the rule's `allowAttributes` / `allowComponents` options. **`eslint --fix` also auto-migrates deprecated v2 props** (renames, boolean-polarity inversions like `allowWriting`→`disableWriting`, value remaps like BbToast `placement`→`position`, and deletion of inert removed props); structural migrations that need a slot/directive/CSS are reported but left by hand. **This library is TS-first (recipes ship `<script setup lang="ts">`, some with `generic="T"`), so wire `@typescript-eslint/parser` for both `.ts` and `.vue` files** — without it `vue-eslint-parser` throws a `Parsing error` on those files, which means no rule (including `no-unknown-attributes`) runs on them at all. See the README "ESLint plugin" section for the full config snippet (both parser blocks + the `npm i -D @typescript-eslint/parser` line) and the fix table. `recommended` also enables `bitboss-ui/no-active-class-on-root-link`: `active-class` on a link-capable `Bb*` component (`BbButton`/`BbBaseButton`/`BbBadgeButton`) matches by path PREFIX, so a link whose target is the literal root (`href="/"` / `to="/"`) reads as "active" on every URL — the rule flags that combination and points you at `exact-active-class` instead.
|
|
569
|
+
For a human-in-the-loop (and agent) safety net, add the `bitboss-ui/eslint-plugin` flat-config plugin (`...bitbossUi.configs.recommended`) so unknown/removed `Bb*` props surface as ESLint errors in the editor and CI — the same manifest checks as `bitboss-ui check`, reusing your `eslint-plugin-vue` parser. Real HTML attributes fall through untouched; escape hatches are the standard `<!-- eslint-disable-next-line bitboss-ui/no-unknown-attributes -->` and the rule's `allowAttributes` / `allowComponents` options. **`eslint --fix` also auto-migrates deprecated v2 props** (renames, boolean-polarity inversions like `allowWriting`→`disableWriting`, value remaps like BbToast `placement`→`position`, and deletion of inert removed props); structural migrations that need a slot/directive/CSS are reported but left by hand. One deliberate boundary: the rule's "did you mean `<prop>`?" hints for a mistyped/unknown attribute are advisory message text, not fixes — `eslint --fix` (including an unattended run in a pre-commit hook) never applies them; only the registered v2→v3 migrations above are auto-fixed. A guess applied blind across a codebase would be a silent behavior change, so acting on a hint is always a per-site decision. **This library is TS-first (recipes ship `<script setup lang="ts">`, some with `generic="T"`), so wire `@typescript-eslint/parser` for both `.ts` and `.vue` files** — without it `vue-eslint-parser` throws a `Parsing error` on those files, which means no rule (including `no-unknown-attributes`) runs on them at all. See the README "ESLint plugin" section for the full config snippet (both parser blocks + the `npm i -D @typescript-eslint/parser` line) and the fix table. `recommended` also enables `bitboss-ui/no-active-class-on-root-link`: `active-class` on a link-capable `Bb*` component (`BbButton`/`BbBaseButton`/`BbBadgeButton`) matches by path PREFIX, so a link whose target is the literal root (`href="/"` / `to="/"`) reads as "active" on every URL — the rule flags that combination and points you at `exact-active-class` instead.
|
|
510
570
|
|
|
511
571
|
**The manifest ships with the package** — `dist/ai/components.json` is inside
|
|
512
572
|
the tarball, and the rules resolve it relative to their own file, so a normal
|
|
@@ -516,6 +576,8 @@ nothing), the rules cannot check anything: they now **warn once** saying they
|
|
|
516
576
|
are inactive rather than passing silently. Pass `failClosed: true` to a rule's
|
|
517
577
|
options if you would rather CI stop than under-check.
|
|
518
578
|
|
|
579
|
+
`recommended` also enables **`bitboss-ui/no-reverse-false`**, which covers the one v2 break a rename table cannot: `reverse` on `BbCheckbox` / `BbRadio` / `BbSwitch` kept its NAME and inverted its MEANING in v3, so the v2 spelling `:reverse="false"` (control on the right) is now a no-op that renders the control on the LEFT. Nothing else catches it — it is a declared prop, correctly typed, holding its own default value — and it cannot be expressed as a rename, because a rename entry is keyed by prop name and would rewrite the legitimate v3 spellings too. The rule flags only a LITERAL `:reverse="false"` (a dynamic `:reverse="isRtl"` that evaluates false is left alone) and offers both corrections as editor suggestions; pass `{ assumeV2: true }` to promote the v2-intent rewrite to a real `--fix` for a bulk sweep, then remove it — the two readings produce opposite layouts, so it must never be on by default. See [the migration guide](../guides/migration/components/bb-checkbox.md).
|
|
580
|
+
|
|
519
581
|
It also enables `bitboss-ui/require-partner-prop`: an opt-in prop set without its documented required partner — BbTable `keyboard-navigation` / `v-model:highlighted` without `row-class` (the shipped tint says "current row"; `row-class` says why, and is how you override it), or `loading-text` without `:loading` bound — compiles and mounts clean and just does nothing; the rule names the missing partner and quotes why.
|
|
520
582
|
|
|
521
583
|
## 9) Setup Verification Checklist
|
|
@@ -20,6 +20,7 @@ The three groups share their surface (`BbSwitchGroup` re-exports
|
|
|
20
20
|
| `name: string` required (**BbRadioGroup** only; the other two already optional) | `name?: string` (auto-generated per group when omitted) | relaxation — the generated name is unique per group instance, so options still group and two groups never collide |
|
|
21
21
|
| — | `legendMode: 'outside' \| 'inside'`, `description` | additive |
|
|
22
22
|
| `BbSwitchGroup` `multiple: false` silently ignored (always array emit) | honored — emits a bare value in single-select mode | **⚠ behavioral** (bugfix: the prop was advertised but never forwarded; fixed 2026-07-18) |
|
|
23
|
+
| `disabled` / `selectable: false` left a **selected** option interactive | a selected option is disabled like any other | **⚠ behavioral** (bugfix, 2026-08-31 — see below) |
|
|
23
24
|
|
|
24
25
|
`max` (checkbox/switch), `required` (radio), and `multiple` defaults are
|
|
25
26
|
unchanged.
|
|
@@ -54,6 +55,35 @@ The `item.disabled` change is the dangerous one: nothing errors, options that
|
|
|
54
55
|
used to render disabled simply become selectable. Grep item-building code for
|
|
55
56
|
`disabled:` near these groups.
|
|
56
57
|
|
|
58
|
+
## `disabled` now disables the selection too
|
|
59
|
+
|
|
60
|
+
Until 2026-08-31 a **selected** option in a `disabled` (or
|
|
61
|
+
`selectable: false`) group stayed interactive: it rendered without the native
|
|
62
|
+
`disabled` attribute, and clicking it emitted `update:modelValue` with the
|
|
63
|
+
option removed. So a fieldset switched off to prevent edits still let the user
|
|
64
|
+
clear the value it was showing.
|
|
65
|
+
|
|
66
|
+
```vue
|
|
67
|
+
<!-- before: "a" was clickable, and clicking it emitted [] -->
|
|
68
|
+
<BbCheckboxGroup v-model="picked" disabled :items="items" legend="Plan" />
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The resolver short-circuited on `selected` above both checks. That escape
|
|
72
|
+
exists for the **`max` swap affordance** — at the cap, already-selected options
|
|
73
|
+
stay live so the user can trade one for another — and it now sits only above
|
|
74
|
+
the `max` check, where it belongs. Unchanged:
|
|
75
|
+
|
|
76
|
+
```vue
|
|
77
|
+
<!-- still works: at max, selected options remain tradeable -->
|
|
78
|
+
<BbCheckboxGroup v-model="picked" :max="1" :items="items" legend="Plan" />
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**What to check when you upgrade.** If you relied on the old behaviour to let
|
|
82
|
+
someone _remove_ a value from an otherwise locked group, `disabled` is no
|
|
83
|
+
longer the prop for that — it now means what it says. Use `readonly`, which
|
|
84
|
+
keeps the options focusable and announced (`aria-readonly`) while blocking
|
|
85
|
+
every change, or leave the group enabled and gate on your own handler.
|
|
86
|
+
|
|
57
87
|
## DOM: the shared `bb-cr-container` block split three ways
|
|
58
88
|
|
|
59
89
|
v2 rendered one prefix for all three groups — `bb-cr-container` ("checkbox /
|