bitboss-ui 2.1.135 → 3.0.0-alpha.4
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/LICENSE +21 -0
- package/README.md +274 -24
- package/bin/bitboss-ui-mcp.mjs +662 -0
- package/bin/bitboss-ui.mjs +710 -0
- package/bin/bitboss-ui.node.test.mjs +113 -0
- package/dist/ai/BbAccordion.md +528 -113
- package/dist/ai/BbAlert.md +380 -197
- package/dist/ai/BbAsterisk.md +46 -0
- package/dist/ai/BbAvatar.md +458 -178
- package/dist/ai/BbBadge.md +697 -225
- package/dist/ai/BbBadgeButton.md +54 -0
- package/dist/ai/BbBaseButton.md +491 -0
- package/dist/ai/BbBaseCheckbox.md +49 -0
- package/dist/ai/BbBaseCheckboxGroup.md +64 -0
- package/dist/ai/BbBaseCheckboxIcon.md +176 -0
- package/dist/ai/BbBaseColorInput.md +64 -0
- package/dist/ai/BbBaseColorPalette.md +39 -0
- package/dist/ai/BbBaseDatePicker.md +42 -0
- package/dist/ai/BbBaseDatePickerInput.md +73 -0
- package/dist/ai/BbBaseInputContainer.md +48 -0
- package/dist/ai/BbBaseNumberInput.md +71 -0
- package/dist/ai/BbBaseRadio.md +46 -0
- package/dist/ai/BbBaseRadioGroup.md +64 -0
- package/dist/ai/BbBaseRadioIcon.md +191 -0
- package/dist/ai/BbBaseRating.md +51 -0
- package/dist/ai/BbBaseSelect.md +88 -0
- package/dist/ai/BbBaseSlider.md +56 -0
- package/dist/ai/BbBaseSwitch.md +49 -0
- package/dist/ai/BbBaseSwitchGroup.md +64 -0
- package/dist/ai/BbBaseSwitchIcon.md +186 -0
- package/dist/ai/BbBaseTag.md +68 -0
- package/dist/ai/BbBaseTextInput.md +75 -0
- package/dist/ai/BbBaseTextarea.md +62 -0
- package/dist/ai/BbBaseTimePickerInput.md +62 -0
- package/dist/ai/BbBreadcrumbs.md +553 -503
- package/dist/ai/BbButton.md +841 -636
- package/dist/ai/BbCheckbox.md +585 -254
- package/dist/ai/BbCheckboxGroup.md +573 -361
- package/dist/ai/BbCollapsible.md +425 -103
- package/dist/ai/BbColorInput.md +536 -323
- package/dist/ai/BbColorPalette.md +569 -330
- package/dist/ai/BbConfirm.md +659 -136
- package/dist/ai/BbConfirmPortal.md +28 -0
- package/dist/ai/BbDatePicker.md +244 -0
- package/dist/ai/BbDatePickerInput.md +720 -388
- package/dist/ai/BbDialog.md +778 -99
- package/dist/ai/BbDropdown.md +1072 -763
- package/dist/ai/BbDropdownButton.md +525 -614
- package/dist/ai/BbDropdownGroup.md +34 -0
- package/dist/ai/BbDropzone.md +1206 -436
- package/dist/ai/BbForm.md +239 -0
- package/dist/ai/BbIcon.md +382 -212
- package/dist/ai/BbIndicator.md +283 -0
- package/dist/ai/BbNumberInput.md +717 -355
- package/dist/ai/BbOffCanvas.md +897 -498
- package/dist/ai/BbPagination.md +489 -535
- package/dist/ai/BbPopover.md +591 -546
- package/dist/ai/BbProgress.md +462 -69
- package/dist/ai/BbRadio.md +352 -229
- package/dist/ai/BbRadioGroup.md +437 -353
- package/dist/ai/BbRating.md +372 -225
- package/dist/ai/BbSelect.md +1399 -536
- package/dist/ai/BbSelectPopover.md +1255 -1578
- package/dist/ai/BbSlider.md +500 -256
- package/dist/ai/BbSmoothHeight.md +485 -139
- package/dist/ai/BbSpinner.md +718 -131
- package/dist/ai/BbSwitch.md +573 -119
- package/dist/ai/BbSwitchGroup.md +521 -214
- package/dist/ai/BbTable.md +1996 -2365
- package/dist/ai/BbTabs.md +1147 -0
- package/dist/ai/BbTabsList.md +29 -0
- package/dist/ai/BbTabsPanes.md +27 -0
- package/dist/ai/BbTabsRoot.md +57 -0
- package/dist/ai/BbTag.md +416 -292
- package/dist/ai/BbTextInput.md +878 -333
- package/dist/ai/BbTextarea.md +850 -255
- package/dist/ai/BbTimePicker.md +231 -0
- package/dist/ai/BbTimePickerInput.md +200 -0
- package/dist/ai/BbToast.md +669 -196
- package/dist/ai/BbToastPortal.md +28 -0
- package/dist/ai/BbTooltip.md +453 -346
- package/dist/ai/BbTree.md +993 -234
- package/dist/ai/ChipsBox.md +27 -199
- package/dist/ai/ClearableButton.md +21 -55
- package/dist/ai/CommaBox.md +25 -200
- package/dist/ai/CommonInputWrapper.md +42 -0
- package/dist/ai/CommonPopover.md +30 -510
- package/dist/ai/ErrorIcon.md +19 -56
- package/dist/ai/FlatListBox.md +35 -379
- package/dist/ai/GroupedListBox.md +37 -535
- package/dist/ai/GuidesComponent.md +21 -0
- package/dist/ai/ListBox.md +38 -231
- package/dist/ai/OptionsContainer.md +34 -253
- package/dist/ai/WarningIcon.md +21 -0
- package/dist/ai/components.json +15897 -0
- package/dist/ai/composables/useBbConfig.md +80 -0
- package/dist/ai/composables/useBbFormContext.md +110 -0
- package/dist/ai/composables/useBbTableContext.md +167 -0
- package/dist/ai/composables/useBbTabsContext.md +118 -0
- package/dist/ai/composables/useBroadcastChannelInstance.md +97 -0
- package/dist/ai/composables/useConfirm.md +313 -0
- package/dist/ai/composables/useCountdown.md +86 -0
- package/dist/ai/composables/useId.md +60 -0
- package/dist/ai/composables/useMobile.md +85 -0
- package/dist/ai/composables/useToast.md +238 -0
- package/dist/ai/guides/agent-contract.md +165 -0
- package/dist/ai/guides/ai-router.md +113 -0
- package/dist/ai/guides/app-layout.md +318 -0
- package/dist/ai/guides/coherence-playbook.md +136 -0
- package/dist/ai/guides/component-picker.md +236 -0
- package/dist/ai/guides/design-language.md +478 -0
- package/dist/ai/guides/design-tokens.md +450 -0
- package/dist/ai/guides/fetch-items-playbook.md +161 -0
- package/dist/ai/guides/floating-bottom-panel.md +130 -0
- package/dist/ai/guides/icons-policy.md +257 -0
- package/dist/ai/guides/inertia-helpers.md +1443 -0
- package/dist/ai/guides/inline-edit-playbook.md +267 -0
- package/dist/ai/guides/installation-and-plugin-setup.md +440 -0
- package/dist/ai/guides/migration/components/bb-alert.md +37 -0
- package/dist/ai/guides/migration/components/bb-avatar.md +24 -0
- package/dist/ai/guides/migration/components/bb-badge.md +110 -0
- package/dist/ai/guides/migration/components/bb-breadcrumbs.md +26 -0
- package/dist/ai/guides/migration/components/bb-button.md +55 -0
- package/dist/ai/guides/migration/components/bb-checkbox-group.md +54 -0
- package/dist/ai/guides/migration/components/bb-checkbox.md +45 -0
- package/dist/ai/guides/migration/components/bb-chip.md +35 -0
- package/dist/ai/guides/migration/components/bb-collapsible.md +26 -0
- package/dist/ai/guides/migration/components/bb-color-input.md +23 -0
- package/dist/ai/guides/migration/components/bb-color-palette.md +31 -0
- package/dist/ai/guides/migration/components/bb-date-picker-input.md +84 -0
- package/dist/ai/guides/migration/components/bb-dialog.md +46 -0
- package/dist/ai/guides/migration/components/bb-dropdown-button.md +31 -0
- package/dist/ai/guides/migration/components/bb-dropdown.md +36 -0
- package/dist/ai/guides/migration/components/bb-dropzone.md +27 -0
- package/dist/ai/guides/migration/components/bb-icon.md +27 -0
- package/dist/ai/guides/migration/components/bb-offcanvas.md +63 -0
- package/dist/ai/guides/migration/components/bb-pagination.md +24 -0
- package/dist/ai/guides/migration/components/bb-popover.md +52 -0
- package/dist/ai/guides/migration/components/bb-rating.md +24 -0
- package/dist/ai/guides/migration/components/bb-select-popover.md +59 -0
- package/dist/ai/guides/migration/components/bb-select.md +69 -0
- package/dist/ai/guides/migration/components/bb-slider.md +25 -0
- package/dist/ai/guides/migration/components/bb-smooth-height.md +45 -0
- package/dist/ai/guides/migration/components/bb-spinner.md +23 -0
- package/dist/ai/guides/migration/components/bb-table.md +66 -0
- package/dist/ai/guides/migration/components/bb-tabs.md +47 -0
- package/dist/ai/guides/migration/components/bb-tag.md +29 -0
- package/dist/ai/guides/migration/components/bb-text-input.md +37 -0
- package/dist/ai/guides/migration/components/bb-toast.md +47 -0
- package/dist/ai/guides/migration/components/bb-tooltip.md +34 -0
- package/dist/ai/guides/migration/components/bb-tree.md +77 -0
- package/dist/ai/guides/migration/components/use-confirm.md +46 -0
- package/dist/ai/guides/migration/v2-to-v3.md +649 -0
- package/dist/ai/guides/options-items-playbook.md +222 -0
- package/dist/ai/guides/page-shell.md +113 -0
- package/dist/ai/guides/validated-forms.md +177 -0
- package/dist/ai/index.md +158 -32
- package/dist/ai/recipes/inertia/approvals-inbox.md +1635 -0
- package/dist/ai/recipes/inertia/inline-edit-workspace.md +1765 -0
- package/dist/ai/recipes/inertia/layout-scaffold.md +385 -0
- package/dist/ai/recipes/inertia/onboarding.md +1791 -0
- package/dist/ai/recipes/inertia/ownership-atlas.md +1327 -0
- package/dist/ai/recipes/inertia/record-form.md +1489 -0
- package/dist/ai/recipes/inertia/records-workspace.md +1416 -0
- package/dist/ai/recipes/inertia/upload-center.md +2003 -0
- package/dist/ai/recipes/inertia/wizard-form.md +1500 -0
- package/dist/ai/recipes/nuxt/approvals-inbox.md +1578 -0
- package/dist/ai/recipes/nuxt/inline-edit-workspace.md +1703 -0
- package/dist/ai/recipes/nuxt/layout-scaffold.md +385 -0
- package/dist/ai/recipes/nuxt/onboarding.md +1724 -0
- package/dist/ai/recipes/nuxt/record-form.md +1502 -0
- package/dist/ai/recipes/nuxt/records-workspace.md +1329 -0
- package/dist/ai/recipes/nuxt/upload-center.md +1886 -0
- package/dist/ai/recipes/nuxt/wizard-form.md +1509 -0
- package/dist/ai/recipes/vue/approvals-inbox.md +1496 -0
- package/dist/ai/recipes/vue/inline-edit-workspace.md +1594 -0
- package/dist/ai/recipes/vue/layout-scaffold.md +385 -0
- package/dist/ai/recipes/vue/onboarding.md +1679 -0
- package/dist/ai/recipes/vue/record-form.md +1586 -0
- package/dist/ai/recipes/vue/records-workspace.md +1245 -0
- package/dist/ai/recipes/vue/upload-center.md +1845 -0
- package/dist/ai/recipes/vue/wizard-form.md +1441 -0
- package/dist/ai/source/BbAccordion.md +123 -0
- package/dist/ai/source/BbAlert.md +401 -0
- package/dist/ai/source/BbAsterisk.md +32 -0
- package/dist/ai/source/BbAvatar.md +258 -0
- package/dist/ai/source/BbBadge.md +560 -0
- package/dist/ai/source/BbBadgeButton.md +490 -0
- package/dist/ai/source/BbBaseButton.md +682 -0
- package/dist/ai/source/BbBaseCheckbox.md +461 -0
- package/dist/ai/source/BbBaseCheckboxGroup.md +554 -0
- package/dist/ai/source/BbBaseCheckboxIcon.md +201 -0
- package/dist/ai/source/BbBaseColorInput.md +416 -0
- package/dist/ai/source/BbBaseColorPalette.md +934 -0
- package/dist/ai/source/BbBaseDatePicker.md +1001 -0
- package/dist/ai/source/BbBaseDatePickerInput.md +1785 -0
- package/dist/ai/source/BbBaseInputContainer.md +1210 -0
- package/dist/ai/source/BbBaseNumberInput.md +617 -0
- package/dist/ai/source/BbBaseRadio.md +377 -0
- package/dist/ai/source/BbBaseRadioGroup.md +533 -0
- package/dist/ai/source/BbBaseRadioIcon.md +153 -0
- package/dist/ai/source/BbBaseRating.md +573 -0
- package/dist/ai/source/BbBaseSelect.md +898 -0
- package/dist/ai/source/BbBaseSlider.md +1085 -0
- package/dist/ai/source/BbBaseSwitch.md +246 -0
- package/dist/ai/source/BbBaseSwitchGroup.md +302 -0
- package/dist/ai/source/BbBaseSwitchIcon.md +206 -0
- package/dist/ai/source/BbBaseTag.md +694 -0
- package/dist/ai/source/BbBaseTextInput.md +511 -0
- package/dist/ai/source/BbBaseTextarea.md +480 -0
- package/dist/ai/source/BbBaseTimePickerInput.md +1031 -0
- package/dist/ai/source/BbBreadcrumbs.md +815 -0
- package/dist/ai/source/BbButton.md +1006 -0
- package/dist/ai/source/BbCheckbox.md +326 -0
- package/dist/ai/source/BbCheckboxGroup.md +419 -0
- package/dist/ai/source/BbCollapsible.md +137 -0
- package/dist/ai/source/BbColorInput.md +322 -0
- package/dist/ai/source/BbColorPalette.md +371 -0
- package/dist/ai/source/BbConfirm.md +193 -0
- package/dist/ai/source/BbConfirmPortal.md +74 -0
- package/dist/ai/source/BbDatePicker.md +729 -0
- package/dist/ai/source/BbDatePickerInput.md +525 -0
- package/dist/ai/source/BbDialog.md +818 -0
- package/dist/ai/source/BbDropdown.md +2387 -0
- package/dist/ai/source/BbDropdownButton.md +315 -0
- package/dist/ai/source/BbDropdownGroup.md +1259 -0
- package/dist/ai/source/BbDropzone.md +864 -0
- package/dist/ai/source/BbForm.md +100 -0
- package/dist/ai/source/BbIcon.md +214 -0
- package/dist/ai/source/BbIndicator.md +298 -0
- package/dist/ai/source/BbNumberInput.md +374 -0
- package/dist/ai/source/BbOffCanvas.md +1266 -0
- package/dist/ai/source/BbPagination.md +835 -0
- package/dist/ai/source/BbPopover.md +860 -0
- package/dist/ai/source/BbProgress.md +140 -0
- package/dist/ai/source/BbRadio.md +303 -0
- package/dist/ai/source/BbRadioGroup.md +420 -0
- package/dist/ai/source/BbRating.md +369 -0
- package/dist/ai/source/BbSelect.md +688 -0
- package/dist/ai/source/BbSelectPopover.md +2234 -0
- package/dist/ai/source/BbSlider.md +378 -0
- package/dist/ai/source/BbSmoothHeight.md +265 -0
- package/dist/ai/source/BbSpinner.md +127 -0
- package/dist/ai/source/BbSwitch.md +175 -0
- package/dist/ai/source/BbSwitchGroup.md +240 -0
- package/dist/ai/source/BbTable.md +3433 -0
- package/dist/ai/source/BbTabs.md +403 -0
- package/dist/ai/source/BbTabsList.md +578 -0
- package/dist/ai/source/BbTabsPanes.md +368 -0
- package/dist/ai/source/BbTabsRoot.md +372 -0
- package/dist/ai/source/BbTag.md +390 -0
- package/dist/ai/source/BbTextInput.md +352 -0
- package/dist/ai/source/BbTextarea.md +337 -0
- package/dist/ai/source/BbTimePicker.md +595 -0
- package/dist/ai/source/BbTimePickerInput.md +376 -0
- package/dist/ai/source/BbToast.md +525 -0
- package/dist/ai/source/BbToastPortal.md +482 -0
- package/dist/ai/source/BbTooltip.md +522 -0
- package/dist/ai/source/BbTree.md +323 -0
- package/dist/ai/source/ChipsBox.md +201 -0
- package/dist/ai/source/ClearableButton.md +70 -0
- package/dist/ai/source/CommaBox.md +202 -0
- package/dist/ai/source/CommonInputWrapper.md +554 -0
- package/dist/ai/source/CommonPopover.md +616 -0
- package/dist/ai/source/ErrorIcon.md +43 -0
- package/dist/ai/source/FlatListBox.md +396 -0
- package/dist/ai/source/GroupedListBox.md +540 -0
- package/dist/ai/source/GuidesComponent.md +383 -0
- package/dist/ai/source/ListBox.md +238 -0
- package/dist/ai/source/OptionsContainer.md +191 -0
- package/dist/ai/source/WarningIcon.md +47 -0
- package/dist/alert-variants.d.ts +19 -0
- package/dist/assets/css/reset.css_inline.js +4 -0
- package/dist/assets/svgs/alert.svg_raw.js +4 -0
- package/dist/assets/svgs/calendar.svg_raw.js +4 -0
- package/dist/assets/svgs/check_stroke.svg_raw.js +4 -0
- package/dist/assets/svgs/chevron_down.svg_raw.js +4 -0
- package/dist/assets/svgs/chevron_right.svg_raw.js +4 -0
- package/dist/assets/svgs/clear.svg_raw.js +4 -0
- package/dist/assets/svgs/clock.svg_raw.js +4 -0
- package/dist/assets/svgs/error.svg_raw.js +4 -0
- package/dist/assets/svgs/search.svg_raw.js +4 -0
- package/dist/assets/svgs/sort.svg_raw.js +4 -0
- package/dist/assets/svgs/spinner.svg_raw.js +4 -0
- package/dist/assets/svgs/user.svg_raw.js +4 -0
- package/dist/badge-variants.d.ts +19 -0
- package/dist/button-variants.d.ts +21 -0
- package/dist/components/BbAccordion/BbAccordion.vue.d.ts +9 -3
- package/dist/components/BbAccordion/BbAccordion.vue.js +6 -0
- package/dist/components/BbAccordion/BbAccordion.vue_vue_type_script_setup_true_lang.js +66 -0
- package/dist/components/BbAccordion/types.d.ts +12 -8
- package/dist/components/BbAlert/BbAlert.vue.d.ts +12 -3
- package/dist/components/BbAlert/BbAlert.vue.js +6 -0
- package/dist/components/BbAlert/BbAlert.vue_vue_type_script_setup_true_lang.js +65 -0
- package/dist/components/BbAlert/types.d.ts +56 -12
- package/dist/components/BbAsterisk/BbAsterisk.vue.d.ts +3 -0
- package/dist/components/BbAsterisk/BbAsterisk.vue.js +6 -0
- package/dist/components/BbAsterisk/BbAsterisk.vue_vue_type_script_setup_true_lang.js +13 -0
- package/dist/components/BbAvatar/BbAvatar.vue.d.ts +5 -0
- package/dist/components/BbAvatar/BbAvatar.vue.js +6 -0
- package/dist/components/BbAvatar/BbAvatar.vue_vue_type_script_setup_true_lang.js +78 -0
- package/dist/components/BbAvatar/types.d.ts +6 -5
- package/dist/components/BbBadge/BadgeAppendIcon.vue.d.ts +3 -0
- package/dist/components/BbBadge/BadgeAppendIcon.vue.js +5 -0
- package/dist/components/BbBadge/BadgeAppendIcon.vue_vue_type_script_setup_true_lang.js +22 -0
- package/dist/components/BbBadge/BadgeBodyContent.vue.d.ts +15 -0
- package/dist/components/BbBadge/BadgeBodyContent.vue.js +5 -0
- package/dist/components/BbBadge/BadgeBodyContent.vue_vue_type_script_setup_true_lang.js +34 -0
- package/dist/components/BbBadge/BbBadge.vue.d.ts +8 -1
- package/dist/components/BbBadge/BbBadge.vue.js +6 -0
- package/dist/components/BbBadge/BbBadge.vue_vue_type_script_setup_true_lang.js +83 -0
- package/dist/components/BbBadge/BbBadgeButton.vue.d.ts +12 -0
- package/dist/components/BbBadge/BbBadgeButton.vue.js +5 -0
- package/dist/components/BbBadge/BbBadgeButton.vue_vue_type_script_setup_true_lang.js +54 -0
- package/dist/components/BbBadge/badgeButtonContext.d.ts +27 -0
- package/dist/components/BbBadge/badgeButtonContext.js +5 -0
- package/dist/components/BbBadge/types.d.ts +61 -16
- package/dist/components/BbBaseButton/BbBaseButton.vue.d.ts +13 -0
- package/dist/components/BbBaseButton/BbBaseButton.vue.js +6 -0
- package/dist/components/BbBaseButton/BbBaseButton.vue_vue_type_script_setup_true_lang.js +171 -0
- package/dist/components/BbBaseButton/RouterComponent.vue.js +5 -0
- package/dist/components/BbBaseButton/RouterComponent.vue_vue_type_script_setup_true_lang.js +29 -0
- package/dist/components/BbBaseButton/types.d.ts +191 -0
- package/dist/components/BbBaseButton/types.js +33 -0
- package/dist/components/BbBaseCheckbox/BbBaseCheckbox.vue.d.ts +40 -0
- package/dist/components/BbBaseCheckbox/BbBaseCheckbox.vue.js +6 -0
- package/dist/components/BbBaseCheckbox/BbBaseCheckbox.vue_vue_type_script_setup_true_lang.js +145 -0
- package/dist/components/BbBaseCheckbox/types.d.ts +224 -0
- package/dist/components/BbBaseCheckboxGroup/BbBaseCheckboxGroup.vue.d.ts +19 -0
- package/dist/components/BbBaseCheckboxGroup/BbBaseCheckboxGroup.vue.js +6 -0
- package/dist/components/BbBaseCheckboxGroup/BbBaseCheckboxGroup.vue_vue_type_script_setup_true_lang.js +190 -0
- package/dist/components/BbBaseCheckboxGroup/types.d.ts +257 -0
- package/dist/components/BbBaseCheckboxIcon/BbBaseCheckboxIcon.vue.d.ts +4 -0
- package/dist/components/BbBaseCheckboxIcon/BbBaseCheckboxIcon.vue.js +6 -0
- package/dist/components/BbBaseCheckboxIcon/BbBaseCheckboxIcon.vue_vue_type_script_setup_true_lang.js +43 -0
- package/dist/components/BbBaseCheckboxIcon/types.d.ts +47 -0
- package/dist/components/BbBaseColorInput/BbBaseColorInput.vue.d.ts +42 -0
- package/dist/components/BbBaseColorInput/BbBaseColorInput.vue.js +6 -0
- package/dist/components/BbBaseColorInput/BbBaseColorInput.vue_vue_type_script_setup_true_lang.js +178 -0
- package/dist/components/BbBaseColorInput/types.d.ts +210 -0
- package/dist/components/BbBaseColorPalette/BbBaseColorPalette.vue.d.ts +13 -0
- package/dist/components/BbBaseColorPalette/BbBaseColorPalette.vue.js +6 -0
- package/dist/components/BbBaseColorPalette/BbBaseColorPalette.vue_vue_type_script_setup_true_lang.js +395 -0
- package/dist/components/BbBaseColorPalette/types.d.ts +40 -0
- package/dist/components/BbBaseDatePicker/BbBaseDatePicker.vue.js +6 -0
- package/dist/components/BbBaseDatePicker/BbBaseDatePicker.vue_vue_type_script_setup_true_lang.js +300 -0
- package/dist/components/BbBaseDatePicker/BbBaseDatePickerInputDaySelector.vue.d.ts +44 -0
- package/dist/components/BbBaseDatePicker/BbBaseDatePickerInputDaySelector.vue.js +5 -0
- package/dist/components/BbBaseDatePicker/BbBaseDatePickerInputDaySelector.vue_vue_type_script_setup_true_lang.js +310 -0
- package/dist/components/BbBaseDatePicker/BbBaseDatePickerMonthSelector.vue.d.ts +5 -0
- package/dist/components/BbBaseDatePicker/BbBaseDatePickerMonthSelector.vue.js +5 -0
- package/dist/components/BbBaseDatePicker/BbBaseDatePickerMonthSelector.vue_vue_type_script_setup_true_lang.js +63 -0
- package/dist/components/BbBaseDatePicker/BbBaseDatePickerYearSelector.vue.d.ts +5 -0
- package/dist/components/BbBaseDatePicker/BbBaseDatePickerYearSelector.vue.js +5 -0
- package/dist/components/BbBaseDatePicker/BbBaseDatePickerYearSelector.vue_vue_type_script_setup_true_lang.js +75 -0
- package/dist/components/BbBaseDatePicker/typeahead.d.ts +112 -0
- package/dist/components/BbBaseDatePicker/typeahead.js +37 -0
- package/dist/components/BbBaseDatePicker/types.d.ts +97 -0
- package/dist/components/BbBaseDatePicker/useDatePickerContext.d.ts +58 -0
- package/dist/components/BbBaseDatePicker/useDatePickerContext.js +11 -0
- package/dist/components/BbBaseDatePickerInput/BbBaseDatePickerInput.vue.d.ts +30 -0
- package/dist/components/BbBaseDatePickerInput/BbBaseDatePickerInput.vue.js +6 -0
- package/dist/components/BbBaseDatePickerInput/BbBaseDatePickerInput.vue_vue_type_script_setup_true_lang.js +716 -0
- package/dist/components/BbBaseDatePickerInput/BbBaseDatePickerTimeSelector.vue.d.ts +30 -0
- package/dist/components/BbBaseDatePickerInput/BbBaseDatePickerTimeSelector.vue.js +6 -0
- package/dist/components/BbBaseDatePickerInput/BbBaseDatePickerTimeSelector.vue_vue_type_script_setup_true_lang.js +204 -0
- package/dist/components/BbBaseDatePickerInput/types.d.ts +311 -0
- package/dist/components/BbBaseInputContainer/BbBaseInputContainer.vue.d.ts +17 -0
- package/dist/components/BbBaseInputContainer/BbBaseInputContainer.vue.js +6 -0
- package/dist/components/BbBaseInputContainer/BbBaseInputContainer.vue_vue_type_script_setup_true_lang.js +191 -0
- package/dist/components/BbBaseInputContainer/types.d.ts +197 -0
- package/dist/components/BbBaseNumberInput/BbBaseNumberInput.vue.d.ts +52 -0
- package/dist/components/BbBaseNumberInput/BbBaseNumberInput.vue.js +6 -0
- package/dist/components/BbBaseNumberInput/BbBaseNumberInput.vue_vue_type_script_setup_true_lang.js +215 -0
- package/dist/components/BbBaseNumberInput/types.d.ts +211 -0
- package/dist/components/BbBaseRadio/BbBaseRadio.vue.d.ts +33 -0
- package/dist/components/BbBaseRadio/BbBaseRadio.vue.js +6 -0
- package/dist/components/BbBaseRadio/BbBaseRadio.vue_vue_type_script_setup_true_lang.js +114 -0
- package/dist/components/BbBaseRadio/types.d.ts +179 -0
- package/dist/components/BbBaseRadioGroup/BbBaseRadioGroup.vue.d.ts +19 -0
- package/dist/components/BbBaseRadioGroup/BbBaseRadioGroup.vue.js +6 -0
- package/dist/components/BbBaseRadioGroup/BbBaseRadioGroup.vue_vue_type_script_setup_true_lang.js +177 -0
- package/dist/components/BbBaseRadioGroup/types.d.ts +223 -0
- package/dist/components/BbBaseRadioIcon/BbBaseRadioIcon.vue.d.ts +4 -0
- package/dist/components/BbBaseRadioIcon/BbBaseRadioIcon.vue.js +6 -0
- package/dist/components/BbBaseRadioIcon/BbBaseRadioIcon.vue_vue_type_script_setup_true_lang.js +28 -0
- package/dist/components/BbBaseRadioIcon/types.d.ts +41 -0
- package/dist/components/BbBaseRating/BbBaseRating.vue.d.ts +38 -0
- package/dist/components/BbBaseRating/BbBaseRating.vue.js +6 -0
- package/dist/components/BbBaseRating/BbBaseRating.vue_vue_type_script_setup_true_lang.js +184 -0
- package/dist/components/BbBaseRating/types.d.ts +168 -0
- package/dist/components/BbBaseSelect/BbBaseSelect.vue.d.ts +19 -0
- package/dist/components/BbBaseSelect/BbBaseSelect.vue.js +6 -0
- package/dist/components/BbBaseSelect/BbBaseSelect.vue_vue_type_script_setup_true_lang.js +307 -0
- package/dist/components/BbBaseSelect/types.d.ts +297 -0
- package/dist/components/BbBaseSlider/BbBaseSlider.vue.d.ts +35 -0
- package/dist/components/BbBaseSlider/BbBaseSlider.vue.js +6 -0
- package/dist/components/BbBaseSlider/BbBaseSlider.vue_vue_type_script_setup_true_lang.js +324 -0
- package/dist/components/BbBaseSlider/types.d.ts +200 -0
- package/dist/components/BbBaseSwitch/BbBaseSwitch.vue.d.ts +35 -0
- package/dist/components/BbBaseSwitch/BbBaseSwitch.vue.js +6 -0
- package/dist/components/BbBaseSwitch/BbBaseSwitch.vue_vue_type_script_setup_true_lang.js +146 -0
- package/dist/components/BbBaseSwitch/types.d.ts +10 -0
- package/dist/components/BbBaseSwitchGroup/BbBaseSwitchGroup.vue.d.ts +19 -0
- package/dist/components/BbBaseSwitchGroup/BbBaseSwitchGroup.vue.js +6 -0
- package/dist/components/BbBaseSwitchGroup/BbBaseSwitchGroup.vue_vue_type_script_setup_true_lang.js +190 -0
- package/dist/components/BbBaseSwitchGroup/types.d.ts +8 -0
- package/dist/components/BbBaseSwitchIcon/BbBaseSwitchIcon.vue.d.ts +4 -0
- package/dist/components/BbBaseSwitchIcon/BbBaseSwitchIcon.vue.js +6 -0
- package/dist/components/BbBaseSwitchIcon/BbBaseSwitchIcon.vue_vue_type_script_setup_true_lang.js +30 -0
- package/dist/components/BbBaseSwitchIcon/types.d.ts +48 -0
- package/dist/components/BbBaseTag/BbBaseTag.vue.d.ts +50 -0
- package/dist/components/BbBaseTag/BbBaseTag.vue.js +6 -0
- package/dist/components/BbBaseTag/BbBaseTag.vue_vue_type_script_setup_true_lang.js +266 -0
- package/dist/components/BbBaseTag/types.d.ts +160 -0
- package/dist/components/BbBaseTextInput/BbBaseTextInput.vue.d.ts +45 -0
- package/dist/components/BbBaseTextInput/BbBaseTextInput.vue.js +6 -0
- package/dist/components/BbBaseTextInput/BbBaseTextInput.vue_vue_type_script_setup_true_lang.js +200 -0
- package/dist/components/BbBaseTextInput/types.d.ts +209 -0
- package/dist/components/BbBaseTextarea/BbBaseTextarea.vue.d.ts +39 -0
- package/dist/components/BbBaseTextarea/BbBaseTextarea.vue.js +6 -0
- package/dist/components/BbBaseTextarea/BbBaseTextarea.vue_vue_type_script_setup_true_lang.js +175 -0
- package/dist/components/BbBaseTextarea/types.d.ts +170 -0
- package/dist/components/BbBaseTimePickerInput/BbBaseTimePickerInput.vue.d.ts +27 -0
- package/dist/components/BbBaseTimePickerInput/BbBaseTimePickerInput.vue.js +6 -0
- package/dist/components/BbBaseTimePickerInput/BbBaseTimePickerInput.vue_vue_type_script_setup_true_lang.js +522 -0
- package/dist/components/BbBaseTimePickerInput/types.d.ts +151 -0
- package/dist/components/BbBreadcrumbs/BbBreadcrumbs.vue.d.ts +0 -1
- package/dist/components/BbBreadcrumbs/BbBreadcrumbs.vue.js +6 -0
- package/dist/components/BbBreadcrumbs/BbBreadcrumbs.vue_vue_type_script_setup_true_lang.js +224 -0
- package/dist/components/BbBreadcrumbs/estimateBreadcrumbItemWidth.js +47 -0
- package/dist/components/BbBreadcrumbs/types.d.ts +37 -22
- package/dist/components/BbButton/BbButton.vue.d.ts +6 -5
- package/dist/components/BbButton/BbButton.vue.js +6 -0
- package/dist/components/BbButton/BbButton.vue_vue_type_script_setup_true_lang.js +181 -0
- package/dist/components/BbButton/types.d.ts +48 -47
- package/dist/components/BbCheckbox/BbCheckbox.vue.d.ts +4 -3
- package/dist/components/BbCheckbox/BbCheckbox.vue.js +6 -0
- package/dist/components/BbCheckbox/BbCheckbox.vue_vue_type_script_setup_true_lang.js +146 -0
- package/dist/components/BbCheckbox/types.d.ts +31 -10
- package/dist/components/BbCheckboxGroup/BbCheckboxGroup.vue.d.ts +2 -13
- package/dist/components/BbCheckboxGroup/BbCheckboxGroup.vue.js +6 -0
- package/dist/components/BbCheckboxGroup/BbCheckboxGroup.vue_vue_type_script_setup_true_lang.js +190 -0
- package/dist/components/BbCheckboxGroup/types.d.ts +51 -23
- package/dist/components/BbCollapsible/BbCollapsible.vue.d.ts +2 -1
- package/dist/components/BbCollapsible/BbCollapsible.vue.js +6 -0
- package/dist/components/BbCollapsible/BbCollapsible.vue_vue_type_script_setup_true_lang.js +31 -0
- package/dist/components/BbCollapsible/types.d.ts +13 -8
- package/dist/components/BbColorInput/BbColorInput.vue.d.ts +10 -1
- package/dist/components/BbColorInput/BbColorInput.vue.js +6 -0
- package/dist/components/BbColorInput/BbColorInput.vue_vue_type_script_setup_true_lang.js +177 -0
- package/dist/components/BbColorInput/types.d.ts +44 -11
- package/dist/components/BbColorPalette/BbColorPalette.vue.d.ts +5 -8
- package/dist/components/BbColorPalette/BbColorPalette.vue.js +5 -0
- package/dist/components/BbColorPalette/BbColorPalette.vue_vue_type_script_setup_true_lang.js +126 -0
- package/dist/components/BbColorPalette/types.d.ts +71 -52
- package/dist/components/BbConfirm/BbConfirm.vue.js +6 -0
- package/dist/components/BbConfirm/BbConfirm.vue_vue_type_script_setup_true_lang.js +138 -0
- package/dist/components/BbConfirm/BbConfirmPortal.vue.d.ts +5 -6
- package/dist/components/BbConfirm/BbConfirmPortal.vue.js +5 -0
- package/dist/components/BbConfirm/BbConfirmPortal.vue_vue_type_script_setup_true_lang.js +19 -0
- package/dist/components/BbDatePicker/BbDatePicker.vue.d.ts +37 -0
- package/dist/components/BbDatePicker/BbDatePicker.vue.js +6 -0
- package/dist/components/BbDatePicker/BbDatePicker.vue_vue_type_script_setup_true_lang.js +319 -0
- package/dist/components/BbDatePicker/types.d.ts +159 -0
- package/dist/components/BbDatePickerInput/BbDatePickerInput.vue.d.ts +3 -1
- package/dist/components/BbDatePickerInput/BbDatePickerInput.vue.js +6 -0
- package/dist/components/BbDatePickerInput/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +179 -0
- package/dist/components/BbDatePickerInput/types.d.ts +134 -16
- package/dist/components/BbDialog/BbDialog.vue.d.ts +14 -6
- package/dist/components/BbDialog/BbDialog.vue.js +6 -0
- package/dist/components/BbDialog/BbDialog.vue_vue_type_script_setup_true_lang.js +214 -0
- package/dist/components/BbDialog/types.d.ts +146 -1
- package/dist/components/BbDialog/useDialogStack.d.ts +5 -0
- package/dist/components/BbDialog/useDialogStack.js +20 -0
- package/dist/components/BbDropdown/AdaptiveDropdown.vue.d.ts +24 -0
- package/dist/components/BbDropdown/AdaptiveDropdown.vue.js +6 -0
- package/dist/components/BbDropdown/AdaptiveDropdown.vue_vue_type_script_setup_true_lang.js +116 -0
- package/dist/components/BbDropdown/BbDropdown.vue.d.ts +14 -7
- package/dist/components/BbDropdown/BbDropdown.vue.js +6 -0
- package/dist/components/BbDropdown/BbDropdown.vue_vue_type_script_setup_true_lang.js +561 -0
- package/dist/components/BbDropdown/BbDropdownGroup.vue.d.ts +44 -0
- package/dist/components/BbDropdown/BbDropdownGroup.vue.js +5 -0
- package/dist/components/BbDropdown/BbDropdownGroup.vue_vue_type_script_setup_true_lang.js +36 -0
- package/dist/components/BbDropdown/BbDropdownList.vue.d.ts +31 -0
- package/dist/components/BbDropdown/BbDropdownList.vue.js +6 -0
- package/dist/components/BbDropdown/BbDropdownList.vue_vue_type_script_setup_true_lang.js +470 -0
- package/dist/components/BbDropdown/DropdownPipelineResolver.vue.d.ts +16 -0
- package/dist/components/BbDropdown/DropdownPipelineResolver.vue.js +5 -0
- package/dist/components/BbDropdown/DropdownPipelineResolver.vue_vue_type_script_setup_true_lang.js +168 -0
- package/dist/components/BbDropdown/normalizeGroups.d.ts +18 -0
- package/dist/components/BbDropdown/normalizeGroups.js +46 -0
- package/dist/components/BbDropdown/types.d.ts +468 -46
- package/dist/components/BbDropdown/types.js +4 -0
- package/dist/components/BbDropdown/useDropdownContext.d.ts +89 -0
- package/dist/components/BbDropdown/useDropdownContext.js +9 -0
- package/dist/components/BbDropdown/useDropdownGroupRegistry.d.ts +108 -0
- package/dist/components/BbDropdown/useDropdownGroupRegistry.js +5 -0
- package/dist/components/BbDropdownButton/BbDropdownButton.vue.d.ts +3 -3
- package/dist/components/BbDropdownButton/BbDropdownButton.vue.js +6 -0
- package/dist/components/BbDropdownButton/BbDropdownButton.vue_vue_type_script_setup_true_lang.js +119 -0
- package/dist/components/BbDropdownButton/types.d.ts +47 -52
- package/dist/components/BbDropzone/BbDropzone.vue.d.ts +5 -4
- package/dist/components/BbDropzone/BbDropzone.vue.js +6 -0
- package/dist/components/BbDropzone/BbDropzone.vue_vue_type_script_setup_true_lang.js +308 -0
- package/dist/components/BbDropzone/types.d.ts +77 -8
- package/dist/components/BbIcon/BbIcon.vue.d.ts +3 -2
- package/dist/components/BbIcon/BbIcon.vue.js +6 -0
- package/dist/components/BbIcon/BbIcon.vue_vue_type_script_setup_true_lang.js +65 -0
- package/dist/components/BbIcon/types.d.ts +6 -19
- package/dist/components/BbIndicator/BbIndicator.vue.d.ts +14 -0
- package/dist/components/BbIndicator/BbIndicator.vue.js +6 -0
- package/dist/components/BbIndicator/BbIndicator.vue_vue_type_script_setup_true_lang.js +56 -0
- package/dist/components/BbIndicator/types.d.ts +49 -0
- package/dist/components/BbNumberInput/BbNumberInput.vue.d.ts +12 -6
- package/dist/components/BbNumberInput/BbNumberInput.vue.js +6 -0
- package/dist/components/BbNumberInput/BbNumberInput.vue_vue_type_script_setup_true_lang.js +194 -0
- package/dist/components/BbNumberInput/types.d.ts +40 -4
- package/dist/components/BbOffCanvas/BbOffCanvas.vue.d.ts +16 -10
- package/dist/components/BbOffCanvas/BbOffCanvas.vue.js +6 -0
- package/dist/components/BbOffCanvas/BbOffCanvas.vue_vue_type_script_setup_true_lang.js +284 -0
- package/dist/components/BbOffCanvas/types.d.ts +71 -39
- package/dist/components/BbOffCanvas/useOffCanvasStack.d.ts +25 -0
- package/dist/components/BbOffCanvas/useOffCanvasStack.js +68 -0
- package/dist/components/BbPagination/BbPagination.vue.d.ts +9 -4
- package/dist/components/BbPagination/BbPagination.vue.js +6 -0
- package/dist/components/BbPagination/BbPagination.vue_vue_type_script_setup_true_lang.js +244 -0
- package/dist/components/BbPagination/paginationFit.d.ts +38 -0
- package/dist/components/BbPagination/paginationFit.js +13 -0
- package/dist/components/BbPagination/types.d.ts +51 -16
- package/dist/components/BbPopover/BbPopover.vue.d.ts +16 -15
- package/dist/components/BbPopover/BbPopover.vue.js +6 -0
- package/dist/components/BbPopover/BbPopover.vue_vue_type_script_setup_true_lang.js +309 -0
- package/dist/components/BbPopover/escapeStack.d.ts +6 -0
- package/dist/components/BbPopover/escapeStack.js +10 -0
- package/dist/components/BbPopover/types.d.ts +90 -31
- package/dist/components/BbProgress/BbProgress.vue.d.ts +1 -0
- package/dist/components/BbProgress/BbProgress.vue.js +6 -0
- package/dist/components/BbProgress/BbProgress.vue_vue_type_script_setup_true_lang.js +36 -0
- package/dist/components/BbProgress/types.d.ts +15 -1
- package/dist/components/BbRadio/BbRadio.vue.d.ts +5 -3
- package/dist/components/BbRadio/BbRadio.vue.js +6 -0
- package/dist/components/BbRadio/BbRadio.vue_vue_type_script_setup_true_lang.js +133 -0
- package/dist/components/BbRadio/types.d.ts +32 -9
- package/dist/components/BbRadioGroup/BbRadioGroup.vue.d.ts +4 -14
- package/dist/components/BbRadioGroup/BbRadioGroup.vue.js +6 -0
- package/dist/components/BbRadioGroup/BbRadioGroup.vue_vue_type_script_setup_true_lang.js +186 -0
- package/dist/components/BbRadioGroup/types.d.ts +48 -22
- package/dist/components/BbRating/BbRating.vue.d.ts +4 -1
- package/dist/components/BbRating/BbRating.vue.js +6 -0
- package/dist/components/BbRating/BbRating.vue_vue_type_script_setup_true_lang.js +150 -0
- package/dist/components/BbRating/types.d.ts +44 -10
- package/dist/components/BbSelect/BbSelect.vue.d.ts +2 -11
- package/dist/components/BbSelect/BbSelect.vue.js +6 -0
- package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +241 -0
- package/dist/components/BbSelect/types.d.ts +112 -59
- package/dist/components/BbSelectPopover/BbSelectPopover.vue.d.ts +1 -10
- package/dist/components/BbSelectPopover/BbSelectPopover.vue.js +6 -0
- package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +639 -0
- package/dist/components/BbSelectPopover/types.d.ts +197 -105
- package/dist/components/BbSlider/BbSlider.vue.d.ts +3 -6
- package/dist/components/BbSlider/BbSlider.vue.js +6 -0
- package/dist/components/BbSlider/BbSlider.vue_vue_type_script_setup_true_lang.js +166 -0
- package/dist/components/BbSlider/types.d.ts +44 -13
- package/dist/components/BbSmoothHeight/BbSmoothHeight.vue.d.ts +3 -1
- package/dist/components/BbSmoothHeight/BbSmoothHeight.vue.js +6 -0
- package/dist/components/BbSmoothHeight/BbSmoothHeight.vue_vue_type_script_setup_true_lang.js +79 -0
- package/dist/components/BbSmoothHeight/types.d.ts +17 -2
- package/dist/components/BbSpinner/BbSpinner.vue.d.ts +1 -1
- package/dist/components/BbSpinner/BbSpinner.vue.js +6 -0
- package/dist/components/BbSpinner/BbSpinner.vue_vue_type_script_setup_true_lang.js +30 -0
- package/dist/components/BbSpinner/types.d.ts +10 -3
- package/dist/components/BbSwitch/BbSwitch.vue.d.ts +5 -3
- package/dist/components/BbSwitch/BbSwitch.vue.js +6 -0
- package/dist/components/BbSwitch/BbSwitch.vue_vue_type_script_setup_true_lang.js +142 -0
- package/dist/components/BbSwitch/types.d.ts +3 -1
- package/dist/components/BbSwitchGroup/BbSwitchGroup.vue.d.ts +4 -14
- package/dist/components/BbSwitchGroup/BbSwitchGroup.vue.js +6 -0
- package/dist/components/BbSwitchGroup/BbSwitchGroup.vue_vue_type_script_setup_true_lang.js +190 -0
- package/dist/components/BbSwitchGroup/types.d.ts +3 -22
- package/dist/components/BbTable/BbTable.vue.d.ts +58 -31
- package/dist/components/BbTable/BbTable.vue.js +6 -0
- package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +900 -0
- package/dist/components/BbTable/types.d.ts +213 -37
- package/dist/components/BbTable/utils.d.ts +9 -1
- package/dist/components/BbTable/utils.js +53 -0
- package/dist/components/BbTabs/BbTabs.vue.d.ts +20 -0
- package/dist/components/BbTabs/BbTabs.vue.js +6 -0
- package/dist/components/BbTabs/BbTabs.vue_vue_type_script_setup_true_lang.js +64 -0
- package/dist/components/BbTabs/BbTabsList.vue.d.ts +19 -0
- package/dist/components/BbTabs/BbTabsList.vue.js +6 -0
- package/dist/components/BbTabs/BbTabsList.vue_vue_type_script_setup_true_lang.js +123 -0
- package/dist/components/BbTabs/BbTabsPanes.vue.d.ts +16 -0
- package/dist/components/BbTabs/BbTabsPanes.vue.js +6 -0
- package/dist/components/BbTabs/BbTabsPanes.vue_vue_type_script_setup_true_lang.js +35 -0
- package/dist/components/BbTabs/BbTabsRoot.vue.d.ts +20 -0
- package/dist/components/BbTabs/BbTabsRoot.vue.js +5 -0
- package/dist/components/BbTabs/BbTabsRoot.vue_vue_type_script_setup_true_lang.js +55 -0
- package/dist/components/BbTabs/types.d.ts +264 -0
- package/dist/components/BbTag/BbTag.vue.d.ts +19 -6
- package/dist/components/BbTag/BbTag.vue.js +6 -0
- package/dist/components/BbTag/BbTag.vue_vue_type_script_setup_true_lang.js +187 -0
- package/dist/components/BbTag/types.d.ts +55 -17
- package/dist/components/BbTextInput/BbTextInput.vue.d.ts +10 -1
- package/dist/components/BbTextInput/BbTextInput.vue.js +6 -0
- package/dist/components/BbTextInput/BbTextInput.vue_vue_type_script_setup_true_lang.js +195 -0
- package/dist/components/BbTextInput/types.d.ts +31 -4
- package/dist/components/BbTextarea/BbTextarea.vue.d.ts +10 -1
- package/dist/components/BbTextarea/BbTextarea.vue.js +6 -0
- package/dist/components/BbTextarea/BbTextarea.vue_vue_type_script_setup_true_lang.js +178 -0
- package/dist/components/BbTextarea/types.d.ts +33 -2
- package/dist/components/BbTimePicker/BbTimePicker.vue.d.ts +33 -0
- package/dist/components/BbTimePicker/BbTimePicker.vue.js +6 -0
- package/dist/components/BbTimePicker/BbTimePicker.vue_vue_type_script_setup_true_lang.js +244 -0
- package/dist/components/BbTimePicker/types.d.ts +133 -0
- package/dist/components/BbTimePickerInput/BbTimePickerInput.vue.d.ts +25 -0
- package/dist/components/BbTimePickerInput/BbTimePickerInput.vue.js +6 -0
- package/dist/components/BbTimePickerInput/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +157 -0
- package/dist/components/BbTimePickerInput/types.d.ts +174 -0
- package/dist/components/BbToast/BbToast.vue.d.ts +2 -3
- package/dist/components/BbToast/BbToast.vue.js +6 -0
- package/dist/components/BbToast/BbToast.vue_vue_type_script_setup_true_lang.js +39 -0
- package/dist/components/BbToast/BbToastMessage.vue.d.ts +17 -8
- package/dist/components/BbToast/BbToastMessage.vue.js +5 -0
- package/dist/components/BbToast/BbToastMessage.vue_vue_type_script_setup_true_lang.js +170 -0
- package/dist/components/BbToast/BbToastPortal.vue.d.ts +30 -0
- package/dist/components/BbToast/BbToastPortal.vue.js +5 -0
- package/dist/components/BbToast/BbToastPortal.vue_vue_type_script_setup_true_lang.js +19 -0
- package/dist/components/BbToast/BbToastRegion.vue.d.ts +8 -0
- package/dist/components/BbToast/BbToastRegion.vue.js +5 -0
- package/dist/components/BbToast/BbToastRegion.vue_vue_type_script_setup_true_lang.js +100 -0
- package/dist/components/BbToast/types.d.ts +69 -5
- package/dist/components/BbTooltip/BbTooltip.vue.d.ts +10 -3
- package/dist/components/BbTooltip/BbTooltip.vue.js +6 -0
- package/dist/components/BbTooltip/BbTooltip.vue_vue_type_script_setup_true_lang.js +160 -0
- package/dist/components/BbTooltip/types.d.ts +69 -11
- package/dist/components/BbTree/BbTree.vue.d.ts +28 -13
- package/dist/components/BbTree/BbTree.vue.js +6 -0
- package/dist/components/BbTree/BbTree.vue_vue_type_script_setup_true_lang.js +55 -0
- package/dist/components/BbTree/BbTreeLevel.vue.d.ts +19 -0
- package/dist/components/BbTree/BbTreeLevel.vue.js +5 -0
- package/dist/components/BbTree/BbTreeLevel.vue_vue_type_script_setup_true_lang.js +94 -0
- package/dist/components/BbTree/context.d.ts +17 -0
- package/dist/components/BbTree/context.js +4 -0
- package/dist/components/BbTree/types.d.ts +94 -41
- package/dist/components/ChipsBox/ChipsBox.vue.d.ts +2 -1
- package/dist/components/ChipsBox/ChipsBox.vue.js +5 -0
- package/dist/components/ChipsBox/ChipsBox.vue_vue_type_script_setup_true_lang.js +98 -0
- package/dist/components/ChipsBox/types.d.ts +12 -5
- package/dist/components/ClearableButton/ClearableButton.vue.d.ts +2 -1
- package/dist/components/ClearableButton/ClearableButton.vue.js +6 -0
- package/dist/components/ClearableButton/ClearableButton.vue_vue_type_script_setup_true_lang.js +19 -0
- package/dist/components/ClearableButton/types.d.ts +7 -1
- package/dist/components/CloseIcon/CloseButton.vue.d.ts +5 -0
- package/dist/components/CloseIcon/CloseButton.vue.js +7 -0
- package/dist/components/CloseIcon/CloseButton.vue_vue_type_script_setup_true_lang.js +23 -0
- package/dist/components/CloseIcon/types.d.ts +2 -0
- package/dist/components/CommaBox/CommaBox.vue.d.ts +2 -1
- package/dist/components/CommaBox/CommaBox.vue.js +6 -0
- package/dist/components/CommaBox/CommaBox.vue_vue_type_script_setup_true_lang.js +81 -0
- package/dist/components/CommaBox/types.d.ts +6 -7
- package/dist/components/CommonInputWrapper/CommonInputWrapper.vue.d.ts +19 -0
- package/dist/components/CommonInputWrapper/CommonInputWrapper.vue.js +6 -0
- package/dist/components/CommonInputWrapper/CommonInputWrapper.vue_vue_type_script_setup_true_lang.js +107 -0
- package/dist/components/CommonInputWrapper/types.d.ts +96 -0
- package/dist/components/CommonPopover/CommonPopover.vue.d.ts +9 -3
- package/dist/components/CommonPopover/CommonPopover.vue.js +6 -0
- package/dist/components/CommonPopover/CommonPopover.vue_vue_type_script_setup_true_lang.js +160 -0
- package/dist/components/CommonPopover/types.d.ts +65 -16
- package/dist/components/ErrorIcon/ErrorIcon.vue.d.ts +2 -0
- package/dist/components/ErrorIcon/ErrorIcon.vue.js +6 -0
- package/dist/components/ErrorIcon/ErrorIcon.vue_vue_type_script_setup_true_lang.js +16 -0
- package/dist/components/FlatListBox/FlatListBox.vue.d.ts +2 -5
- package/dist/components/FlatListBox/FlatListBox.vue.js +5 -0
- package/dist/components/FlatListBox/FlatListBox.vue_vue_type_script_setup_true_lang.js +167 -0
- package/dist/components/FlatListBox/types.d.ts +1 -1
- package/dist/components/GroupedListBox/GroupedListBox.vue.d.ts +2 -5
- package/dist/components/GroupedListBox/GroupedListBox.vue.js +5 -0
- package/dist/components/GroupedListBox/GroupedListBox.vue_vue_type_script_setup_true_lang.js +218 -0
- package/dist/components/ListBox/ListBox.vue.d.ts +3 -6
- package/dist/components/ListBox/ListBox.vue.js +5 -0
- package/dist/components/ListBox/ListBox.vue_vue_type_script_setup_true_lang.js +112 -0
- package/dist/components/ListBox/types.d.ts +1 -1
- package/dist/components/OptionsContainer/OptionsContainer.vue.d.ts +1 -0
- package/dist/components/OptionsContainer/OptionsContainer.vue.js +5 -0
- package/dist/components/OptionsContainer/OptionsContainer.vue_vue_type_script_setup_true_lang.js +52 -0
- package/dist/components/OptionsContainer/types.d.ts +14 -24
- package/dist/components/Transitions/ScaleFade.vue.d.ts +2 -2
- package/dist/components/Transitions/ScaleFade.vue.js +5 -0
- package/dist/components/Transitions/ScaleFade.vue_vue_type_script_setup_true_lang.js +47 -0
- package/dist/components/Transitions/Slide.vue.d.ts +15 -0
- package/dist/components/Transitions/Slide.vue.js +7 -0
- package/dist/components/Transitions/Slide.vue_vue_type_script_setup_true_lang.js +28 -0
- package/dist/components/WarningIcon/WarningIcon.vue.d.ts +5 -0
- package/dist/components/WarningIcon/WarningIcon.vue.js +6 -0
- package/dist/components/WarningIcon/WarningIcon.vue_vue_type_script_setup_true_lang.js +16 -0
- package/dist/components/WarningIcon/types.d.ts +3 -0
- package/dist/composables/__testResets.d.ts +1 -0
- package/dist/composables/useActiveInactiveState.d.ts +4 -0
- package/dist/composables/useActiveInactiveState.js +21 -0
- package/dist/composables/useBaseOptions.d.ts +3 -3
- package/dist/composables/useBaseOptions.js +31 -0
- package/dist/composables/useBbConfig.d.ts +8 -37
- package/dist/composables/useBbConfig.js +5 -0
- package/dist/composables/useBbDropdownContext.d.ts +89 -0
- package/dist/composables/useBbDropdownContext.js +46 -0
- package/dist/composables/useBbFormContext.d.ts +90 -0
- package/dist/composables/useBbFormContext.js +69 -0
- package/dist/composables/useBbTableContext.d.ts +195 -0
- package/dist/composables/useBbTableContext.js +208 -0
- package/dist/composables/useBbTabsContext.d.ts +111 -0
- package/dist/composables/useBbTabsContext.js +225 -0
- package/dist/composables/useBreakpoint.d.ts +13 -0
- package/dist/composables/useBreakpoint.js +39 -0
- package/dist/composables/useBroadcastChannelInstance.d.ts +1 -3
- package/dist/composables/useBroadcastChannelInstance.js +39 -0
- package/dist/composables/useCancelableFunction.js +37 -0
- package/dist/composables/useClosingInert.d.ts +28 -0
- package/dist/composables/useClosingInert.js +23 -0
- package/dist/composables/useCoherence.js +16 -0
- package/dist/composables/useConfirm.d.ts +278 -68
- package/dist/composables/useConfirm.js +130 -0
- package/dist/composables/useCountdown.js +42 -0
- package/dist/composables/useHashedWatcher.d.ts +17 -0
- package/dist/composables/useHashedWatcher.js +14 -0
- package/dist/composables/useId.d.ts +3 -2
- package/dist/composables/useIndexById.js +16 -0
- package/dist/composables/useInertiaPage.d.ts +10 -0
- package/dist/composables/useInertiaPage.js +8 -0
- package/dist/composables/useItemText.js +17 -0
- package/dist/composables/useItemValue.js +9 -0
- package/dist/composables/useItemsGetter.d.ts +1 -1
- package/dist/composables/useItemsGetter.js +30 -0
- package/dist/composables/useListboxFocus.js +66 -0
- package/dist/composables/useLocale.d.ts +1 -1
- package/dist/composables/useLocale.js +11 -0
- package/dist/composables/useLogger.d.ts +1 -1
- package/dist/composables/useLogger.js +10 -0
- package/dist/composables/useMinimalQueue.d.ts +1 -1
- package/dist/composables/useMobile.js +7 -0
- package/dist/composables/useOnFalsy.d.ts +2 -0
- package/dist/composables/useOnFalsy.js +9 -0
- package/dist/composables/useOnTruthy.d.ts +7 -0
- package/dist/composables/useOnTruthy.js +9 -0
- package/dist/composables/usePrefill.d.ts +2 -1
- package/dist/composables/usePrefill.js +24 -0
- package/dist/composables/useQuery.d.ts +15 -3
- package/dist/composables/useQuery.js +42 -0
- package/dist/composables/useRoute.js +11 -0
- package/dist/composables/useRouter.js +8 -0
- package/dist/composables/useSafeArea.d.ts +51 -0
- package/dist/composables/useSafeArea.js +16 -0
- package/dist/composables/useSegmentedFields.d.ts +104 -0
- package/dist/composables/useSegmentedFields.js +159 -0
- package/dist/composables/useTableWidthContext.d.ts +5 -0
- package/dist/composables/useTableWidthContext.js +42 -0
- package/dist/composables/useToast.d.ts +40 -70
- package/dist/composables/useToast.js +58 -0
- package/dist/composables/useTopLayer.d.ts +9 -0
- package/dist/composables/useTopLayer.js +7 -0
- package/dist/composables/useUntil.js +13 -0
- package/dist/composables/useViewportWidth.d.ts +17 -0
- package/dist/composables/useViewportWidth.js +6 -0
- package/dist/confirm-variants.d.ts +17 -0
- package/dist/deprecation/ai-deprecations.json.d.ts +784 -0
- package/dist/deprecation/ai-deprecations.json.js +4 -0
- package/dist/deprecation/removedProps.d.ts +3 -0
- package/dist/deprecation/removedProps.js +13 -0
- package/dist/directives/bbColor.d.ts +65 -0
- package/dist/directives/bbColor.js +24 -0
- package/dist/directives/bbDate.d.ts +66 -0
- package/dist/directives/bbDate.js +24 -0
- package/dist/directives/bbDropdown.d.ts +15 -11
- package/dist/directives/bbDropdown.js +23 -0
- package/dist/directives/bbTime.d.ts +64 -0
- package/dist/directives/bbTime.js +24 -0
- package/dist/directives/bbTooltip.d.ts +16 -11
- package/dist/directives/bbTooltip.js +24 -0
- package/dist/directives/createPopoverDirective.js +54 -0
- package/dist/dropdown-item-variants.d.ts +17 -0
- package/dist/i18n/index.d.ts +51 -3
- package/dist/i18n/index.js +27 -0
- package/dist/i18n/locales/cs.json +115 -0
- package/dist/i18n/locales/da.json +115 -0
- package/dist/i18n/locales/de.json +115 -0
- package/dist/i18n/locales/el.json +115 -0
- package/dist/i18n/locales/en.json +115 -0
- package/dist/i18n/locales/es.json +115 -0
- package/dist/i18n/locales/fi.json +115 -0
- package/dist/i18n/locales/fr.json +115 -0
- package/dist/i18n/locales/hu.json +115 -0
- package/dist/i18n/locales/it.json +115 -0
- package/dist/i18n/locales/ja.json +115 -0
- package/dist/i18n/locales/ko.json +115 -0
- package/dist/i18n/locales/nb.json +115 -0
- package/dist/i18n/locales/nl.json +115 -0
- package/dist/i18n/locales/pl.json +115 -0
- package/dist/i18n/locales/pt.json +115 -0
- package/dist/i18n/locales/ro.json +115 -0
- package/dist/i18n/locales/ru.json +115 -0
- package/dist/i18n/locales/sv.json +115 -0
- package/dist/i18n/locales/tr.json +115 -0
- package/dist/i18n/locales/uk.json +115 -0
- package/dist/i18n/locales/zh-cn.json +115 -0
- package/dist/icons-whitelist.d.ts +8 -0
- package/dist/index.d.ts +96 -79
- package/dist/index.js +76 -82
- package/dist/indicator-variants.d.ts +20 -0
- package/dist/llms-full.txt +79703 -0
- package/dist/llms-medium.txt +1514 -0
- package/dist/llms.txt +105 -0
- package/dist/locale-blueprint.json +141 -0
- package/dist/locale-registry.d.ts +37 -0
- package/dist/nuxt-module.d.ts +3 -0
- package/dist/nuxt.js +19 -0
- package/dist/plugin.d.ts +4 -0
- package/dist/plugin.js +22 -0
- package/dist/reset.css +1 -0
- package/dist/reset.d.ts +0 -0
- package/dist/runtime/nuxt-plugin.d.ts +2 -0
- package/dist/runtime/nuxt-plugin.js +24 -0
- package/dist/styles.css +2 -0
- package/dist/styles.d.ts +0 -0
- package/dist/toast-variants.d.ts +20 -0
- package/dist/tooltip-variants.d.ts +17 -0
- package/dist/types/ActionButton.d.ts +32 -0
- package/dist/types/AlertVariant.d.ts +16 -0
- package/dist/types/BadgeVariant.d.ts +16 -0
- package/dist/types/ButtonVariant.d.ts +17 -0
- package/dist/types/Classes.d.ts +1 -1
- package/dist/types/ColumnName.d.ts +1 -1
- package/dist/types/CommonProps.d.ts +68 -277
- package/dist/types/Config.d.ts +84 -0
- package/dist/types/ConfirmVariant.d.ts +15 -0
- package/dist/types/DropdownItemVariant.d.ts +18 -0
- package/dist/types/Icon.d.ts +5 -7
- package/dist/types/IndicatorVariant.d.ts +16 -0
- package/dist/types/InputDirection.d.ts +15 -0
- package/dist/types/ItemAccessor.d.ts +21 -0
- package/dist/types/Placement.d.ts +6 -0
- package/dist/types/ResponsiveSize.d.ts +20 -0
- package/dist/types/SizeScale.d.ts +8 -0
- package/dist/types/ToastVariant.d.ts +17 -0
- package/dist/types/TooltipVariant.d.ts +18 -0
- package/dist/utilities/functions/bytesToUnit.d.ts +2 -0
- package/dist/utilities/functions/bytesToUnit.js +18 -0
- package/dist/utilities/functions/clampPrecision.js +10 -0
- package/dist/utilities/functions/convertDateValue.d.ts +23 -10
- package/dist/utilities/functions/convertDateValue.js +12 -0
- package/dist/utilities/functions/deburr.js +5 -0
- package/dist/utilities/functions/empty.js +5 -0
- package/dist/utilities/functions/flattenTree.d.ts +1 -1
- package/dist/utilities/functions/hash.js +5 -0
- package/dist/utilities/functions/isDateDisabled.d.ts +1 -0
- package/dist/utilities/functions/isDateDisabled.js +20 -0
- package/dist/utilities/functions/isEqual.js +5 -0
- package/dist/utilities/functions/isNotEmpty.js +5 -0
- package/dist/utilities/functions/matchAnyKey.d.ts +1 -1
- package/dist/utilities/functions/matchAnyKey.js +15 -0
- package/dist/utilities/functions/parseSize.d.ts +1 -1
- package/dist/utilities/functions/parseSize.js +15 -0
- package/dist/utilities/functions/percentage.js +11 -0
- package/dist/utilities/functions/pipe.d.ts +1 -1
- package/dist/utilities/functions/reject.d.ts +25 -0
- package/dist/utilities/functions/reject.js +28 -0
- package/dist/utilities/functions/resolveEnumProp.d.ts +19 -0
- package/dist/utilities/functions/resolveEnumProp.js +5 -0
- package/dist/utilities/functions/slotKey.d.ts +13 -0
- package/dist/utilities/functions/slotKey.js +4 -0
- package/dist/utilities/functions/sort.d.ts +2 -2
- package/dist/utilities/functions/sort.js +19 -0
- package/dist/utilities/functions/throttle.js +5 -0
- package/dist/utilities/functions/waitFor.d.ts +9 -2
- package/dist/utilities/functions/waitFor.js +14 -0
- package/dist/utilities/functions/warnRemovedAttrs.d.ts +11 -0
- package/dist/utilities/functions/warnRemovedAttrs.js +20 -0
- package/dist/utilities/functions/when.js +5 -0
- package/dist/utilities/misc/iconsInjectionKey.d.ts +15 -0
- package/dist/utilities/misc/iconsInjectionKey.js +4 -0
- package/dist/utilities/misc/transitions.d.ts +5 -0
- package/dist/utilities/misc/transitions.js +8 -0
- package/dist/utils/injectLibraryStyles.d.ts +6 -0
- package/dist/utils/injectLibraryStyles.js +38 -0
- package/dist/validated/BbCheckbox.vue.d.ts +29 -0
- package/dist/validated/BbCheckbox.vue.js +5 -0
- package/dist/validated/BbCheckbox.vue_vue_type_script_setup_true_lang.js +75 -0
- package/dist/validated/BbCheckboxGroup.vue.d.ts +34 -0
- package/dist/validated/BbCheckboxGroup.vue.js +5 -0
- package/dist/validated/BbCheckboxGroup.vue_vue_type_script_setup_true_lang.js +82 -0
- package/dist/validated/BbColorInput.vue.d.ts +36 -0
- package/dist/validated/BbColorInput.vue.js +5 -0
- package/dist/validated/BbColorInput.vue_vue_type_script_setup_true_lang.js +71 -0
- package/dist/validated/BbDatePickerInput.vue.d.ts +41 -0
- package/dist/validated/BbDatePickerInput.vue.js +5 -0
- package/dist/validated/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +90 -0
- package/dist/validated/BbDropzone.vue.d.ts +24 -0
- package/dist/validated/BbDropzone.vue.js +5 -0
- package/dist/validated/BbDropzone.vue_vue_type_script_setup_true_lang.js +45 -0
- package/dist/validated/BbForm.vue.d.ts +28 -0
- package/dist/validated/BbForm.vue.js +5 -0
- package/dist/validated/BbForm.vue_vue_type_script_setup_true_lang.js +42 -0
- package/dist/validated/BbNumberInput.vue.d.ts +36 -0
- package/dist/validated/BbNumberInput.vue.js +5 -0
- package/dist/validated/BbNumberInput.vue_vue_type_script_setup_true_lang.js +72 -0
- package/dist/validated/BbRadioGroup.vue.d.ts +34 -0
- package/dist/validated/BbRadioGroup.vue.js +5 -0
- package/dist/validated/BbRadioGroup.vue_vue_type_script_setup_true_lang.js +78 -0
- package/dist/validated/BbRating.vue.d.ts +30 -0
- package/dist/validated/BbRating.vue.js +5 -0
- package/dist/validated/BbRating.vue_vue_type_script_setup_true_lang.js +63 -0
- package/dist/validated/BbSelect.vue.d.ts +46 -0
- package/dist/validated/BbSelect.vue.js +5 -0
- package/dist/validated/BbSelect.vue_vue_type_script_setup_true_lang.js +109 -0
- package/dist/validated/BbSlider.vue.d.ts +36 -0
- package/dist/validated/BbSlider.vue.js +5 -0
- package/dist/validated/BbSlider.vue_vue_type_script_setup_true_lang.js +69 -0
- package/dist/validated/BbSwitch.vue.d.ts +29 -0
- package/dist/validated/BbSwitch.vue.js +5 -0
- package/dist/validated/BbSwitch.vue_vue_type_script_setup_true_lang.js +75 -0
- package/dist/validated/BbSwitchGroup.vue.d.ts +34 -0
- package/dist/validated/BbSwitchGroup.vue.js +5 -0
- package/dist/validated/BbSwitchGroup.vue_vue_type_script_setup_true_lang.js +82 -0
- package/dist/validated/BbTag.vue.d.ts +36 -0
- package/dist/validated/BbTag.vue.js +5 -0
- package/dist/validated/BbTag.vue_vue_type_script_setup_true_lang.js +72 -0
- package/dist/validated/BbTextInput.vue.d.ts +36 -0
- package/dist/validated/BbTextInput.vue.js +5 -0
- package/dist/validated/BbTextInput.vue_vue_type_script_setup_true_lang.js +72 -0
- package/dist/validated/BbTextarea.vue.d.ts +36 -0
- package/dist/validated/BbTextarea.vue.js +5 -0
- package/dist/validated/BbTextarea.vue_vue_type_script_setup_true_lang.js +70 -0
- package/dist/validated/BbTimePickerInput.vue.d.ts +37 -0
- package/dist/validated/BbTimePickerInput.vue.js +5 -0
- package/dist/validated/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +81 -0
- package/dist/validated/index.d.ts +29 -0
- package/dist/validated/useValidatedField.d.ts +93 -0
- package/dist/validated/useValidatedField.js +51 -0
- package/dist/validated.js +21 -0
- package/dist/vite-plugin.d.ts +261 -0
- package/dist/vite.js +603 -0
- package/llms.txt +107 -0
- package/package.json +181 -60
- package/scripts/lib/__fixtures__/validated-manifest.json +65 -0
- package/scripts/lib/ensure-manifest.mjs +39 -0
- package/scripts/lib/eslint-plugin-autofix.node.test.mjs +109 -0
- package/scripts/lib/eslint-plugin-recommended.node.test.mjs +87 -0
- package/scripts/lib/eslint-plugin-slots.node.test.mjs +271 -0
- package/scripts/lib/eslint-plugin.mjs +702 -0
- package/scripts/lib/eslint-plugin.node.test.mjs +193 -0
- package/scripts/lib/html-attributes.mjs +191 -0
- package/scripts/lib/mcp-config.mjs +126 -0
- package/scripts/lib/migrate-fix.mjs +115 -0
- package/scripts/lib/validate-bb-markup.mjs +488 -0
- package/dist/ai/BaseButton.md +0 -449
- package/dist/ai/BaseCheckbox.md +0 -512
- package/dist/ai/BaseCheckboxGroup.md +0 -597
- package/dist/ai/BaseColorInput.md +0 -461
- package/dist/ai/BaseDatePicker.md +0 -739
- package/dist/ai/BaseDatePickerInput.md +0 -1517
- package/dist/ai/BaseDialog.md +0 -610
- package/dist/ai/BaseInputContainer.md +0 -570
- package/dist/ai/BaseNumberInput.md +0 -509
- package/dist/ai/BaseRadio.md +0 -405
- package/dist/ai/BaseRadioGroup.md +0 -535
- package/dist/ai/BaseRating.md +0 -489
- package/dist/ai/BaseSelect.md +0 -1742
- package/dist/ai/BaseSlider.md +0 -871
- package/dist/ai/BaseSwitch.md +0 -322
- package/dist/ai/BaseSwitchGroup.md +0 -298
- package/dist/ai/BaseTag.md +0 -623
- package/dist/ai/BaseTextInput.md +0 -392
- package/dist/ai/BaseTextarea.md +0 -398
- package/dist/ai/BbChip.md +0 -147
- package/dist/ai/BbIntersection.md +0 -120
- package/dist/ai/BbRatio.md +0 -61
- package/dist/ai/BbRows.md +0 -307
- package/dist/ai/BbTab.md +0 -950
- package/dist/ai/CommonInputInnerContainer.md +0 -414
- package/dist/ai/CommonInputOuterContainer.md +0 -55
- package/dist/components/BaseButton/BaseButton.vue.d.ts +0 -14
- package/dist/components/BaseButton/types.d.ts +0 -159
- package/dist/components/BaseCheckbox/BaseCheckbox.vue.d.ts +0 -39
- package/dist/components/BaseCheckbox/types.d.ts +0 -213
- package/dist/components/BaseCheckboxGroup/BaseCheckboxGroup.vue.d.ts +0 -30
- package/dist/components/BaseCheckboxGroup/types.d.ts +0 -282
- package/dist/components/BaseColorInput/BaseColorInput.vue.d.ts +0 -35
- package/dist/components/BaseColorInput/ColorPalette.vue.d.ts +0 -13
- package/dist/components/BaseColorInput/types.d.ts +0 -233
- package/dist/components/BaseDatePicker/BaseDatePickerHeader.vue.d.ts +0 -15
- package/dist/components/BaseDatePicker/BaseDatePickerInputDaySelector.vue.d.ts +0 -58
- package/dist/components/BaseDatePicker/BaseDatePickerMonthSelector.vue.d.ts +0 -12
- package/dist/components/BaseDatePicker/BaseDatePickerYearSelector.vue.d.ts +0 -12
- package/dist/components/BaseDatePicker/types.d.ts +0 -100
- package/dist/components/BaseDatePickerInput/BaseDatePickerInput.vue.d.ts +0 -26
- package/dist/components/BaseDatePickerInput/types.d.ts +0 -206
- package/dist/components/BaseDialog/BaseDialog.vue.d.ts +0 -37
- package/dist/components/BaseDialog/types.d.ts +0 -180
- package/dist/components/BaseInputContainer/BaseInputContainer.vue.d.ts +0 -18
- package/dist/components/BaseInputContainer/types.d.ts +0 -126
- package/dist/components/BaseNumberInput/BaseNumberInput.vue.d.ts +0 -46
- package/dist/components/BaseNumberInput/types.d.ts +0 -191
- package/dist/components/BaseRadio/BaseRadio.vue.d.ts +0 -31
- package/dist/components/BaseRadio/types.d.ts +0 -173
- package/dist/components/BaseRadioGroup/BaseRadioGroup.vue.d.ts +0 -30
- package/dist/components/BaseRadioGroup/types.d.ts +0 -240
- package/dist/components/BaseRating/BaseRating.vue.d.ts +0 -35
- package/dist/components/BaseRating/types.d.ts +0 -144
- package/dist/components/BaseSelect/BaseSelect.vue.d.ts +0 -28
- package/dist/components/BaseSelect/types.d.ts +0 -470
- package/dist/components/BaseSlider/BaseSlider.vue.d.ts +0 -38
- package/dist/components/BaseSlider/types.d.ts +0 -201
- package/dist/components/BaseSwitch/BaseSwitch.vue.d.ts +0 -34
- package/dist/components/BaseSwitch/types.d.ts +0 -25
- package/dist/components/BaseSwitchGroup/BaseSwitchGroup.vue.d.ts +0 -30
- package/dist/components/BaseSwitchGroup/types.d.ts +0 -8
- package/dist/components/BaseTag/BaseTag.vue.d.ts +0 -37
- package/dist/components/BaseTag/types.d.ts +0 -136
- package/dist/components/BaseTextInput/BaseTextInput.vue.d.ts +0 -33
- package/dist/components/BaseTextInput/types.d.ts +0 -166
- package/dist/components/BaseTextarea/BaseTextarea.vue.d.ts +0 -31
- package/dist/components/BaseTextarea/types.d.ts +0 -151
- package/dist/components/BbChip/BbChip.vue.d.ts +0 -17
- package/dist/components/BbChip/types.d.ts +0 -23
- package/dist/components/BbIntersection/BbIntersection.vue.d.ts +0 -23
- package/dist/components/BbIntersection/types.d.ts +0 -36
- package/dist/components/BbRatio/BbRatio.vue.d.ts +0 -14
- package/dist/components/BbRatio/types.d.ts +0 -15
- package/dist/components/BbRows/BbRows.vue.d.ts +0 -62
- package/dist/components/BbRows/types.d.ts +0 -21
- package/dist/components/BbTab/BbTab.vue.d.ts +0 -27
- package/dist/components/BbTab/types.d.ts +0 -186
- package/dist/components/CommonInputInnerContainer/CommonInputInnerContainer.vue.d.ts +0 -15
- package/dist/components/CommonInputInnerContainer/types.d.ts +0 -47
- package/dist/components/CommonInputOuterContainer/CommonInputOuterContainer.vue.d.ts +0 -11
- package/dist/components/CommonInputOuterContainer/types.d.ts +0 -16
- package/dist/composables/useModalsState.d.ts +0 -5
- package/dist/composables/useQueue.d.ts +0 -58
- package/dist/composables/useWizard.d.ts +0 -85
- package/dist/i18n/en.d.ts +0 -67
- package/dist/i18n/it.d.ts +0 -67
- package/dist/index.css +0 -2
- package/dist/index100.js +0 -6
- package/dist/index101.js +0 -300
- package/dist/index102.js +0 -16
- package/dist/index103.js +0 -16
- package/dist/index104.js +0 -27
- package/dist/index109.js +0 -19
- package/dist/index11.js +0 -42
- package/dist/index110.js +0 -12
- package/dist/index111.js +0 -19
- package/dist/index112.js +0 -25
- package/dist/index114.js +0 -7
- package/dist/index115.js +0 -241
- package/dist/index116.js +0 -5
- package/dist/index117.js +0 -42
- package/dist/index118.js +0 -5
- package/dist/index119.js +0 -53
- package/dist/index120.js +0 -5
- package/dist/index121.js +0 -32
- package/dist/index122.js +0 -5
- package/dist/index124.js +0 -52
- package/dist/index125.js +0 -5
- package/dist/index126.js +0 -223
- package/dist/index128.js +0 -6
- package/dist/index129.js +0 -162
- package/dist/index13.js +0 -92
- package/dist/index130.js +0 -25
- package/dist/index131.js +0 -51
- package/dist/index132.js +0 -5
- package/dist/index133.js +0 -607
- package/dist/index135.js +0 -6
- package/dist/index136.js +0 -14
- package/dist/index137.js +0 -153
- package/dist/index139.js +0 -6
- package/dist/index14.js +0 -306
- package/dist/index140.js +0 -224
- package/dist/index141.js +0 -5
- package/dist/index143.js +0 -128
- package/dist/index145.js +0 -6
- package/dist/index146.js +0 -8
- package/dist/index147.js +0 -182
- package/dist/index149.js +0 -6
- package/dist/index15.js +0 -10
- package/dist/index151.js +0 -4
- package/dist/index152.js +0 -95
- package/dist/index154.js +0 -6
- package/dist/index155.js +0 -168
- package/dist/index157.js +0 -6
- package/dist/index158.js +0 -145
- package/dist/index16.js +0 -59
- package/dist/index160.js +0 -6
- package/dist/index161.js +0 -53
- package/dist/index163.js +0 -6
- package/dist/index164.js +0 -16
- package/dist/index166.js +0 -35
- package/dist/index168.js +0 -6
- package/dist/index169.js +0 -89
- package/dist/index171.js +0 -6
- package/dist/index172.js +0 -82
- package/dist/index174.js +0 -6
- package/dist/index175.js +0 -38
- package/dist/index176.js +0 -461
- package/dist/index177.js +0 -28
- package/dist/index178.js +0 -66
- package/dist/index18.js +0 -35
- package/dist/index180.js +0 -162
- package/dist/index181.js +0 -5
- package/dist/index182.js +0 -217
- package/dist/index183.js +0 -5
- package/dist/index184.js +0 -112
- package/dist/index185.js +0 -5
- package/dist/index186.js +0 -459
- package/dist/index188.js +0 -6
- package/dist/index19.js +0 -4
- package/dist/index192.js +0 -268
- package/dist/index194.js +0 -6
- package/dist/index195.js +0 -124
- package/dist/index197.js +0 -6
- package/dist/index198.js +0 -174
- package/dist/index2.js +0 -20
- package/dist/index20.js +0 -9
- package/dist/index200.js +0 -6
- package/dist/index201.js +0 -224
- package/dist/index203.js +0 -6
- package/dist/index204.js +0 -135
- package/dist/index206.js +0 -6
- package/dist/index207.js +0 -5
- package/dist/index208.js +0 -170
- package/dist/index21.js +0 -35
- package/dist/index210.js +0 -6
- package/dist/index211.js +0 -37
- package/dist/index213.js +0 -6
- package/dist/index214.js +0 -63
- package/dist/index216.js +0 -6
- package/dist/index217.js +0 -74
- package/dist/index219.js +0 -6
- package/dist/index22.js +0 -6
- package/dist/index220.js +0 -65
- package/dist/index222.js +0 -6
- package/dist/index223.js +0 -67
- package/dist/index225.js +0 -6
- package/dist/index226.js +0 -41
- package/dist/index228.js +0 -6
- package/dist/index229.js +0 -10
- package/dist/index23.js +0 -7
- package/dist/index230.js +0 -22
- package/dist/index232.js +0 -8
- package/dist/index233.js +0 -297
- package/dist/index235.js +0 -6
- package/dist/index236.js +0 -47
- package/dist/index237.js +0 -165
- package/dist/index239.js +0 -6
- package/dist/index24.js +0 -9
- package/dist/index241.js +0 -159
- package/dist/index243.js +0 -6
- package/dist/index244.js +0 -134
- package/dist/index246.js +0 -6
- package/dist/index247.js +0 -167
- package/dist/index249.js +0 -6
- package/dist/index25.js +0 -24
- package/dist/index250.js +0 -147
- package/dist/index252.js +0 -6
- package/dist/index253.js +0 -35
- package/dist/index255.js +0 -6
- package/dist/index256.js +0 -65
- package/dist/index258.js +0 -6
- package/dist/index259.js +0 -19
- package/dist/index260.js +0 -5
- package/dist/index261.js +0 -160
- package/dist/index263.js +0 -6
- package/dist/index264.js +0 -60
- package/dist/index266.js +0 -6
- package/dist/index267.js +0 -134
- package/dist/index269.js +0 -6
- package/dist/index27.js +0 -4
- package/dist/index271.js +0 -206
- package/dist/index273.js +0 -6
- package/dist/index274.js +0 -85
- package/dist/index275.js +0 -5
- package/dist/index276.js +0 -55
- package/dist/index277.js +0 -5
- package/dist/index278.js +0 -164
- package/dist/index28.js +0 -8
- package/dist/index280.js +0 -6
- package/dist/index281.js +0 -145
- package/dist/index283.js +0 -6
- package/dist/index284.js +0 -11
- package/dist/index285.js +0 -200
- package/dist/index287.js +0 -6
- package/dist/index288.js +0 -241
- package/dist/index29.js +0 -7
- package/dist/index290.js +0 -6
- package/dist/index291.js +0 -21
- package/dist/index293.js +0 -6
- package/dist/index294.js +0 -125
- package/dist/index296.js +0 -6
- package/dist/index297.js +0 -161
- package/dist/index299.js +0 -6
- package/dist/index30.js +0 -118
- package/dist/index300.js +0 -127
- package/dist/index302.js +0 -6
- package/dist/index303.js +0 -20
- package/dist/index305.js +0 -6
- package/dist/index306.js +0 -116
- package/dist/index307.js +0 -5
- package/dist/index308.js +0 -507
- package/dist/index31.js +0 -10
- package/dist/index310.js +0 -6
- package/dist/index311.js +0 -196
- package/dist/index313.js +0 -6
- package/dist/index314.js +0 -142
- package/dist/index316.js +0 -6
- package/dist/index317.js +0 -134
- package/dist/index319.js +0 -6
- package/dist/index32.js +0 -28
- package/dist/index320.js +0 -162
- package/dist/index322.js +0 -6
- package/dist/index323.js +0 -319
- package/dist/index325.js +0 -6
- package/dist/index326.js +0 -40
- package/dist/index327.js +0 -43
- package/dist/index328.js +0 -665
- package/dist/index33.js +0 -5
- package/dist/index330.js +0 -6
- package/dist/index331.js +0 -155
- package/dist/index333.js +0 -6
- package/dist/index334.js +0 -142
- package/dist/index336.js +0 -6
- package/dist/index337.js +0 -155
- package/dist/index339.js +0 -6
- package/dist/index34.js +0 -112
- package/dist/index340.js +0 -58
- package/dist/index341.js +0 -5
- package/dist/index342.js +0 -20
- package/dist/index344.js +0 -6
- package/dist/index345.js +0 -142
- package/dist/index347.js +0 -6
- package/dist/index349.js +0 -109
- package/dist/index351.js +0 -6
- package/dist/index352.js +0 -55
- package/dist/index353.js +0 -24
- package/dist/index354.js +0 -23
- package/dist/index355.js +0 -839
- package/dist/index356.js +0 -474
- package/dist/index357.js +0 -52
- package/dist/index358.js +0 -7
- package/dist/index36.js +0 -6
- package/dist/index38.js +0 -63
- package/dist/index39.js +0 -63
- package/dist/index40.js +0 -9
- package/dist/index42.js +0 -8
- package/dist/index43.js +0 -179
- package/dist/index44.js +0 -21
- package/dist/index46.js +0 -385
- package/dist/index48.js +0 -6
- package/dist/index49.js +0 -33
- package/dist/index5.js +0 -34
- package/dist/index50.js +0 -12
- package/dist/index51.js +0 -8
- package/dist/index52.js +0 -106
- package/dist/index53.js +0 -330
- package/dist/index54.js +0 -97
- package/dist/index55.js +0 -328
- package/dist/index56.js +0 -28
- package/dist/index57.js +0 -102
- package/dist/index58.js +0 -157
- package/dist/index6.js +0 -38
- package/dist/index60.js +0 -6
- package/dist/index61.js +0 -131
- package/dist/index62.js +0 -5
- package/dist/index65.js +0 -35
- package/dist/index66.js +0 -26
- package/dist/index68.js +0 -6
- package/dist/index69.js +0 -54
- package/dist/index7.js +0 -58
- package/dist/index71.js +0 -6
- package/dist/index72.js +0 -14
- package/dist/index74.js +0 -6
- package/dist/index75.js +0 -159
- package/dist/index77.js +0 -6
- package/dist/index78.js +0 -4
- package/dist/index79.js +0 -4
- package/dist/index80.js +0 -54
- package/dist/index81.js +0 -5
- package/dist/index82.js +0 -5
- package/dist/index83.js +0 -141
- package/dist/index85.js +0 -6
- package/dist/index86.js +0 -65
- package/dist/index88.js +0 -6
- package/dist/index89.js +0 -30
- package/dist/index9.js +0 -11
- package/dist/index90.js +0 -19
- package/dist/index91.js +0 -17
- package/dist/index92.js +0 -9
- package/dist/index93.js +0 -34
- package/dist/index95.js +0 -16
- package/dist/index96.js +0 -10
- package/dist/index97.js +0 -18
- package/dist/index98.js +0 -189
- package/dist/types/VoidHtmlElements.d.ts +0 -1
- package/dist/utilities/functions/add.d.ts +0 -1
- package/dist/utilities/functions/booleanishToBoolean.d.ts +0 -6
- package/dist/utilities/functions/capitalize.d.ts +0 -4
- package/dist/utilities/functions/cloneDeep.d.ts +0 -1
- package/dist/utilities/functions/debounce.d.ts +0 -1
- package/dist/utilities/functions/drop.d.ts +0 -1
- package/dist/utilities/functions/exceedsPrecision.d.ts +0 -1
- package/dist/utilities/functions/findRight.d.ts +0 -4
- package/dist/utilities/functions/findRightIndex.d.ts +0 -4
- package/dist/utilities/functions/flow.d.ts +0 -1
- package/dist/utilities/functions/getHueFromRGB.d.ts +0 -9
- package/dist/utilities/functions/groupBy.d.ts +0 -6
- package/dist/utilities/functions/gt.d.ts +0 -7
- package/dist/utilities/functions/hexToRGB.d.ts +0 -7
- package/dist/utilities/functions/hslToHex.d.ts +0 -1
- package/dist/utilities/functions/includes.d.ts +0 -1
- package/dist/utilities/functions/initial.d.ts +0 -1
- package/dist/utilities/functions/isCssColor.d.ts +0 -5
- package/dist/utilities/functions/lt.d.ts +0 -7
- package/dist/utilities/functions/makeUrl.d.ts +0 -1
- package/dist/utilities/functions/mapKeys.d.ts +0 -5
- package/dist/utilities/functions/mapValues.d.ts +0 -1
- package/dist/utilities/functions/matchesPropertyInsensitive.d.ts +0 -1
- package/dist/utilities/functions/max.d.ts +0 -2
- package/dist/utilities/functions/mean.d.ts +0 -4
- package/dist/utilities/functions/merge.d.ts +0 -11
- package/dist/utilities/functions/millisecondsTo.d.ts +0 -1
- package/dist/utilities/functions/negate.d.ts +0 -4
- package/dist/utilities/functions/normalizeItemGroups.d.ts +0 -13
- package/dist/utilities/functions/omit.d.ts +0 -2
- package/dist/utilities/functions/overEvery.d.ts +0 -4
- package/dist/utilities/functions/pick.d.ts +0 -1
- package/dist/utilities/functions/replace.d.ts +0 -1
- package/dist/utilities/functions/replaceInTree.d.ts +0 -4
- package/dist/utilities/functions/retry.d.ts +0 -5
- package/dist/utilities/functions/roundToTheNearest.d.ts +0 -8
- package/dist/utilities/functions/set.d.ts +0 -15
- package/dist/utilities/functions/stub.d.ts +0 -6
- package/dist/utilities/functions/transposePercent.d.ts +0 -9
- package/dist/utilities/functions/tryTo.d.ts +0 -2
- package/dist/utilities/functions/uniqBy.d.ts +0 -1
- /package/dist/{index64.js → _virtual/_plugin-vue_export-helper.js} +0 -0
- /package/dist/components/{BaseButton → BbBaseButton}/RouterComponent.vue.d.ts +0 -0
- /package/dist/components/{BaseDatePicker/BaseDatePicker.vue.d.ts → BbBaseDatePicker/BbBaseDatePicker.vue.d.ts} +0 -0
- /package/dist/{index165.js → composables/useArray.js} +0 -0
- /package/dist/{index17.js → composables/useFrameworkDetection.js} +0 -0
- /package/dist/{index12.js → composables/useId.js} +0 -0
- /package/dist/{index107.js → utilities/functions/chunk.js} +0 -0
- /package/dist/{index8.js → utilities/functions/clamp.js} +0 -0
- /package/dist/{index150.js → utilities/functions/curry.js} +0 -0
- /package/dist/{index45.js → utilities/functions/extractDomContainer.js} +0 -0
- /package/dist/{index270.js → utilities/functions/findInTree.js} +0 -0
- /package/dist/{index348.js → utilities/functions/flattenTree.js} +0 -0
- /package/dist/{index41.js → utilities/functions/get.js} +0 -0
- /package/dist/{index189.js → utilities/functions/head.js} +0 -0
- /package/dist/{index108.js → utilities/functions/identity.js} +0 -0
- /package/dist/{index179.js → utilities/functions/indexBy.js} +0 -0
- /package/dist/{index37.js → utilities/functions/isHex.js} +0 -0
- /package/dist/{index94.js → utilities/functions/isNil.js} +0 -0
- /package/dist/{index26.js → utilities/functions/isNotNil.js} +0 -0
- /package/dist/{index105.js → utilities/functions/last.js} +0 -0
- /package/dist/{index142.js → utilities/functions/noop.js} +0 -0
- /package/dist/{index231.js → utilities/functions/parseWidthString.js} +0 -0
- /package/dist/{index240.js → utilities/functions/pickBy.js} +0 -0
- /package/dist/{index123.js → utilities/functions/range.js} +0 -0
- /package/dist/{index190.js → utilities/functions/snapToStep.js} +0 -0
- /package/dist/{index191.js → utilities/functions/transpose.js} +0 -0
- /package/dist/{index106.js → utilities/functions/validateDateFormat.js} +0 -0
- /package/dist/{index10.js → utilities/functions/wait.js} +0 -0
|
@@ -0,0 +1,2234 @@
|
|
|
1
|
+
# BbSelectPopover — Implementation Source
|
|
2
|
+
|
|
3
|
+
> Full implementation for deep dives. For everyday usage read the typed contract: [../BbSelectPopover.md](../BbSelectPopover.md).
|
|
4
|
+
|
|
5
|
+
## Template & Script
|
|
6
|
+
|
|
7
|
+
```vue
|
|
8
|
+
<template>
|
|
9
|
+
<slot
|
|
10
|
+
v-if="!hasExternalActivator"
|
|
11
|
+
name="activator"
|
|
12
|
+
v-bind="{
|
|
13
|
+
props: {
|
|
14
|
+
ref: setActivatorRef,
|
|
15
|
+
},
|
|
16
|
+
shown,
|
|
17
|
+
disabled,
|
|
18
|
+
readonly,
|
|
19
|
+
loading: computedLoading,
|
|
20
|
+
query,
|
|
21
|
+
selectedOptions: publicSelectedOptions,
|
|
22
|
+
text: triggerInputValue,
|
|
23
|
+
clear: onClear,
|
|
24
|
+
focus: focusPopoverContent,
|
|
25
|
+
open,
|
|
26
|
+
close,
|
|
27
|
+
toggle,
|
|
28
|
+
}"
|
|
29
|
+
/>
|
|
30
|
+
|
|
31
|
+
<!-- The search field and the options list are authored once here and reused in
|
|
32
|
+
both surfaces below, so the desktop popover and the mobile off-canvas share the
|
|
33
|
+
exact same markup, refs and event wiring. -->
|
|
34
|
+
<DefineSearch>
|
|
35
|
+
<div
|
|
36
|
+
v-if="computedAllowWriting"
|
|
37
|
+
class="bb-select-popover__search-container"
|
|
38
|
+
>
|
|
39
|
+
<input
|
|
40
|
+
:id="`${id}_search`"
|
|
41
|
+
ref="searchInput"
|
|
42
|
+
v-model="query"
|
|
43
|
+
:aria-activedescendant="activeDescendantId"
|
|
44
|
+
:aria-controls="renderListBox ? `${id}_listbox` : undefined"
|
|
45
|
+
:aria-describedby="computedAriaDescribedby"
|
|
46
|
+
:aria-invalid="computedAriaInvalid"
|
|
47
|
+
:aria-label="searchInputAriaLabel"
|
|
48
|
+
:autocomplete="autocomplete"
|
|
49
|
+
class="bb-select-popover__search-input"
|
|
50
|
+
:inputmode="inputmode"
|
|
51
|
+
role="searchbox"
|
|
52
|
+
:tabindex="shown ? 0 : -1"
|
|
53
|
+
type="text"
|
|
54
|
+
@blur.stop="onSearchInputBlur"
|
|
55
|
+
@change.stop="onSearchInputChange"
|
|
56
|
+
@focus.stop="onSearchInputFocus"
|
|
57
|
+
@input.stop="onSearchInputInput"
|
|
58
|
+
@keydown.stop.prevent.down="onArrowDown"
|
|
59
|
+
@keydown.stop.prevent.enter="onEnter"
|
|
60
|
+
@keydown.stop.prevent.esc="onEscape"
|
|
61
|
+
@keydown.stop.prevent.up="onArrowUp"
|
|
62
|
+
/>
|
|
63
|
+
<ErrorIcon
|
|
64
|
+
aria-hidden="true"
|
|
65
|
+
class="bb-select-popover__search-error-icon"
|
|
66
|
+
focusable="false"
|
|
67
|
+
/>
|
|
68
|
+
<WarningIcon
|
|
69
|
+
aria-hidden="true"
|
|
70
|
+
class="bb-select-popover__search-warning-icon"
|
|
71
|
+
focusable="false"
|
|
72
|
+
/>
|
|
73
|
+
<BbIcon
|
|
74
|
+
aria-hidden="true"
|
|
75
|
+
class="bb-select-popover__search-icon"
|
|
76
|
+
focusable="false"
|
|
77
|
+
:icon="searchIcon"
|
|
78
|
+
/>
|
|
79
|
+
<!-- Clearable: the clear button shares the lens' slot in the icon
|
|
80
|
+
stack. At rest the lens shows; hovering or focusing the search field
|
|
81
|
+
swaps it for the clear (index.css), but only while there is something
|
|
82
|
+
to clear (`--clearable-active`). It resets both the query and the
|
|
83
|
+
selection; `@mousedown.prevent` keeps focus in the field so the swap
|
|
84
|
+
doesn't collapse mid-click. Reuses the shared ClearableButton so the
|
|
85
|
+
icon, aria-label fallback and focus ring match every other clear in
|
|
86
|
+
the library. -->
|
|
87
|
+
<ClearableButton
|
|
88
|
+
v-if="clearable"
|
|
89
|
+
class="bb-select-popover__search-clear"
|
|
90
|
+
:tabindex="hasClearableValue && shown ? 0 : -1"
|
|
91
|
+
@click.stop="onSearchClear"
|
|
92
|
+
@mousedown.prevent
|
|
93
|
+
/>
|
|
94
|
+
<!-- Overlays the search field's bottom border while a re-fetch runs over
|
|
95
|
+
an existing result set — matches BbDropdown's searchable groups. -->
|
|
96
|
+
<div
|
|
97
|
+
v-if="isReloading"
|
|
98
|
+
aria-hidden="true"
|
|
99
|
+
class="bb-select-popover__search-strip"
|
|
100
|
+
></div>
|
|
101
|
+
</div>
|
|
102
|
+
<button
|
|
103
|
+
v-else
|
|
104
|
+
ref="popoverFocusProxy"
|
|
105
|
+
:aria-activedescendant="activeDescendantId"
|
|
106
|
+
:aria-controls="`${id}_listbox`"
|
|
107
|
+
:aria-describedby="computedAriaDescribedby"
|
|
108
|
+
aria-expanded="true"
|
|
109
|
+
:aria-invalid="computedAriaInvalid"
|
|
110
|
+
:aria-label="searchInputAriaLabel"
|
|
111
|
+
class="bb-select-popover__focus-proxy sr-only"
|
|
112
|
+
role="combobox"
|
|
113
|
+
tabindex="-1"
|
|
114
|
+
type="button"
|
|
115
|
+
@focus="onPopoverFocusProxyFocus"
|
|
116
|
+
@keydown.stop.prevent.down="onArrowDown"
|
|
117
|
+
@keydown.stop.prevent.enter="onEnter"
|
|
118
|
+
@keydown.stop.prevent.esc="onEscape"
|
|
119
|
+
@keydown.stop.prevent.up="onArrowUp"
|
|
120
|
+
></button>
|
|
121
|
+
</DefineSearch>
|
|
122
|
+
|
|
123
|
+
<DefineOptions>
|
|
124
|
+
<ListBox
|
|
125
|
+
:id="`${id}_listbox`"
|
|
126
|
+
ref="optionsContainer"
|
|
127
|
+
:compact="compact"
|
|
128
|
+
:groups="groupBy ? groupedOptions : undefined"
|
|
129
|
+
:header-height="headerHeight"
|
|
130
|
+
:loading="computedLoading"
|
|
131
|
+
:loading-text="loadingText"
|
|
132
|
+
:multiple="multiple"
|
|
133
|
+
:no-data-text="computedNoDataText"
|
|
134
|
+
:open="shown"
|
|
135
|
+
:option-height="itemHeight"
|
|
136
|
+
:options="groupBy ? undefined : filteredOptions"
|
|
137
|
+
@focused:change="onListboxFocusedChange"
|
|
138
|
+
@option:selected="onOptionSelected"
|
|
139
|
+
@option:unselected="onOptionUnselected"
|
|
140
|
+
>
|
|
141
|
+
<template #loading><slot name="loading" :query="query" /></template>
|
|
142
|
+
<template #no-data
|
|
143
|
+
><slot :focus="focusPopoverContent" name="no-data" :query="query"
|
|
144
|
+
/></template>
|
|
145
|
+
<template #option="data"
|
|
146
|
+
><slot :loading="computedLoading" name="option" v-bind="data"
|
|
147
|
+
/></template>
|
|
148
|
+
<template #group="data"><slot name="group" v-bind="data" /></template>
|
|
149
|
+
</ListBox>
|
|
150
|
+
</DefineOptions>
|
|
151
|
+
|
|
152
|
+
<!-- Mobile adaptive surface: a bottom sheet that reuses the search + options
|
|
153
|
+
verbatim and adds a dedicated representation of the current selection (chips for
|
|
154
|
+
multiple, the selected label for single) between them. -->
|
|
155
|
+
<BbOffCanvas
|
|
156
|
+
v-if="useOffcanvas"
|
|
157
|
+
v-model="shown"
|
|
158
|
+
class="bb-select-popover-offcanvas"
|
|
159
|
+
v-bind="{ ...offcanvasBindings, ...$attrs }"
|
|
160
|
+
@hidden="onOffcanvasHidden"
|
|
161
|
+
>
|
|
162
|
+
<template v-if="$slots.header" #header>
|
|
163
|
+
<slot name="header" v-bind="panelSlotProps" />
|
|
164
|
+
</template>
|
|
165
|
+
<div
|
|
166
|
+
class="bb-select-popover bb-select-popover--sheet"
|
|
167
|
+
:class="{
|
|
168
|
+
'bb-select-popover--errors': hasErrors,
|
|
169
|
+
'bb-select-popover--warnings': showWarning,
|
|
170
|
+
'bb-select-popover--loading': computedLoading,
|
|
171
|
+
'bb-select-popover--reloading': isReloading,
|
|
172
|
+
'bb-select-popover--clearable-active': hasClearableValue,
|
|
173
|
+
}"
|
|
174
|
+
>
|
|
175
|
+
<!-- Current selection sits above the search: chips for multiple (as in the
|
|
176
|
+
control), a plain label for single. Hidden entirely when nothing is picked. -->
|
|
177
|
+
<div
|
|
178
|
+
v-if="selectedOptions.length"
|
|
179
|
+
class="bb-select-popover__sheet-selection"
|
|
180
|
+
>
|
|
181
|
+
<div class="bb-select-popover__sheet-chips">
|
|
182
|
+
<!-- One badge per selection: removable (clearable) unless the
|
|
183
|
+
control is disabled/readonly. -->
|
|
184
|
+
<BbBadge
|
|
185
|
+
v-for="option in selectedOptions"
|
|
186
|
+
:key="option.valueHash"
|
|
187
|
+
class="bb-select-popover__sheet-chip"
|
|
188
|
+
:clearable="!disabled && !readonly"
|
|
189
|
+
size="xl"
|
|
190
|
+
variant="secondary"
|
|
191
|
+
@click:clear="onOptionUnselected(option)"
|
|
192
|
+
>{{ option.text }}</BbBadge
|
|
193
|
+
>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
|
|
197
|
+
<ReuseSearch />
|
|
198
|
+
<BbSmoothHeight>
|
|
199
|
+
<ReuseOptions />
|
|
200
|
+
</BbSmoothHeight>
|
|
201
|
+
</div>
|
|
202
|
+
<template v-if="$slots.footer" #footer>
|
|
203
|
+
<slot name="footer" v-bind="panelSlotProps" />
|
|
204
|
+
</template>
|
|
205
|
+
</BbOffCanvas>
|
|
206
|
+
|
|
207
|
+
<!-- `tag="span"`: this popover is BbBaseSelect's root, so it mounts inside
|
|
208
|
+
BbBaseInputContainer's inline input wrapper, which only accepts phrasing
|
|
209
|
+
content. Positioning is unaffected — the wrapper is `position: fixed`. -->
|
|
210
|
+
<CommonPopover
|
|
211
|
+
v-else
|
|
212
|
+
v-model="shown"
|
|
213
|
+
:anchor="positionAnchorEl"
|
|
214
|
+
:boundary="boundary"
|
|
215
|
+
class="bb-select-popover"
|
|
216
|
+
:class="{
|
|
217
|
+
'bb-select-popover--errors': hasErrors,
|
|
218
|
+
'bb-select-popover--warnings': showWarning,
|
|
219
|
+
'bb-select-popover--loading': computedLoading,
|
|
220
|
+
'bb-select-popover--reloading': isReloading,
|
|
221
|
+
'bb-select-popover--clearable-active': hasClearableValue,
|
|
222
|
+
}"
|
|
223
|
+
:disable-flip="disableFlip"
|
|
224
|
+
hide-arrow
|
|
225
|
+
:offset="offset"
|
|
226
|
+
:padding="padding"
|
|
227
|
+
:placement="placement"
|
|
228
|
+
:style="panelStyles"
|
|
229
|
+
tag="span"
|
|
230
|
+
:transition-duration="transitionDuration"
|
|
231
|
+
v-bind="$attrs"
|
|
232
|
+
>
|
|
233
|
+
<div
|
|
234
|
+
v-if="$slots.header"
|
|
235
|
+
class="bb-select-popover__header"
|
|
236
|
+
:inert="panelChromeInert"
|
|
237
|
+
>
|
|
238
|
+
<slot name="header" v-bind="panelSlotProps" />
|
|
239
|
+
</div>
|
|
240
|
+
<ReuseSearch />
|
|
241
|
+
<ReuseOptions />
|
|
242
|
+
<div
|
|
243
|
+
v-if="$slots.footer"
|
|
244
|
+
class="bb-select-popover__footer"
|
|
245
|
+
:inert="panelChromeInert"
|
|
246
|
+
>
|
|
247
|
+
<slot name="footer" v-bind="panelSlotProps" />
|
|
248
|
+
</div>
|
|
249
|
+
</CommonPopover>
|
|
250
|
+
</template>
|
|
251
|
+
|
|
252
|
+
<script setup lang="ts" generic="Item = any">
|
|
253
|
+
import type { Option as BaseOption, GroupedOptions } from '@/types/Option';
|
|
254
|
+
import {
|
|
255
|
+
computed,
|
|
256
|
+
ref,
|
|
257
|
+
nextTick,
|
|
258
|
+
watch,
|
|
259
|
+
onBeforeMount,
|
|
260
|
+
onBeforeUnmount,
|
|
261
|
+
} from 'vue';
|
|
262
|
+
import { extractDomContainer } from '@/utilities/functions/extractDomContainer';
|
|
263
|
+
import { get } from '@/utilities/functions/get';
|
|
264
|
+
import { hash } from '@/utilities/functions/hash';
|
|
265
|
+
import { useLogger } from '@/composables/useLogger';
|
|
266
|
+
import { isNil } from '@/utilities/functions/isNil';
|
|
267
|
+
import { matchAnyKey } from '@/utilities/functions/matchAnyKey';
|
|
268
|
+
import { parseWidthString } from '@/utilities/functions/parseWidthString';
|
|
269
|
+
import { toRef } from 'vue';
|
|
270
|
+
import { useArray } from '@/composables/useArray';
|
|
271
|
+
import { useBaseOptions } from '@/composables/useBaseOptions';
|
|
272
|
+
import { useCoherence } from '@/composables/useCoherence';
|
|
273
|
+
import {
|
|
274
|
+
createReusableTemplate,
|
|
275
|
+
useElementSize,
|
|
276
|
+
useIntersectionObserver,
|
|
277
|
+
} from '@vueuse/core';
|
|
278
|
+
import { useHashedWatcher } from '@/composables/useHashedWatcher';
|
|
279
|
+
import { useId } from '@/composables/useId';
|
|
280
|
+
import { useIndexById } from '@/composables/useIndexById';
|
|
281
|
+
import { useItemsGetter } from '@/composables/useItemsGetter';
|
|
282
|
+
import { useLocale } from '@/composables/useLocale';
|
|
283
|
+
import { useMobile } from '@/composables/useMobile';
|
|
284
|
+
import { usePrefill } from '@/composables/usePrefill';
|
|
285
|
+
import { config } from 'virtual:bitboss-ui/config';
|
|
286
|
+
import { useUntil } from '@/composables/useUntil';
|
|
287
|
+
import { useClosingInert } from '@/composables/useClosingInert';
|
|
288
|
+
import { wait } from '@/utilities/functions/wait';
|
|
289
|
+
import BbBadge from '../BbBadge/BbBadge.vue';
|
|
290
|
+
import BbIcon from '../BbIcon/BbIcon.vue';
|
|
291
|
+
import BbOffCanvas from '../BbOffCanvas/BbOffCanvas.vue';
|
|
292
|
+
import ClearableButton from '../ClearableButton/ClearableButton.vue';
|
|
293
|
+
import CommonPopover from '../CommonPopover/CommonPopover.vue';
|
|
294
|
+
import ErrorIcon from '../ErrorIcon/ErrorIcon.vue';
|
|
295
|
+
import WarningIcon from '../WarningIcon/WarningIcon.vue';
|
|
296
|
+
import searchIcon from '@/assets/svgs/search.svg?raw';
|
|
297
|
+
import ListBox from '../ListBox/ListBox.vue';
|
|
298
|
+
import { waitFor } from '@/utilities/functions/waitFor';
|
|
299
|
+
import type {
|
|
300
|
+
BbSelectPopoverEvents,
|
|
301
|
+
BbSelectPopoverProps,
|
|
302
|
+
BbSelectPopoverSlots,
|
|
303
|
+
BbSelectResolvedOption,
|
|
304
|
+
} from './types';
|
|
305
|
+
import BbSmoothHeight from '../BbSmoothHeight/BbSmoothHeight.vue';
|
|
306
|
+
import { transitions } from '@/utilities/misc/transitions';
|
|
307
|
+
import { removedPropsFor } from '@/deprecation/removedProps';
|
|
308
|
+
import { warnRemovedAttrs } from '@/utilities/functions/warnRemovedAttrs';
|
|
309
|
+
|
|
310
|
+
const props = withDefaults(defineProps<BbSelectPopoverProps<Item>>(), {
|
|
311
|
+
// `undefined` (declared, not omitted) keeps `adaptive` three-state: it disables
|
|
312
|
+
// Vue's absent→`false` Boolean cast so `props.adaptive ?? config.adaptive` can
|
|
313
|
+
// reach the config default, while keeping the Boolean type so the valueless
|
|
314
|
+
// `adaptive` shorthand still resolves to `true`.
|
|
315
|
+
adaptive: undefined,
|
|
316
|
+
anchor: null,
|
|
317
|
+
// Same three-state trap as `adaptive`: without this, Vue's absent→`false`
|
|
318
|
+
// Boolean cast made `props.ariaInvalid ?? !!props.hasErrors` short-circuit on
|
|
319
|
+
// `false`, so the documented hasErrors fallback never fired and an errored
|
|
320
|
+
// searchbox never announced `aria-invalid`.
|
|
321
|
+
ariaInvalid: undefined,
|
|
322
|
+
autocomplete: 'off',
|
|
323
|
+
depsDebounceTime: 0,
|
|
324
|
+
dependencies: () => [],
|
|
325
|
+
filterBy: () => [],
|
|
326
|
+
max: Infinity,
|
|
327
|
+
modelValueDebounceTime: 0,
|
|
328
|
+
offset: 4,
|
|
329
|
+
padding: 10,
|
|
330
|
+
placement: 'bottom',
|
|
331
|
+
prefill: 'interaction',
|
|
332
|
+
queryDebounceTime: 500,
|
|
333
|
+
selectable: true,
|
|
334
|
+
transitionDuration: transitions.medium,
|
|
335
|
+
width: '200',
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
const emit = defineEmits<BbSelectPopoverEvents>();
|
|
339
|
+
|
|
340
|
+
defineSlots<BbSelectPopoverSlots<Item>>();
|
|
341
|
+
|
|
342
|
+
if (process.env.NODE_ENV !== 'production')
|
|
343
|
+
warnRemovedAttrs('BbSelectPopover', removedPropsFor('BbSelectPopover'));
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Author the search field and the options list once, replay them in both the
|
|
347
|
+
* desktop popover and the mobile sheet. `ReuseSearch`/`ReuseOptions` render the
|
|
348
|
+
* captured markup inline (with the component's own refs, slots and handlers), so
|
|
349
|
+
* only ever one live instance exists at a time — the branch that is mounted.
|
|
350
|
+
*/
|
|
351
|
+
const [DefineSearch, ReuseSearch] = createReusableTemplate();
|
|
352
|
+
const [DefineOptions, ReuseOptions] = createReusableTemplate();
|
|
353
|
+
|
|
354
|
+
// Guard in `onBeforeMount` (not the setup body): the dev error still throws
|
|
355
|
+
// synchronously during mount, but letting setup finish first means Vue never
|
|
356
|
+
// attempts the partial render of an errored instance whose `<script setup>`
|
|
357
|
+
// bindings (component imports, reusable-template handles) are all undefined —
|
|
358
|
+
// which would otherwise log spurious "Invalid vnode type: undefined" warnings.
|
|
359
|
+
onBeforeMount(() => {
|
|
360
|
+
if (props.multiple && !Array.isArray(props.modelValue)) {
|
|
361
|
+
useLogger().throw(
|
|
362
|
+
`BbSelectPopover: \`multiple\` requires an array modelValue, received ${
|
|
363
|
+
props.modelValue === null ? 'null' : typeof props.modelValue
|
|
364
|
+
}. Seed it with \`[]\` for an empty selection — \`null\`/\`undefined\` are not accepted, ` +
|
|
365
|
+
'because a multi-select with no array has no way to express "nothing selected" separately from "not ready".'
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* START ELEMENT REFERENCES
|
|
372
|
+
*/
|
|
373
|
+
const activatorEl = ref<HTMLElement>();
|
|
374
|
+
const optionsContainer = ref<any | null>(null);
|
|
375
|
+
const searchInput = ref<HTMLInputElement | null>(null);
|
|
376
|
+
const popoverFocusProxy = ref<HTMLButtonElement | null>(null);
|
|
377
|
+
const activeDescendantId = ref<string>();
|
|
378
|
+
|
|
379
|
+
const positionAnchorEl = computed<HTMLElement | undefined>(() => {
|
|
380
|
+
if (props.anchor) {
|
|
381
|
+
const el = extractDomContainer(props.anchor);
|
|
382
|
+
if (el) return el;
|
|
383
|
+
}
|
|
384
|
+
return activatorEl.value;
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
const { width: activatorWidth } = useElementSize(
|
|
388
|
+
positionAnchorEl,
|
|
389
|
+
{ width: 0, height: 0 },
|
|
390
|
+
{
|
|
391
|
+
box: 'border-box',
|
|
392
|
+
}
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* END ELEMENT REFERENCES
|
|
397
|
+
*/
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* START ACTIVATOR MANAGEMENT
|
|
401
|
+
*/
|
|
402
|
+
const hasExternalActivator = computed(() => props.activator != null);
|
|
403
|
+
|
|
404
|
+
const setActivatorRef = (reference: unknown) => {
|
|
405
|
+
const el = extractDomContainer(reference);
|
|
406
|
+
if (!el) return;
|
|
407
|
+
activatorEl.value = el;
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
watch(
|
|
411
|
+
() => props.activator,
|
|
412
|
+
(val) => {
|
|
413
|
+
if (val) setActivatorRef(val);
|
|
414
|
+
},
|
|
415
|
+
{ immediate: true }
|
|
416
|
+
);
|
|
417
|
+
/**
|
|
418
|
+
* END ACTIVATOR MANAGEMENT
|
|
419
|
+
*/
|
|
420
|
+
|
|
421
|
+
const { isMobile } = useMobile();
|
|
422
|
+
const computedAllowWriting = computed(() => {
|
|
423
|
+
if (props.disableWriting === 'mobile') return !isMobile.value;
|
|
424
|
+
if (props.disableWriting === 'desktop') return isMobile.value;
|
|
425
|
+
return !props.disableWriting;
|
|
426
|
+
});
|
|
427
|
+
const inputmode = computed(() =>
|
|
428
|
+
(props.disableWriting === 'mobile' && isMobile.value) ||
|
|
429
|
+
(props.disableWriting === 'desktop' && !isMobile.value)
|
|
430
|
+
? 'none'
|
|
431
|
+
: undefined
|
|
432
|
+
);
|
|
433
|
+
const { t } = useLocale();
|
|
434
|
+
const searchInputAriaLabel = computed(
|
|
435
|
+
() => props.searchInputAriaLabel ?? t('select.searchLabel').value
|
|
436
|
+
);
|
|
437
|
+
// The in-search clear affordance only lights up when there is something to
|
|
438
|
+
// clear — a typed query or an actual selection — so an empty clearable popover
|
|
439
|
+
// keeps showing the lens. `--clearable-active` (below) is what CSS keys the
|
|
440
|
+
// lens→clear swap off; the button itself is always rendered when `clearable`
|
|
441
|
+
// so the fade has an element to transition.
|
|
442
|
+
const hasClearableValue = computed(
|
|
443
|
+
() =>
|
|
444
|
+
!!props.clearable &&
|
|
445
|
+
(query.value.length > 0 ||
|
|
446
|
+
(props.multiple
|
|
447
|
+
? Array.isArray(props.modelValue) && props.modelValue.length > 0
|
|
448
|
+
: !isNil(props.modelValue)))
|
|
449
|
+
);
|
|
450
|
+
|
|
451
|
+
const id = props.id || useId().id.value;
|
|
452
|
+
const computedAriaInvalid = computed(() => {
|
|
453
|
+
const isInvalid = props.ariaInvalid ?? !!props.hasErrors;
|
|
454
|
+
return isInvalid ? 'true' : undefined;
|
|
455
|
+
});
|
|
456
|
+
const computedAriaDescribedby = computed(() => {
|
|
457
|
+
const describedBy = props.ariaDescribedby;
|
|
458
|
+
if (Array.isArray(describedBy)) {
|
|
459
|
+
const normalized = describedBy
|
|
460
|
+
.map((value) => value.trim())
|
|
461
|
+
.filter(Boolean)
|
|
462
|
+
.join(' ');
|
|
463
|
+
return normalized || undefined;
|
|
464
|
+
}
|
|
465
|
+
if (typeof describedBy === 'string') {
|
|
466
|
+
const normalized = describedBy.trim();
|
|
467
|
+
return normalized || undefined;
|
|
468
|
+
}
|
|
469
|
+
return undefined;
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
const { resume, pause } = useIntersectionObserver(
|
|
473
|
+
activatorEl,
|
|
474
|
+
async ([{ intersectionRatio }]) => {
|
|
475
|
+
if (intersectionRatio !== 1 && shown.value) {
|
|
476
|
+
await close();
|
|
477
|
+
}
|
|
478
|
+
},
|
|
479
|
+
{ threshold: [0, 1], immediate: false }
|
|
480
|
+
);
|
|
481
|
+
|
|
482
|
+
const normalizedWidth = computed(() => {
|
|
483
|
+
if (props.width === 'auto') return 'auto';
|
|
484
|
+
if (props.width == null || props.width === '') {
|
|
485
|
+
return activatorWidth.value ? `${activatorWidth.value}px` : '320px';
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
try {
|
|
489
|
+
const { value, unit } = parseWidthString(props.width);
|
|
490
|
+
if (unit === '%') {
|
|
491
|
+
if (!activatorWidth.value) return '320px';
|
|
492
|
+
return `${activatorWidth.value * (value / 100)}px`;
|
|
493
|
+
}
|
|
494
|
+
return `${value}${unit}`;
|
|
495
|
+
} catch {
|
|
496
|
+
if (typeof props.width === 'string') return props.width.trim();
|
|
497
|
+
return activatorWidth.value ? `${activatorWidth.value}px` : '320px';
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
const panelStyles = computed(() => ({
|
|
502
|
+
'--w': normalizedWidth.value,
|
|
503
|
+
}));
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* START FOCUS HELPERS
|
|
507
|
+
*/
|
|
508
|
+
const focusActivator = () => {
|
|
509
|
+
activatorEl.value?.focus();
|
|
510
|
+
};
|
|
511
|
+
const focusSearchInput = () => {
|
|
512
|
+
if (searchInput.value instanceof HTMLInputElement) {
|
|
513
|
+
searchInput.value.focus();
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
const focusPopoverFocusProxy = () => {
|
|
517
|
+
if (popoverFocusProxy.value instanceof HTMLButtonElement) {
|
|
518
|
+
popoverFocusProxy.value.focus();
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
const focusPopoverContent = () => {
|
|
522
|
+
if (computedAllowWriting.value) {
|
|
523
|
+
focusSearchInput();
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
focusPopoverFocusProxy();
|
|
527
|
+
};
|
|
528
|
+
/**
|
|
529
|
+
* END FOCUS HELPERS
|
|
530
|
+
*/
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Search input focus keeps the whole control in active state.
|
|
534
|
+
*/
|
|
535
|
+
const onSearchInputFocus = (event: FocusEvent) => {
|
|
536
|
+
emit('focus', event);
|
|
537
|
+
setActive();
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
const onSearchInputBlur = (event: FocusEvent) => {
|
|
541
|
+
emit('blur', event);
|
|
542
|
+
syncActiveStateOnBlur();
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
const onSearchInputChange = (event: Event) => {
|
|
546
|
+
emit('change', event);
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
const onPopoverFocusProxyFocus = (_event: FocusEvent) => {
|
|
550
|
+
setActive();
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Search on user typing inside the popover search field.
|
|
555
|
+
*/
|
|
556
|
+
const onSearchInputInput = (event: Event) => {
|
|
557
|
+
emit('input', event);
|
|
558
|
+
// A user search is a first load like any other, so unlock `canLoad` — without
|
|
559
|
+
// this a search-first instance (whose `prefill` trigger is false by design)
|
|
560
|
+
// would never engage its dependency/model watchers, and results would go stale
|
|
561
|
+
// the moment a dependency changed. Marked on dispatch rather than completion:
|
|
562
|
+
// `debouncedGetter`'s superseded calls resolve too (VueUse settles them with
|
|
563
|
+
// `undefined` when `rejectOnCancel` is off), so awaiting it cannot tell a real
|
|
564
|
+
// load from a debounced-away keystroke. No-op in every other prefill mode,
|
|
565
|
+
// where opening has already prefilled.
|
|
566
|
+
markPrefilled();
|
|
567
|
+
debouncedGetter(query.value, false, props.modelValue);
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
const onListboxFocusedChange = (id: string | undefined) => {
|
|
571
|
+
activeDescendantId.value = id;
|
|
572
|
+
};
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* On click outside of the activator and popover, close the panel and remove active state.
|
|
576
|
+
*/
|
|
577
|
+
const onOutsideInteraction = async (event: Event) => {
|
|
578
|
+
const target =
|
|
579
|
+
event.target instanceof Element
|
|
580
|
+
? event.target
|
|
581
|
+
: event.target instanceof Text
|
|
582
|
+
? event.target.parentElement
|
|
583
|
+
: null;
|
|
584
|
+
if (!target) return;
|
|
585
|
+
const insideActivator = positionAnchorEl.value?.contains(target);
|
|
586
|
+
const insidePopover = !!target.closest('.bb-common-popover');
|
|
587
|
+
if (insideActivator || insidePopover) return;
|
|
588
|
+
const label =
|
|
589
|
+
target instanceof HTMLLabelElement ? target : target.closest('label');
|
|
590
|
+
if (label?.control && positionAnchorEl.value?.contains(label.control)) return;
|
|
591
|
+
await close();
|
|
592
|
+
setInactive();
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
const canProcessKeyboardBindings = computed(() => {
|
|
596
|
+
if (props.readonly) return false;
|
|
597
|
+
if (props.disabled) return false;
|
|
598
|
+
if (computedLoading.value) return false;
|
|
599
|
+
return true;
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* On first open the listbox is lazily mounted.
|
|
604
|
+
* Wait a few micro-cycles so imperative focus calls don't no-op.
|
|
605
|
+
*/
|
|
606
|
+
const waitForOptionsContainer = async () =>
|
|
607
|
+
waitFor(() => !!optionsContainer.value, { interval: 100 });
|
|
608
|
+
|
|
609
|
+
const focusFirstSelectedOption = () => {
|
|
610
|
+
const firstSelected = selectedOptions.value[0];
|
|
611
|
+
if (firstSelected?.valueHash) {
|
|
612
|
+
optionsContainer.value?.focusByHash(firstSelected.valueHash);
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
optionsContainer.value?.focusFirstSelected();
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
const focusLastSelectedOption = () => {
|
|
619
|
+
const lastSelected = selectedOptions.value[selectedOptions.value.length - 1];
|
|
620
|
+
if (lastSelected?.valueHash) {
|
|
621
|
+
optionsContainer.value?.focusByHash(lastSelected.valueHash);
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
optionsContainer.value?.focusLastSelected();
|
|
625
|
+
};
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* On arrow up:
|
|
629
|
+
* When the panel is open — focus on the previous option
|
|
630
|
+
* When the panel is closed — open and focus on the last selected option
|
|
631
|
+
*/
|
|
632
|
+
const onArrowUp = async () => {
|
|
633
|
+
if (!canProcessKeyboardBindings.value) return;
|
|
634
|
+
if (shown.value) {
|
|
635
|
+
optionsContainer.value?.focusPrevious();
|
|
636
|
+
} else {
|
|
637
|
+
await open({ focusPopoverContent: false });
|
|
638
|
+
await waitForOptionsContainer();
|
|
639
|
+
await wait(props.transitionDuration);
|
|
640
|
+
focusLastSelectedOption();
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
|
|
644
|
+
const onArrowDown = async () => {
|
|
645
|
+
if (!canProcessKeyboardBindings.value) return;
|
|
646
|
+
if (shown.value) {
|
|
647
|
+
optionsContainer.value?.focusNext();
|
|
648
|
+
} else {
|
|
649
|
+
await open({ focusPopoverContent: false });
|
|
650
|
+
await waitForOptionsContainer();
|
|
651
|
+
await wait(props.transitionDuration);
|
|
652
|
+
focusFirstSelectedOption();
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
|
|
656
|
+
const onEnter = async () => {
|
|
657
|
+
if (!canProcessKeyboardBindings.value) {
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
if (!shown.value) {
|
|
661
|
+
await open({ focusPopoverContent: false });
|
|
662
|
+
await waitForOptionsContainer();
|
|
663
|
+
await wait(props.transitionDuration);
|
|
664
|
+
if (selectedOptions.value.length) {
|
|
665
|
+
focusFirstSelectedOption();
|
|
666
|
+
} else if (computedAllowWriting.value) {
|
|
667
|
+
focusSearchInput();
|
|
668
|
+
} else {
|
|
669
|
+
focusPopoverFocusProxy();
|
|
670
|
+
}
|
|
671
|
+
return;
|
|
672
|
+
} else if (optionsContainer.value?.getHighlighted()) {
|
|
673
|
+
optionsContainer.value.confirmOption();
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
if (!computedAllowWriting.value) return;
|
|
677
|
+
const text = query.value.trim();
|
|
678
|
+
if (isItemSelected(text)) return;
|
|
679
|
+
emit('option:add', text);
|
|
680
|
+
query.value = '';
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
const onEscape = async () => {
|
|
684
|
+
if (shown.value) {
|
|
685
|
+
await close();
|
|
686
|
+
focusActivator();
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
const query = ref<string>('');
|
|
691
|
+
const hasInteracted = ref(false);
|
|
692
|
+
|
|
693
|
+
const {
|
|
694
|
+
getter,
|
|
695
|
+
debouncedGetter,
|
|
696
|
+
items: internalItems,
|
|
697
|
+
loading,
|
|
698
|
+
} = useItemsGetter({
|
|
699
|
+
items: toRef(props, 'items'),
|
|
700
|
+
debounce: props.queryDebounceTime,
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
const {
|
|
704
|
+
array: innerStash,
|
|
705
|
+
add: addToStash,
|
|
706
|
+
remove: removeFromStash,
|
|
707
|
+
set: setStash,
|
|
708
|
+
} = useArray<BaseOption>();
|
|
709
|
+
|
|
710
|
+
/** Whether the model currently holds anything (an empty model is always coherent). */
|
|
711
|
+
const hasModelValue = computed(() =>
|
|
712
|
+
props.multiple
|
|
713
|
+
? !!(props.modelValue as unknown[])?.length
|
|
714
|
+
: !isNil(props.modelValue)
|
|
715
|
+
);
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Search-first: the user must type before anything is fetched — opening the
|
|
719
|
+
* panel alone does not. Only for a *provider* with `prefill: false`, writing
|
|
720
|
+
* allowed and an empty model, because each of those is what makes deferring
|
|
721
|
+
* safe: an array costs no network (E1 rule 1), a seeded model needs its text
|
|
722
|
+
* resolved to render (and `BbBaseSelect` already forces `prefill: true` for it),
|
|
723
|
+
* and with writing disabled the search field is hidden — so a load the user
|
|
724
|
+
* cannot trigger would leave them staring at an empty panel forever.
|
|
725
|
+
*/
|
|
726
|
+
const isSearchFirst = computed(
|
|
727
|
+
() =>
|
|
728
|
+
props.prefill === false &&
|
|
729
|
+
!Array.isArray(props.items) &&
|
|
730
|
+
computedAllowWriting.value &&
|
|
731
|
+
!hasModelValue.value
|
|
732
|
+
);
|
|
733
|
+
|
|
734
|
+
/** The hint replaces "no data" only while nothing has been searched for yet. */
|
|
735
|
+
const computedNoDataText = computed(() =>
|
|
736
|
+
isSearchFirst.value && !query.value
|
|
737
|
+
? t('select.searchToStart').value
|
|
738
|
+
: props.noDataText
|
|
739
|
+
);
|
|
740
|
+
|
|
741
|
+
const {
|
|
742
|
+
hasPrefilled,
|
|
743
|
+
isPrefilling,
|
|
744
|
+
canLoad,
|
|
745
|
+
prefill: prefillItems,
|
|
746
|
+
markPrefilled,
|
|
747
|
+
} = usePrefill({
|
|
748
|
+
trigger: computed(
|
|
749
|
+
() =>
|
|
750
|
+
// Array `items` are never lazy: there is no request to defer, so waiting
|
|
751
|
+
// buys nothing and costs correctness — the selection stays unresolved
|
|
752
|
+
// (empty `text`/`selectedOptions`) and coherence cannot run. Resolving
|
|
753
|
+
// costs no network, so do it now regardless of `prefill`.
|
|
754
|
+
Array.isArray(props.items) ||
|
|
755
|
+
props.prefill === true ||
|
|
756
|
+
// Opting into `enforce-coherence` with a seeded model is a request to
|
|
757
|
+
// validate it, which is impossible without options — so load. An empty
|
|
758
|
+
// model needs no check and stays lazy.
|
|
759
|
+
(props.enforceCoherence && hasModelValue.value) ||
|
|
760
|
+
(props.prefill === 'interaction' && hasInteracted.value)
|
|
761
|
+
),
|
|
762
|
+
currentValue: undefined,
|
|
763
|
+
multiple: false,
|
|
764
|
+
fn: async (isPrefill) => {
|
|
765
|
+
await getter(query.value, isPrefill, props.modelValue);
|
|
766
|
+
if (props.stash) {
|
|
767
|
+
// Stash only the *selected* options this load resolved — the pre-seeded
|
|
768
|
+
// model items that happen to be in the fetch — so they stay resolvable
|
|
769
|
+
// when a later search/dependency no longer returns them. Stashing every
|
|
770
|
+
// fetched option (the previous behavior) hoarded rows the user never
|
|
771
|
+
// picked and contradicted `stash`'s own contract ("accumulate selected
|
|
772
|
+
// values across searches").
|
|
773
|
+
addToStash(...options.value.filter((o) => o.selected).map((o) => o.item));
|
|
774
|
+
}
|
|
775
|
+
// The first load is a load: check now rather than waiting for some later
|
|
776
|
+
// change. Without this the two watchers below only ever fire on a *change*,
|
|
777
|
+
// so a seeded-but-invalid model would survive until something else moved.
|
|
778
|
+
if (props.enforceCoherence && !coherent.value) {
|
|
779
|
+
emit('update:modelValue', coherentValue.value);
|
|
780
|
+
}
|
|
781
|
+
},
|
|
782
|
+
});
|
|
783
|
+
|
|
784
|
+
const { data: modelValueIndexedByHash, get: isItemSelected } = useIndexById({
|
|
785
|
+
items: computed(() => [].concat(props.modelValue)),
|
|
786
|
+
});
|
|
787
|
+
|
|
788
|
+
const { options } = useBaseOptions({
|
|
789
|
+
disabled: toRef(props, 'disabled'),
|
|
790
|
+
items: computed(() => [...internalItems.value, ...innerStash.value]),
|
|
791
|
+
itemText: props.itemText,
|
|
792
|
+
itemValue: props.itemValue,
|
|
793
|
+
max: props.max,
|
|
794
|
+
selectable: toRef(props, 'selectable'),
|
|
795
|
+
selectedIndexedByHash: modelValueIndexedByHash,
|
|
796
|
+
});
|
|
797
|
+
|
|
798
|
+
const { data: optionsIndexedByHash } = useIndexById({
|
|
799
|
+
items: options,
|
|
800
|
+
key: 'valueHash',
|
|
801
|
+
});
|
|
802
|
+
|
|
803
|
+
const { coherent, coherentValue } = useCoherence({
|
|
804
|
+
modelValue: toRef(props, 'modelValue'),
|
|
805
|
+
multiple: props.multiple,
|
|
806
|
+
iteratee: (item) => !!optionsIndexedByHash.value[hash(item)],
|
|
807
|
+
});
|
|
808
|
+
|
|
809
|
+
const selectedOptions = computed<BaseOption[]>(() =>
|
|
810
|
+
([] as any[])
|
|
811
|
+
.concat(props.modelValue)
|
|
812
|
+
.map((v) => optionsIndexedByHash.value[hash(v)])
|
|
813
|
+
.filter(Boolean)
|
|
814
|
+
);
|
|
815
|
+
|
|
816
|
+
/**
|
|
817
|
+
* Explicit allowlist mapping the internal `Option` to the public shape handed to
|
|
818
|
+
* consumer slots (`activator`, `header`, `footer`). Picking fields by hand — as
|
|
819
|
+
* opposed to passing the raw option — keeps `valueHash` (and anything added to
|
|
820
|
+
* the internal option later) from leaking into the public contract, so callers
|
|
821
|
+
* can never come to depend on selection internals.
|
|
822
|
+
*/
|
|
823
|
+
const toPublicOption = (
|
|
824
|
+
option: BaseOption<Item>
|
|
825
|
+
): BbSelectResolvedOption<Item> => ({
|
|
826
|
+
item: option.item,
|
|
827
|
+
text: option.text,
|
|
828
|
+
value: option.value,
|
|
829
|
+
selected: option.selected ?? true,
|
|
830
|
+
disabled: option.disabled ?? false,
|
|
831
|
+
});
|
|
832
|
+
|
|
833
|
+
const publicSelectedOptions = computed<Array<BbSelectResolvedOption<Item>>>(
|
|
834
|
+
() => selectedOptions.value.map(toPublicOption)
|
|
835
|
+
);
|
|
836
|
+
|
|
837
|
+
const computedLoading = computed(() => !!(loading.value || props.loading));
|
|
838
|
+
/**
|
|
839
|
+
* A re-fetch running over an existing result set — the options stay on screen
|
|
840
|
+
* (faint, under a loading strip) instead of a spinner, matching BbDropdown's
|
|
841
|
+
* searchable groups. A first load (no options yet) shows the listbox's loading
|
|
842
|
+
* row instead.
|
|
843
|
+
*/
|
|
844
|
+
const isReloading = computed(
|
|
845
|
+
() => computedLoading.value && options.value.length > 0
|
|
846
|
+
);
|
|
847
|
+
const hasErrors = computed(() => !!props.hasErrors);
|
|
848
|
+
/** Warning chrome only when no error is claiming the same icon slot. */
|
|
849
|
+
const showWarning = computed(
|
|
850
|
+
() => Boolean(props.hasWarning) && !hasErrors.value
|
|
851
|
+
);
|
|
852
|
+
const triggerInputValue = computed(() => {
|
|
853
|
+
return (
|
|
854
|
+
selectedOptions.value
|
|
855
|
+
.map((option) => option.text)
|
|
856
|
+
.filter(Boolean)
|
|
857
|
+
.join(', ') || ''
|
|
858
|
+
);
|
|
859
|
+
});
|
|
860
|
+
|
|
861
|
+
useHashedWatcher(
|
|
862
|
+
() => props.modelValue,
|
|
863
|
+
async () => {
|
|
864
|
+
if (!canLoad.value) return;
|
|
865
|
+
if (!coherent.value) {
|
|
866
|
+
await getter(query.value, true, props.modelValue);
|
|
867
|
+
if (props.enforceCoherence) {
|
|
868
|
+
emit('update:modelValue', coherentValue.value);
|
|
869
|
+
optionsContainer.value?.blur();
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
},
|
|
873
|
+
{ debounce: props.modelValueDebounceTime }
|
|
874
|
+
);
|
|
875
|
+
useHashedWatcher(
|
|
876
|
+
() => [props.dependencies, props.items],
|
|
877
|
+
async () => {
|
|
878
|
+
if (!canLoad.value) return;
|
|
879
|
+
await getter(query.value, true, props.modelValue);
|
|
880
|
+
if (props.enforceCoherence && !coherent.value) {
|
|
881
|
+
emit('update:modelValue', coherentValue.value);
|
|
882
|
+
optionsContainer.value?.blur();
|
|
883
|
+
}
|
|
884
|
+
},
|
|
885
|
+
{ debounce: props.depsDebounceTime }
|
|
886
|
+
);
|
|
887
|
+
|
|
888
|
+
const onOptionSelected = async (option: BaseOption) => {
|
|
889
|
+
if (props.multiple) {
|
|
890
|
+
emit('update:modelValue', props.modelValue.concat(option.value));
|
|
891
|
+
if (props.stash) {
|
|
892
|
+
addToStash(option.item);
|
|
893
|
+
}
|
|
894
|
+
} else {
|
|
895
|
+
if (props.stash) {
|
|
896
|
+
setStash(option.item);
|
|
897
|
+
}
|
|
898
|
+
emit('update:modelValue', option.value);
|
|
899
|
+
await nextTick();
|
|
900
|
+
}
|
|
901
|
+
if (props.multiple && computedAllowWriting.value && shown.value) {
|
|
902
|
+
focusSearchInput();
|
|
903
|
+
} else {
|
|
904
|
+
focusActivator();
|
|
905
|
+
}
|
|
906
|
+
if (!props.multiple) {
|
|
907
|
+
close();
|
|
908
|
+
}
|
|
909
|
+
};
|
|
910
|
+
|
|
911
|
+
const onOptionUnselected = async (option: BaseOption) => {
|
|
912
|
+
// Single select: clicking the option that is already selected is not a
|
|
913
|
+
// request to empty the field — it picks what is already picked, so the panel
|
|
914
|
+
// simply closes on the value it has. Emptying is an explicit affordance (the
|
|
915
|
+
// clear button, or the `clear` callback on the activator/panel slots), never
|
|
916
|
+
// an accidental second click. Multiple mode still toggles: there, unselecting
|
|
917
|
+
// by clicking is the whole interaction.
|
|
918
|
+
if (!props.multiple) {
|
|
919
|
+
focusActivator();
|
|
920
|
+
close();
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
removeFromStash((o) => o.valueHash !== option.valueHash);
|
|
925
|
+
const copy = { ...modelValueIndexedByHash.value };
|
|
926
|
+
delete copy[option.valueHash];
|
|
927
|
+
emit('update:modelValue', Object.values(copy));
|
|
928
|
+
|
|
929
|
+
if (computedAllowWriting.value && shown.value) {
|
|
930
|
+
focusSearchInput();
|
|
931
|
+
} else {
|
|
932
|
+
focusActivator();
|
|
933
|
+
}
|
|
934
|
+
};
|
|
935
|
+
|
|
936
|
+
/**
|
|
937
|
+
* Filter options based on the current query.
|
|
938
|
+
*/
|
|
939
|
+
const filteredOptions = computed<Array<BaseOption<Item>>>(() => {
|
|
940
|
+
if (!query.value) return options.value;
|
|
941
|
+
if (!props.multiple) {
|
|
942
|
+
const queryMatchesASelectedOption = selectedOptions.value.some(
|
|
943
|
+
(option: BaseOption) => option.text === query.value
|
|
944
|
+
);
|
|
945
|
+
if (queryMatchesASelectedOption) return options.value;
|
|
946
|
+
}
|
|
947
|
+
const q = query.value.trim();
|
|
948
|
+
if (props.filterBy.length) {
|
|
949
|
+
return options.value.filter((item: BaseOption) =>
|
|
950
|
+
matchAnyKey(item.item, props.filterBy, q)
|
|
951
|
+
);
|
|
952
|
+
}
|
|
953
|
+
return options.value.filter((item: BaseOption) =>
|
|
954
|
+
matchAnyKey(item, ['text'], q)
|
|
955
|
+
);
|
|
956
|
+
});
|
|
957
|
+
|
|
958
|
+
const defaultGroupSymbol = Symbol('default');
|
|
959
|
+
|
|
960
|
+
const getGroupData = (option: BaseOption) => {
|
|
961
|
+
if (isNil(props.groupBy)) return defaultGroupSymbol;
|
|
962
|
+
if (typeof props.groupBy === 'function') return props.groupBy(option.item);
|
|
963
|
+
return (get as any)(option.item, props.groupBy);
|
|
964
|
+
};
|
|
965
|
+
|
|
966
|
+
const groupedOptions = computed<GroupedOptions[]>(() => {
|
|
967
|
+
const groupIndex: Record<GroupedOptions['id'], GroupedOptions> = {};
|
|
968
|
+
for (const option of filteredOptions.value) {
|
|
969
|
+
const groupData = getGroupData(option);
|
|
970
|
+
const groupId = hash(groupData);
|
|
971
|
+
if (!groupIndex[groupId]) {
|
|
972
|
+
groupIndex[groupId] = {
|
|
973
|
+
id: groupId,
|
|
974
|
+
data: groupData ?? null,
|
|
975
|
+
options: [],
|
|
976
|
+
};
|
|
977
|
+
}
|
|
978
|
+
groupIndex[groupId].options.push(option);
|
|
979
|
+
}
|
|
980
|
+
return Object.values(groupIndex).filter((g) => g.options.length);
|
|
981
|
+
});
|
|
982
|
+
|
|
983
|
+
/**
|
|
984
|
+
* START POPOVER STATE
|
|
985
|
+
*/
|
|
986
|
+
const shown = ref(false);
|
|
987
|
+
const renderListBox = useUntil(shown);
|
|
988
|
+
/**
|
|
989
|
+
* `shown` is the open model — it flips the instant the panel starts closing, so
|
|
990
|
+
* binding `:inert` straight off it stripped the still-fading header/footer from
|
|
991
|
+
* the accessibility tree mid-animation. This trails CommonPopover's fade-out
|
|
992
|
+
* (same `transitionDuration`) and only then goes inert.
|
|
993
|
+
*/
|
|
994
|
+
const panelChromeInert = useClosingInert(shown, () => props.transitionDuration);
|
|
995
|
+
|
|
996
|
+
/**
|
|
997
|
+
* START ADAPTIVE SURFACE
|
|
998
|
+
* On mobile with `adaptive`, the panel becomes a bottom off-canvas sheet instead
|
|
999
|
+
* of a floating popover. The surface is latched when the panel opens and frozen
|
|
1000
|
+
* until it closes, so a mid-session resize never swaps a live popover into a sheet
|
|
1001
|
+
* (or vice-versa) — mirroring BbPopover/BbDropdown/BbDialog.
|
|
1002
|
+
*/
|
|
1003
|
+
const resolveSurface = (): 'popover' | 'canvas' =>
|
|
1004
|
+
(props.adaptive ?? config.adaptive) && isMobile.value ? 'canvas' : 'popover';
|
|
1005
|
+
const surface = ref<'popover' | 'canvas'>(resolveSurface());
|
|
1006
|
+
const useOffcanvas = computed(() => surface.value === 'canvas');
|
|
1007
|
+
|
|
1008
|
+
// While closed, keep tracking the viewport so the next open resolves correctly;
|
|
1009
|
+
// while open the surface stays frozen.
|
|
1010
|
+
watch([() => props.adaptive, isMobile, shown], () => {
|
|
1011
|
+
if (!shown.value) surface.value = resolveSurface();
|
|
1012
|
+
});
|
|
1013
|
+
|
|
1014
|
+
const offcanvasBindings = computed(() => ({
|
|
1015
|
+
side: 'bottom' as const,
|
|
1016
|
+
size: 'auto' as const,
|
|
1017
|
+
draggable: true,
|
|
1018
|
+
// In sheet mode skip selected chips: focus the search field when writable,
|
|
1019
|
+
// otherwise land on the first interactive option for immediate keyboard nav.
|
|
1020
|
+
focusTarget: computedAllowWriting.value
|
|
1021
|
+
? '.bb-select-popover__search-input'
|
|
1022
|
+
: '.bb-listbox__option[role="option"]:not(.autocomplete-option--disabled), .bb-select-popover__focus-proxy',
|
|
1023
|
+
disabled: props.disabled,
|
|
1024
|
+
transitionDuration: props.transitionDuration,
|
|
1025
|
+
// `width` is intentionally not forwarded — a sheet spans the viewport width.
|
|
1026
|
+
...props.offCanvasProps,
|
|
1027
|
+
}));
|
|
1028
|
+
/**
|
|
1029
|
+
* END ADAPTIVE SURFACE
|
|
1030
|
+
*/
|
|
1031
|
+
|
|
1032
|
+
const open = async ({
|
|
1033
|
+
focusPopoverContent = true,
|
|
1034
|
+
}: { focusPopoverContent?: boolean } = {}) => {
|
|
1035
|
+
if (props.disabled || props.readonly) return;
|
|
1036
|
+
if (shown.value) return;
|
|
1037
|
+
// Latch the surface for this open cycle before anything reads it.
|
|
1038
|
+
surface.value = resolveSurface();
|
|
1039
|
+
hasInteracted.value = true;
|
|
1040
|
+
shown.value = true;
|
|
1041
|
+
|
|
1042
|
+
// Search-first defers the one-time initial fetch to the first query, so
|
|
1043
|
+
// opening must not perform it — this is the only thing separating
|
|
1044
|
+
// `prefill: false` from `'interaction'`.
|
|
1045
|
+
if (!hasPrefilled.value && !isPrefilling.value && !isSearchFirst.value) {
|
|
1046
|
+
await prefillItems();
|
|
1047
|
+
// close() may have run during the fetch — attaching listeners or
|
|
1048
|
+
// stealing focus now would act on a closed popover.
|
|
1049
|
+
if (!shown.value) return;
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
await nextTick();
|
|
1053
|
+
if (!shown.value) return;
|
|
1054
|
+
|
|
1055
|
+
// The off-canvas sheet is modal and manages its own backdrop, Escape and focus
|
|
1056
|
+
// — skip the floating-panel document listeners and the activator visibility watch.
|
|
1057
|
+
if (useOffcanvas.value) return;
|
|
1058
|
+
|
|
1059
|
+
resume();
|
|
1060
|
+
document.addEventListener('click', onOutsideInteraction);
|
|
1061
|
+
document.addEventListener('focusin', onOutsideInteraction);
|
|
1062
|
+
|
|
1063
|
+
if (!focusPopoverContent) return;
|
|
1064
|
+
|
|
1065
|
+
await wait(0);
|
|
1066
|
+
if (!shown.value) return;
|
|
1067
|
+
if (computedAllowWriting.value) {
|
|
1068
|
+
focusSearchInput();
|
|
1069
|
+
} else {
|
|
1070
|
+
focusPopoverFocusProxy();
|
|
1071
|
+
}
|
|
1072
|
+
};
|
|
1073
|
+
|
|
1074
|
+
const close = async () => {
|
|
1075
|
+
if (!shown.value) return;
|
|
1076
|
+
shown.value = false;
|
|
1077
|
+
optionsContainer.value?.blur();
|
|
1078
|
+
activeDescendantId.value = undefined;
|
|
1079
|
+
query.value = '';
|
|
1080
|
+
|
|
1081
|
+
// In sheet mode `onOffcanvasHidden` runs the rest of the teardown once the close
|
|
1082
|
+
// transition finishes; the flyout's document listeners were never attached.
|
|
1083
|
+
if (useOffcanvas.value) return;
|
|
1084
|
+
|
|
1085
|
+
pause();
|
|
1086
|
+
document.removeEventListener('click', onOutsideInteraction);
|
|
1087
|
+
document.removeEventListener('focusin', onOutsideInteraction);
|
|
1088
|
+
};
|
|
1089
|
+
|
|
1090
|
+
/**
|
|
1091
|
+
* The sheet can also close itself (backdrop tap, drag-to-dismiss, Escape) by
|
|
1092
|
+
* flipping the `shown` model without going through `close()`. Run the shared
|
|
1093
|
+
* teardown after its close transition and return focus to the activator.
|
|
1094
|
+
*/
|
|
1095
|
+
const onOffcanvasHidden = () => {
|
|
1096
|
+
optionsContainer.value?.blur();
|
|
1097
|
+
activeDescendantId.value = undefined;
|
|
1098
|
+
query.value = '';
|
|
1099
|
+
setInactive();
|
|
1100
|
+
focusActivator();
|
|
1101
|
+
};
|
|
1102
|
+
|
|
1103
|
+
const toggle = () => {
|
|
1104
|
+
if (shown.value) return close();
|
|
1105
|
+
return open();
|
|
1106
|
+
};
|
|
1107
|
+
/**
|
|
1108
|
+
* END POPOVER STATE
|
|
1109
|
+
*/
|
|
1110
|
+
|
|
1111
|
+
/**
|
|
1112
|
+
* START ACTIVE STATE
|
|
1113
|
+
* Tracks whether the user is inside this whole component.
|
|
1114
|
+
* We cannot use :focus-within as it doesn't work for teleported elements.
|
|
1115
|
+
*/
|
|
1116
|
+
const active = ref(false);
|
|
1117
|
+
|
|
1118
|
+
const setActive = () => {
|
|
1119
|
+
if (active.value) return;
|
|
1120
|
+
active.value = true;
|
|
1121
|
+
emit('active');
|
|
1122
|
+
};
|
|
1123
|
+
const setInactive = () => {
|
|
1124
|
+
if (!active.value) return;
|
|
1125
|
+
active.value = false;
|
|
1126
|
+
emit('inactive');
|
|
1127
|
+
};
|
|
1128
|
+
|
|
1129
|
+
const isFocusInsideComponent = (target: EventTarget | null) => {
|
|
1130
|
+
if (!(target instanceof Node)) return false;
|
|
1131
|
+
const insideActivator = !!activatorEl.value?.contains(target);
|
|
1132
|
+
const insidePopover = !!optionsContainer.value?.$el
|
|
1133
|
+
?.closest('.bb-common-popover')
|
|
1134
|
+
?.contains(target);
|
|
1135
|
+
return insideActivator || insidePopover;
|
|
1136
|
+
};
|
|
1137
|
+
|
|
1138
|
+
let blurSyncTimer: ReturnType<typeof setTimeout> | undefined;
|
|
1139
|
+
const syncActiveStateOnBlur = () => {
|
|
1140
|
+
clearTimeout(blurSyncTimer);
|
|
1141
|
+
blurSyncTimer = setTimeout(() => {
|
|
1142
|
+
if (shown.value) {
|
|
1143
|
+
setActive();
|
|
1144
|
+
return;
|
|
1145
|
+
}
|
|
1146
|
+
if (isFocusInsideComponent(document.activeElement)) {
|
|
1147
|
+
setActive();
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1150
|
+
setInactive();
|
|
1151
|
+
}, 0);
|
|
1152
|
+
};
|
|
1153
|
+
/**
|
|
1154
|
+
* END ACTIVE STATE
|
|
1155
|
+
*/
|
|
1156
|
+
|
|
1157
|
+
const onClear = () => {
|
|
1158
|
+
emit('update:modelValue', props.multiple ? [] : null);
|
|
1159
|
+
};
|
|
1160
|
+
|
|
1161
|
+
// The in-search clear button resets the whole search state — both the typed
|
|
1162
|
+
// query and the selection — matching the searchbox affordance it sits in.
|
|
1163
|
+
// `@mousedown.prevent` on the button keeps focus in the input, so clearing
|
|
1164
|
+
// doesn't bounce focus out of the popover.
|
|
1165
|
+
const onSearchClear = () => {
|
|
1166
|
+
query.value = '';
|
|
1167
|
+
onClear();
|
|
1168
|
+
};
|
|
1169
|
+
|
|
1170
|
+
/**
|
|
1171
|
+
* Props exposed to the `header` / `footer` slots — identical in both the desktop
|
|
1172
|
+
* popover and the adaptive sheet, so a consumer's slot markup works unchanged
|
|
1173
|
+
* across surfaces.
|
|
1174
|
+
*/
|
|
1175
|
+
const panelSlotProps = computed(() => ({
|
|
1176
|
+
close,
|
|
1177
|
+
clear: onClear,
|
|
1178
|
+
focus: focusPopoverContent,
|
|
1179
|
+
query: query.value,
|
|
1180
|
+
selectedOptions: publicSelectedOptions.value,
|
|
1181
|
+
}));
|
|
1182
|
+
|
|
1183
|
+
/**
|
|
1184
|
+
* START ACTIVATOR LISTENERS
|
|
1185
|
+
* Programmatically attach accessibility attributes and event listeners
|
|
1186
|
+
* to the activator element, following the BbDropdown pattern.
|
|
1187
|
+
*/
|
|
1188
|
+
let cleanupActivator: (() => void) | null = null;
|
|
1189
|
+
|
|
1190
|
+
watch(
|
|
1191
|
+
activatorEl,
|
|
1192
|
+
(el) => {
|
|
1193
|
+
if (cleanupActivator) {
|
|
1194
|
+
cleanupActivator();
|
|
1195
|
+
cleanupActivator = null;
|
|
1196
|
+
}
|
|
1197
|
+
if (!el) return;
|
|
1198
|
+
|
|
1199
|
+
el.setAttribute('role', 'combobox');
|
|
1200
|
+
el.setAttribute('aria-haspopup', 'listbox');
|
|
1201
|
+
|
|
1202
|
+
const handleClick = async (event: MouseEvent) => {
|
|
1203
|
+
emit('click', event);
|
|
1204
|
+
if (props.disabled) return;
|
|
1205
|
+
event.preventDefault();
|
|
1206
|
+
if (props.readonly) {
|
|
1207
|
+
focusActivator();
|
|
1208
|
+
return;
|
|
1209
|
+
}
|
|
1210
|
+
if (shown.value) {
|
|
1211
|
+
await close();
|
|
1212
|
+
focusActivator();
|
|
1213
|
+
return;
|
|
1214
|
+
}
|
|
1215
|
+
await open();
|
|
1216
|
+
};
|
|
1217
|
+
|
|
1218
|
+
const handlePointerDown = (event: PointerEvent) => {
|
|
1219
|
+
if (!props.readonly || props.disabled) return;
|
|
1220
|
+
// Keep focus/ring stable during press in readonly mode.
|
|
1221
|
+
event.preventDefault();
|
|
1222
|
+
setActive();
|
|
1223
|
+
focusActivator();
|
|
1224
|
+
};
|
|
1225
|
+
|
|
1226
|
+
const handleKeydown = (event: KeyboardEvent) => {
|
|
1227
|
+
switch (event.key) {
|
|
1228
|
+
case 'ArrowDown':
|
|
1229
|
+
event.preventDefault();
|
|
1230
|
+
onArrowDown();
|
|
1231
|
+
break;
|
|
1232
|
+
case 'ArrowUp':
|
|
1233
|
+
event.preventDefault();
|
|
1234
|
+
onArrowUp();
|
|
1235
|
+
break;
|
|
1236
|
+
case 'Enter':
|
|
1237
|
+
event.preventDefault();
|
|
1238
|
+
onEnter();
|
|
1239
|
+
break;
|
|
1240
|
+
case 'Escape':
|
|
1241
|
+
if (shown.value) {
|
|
1242
|
+
event.preventDefault();
|
|
1243
|
+
onEscape();
|
|
1244
|
+
}
|
|
1245
|
+
break;
|
|
1246
|
+
}
|
|
1247
|
+
};
|
|
1248
|
+
|
|
1249
|
+
const handleFocus = (event: FocusEvent) => {
|
|
1250
|
+
emit('focus', event);
|
|
1251
|
+
setActive();
|
|
1252
|
+
};
|
|
1253
|
+
|
|
1254
|
+
const handleBlur = (event: FocusEvent) => {
|
|
1255
|
+
emit('blur', event);
|
|
1256
|
+
syncActiveStateOnBlur();
|
|
1257
|
+
};
|
|
1258
|
+
|
|
1259
|
+
el.addEventListener('click', handleClick);
|
|
1260
|
+
el.addEventListener('pointerdown', handlePointerDown);
|
|
1261
|
+
el.addEventListener('keydown', handleKeydown);
|
|
1262
|
+
el.addEventListener('focus', handleFocus);
|
|
1263
|
+
el.addEventListener('blur', handleBlur);
|
|
1264
|
+
|
|
1265
|
+
cleanupActivator = () => {
|
|
1266
|
+
el.removeEventListener('click', handleClick);
|
|
1267
|
+
el.removeEventListener('pointerdown', handlePointerDown);
|
|
1268
|
+
el.removeEventListener('keydown', handleKeydown);
|
|
1269
|
+
el.removeEventListener('focus', handleFocus);
|
|
1270
|
+
el.removeEventListener('blur', handleBlur);
|
|
1271
|
+
el.removeAttribute('role');
|
|
1272
|
+
el.removeAttribute('aria-haspopup');
|
|
1273
|
+
el.removeAttribute('aria-expanded');
|
|
1274
|
+
el.removeAttribute('aria-controls');
|
|
1275
|
+
el.removeAttribute('aria-invalid');
|
|
1276
|
+
el.removeAttribute('aria-describedby');
|
|
1277
|
+
el.removeAttribute('aria-valuetext');
|
|
1278
|
+
el.removeAttribute('aria-activedescendant');
|
|
1279
|
+
};
|
|
1280
|
+
},
|
|
1281
|
+
{ immediate: true }
|
|
1282
|
+
);
|
|
1283
|
+
|
|
1284
|
+
watch(
|
|
1285
|
+
[
|
|
1286
|
+
activatorEl,
|
|
1287
|
+
shown,
|
|
1288
|
+
renderListBox,
|
|
1289
|
+
computedAriaInvalid,
|
|
1290
|
+
computedAriaDescribedby,
|
|
1291
|
+
triggerInputValue,
|
|
1292
|
+
activeDescendantId,
|
|
1293
|
+
] as const,
|
|
1294
|
+
([
|
|
1295
|
+
el,
|
|
1296
|
+
isShown,
|
|
1297
|
+
hasListBox,
|
|
1298
|
+
ariaInvalid,
|
|
1299
|
+
ariaDescribedby,
|
|
1300
|
+
triggerText,
|
|
1301
|
+
descendantId,
|
|
1302
|
+
]) => {
|
|
1303
|
+
if (!el) return;
|
|
1304
|
+
el.setAttribute('aria-expanded', String(isShown));
|
|
1305
|
+
if (ariaInvalid != null) {
|
|
1306
|
+
el.setAttribute('aria-invalid', ariaInvalid);
|
|
1307
|
+
} else {
|
|
1308
|
+
el.removeAttribute('aria-invalid');
|
|
1309
|
+
}
|
|
1310
|
+
if (hasListBox) {
|
|
1311
|
+
el.setAttribute('aria-controls', `${id}_listbox`);
|
|
1312
|
+
} else {
|
|
1313
|
+
el.removeAttribute('aria-controls');
|
|
1314
|
+
}
|
|
1315
|
+
if (ariaDescribedby != null) {
|
|
1316
|
+
el.setAttribute('aria-describedby', ariaDescribedby);
|
|
1317
|
+
} else {
|
|
1318
|
+
el.removeAttribute('aria-describedby');
|
|
1319
|
+
}
|
|
1320
|
+
if (triggerText) {
|
|
1321
|
+
el.setAttribute('aria-valuetext', triggerText);
|
|
1322
|
+
} else {
|
|
1323
|
+
el.removeAttribute('aria-valuetext');
|
|
1324
|
+
}
|
|
1325
|
+
if (isShown && descendantId) {
|
|
1326
|
+
el.setAttribute('aria-activedescendant', descendantId);
|
|
1327
|
+
} else {
|
|
1328
|
+
el.removeAttribute('aria-activedescendant');
|
|
1329
|
+
}
|
|
1330
|
+
},
|
|
1331
|
+
{ immediate: true }
|
|
1332
|
+
);
|
|
1333
|
+
|
|
1334
|
+
onBeforeUnmount(() => {
|
|
1335
|
+
clearTimeout(blurSyncTimer);
|
|
1336
|
+
cleanupActivator?.();
|
|
1337
|
+
document.removeEventListener('click', onOutsideInteraction);
|
|
1338
|
+
document.removeEventListener('focusin', onOutsideInteraction);
|
|
1339
|
+
});
|
|
1340
|
+
/**
|
|
1341
|
+
* END ACTIVATOR LISTENERS
|
|
1342
|
+
*/
|
|
1343
|
+
</script>
|
|
1344
|
+
|
|
1345
|
+
<style lang="postcss">
|
|
1346
|
+
@import './index.css';
|
|
1347
|
+
</style>
|
|
1348
|
+
```
|
|
1349
|
+
|
|
1350
|
+
## Types
|
|
1351
|
+
|
|
1352
|
+
```ts
|
|
1353
|
+
import type { HTMLAttributes, InputHTMLAttributes } from 'vue';
|
|
1354
|
+
import type { Placement } from '@/types/Placement';
|
|
1355
|
+
import type { ItemAccessor } from '@/types/ItemAccessor';
|
|
1356
|
+
import type { BbOffCanvasProps } from '../BbOffCanvas/types';
|
|
1357
|
+
|
|
1358
|
+
/**
|
|
1359
|
+
* A selected option as resolved by the select family and exposed through slot
|
|
1360
|
+
* props (`selectedOptions`): the raw source `item` plus its resolved display
|
|
1361
|
+
* `text` / `value` and its `selected` / `disabled` state.
|
|
1362
|
+
*
|
|
1363
|
+
* This is a hand-picked public shape, produced by an explicit mapper in the
|
|
1364
|
+
* component — the internal `valueHash` (and any future internal field on the
|
|
1365
|
+
* underlying option) is intentionally NOT exposed, so consumers cannot come to
|
|
1366
|
+
* depend on selection internals.
|
|
1367
|
+
*/
|
|
1368
|
+
export type BbSelectResolvedOption<Item = any> = {
|
|
1369
|
+
/** The raw source item from the `items` prop. */
|
|
1370
|
+
item: Item;
|
|
1371
|
+
/** The resolved display text for this option. */
|
|
1372
|
+
text: string;
|
|
1373
|
+
/** The resolved value for this option. */
|
|
1374
|
+
value: any;
|
|
1375
|
+
/** Whether this option is currently selected. */
|
|
1376
|
+
selected: boolean;
|
|
1377
|
+
/** Whether this option is disabled. */
|
|
1378
|
+
disabled: boolean;
|
|
1379
|
+
};
|
|
1380
|
+
|
|
1381
|
+
export type BbSelectPopoverProps<Item> = {
|
|
1382
|
+
/**
|
|
1383
|
+
* External activator element or component ref.
|
|
1384
|
+
* When provided, the activator slot is not rendered and event listeners
|
|
1385
|
+
* are attached programmatically to the referenced element.
|
|
1386
|
+
*/
|
|
1387
|
+
activator?: HTMLElement | Record<string, any> | null;
|
|
1388
|
+
/**
|
|
1389
|
+
* When `true`, the panel opens as a bottom off-canvas sheet on mobile viewports
|
|
1390
|
+
* instead of a floating popover; on desktop it stays a popover. The sheet reuses
|
|
1391
|
+
* the same search field and options list, adding a representation of the current
|
|
1392
|
+
* selection between them. Mirrors the adaptive behaviour of `BbPopover`/`BbDropdown`.
|
|
1393
|
+
*
|
|
1394
|
+
* When unset, falls back to the global `config.adaptive`.
|
|
1395
|
+
* @defaultValue `config.adaptive` (`true`)
|
|
1396
|
+
*/
|
|
1397
|
+
adaptive?: boolean;
|
|
1398
|
+
/**
|
|
1399
|
+
* Extra props forwarded to the `BbOffCanvas` sheet when `adaptive` is active on
|
|
1400
|
+
* mobile (e.g. `size`, `draggable`, `fullscreen`, `stack`).
|
|
1401
|
+
*/
|
|
1402
|
+
offCanvasProps?: Partial<BbOffCanvasProps>;
|
|
1403
|
+
/**
|
|
1404
|
+
* Override the element used for popover positioning and width measurement.
|
|
1405
|
+
* Useful when the focusable activator is narrower than its visual container
|
|
1406
|
+
* (e.g. a button inside a wrapper). Falls back to `activatorEl` when omitted.
|
|
1407
|
+
*
|
|
1408
|
+
* @defaultValue `null`
|
|
1409
|
+
*/
|
|
1410
|
+
anchor?: HTMLElement | Record<string, any> | null;
|
|
1411
|
+
/**
|
|
1412
|
+
* Controls whether the search input is shown inside the popover panel.
|
|
1413
|
+
* Use `'mobile'` to hide the search input on mobile, `'desktop'` to hide it on desktop.
|
|
1414
|
+
*
|
|
1415
|
+
* @defaultValue `false`
|
|
1416
|
+
*/
|
|
1417
|
+
disableWriting?: boolean | 'mobile' | 'desktop';
|
|
1418
|
+
/**
|
|
1419
|
+
* Space-separated IDREF(s) that describe this field for assistive technologies.
|
|
1420
|
+
* Accepts either a string or array of ids.
|
|
1421
|
+
*/
|
|
1422
|
+
ariaDescribedby?: string | string[];
|
|
1423
|
+
/**
|
|
1424
|
+
* Explicit invalid state for accessibility semantics.
|
|
1425
|
+
* Falls back to `hasErrors` when not provided.
|
|
1426
|
+
*/
|
|
1427
|
+
ariaInvalid?: boolean;
|
|
1428
|
+
/**
|
|
1429
|
+
* Browser autocomplete hint for the popover search input.
|
|
1430
|
+
*
|
|
1431
|
+
* @defaultValue `'off'`
|
|
1432
|
+
*/
|
|
1433
|
+
autocomplete?: InputHTMLAttributes['autocomplete'];
|
|
1434
|
+
/**
|
|
1435
|
+
* Constrains the popover to a specific boundary element.
|
|
1436
|
+
*/
|
|
1437
|
+
boundary?: HTMLElement | Record<string, any> | string | null;
|
|
1438
|
+
/**
|
|
1439
|
+
* Apply the compact density variant.
|
|
1440
|
+
*/
|
|
1441
|
+
compact?: boolean;
|
|
1442
|
+
/**
|
|
1443
|
+
* Additional dependencies that trigger item reloading when changed.
|
|
1444
|
+
*
|
|
1445
|
+
* @defaultValue `[]`
|
|
1446
|
+
*/
|
|
1447
|
+
dependencies?: unknown[];
|
|
1448
|
+
/**
|
|
1449
|
+
* Debounce delay (ms) for dependency-triggered reloads.
|
|
1450
|
+
*
|
|
1451
|
+
* @defaultValue `0`
|
|
1452
|
+
*/
|
|
1453
|
+
depsDebounceTime?: number;
|
|
1454
|
+
/**
|
|
1455
|
+
* Shows a clear button inside the search field's icon stack: it takes the
|
|
1456
|
+
* lens' place on hover/focus while there is a query or selection to clear,
|
|
1457
|
+
* and resets both. Off by default. Leave it off when the component is
|
|
1458
|
+
* wrapped by a control that already exposes its own clear affordance (e.g.
|
|
1459
|
+
* BbSelect clears from the activator) to avoid a duplicate clear button.
|
|
1460
|
+
*/
|
|
1461
|
+
clearable?: boolean;
|
|
1462
|
+
/**
|
|
1463
|
+
* Disables the component.
|
|
1464
|
+
*/
|
|
1465
|
+
disabled?: boolean;
|
|
1466
|
+
/**
|
|
1467
|
+
* Reset modelValue to `null` or empty array if it no longer matches available items.
|
|
1468
|
+
*/
|
|
1469
|
+
enforceCoherence?: boolean;
|
|
1470
|
+
/**
|
|
1471
|
+
* Property paths used to filter options when the user types in the search input.
|
|
1472
|
+
* When empty (default) options are matched against their display text.
|
|
1473
|
+
* When non-empty the provided paths are searched instead of the display text.
|
|
1474
|
+
* To disable filtering entirely set `disableWriting` so the user cannot type a query.
|
|
1475
|
+
*
|
|
1476
|
+
* @defaultValue `[]`
|
|
1477
|
+
*/
|
|
1478
|
+
filterBy?: string[];
|
|
1479
|
+
/**
|
|
1480
|
+
* Disables the automatic flip to the opposite side when the popover
|
|
1481
|
+
* would overflow (flipping is on by default).
|
|
1482
|
+
*
|
|
1483
|
+
* @defaultValue `false`
|
|
1484
|
+
*/
|
|
1485
|
+
disableFlip?: boolean;
|
|
1486
|
+
/** Path to item property for grouping options. */
|
|
1487
|
+
groupBy?: string | ((item: Item) => string | number | symbol);
|
|
1488
|
+
/**
|
|
1489
|
+
* Marks the component as being in error state.
|
|
1490
|
+
*/
|
|
1491
|
+
hasErrors?: boolean;
|
|
1492
|
+
/**
|
|
1493
|
+
* Marks the component as being in a warning state. Visually mirrors
|
|
1494
|
+
* `hasErrors` but uses `--bb-warn` chrome; errors take priority when both
|
|
1495
|
+
* are set.
|
|
1496
|
+
*/
|
|
1497
|
+
hasWarning?: boolean;
|
|
1498
|
+
/**
|
|
1499
|
+
* Height of group headers in the listbox (px). Defaults to 24px (compact) or 32px.
|
|
1500
|
+
* Only applies when `groupBy` is set.
|
|
1501
|
+
*/
|
|
1502
|
+
headerHeight?: number;
|
|
1503
|
+
/**
|
|
1504
|
+
* Explicit id for the component. Used to generate ids for listbox and options.
|
|
1505
|
+
*/
|
|
1506
|
+
id?: HTMLAttributes['id'];
|
|
1507
|
+
/**
|
|
1508
|
+
* Height of the options in the listbox (px).
|
|
1509
|
+
*
|
|
1510
|
+
* @defaultValue `40`
|
|
1511
|
+
*/
|
|
1512
|
+
itemHeight?: number;
|
|
1513
|
+
/**
|
|
1514
|
+
* Array of items or function to load them asynchronously.
|
|
1515
|
+
* Functions receive `(query, prefill, modelValue)` and can return a promise.
|
|
1516
|
+
* `modelValue` is the raw v-model: an array in `multiple` mode, the raw
|
|
1517
|
+
* model value (possibly `null`) in single mode.
|
|
1518
|
+
*
|
|
1519
|
+
* @defaultValue `[]`
|
|
1520
|
+
*/
|
|
1521
|
+
items:
|
|
1522
|
+
| Item[]
|
|
1523
|
+
| ((query: string, prefill: boolean, modelValue: any) => Promise<Item[]>)
|
|
1524
|
+
| ((query: string, prefill: boolean, modelValue: any) => Item[]);
|
|
1525
|
+
/**
|
|
1526
|
+
* Path to item property for display text or function to extract it.
|
|
1527
|
+
*/
|
|
1528
|
+
itemText?: ItemAccessor<Item, string>;
|
|
1529
|
+
/**
|
|
1530
|
+
* Path to item property for value or function to extract it.
|
|
1531
|
+
*/
|
|
1532
|
+
itemValue?: ItemAccessor<Item>;
|
|
1533
|
+
/**
|
|
1534
|
+
* Display the loading state styles.
|
|
1535
|
+
*/
|
|
1536
|
+
loading?: boolean;
|
|
1537
|
+
/**
|
|
1538
|
+
* Message shown while items are being loaded.
|
|
1539
|
+
*/
|
|
1540
|
+
loadingText?: string;
|
|
1541
|
+
/**
|
|
1542
|
+
* Maximum number of selectable items (limits selection when `multiple` is true).
|
|
1543
|
+
*
|
|
1544
|
+
* @defaultValue `Infinity`
|
|
1545
|
+
*/
|
|
1546
|
+
max?: number;
|
|
1547
|
+
/**
|
|
1548
|
+
* v-model value. Single value for single select, array for multiple select.
|
|
1549
|
+
*/
|
|
1550
|
+
modelValue: any;
|
|
1551
|
+
/**
|
|
1552
|
+
* Debounce delay (ms) for modelValue change handling.
|
|
1553
|
+
*
|
|
1554
|
+
* @defaultValue `0`
|
|
1555
|
+
*/
|
|
1556
|
+
modelValueDebounceTime?: number;
|
|
1557
|
+
/**
|
|
1558
|
+
* Enable multiple item selection. When true, modelValue must be an array.
|
|
1559
|
+
*/
|
|
1560
|
+
multiple?: boolean;
|
|
1561
|
+
/**
|
|
1562
|
+
* Message displayed when no items are available.
|
|
1563
|
+
*/
|
|
1564
|
+
noDataText?: string;
|
|
1565
|
+
/**
|
|
1566
|
+
* Distance (px) between the activator and the popover.
|
|
1567
|
+
*
|
|
1568
|
+
* @defaultValue `4`
|
|
1569
|
+
*/
|
|
1570
|
+
offset?: number;
|
|
1571
|
+
/**
|
|
1572
|
+
* Minimum page padding used by floating shift middleware.
|
|
1573
|
+
*
|
|
1574
|
+
* @defaultValue `10`
|
|
1575
|
+
*/
|
|
1576
|
+
padding?: number;
|
|
1577
|
+
/**
|
|
1578
|
+
* Floating placement of the popover.
|
|
1579
|
+
*
|
|
1580
|
+
* @defaultValue `'bottom'`
|
|
1581
|
+
*/
|
|
1582
|
+
placement?: Placement;
|
|
1583
|
+
/**
|
|
1584
|
+
* Controls when items are pre-loaded.
|
|
1585
|
+
* `'interaction'` loads on the first user interaction (opening the
|
|
1586
|
+
* popover), `true` loads immediately on mount (and during SSR via
|
|
1587
|
+
* `onServerPrefetch`), `false` is *search-first*: nothing is fetched until
|
|
1588
|
+
* the user types a query — opening the panel alone does not load, and the
|
|
1589
|
+
* panel shows a "search to begin" hint until it does.
|
|
1590
|
+
* With the default, a seeded model resolves its option text on the first
|
|
1591
|
+
* interaction, not on mount — set `prefill: true` when the trigger must
|
|
1592
|
+
* show the selection's text without user interaction.
|
|
1593
|
+
*
|
|
1594
|
+
* Search-first needs a way to search and something to defer, so `false`
|
|
1595
|
+
* falls back to loading on open when any of these is true: `items` is an
|
|
1596
|
+
* array (nothing to defer — arrays resolve on mount), writing is disabled
|
|
1597
|
+
* (no search field, so the user could never trigger a load), or the model
|
|
1598
|
+
* is non-empty (its text must resolve to render the selection).
|
|
1599
|
+
*
|
|
1600
|
+
* @defaultValue `'interaction'`
|
|
1601
|
+
*/
|
|
1602
|
+
prefill?: boolean | 'interaction';
|
|
1603
|
+
/**
|
|
1604
|
+
* Debounce delay (ms) before triggering search queries after user input stops.
|
|
1605
|
+
*
|
|
1606
|
+
* @defaultValue `500`
|
|
1607
|
+
*/
|
|
1608
|
+
queryDebounceTime?: number;
|
|
1609
|
+
/**
|
|
1610
|
+
* Prevents opening the popover while keeping the activator accessible.
|
|
1611
|
+
*/
|
|
1612
|
+
readonly?: boolean;
|
|
1613
|
+
/**
|
|
1614
|
+
* Accessible label used by the search input rendered inside the popover.
|
|
1615
|
+
* Falls back to the localized `select.searchLabel` key when omitted.
|
|
1616
|
+
*
|
|
1617
|
+
* @defaultValue `t('select.searchLabel')` (`'Search options'`)
|
|
1618
|
+
*/
|
|
1619
|
+
searchInputAriaLabel?: string;
|
|
1620
|
+
/**
|
|
1621
|
+
* Defines whether options are selectable.
|
|
1622
|
+
* Can be a global boolean that affects all options or a function
|
|
1623
|
+
* that accepts an item and returns a boolean that only affects that item.
|
|
1624
|
+
* Non-selectable options are rendered disabled.
|
|
1625
|
+
*
|
|
1626
|
+
* @defaultValue `true`
|
|
1627
|
+
*/
|
|
1628
|
+
selectable?: boolean | ((item: Item) => boolean);
|
|
1629
|
+
/**
|
|
1630
|
+
* Accumulate selected items across searches instead of replacing them.
|
|
1631
|
+
*/
|
|
1632
|
+
stash?: boolean;
|
|
1633
|
+
/**
|
|
1634
|
+
* Transition duration (ms) for popover show/hide animations.
|
|
1635
|
+
*
|
|
1636
|
+
* @defaultValue `250`
|
|
1637
|
+
*/
|
|
1638
|
+
transitionDuration?: number;
|
|
1639
|
+
/**
|
|
1640
|
+
* Width of the popover in pixels, percentage, or `'auto'`. A bare number is
|
|
1641
|
+
* read as pixels — the default is the string `'200'`, not the number `200`.
|
|
1642
|
+
*
|
|
1643
|
+
* @defaultValue `'200'`
|
|
1644
|
+
*/
|
|
1645
|
+
width?: number | string;
|
|
1646
|
+
};
|
|
1647
|
+
|
|
1648
|
+
export type BbSelectPopoverEvents = {
|
|
1649
|
+
/**
|
|
1650
|
+
* Emitted when the activator loses focus.
|
|
1651
|
+
*/
|
|
1652
|
+
(e: 'blur', event: FocusEvent): void;
|
|
1653
|
+
/**
|
|
1654
|
+
* Emitted when the value changes via native change event.
|
|
1655
|
+
*/
|
|
1656
|
+
(e: 'change', event: Event): void;
|
|
1657
|
+
/**
|
|
1658
|
+
* Emitted when the activator is clicked.
|
|
1659
|
+
*/
|
|
1660
|
+
(e: 'click', event: MouseEvent): void;
|
|
1661
|
+
/**
|
|
1662
|
+
* Emitted when the activator receives focus.
|
|
1663
|
+
*/
|
|
1664
|
+
(e: 'focus', event: FocusEvent): void;
|
|
1665
|
+
/**
|
|
1666
|
+
* Emitted when focus moves outside the entire component after it was active.
|
|
1667
|
+
*/
|
|
1668
|
+
(e: 'inactive'): void;
|
|
1669
|
+
/** Emitted when the component becomes active (focus enters it). */
|
|
1670
|
+
(e: 'active'): void;
|
|
1671
|
+
/**
|
|
1672
|
+
* Emitted on native input events from the search input.
|
|
1673
|
+
*/
|
|
1674
|
+
(e: 'input', event: Event): void;
|
|
1675
|
+
/**
|
|
1676
|
+
* Emitted with the next selection value whenever selection changes.
|
|
1677
|
+
*/
|
|
1678
|
+
(e: 'update:modelValue', value: any): void;
|
|
1679
|
+
/**
|
|
1680
|
+
* Emitted when the user types a new value and confirms it (Enter key) while
|
|
1681
|
+
* writing is enabled (i.e. `disableWriting` does not suppress the search
|
|
1682
|
+
* input for the current surface).
|
|
1683
|
+
*/
|
|
1684
|
+
(e: 'option:add', text: string): void;
|
|
1685
|
+
};
|
|
1686
|
+
|
|
1687
|
+
/** Props exposed by the `activator` slot. */
|
|
1688
|
+
export type BbSelectPopoverActivatorSlotProps = {
|
|
1689
|
+
/** Clears the current selection and query. */
|
|
1690
|
+
clear: () => void;
|
|
1691
|
+
/** Closes the popover. */
|
|
1692
|
+
close: () => Promise<void>;
|
|
1693
|
+
/** Focuses the search input when writing is enabled, otherwise the listbox. */
|
|
1694
|
+
focus: () => void;
|
|
1695
|
+
/** Whether the select is disabled. */
|
|
1696
|
+
disabled: boolean | undefined;
|
|
1697
|
+
/** Whether options are currently being fetched. */
|
|
1698
|
+
loading: boolean;
|
|
1699
|
+
/** Opens the popover. */
|
|
1700
|
+
open: () => Promise<void>;
|
|
1701
|
+
/** Bind onto the activator element with `v-bind="props"` to wire up the popover reference. */
|
|
1702
|
+
props: {
|
|
1703
|
+
ref: (reference: unknown) => void;
|
|
1704
|
+
};
|
|
1705
|
+
/** The current search query string. */
|
|
1706
|
+
query: string;
|
|
1707
|
+
/** Whether the select is read-only. */
|
|
1708
|
+
readonly: boolean | undefined;
|
|
1709
|
+
/** The resolved options that are currently selected. */
|
|
1710
|
+
selectedOptions: BbSelectResolvedOption[];
|
|
1711
|
+
/** Whether the popover is currently open. */
|
|
1712
|
+
shown: boolean;
|
|
1713
|
+
/** Display text of the current selection. */
|
|
1714
|
+
text: string;
|
|
1715
|
+
/** Toggles the popover open/closed. */
|
|
1716
|
+
toggle: () => Promise<void>;
|
|
1717
|
+
};
|
|
1718
|
+
|
|
1719
|
+
/** Props exposed by the `option` slot. */
|
|
1720
|
+
export type BbSelectPopoverOptionSlotProps<Item> = {
|
|
1721
|
+
/** Whether this option is disabled. */
|
|
1722
|
+
disabled: boolean;
|
|
1723
|
+
/** Whether this option currently has keyboard focus. */
|
|
1724
|
+
focused: boolean;
|
|
1725
|
+
/** Zero-based index of this option in the list. */
|
|
1726
|
+
index: number;
|
|
1727
|
+
/** The raw item from the `items` prop. */
|
|
1728
|
+
item: Item;
|
|
1729
|
+
/** Whether items are still being fetched. */
|
|
1730
|
+
loading: boolean;
|
|
1731
|
+
/** Whether this option is currently selected. */
|
|
1732
|
+
selected: boolean;
|
|
1733
|
+
/** The resolved display text for this option. */
|
|
1734
|
+
text: string;
|
|
1735
|
+
/** The resolved value for this option. */
|
|
1736
|
+
value: any;
|
|
1737
|
+
};
|
|
1738
|
+
|
|
1739
|
+
/** Props exposed by the `group` slot. */
|
|
1740
|
+
export type BbSelectPopoverGroupSlotProps<Item> = {
|
|
1741
|
+
/** Whether all options in this group are disabled. */
|
|
1742
|
+
disabled: boolean;
|
|
1743
|
+
/** Zero-based index of the first option in this group. */
|
|
1744
|
+
index: number;
|
|
1745
|
+
/** The raw group item. */
|
|
1746
|
+
item: Item;
|
|
1747
|
+
/** Number of options in this group. */
|
|
1748
|
+
length: number;
|
|
1749
|
+
/** The display text for this group. */
|
|
1750
|
+
text: string;
|
|
1751
|
+
};
|
|
1752
|
+
|
|
1753
|
+
/**
|
|
1754
|
+
* Props exposed by the `header` / `footer` panel slots. Identical across the
|
|
1755
|
+
* desktop popover and the adaptive sheet.
|
|
1756
|
+
*/
|
|
1757
|
+
export type BbSelectPopoverPanelSlotProps = {
|
|
1758
|
+
/** Closes the panel. */
|
|
1759
|
+
close: () => Promise<void>;
|
|
1760
|
+
/** Clears the current selection. */
|
|
1761
|
+
clear: () => void;
|
|
1762
|
+
/** Focuses the search input (or the options when writing is disabled). */
|
|
1763
|
+
focus: () => void;
|
|
1764
|
+
/** The current search query string. */
|
|
1765
|
+
query: string;
|
|
1766
|
+
/** The resolved options that are currently selected. */
|
|
1767
|
+
selectedOptions: BbSelectResolvedOption[];
|
|
1768
|
+
};
|
|
1769
|
+
|
|
1770
|
+
export type BbSelectPopoverSlots<Item> = {
|
|
1771
|
+
/**
|
|
1772
|
+
* Replaces the default trigger element that opens the select popover.
|
|
1773
|
+
*/
|
|
1774
|
+
activator?: (props: BbSelectPopoverActivatorSlotProps) => any;
|
|
1775
|
+
/**
|
|
1776
|
+
* Content pinned to the top of the panel, above the search field. Rendered in
|
|
1777
|
+
* both the desktop popover and the adaptive sheet.
|
|
1778
|
+
*/
|
|
1779
|
+
header?: (props: BbSelectPopoverPanelSlotProps) => any;
|
|
1780
|
+
/**
|
|
1781
|
+
* Content pinned to the bottom of the panel, below the options list. Rendered in
|
|
1782
|
+
* both the desktop popover and the adaptive sheet.
|
|
1783
|
+
*/
|
|
1784
|
+
footer?: (props: BbSelectPopoverPanelSlotProps) => any;
|
|
1785
|
+
/**
|
|
1786
|
+
* Replaces the default group header rendered above grouped options.
|
|
1787
|
+
*/
|
|
1788
|
+
group?: (props: BbSelectPopoverGroupSlotProps<Item>) => any;
|
|
1789
|
+
/**
|
|
1790
|
+
* Content shown inside the options dropdown while items are loading.
|
|
1791
|
+
*/
|
|
1792
|
+
loading?: (props: { query: string }) => any;
|
|
1793
|
+
/**
|
|
1794
|
+
* Content shown when no options match the query or the list is empty.
|
|
1795
|
+
*/
|
|
1796
|
+
'no-data'?: (props: { query: string; focus: () => void }) => any;
|
|
1797
|
+
/**
|
|
1798
|
+
* Replaces the default rendering of each option row in the dropdown.
|
|
1799
|
+
*/
|
|
1800
|
+
option?: (props: BbSelectPopoverOptionSlotProps<Item>) => any;
|
|
1801
|
+
};
|
|
1802
|
+
```
|
|
1803
|
+
|
|
1804
|
+
## Styles
|
|
1805
|
+
|
|
1806
|
+
```css
|
|
1807
|
+
/* @inherit --transition-duration --option-height — set inline by the component */
|
|
1808
|
+
.bb-select-popover {
|
|
1809
|
+
overflow: visible;
|
|
1810
|
+
text-align: left;
|
|
1811
|
+
width: var(--w, 320px);
|
|
1812
|
+
|
|
1813
|
+
.bb-common-popover__bubble {
|
|
1814
|
+
box-shadow: var(--bb-shadow);
|
|
1815
|
+
overflow: hidden;
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
.bb-select-popover__search-container {
|
|
1819
|
+
align-items: center;
|
|
1820
|
+
border-bottom: 1px solid var(--bb-border);
|
|
1821
|
+
display: flex;
|
|
1822
|
+
padding: 0.375rem 0.75rem;
|
|
1823
|
+
position: relative;
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1826
|
+
/* `header` / `footer` slot regions: pinned above the search and below the
|
|
1827
|
+
options list. In the adaptive sheet the same slots render in the off-canvas
|
|
1828
|
+
header / footer instead, so these rules only apply to the popover. */
|
|
1829
|
+
.bb-select-popover__header {
|
|
1830
|
+
border-bottom: 1px solid var(--bb-border);
|
|
1831
|
+
padding: 0.5rem 0.75rem;
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
.bb-select-popover__footer {
|
|
1835
|
+
border-top: 1px solid var(--bb-border);
|
|
1836
|
+
padding: 0.5rem 0.75rem;
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
.bb-select-popover__search-icon,
|
|
1840
|
+
.bb-select-popover__search-error-icon,
|
|
1841
|
+
.bb-select-popover__search-warning-icon,
|
|
1842
|
+
.bb-select-popover__search-clear {
|
|
1843
|
+
color: var(--bb-text-muted);
|
|
1844
|
+
flex-shrink: 0;
|
|
1845
|
+
opacity: 0;
|
|
1846
|
+
pointer-events: none;
|
|
1847
|
+
position: absolute;
|
|
1848
|
+
right: 0.75rem;
|
|
1849
|
+
top: 50%;
|
|
1850
|
+
transform: translateY(-50%);
|
|
1851
|
+
transition:
|
|
1852
|
+
color 0.3s,
|
|
1853
|
+
opacity 0.3s;
|
|
1854
|
+
/* Sized to the option checkmark (0.875rem) and right-anchored to the same
|
|
1855
|
+
column, so the search lens/clear line up vertically with the ticks in
|
|
1856
|
+
the list below. */
|
|
1857
|
+
width: 0.875rem;
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
/* ClearableButton brings its own reset + focus ring. The clear (X) needs a
|
|
1861
|
+
larger box than the lens: its glyph fills far less of its viewBox than the
|
|
1862
|
+
magnifier, so at the lens' 0.875rem it reads tiny. Give it the full
|
|
1863
|
+
input-icon box, nudged 3px rightward off the shared right offset so its
|
|
1864
|
+
centre lands on the option checkmarks' column (the wider box would
|
|
1865
|
+
otherwise sit left of it). */
|
|
1866
|
+
.bb-select-popover__search-clear,
|
|
1867
|
+
.bb-select-popover__search-clear .bb-icon {
|
|
1868
|
+
width: var(--bb-input-icon);
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
.bb-select-popover__search-clear {
|
|
1872
|
+
right: calc(0.75rem - 3px);
|
|
1873
|
+
}
|
|
1874
|
+
|
|
1875
|
+
.bb-select-popover__search-clear:hover {
|
|
1876
|
+
color: var(--bb-text);
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
.bb-select-popover__search-input {
|
|
1880
|
+
background-color: transparent;
|
|
1881
|
+
border: 0;
|
|
1882
|
+
color: var(--bb-text);
|
|
1883
|
+
flex: 1 1 auto;
|
|
1884
|
+
font-size: var(--bb-input-fs);
|
|
1885
|
+
line-height: var(--bb-leading);
|
|
1886
|
+
outline: none;
|
|
1887
|
+
padding: 0;
|
|
1888
|
+
padding-right: calc(var(--bb-input-icon) + 0.5rem);
|
|
1889
|
+
width: 100%;
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
.bb-select-popover__search-icon {
|
|
1893
|
+
opacity: 1;
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
&.bb-select-popover--errors {
|
|
1897
|
+
.bb-select-popover__search-error-icon {
|
|
1898
|
+
color: var(--bb-danger);
|
|
1899
|
+
opacity: 1;
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1902
|
+
.bb-select-popover__search-icon {
|
|
1903
|
+
opacity: 0;
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
|
|
1907
|
+
&.bb-select-popover--warnings {
|
|
1908
|
+
.bb-select-popover__search-warning-icon {
|
|
1909
|
+
color: var(--bb-warn);
|
|
1910
|
+
opacity: 1;
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
.bb-select-popover__search-icon {
|
|
1914
|
+
opacity: 0;
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1918
|
+
/* Re-fetch over an existing result set: a 2px indeterminate strip on the
|
|
1919
|
+
search field's bottom border + faint options — identical to BbDropdown's
|
|
1920
|
+
searchable groups (no spinner). A first load (no options yet) shows the
|
|
1921
|
+
listbox's loading row instead. */
|
|
1922
|
+
.bb-select-popover__search-strip {
|
|
1923
|
+
animation: bb-select-popover-busy-slide 1.1s linear infinite;
|
|
1924
|
+
background: linear-gradient(
|
|
1925
|
+
90deg,
|
|
1926
|
+
transparent 0%,
|
|
1927
|
+
var(--bb-primary) 50%,
|
|
1928
|
+
transparent 100%
|
|
1929
|
+
);
|
|
1930
|
+
background-repeat: no-repeat;
|
|
1931
|
+
background-size: 40% 100%;
|
|
1932
|
+
bottom: -1px;
|
|
1933
|
+
height: 2px;
|
|
1934
|
+
inset-inline: 0;
|
|
1935
|
+
pointer-events: none;
|
|
1936
|
+
position: absolute;
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1939
|
+
&.bb-select-popover--reloading {
|
|
1940
|
+
.bb-listbox__option {
|
|
1941
|
+
opacity: 0.55;
|
|
1942
|
+
transition: opacity var(--bb-transition-fast, 0.15s) ease;
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
/* The clear replaces the lens whenever there is something to clear. It must
|
|
1947
|
+
be persistent (not hover-gated): selecting options moves focus off the
|
|
1948
|
+
search field, so a focus/hover-gated clear would flicker away on every
|
|
1949
|
+
pick. Suppressed only while the stack shows the error or warning icon.
|
|
1950
|
+
`:hover` below just deepens the clear's colour on pointer-over. */
|
|
1951
|
+
&.bb-select-popover--clearable-active:not(.bb-select-popover--errors):not(
|
|
1952
|
+
.bb-select-popover--warnings
|
|
1953
|
+
) {
|
|
1954
|
+
.bb-select-popover__search-icon {
|
|
1955
|
+
opacity: 0;
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1958
|
+
.bb-select-popover__search-clear {
|
|
1959
|
+
opacity: 1;
|
|
1960
|
+
pointer-events: auto;
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1964
|
+
.bb-listbox {
|
|
1965
|
+
--option-h: var(--option-height);
|
|
1966
|
+
display: block;
|
|
1967
|
+
user-select: none;
|
|
1968
|
+
|
|
1969
|
+
&.bb-listbox--open {
|
|
1970
|
+
transition: min-height 0s 0s;
|
|
1971
|
+
|
|
1972
|
+
.bb-listbox__outer-container {
|
|
1973
|
+
grid-template-rows: 1fr;
|
|
1974
|
+
opacity: 1;
|
|
1975
|
+
transition-delay: 0s, 0ms;
|
|
1976
|
+
|
|
1977
|
+
> * {
|
|
1978
|
+
opacity: 1;
|
|
1979
|
+
transition-delay: calc(var(--transition-duration) * 0.8);
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1984
|
+
&.bb-listbox--no-data {
|
|
1985
|
+
.bb-listbox__outer-container {
|
|
1986
|
+
.bb-listbox__inner-container {
|
|
1987
|
+
.bb-listbox__no-data {
|
|
1988
|
+
display: block;
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
|
|
1994
|
+
&.bb-listbox--loading {
|
|
1995
|
+
.bb-listbox__outer-container {
|
|
1996
|
+
.bb-listbox__inner-container {
|
|
1997
|
+
.bb-listbox__loading {
|
|
1998
|
+
display: block;
|
|
1999
|
+
text-align: left;
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
|
|
2005
|
+
.bb-listbox__outer-container {
|
|
2006
|
+
background-color: var(--bb-panel);
|
|
2007
|
+
border-width: 0;
|
|
2008
|
+
display: grid;
|
|
2009
|
+
grid-template-rows: 0fr;
|
|
2010
|
+
opacity: 0;
|
|
2011
|
+
transition-delay: calc(var(--transition-duration) * 0.25), 0s, 0s;
|
|
2012
|
+
transition-duration:
|
|
2013
|
+
var(--transition-duration), calc(var(--transition-duration) * 1.4),
|
|
2014
|
+
var(--transition-duration);
|
|
2015
|
+
transition-property: grid-template-rows, opacity, border;
|
|
2016
|
+
|
|
2017
|
+
> * {
|
|
2018
|
+
opacity: 0;
|
|
2019
|
+
transition-delay: 0s;
|
|
2020
|
+
transition-duration: calc(var(--transition-duration) * 2);
|
|
2021
|
+
transition-property: opacity;
|
|
2022
|
+
}
|
|
2023
|
+
|
|
2024
|
+
.bb-listbox__inner-container {
|
|
2025
|
+
max-height: min(
|
|
2026
|
+
calc(var(--option-h) * 6 + 0.5rem),
|
|
2027
|
+
calc(round(down, calc(100dvh - 130px), var(--option-h)) - 1px)
|
|
2028
|
+
);
|
|
2029
|
+
overflow: auto;
|
|
2030
|
+
overflow-x: clip;
|
|
2031
|
+
padding: 0.25rem;
|
|
2032
|
+
text-align: left;
|
|
2033
|
+
|
|
2034
|
+
.bb-listbox__loading,
|
|
2035
|
+
.bb-listbox__no-data {
|
|
2036
|
+
color: color-mix(in oklab, var(--bb-text) 45%, transparent);
|
|
2037
|
+
display: none;
|
|
2038
|
+
font-size: 0.8125rem;
|
|
2039
|
+
padding: 0.375rem 0.5rem;
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
span[role='listbox'] {
|
|
2043
|
+
display: block;
|
|
2044
|
+
position: relative;
|
|
2045
|
+
width: 100%;
|
|
2046
|
+
|
|
2047
|
+
.bb-listbox__group {
|
|
2048
|
+
display: block;
|
|
2049
|
+
left: 0;
|
|
2050
|
+
position: absolute;
|
|
2051
|
+
top: 0;
|
|
2052
|
+
width: 100%;
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
.bb-listbox__group-header {
|
|
2056
|
+
align-items: center;
|
|
2057
|
+
display: flex;
|
|
2058
|
+
height: var(--group-header-height, 32px);
|
|
2059
|
+
padding: 0 0.5rem;
|
|
2060
|
+
user-select: none;
|
|
2061
|
+
|
|
2062
|
+
.bb-listbox__group-header-label {
|
|
2063
|
+
color: color-mix(in oklab, var(--bb-text) 45%, transparent);
|
|
2064
|
+
flex: auto;
|
|
2065
|
+
font-size: 0.75rem;
|
|
2066
|
+
font-weight: 500;
|
|
2067
|
+
overflow: hidden;
|
|
2068
|
+
text-align: left;
|
|
2069
|
+
text-overflow: ellipsis;
|
|
2070
|
+
white-space: nowrap;
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
|
|
2074
|
+
.bb-listbox__option {
|
|
2075
|
+
display: block;
|
|
2076
|
+
left: 0;
|
|
2077
|
+
position: absolute;
|
|
2078
|
+
top: 0;
|
|
2079
|
+
width: 100%;
|
|
2080
|
+
}
|
|
2081
|
+
|
|
2082
|
+
.bb-listbox__group > .bb-listbox__option {
|
|
2083
|
+
position: static;
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
.autocomplete-option {
|
|
2087
|
+
align-items: center;
|
|
2088
|
+
border-radius: clamp(
|
|
2089
|
+
0px,
|
|
2090
|
+
calc(var(--bb-radius) - 4px),
|
|
2091
|
+
calc(var(--bb-input-h) / 2)
|
|
2092
|
+
);
|
|
2093
|
+
color: var(--bb-text);
|
|
2094
|
+
cursor: pointer;
|
|
2095
|
+
display: flex;
|
|
2096
|
+
gap: 0.5rem;
|
|
2097
|
+
height: var(--option-h);
|
|
2098
|
+
padding-left: 0.5rem;
|
|
2099
|
+
padding-right: 0.5rem;
|
|
2100
|
+
transition: background-color 150ms ease;
|
|
2101
|
+
width: 100%;
|
|
2102
|
+
|
|
2103
|
+
&:hover:not(.autocomplete-option--disabled),
|
|
2104
|
+
&--focused:not(.autocomplete-option--disabled) {
|
|
2105
|
+
background-color: color-mix(
|
|
2106
|
+
in oklab,
|
|
2107
|
+
var(--bb-text) 8%,
|
|
2108
|
+
transparent
|
|
2109
|
+
);
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
&--disabled {
|
|
2113
|
+
cursor: not-allowed;
|
|
2114
|
+
opacity: 0.5;
|
|
2115
|
+
}
|
|
2116
|
+
|
|
2117
|
+
&__label {
|
|
2118
|
+
flex: 1 1 auto;
|
|
2119
|
+
font-size: 0.875rem;
|
|
2120
|
+
min-width: 0;
|
|
2121
|
+
overflow: hidden;
|
|
2122
|
+
text-align: left;
|
|
2123
|
+
text-overflow: ellipsis;
|
|
2124
|
+
white-space: nowrap;
|
|
2125
|
+
}
|
|
2126
|
+
|
|
2127
|
+
&__check {
|
|
2128
|
+
color: var(--bb-text);
|
|
2129
|
+
flex-shrink: 0;
|
|
2130
|
+
height: 0.875rem;
|
|
2131
|
+
width: 0.875rem;
|
|
2132
|
+
|
|
2133
|
+
path {
|
|
2134
|
+
stroke-dasharray: 30;
|
|
2135
|
+
stroke-dashoffset: 30;
|
|
2136
|
+
transition: stroke-dashoffset var(--bb-transition-medium)
|
|
2137
|
+
var(--bb-ease);
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
&--selected {
|
|
2142
|
+
.autocomplete-option__check {
|
|
2143
|
+
path {
|
|
2144
|
+
stroke-dashoffset: 0;
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
|
|
2155
|
+
@keyframes bb-select-popover-busy-slide {
|
|
2156
|
+
from {
|
|
2157
|
+
background-position: -40% 0;
|
|
2158
|
+
}
|
|
2159
|
+
|
|
2160
|
+
to {
|
|
2161
|
+
background-position: 140% 0;
|
|
2162
|
+
}
|
|
2163
|
+
}
|
|
2164
|
+
|
|
2165
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2166
|
+
.bb-select-popover .bb-select-popover__search-strip {
|
|
2167
|
+
animation: none;
|
|
2168
|
+
background: var(--bb-primary);
|
|
2169
|
+
opacity: 0.5;
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
/* ------------------------------------------------------------------------- */
|
|
2174
|
+
/* Adaptive bottom sheet */
|
|
2175
|
+
/* The sheet reuses every `.bb-select-popover` descendant rule (search field, */
|
|
2176
|
+
/* listbox, options) verbatim; this section only overrides the fixed popover */
|
|
2177
|
+
/* width, stacks the regions vertically and styles the selection summary that */
|
|
2178
|
+
/* sits above the search. Declared after the base block so equal-specificity */
|
|
2179
|
+
/* overrides (width, listbox max-height) win on source order. */
|
|
2180
|
+
/* ------------------------------------------------------------------------- */
|
|
2181
|
+
.bb-select-popover.bb-select-popover--sheet {
|
|
2182
|
+
display: flex;
|
|
2183
|
+
flex-direction: column;
|
|
2184
|
+
min-height: 0;
|
|
2185
|
+
overflow: hidden;
|
|
2186
|
+
width: 100%;
|
|
2187
|
+
}
|
|
2188
|
+
|
|
2189
|
+
.bb-select-popover--sheet {
|
|
2190
|
+
/* Selection sits above the search; search + listbox keep the popover styling
|
|
2191
|
+
(they are the same `.bb-select-popover` descendants). */
|
|
2192
|
+
.bb-select-popover__sheet-selection {
|
|
2193
|
+
flex-shrink: 0;
|
|
2194
|
+
padding: 0 0.25rem 0.625rem;
|
|
2195
|
+
text-align: left;
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
.bb-select-popover__sheet-chips {
|
|
2199
|
+
display: flex;
|
|
2200
|
+
flex-wrap: wrap;
|
|
2201
|
+
gap: 0.375rem;
|
|
2202
|
+
}
|
|
2203
|
+
|
|
2204
|
+
.bb-select-popover__sheet-single {
|
|
2205
|
+
color: var(--bb-text);
|
|
2206
|
+
font-size: var(--bb-input-fs);
|
|
2207
|
+
line-height: var(--bb-leading);
|
|
2208
|
+
overflow: hidden;
|
|
2209
|
+
text-overflow: ellipsis;
|
|
2210
|
+
white-space: nowrap;
|
|
2211
|
+
}
|
|
2212
|
+
|
|
2213
|
+
/* Options list breathes a little more on a sheet and scrolls internally. */
|
|
2214
|
+
.bb-listbox {
|
|
2215
|
+
flex: 1 1 auto;
|
|
2216
|
+
min-height: 0;
|
|
2217
|
+
}
|
|
2218
|
+
|
|
2219
|
+
.bb-listbox .bb-listbox__outer-container .bb-listbox__inner-container {
|
|
2220
|
+
max-height: min(
|
|
2221
|
+
calc(var(--option-h) * 9 + 0.5rem),
|
|
2222
|
+
calc(round(down, 55dvh, var(--option-h)) - 1px)
|
|
2223
|
+
);
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
|
|
2227
|
+
/* When a footer slot is present, drop the sheet body's bottom padding so the
|
|
2228
|
+
footer (which brings its own border-top + padding) sits flush against the
|
|
2229
|
+
options instead of leaving a gap. */
|
|
2230
|
+
.bb-select-popover-offcanvas:has(.bb-offcanvas__footer:not(:empty))
|
|
2231
|
+
.bb-offcanvas__body-content {
|
|
2232
|
+
padding-bottom: 0;
|
|
2233
|
+
}
|
|
2234
|
+
```
|