bitboss-ui 3.0.0-beta.48 → 3.0.0-beta.49
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 +24 -7
- package/bin/bitboss-ui-mcp.mjs +15 -3
- package/bin/bitboss-ui.mjs +115 -13
- package/dist/ai/BbAvatar.md +1 -1
- package/dist/ai/BbBreadcrumbs.md +65 -65
- package/dist/ai/BbButton.md +16 -5
- package/dist/ai/BbCheckbox.md +0 -2
- package/dist/ai/BbCheckboxGroup.md +13 -20
- package/dist/ai/BbDatePickerInput.md +4 -2
- package/dist/ai/BbDialog.md +1 -8
- package/dist/ai/BbDropdown.md +231 -220
- package/dist/ai/BbDropdownButton.md +65 -65
- package/dist/ai/BbDropdownGroup.md +2 -2
- package/dist/ai/BbDropzone.md +10 -10
- package/dist/ai/BbForm.md +43 -52
- package/dist/ai/BbHoverCard.md +4 -2
- package/dist/ai/BbNumberInput.md +88 -21
- package/dist/ai/BbPopover.md +29 -23
- package/dist/ai/BbProgress.md +48 -22
- package/dist/ai/BbRadioGroup.md +13 -19
- package/dist/ai/BbSelect.md +16 -36
- package/dist/ai/BbSelectPopover.md +14 -30
- package/dist/ai/BbSmoothHeight.md +0 -2
- package/dist/ai/BbSwitchGroup.md +13 -20
- package/dist/ai/BbTable.md +11 -10
- package/dist/ai/BbTabs.md +106 -105
- package/dist/ai/BbTabsList.md +2 -2
- package/dist/ai/BbTabsPanels.md +1 -1
- package/dist/ai/BbTabsRoot.md +2 -2
- package/dist/ai/BbTooltip.md +24 -10
- package/dist/ai/BbTree.md +14 -11
- package/dist/ai/changelog.json +256 -5
- package/dist/ai/components.json +36 -34
- package/dist/ai/composables/useBbDropdownContext.md +16 -16
- package/dist/ai/composables/useBbFormField.md +5 -1
- package/dist/ai/composables/useBbTabsContext.md +14 -14
- package/dist/ai/guides/agent-contract.md +27 -27
- package/dist/ai/guides/ai-router.md +1 -1
- package/dist/ai/guides/component-picker.md +3 -3
- package/dist/ai/guides/fetch-items-playbook.md +1 -1
- package/dist/ai/guides/icons-policy.md +10 -10
- package/dist/ai/guides/inertia-helpers.md +120 -67
- package/dist/ai/guides/installation-and-plugin-setup.md +43 -15
- package/dist/ai/guides/migration/components/bb-breadcrumbs.md +3 -2
- package/dist/ai/guides/migration/components/bb-checkbox-group.md +16 -16
- package/dist/ai/guides/migration/components/bb-dropdown-button.md +9 -8
- package/dist/ai/guides/migration/components/bb-dropdown.md +15 -14
- package/dist/ai/guides/migration/components/bb-radio-group.md +2 -1
- package/dist/ai/guides/migration/components/bb-select-popover.md +6 -1
- package/dist/ai/guides/migration/components/bb-select.md +10 -2
- package/dist/ai/guides/migration/components/bb-switch-group.md +2 -1
- package/dist/ai/guides/migration/components/bb-tabs.md +9 -8
- package/dist/ai/guides/migration/components/bb-tooltip.md +1 -1
- package/dist/ai/guides/migration/v2-to-v3.md +114 -17
- package/dist/ai/guides/migration/v3-beta-tooling.md +11 -0
- package/dist/ai/guides/options-items-playbook.md +30 -24
- package/dist/ai/guides/passthrough.md +2 -2
- package/dist/ai/guides/preset-components.md +18 -3
- package/dist/ai/guides/typescript-generic-components.md +1 -1
- package/dist/ai/guides/validated-forms.md +11 -22
- package/dist/ai/guides/validation-providers.md +4 -3
- package/dist/ai/helpers/inertia/manifest.json +636 -0
- package/dist/ai/helpers/inertia/types.ts +15 -0
- package/dist/ai/helpers/inertia/useAsyncFn.ts +110 -0
- package/dist/ai/helpers/inertia/useConfirmOnRouteLeave.ts +102 -0
- package/dist/ai/helpers/inertia/useDeleteCmd.ts +30 -0
- package/dist/ai/helpers/inertia/useHasChanged.ts +36 -0
- package/dist/ai/helpers/inertia/useIndexById.ts +23 -0
- package/dist/ai/helpers/inertia/useLazyProp.ts +148 -0
- package/dist/ai/helpers/inertia/useLazyPropGetter.ts +50 -0
- package/dist/ai/helpers/inertia/useLoading.ts +20 -0
- package/dist/ai/helpers/inertia/usePaginatedResponseContext.ts +88 -0
- package/dist/ai/helpers/inertia/usePromiseForm.ts +62 -0
- package/dist/ai/helpers/inertia/useProp.ts +63 -0
- package/dist/ai/helpers/inertia/useQuery.ts +19 -0
- package/dist/ai/helpers/inertia/useQueryObject.ts +116 -0
- package/dist/ai/helpers/inertia/useResourceContext.ts +69 -0
- package/dist/ai/helpers/inertia/useRouteQuery.ts +54 -0
- package/dist/ai/helpers/inertia/useScreenSizes.ts +23 -0
- package/dist/ai/helpers/inertia/useTableContext.ts +34 -0
- package/dist/ai/helpers/inertia/useTableSelectionContext.ts +48 -0
- package/dist/ai/helpers/inertia/useUntil.ts +33 -0
- package/dist/ai/helpers/inertia/utils.ts +24 -0
- package/dist/ai/index.md +6 -6
- package/dist/ai/manifest/components/BbBreadcrumbs.json +10 -6
- package/dist/ai/manifest/components/BbBreadcrumbs.tree.json +1 -1
- package/dist/ai/manifest/components/BbButton.json +1 -1
- package/dist/ai/manifest/components/BbCheckboxGroup.json +2 -2
- package/dist/ai/manifest/components/BbDropdown.json +23 -20
- package/dist/ai/manifest/components/BbDropdown.tree.json +2 -2
- package/dist/ai/manifest/components/BbDropdownButton.json +22 -19
- package/dist/ai/manifest/components/BbDropdownButton.tree.json +1 -1
- package/dist/ai/manifest/components/BbDropdownGroup.json +2 -2
- package/dist/ai/manifest/components/BbForm.json +1 -0
- package/dist/ai/manifest/components/BbNumberInput.json +6 -1
- package/dist/ai/manifest/components/BbNumberInput.tree.json +2 -1
- package/dist/ai/manifest/components/BbPopover.json +1 -0
- package/dist/ai/manifest/components/BbProgress.json +6 -6
- package/dist/ai/manifest/components/BbProgress.tree.json +1 -0
- package/dist/ai/manifest/components/BbRadioGroup.json +2 -2
- package/dist/ai/manifest/components/BbSelect.json +2 -2
- package/dist/ai/manifest/components/BbSelectPopover.json +2 -2
- package/dist/ai/manifest/components/BbSwitchGroup.json +2 -2
- package/dist/ai/manifest/components/BbTabs.json +7 -6
- package/dist/ai/manifest/components/BbTabsList.json +3 -3
- package/dist/ai/manifest/components/BbTabsPanels.json +1 -1
- package/dist/ai/manifest/components/BbTabsRoot.json +5 -4
- package/dist/ai/manifest/components/BbTooltip.json +1 -1
- package/dist/ai/manifest/index.json +2 -2
- package/dist/ai/manifest/meta.json +2 -0
- package/dist/ai/manifest/types.advanced.json +10 -9
- package/dist/ai/manifest/types.api.json +5 -4
- package/dist/ai/recipes/inertia/approvals-inbox.md +16 -18
- package/dist/ai/recipes/inertia/inline-edit-workspace.md +23 -33
- package/dist/ai/recipes/inertia/layout-scaffold.md +16 -16
- package/dist/ai/recipes/inertia/onboarding.md +6 -10
- package/dist/ai/recipes/inertia/ownership-atlas.md +15 -18
- package/dist/ai/recipes/inertia/record-form.md +11 -11
- package/dist/ai/recipes/inertia/records-workspace.md +38 -41
- package/dist/ai/recipes/inertia/settings-workspace.md +26 -38
- package/dist/ai/recipes/inertia/upload-center.md +31 -39
- package/dist/ai/recipes/inertia/wizard-form.md +10 -19
- package/dist/ai/recipes/nuxt/approvals-inbox.md +7 -8
- package/dist/ai/recipes/nuxt/inline-edit-workspace.md +14 -24
- package/dist/ai/recipes/nuxt/layout-scaffold.md +16 -16
- package/dist/ai/recipes/nuxt/onboarding.md +2 -6
- package/dist/ai/recipes/nuxt/ownership-atlas.md +7 -9
- package/dist/ai/recipes/nuxt/record-form.md +5 -5
- package/dist/ai/recipes/nuxt/records-workspace.md +29 -31
- package/dist/ai/recipes/nuxt/settings-workspace.md +22 -34
- package/dist/ai/recipes/nuxt/upload-center.md +22 -29
- package/dist/ai/recipes/nuxt/wizard-form.md +3 -11
- package/dist/ai/recipes/vue/approvals-inbox.md +7 -8
- package/dist/ai/recipes/vue/inline-edit-workspace.md +14 -24
- package/dist/ai/recipes/vue/layout-scaffold.md +16 -16
- package/dist/ai/recipes/vue/onboarding.md +2 -6
- package/dist/ai/recipes/vue/ownership-atlas.md +7 -9
- package/dist/ai/recipes/vue/record-form.md +5 -5
- package/dist/ai/recipes/vue/records-workspace.md +29 -31
- package/dist/ai/recipes/vue/settings-workspace.md +22 -34
- package/dist/ai/recipes/vue/upload-center.md +22 -29
- package/dist/ai/recipes/vue/wizard-form.md +3 -11
- package/dist/ai/source/BbAccordion.md +1 -1
- package/dist/ai/source/BbAlert.md +3 -3
- package/dist/ai/source/BbBadge.md +2 -2
- package/dist/ai/source/BbBadgeButton.md +5 -4
- package/dist/ai/source/BbBaseButton.md +1 -1
- package/dist/ai/source/BbBaseRadioIcon.md +1 -0
- package/dist/ai/source/BbBaseSwitchIcon.md +1 -0
- package/dist/ai/source/BbBreadcrumbs.md +63 -42
- package/dist/ai/source/BbButton.md +71 -33
- package/dist/ai/source/BbCalendar.md +17 -16
- package/dist/ai/source/BbCheckbox.md +3 -2
- package/dist/ai/source/BbCheckboxGroup.md +11 -4
- package/dist/ai/source/BbColorInput.md +10 -9
- package/dist/ai/source/BbConfirm.md +1 -1
- package/dist/ai/source/BbConfirmPortal.md +1 -1
- package/dist/ai/source/BbDatePicker.md +2 -2
- package/dist/ai/source/BbDatePickerInput.md +47 -20
- package/dist/ai/source/BbDialog.md +5 -5
- package/dist/ai/source/BbDropdown.md +230 -158
- package/dist/ai/source/BbDropdownButton.md +19 -12
- package/dist/ai/source/BbDropdownGroup.md +126 -93
- package/dist/ai/source/BbForm.md +25 -1
- package/dist/ai/source/BbIndicator.md +4 -0
- package/dist/ai/source/BbNumberInput.md +855 -19
- package/dist/ai/source/BbOffCanvas.md +27 -11
- package/dist/ai/source/BbPagination.md +3 -3
- package/dist/ai/source/BbPopover.md +152 -8
- package/dist/ai/source/BbPopoverPortal.md +11 -0
- package/dist/ai/source/BbProgress.md +82 -18
- package/dist/ai/source/BbRadioGroup.md +12 -5
- package/dist/ai/source/BbRating.md +11 -9
- package/dist/ai/source/BbSelect.md +16 -10
- package/dist/ai/source/BbSelectPopover.md +29 -23
- package/dist/ai/source/BbSlider.md +12 -6
- package/dist/ai/source/BbSwitch.md +3 -2
- package/dist/ai/source/BbSwitchGroup.md +5 -2
- package/dist/ai/source/BbTable.md +102 -18
- package/dist/ai/source/BbTabs.md +27 -23
- package/dist/ai/source/BbTabsList.md +26 -22
- package/dist/ai/source/BbTabsPanels.md +26 -22
- package/dist/ai/source/BbTabsRoot.md +25 -21
- package/dist/ai/source/BbTag.md +10 -9
- package/dist/ai/source/BbTextInput.md +5 -4
- package/dist/ai/source/BbTextarea.md +6 -5
- package/dist/ai/source/BbTimePicker.md +1 -1
- package/dist/ai/source/BbTimePickerInput.md +46 -9
- package/dist/ai/source/BbToast.md +10 -7
- package/dist/ai/source/BbToastPortal.md +10 -7
- package/dist/ai/source/BbTooltip.md +54 -8
- package/dist/ai/source/BbTree.md +21 -3
- package/dist/ai/source/CommonField.md +6 -4
- package/dist/ai/source/CommonFieldInput.md +15 -10
- package/dist/ai/source/CommonPopover.md +6 -0
- package/dist/ai/source/CommonTimeSelector.md +5 -4
- package/dist/components/BbBadge/BbBadgeButton.vue_vue_type_script_setup_true_lang.js +10 -8
- package/dist/components/BbBaseButton/BbBaseButton.vue_vue_type_script_setup_true_lang.js +8 -8
- package/dist/components/BbBreadcrumbs/BbBreadcrumbs.vue_vue_type_script_setup_true_lang.js +45 -45
- package/dist/components/BbBreadcrumbs/types.d.ts +25 -17
- package/dist/components/BbButton/BbButton.vue_vue_type_script_setup_true_lang.js +84 -71
- package/dist/components/BbButton/toggleRoving.d.ts +6 -0
- package/dist/components/BbButton/toggleRoving.js +45 -0
- package/dist/components/BbButton/types.d.ts +4 -1
- package/dist/components/BbCalendar/BbCalendar.vue_vue_type_script_setup_true_lang.js +178 -178
- package/dist/components/BbCalendar/CalendarMonthPanel.vue_vue_type_script_setup_true_lang.js +15 -15
- package/dist/components/BbCalendar/CalendarYearPanel.vue_vue_type_script_setup_true_lang.js +28 -28
- package/dist/components/BbCalendar/useCalendarGrid.js +141 -139
- package/dist/components/BbCalendar/useDayjsLocale.d.ts +38 -15
- package/dist/components/BbCalendar/useDayjsLocale.js +31 -30
- package/dist/components/BbCheckbox/BbCheckbox.vue_vue_type_script_setup_true_lang.js +48 -48
- package/dist/components/BbCheckboxGroup/BbCheckboxGroup.vue_vue_type_script_setup_true_lang.js +81 -80
- package/dist/components/BbCheckboxGroup/types.d.ts +6 -2
- package/dist/components/BbColorInput/BbColorInput.vue_vue_type_script_setup_true_lang.js +69 -69
- package/dist/components/BbDatePickerInput/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +363 -349
- package/dist/components/BbDropdown/AdaptiveDropdown.vue_vue_type_script_setup_true_lang.js +91 -86
- package/dist/components/BbDropdown/BbDropdown.vue_vue_type_script_setup_true_lang.js +298 -289
- package/dist/components/BbDropdown/BbDropdownList.vue_vue_type_script_setup_true_lang.js +322 -356
- package/dist/components/BbDropdown/DropdownPipelineResolver.vue_vue_type_script_setup_true_lang.js +17 -15
- package/dist/components/BbDropdown/DropdownRow.vue.d.ts +40 -0
- package/dist/components/BbDropdown/DropdownRow.vue.js +5 -0
- package/dist/components/BbDropdown/DropdownRow.vue_vue_type_script_setup_true_lang.js +60 -0
- package/dist/components/BbDropdown/normalizeGroups.d.ts +8 -2
- package/dist/components/BbDropdown/normalizeGroups.js +60 -46
- package/dist/components/BbDropdown/types.d.ts +119 -88
- package/dist/components/BbDropdownButton/BbDropdownButton.vue_vue_type_script_setup_true_lang.js +11 -2
- package/dist/components/BbDropdownButton/types.d.ts +2 -2
- package/dist/components/BbForm/BbForm.vue.d.ts +9 -0
- package/dist/components/BbForm/BbForm.vue_vue_type_script_setup_true_lang.js +114 -105
- package/dist/components/BbForm/BbFormCustomField.js +1 -1
- package/dist/components/BbForm/bindFormField.js +2 -1
- package/dist/components/BbForm/formFields.d.ts +5 -0
- package/dist/components/BbNumberInput/BbNumberInput.vue.d.ts +0 -1
- package/dist/components/BbNumberInput/BbNumberInput.vue_vue_type_script_setup_true_lang.js +452 -125
- package/dist/components/BbNumberInput/numberDisplay.d.ts +256 -0
- package/dist/components/BbNumberInput/numberDisplay.js +499 -0
- package/dist/components/BbNumberInput/types.d.ts +54 -1
- package/dist/components/BbNumberInput/warroom/corpus.d.ts +58 -0
- package/dist/components/BbNumberInput/warroom/currency-verify.rows.d.ts +28 -0
- package/dist/components/BbNumberInput/warroom/currency.rows.d.ts +2 -0
- package/dist/components/BbNumberInput/warroom/harness.d.ts +217 -0
- package/dist/components/BbNumberInput/warroom/oracle.d.ts +150 -0
- package/dist/components/BbPagination/BbPagination.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/BbPopover/BbPopover.vue.d.ts +1 -0
- package/dist/components/BbPopover/BbPopover.vue_vue_type_script_setup_true_lang.js +207 -164
- package/dist/components/BbPopover/types.d.ts +11 -0
- package/dist/components/BbProgress/BbProgress.vue_vue_type_script_setup_true_lang.js +15 -7
- package/dist/components/BbProgress/types.d.ts +23 -7
- package/dist/components/BbProgress/types.js +1 -1
- package/dist/components/BbRadioGroup/BbRadioGroup.vue_vue_type_script_setup_true_lang.js +102 -101
- package/dist/components/BbRadioGroup/types.d.ts +6 -2
- package/dist/components/BbRating/BbRating.vue_vue_type_script_setup_true_lang.js +63 -63
- package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +156 -154
- package/dist/components/BbSelect/types.d.ts +6 -2
- package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/components/BbSelectPopover/types.d.ts +6 -2
- package/dist/components/BbSlider/BbSlider.vue_vue_type_script_setup_true_lang.js +153 -153
- package/dist/components/BbSwitch/BbSwitch.vue_vue_type_script_setup_true_lang.js +62 -62
- package/dist/components/BbSwitchGroup/BbSwitchGroup.vue_vue_type_script_setup_true_lang.js +131 -130
- package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +711 -676
- package/dist/components/BbTabs/BbTabs.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/BbTabs/BbTabsList.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/BbTabs/types.d.ts +25 -21
- package/dist/components/BbTag/BbTag.vue_vue_type_script_setup_true_lang.js +76 -76
- package/dist/components/BbTextInput/BbTextInput.vue_vue_type_script_setup_true_lang.js +58 -58
- package/dist/components/BbTextarea/BbTextarea.vue_vue_type_script_setup_true_lang.js +82 -82
- package/dist/components/BbTimePickerInput/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +246 -236
- package/dist/components/BbTooltip/BbTooltip.vue_vue_type_script_setup_true_lang.js +102 -97
- package/dist/components/BbTooltip/tooltipWarmup.d.ts +23 -0
- package/dist/components/BbTooltip/tooltipWarmup.js +7 -0
- package/dist/components/BbTooltip/types.d.ts +7 -2
- package/dist/components/BbTree/BbTree.vue_vue_type_script_setup_true_lang.js +29 -21
- package/dist/components/BbTree/BbTreeLevel.vue_vue_type_script_setup_true_lang.js +10 -7
- package/dist/components/CommonFieldInput/CommonFieldInput.vue_vue_type_script_setup_true_lang.js +37 -36
- package/dist/components/CommonTimeSelector/CommonTimeSelector.vue_vue_type_script_setup_true_lang.js +9 -9
- package/dist/composables/formSubmitLock.d.ts +6 -0
- package/dist/composables/formSubmitLock.js +4 -0
- package/dist/composables/useBaseOptions.d.ts +7 -1
- package/dist/composables/useBaseOptions.js +32 -32
- package/dist/composables/useBbDropdownContext.d.ts +8 -8
- package/dist/composables/useBbFormField.d.ts +9 -0
- package/dist/composables/useBbFormField.js +5 -3
- package/dist/composables/useBbTabsContext.d.ts +10 -10
- package/dist/composables/useBbTabsContext.js +18 -18
- package/dist/composables/useFormBinding.d.ts +11 -0
- package/dist/composables/useFormBinding.js +15 -13
- package/dist/composables/useItemText.d.ts +5 -1
- package/dist/composables/useItemText.js +8 -3
- package/dist/composables/useItemValue.d.ts +5 -1
- package/dist/composables/useItemValue.js +8 -3
- package/dist/composables/useLocale.js +10 -9
- package/dist/deprecation/ai-deprecations.json.d.ts +130 -0
- package/dist/deprecation/ai-deprecations.json.js +1 -1
- package/dist/deprecation/removedProps.js +1 -1
- package/dist/directives/bbDropdown.js +1 -1
- package/dist/i18n/index.d.ts +7 -12
- package/dist/i18n/locales/cs.json +11 -14
- package/dist/i18n/locales/da.json +13 -16
- package/dist/i18n/locales/de-CH.json +137 -0
- package/dist/i18n/locales/de.json +14 -17
- package/dist/i18n/locales/el.json +10 -13
- package/dist/i18n/locales/en-GB.json +137 -0
- package/dist/i18n/locales/en.json +8 -11
- package/dist/i18n/locales/es-MX.json +137 -0
- package/dist/i18n/locales/es.json +16 -19
- package/dist/i18n/locales/fi.json +8 -11
- package/dist/i18n/locales/fr.json +23 -26
- package/dist/i18n/locales/hu.json +8 -11
- package/dist/i18n/locales/it.json +12 -15
- package/dist/i18n/locales/ja.json +13 -16
- package/dist/i18n/locales/ko.json +10 -13
- package/dist/i18n/locales/nb.json +13 -16
- package/dist/i18n/locales/nl.json +21 -24
- package/dist/i18n/locales/pl.json +10 -13
- package/dist/i18n/locales/{pt.json → pt-BR.json} +19 -22
- package/dist/i18n/locales/pt-PT.json +137 -0
- package/dist/i18n/locales/ro.json +22 -25
- package/dist/i18n/locales/ru.json +11 -14
- package/dist/i18n/locales/sv.json +16 -19
- package/dist/i18n/locales/tr.json +14 -17
- package/dist/i18n/locales/uk.json +11 -14
- package/dist/i18n/locales/{zh-cn.json → zh-CN.json} +10 -13
- package/dist/i18n/locales/zh-HK.json +137 -0
- package/dist/i18n/locales/zh-TW.json +137 -0
- package/dist/i18n/regionHints.d.ts +16 -0
- package/dist/i18n/regionHints.js +49 -0
- package/dist/i18n/regions.d.ts +286 -0
- package/dist/i18n/regions.js +265 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -4
- package/dist/llms-full.txt +1785 -1637
- package/dist/llms-medium.txt +74 -46
- package/dist/llms.txt +7 -7
- package/dist/locale-blueprint.json +16 -13
- package/dist/styles.css +2 -2
- package/dist/types/ptComponentMap.d.ts +1 -1
- package/dist/utilities/functions/slotKey.d.ts +2 -2
- package/dist/utils/versionCheck.js +1 -1
- package/dist/vite-plugin.d.ts +22 -19
- package/dist/vite.js +309 -297
- package/llms.txt +7 -7
- package/package.json +5 -3
- package/scripts/lib/agent-manifest.mjs +2 -1
- package/scripts/lib/eslint-disable.mjs +12 -4
- package/scripts/lib/eslint-plugin.d.ts +5 -1
- package/scripts/lib/eslint-plugin.mjs +187 -6
- package/scripts/lib/helper-canon.mjs +176 -0
- package/scripts/lib/helpers-add.mjs +1303 -0
- package/scripts/lib/local-components.mjs +33 -4
- package/scripts/lib/locale-check.mjs +165 -0
- package/scripts/lib/redundant-item-accessor.mjs +398 -0
- package/scripts/lib/renamed-item-field.mjs +343 -0
- package/scripts/lib/slot-key.mjs +2 -2
- package/scripts/lib/slot-renames.mjs +1 -1
- package/scripts/lib/validate-bb-markup.mjs +123 -56
- package/dist/i18n/index.js +0 -27
|
@@ -506,7 +506,7 @@ export type BbAlertSlots = {
|
|
|
506
506
|
letter-spacing: -0.01em;
|
|
507
507
|
line-height: var(--title-lh);
|
|
508
508
|
margin-bottom: 2px;
|
|
509
|
-
padding-
|
|
509
|
+
padding-inline-end: calc(var(--close-size) + var(--gap));
|
|
510
510
|
}
|
|
511
511
|
|
|
512
512
|
.bb-alert__text {
|
|
@@ -526,9 +526,9 @@ export type BbAlertSlots = {
|
|
|
526
526
|
);
|
|
527
527
|
--right-p: var(--top-p); /* same inset on the right edge */
|
|
528
528
|
color: var(--fg-muted);
|
|
529
|
+
inset-inline-end: var(--right-p);
|
|
529
530
|
padding: 2px;
|
|
530
531
|
position: absolute;
|
|
531
|
-
right: var(--right-p);
|
|
532
532
|
top: var(--top-p);
|
|
533
533
|
.bb-icon {
|
|
534
534
|
--size: var(--close-size);
|
|
@@ -569,8 +569,8 @@ export type BbAlertSlots = {
|
|
|
569
569
|
--hit: 44px;
|
|
570
570
|
content: '';
|
|
571
571
|
height: var(--hit);
|
|
572
|
+
inset-inline-end: calc(-1 * var(--right-p));
|
|
572
573
|
position: absolute;
|
|
573
|
-
right: calc(-1 * var(--right-p));
|
|
574
574
|
top: calc(-1 * var(--top-p));
|
|
575
575
|
width: var(--hit);
|
|
576
576
|
}
|
|
@@ -632,7 +632,7 @@ export type BbBadgeButtonSlots = {
|
|
|
632
632
|
&:has(> .bb-badge__trailing) {
|
|
633
633
|
.bb-badge__body {
|
|
634
634
|
border-radius: var(--r) 0 0 var(--r);
|
|
635
|
-
padding-
|
|
635
|
+
padding-inline-end: 0;
|
|
636
636
|
}
|
|
637
637
|
}
|
|
638
638
|
|
|
@@ -659,7 +659,7 @@ export type BbBadgeButtonSlots = {
|
|
|
659
659
|
/* Overlap the (hidden) clear button onto the append icon so they share the
|
|
660
660
|
trailing slot and cross-fade in place on hover/focus. */
|
|
661
661
|
&:has(+ .bb-badge__clear) {
|
|
662
|
-
margin-
|
|
662
|
+
margin-inline-end: calc(
|
|
663
663
|
(
|
|
664
664
|
var(--gap) + (var(--clear-size) - var(--icon-size)) / 2 +
|
|
665
665
|
var(--icon-size)
|
|
@@ -88,8 +88,9 @@ const bindings = computed(() => {
|
|
|
88
88
|
.concat(onClick ?? [])
|
|
89
89
|
.filter((fn): fn is ClickListener => typeof fn === 'function');
|
|
90
90
|
return mergeProps(rest, props as Record<string, unknown>, {
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
// Only while loading: an `undefined` here would erase the consumer's own
|
|
92
|
+
// `aria-disabled` / `tabindex`, which `rest` carries.
|
|
93
|
+
...(loading.value ? { 'aria-disabled': true, tabindex: -1 } : {}),
|
|
93
94
|
onClick: (event: MouseEvent) => {
|
|
94
95
|
if (loading.value) {
|
|
95
96
|
// A link or submit body must not act either.
|
|
@@ -506,7 +507,7 @@ export type BbBadgeButtonSlots = {
|
|
|
506
507
|
&:has(> .bb-badge__trailing) {
|
|
507
508
|
.bb-badge__body {
|
|
508
509
|
border-radius: var(--r) 0 0 var(--r);
|
|
509
|
-
padding-
|
|
510
|
+
padding-inline-end: 0;
|
|
510
511
|
}
|
|
511
512
|
}
|
|
512
513
|
|
|
@@ -533,7 +534,7 @@ export type BbBadgeButtonSlots = {
|
|
|
533
534
|
/* Overlap the (hidden) clear button onto the append icon so they share the
|
|
534
535
|
trailing slot and cross-fade in place on hover/focus. */
|
|
535
536
|
&:has(+ .bb-badge__clear) {
|
|
536
|
-
margin-
|
|
537
|
+
margin-inline-end: calc(
|
|
537
538
|
(
|
|
538
539
|
var(--gap) + (var(--clear-size) - var(--icon-size)) / 2 +
|
|
539
540
|
var(--icon-size)
|
|
@@ -883,7 +883,7 @@ export const BB_BASE_BUTTON_PROP_KEYS = Object.keys(baseButtonPropMap) as Array<
|
|
|
883
883
|
cursor: pointer;
|
|
884
884
|
outline: 2px solid transparent;
|
|
885
885
|
outline-offset: 2px;
|
|
886
|
-
text-align:
|
|
886
|
+
text-align: start;
|
|
887
887
|
transition-duration: var(--bb-transition-fast);
|
|
888
888
|
transition-property:
|
|
889
889
|
color, background-color, border-color, text-decoration-color, box-shadow;
|
|
@@ -205,6 +205,7 @@ export type BbBaseRadioIconProps = {
|
|
|
205
205
|
/* Inner disc inset must track the glyph stroke, not a leftover 2px,
|
|
206
206
|
or a 3px plate theme clips the checked dot. */
|
|
207
207
|
height: calc(100% - 2 * var(--bb-border-w-sm) - var(--space));
|
|
208
|
+
/* stylelint-disable-next-line property-disallowed-list -- geometry: centred with a physical translate */
|
|
208
209
|
left: 50%;
|
|
209
210
|
position: absolute;
|
|
210
211
|
top: 50%;
|
|
@@ -234,6 +234,7 @@ export type BbBaseSwitchIconProps = {
|
|
|
234
234
|
border-radius: calc(var(--r) * 0.8);
|
|
235
235
|
display: inline-block;
|
|
236
236
|
height: var(--thumb);
|
|
237
|
+
/* stylelint-disable-next-line property-disallowed-list -- geometry: the thumb travels by a physical translate */
|
|
237
238
|
left: var(--inset);
|
|
238
239
|
position: absolute;
|
|
239
240
|
top: var(--inset);
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
<!-- Visible breadcrumb items (index >= overflowCount) -->
|
|
81
81
|
<template
|
|
82
82
|
v-for="(item, index) in items"
|
|
83
|
-
:key="item.
|
|
83
|
+
:key="item.value ?? `:keyless-${index}`"
|
|
84
84
|
>
|
|
85
85
|
<template v-if="index >= overflowCount">
|
|
86
86
|
<li
|
|
@@ -109,13 +109,13 @@
|
|
|
109
109
|
:disabled="item.disabled || disabled"
|
|
110
110
|
:tag="isCurrent(item, index) ? 'span' : undefined"
|
|
111
111
|
>
|
|
112
|
-
<!-- prepend: <
|
|
112
|
+
<!-- prepend: <value>:prepend | item:prepend | inline prepend:icon -->
|
|
113
113
|
<slot
|
|
114
114
|
:disabled="!!(item.disabled || disabled)"
|
|
115
115
|
:index="index"
|
|
116
116
|
:item="item"
|
|
117
|
+
:label="item.label"
|
|
117
118
|
:name="edgeSlot(item, 'prepend').name"
|
|
118
|
-
:text="item.text"
|
|
119
119
|
/>
|
|
120
120
|
<BbIcon
|
|
121
121
|
v-if="
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
class="bb-breadcrumbs__text"
|
|
136
136
|
:title="
|
|
137
137
|
items.length > 1 && overflowCount === items.length - 1
|
|
138
|
-
? item.
|
|
138
|
+
? item.label
|
|
139
139
|
: undefined
|
|
140
140
|
"
|
|
141
141
|
v-bind="
|
|
@@ -149,18 +149,18 @@
|
|
|
149
149
|
:disabled="!!(item.disabled || disabled)"
|
|
150
150
|
:index="index"
|
|
151
151
|
:item="item"
|
|
152
|
+
:label="item.label"
|
|
152
153
|
:name="itemSlotBase(item)"
|
|
153
|
-
|
|
154
|
-
>{{ item.text }}</slot
|
|
154
|
+
>{{ item.label }}</slot
|
|
155
155
|
>
|
|
156
156
|
</span>
|
|
157
|
-
<!-- append: <
|
|
157
|
+
<!-- append: <value>:append | item:append | inline append:icon -->
|
|
158
158
|
<slot
|
|
159
159
|
:disabled="!!(item.disabled || disabled)"
|
|
160
160
|
:index="index"
|
|
161
161
|
:item="item"
|
|
162
|
+
:label="item.label"
|
|
162
163
|
:name="edgeSlot(item, 'append').name"
|
|
163
|
-
:text="item.text"
|
|
164
164
|
/>
|
|
165
165
|
<BbIcon
|
|
166
166
|
v-if="!edgeSlot(item, 'append').exists && item['append:icon']"
|
|
@@ -233,12 +233,12 @@ const props = withDefaults(defineProps<BbBreadcrumbsProps>(), {
|
|
|
233
233
|
|
|
234
234
|
defineSlots<BbBreadcrumbsSlots>();
|
|
235
235
|
|
|
236
|
-
// Per-crumb slots are named after each item's `
|
|
236
|
+
// Per-crumb slots are named after each item's `value` through `slotKey`, so a
|
|
237
237
|
// removed prop or a slot spelled the pre-reset way is reported, as on BbTable
|
|
238
238
|
// / BbTabs (Q56.28).
|
|
239
239
|
if (process.env.NODE_ENV !== 'production')
|
|
240
240
|
warnRemovedAttrs('BbBreadcrumbs', removedPropsFor('BbBreadcrumbs'), {
|
|
241
|
-
slotKeys: () => props.items.map((item) => item.
|
|
241
|
+
slotKeys: () => props.items.map((item) => item.value),
|
|
242
242
|
});
|
|
243
243
|
/**
|
|
244
244
|
* Passthrough (plans/passthrough/BbBreadcrumbs.md). `item` is resolved per crumb (`active` = the current page: the last crumb, when it has no target).
|
|
@@ -291,14 +291,16 @@ const STRUCTURAL_SLOTS = new Set([
|
|
|
291
291
|
]);
|
|
292
292
|
|
|
293
293
|
/**
|
|
294
|
-
* Normalized slot base for an item (`slotKey(
|
|
295
|
-
* component. A crumb without a `
|
|
294
|
+
* Normalized slot base for an item (`slotKey(value)`), shared with every family
|
|
295
|
+
* component. A crumb without a `value` gets `:keyless` — a name `slotKey` never
|
|
296
296
|
* produces and no template can write — so it has no slot of its own and falls
|
|
297
297
|
* back to the generic ones (Q53.16 / owner doctrine 2026-09-24: slot names are
|
|
298
|
-
* written, never derived from the
|
|
298
|
+
* written, never derived from the label).
|
|
299
299
|
*/
|
|
300
300
|
const itemSlotBase = (item: Item) =>
|
|
301
|
-
item.
|
|
301
|
+
item.value == null || item.value === ''
|
|
302
|
+
? ':keyless'
|
|
303
|
+
: slotKey(String(item.value));
|
|
302
304
|
|
|
303
305
|
/**
|
|
304
306
|
* Item props forwarded to the inner `BbBaseButton`, minus the edge-icon fields
|
|
@@ -324,14 +326,20 @@ const isCurrent = (item: Item, index: number) =>
|
|
|
324
326
|
!item.onClick;
|
|
325
327
|
|
|
326
328
|
const buttonProps = (item: Item, index: number) => {
|
|
327
|
-
const {
|
|
329
|
+
const {
|
|
330
|
+
['prepend:icon']: _p,
|
|
331
|
+
['append:icon']: _a,
|
|
332
|
+
value: _value,
|
|
333
|
+
label: _label,
|
|
334
|
+
...rest
|
|
335
|
+
} = item;
|
|
328
336
|
return isCurrent(item, index)
|
|
329
337
|
? { ...rest, 'aria-current': 'page' as const }
|
|
330
338
|
: rest;
|
|
331
339
|
};
|
|
332
340
|
|
|
333
341
|
/**
|
|
334
|
-
* Resolves an edge region's precedence — `<
|
|
342
|
+
* Resolves an edge region's precedence — `<value>:suffix` (per-item) →
|
|
335
343
|
* `item:suffix` (generic) → inline `prepend:icon`/`append:icon`. Returns the
|
|
336
344
|
* winning slot `name` plus whether a slot actually `exists`; when it doesn't,
|
|
337
345
|
* `name` is the (absent) per-key name so the outlet renders nothing and the
|
|
@@ -369,7 +377,7 @@ const resolvedEllipsisAriaLabel = computed(
|
|
|
369
377
|
* Estimates one breadcrumb item width using weighted character categories.
|
|
370
378
|
*/
|
|
371
379
|
const estimateItemWidth = (item: Item) => {
|
|
372
|
-
const label = item.
|
|
380
|
+
const label = item.label ?? '';
|
|
373
381
|
return estimateBreadcrumbItemWidth(label, {
|
|
374
382
|
estimationBias: resolvedEstimationBias.value,
|
|
375
383
|
fontWidth: FONT_WIDTH,
|
|
@@ -492,7 +500,9 @@ const recompute = (availableWidth: number) => {
|
|
|
492
500
|
// Observe this component width so overflow is based on real allocated space.
|
|
493
501
|
const breadcrumbsEl = computed(() => navRef.value);
|
|
494
502
|
const itemsWidthSignature = computed(() =>
|
|
495
|
-
props.items
|
|
503
|
+
props.items
|
|
504
|
+
.map((item) => `${String(item.value)}::${item.label ?? ''}`)
|
|
505
|
+
.join('|')
|
|
496
506
|
);
|
|
497
507
|
// --- Recompute scheduling + runaway-loop guard ------------------------------
|
|
498
508
|
// The ResizeObserver watches this element, but a recompute can flip
|
|
@@ -641,15 +651,15 @@ onBeforeUnmount(() => {
|
|
|
641
651
|
}
|
|
642
652
|
});
|
|
643
653
|
|
|
644
|
-
//
|
|
645
|
-
//
|
|
646
|
-
// are forwarded below, so an overflowed
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
654
|
+
// Hidden crumbs ARE dropdown rows: the same `{ label, value }` shape and the
|
|
655
|
+
// same `prepend:icon` / `append:icon`, so they pass straight through, and the
|
|
656
|
+
// per-crumb slots are forwarded below, so an overflowed crumb renders the same
|
|
657
|
+
// content. A crumb without a label is a row without one.
|
|
658
|
+
const overflowDropdownItems = computed<DropdownItem[]>(() =>
|
|
659
|
+
props.items
|
|
660
|
+
.slice(0, overflowCount.value)
|
|
661
|
+
.map((item) => ({ ...item, label: item.label ?? '' }) as DropdownItem)
|
|
662
|
+
);
|
|
653
663
|
</script>
|
|
654
664
|
|
|
655
665
|
<style lang="postcss">
|
|
@@ -664,27 +674,38 @@ import type { BbBaseButtonProps } from '../BbBaseButton/types';
|
|
|
664
674
|
import type { PtMap, PtValue } from '@/types/passthrough';
|
|
665
675
|
import type { IconType } from '@/types/Icon';
|
|
666
676
|
|
|
667
|
-
export type Item = Omit<
|
|
677
|
+
export type Item = Omit<
|
|
678
|
+
BbBaseButtonProps,
|
|
679
|
+
'block' | 'tag' | 'type' | 'text'
|
|
680
|
+
> & {
|
|
668
681
|
/**
|
|
669
682
|
* Click handler of the button.
|
|
670
683
|
*/
|
|
671
684
|
onClick?: (event: MouseEvent) => void | Promise<void>;
|
|
685
|
+
/** The crumb's text. */
|
|
686
|
+
label?: string;
|
|
672
687
|
/**
|
|
673
|
-
*
|
|
674
|
-
*
|
|
675
|
-
* slot of its own: a
|
|
676
|
-
* (Q53.17 — slot names are written, never derived
|
|
688
|
+
* Identifies the crumb, and names its own slots (`slotKey(value)`,
|
|
689
|
+
* kebab-case: `#<value>`, `#<value>:prepend`, `#<value>:append`). Optional
|
|
690
|
+
* unless the crumb has a slot of its own: a crumb without one renders with
|
|
691
|
+
* the generic slots only (Q53.17 — slot names are written, never derived
|
|
692
|
+
* from the label). A crumb hidden in the overflow menu is a dropdown row with
|
|
693
|
+
* the same `label` and `value`.
|
|
677
694
|
*/
|
|
678
|
-
|
|
695
|
+
value?: string;
|
|
696
|
+
/** Crumbs have no `key` (that is `value`). Guards against the old shape. */
|
|
697
|
+
key?: never;
|
|
698
|
+
/** Crumbs have no `text` (that is `label`). Guards against the old shape. */
|
|
699
|
+
text?: never;
|
|
679
700
|
/**
|
|
680
701
|
* Icon rendered before the breadcrumb label, in the leading edge region
|
|
681
702
|
* (outside the link, so it never inherits the link's text styling). Acts as
|
|
682
|
-
* the fallback when no `<
|
|
703
|
+
* the fallback when no `<value>:prepend` / `item:prepend` slot is provided.
|
|
683
704
|
*/
|
|
684
705
|
'prepend:icon'?: IconType;
|
|
685
706
|
/**
|
|
686
707
|
* Icon rendered after the breadcrumb label, in the trailing edge region.
|
|
687
|
-
* Fallback when no `<
|
|
708
|
+
* Fallback when no `<value>:append` / `item:append` slot is provided.
|
|
688
709
|
*/
|
|
689
710
|
'append:icon'?: IconType;
|
|
690
711
|
};
|
|
@@ -786,8 +807,8 @@ export type BbBreadcrumbsItemSlotProps = {
|
|
|
786
807
|
index: number;
|
|
787
808
|
/** The raw item object from the `items` prop. */
|
|
788
809
|
item: Item;
|
|
789
|
-
/** The
|
|
790
|
-
|
|
810
|
+
/** The crumb's label. */
|
|
811
|
+
label?: string;
|
|
791
812
|
};
|
|
792
813
|
|
|
793
814
|
/** Props exposed by the `ellipsis` slot. */
|
|
@@ -806,9 +827,9 @@ export type BbBreadcrumbsEllipsisSlotProps = {
|
|
|
806
827
|
};
|
|
807
828
|
|
|
808
829
|
/**
|
|
809
|
-
* @dynamicSlot `<
|
|
810
|
-
* @dynamicSlot `<
|
|
811
|
-
* @dynamicSlot `<
|
|
830
|
+
* @dynamicSlot `<value>` {BbBreadcrumbsItemSlotProps} - One crumb's label, by its `value` through `slotKey`; falls back to `item.label`. A crumb folded into the overflow menu follows BbDropdown's slot rules instead (the same `#<value>` names).
|
|
831
|
+
* @dynamicSlot `<value>:prepend` {BbBreadcrumbsItemSlotProps} - The glyph before one crumb's label; beats `item:prepend`, which beats its `prepend:icon`.
|
|
832
|
+
* @dynamicSlot `<value>:append` {BbBreadcrumbsItemSlotProps} - The glyph after one crumb's label; beats `item:append`, which beats its `append:icon`.
|
|
812
833
|
*/
|
|
813
834
|
export type BbBreadcrumbsSlots = {
|
|
814
835
|
/**
|
|
@@ -821,14 +842,14 @@ export type BbBreadcrumbsSlots = {
|
|
|
821
842
|
append?: (props: BbBreadcrumbsEdgeSlotProps) => any;
|
|
822
843
|
/**
|
|
823
844
|
* Content rendered before **every** breadcrumb item's link/button, in the
|
|
824
|
-
* leading edge region. Generic fallback: a per-item `<
|
|
845
|
+
* leading edge region. Generic fallback: a per-item `<value>:prepend` slot
|
|
825
846
|
* takes precedence, and the item's `prepend:icon` is used when neither slot
|
|
826
847
|
* is present.
|
|
827
848
|
*/
|
|
828
849
|
'item:prepend'?: (props: BbBreadcrumbsItemSlotProps) => any;
|
|
829
850
|
/**
|
|
830
851
|
* Content rendered after **every** breadcrumb item's link/button. Generic
|
|
831
|
-
* fallback below a per-item `<
|
|
852
|
+
* fallback below a per-item `<value>:append` slot and above the item's
|
|
832
853
|
* `append:icon`.
|
|
833
854
|
*/
|
|
834
855
|
'item:append'?: (props: BbBreadcrumbsItemSlotProps) => any;
|
|
@@ -69,7 +69,8 @@
|
|
|
69
69
|
<script setup lang="ts">
|
|
70
70
|
import { BbBaseButton, BbSpinner } from '@/index';
|
|
71
71
|
import BbIcon from '../BbIcon/BbIcon.vue';
|
|
72
|
-
import { computed, mergeProps, ref, useAttrs, watchEffect } from 'vue';
|
|
72
|
+
import { computed, inject, mergeProps, ref, useAttrs, watchEffect } from 'vue';
|
|
73
|
+
import { BB_FORM_SUBMIT_LOCK } from '@/composables/formSubmitLock';
|
|
73
74
|
import { pickBy } from '@/utilities/functions/pickBy';
|
|
74
75
|
import { noop } from '@/utilities/functions/noop';
|
|
75
76
|
import { useLocale } from '@/composables/useLocale';
|
|
@@ -81,6 +82,7 @@ import { extractDomContainer } from '@/utilities/functions/extractDomContainer';
|
|
|
81
82
|
import { isEqual } from '@/utilities/functions/isEqual';
|
|
82
83
|
import { usePassthrough } from '@/composables/usePassthrough';
|
|
83
84
|
import { BB_BUTTON_PT, type BbButtonProps, type BbButtonSlots } from './types';
|
|
85
|
+
import { useToggleRoving } from './toggleRoving';
|
|
84
86
|
import type { Sizes as SizeMap } from '@/types/SizeScale';
|
|
85
87
|
type Sizes = keyof SizeMap;
|
|
86
88
|
|
|
@@ -143,8 +145,16 @@ const forwardedAttrs = computed(() => {
|
|
|
143
145
|
|
|
144
146
|
const internalLoading = ref(0);
|
|
145
147
|
|
|
148
|
+
// Q60.17: a `type="submit"` button inside a BbForm spins while the form's
|
|
149
|
+
// save runs (unless the form sets `disable-submit-lock`). Other buttons in
|
|
150
|
+
// the form (Cancel, a row action) are untouched.
|
|
151
|
+
const formLock = inject(BB_FORM_SUBMIT_LOCK, null);
|
|
152
|
+
|
|
146
153
|
const loading = computed(
|
|
147
|
-
() =>
|
|
154
|
+
() =>
|
|
155
|
+
props.loading ||
|
|
156
|
+
(!!internalLoading.value && !props.disableAutoLoading) ||
|
|
157
|
+
(props.type === 'submit' && !!formLock?.locked())
|
|
148
158
|
);
|
|
149
159
|
|
|
150
160
|
/** Latches on the first load; gates the spinner's <Transition> — see the template. */
|
|
@@ -289,11 +299,35 @@ const softDisabled = computed(
|
|
|
289
299
|
() => loading.value && !props.interactiveWhileLoading
|
|
290
300
|
);
|
|
291
301
|
|
|
302
|
+
/**
|
|
303
|
+
* Adjacent `group` toggles are one Tab stop with arrow keys inside
|
|
304
|
+
* (Q44.25-001, see `toggleRoving.ts`). A consumer `tabindex` opts a button out.
|
|
305
|
+
*/
|
|
306
|
+
const roving = useToggleRoving(
|
|
307
|
+
buttonDom,
|
|
308
|
+
computed(() => !!props.group && isToggle.value && !('tabindex' in attrs)),
|
|
309
|
+
() => [isPressed.value, props.disabled, softDisabled.value]
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* The `tabindex` / `aria-disabled` we mean, or nothing. Written as `undefined`
|
|
314
|
+
* they used to reach `mergeProps` after the forwarded attrs and erase a
|
|
315
|
+
* consumer's own `tabindex` / `aria-disabled`: an explicit attr wins unless we
|
|
316
|
+
* mean one (loading takes the button out of the tab order either way).
|
|
317
|
+
*/
|
|
318
|
+
const managedFocus = computed(() => {
|
|
319
|
+
const tabindex = softDisabled.value ? -1 : roving.tabindex.value;
|
|
320
|
+
return {
|
|
321
|
+
...(softDisabled.value ? { 'aria-disabled': true } : {}),
|
|
322
|
+
...(tabindex === undefined ? {} : { tabindex }),
|
|
323
|
+
};
|
|
324
|
+
});
|
|
325
|
+
|
|
292
326
|
const rootBindings = computed(() =>
|
|
293
327
|
mergeProps(
|
|
294
328
|
propsToPass.value,
|
|
295
329
|
{
|
|
296
|
-
|
|
330
|
+
...managedFocus.value,
|
|
297
331
|
'aria-pressed': isToggle.value ? isPressed.value : undefined,
|
|
298
332
|
class: [
|
|
299
333
|
'bb-button',
|
|
@@ -308,8 +342,9 @@ const rootBindings = computed(() =>
|
|
|
308
342
|
},
|
|
309
343
|
],
|
|
310
344
|
disabled: props.disabled,
|
|
311
|
-
tabindex: softDisabled.value ? -1 : undefined,
|
|
312
345
|
onClick,
|
|
346
|
+
onFocusin: roving.onFocusin,
|
|
347
|
+
onKeydown: roving.onKeydown,
|
|
313
348
|
},
|
|
314
349
|
passthrough.root
|
|
315
350
|
)
|
|
@@ -463,7 +498,10 @@ export type BbButtonProps = {
|
|
|
463
498
|
exactActiveClass?: string;
|
|
464
499
|
|
|
465
500
|
/**
|
|
466
|
-
* Identifies the button as part of a button group
|
|
501
|
+
* Identifies the button as part of a button group: adjacent `group`
|
|
502
|
+
* buttons fuse into one segment (shared borders and radius). Adjacent
|
|
503
|
+
* `group` toggles (each with a `v-model`) are also one Tab stop, with
|
|
504
|
+
* ArrowLeft / ArrowRight / Home / End moving between them.
|
|
467
505
|
*/
|
|
468
506
|
group?: boolean;
|
|
469
507
|
|
|
@@ -885,15 +923,6 @@ export type BbButtonSlots = {
|
|
|
885
923
|
border-radius: var(--r);
|
|
886
924
|
border-style: solid;
|
|
887
925
|
border-width: var(--bw);
|
|
888
|
-
/* Resting lift, but only on a PLATE — primary, secondary, outline and
|
|
889
|
-
destructive opt in below. Ghost, link and `none` stay flat whatever the
|
|
890
|
-
theme asks for, because a lift on a transparent box reads as a bug.
|
|
891
|
-
|
|
892
|
-
The plates read `--elev-tier`, not `--bb-elev` directly, so the size
|
|
893
|
-
blocks can drop xs and sm to the small tier without handing a shadow to
|
|
894
|
-
the flat variants. */
|
|
895
|
-
--elev-tier: var(--bb-elev); /* the shadow a plate variant may take */
|
|
896
|
-
--elev: 0 0 0 0 transparent; /* the shadow painted; flat variants keep this */
|
|
897
926
|
box-shadow:
|
|
898
927
|
var(--elev),
|
|
899
928
|
0px 0px 0px 0px var(--ring-color);
|
|
@@ -905,14 +934,23 @@ export type BbButtonSlots = {
|
|
|
905
934
|
justify-content: center;
|
|
906
935
|
line-height: var(--fs);
|
|
907
936
|
min-height: var(--h);
|
|
908
|
-
padding-
|
|
909
|
-
padding-
|
|
937
|
+
padding-inline-end: var(--px);
|
|
938
|
+
padding-inline-start: var(--px);
|
|
910
939
|
transition-duration: var(--bb-transition-fast);
|
|
911
940
|
transition-property:
|
|
912
941
|
box-shadow, color, background-color, border-color, min-height, font-size,
|
|
913
942
|
padding-left;
|
|
914
943
|
transition-timing-function: var(--bb-ease);
|
|
915
944
|
vertical-align: top;
|
|
945
|
+
/* Resting lift, but only on a PLATE — primary, secondary, outline and
|
|
946
|
+
destructive opt in below. Ghost, link and `none` stay flat whatever the
|
|
947
|
+
theme asks for, because a lift on a transparent box reads as a bug.
|
|
948
|
+
|
|
949
|
+
The plates read `--elev-tier`, not `--bb-elev` directly, so the size
|
|
950
|
+
blocks can drop xs and sm to the small tier without handing a shadow to
|
|
951
|
+
the flat variants. */
|
|
952
|
+
--elev-tier: var(--bb-elev); /* the shadow a plate variant may take */
|
|
953
|
+
--elev: 0 0 0 0 transparent; /* the shadow painted; flat variants keep this */
|
|
916
954
|
|
|
917
955
|
&:hover:not(.bb-base-button--disabled) {
|
|
918
956
|
background-color: var(--bg-hover);
|
|
@@ -1012,7 +1050,7 @@ export type BbButtonSlots = {
|
|
|
1012
1050
|
rules above, which paint `border-color` on the button and would
|
|
1013
1051
|
otherwise take the left edge with them. */
|
|
1014
1052
|
& + .bb-button.bb-button--group {
|
|
1015
|
-
border-
|
|
1053
|
+
border-inline-start-color: color-mix(
|
|
1016
1054
|
in oklab,
|
|
1017
1055
|
var(--bb-primary) 60%,
|
|
1018
1056
|
var(--bb-border)
|
|
@@ -1030,7 +1068,7 @@ export type BbButtonSlots = {
|
|
|
1030
1068
|
--elev: var(--elev-tier);
|
|
1031
1069
|
|
|
1032
1070
|
& + .bb-button.bb-button--group {
|
|
1033
|
-
border-
|
|
1071
|
+
border-inline-start-color: var(--bb-secondary-pressed);
|
|
1034
1072
|
}
|
|
1035
1073
|
}
|
|
1036
1074
|
|
|
@@ -1100,19 +1138,19 @@ export type BbButtonSlots = {
|
|
|
1100
1138
|
|
|
1101
1139
|
&.bb-button--icon {
|
|
1102
1140
|
min-width: var(--h);
|
|
1103
|
-
padding-
|
|
1104
|
-
padding-
|
|
1141
|
+
padding-inline-end: 0;
|
|
1142
|
+
padding-inline-start: 0;
|
|
1105
1143
|
}
|
|
1106
1144
|
|
|
1107
1145
|
&:has(.bb-button__prepend-icon),
|
|
1108
1146
|
&.bb-button--loading:not(.bb-button--icon):not(
|
|
1109
1147
|
:has(.bb-button__append-icon)
|
|
1110
1148
|
) {
|
|
1111
|
-
padding-
|
|
1149
|
+
padding-inline-start: calc(var(--px) * 0.65);
|
|
1112
1150
|
}
|
|
1113
1151
|
|
|
1114
1152
|
&:has(.bb-button__append-icon) {
|
|
1115
|
-
padding-
|
|
1153
|
+
padding-inline-end: calc(var(--px) * 0.65);
|
|
1116
1154
|
}
|
|
1117
1155
|
|
|
1118
1156
|
&.bb-button--soft-disabled {
|
|
@@ -1133,7 +1171,7 @@ export type BbButtonSlots = {
|
|
|
1133
1171
|
|
|
1134
1172
|
/* No icon to hide behind: carve the spinner's slot out of the label. */
|
|
1135
1173
|
+ .bb-button__text {
|
|
1136
|
-
margin-
|
|
1174
|
+
margin-inline-start: calc(var(--gap) + var(--icon-size));
|
|
1137
1175
|
}
|
|
1138
1176
|
}
|
|
1139
1177
|
|
|
@@ -1145,21 +1183,21 @@ export type BbButtonSlots = {
|
|
|
1145
1183
|
}
|
|
1146
1184
|
|
|
1147
1185
|
.bb-spinner + .bb-button__text {
|
|
1148
|
-
margin-
|
|
1186
|
+
margin-inline-start: 0;
|
|
1149
1187
|
}
|
|
1150
1188
|
}
|
|
1151
1189
|
}
|
|
1152
1190
|
|
|
1153
1191
|
&.bb-button--group {
|
|
1154
1192
|
&:has(+ .bb-button--group) {
|
|
1155
|
-
border-
|
|
1156
|
-
border-
|
|
1157
|
-
border-
|
|
1193
|
+
border-end-end-radius: 0;
|
|
1194
|
+
border-inline-end-width: 0;
|
|
1195
|
+
border-start-end-radius: 0;
|
|
1158
1196
|
}
|
|
1159
1197
|
|
|
1160
1198
|
& + .bb-button--group {
|
|
1161
|
-
border-
|
|
1162
|
-
border-
|
|
1199
|
+
border-end-start-radius: 0;
|
|
1200
|
+
border-start-start-radius: 0;
|
|
1163
1201
|
}
|
|
1164
1202
|
}
|
|
1165
1203
|
|
|
@@ -1229,7 +1267,7 @@ export type BbButtonSlots = {
|
|
|
1229
1267
|
--elev-tier: var(--bb-elev);
|
|
1230
1268
|
}
|
|
1231
1269
|
.bb-button__text {
|
|
1232
|
-
margin-
|
|
1270
|
+
margin-inline-start: 0;
|
|
1233
1271
|
transition: margin-left var(--bb-transition-medium) var(--bb-ease);
|
|
1234
1272
|
|
|
1235
1273
|
/* Optical centering, as on BbBadge's label. Flex centers the LINE BOX,
|
|
@@ -1273,7 +1311,7 @@ export type BbButtonSlots = {
|
|
|
1273
1311
|
by an equal negative margin, so it lands exactly on top of the neighbour
|
|
1274
1312
|
it stands in for. The fade itself is the Vue <Transition> below. */
|
|
1275
1313
|
.bb-spinner {
|
|
1276
|
-
margin-
|
|
1314
|
+
margin-inline-end: calc((var(--gap) + var(--icon-size)) * -1);
|
|
1277
1315
|
}
|
|
1278
1316
|
|
|
1279
1317
|
/* <Transition name="bb-button-spinner"> endpoints; the duration comes from
|
|
@@ -1288,8 +1326,8 @@ export type BbButtonSlots = {
|
|
|
1288
1326
|
it overlays the append icon by the same zero-cost trick. */
|
|
1289
1327
|
&:has(.bb-button__append-icon):not(:has(.bb-button__prepend-icon)) {
|
|
1290
1328
|
.bb-spinner {
|
|
1291
|
-
margin-
|
|
1292
|
-
margin-
|
|
1329
|
+
margin-inline-end: 0;
|
|
1330
|
+
margin-inline-start: calc((var(--gap) + var(--icon-size)) * -1);
|
|
1293
1331
|
order: 1;
|
|
1294
1332
|
}
|
|
1295
1333
|
}
|