bitboss-ui 3.0.0-beta.47 → 3.0.0-beta.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -7
- package/bin/bitboss-ui-mcp.mjs +15 -3
- package/bin/bitboss-ui.mjs +167 -14
- package/dist/ai/BbAccordion.md +1 -1
- package/dist/ai/BbAvatar.md +1 -1
- package/dist/ai/BbBreadcrumbs.md +65 -65
- package/dist/ai/BbButton.md +28 -8
- package/dist/ai/BbCheckbox.md +0 -2
- package/dist/ai/BbCheckboxGroup.md +13 -20
- package/dist/ai/BbCollapsible.md +1 -1
- package/dist/ai/BbColorPalette.md +1 -1
- package/dist/ai/BbConfirm.md +8 -0
- package/dist/ai/BbConfirmPortal.md +1 -1
- package/dist/ai/BbDatePickerInput.md +4 -2
- package/dist/ai/BbDialog.md +1 -8
- package/dist/ai/BbDropdown.md +231 -220
- package/dist/ai/BbDropdownButton.md +65 -65
- package/dist/ai/BbDropdownGroup.md +2 -2
- package/dist/ai/BbDropzone.md +10 -10
- package/dist/ai/BbForm.md +43 -52
- package/dist/ai/BbHoverCard.md +19 -7
- package/dist/ai/BbHoverCardPortal.md +1 -1
- package/dist/ai/BbNumberInput.md +88 -21
- package/dist/ai/BbPopover.md +47 -40
- package/dist/ai/BbPopoverPortal.md +1 -1
- package/dist/ai/BbProgress.md +48 -22
- package/dist/ai/BbRadioGroup.md +13 -19
- package/dist/ai/BbSelect.md +16 -36
- package/dist/ai/BbSelectPopover.md +14 -30
- package/dist/ai/BbSmoothHeight.md +0 -2
- package/dist/ai/BbSwitchGroup.md +13 -20
- package/dist/ai/BbTable.md +11 -10
- package/dist/ai/BbTabs.md +107 -106
- package/dist/ai/BbTabsList.md +2 -2
- package/dist/ai/BbTabsPanels.md +1 -1
- package/dist/ai/BbTabsRoot.md +3 -3
- package/dist/ai/BbTooltip.md +29 -13
- package/dist/ai/BbTree.md +14 -11
- package/dist/ai/CommonPopover.md +1 -1
- package/dist/ai/changelog.json +297 -6
- package/dist/ai/components.json +50 -45
- package/dist/ai/composables/useBbDropdownContext.md +16 -16
- package/dist/ai/composables/useBbFormField.md +5 -1
- package/dist/ai/composables/useBbTabsContext.md +14 -14
- package/dist/ai/guides/agent-contract.md +27 -27
- package/dist/ai/guides/ai-router.md +1 -1
- package/dist/ai/guides/component-picker.md +3 -3
- package/dist/ai/guides/fetch-items-playbook.md +1 -1
- package/dist/ai/guides/icons-policy.md +10 -10
- package/dist/ai/guides/inertia-helpers.md +120 -67
- package/dist/ai/guides/installation-and-plugin-setup.md +45 -15
- package/dist/ai/guides/migration/components/bb-breadcrumbs.md +3 -2
- package/dist/ai/guides/migration/components/bb-checkbox-group.md +16 -16
- package/dist/ai/guides/migration/components/bb-dropdown-button.md +9 -8
- package/dist/ai/guides/migration/components/bb-dropdown.md +15 -14
- package/dist/ai/guides/migration/components/bb-radio-group.md +2 -1
- package/dist/ai/guides/migration/components/bb-select-popover.md +6 -1
- package/dist/ai/guides/migration/components/bb-select.md +10 -2
- package/dist/ai/guides/migration/components/bb-switch-group.md +2 -1
- package/dist/ai/guides/migration/components/bb-tabs.md +9 -8
- package/dist/ai/guides/migration/components/bb-tooltip.md +1 -1
- package/dist/ai/guides/migration/v2-to-v3.md +143 -28
- package/dist/ai/guides/migration/v3-beta-css-classes.md +29 -27
- package/dist/ai/guides/migration/v3-beta-tooling.md +11 -0
- package/dist/ai/guides/options-items-playbook.md +30 -24
- package/dist/ai/guides/passthrough.md +4 -4
- package/dist/ai/guides/preset-components.md +18 -3
- package/dist/ai/guides/typescript-generic-components.md +1 -1
- package/dist/ai/guides/validated-forms.md +11 -22
- package/dist/ai/guides/validation-providers.md +4 -3
- package/dist/ai/helpers/inertia/manifest.json +636 -0
- package/dist/ai/helpers/inertia/types.ts +15 -0
- package/dist/ai/helpers/inertia/useAsyncFn.ts +110 -0
- package/dist/ai/helpers/inertia/useConfirmOnRouteLeave.ts +102 -0
- package/dist/ai/helpers/inertia/useDeleteCmd.ts +30 -0
- package/dist/ai/helpers/inertia/useHasChanged.ts +36 -0
- package/dist/ai/helpers/inertia/useIndexById.ts +23 -0
- package/dist/ai/helpers/inertia/useLazyProp.ts +148 -0
- package/dist/ai/helpers/inertia/useLazyPropGetter.ts +50 -0
- package/dist/ai/helpers/inertia/useLoading.ts +20 -0
- package/dist/ai/helpers/inertia/usePaginatedResponseContext.ts +88 -0
- package/dist/ai/helpers/inertia/usePromiseForm.ts +62 -0
- package/dist/ai/helpers/inertia/useProp.ts +63 -0
- package/dist/ai/helpers/inertia/useQuery.ts +19 -0
- package/dist/ai/helpers/inertia/useQueryObject.ts +116 -0
- package/dist/ai/helpers/inertia/useResourceContext.ts +69 -0
- package/dist/ai/helpers/inertia/useRouteQuery.ts +54 -0
- package/dist/ai/helpers/inertia/useScreenSizes.ts +23 -0
- package/dist/ai/helpers/inertia/useTableContext.ts +34 -0
- package/dist/ai/helpers/inertia/useTableSelectionContext.ts +48 -0
- package/dist/ai/helpers/inertia/useUntil.ts +33 -0
- package/dist/ai/helpers/inertia/utils.ts +24 -0
- package/dist/ai/index.md +6 -6
- package/dist/ai/manifest/components/BbAccordion.json +1 -1
- package/dist/ai/manifest/components/BbBreadcrumbs.json +10 -6
- package/dist/ai/manifest/components/BbBreadcrumbs.tree.json +1 -1
- package/dist/ai/manifest/components/BbButton.json +2 -1
- package/dist/ai/manifest/components/BbButton.tree.json +1 -1
- package/dist/ai/manifest/components/BbCheckboxGroup.json +2 -2
- package/dist/ai/manifest/components/BbCollapsible.json +1 -1
- package/dist/ai/manifest/components/BbColorPalette.json +1 -1
- package/dist/ai/manifest/components/BbConfirmPortal.json +5 -2
- package/dist/ai/manifest/components/BbDropdown.json +23 -20
- package/dist/ai/manifest/components/BbDropdown.tree.json +2 -2
- package/dist/ai/manifest/components/BbDropdownButton.json +22 -19
- package/dist/ai/manifest/components/BbDropdownButton.tree.json +1 -1
- package/dist/ai/manifest/components/BbDropdownGroup.json +2 -2
- package/dist/ai/manifest/components/BbForm.json +1 -0
- package/dist/ai/manifest/components/BbHoverCard.json +1 -1
- package/dist/ai/manifest/components/BbHoverCardPortal.json +2 -2
- package/dist/ai/manifest/components/BbNumberInput.json +6 -1
- package/dist/ai/manifest/components/BbNumberInput.tree.json +2 -1
- package/dist/ai/manifest/components/BbPopover.json +2 -1
- package/dist/ai/manifest/components/BbPopoverPortal.json +2 -2
- package/dist/ai/manifest/components/BbProgress.json +6 -6
- package/dist/ai/manifest/components/BbProgress.tree.json +1 -0
- package/dist/ai/manifest/components/BbRadioGroup.json +2 -2
- package/dist/ai/manifest/components/BbSelect.json +2 -2
- package/dist/ai/manifest/components/BbSelect.tree.json +2 -2
- package/dist/ai/manifest/components/BbSelectPopover.json +2 -2
- package/dist/ai/manifest/components/BbSelectPopover.tree.json +1 -1
- package/dist/ai/manifest/components/BbSwitchGroup.json +2 -2
- package/dist/ai/manifest/components/BbTabs.json +8 -7
- package/dist/ai/manifest/components/BbTabsList.json +3 -3
- package/dist/ai/manifest/components/BbTabsPanels.json +1 -1
- package/dist/ai/manifest/components/BbTabsRoot.json +6 -5
- package/dist/ai/manifest/components/BbTag.tree.json +1 -1
- package/dist/ai/manifest/components/BbTooltip.json +2 -2
- package/dist/ai/manifest/components/ChipsBox.tree.json +1 -1
- package/dist/ai/manifest/components/CommonPopover.json +1 -1
- package/dist/ai/manifest/index.json +2 -2
- package/dist/ai/manifest/meta.json +5 -0
- package/dist/ai/manifest/types.advanced.json +10 -9
- package/dist/ai/manifest/types.api.json +8 -5
- package/dist/ai/manifest/types.wrapper.json +1 -0
- package/dist/ai/recipes/inertia/approvals-inbox.md +16 -18
- package/dist/ai/recipes/inertia/inline-edit-workspace.md +23 -33
- package/dist/ai/recipes/inertia/layout-scaffold.md +16 -16
- package/dist/ai/recipes/inertia/onboarding.md +6 -10
- package/dist/ai/recipes/inertia/ownership-atlas.md +15 -18
- package/dist/ai/recipes/inertia/record-form.md +11 -11
- package/dist/ai/recipes/inertia/records-workspace.md +38 -41
- package/dist/ai/recipes/inertia/settings-workspace.md +26 -38
- package/dist/ai/recipes/inertia/upload-center.md +31 -39
- package/dist/ai/recipes/inertia/wizard-form.md +10 -19
- package/dist/ai/recipes/nuxt/approvals-inbox.md +7 -8
- package/dist/ai/recipes/nuxt/inline-edit-workspace.md +14 -24
- package/dist/ai/recipes/nuxt/layout-scaffold.md +16 -16
- package/dist/ai/recipes/nuxt/onboarding.md +2 -6
- package/dist/ai/recipes/nuxt/ownership-atlas.md +7 -9
- package/dist/ai/recipes/nuxt/record-form.md +5 -5
- package/dist/ai/recipes/nuxt/records-workspace.md +29 -31
- package/dist/ai/recipes/nuxt/settings-workspace.md +22 -34
- package/dist/ai/recipes/nuxt/upload-center.md +22 -29
- package/dist/ai/recipes/nuxt/wizard-form.md +3 -11
- package/dist/ai/recipes/vue/approvals-inbox.md +7 -8
- package/dist/ai/recipes/vue/inline-edit-workspace.md +14 -24
- package/dist/ai/recipes/vue/layout-scaffold.md +16 -16
- package/dist/ai/recipes/vue/onboarding.md +2 -6
- package/dist/ai/recipes/vue/ownership-atlas.md +7 -9
- package/dist/ai/recipes/vue/record-form.md +5 -5
- package/dist/ai/recipes/vue/records-workspace.md +29 -31
- package/dist/ai/recipes/vue/settings-workspace.md +22 -34
- package/dist/ai/recipes/vue/upload-center.md +22 -29
- package/dist/ai/recipes/vue/wizard-form.md +3 -11
- package/dist/ai/source/BbAccordion.md +1 -1
- package/dist/ai/source/BbAlert.md +3 -3
- package/dist/ai/source/BbBadge.md +14 -10
- package/dist/ai/source/BbBadgeButton.md +17 -12
- package/dist/ai/source/BbBaseButton.md +1 -1
- package/dist/ai/source/BbBaseRadioIcon.md +1 -0
- package/dist/ai/source/BbBaseSwitchIcon.md +1 -0
- package/dist/ai/source/BbBreadcrumbs.md +63 -42
- package/dist/ai/source/BbButton.md +84 -38
- package/dist/ai/source/BbCalendar.md +17 -16
- package/dist/ai/source/BbCheckbox.md +3 -2
- package/dist/ai/source/BbCheckboxGroup.md +11 -4
- package/dist/ai/source/BbCollapsible.md +2 -1
- package/dist/ai/source/BbColorInput.md +10 -9
- package/dist/ai/source/BbColorPalette.md +2 -1
- package/dist/ai/source/BbConfirm.md +18 -1
- package/dist/ai/source/BbConfirmPortal.md +20 -6
- package/dist/ai/source/BbDatePicker.md +2 -2
- package/dist/ai/source/BbDatePickerInput.md +47 -20
- package/dist/ai/source/BbDialog.md +5 -5
- package/dist/ai/source/BbDropdown.md +231 -158
- package/dist/ai/source/BbDropdownButton.md +19 -12
- package/dist/ai/source/BbDropdownGroup.md +127 -93
- package/dist/ai/source/BbForm.md +25 -1
- package/dist/ai/source/BbHoverCard.md +30 -3
- package/dist/ai/source/BbHoverCardPortal.md +18 -3
- package/dist/ai/source/BbIndicator.md +4 -0
- package/dist/ai/source/BbNumberInput.md +855 -19
- package/dist/ai/source/BbOffCanvas.md +27 -11
- package/dist/ai/source/BbPagination.md +3 -3
- package/dist/ai/source/BbPopover.md +185 -12
- package/dist/ai/source/BbPopoverPortal.md +30 -3
- package/dist/ai/source/BbProgress.md +82 -18
- package/dist/ai/source/BbRadioGroup.md +12 -5
- package/dist/ai/source/BbRating.md +11 -9
- package/dist/ai/source/BbSelect.md +16 -10
- package/dist/ai/source/BbSelectPopover.md +29 -23
- package/dist/ai/source/BbSlider.md +12 -6
- package/dist/ai/source/BbSwitch.md +3 -2
- package/dist/ai/source/BbSwitchGroup.md +5 -2
- package/dist/ai/source/BbTable.md +102 -18
- package/dist/ai/source/BbTabs.md +30 -24
- package/dist/ai/source/BbTabsList.md +29 -23
- package/dist/ai/source/BbTabsPanels.md +29 -23
- package/dist/ai/source/BbTabsRoot.md +28 -22
- package/dist/ai/source/BbTag.md +10 -9
- package/dist/ai/source/BbTextInput.md +5 -4
- package/dist/ai/source/BbTextarea.md +6 -5
- package/dist/ai/source/BbTimePicker.md +1 -1
- package/dist/ai/source/BbTimePickerInput.md +46 -9
- package/dist/ai/source/BbToast.md +10 -7
- package/dist/ai/source/BbToastPortal.md +10 -7
- package/dist/ai/source/BbTooltip.md +88 -11
- package/dist/ai/source/BbTree.md +21 -3
- package/dist/ai/source/CommonField.md +6 -4
- package/dist/ai/source/CommonFieldInput.md +15 -10
- package/dist/ai/source/CommonPopover.md +8 -1
- package/dist/ai/source/CommonTimeSelector.md +5 -4
- package/dist/components/BbBadge/BbBadgeButton.vue_vue_type_script_setup_true_lang.js +10 -8
- package/dist/components/BbBaseButton/BbBaseButton.vue_vue_type_script_setup_true_lang.js +8 -8
- package/dist/components/BbBreadcrumbs/BbBreadcrumbs.vue_vue_type_script_setup_true_lang.js +45 -45
- package/dist/components/BbBreadcrumbs/types.d.ts +25 -17
- package/dist/components/BbButton/BbButton.vue_vue_type_script_setup_true_lang.js +88 -70
- package/dist/components/BbButton/toggleRoving.d.ts +6 -0
- package/dist/components/BbButton/toggleRoving.js +45 -0
- package/dist/components/BbButton/types.d.ts +12 -4
- package/dist/components/BbButton/types.js +5 -1
- package/dist/components/BbCalendar/BbCalendar.vue_vue_type_script_setup_true_lang.js +178 -178
- package/dist/components/BbCalendar/CalendarMonthPanel.vue_vue_type_script_setup_true_lang.js +15 -15
- package/dist/components/BbCalendar/CalendarYearPanel.vue_vue_type_script_setup_true_lang.js +28 -28
- package/dist/components/BbCalendar/useCalendarGrid.js +141 -139
- package/dist/components/BbCalendar/useDayjsLocale.d.ts +38 -15
- package/dist/components/BbCalendar/useDayjsLocale.js +31 -30
- package/dist/components/BbCheckbox/BbCheckbox.vue_vue_type_script_setup_true_lang.js +48 -48
- package/dist/components/BbCheckboxGroup/BbCheckboxGroup.vue_vue_type_script_setup_true_lang.js +81 -80
- package/dist/components/BbCheckboxGroup/types.d.ts +6 -2
- package/dist/components/BbCollapsible/types.d.ts +2 -1
- package/dist/components/BbColorInput/BbColorInput.vue_vue_type_script_setup_true_lang.js +69 -69
- package/dist/components/BbColorPalette/types.d.ts +2 -1
- package/dist/components/BbConfirm/BbConfirmPortal.vue.d.ts +2 -5
- package/dist/components/BbConfirm/types.d.ts +15 -0
- package/dist/components/BbDatePickerInput/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +363 -349
- package/dist/components/BbDropdown/AdaptiveDropdown.vue_vue_type_script_setup_true_lang.js +91 -86
- package/dist/components/BbDropdown/BbDropdown.vue_vue_type_script_setup_true_lang.js +298 -289
- package/dist/components/BbDropdown/BbDropdownList.vue_vue_type_script_setup_true_lang.js +322 -356
- package/dist/components/BbDropdown/DropdownPipelineResolver.vue_vue_type_script_setup_true_lang.js +17 -15
- package/dist/components/BbDropdown/DropdownRow.vue.d.ts +40 -0
- package/dist/components/BbDropdown/DropdownRow.vue.js +5 -0
- package/dist/components/BbDropdown/DropdownRow.vue_vue_type_script_setup_true_lang.js +60 -0
- package/dist/components/BbDropdown/normalizeGroups.d.ts +8 -2
- package/dist/components/BbDropdown/normalizeGroups.js +60 -46
- package/dist/components/BbDropdown/types.d.ts +120 -88
- package/dist/components/BbDropdownButton/BbDropdownButton.vue_vue_type_script_setup_true_lang.js +11 -2
- package/dist/components/BbDropdownButton/types.d.ts +2 -2
- package/dist/components/BbForm/BbForm.vue.d.ts +9 -0
- package/dist/components/BbForm/BbForm.vue_vue_type_script_setup_true_lang.js +114 -105
- package/dist/components/BbForm/BbFormCustomField.js +1 -1
- package/dist/components/BbForm/bindFormField.js +2 -1
- package/dist/components/BbForm/formFields.d.ts +5 -0
- package/dist/components/BbHoverCard/BbHoverCard.vue_vue_type_script_setup_true_lang.js +145 -142
- package/dist/components/BbHoverCard/BbHoverCardPortal.vue.d.ts +2 -2
- package/dist/components/BbHoverCard/types.d.ts +14 -1
- package/dist/components/BbNumberInput/BbNumberInput.vue.d.ts +0 -1
- package/dist/components/BbNumberInput/BbNumberInput.vue_vue_type_script_setup_true_lang.js +452 -125
- package/dist/components/BbNumberInput/numberDisplay.d.ts +256 -0
- package/dist/components/BbNumberInput/numberDisplay.js +499 -0
- package/dist/components/BbNumberInput/types.d.ts +54 -1
- package/dist/components/BbNumberInput/warroom/corpus.d.ts +58 -0
- package/dist/components/BbNumberInput/warroom/currency-verify.rows.d.ts +28 -0
- package/dist/components/BbNumberInput/warroom/currency.rows.d.ts +2 -0
- package/dist/components/BbNumberInput/warroom/harness.d.ts +217 -0
- package/dist/components/BbNumberInput/warroom/oracle.d.ts +150 -0
- package/dist/components/BbPagination/BbPagination.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/BbPopover/BbPopover.vue.d.ts +1 -0
- package/dist/components/BbPopover/BbPopover.vue_vue_type_script_setup_true_lang.js +207 -162
- package/dist/components/BbPopover/BbPopoverPortal.vue.d.ts +2 -2
- package/dist/components/BbPopover/types.d.ts +26 -1
- package/dist/components/BbProgress/BbProgress.vue_vue_type_script_setup_true_lang.js +15 -7
- package/dist/components/BbProgress/types.d.ts +23 -7
- package/dist/components/BbProgress/types.js +1 -1
- package/dist/components/BbRadioGroup/BbRadioGroup.vue_vue_type_script_setup_true_lang.js +102 -101
- package/dist/components/BbRadioGroup/types.d.ts +6 -2
- package/dist/components/BbRating/BbRating.vue_vue_type_script_setup_true_lang.js +63 -63
- package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +156 -154
- package/dist/components/BbSelect/types.d.ts +6 -2
- package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/components/BbSelectPopover/types.d.ts +6 -2
- package/dist/components/BbSlider/BbSlider.vue_vue_type_script_setup_true_lang.js +153 -153
- package/dist/components/BbSwitch/BbSwitch.vue_vue_type_script_setup_true_lang.js +62 -62
- package/dist/components/BbSwitchGroup/BbSwitchGroup.vue_vue_type_script_setup_true_lang.js +131 -130
- package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +711 -676
- package/dist/components/BbTabs/BbTabs.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/BbTabs/BbTabsList.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/BbTabs/types.d.ts +28 -22
- package/dist/components/BbTag/BbTag.vue_vue_type_script_setup_true_lang.js +76 -76
- package/dist/components/BbTextInput/BbTextInput.vue_vue_type_script_setup_true_lang.js +58 -58
- package/dist/components/BbTextarea/BbTextarea.vue_vue_type_script_setup_true_lang.js +82 -82
- package/dist/components/BbTimePickerInput/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +246 -236
- package/dist/components/BbTooltip/BbTooltip.vue_vue_type_script_setup_true_lang.js +99 -86
- package/dist/components/BbTooltip/tooltipWarmup.d.ts +23 -0
- package/dist/components/BbTooltip/tooltipWarmup.js +7 -0
- package/dist/components/BbTooltip/types.d.ts +10 -3
- package/dist/components/BbTree/BbTree.vue_vue_type_script_setup_true_lang.js +29 -21
- package/dist/components/BbTree/BbTreeLevel.vue_vue_type_script_setup_true_lang.js +10 -7
- package/dist/components/CommonFieldInput/CommonFieldInput.vue_vue_type_script_setup_true_lang.js +37 -36
- package/dist/components/CommonPopover/types.d.ts +2 -1
- package/dist/components/CommonTimeSelector/CommonTimeSelector.vue_vue_type_script_setup_true_lang.js +9 -9
- package/dist/composables/formSubmitLock.d.ts +6 -0
- package/dist/composables/formSubmitLock.js +4 -0
- package/dist/composables/useBaseOptions.d.ts +7 -1
- package/dist/composables/useBaseOptions.js +32 -32
- package/dist/composables/useBbDropdownContext.d.ts +8 -8
- package/dist/composables/useBbFormField.d.ts +9 -0
- package/dist/composables/useBbFormField.js +5 -3
- package/dist/composables/useBbTabsContext.d.ts +10 -10
- package/dist/composables/useBbTabsContext.js +18 -18
- package/dist/composables/useFormBinding.d.ts +11 -0
- package/dist/composables/useFormBinding.js +15 -13
- package/dist/composables/useItemText.d.ts +5 -1
- package/dist/composables/useItemText.js +8 -3
- package/dist/composables/useItemValue.d.ts +5 -1
- package/dist/composables/useItemValue.js +8 -3
- package/dist/composables/useLocale.js +10 -9
- package/dist/deprecation/ai-deprecations.json.d.ts +130 -0
- package/dist/deprecation/ai-deprecations.json.js +1 -1
- package/dist/deprecation/removedProps.js +1 -1
- package/dist/directives/bbDropdown.js +1 -1
- package/dist/directives/directivePortal.d.ts +13 -7
- package/dist/directives/directivePortal.js +1 -4
- package/dist/i18n/index.d.ts +7 -12
- package/dist/i18n/locales/cs.json +11 -14
- package/dist/i18n/locales/da.json +13 -16
- package/dist/i18n/locales/de-CH.json +137 -0
- package/dist/i18n/locales/de.json +14 -17
- package/dist/i18n/locales/el.json +10 -13
- package/dist/i18n/locales/en-GB.json +137 -0
- package/dist/i18n/locales/en.json +8 -11
- package/dist/i18n/locales/es-MX.json +137 -0
- package/dist/i18n/locales/es.json +16 -19
- package/dist/i18n/locales/fi.json +8 -11
- package/dist/i18n/locales/fr.json +23 -26
- package/dist/i18n/locales/hu.json +8 -11
- package/dist/i18n/locales/it.json +12 -15
- package/dist/i18n/locales/ja.json +13 -16
- package/dist/i18n/locales/ko.json +10 -13
- package/dist/i18n/locales/nb.json +13 -16
- package/dist/i18n/locales/nl.json +21 -24
- package/dist/i18n/locales/pl.json +10 -13
- package/dist/i18n/locales/{pt.json → pt-BR.json} +19 -22
- package/dist/i18n/locales/pt-PT.json +137 -0
- package/dist/i18n/locales/ro.json +22 -25
- package/dist/i18n/locales/ru.json +11 -14
- package/dist/i18n/locales/sv.json +16 -19
- package/dist/i18n/locales/tr.json +14 -17
- package/dist/i18n/locales/uk.json +11 -14
- package/dist/i18n/locales/{zh-cn.json → zh-CN.json} +10 -13
- package/dist/i18n/locales/zh-HK.json +137 -0
- package/dist/i18n/locales/zh-TW.json +137 -0
- package/dist/i18n/regionHints.d.ts +16 -0
- package/dist/i18n/regionHints.js +49 -0
- package/dist/i18n/regions.d.ts +286 -0
- package/dist/i18n/regions.js +265 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -4
- package/dist/llms-full.txt +1914 -1714
- package/dist/llms-medium.txt +76 -46
- package/dist/llms.txt +7 -7
- package/dist/locale-blueprint.json +16 -13
- package/dist/styles.css +2 -2
- package/dist/types/passthrough.d.ts +1 -1
- package/dist/types/ptComponentMap.d.ts +2 -2
- package/dist/utilities/functions/slotKey.d.ts +2 -2
- package/dist/utils/versionCheck.js +1 -1
- package/dist/vite-plugin.d.ts +22 -19
- package/dist/vite.js +309 -297
- package/llms.txt +7 -7
- package/package.json +5 -3
- package/scripts/lib/agent-manifest.mjs +2 -1
- package/scripts/lib/eslint-disable.mjs +17 -4
- package/scripts/lib/eslint-plugin.d.ts +9 -1
- package/scripts/lib/eslint-plugin.mjs +256 -6
- package/scripts/lib/helper-canon.mjs +176 -0
- package/scripts/lib/helpers-add.mjs +1303 -0
- package/scripts/lib/local-components.mjs +33 -4
- package/scripts/lib/locale-check.mjs +165 -0
- package/scripts/lib/portal-names.mjs +458 -0
- package/scripts/lib/redundant-item-accessor.mjs +398 -0
- package/scripts/lib/renamed-item-field.mjs +343 -0
- package/scripts/lib/slot-key.mjs +2 -2
- package/scripts/lib/slot-renames.mjs +1 -1
- package/scripts/lib/unimported-components.mjs +5 -2
- package/scripts/lib/validate-bb-markup.mjs +123 -56
- package/dist/i18n/index.js +0 -27
package/dist/ai/BbDropdown.md
CHANGED
|
@@ -48,31 +48,33 @@ handling in markup — hand `BbDropdown` an `items` array.
|
|
|
48
48
|
|
|
49
49
|
An `items` entry is one of three shapes, and you can mix them freely:
|
|
50
50
|
|
|
51
|
-
- a **menu item** — an object with a `
|
|
51
|
+
- a **menu item** — an object with a `value` and a `label`;
|
|
52
52
|
- a **separator section** — a nested `[ … ]` array, rendered as its own
|
|
53
53
|
divider-separated anonymous group;
|
|
54
|
-
- a **group object** — `{
|
|
55
|
-
selectable section (next sections). A group's heading is `label`
|
|
54
|
+
- a **group object** — `{ id, label?, items, selectable?, … }`, a titled and/or
|
|
55
|
+
selectable section (next sections). A group's heading is its `label` too;
|
|
56
56
|
add `hideLabel` to keep the `label` for the adaptive sheet title / chips /
|
|
57
57
|
`useBbDropdownContext` while rendering no heading in the menu.
|
|
58
58
|
|
|
59
59
|
Each item extends `BbBaseButton`'s prop surface, so an item is an action, a
|
|
60
60
|
link, or a submenu opener depending on which fields it carries:
|
|
61
61
|
|
|
62
|
-
- `
|
|
63
|
-
reads it: a row in a `selectable` group
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
group
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
62
|
+
- `value` — a row's stable identity (a group's is its `id`). **Required**
|
|
63
|
+
wherever something outside the menu reads it: a row in a `selectable` group
|
|
64
|
+
(the v-model holds it), a row with a slot of its own (`#<value>` is named by
|
|
65
|
+
it), and a group that has a slot, is selectable or is bound by a
|
|
66
|
+
`<BbDropdownGroup id>` (its `id`). **Optional** on a plain action row (one
|
|
67
|
+
with an `onClick`, `href` or submenu) and on a layout-only group: the
|
|
68
|
+
dropdown then keys the row internally from its label, and nothing outside
|
|
69
|
+
ever sees that identity. Why the split: an identifier something outside
|
|
70
|
+
reads must be one you wrote — derived from the label it would change with
|
|
71
|
+
every translation and copy edit. So a row without a `value` in a selectable
|
|
72
|
+
group renders but can't be selected, and two such rows with the same label in
|
|
73
|
+
one group need values (the same label across groups is fine); `bitboss-ui
|
|
74
|
+
check` flags both (`missing-value`, `duplicate-row-label`) when the items are
|
|
75
|
+
in the same file.
|
|
76
|
+
- `label` — the row's text; `description` adds a muted second line (the row
|
|
77
|
+
grows, icons stay aligned with the title line).
|
|
76
78
|
- `onClick` — makes it an **action**. Never navigate from here.
|
|
77
79
|
- `href` (anchor / Inertia visit, with `method`/`data`) or `to` (vue-router) —
|
|
78
80
|
makes it a **navigation link**; the dropdown renders an `<a>` / router link,
|
|
@@ -141,22 +143,22 @@ const { confirm } = useConfirm();
|
|
|
141
143
|
const items: BbDropdownItem[] = [
|
|
142
144
|
// Plain leaf actions carry an `onClick`.
|
|
143
145
|
{
|
|
144
|
-
|
|
145
|
-
|
|
146
|
+
value: 'rename',
|
|
147
|
+
label: 'Rename',
|
|
146
148
|
'prepend:icon': 'lucide:pencil',
|
|
147
149
|
onClick: () => (last.value = 'Renamed'),
|
|
148
150
|
},
|
|
149
151
|
{
|
|
150
|
-
|
|
151
|
-
|
|
152
|
+
value: 'duplicate',
|
|
153
|
+
label: 'Duplicate',
|
|
152
154
|
'prepend:icon': 'lucide:copy',
|
|
153
155
|
onClick: () => (last.value = 'Duplicated'),
|
|
154
156
|
},
|
|
155
157
|
// A navigation item: the dropdown renders an <a>. Never wire navigation
|
|
156
158
|
// through onClick — pass href (or `to` in a router app) instead.
|
|
157
159
|
{
|
|
158
|
-
|
|
159
|
-
|
|
160
|
+
value: 'preview',
|
|
161
|
+
label: 'Open preview',
|
|
160
162
|
'prepend:icon': 'lucide:external-link',
|
|
161
163
|
href: '#preview',
|
|
162
164
|
target: '_blank',
|
|
@@ -166,8 +168,8 @@ const items: BbDropdownItem[] = [
|
|
|
166
168
|
// proceeds on a yes.
|
|
167
169
|
[
|
|
168
170
|
{
|
|
169
|
-
|
|
170
|
-
|
|
171
|
+
value: 'delete',
|
|
172
|
+
label: 'Delete file',
|
|
171
173
|
description: 'This cannot be undone',
|
|
172
174
|
'prepend:icon': 'lucide:trash-2',
|
|
173
175
|
variant: 'destructive',
|
|
@@ -196,9 +198,9 @@ import type { BbDropdownItem } from 'bitboss-ui';
|
|
|
196
198
|
|
|
197
199
|
const items: BbDropdownItem[] = [
|
|
198
200
|
// Nuxt / vue-router route
|
|
199
|
-
{
|
|
201
|
+
{ value: 'settings', label: 'Settings', to: { name: 'settings' } },
|
|
200
202
|
// Inertia visit
|
|
201
|
-
{
|
|
203
|
+
{ value: 'logout', label: 'Log out', href: '/logout', method: 'post' },
|
|
202
204
|
];
|
|
203
205
|
</script>
|
|
204
206
|
```
|
|
@@ -258,8 +260,8 @@ const status = ref('Idle');
|
|
|
258
260
|
// activator can stay busy while the work runs in the background.
|
|
259
261
|
const items: BbDropdownItem[] = [
|
|
260
262
|
{
|
|
261
|
-
|
|
262
|
-
|
|
263
|
+
value: 'sync',
|
|
264
|
+
label: 'Sync now',
|
|
263
265
|
'prepend:icon': 'lucide:refresh-cw',
|
|
264
266
|
onClick: async () => {
|
|
265
267
|
status.value = 'Syncing…';
|
|
@@ -268,8 +270,8 @@ const items: BbDropdownItem[] = [
|
|
|
268
270
|
},
|
|
269
271
|
},
|
|
270
272
|
{
|
|
271
|
-
|
|
272
|
-
|
|
273
|
+
value: 'history',
|
|
274
|
+
label: 'View sync history',
|
|
273
275
|
'prepend:icon': 'lucide:history',
|
|
274
276
|
href: '#history',
|
|
275
277
|
},
|
|
@@ -320,32 +322,32 @@ import type { BbDropdownItem } from 'bitboss-ui';
|
|
|
320
322
|
// a chevron replaces the item's own `append:icon`.
|
|
321
323
|
const items: BbDropdownItem[] = [
|
|
322
324
|
{
|
|
323
|
-
|
|
324
|
-
|
|
325
|
+
value: 'account',
|
|
326
|
+
label: 'Account',
|
|
325
327
|
'prepend:icon': 'lucide:user',
|
|
326
328
|
items: [
|
|
327
|
-
{
|
|
328
|
-
{
|
|
329
|
+
{ value: 'profile', label: 'View profile', href: '#profile' },
|
|
330
|
+
{ value: 'billing', label: 'Billing & plans', href: '#billing' },
|
|
329
331
|
{
|
|
330
|
-
|
|
331
|
-
|
|
332
|
+
value: 'security',
|
|
333
|
+
label: 'Security',
|
|
332
334
|
items: [
|
|
333
|
-
{
|
|
334
|
-
{
|
|
335
|
+
{ value: '2fa', label: 'Two-factor auth', href: '#2fa' },
|
|
336
|
+
{ value: 'sessions', label: 'Active sessions', href: '#sessions' },
|
|
335
337
|
],
|
|
336
338
|
},
|
|
337
339
|
],
|
|
338
340
|
},
|
|
339
341
|
{
|
|
340
|
-
|
|
341
|
-
|
|
342
|
+
value: 'help',
|
|
343
|
+
label: 'Help & support',
|
|
342
344
|
'prepend:icon': 'lucide:life-buoy',
|
|
343
345
|
href: '#help',
|
|
344
346
|
},
|
|
345
347
|
[
|
|
346
348
|
{
|
|
347
|
-
|
|
348
|
-
|
|
349
|
+
value: 'signout',
|
|
350
|
+
label: 'Sign out',
|
|
349
351
|
'prepend:icon': 'lucide:log-out',
|
|
350
352
|
href: '#signout',
|
|
351
353
|
},
|
|
@@ -360,24 +362,24 @@ Turn a group into a chooser by marking it `selectable` (single choice, radio
|
|
|
360
362
|
semantics) or `selectable` + `multiple` (many choices, checkbox semantics).
|
|
361
363
|
Selected rows render a check on the right (replacing any `append:icon`).
|
|
362
364
|
**Bind the selection with a `<BbDropdownGroup>` companion** whose `id` is the
|
|
363
|
-
group's `
|
|
365
|
+
group's `id` (details below):
|
|
364
366
|
|
|
365
367
|
```vue
|
|
366
368
|
<BbDropdown
|
|
367
369
|
:items="[
|
|
368
370
|
{
|
|
369
|
-
|
|
371
|
+
id: 'status',
|
|
370
372
|
label: 'Status',
|
|
371
373
|
selectable: true,
|
|
372
374
|
multiple: true,
|
|
373
375
|
items: [
|
|
374
|
-
{
|
|
375
|
-
{
|
|
376
|
+
{ value: 'open', label: 'Open' },
|
|
377
|
+
{ value: 'paid', label: 'Paid' },
|
|
376
378
|
],
|
|
377
379
|
},
|
|
378
380
|
]"
|
|
379
381
|
>
|
|
380
|
-
<!-- selectedStatuses = ref<string[]>([]) — the checked rows'
|
|
382
|
+
<!-- selectedStatuses = ref<string[]>([]) — the checked rows' values -->
|
|
381
383
|
<BbDropdownGroup id="status" v-model="selectedStatuses" />
|
|
382
384
|
</BbDropdown>
|
|
383
385
|
```
|
|
@@ -391,7 +393,7 @@ Behavior you can rely on:
|
|
|
391
393
|
(the same one included) also closes the menu;
|
|
392
394
|
- a **multiple** group keeps the menu open while you toggle;
|
|
393
395
|
- the dropdown emits `item:selected` / `item:unselected` with the item's
|
|
394
|
-
**value** (its `
|
|
396
|
+
**value** (its `itemValue` for pipeline groups, else its own `value`) when the user
|
|
395
397
|
picks or unpicks a row, never for your own changes to a group's value — the
|
|
396
398
|
same value shape and meaning as `BbTable`'s (and the companion's pair).
|
|
397
399
|
|
|
@@ -400,7 +402,7 @@ Behavior you can rely on:
|
|
|
400
402
|
|
|
401
403
|
```ts
|
|
402
404
|
const statusGroup = {
|
|
403
|
-
|
|
405
|
+
id: 'status',
|
|
404
406
|
multiple: true,
|
|
405
407
|
selectable: (row: { archived?: boolean }) => !row.archived,
|
|
406
408
|
items: statuses,
|
|
@@ -418,19 +420,19 @@ const statusGroup = {
|
|
|
418
420
|
selected ones stay live so the user can swap.
|
|
419
421
|
- The function receives the **row object** in a hand-written group and the
|
|
420
422
|
**raw fetched item** in a fetched group.
|
|
421
|
-
- `useBbDropdownContext(id).groups[
|
|
423
|
+
- `useBbDropdownContext(id).groups[groupId].selectable` stays a plain `true`.
|
|
422
424
|
|
|
423
425
|
This is also how a fetched row gets disabled — see
|
|
424
426
|
[why fetched rows have no `disabled`](#additional-row-fields-itemprops).
|
|
425
427
|
|
|
426
428
|
Selection state lives on the dropdown; a companion `<BbDropdownGroup>` in the
|
|
427
429
|
default slot binds to it. The companion is intentionally minimal — it takes
|
|
428
|
-
only the group's `id` (which must match the group's `
|
|
430
|
+
only the group's `id` (which must match the group's `id` in `items`) and a
|
|
429
431
|
`v-model`; the options themselves stay declared in the host's `items`. Its
|
|
430
432
|
`v-model` seeds the initial selection before the menu ever opens, and it emits
|
|
431
433
|
the same `item:selected` / `item:unselected` pair. Two hard rules, enforced
|
|
432
434
|
with thrown errors: a `multiple` group's model must be an array, and the `id`
|
|
433
|
-
must point at a _group_ (not a plain item, not a missing
|
|
435
|
+
must point at a _group_ (not a plain item, not a missing id).
|
|
434
436
|
|
|
435
437
|
A companion you listen to (`v-model`, or `@update:model-value`) is
|
|
436
438
|
**controlled**, like a `BbCheckbox`: the menu shows your value and nothing
|
|
@@ -491,24 +493,24 @@ import type { BbDropdownItem } from 'bitboss-ui';
|
|
|
491
493
|
// `multiple` → many choices (checkbox semantics, stays open while toggling).
|
|
492
494
|
const items: BbDropdownItem[] = [
|
|
493
495
|
{
|
|
494
|
-
|
|
496
|
+
id: 'sort',
|
|
495
497
|
label: 'Sort by',
|
|
496
498
|
selectable: true,
|
|
497
499
|
items: [
|
|
498
|
-
{
|
|
499
|
-
{
|
|
500
|
-
{
|
|
500
|
+
{ value: 'recent', label: 'Most recent' },
|
|
501
|
+
{ value: 'name', label: 'Name (A–Z)' },
|
|
502
|
+
{ value: 'amount', label: 'Amount (high → low)' },
|
|
501
503
|
],
|
|
502
504
|
},
|
|
503
505
|
{
|
|
504
|
-
|
|
506
|
+
id: 'tags',
|
|
505
507
|
label: 'Tags',
|
|
506
508
|
selectable: true,
|
|
507
509
|
multiple: true,
|
|
508
510
|
items: [
|
|
509
|
-
{
|
|
510
|
-
{
|
|
511
|
-
{
|
|
511
|
+
{ value: 'overdue', label: 'Overdue' },
|
|
512
|
+
{ value: 'vip', label: 'VIP' },
|
|
513
|
+
{ value: 'review', label: 'Needs review' },
|
|
512
514
|
],
|
|
513
515
|
},
|
|
514
516
|
];
|
|
@@ -520,14 +522,14 @@ const tags = ref<string[]>(['overdue']);
|
|
|
520
522
|
|
|
521
523
|
#### The same choices in two places
|
|
522
524
|
|
|
523
|
-
|
|
525
|
+
Row values are scoped to their **group** for selection. Two groups can both
|
|
524
526
|
list `doctors` and `rooms` (say a day layout at the top level and a week
|
|
525
527
|
layout inside a `Week ›` submenu) and each keeps its own pick, with its own
|
|
526
528
|
companion and `v-model`.
|
|
527
529
|
|
|
528
530
|
To show a submenu's current pick on its parent row, compute the row from the
|
|
529
531
|
same state. `items` is reactive config, so the parent's `description` (or its
|
|
530
|
-
`#<
|
|
532
|
+
`#<value>:append` slot) follows the submenu group's `v-model`:
|
|
531
533
|
|
|
532
534
|
**A submenu's pick on its parent row**
|
|
533
535
|
|
|
@@ -545,7 +547,7 @@ same state. `items` is reactive config, so the parent's `description` (or its
|
|
|
545
547
|
Layout
|
|
546
548
|
</BbButton>
|
|
547
549
|
</template>
|
|
548
|
-
<!-- Both groups list the same
|
|
550
|
+
<!-- Both groups list the same values; each keeps its own selection. -->
|
|
549
551
|
<BbDropdownGroup id="day" v-model="day" />
|
|
550
552
|
<BbDropdownGroup id="week" v-model="week" />
|
|
551
553
|
</BbDropdown>
|
|
@@ -561,11 +563,11 @@ import { BbButton, BbDropdown, BbDropdownGroup } from 'bitboss-ui';
|
|
|
561
563
|
import type { BbDropdownItem } from 'bitboss-ui';
|
|
562
564
|
|
|
563
565
|
const choices = [
|
|
564
|
-
{
|
|
565
|
-
{
|
|
566
|
+
{ value: 'doctors', label: 'Doctors' },
|
|
567
|
+
{ value: 'rooms', label: 'Rooms' },
|
|
566
568
|
];
|
|
567
|
-
const label = (
|
|
568
|
-
choices.find((choice) => choice.
|
|
569
|
+
const label = (value: string) =>
|
|
570
|
+
choices.find((choice) => choice.value === value)?.label ?? value;
|
|
569
571
|
|
|
570
572
|
const day = ref('doctors');
|
|
571
573
|
const week = ref('rooms');
|
|
@@ -574,32 +576,33 @@ const week = ref('rooms');
|
|
|
574
576
|
// from the same state its group writes, so the parent row always shows the
|
|
575
577
|
// current pick ("Week · Rooms") without opening the submenu.
|
|
576
578
|
const items = computed<BbDropdownItem[]>(() => [
|
|
577
|
-
{
|
|
579
|
+
{ id: 'day', label: 'Day', selectable: true, items: choices },
|
|
578
580
|
{
|
|
579
|
-
|
|
580
|
-
|
|
581
|
+
value: 'week-menu',
|
|
582
|
+
label: 'Week',
|
|
581
583
|
description: label(week.value),
|
|
582
|
-
items: [{
|
|
584
|
+
items: [{ id: 'week', selectable: true, items: choices }],
|
|
583
585
|
},
|
|
584
586
|
]);
|
|
585
587
|
</script>
|
|
586
588
|
```
|
|
587
589
|
|
|
588
|
-
Three things still go by the bare
|
|
589
|
-
rows distinct
|
|
590
|
+
Three things still go by the bare value across the whole menu, so give those
|
|
591
|
+
rows distinct values when it matters:
|
|
590
592
|
|
|
591
|
-
- **`#<
|
|
592
|
-
group. Use `#<
|
|
593
|
+
- **`#<value>` row slots.** `#doctors` fills every row whose value is `doctors`,
|
|
594
|
+
in every group. Use `#<groupId>:item` (with the `item` payload) to target one
|
|
593
595
|
group's rows.
|
|
594
596
|
- **The async loading flag.** While a row's async `onClick` runs, every row
|
|
595
|
-
with that
|
|
596
|
-
- **Submenu parents.** A row that opens a submenu needs a
|
|
597
|
+
with that value shows as loading.
|
|
598
|
+
- **Submenu parents.** A row that opens a submenu needs a value unique in the
|
|
597
599
|
whole menu; the flyout is addressed by it.
|
|
598
600
|
|
|
599
601
|
### Loading options on demand
|
|
600
602
|
|
|
601
603
|
For options that come from an API, make the group a **pipeline group**: pass an
|
|
602
|
-
(async) getter as `items
|
|
604
|
+
(async) getter as `items`, and an `itemText` / `itemValue` pair unless the raw
|
|
605
|
+
rows already carry `label` and `value`. This mirrors
|
|
603
606
|
`BbSelect`'s fetch model, so the same data source drops into either component.
|
|
604
607
|
The full grammar:
|
|
605
608
|
|
|
@@ -619,7 +622,8 @@ The full grammar:
|
|
|
619
622
|
A getter **throws** to fail: the group shows `failedText` (or the `#empty`
|
|
620
623
|
slot with its `error` prop) instead of "no data".
|
|
621
624
|
- `itemText` / `itemValue` — a path string or getter producing each raw item's
|
|
622
|
-
label and value
|
|
625
|
+
label and value; without them a row reads its own `label` (else `text`) and
|
|
626
|
+
`value`. `v-model` on the companion surfaces the selected value(s);
|
|
623
627
|
internally the selection key is a hash of the value.
|
|
624
628
|
- `itemProps` — every **additional** field of a row (see
|
|
625
629
|
[Additional row fields](#additional-row-fields-itemprops) below). Nothing
|
|
@@ -629,7 +633,7 @@ The full grammar:
|
|
|
629
633
|
- `loadingText` / `emptyText` / `failedText` — placeholder row text per
|
|
630
634
|
group; the dropdown-level `loading-text` / `empty-text` / `failed-text` props
|
|
631
635
|
set the default for all groups, and the `#loading` / `#empty` slots (payload:
|
|
632
|
-
`{ text,
|
|
636
|
+
`{ text, groupId }`, `#empty` also `error`) replace the placeholder rows
|
|
633
637
|
entirely.
|
|
634
638
|
- `dependencies: [...]` + `depsDebounceTime` — re-run the getter (debounced)
|
|
635
639
|
when any dependency changes, e.g. a search field feeding the fetch.
|
|
@@ -689,7 +693,7 @@ const team: Member[] = [
|
|
|
689
693
|
// (prefill is always `true` here — menus have no search field).
|
|
690
694
|
const items: BbDropdownItem[] = [
|
|
691
695
|
{
|
|
692
|
-
|
|
696
|
+
id: 'assignees',
|
|
693
697
|
label: 'Assign to',
|
|
694
698
|
selectable: true,
|
|
695
699
|
multiple: true,
|
|
@@ -795,16 +799,16 @@ const loadMembers = (): Promise<Member[]> =>
|
|
|
795
799
|
// refetch. `enforceCoherence` then drops picks missing from the fresh items.
|
|
796
800
|
const menu = computed<BbDropdownItem[]>(() => [
|
|
797
801
|
{
|
|
798
|
-
|
|
802
|
+
id: 'board',
|
|
799
803
|
label: 'Board',
|
|
800
804
|
selectable: true,
|
|
801
805
|
items: [
|
|
802
|
-
{
|
|
803
|
-
{
|
|
806
|
+
{ value: 'website', label: 'Website' },
|
|
807
|
+
{ value: 'mobile-app', label: 'Mobile app' },
|
|
804
808
|
],
|
|
805
809
|
},
|
|
806
810
|
{
|
|
807
|
-
|
|
811
|
+
id: 'assignees',
|
|
808
812
|
label: 'Assignee',
|
|
809
813
|
selectable: true,
|
|
810
814
|
multiple: true,
|
|
@@ -828,14 +832,15 @@ const assigneeNames = computed(() =>
|
|
|
828
832
|
|
|
829
833
|
### Additional row fields: `itemProps`
|
|
830
834
|
|
|
831
|
-
A fetched row's **
|
|
835
|
+
A fetched row's **label** and **value** come from `itemText` and `itemValue` (by
|
|
836
|
+
default the raw item's own `label` and `value`).
|
|
832
837
|
Everything **else** about the row comes from `itemProps` — and only from there.
|
|
833
838
|
The raw item is data: a `href`, `disabled` or `prepend:icon` field sitting on it
|
|
834
839
|
does nothing on its own.
|
|
835
840
|
|
|
836
841
|
```ts
|
|
837
842
|
const assigneeGroup = {
|
|
838
|
-
|
|
843
|
+
id: 'assignee',
|
|
839
844
|
selectable: true,
|
|
840
845
|
items: () => api.users(),
|
|
841
846
|
itemText: 'name',
|
|
@@ -908,10 +913,11 @@ const team: Member[] = [
|
|
|
908
913
|
|
|
909
914
|
const items: BbDropdownItem[] = [
|
|
910
915
|
{
|
|
911
|
-
|
|
916
|
+
id: 'assignees',
|
|
912
917
|
label: 'Assign to',
|
|
913
918
|
multiple: true,
|
|
914
|
-
// Fetched rows take their text and value from `itemText` / `itemValue
|
|
919
|
+
// Fetched rows take their text and value from `itemText` / `itemValue`
|
|
920
|
+
// (without them, the row's own `label` and `value`),
|
|
915
921
|
// and EVERY other field only from `itemProps` — a raw `disabled` or
|
|
916
922
|
// `prepend:icon` sitting on the item would do nothing.
|
|
917
923
|
itemText: 'name',
|
|
@@ -981,14 +987,14 @@ const recent: Project[] = [
|
|
|
981
987
|
const lastOpened = ref<string | null>(null);
|
|
982
988
|
|
|
983
989
|
const items: BbDropdownItem[] = [
|
|
984
|
-
{
|
|
990
|
+
{ value: 'new', label: 'New project', 'prepend:icon': 'lucide:plus' },
|
|
985
991
|
{
|
|
986
992
|
// A fetched group of LINKS (not selectable). Its rows get `href`, an icon,
|
|
987
993
|
// a description and a click handler from `itemProps`, using the function
|
|
988
994
|
// form. In the object form a function is a GETTER, so a handler would be
|
|
989
995
|
// written `onClick: (project) => () => …`; here the function form returns
|
|
990
996
|
// the handler directly.
|
|
991
|
-
|
|
997
|
+
id: 'recent',
|
|
992
998
|
label: 'Recent',
|
|
993
999
|
itemText: 'name',
|
|
994
1000
|
itemValue: 'id',
|
|
@@ -1021,11 +1027,11 @@ reject the common slip `onClick: () => openProfile()`, because it doesn't return
|
|
|
1021
1027
|
a function.)
|
|
1022
1028
|
|
|
1023
1029
|
**Which fields.** Everything a hand-written row accepts, except its identity and
|
|
1024
|
-
structure — `
|
|
1030
|
+
structure — `value`, `label`, `items`, `group` — and `disabled`:
|
|
1025
1031
|
|
|
1026
1032
|
- `description` — a muted second line under the text, announced as the row's
|
|
1027
1033
|
description (never part of its name), searched with the text, and exposed as
|
|
1028
|
-
`description` on `useBbDropdownContext(id).groups[
|
|
1034
|
+
`description` on `useBbDropdownContext(id).groups[groupId].selectedOptions`.
|
|
1029
1035
|
- `prepend:icon`, `append:icon`, `variant`.
|
|
1030
1036
|
- `onClick`, `href`, `to`, `target`, `rel`, `download`, `external`, and the
|
|
1031
1037
|
Inertia visit options.
|
|
@@ -1066,7 +1072,7 @@ group owns an independent query.
|
|
|
1066
1072
|
<BbDropdown
|
|
1067
1073
|
:items="[
|
|
1068
1074
|
{
|
|
1069
|
-
|
|
1075
|
+
id: 'assignee',
|
|
1070
1076
|
label: 'Assignee',
|
|
1071
1077
|
searchable: true,
|
|
1072
1078
|
searchPlaceholder: 'Find a teammate…',
|
|
@@ -1136,17 +1142,17 @@ const { isReady, open, groups } = useBbDropdownContext('invoice-filters');
|
|
|
1136
1142
|
|
|
1137
1143
|
- `isReady` — a dropdown with that id is mounted.
|
|
1138
1144
|
- `open` — the panel/sheet is open.
|
|
1139
|
-
- `groups` — one entry per **selectable** group, keyed by group
|
|
1145
|
+
- `groups` — one entry per **selectable** group, keyed by the group's `id`.
|
|
1140
1146
|
|
|
1141
1147
|
Each entry is **the group exactly as you declared it, with live state on top**,
|
|
1142
1148
|
so a chip can be driven entirely from the group config:
|
|
1143
1149
|
|
|
1144
|
-
| From your config
|
|
1145
|
-
|
|
|
1146
|
-
| `
|
|
1150
|
+
| From your config | Added live |
|
|
1151
|
+
| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
|
|
1152
|
+
| `id`, `label`, `hideLabel`, `max`, `filterBy`, `prepend:icon`, `variant`, … | `value` (the `v-model`), `selectedOptions`, `multiple`, `selectable`, `loading` |
|
|
1147
1153
|
|
|
1148
|
-
`selectedOptions` is `{ value,
|
|
1149
|
-
`
|
|
1154
|
+
`selectedOptions` is `{ value, label?, original? }[]`. `value` is always there;
|
|
1155
|
+
`label`/`original` fill in once the owning group has the item — so use
|
|
1150
1156
|
`hideLabel` when a group's name is already shown by its parent category but you
|
|
1151
1157
|
still want a chip prefix.
|
|
1152
1158
|
|
|
@@ -1165,55 +1171,55 @@ its resolved counterpart.
|
|
|
1165
1171
|
### Per-item and per-group slots
|
|
1166
1172
|
|
|
1167
1173
|
Every row (and every titled group header) can be customized without leaving
|
|
1168
|
-
the config-driven model. Slot names come from
|
|
1169
|
-
kebab-case (words split at separators, camelCase
|
|
1170
|
-
joined by `-`):
|
|
1171
|
-
`#delete-file`. For a
|
|
1174
|
+
the config-driven model. Slot names come from a row's `value` (a group's `id`)
|
|
1175
|
+
through `slotKey`, which is kebab-case (words split at separators, camelCase
|
|
1176
|
+
humps and digits, lowercased, joined by `-`): `"Delete file"`, `"delete_file"`
|
|
1177
|
+
and `"deleteFile"` all → `#delete-file`. For a value with accents, non-Latin letters or punctuation, or
|
|
1172
1178
|
when unsure, write `#[slotKey('Qualità')]` (`import { slotKey } from
|
|
1173
1179
|
'bitboss-ui'`) instead of spelling it by hand.
|
|
1174
1180
|
|
|
1175
|
-
| Slot
|
|
1176
|
-
|
|
|
1177
|
-
| `#<
|
|
1178
|
-
| `#<
|
|
1179
|
-
| `#<
|
|
1180
|
-
| `item:prepend`, `item:append`
|
|
1181
|
+
| Slot | Renders for |
|
|
1182
|
+
| ------------------------------------------------------------- | --------------------------------------------------------- |
|
|
1183
|
+
| `#<value>`, `#<value>:prepend`, `#<value>:append` | one row — its content, leading or trailing region |
|
|
1184
|
+
| `#<groupId>:item`, `#<groupId>:item:prepend`, `…:item:append` | **every row of that group**, and nothing else |
|
|
1185
|
+
| `#<groupId>`, `#<groupId>:prepend`, `#<groupId>:append` | that group's title line |
|
|
1186
|
+
| `item:prepend`, `item:append` | every row **and** every group title line, across the menu |
|
|
1181
1187
|
|
|
1182
1188
|
Each edge of a row has **one occupant** — nothing renders side by side. From
|
|
1183
1189
|
strongest to weakest:
|
|
1184
1190
|
|
|
1185
|
-
| Leading edge
|
|
1186
|
-
|
|
|
1187
|
-
| —
|
|
1188
|
-
| `#<
|
|
1189
|
-
| —
|
|
1190
|
-
| `#<
|
|
1191
|
-
| `item:prepend`
|
|
1192
|
-
| `prepend:icon`
|
|
1191
|
+
| Leading edge | Trailing edge |
|
|
1192
|
+
| ------------------------- | -------------------------------------------------------- |
|
|
1193
|
+
| — | the check, on the **selected** row of a selectable group |
|
|
1194
|
+
| `#<value>:prepend` | `#<value>:append` |
|
|
1195
|
+
| — | the submenu chevron |
|
|
1196
|
+
| `#<groupId>:item:prepend` | `#<groupId>:item:append` |
|
|
1197
|
+
| `item:prepend` | `item:append` |
|
|
1198
|
+
| `prepend:icon` | `append:icon` |
|
|
1193
1199
|
|
|
1194
1200
|
So a slot always replaces the row's icon and the most specific slot wins. A
|
|
1195
|
-
row's own `#<
|
|
1201
|
+
row's own `#<value>:append` is written for that one row, so it may replace its
|
|
1196
1202
|
submenu chevron; the group-wide and shared append slots never do, so a submenu
|
|
1197
1203
|
row keeps its chevron unless you name it. The check beats everything — as in
|
|
1198
1204
|
`BbSelect`, it takes the append content's place on the selected row only, so unselected rows of a selectable group still show their
|
|
1199
1205
|
`append:icon` or append slot. Group title lines follow the same order with
|
|
1200
|
-
their own `#<
|
|
1206
|
+
their own `#<groupId>:prepend` / `:append`. In fetched groups a row's `#<value>`
|
|
1201
1207
|
derives from its resolved `itemValue`.
|
|
1202
1208
|
|
|
1203
1209
|
The payload is one-way — no callbacks; clicks and selection stay wired by the
|
|
1204
1210
|
dropdown, so keep slot content presentational:
|
|
1205
1211
|
|
|
1206
|
-
- `item`, `
|
|
1212
|
+
- `item`, `label`, `description`, `index`, `selected`, `disabled`, `loading`,
|
|
1207
1213
|
`open`, `placement`
|
|
1208
|
-
- `group` — `{
|
|
1209
|
-
sits in (`
|
|
1214
|
+
- `group` — `{ id, label, meta, selectable, multiple }` of the group the row
|
|
1215
|
+
sits in (`id` is `undefined` for loose rows and plain arrays)
|
|
1210
1216
|
- `level` — `0` in the root menu, `1` in a submenu, and so on, on the flyout
|
|
1211
1217
|
and the phone sheet alike
|
|
1212
1218
|
- `groupTitle` — `true` when the shared `item:prepend` / `item:append` is
|
|
1213
1219
|
drawing a group's title line (with the group as `item`), `false` on a row
|
|
1214
1220
|
|
|
1215
1221
|
There is **no** bare `#item` slot: restyle every row with the shared edge
|
|
1216
|
-
slots, one group's rows with `#<
|
|
1222
|
+
slots, one group's rows with `#<groupId>:item…`, one row with its value.
|
|
1217
1223
|
|
|
1218
1224
|
**Status dots and a per-row badge**
|
|
1219
1225
|
|
|
@@ -1248,11 +1254,11 @@ slots, one group's rows with `#<groupKey>:item…`, one row with its key.
|
|
|
1248
1254
|
/>
|
|
1249
1255
|
</template>
|
|
1250
1256
|
|
|
1251
|
-
<!-- Per-
|
|
1252
|
-
the
|
|
1253
|
-
<template #billing="{
|
|
1257
|
+
<!-- Per-row slot: replaces just this row's label region. The name is
|
|
1258
|
+
the row's `value` in kebab-case (`slotKey`: `billingInfo` → `#billing-info`). -->
|
|
1259
|
+
<template #billing="{ label }">
|
|
1254
1260
|
<span class="flex flex-1 items-center justify-between gap-2 text-left">
|
|
1255
|
-
{{
|
|
1261
|
+
{{ label }}
|
|
1256
1262
|
<BbBadge variant="soft-amber">3 due</BbBadge>
|
|
1257
1263
|
</span>
|
|
1258
1264
|
</template>
|
|
@@ -1264,13 +1270,13 @@ import { BbBadge, BbButton, BbDropdown, BbIcon } from 'bitboss-ui';
|
|
|
1264
1270
|
import type { BbDropdownItem, IconType } from 'bitboss-ui';
|
|
1265
1271
|
|
|
1266
1272
|
const items: BbDropdownItem[] = [
|
|
1267
|
-
{
|
|
1268
|
-
{
|
|
1269
|
-
[{
|
|
1273
|
+
{ value: 'production', label: 'Production', href: '#production' },
|
|
1274
|
+
{ value: 'staging', label: 'Staging', href: '#staging' },
|
|
1275
|
+
[{ value: 'billing', label: 'Billing', href: '#billing' }],
|
|
1270
1276
|
];
|
|
1271
1277
|
|
|
1272
1278
|
/** Status glyph per workspace row — color inherits via currentColor. */
|
|
1273
|
-
// `
|
|
1279
|
+
// `value` is optional on a row (Q53.17), so a slot reading it may see none.
|
|
1274
1280
|
const envIcon = (key?: string): IconType => {
|
|
1275
1281
|
if (key === 'production') return 'lucide:circle-check';
|
|
1276
1282
|
if (key === 'staging') return 'lucide:circle-dashed';
|
|
@@ -1307,7 +1313,7 @@ pieces, and nothing else:
|
|
|
1307
1313
|
announces the current one with the built-in check; `searchable` plus a
|
|
1308
1314
|
fetched `items` getter scales to hundreds; bind its `<BbDropdownGroup
|
|
1309
1315
|
v-model>` to the current id and switch when it changes.
|
|
1310
|
-
3. **`meta` + `#<
|
|
1316
|
+
3. **`meta` + `#<groupId>:item:prepend`** — every entry takes a `meta`: your
|
|
1311
1317
|
own data, carried untouched to its slots as `item.meta` (and to per-item
|
|
1312
1318
|
`pt` functions), never read by the dropdown, never put on the DOM. A
|
|
1313
1319
|
hand-written row sets it directly (`meta: workspace`); a fetched row sets it
|
|
@@ -1388,7 +1394,7 @@ const initials = (workspace: Workspace) =>
|
|
|
1388
1394
|
// A constant, so the fetched group is declared once while the row above it
|
|
1389
1395
|
// follows the current workspace.
|
|
1390
1396
|
const switcher: BbDropdownItem = {
|
|
1391
|
-
|
|
1397
|
+
id: 'workspaces',
|
|
1392
1398
|
label: 'Switch workspace',
|
|
1393
1399
|
// The row that opens this submenu already names it.
|
|
1394
1400
|
hideLabel: true,
|
|
@@ -1399,7 +1405,7 @@ const switcher: BbDropdownItem = {
|
|
|
1399
1405
|
itemText: 'name',
|
|
1400
1406
|
itemValue: 'id',
|
|
1401
1407
|
// `meta` hands each row its workspace, so the slot draws from the record
|
|
1402
|
-
// instead of looking it up by
|
|
1408
|
+
// instead of looking it up by value.
|
|
1403
1409
|
itemProps: (workspace: Workspace) => ({
|
|
1404
1410
|
description: workspace.plan,
|
|
1405
1411
|
meta: workspace,
|
|
@@ -1417,30 +1423,30 @@ const switcher: BbDropdownItem = {
|
|
|
1417
1423
|
|
|
1418
1424
|
const items = computed<BbDropdownItem[]>(() => [
|
|
1419
1425
|
{
|
|
1420
|
-
|
|
1421
|
-
|
|
1426
|
+
value: 'current-workspace',
|
|
1427
|
+
label: current.value?.name ?? 'Choose a workspace',
|
|
1422
1428
|
description: current.value?.plan,
|
|
1423
1429
|
meta: current.value,
|
|
1424
1430
|
items: [switcher],
|
|
1425
1431
|
},
|
|
1426
1432
|
[
|
|
1427
1433
|
{
|
|
1428
|
-
|
|
1429
|
-
|
|
1434
|
+
value: 'profile',
|
|
1435
|
+
label: 'Profile',
|
|
1430
1436
|
'prepend:icon': 'lucide:user',
|
|
1431
1437
|
href: '#profile',
|
|
1432
1438
|
},
|
|
1433
1439
|
{
|
|
1434
|
-
|
|
1435
|
-
|
|
1440
|
+
value: 'settings',
|
|
1441
|
+
label: 'Settings',
|
|
1436
1442
|
'prepend:icon': 'lucide:settings',
|
|
1437
1443
|
href: '#settings',
|
|
1438
1444
|
},
|
|
1439
1445
|
],
|
|
1440
1446
|
[
|
|
1441
1447
|
{
|
|
1442
|
-
|
|
1443
|
-
|
|
1448
|
+
value: 'sign-out',
|
|
1449
|
+
label: 'Sign out',
|
|
1444
1450
|
'prepend:icon': 'lucide:log-out',
|
|
1445
1451
|
href: '#sign-out',
|
|
1446
1452
|
},
|
|
@@ -1451,8 +1457,8 @@ const items = computed<BbDropdownItem[]>(() => [
|
|
|
1451
1457
|
|
|
1452
1458
|
Two things this replaces, both seen in real apps:
|
|
1453
1459
|
|
|
1454
|
-
- **Matching
|
|
1455
|
-
`v-else-if="clinicsById.get(item.
|
|
1460
|
+
- **Matching values in the shared slots** (`v-if="item.value === 'current'"`,
|
|
1461
|
+
`v-else-if="clinicsById.get(item.value)"`) to tell a record row from an action
|
|
1456
1462
|
row, and a lookup map rebuilt from the fetch to get the record back. The
|
|
1457
1463
|
group row slot is the "which rows" answer; `item.meta` is the record.
|
|
1458
1464
|
- **Re-drawing the other rows' icons**, because a shared `item:prepend`
|
|
@@ -1471,9 +1477,9 @@ the sheet's pinned header and footer.
|
|
|
1471
1477
|
```vue
|
|
1472
1478
|
<BbDropdown
|
|
1473
1479
|
:items="[
|
|
1474
|
-
{
|
|
1475
|
-
{
|
|
1476
|
-
{
|
|
1480
|
+
{ value: 'jan', label: 'January', href: '#jan' },
|
|
1481
|
+
{ value: 'feb', label: 'February', href: '#feb' },
|
|
1482
|
+
{ value: 'mar', label: 'March', href: '#mar' },
|
|
1477
1483
|
]"
|
|
1478
1484
|
:width="240"
|
|
1479
1485
|
>
|
|
@@ -1553,14 +1559,14 @@ const last = ref('Right-click the row');
|
|
|
1553
1559
|
|
|
1554
1560
|
const items: BbDropdownItem[] = [
|
|
1555
1561
|
{
|
|
1556
|
-
|
|
1557
|
-
|
|
1562
|
+
value: 'download',
|
|
1563
|
+
label: 'Download PDF',
|
|
1558
1564
|
'prepend:icon': 'lucide:download',
|
|
1559
1565
|
onClick: () => (last.value = 'Downloading'),
|
|
1560
1566
|
},
|
|
1561
1567
|
{
|
|
1562
|
-
|
|
1563
|
-
|
|
1568
|
+
value: 'share',
|
|
1569
|
+
label: 'Share link',
|
|
1564
1570
|
'prepend:icon': 'lucide:link',
|
|
1565
1571
|
href: '#share',
|
|
1566
1572
|
},
|
|
@@ -1568,8 +1574,8 @@ const items: BbDropdownItem[] = [
|
|
|
1568
1574
|
// awaits useConfirm — see the mixed action menu example.
|
|
1569
1575
|
[
|
|
1570
1576
|
{
|
|
1571
|
-
|
|
1572
|
-
|
|
1577
|
+
value: 'trash',
|
|
1578
|
+
label: 'Move to trash',
|
|
1573
1579
|
'prepend:icon': 'lucide:trash-2',
|
|
1574
1580
|
onClick: () => (last.value = 'Moved to trash'),
|
|
1575
1581
|
},
|
|
@@ -1608,15 +1614,20 @@ const items: BbDropdownItem[] = [
|
|
|
1608
1614
|
width="100%"
|
|
1609
1615
|
:items="[
|
|
1610
1616
|
{
|
|
1611
|
-
|
|
1612
|
-
|
|
1617
|
+
value: 'starter',
|
|
1618
|
+
label: 'Starter',
|
|
1613
1619
|
description: 'For side projects',
|
|
1614
1620
|
href: '#starter',
|
|
1615
1621
|
},
|
|
1616
|
-
{ key: 'pro', text: 'Pro', description: 'For growing teams', href: '#pro' },
|
|
1617
1622
|
{
|
|
1618
|
-
|
|
1619
|
-
|
|
1623
|
+
value: 'pro',
|
|
1624
|
+
label: 'Pro',
|
|
1625
|
+
description: 'For growing teams',
|
|
1626
|
+
href: '#pro',
|
|
1627
|
+
},
|
|
1628
|
+
{
|
|
1629
|
+
value: 'enterprise',
|
|
1630
|
+
label: 'Enterprise',
|
|
1620
1631
|
description: 'Custom contracts',
|
|
1621
1632
|
href: '#enterprise',
|
|
1622
1633
|
},
|
|
@@ -1678,16 +1689,16 @@ long lists.
|
|
|
1678
1689
|
```vue
|
|
1679
1690
|
<BbButton
|
|
1680
1691
|
v-bb-dropdown="[
|
|
1681
|
-
{
|
|
1692
|
+
{ value: 'profile', label: 'View profile', href: '#profile' },
|
|
1682
1693
|
{
|
|
1683
|
-
|
|
1684
|
-
|
|
1694
|
+
value: 'settings',
|
|
1695
|
+
label: 'Settings',
|
|
1685
1696
|
'prepend:icon': 'lucide:settings',
|
|
1686
1697
|
href: '#settings',
|
|
1687
1698
|
},
|
|
1688
1699
|
{
|
|
1689
|
-
|
|
1690
|
-
|
|
1700
|
+
value: 'signout',
|
|
1701
|
+
label: 'Sign out',
|
|
1691
1702
|
variant: 'destructive',
|
|
1692
1703
|
href: '#signout',
|
|
1693
1704
|
},
|
|
@@ -1727,8 +1738,8 @@ the same floor the select's own sheet holds.
|
|
|
1727
1738
|
v-bb-dropdown="{
|
|
1728
1739
|
compact: true,
|
|
1729
1740
|
items: [
|
|
1730
|
-
{
|
|
1731
|
-
{
|
|
1741
|
+
{ value: 'rename', label: 'Rename' },
|
|
1742
|
+
{ value: 'duplicate', label: 'Duplicate' },
|
|
1732
1743
|
],
|
|
1733
1744
|
}"
|
|
1734
1745
|
size="sm"
|
|
@@ -1772,8 +1783,8 @@ broadcast, on the flyout and the phone sheet alike; its magnifier is chrome),
|
|
|
1772
1783
|
— a flex column with a 1px gap; a submenu's list is not reached), `item` — every entry, submenus included, a broadcast
|
|
1773
1784
|
resolved per entry — and `itemText` / `itemIcon` / `itemDescription`, that
|
|
1774
1785
|
entry's label, its prepend / append icons and its muted second line (the item's
|
|
1775
|
-
`
|
|
1776
|
-
states (a per-entry `#<
|
|
1786
|
+
`label` / `prepend:icon` · `append:icon` / `description`), resolved with the entry's
|
|
1787
|
+
states (a per-entry `#<value>` slot replaces the label and description). States: `open`, and `selected` / `disabled` per entry.
|
|
1777
1788
|
Groups, headings and dividers are not parts.
|
|
1778
1789
|
|
|
1779
1790
|
The invoice View menu, restyled through those parts: a muted wash on
|
|
@@ -1836,30 +1847,30 @@ import type { BbDropdownItem } from 'bitboss-ui';
|
|
|
1836
1847
|
// container instead).
|
|
1837
1848
|
const items: BbDropdownItem[] = [
|
|
1838
1849
|
{
|
|
1839
|
-
|
|
1850
|
+
id: 'sort',
|
|
1840
1851
|
label: 'Sort by',
|
|
1841
1852
|
selectable: true,
|
|
1842
1853
|
items: [
|
|
1843
|
-
{
|
|
1844
|
-
{
|
|
1845
|
-
{
|
|
1854
|
+
{ value: 'recent', label: 'Most recent' },
|
|
1855
|
+
{ value: 'name', label: 'Name (A–Z)' },
|
|
1856
|
+
{ value: 'amount', label: 'Amount (high → low)' },
|
|
1846
1857
|
],
|
|
1847
1858
|
},
|
|
1848
1859
|
{
|
|
1849
|
-
|
|
1860
|
+
id: 'tags',
|
|
1850
1861
|
label: 'Tags',
|
|
1851
1862
|
selectable: true,
|
|
1852
1863
|
multiple: true,
|
|
1853
1864
|
items: [
|
|
1854
|
-
{
|
|
1855
|
-
{
|
|
1856
|
-
{
|
|
1865
|
+
{ value: 'overdue', label: 'Overdue' },
|
|
1866
|
+
{ value: 'vip', label: 'VIP' },
|
|
1867
|
+
{ value: 'review', label: 'Needs review' },
|
|
1857
1868
|
],
|
|
1858
1869
|
},
|
|
1859
1870
|
[
|
|
1860
1871
|
{
|
|
1861
|
-
|
|
1862
|
-
|
|
1872
|
+
value: 'export',
|
|
1873
|
+
label: 'Export CSV',
|
|
1863
1874
|
disabled: true,
|
|
1864
1875
|
},
|
|
1865
1876
|
],
|
|
@@ -1929,23 +1940,23 @@ const run = (name: string) => () => {
|
|
|
1929
1940
|
};
|
|
1930
1941
|
|
|
1931
1942
|
const items: Action[] = [
|
|
1932
|
-
{
|
|
1933
|
-
{
|
|
1943
|
+
{ value: 'rename', label: 'Rename', onClick: run('rename') },
|
|
1944
|
+
{ value: 'duplicate', label: 'Duplicate', onClick: run('duplicate') },
|
|
1934
1945
|
{
|
|
1935
|
-
|
|
1936
|
-
|
|
1946
|
+
value: 'archive',
|
|
1947
|
+
label: 'Archive',
|
|
1937
1948
|
description: 'Hidden from the board, kept for 30 days',
|
|
1938
1949
|
onClick: run('archive'),
|
|
1939
1950
|
},
|
|
1940
1951
|
{
|
|
1941
|
-
|
|
1942
|
-
|
|
1952
|
+
value: 'delete',
|
|
1953
|
+
label: 'Delete project',
|
|
1943
1954
|
danger: true,
|
|
1944
1955
|
onClick: run('delete'),
|
|
1945
1956
|
},
|
|
1946
1957
|
{
|
|
1947
|
-
|
|
1948
|
-
|
|
1958
|
+
value: 'purge',
|
|
1959
|
+
label: 'Purge history',
|
|
1949
1960
|
danger: true,
|
|
1950
1961
|
disabled: true,
|
|
1951
1962
|
},
|
|
@@ -1964,7 +1975,7 @@ const dangerText = ({ item }: { item: Action }) => item.danger && 'font-medium';
|
|
|
1964
1975
|
```
|
|
1965
1976
|
|
|
1966
1977
|
The function can also map a VALUE to its own classes. Here every status in a
|
|
1967
|
-
single-choice group gets its own tone: `pt:item-icon` looks the entry's `
|
|
1978
|
+
single-choice group gets its own tone: `pt:item-icon` looks the entry's `value`
|
|
1968
1979
|
up in a map for the dot's color, and `pt:item` adds a wash of the same tone
|
|
1969
1980
|
while that entry is the `selected` one. Adding a status is one row in the map.
|
|
1970
1981
|
|
|
@@ -2005,7 +2016,7 @@ import { ref } from 'vue';
|
|
|
2005
2016
|
import { BbButton, BbDropdown, BbDropdownGroup } from 'bitboss-ui';
|
|
2006
2017
|
import type { BbDropdownItem } from 'bitboss-ui';
|
|
2007
2018
|
|
|
2008
|
-
// One look per VALUE: the per-item function reads the entry's `
|
|
2019
|
+
// One look per VALUE: the per-item function reads the entry's `value` and looks
|
|
2009
2020
|
// its classes up in a map, so every status gets its own tone — the dot on
|
|
2010
2021
|
// `:pt:item-icon`, a wash of the same tone on `item` while it is the `selected`
|
|
2011
2022
|
// one. A new status is one row in `tones`.
|
|
@@ -2027,12 +2038,12 @@ const labels: Record<Status, string> = {
|
|
|
2027
2038
|
|
|
2028
2039
|
const items: BbDropdownItem[] = [
|
|
2029
2040
|
{
|
|
2030
|
-
|
|
2041
|
+
id: 'status',
|
|
2031
2042
|
label: 'Set status',
|
|
2032
2043
|
selectable: true,
|
|
2033
2044
|
items: (Object.keys(labels) as Status[]).map((key) => ({
|
|
2034
|
-
key,
|
|
2035
|
-
|
|
2045
|
+
value: key,
|
|
2046
|
+
label: labels[key],
|
|
2036
2047
|
'prepend:icon': 'lucide:circle',
|
|
2037
2048
|
})),
|
|
2038
2049
|
},
|
|
@@ -2040,10 +2051,10 @@ const items: BbDropdownItem[] = [
|
|
|
2040
2051
|
|
|
2041
2052
|
const status = ref<Status>('overdue');
|
|
2042
2053
|
|
|
2043
|
-
// A group has no `
|
|
2044
|
-
// (`BbDropdownItem` also covers a nested list, which has no `
|
|
2054
|
+
// A group has no `value`, so only the status rows match.
|
|
2055
|
+
// (`BbDropdownItem` also covers a nested list, which has no `value`.)
|
|
2045
2056
|
const toneOf = (item: BbDropdownItem) =>
|
|
2046
|
-
'
|
|
2057
|
+
'value' in item ? tones[item.value as Status] : undefined;
|
|
2047
2058
|
</script>
|
|
2048
2059
|
```
|
|
2049
2060
|
|
|
@@ -2083,12 +2094,12 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
|
|
|
2083
2094
|
- **Don't rebuild selection** with `onClick` + your own state — mark the group
|
|
2084
2095
|
`selectable` and bind a `<BbDropdownGroup v-model>`.
|
|
2085
2096
|
- **There is no bare `#item` slot** — a template slot named `item` renders
|
|
2086
|
-
nothing. Use `item:prepend`/`item:append`, a group's `#<
|
|
2087
|
-
a per-
|
|
2088
|
-
- **Don't sort rows by
|
|
2089
|
-
rows need a custom look, use `#<
|
|
2097
|
+
nothing. Use `item:prepend`/`item:append`, a group's `#<groupId>:item…`, or
|
|
2098
|
+
a per-row `#<value>` slot.
|
|
2099
|
+
- **Don't sort rows by value inside the shared slots.** When only one group's
|
|
2100
|
+
rows need a custom look, use `#<groupId>:item:prepend`; when a slot needs the
|
|
2090
2101
|
record behind a row, put it in `meta` (through `itemProps` on a fetched group)
|
|
2091
|
-
instead of looking it up by `item.
|
|
2102
|
+
instead of looking it up by `item.value`.
|
|
2092
2103
|
- **Don't hand-roll the "current" mark in a switcher** (a custom `variant` plus
|
|
2093
2104
|
a check in `item:append`). Make the group `selectable` and bind its
|
|
2094
2105
|
`v-model` to the current id — the check, `aria-checked` and the radio role
|
|
@@ -2098,7 +2109,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
|
|
|
2098
2109
|
- Item `variant`s other than `destructive` render only a class hook — register
|
|
2099
2110
|
names via the `dropdownItemVariants` plugin option and ship their CSS.
|
|
2100
2111
|
- `<BbDropdownGroup>` must sit in a `BbDropdown` (or `BbDropdownButton`)
|
|
2101
|
-
default slot, its `id` must match a group `
|
|
2112
|
+
default slot, its `id` must match a group's `id`, and a `multiple` group's
|
|
2102
2113
|
model must be an array — all three misuses throw.
|
|
2103
2114
|
- Placeholder texts default to the config locale's "Loading…" / "No results"
|
|
2104
2115
|
strings (`locale` plugin option) unless you set `loading-text` /
|
|
@@ -2158,7 +2169,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
|
|
|
2158
2169
|
| `boundary` | `string \| Record<string, any> \| HTMLElement \| null \| undefined` | | | Constrains the dropdown within a bounding element. Accepts an HTMLElement, a Vue component ref, or a CSS selector string. |
|
|
2159
2170
|
| `compact` | `boolean \| undefined` | `false` | | Apply the compact density variant — the same ladder `BbSelect` uses, on both surfaces: flyout rows go 28px → 24px, sheet rows 44px → 36px. The label size does not change; density here is height, as it is for a select. A menu row is a touch target in a way a select option is not quite — a mis-tap fires the neighbouring COMMAND rather than picking the wrong value — so the compact sheet stops at 36px and never follows the flyout down to 24px. That is the same floor the select's sheet holds. |
|
|
2160
2171
|
| `disabled` | `boolean \| undefined` | `false` | | Disables the component |
|
|
2161
|
-
| `eager` | `boolean \| undefined` | `false` | |
|
|
2172
|
+
| `eager` | `boolean \| undefined` | `false` | | Renders the menu panel at mount instead of on the first open (the phone sheet's too), and keeps its rows after a close. Without it the rows mount on each open and go once the menu has closed. |
|
|
2162
2173
|
| `emptyText` | `string \| undefined` | | | Default placeholder text shown when a pipeline group resolves to no items. A group's own `emptyText` overrides this; both fall back to the localized `common.emptyText` (`'No data to display'`). |
|
|
2163
2174
|
| `enforceCoherence` | `boolean \| undefined` | `false` | | Default for pipeline groups: drop selections that are no longer present in a group's current items (e.g. after a `dependencies` re-fetch) from the selection and `v-model`. A group's own `enforceCoherence` overrides this. |
|
|
2164
2175
|
| `failedText` | `string \| undefined` | | | Default placeholder text shown when a pipeline group's latest load FAILED (its `items` getter threw). A group's own `failedText` overrides this; both fall back to the localized `common.failedText` (`"Couldn't load items"`). |
|
|
@@ -2188,9 +2199,9 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
|
|
|
2188
2199
|
| `input` | A searchable group's search field — a broadcast: it lands on every searchable group's field, desktop and phone alike. Its magnifier glyph is chrome. |
|
|
2189
2200
|
| `list` | The top-level items container between the bands — the node that lays the entries out (a flex column with a 1px gap; on a phone, the sheet's items container). A submenu's list is not reached. Groups, headings and dividers are not parts. |
|
|
2190
2201
|
| `item` | One menu entry, submenus included — a broadcast resolved per entry. Also takes a per-item function, called with the entry. |
|
|
2191
|
-
| `itemText` | An entry's label (its `
|
|
2202
|
+
| `itemText` | An entry's label (its `label`) — resolved with that entry's states. A per-entry `#<value>` slot replaces it. Also takes a per-item function. |
|
|
2192
2203
|
| `itemIcon` | An entry's prepend / append icons — resolved with that entry's states. Also takes a per-item function. |
|
|
2193
|
-
| `itemDescription` | An entry's muted second line (its `description`) — resolved with that entry's states. A per-entry `#<
|
|
2204
|
+
| `itemDescription` | An entry's muted second line (its `description`) — resolved with that entry's states. A per-entry `#<value>` slot replaces it. Also takes a per-item function. |
|
|
2194
2205
|
|
|
2195
2206
|
States are listed in precedence order: when two are on at once and their entries conflict, the later one wins.
|
|
2196
2207
|
|
|
@@ -2204,7 +2215,7 @@ States are listed in precedence order: when two are on at once and their entries
|
|
|
2204
2215
|
|
|
2205
2216
|
- `hidden` — `(): void` — Emitted once the menu has finished closing.
|
|
2206
2217
|
- `hide` — `(): void` — Emitted as soon as the menu starts to close.
|
|
2207
|
-
- `item:selected` — `(value: any): void` — The user selected a row in a selectable group, at the click — also when a controlled companion's app then refuses the value. The payload is the
|
|
2218
|
+
- `item:selected` — `(value: any): void` — The user selected a row in a selectable group, at the click — also when a controlled companion's app then refuses the value. The payload is the row's value (its `item-value` for pipeline groups, else its `value`) — symmetric with `BbTable`'s `item:selected`.
|
|
2208
2219
|
- `item:unselected` — `(value: any): void` — The user unselected a row (a multiple toggle, a `clearable` re-click, a chip ×, or the old value a single pick replaces). Payload is the item's resolved value, matching `item:selected`.
|
|
2209
2220
|
- `show` — `(): void` — Emitted as soon as the menu (the popover, or the sheet on a phone) starts to open.
|
|
2210
2221
|
- `shown` — `(): void` — Emitted once the menu is open and its open transition has finished.
|
|
@@ -2213,21 +2224,21 @@ States are listed in precedence order: when two are on at once and their entries
|
|
|
2213
2224
|
|
|
2214
2225
|
- `activator` — scope: `BbDropdownActivatorSlotProps` `{ disabled?: boolean; loading: boolean; open: boolean; placement: Placement \| "cursor"; props: BbDropdownActivatorProps }` — The element that triggers the dropdown to open. Spread `props` onto your trigger element.
|
|
2215
2226
|
- `default` — scope: `any` — Hosts `<BbDropdownGroup>` companions. They register their group with the dropdown and render nothing themselves.
|
|
2216
|
-
- `empty` — scope: `BbDropdownPlaceholderSlotProps` `{
|
|
2227
|
+
- `empty` — scope: `BbDropdownPlaceholderSlotProps` `{ groupId?: string; text: string; error?: unknown }` — Replaces the default "no data" placeholder row shown in a pipeline group that resolved to no items. Rendered once per empty group.
|
|
2217
2228
|
- `footer` — scope: `BbDropdownEdgeSlotProps` `{ disabled?: boolean; open: boolean; placement: Placement \| "cursor" }` — Content pinned to the bottom of the dropdown panel, outside the scroll area. Stays visible while the items scroll and is separated from them by a divider — for action buttons.
|
|
2218
2229
|
- `header` — scope: `BbDropdownEdgeSlotProps` `{ disabled?: boolean; open: boolean; placement: Placement \| "cursor" }` — Content pinned to the top of the dropdown panel, outside the scroll area. Stays visible while the items scroll and is separated from them by a divider — for a title or a filter field.
|
|
2219
|
-
- `item:append` — scope: `BbDropdownItemSlotProps` `{ description?: string; disabled?: boolean; group: BbDropdownSlotGroup; groupTitle: boolean; level: number; index: number; item: InternalItem; loading: boolean; open: boolean; placement: Placement \| "cursor"; selected: boolean;
|
|
2220
|
-
- `item:prepend` — scope: `BbDropdownItemSlotProps` `{ description?: string; disabled?: boolean; group: BbDropdownSlotGroup; groupTitle: boolean; level: number; index: number; item: InternalItem; loading: boolean; open: boolean; placement: Placement \| "cursor"; selected: boolean;
|
|
2221
|
-
- `loading` — scope: `BbDropdownPlaceholderSlotProps` `{
|
|
2222
|
-
- `#<
|
|
2223
|
-
- `#<
|
|
2224
|
-
- `#<
|
|
2225
|
-
- `#<
|
|
2226
|
-
- `#<
|
|
2227
|
-
- `#<
|
|
2228
|
-
- `#<
|
|
2229
|
-
- `#<
|
|
2230
|
-
- `#<
|
|
2230
|
+
- `item:append` — scope: `BbDropdownItemSlotProps` `{ description?: string; disabled?: boolean; group: BbDropdownSlotGroup; groupTitle: boolean; level: number; index: number; item: InternalItem; loading: boolean; open: boolean; placement: Placement \| "cursor"; selected: boolean; label: string }` — The trailing region of every row (and group title line), replacing its `append:icon`. A named slot wins over it; the submenu chevron and the check on a selected row take its place.
|
|
2231
|
+
- `item:prepend` — scope: `BbDropdownItemSlotProps` `{ description?: string; disabled?: boolean; group: BbDropdownSlotGroup; groupTitle: boolean; level: number; index: number; item: InternalItem; loading: boolean; open: boolean; placement: Placement \| "cursor"; selected: boolean; label: string }` — The leading region of every row (and group title line), replacing its `prepend:icon`. A row's own or its group's named slot wins over it.
|
|
2232
|
+
- `loading` — scope: `BbDropdownPlaceholderSlotProps` `{ groupId?: string; text: string; error?: unknown }` — Replaces the default loading placeholder row shown in a pipeline group while its async items load. Rendered once per loading group.
|
|
2233
|
+
- `#<value>` (named from data) — scope: `BbDropdownItemSlotProps` — One row's content (label and description), by its value; in a fetched group, by its resolved `itemValue`. Reserved names (their slot is one of this component's own, so an item value or column key spelled like them is an error): `activator`, `default`, `empty`, `footer`, `header`, `item`, `loading`.
|
|
2234
|
+
- `#<value>:prepend` (named from data) — scope: `BbDropdownItemSlotProps` — One row's leading region; replaces its `prepend:icon`.
|
|
2235
|
+
- `#<value>:append` (named from data) — scope: `BbDropdownItemSlotProps` — One row's trailing region; replaces its `append:icon` and its submenu chevron. The check takes its place on the selected row.
|
|
2236
|
+
- `#<groupId>:item` (named from data) — scope: `BbDropdownItemSlotProps` — The content of every row of that group, and no other; a row's own `#<value>` still wins.
|
|
2237
|
+
- `#<groupId>:item:prepend` (named from data) — scope: `BbDropdownItemSlotProps` — The leading region of every row of that group — e.g. an avatar per record, drawn from `item.meta`, while other rows keep their `prepend:icon`.
|
|
2238
|
+
- `#<groupId>:item:append` (named from data) — scope: `BbDropdownItemSlotProps` — The trailing region of every row of that group; replaces their `append:icon`. The check takes its place on the selected row.
|
|
2239
|
+
- `#<groupId>` (named from data) — scope: `BbDropdownItemSlotProps` — That group's title line (the group is passed as `item`, `groupTitle` is `true`). Reserved names (their slot is one of this component's own, so an item value or column key spelled like them is an error): `activator`, `default`, `empty`, `footer`, `header`, `item`, `loading`.
|
|
2240
|
+
- `#<groupId>:prepend` (named from data) — scope: `BbDropdownItemSlotProps` — The leading region of that group's title line.
|
|
2241
|
+
- `#<groupId>:append` (named from data) — scope: `BbDropdownItemSlotProps` — The trailing region of that group's title line.
|
|
2231
2242
|
|
|
2232
2243
|
## CSS custom properties
|
|
2233
2244
|
|
|
@@ -2249,12 +2260,12 @@ Set these on the element, or on a class you put on it, to retune this component
|
|
|
2249
2260
|
|
|
2250
2261
|
- `BbDropdown` _(this component)_ — its own template binds: `panel` → `CommonPopover`, `root` → `CommonPopover`, `header` → `div.bb-dropdown__header`, `list` → `span.bb-dropdown__list`, `footer` → `div.bb-dropdown__footer`
|
|
2251
2262
|
- `BbDropdownList` _(internal — not importable, reach it through `BbDropdown`)_ — also mounts `BbIcon`, `ErrorIcon`, `CommonPopover`, `BbDropdownList`
|
|
2252
|
-
- `BbBaseButton` _(public — [contract](./BbBaseButton.md))_ — its own pt parts (`BbBaseButton`): `root` → `RouterComponent`, `root` → `a`, `root` → `component`; also mounts `RouterComponent`
|
|
2253
2263
|
- `BbBadge` _(public — [contract](./BbBadge.md))_ — its own pt parts (`BbBadge`): `spinner` → `BbSpinner`, `icon` → `BbIcon`, `clear` → `button.bb-badge__clear`; documented CSS variables: `--bg`, `--fg`, `--bw`, `--ring-color`, `--ring-size`, `--min-size-md`, `--min-size`, `--elev`, `--r`, `--fs`, `--icon-size`, `--gap`, `--px`, `--clear-size`, `--bg-disabled`, `--fg-disabled`, `--border-disabled`, `--pad-left`; also mounts `BbIcon`, `BbSpinner`, `BadgeBodyContent`
|
|
2254
2264
|
- `AdaptiveDropdown` _(internal — not importable, reach it through `BbDropdown`)_ — hands `BbOffCanvas` the pt map `{ header: 'header', footer: 'footer', panel: 'root', sheet: 'root' }` (ours → theirs); also mounts `BbSmoothHeight`, `BbDropdownList`
|
|
2255
2265
|
- `BbOffCanvas` _(public — [contract](./BbOffCanvas.md))_ — its own pt parts (`BbOffCanvas`): `header` → `div.bb-offcanvas__header`, `title` → `span.bb-offcanvas__title`, `description` → `p.bb-offcanvas__description`, `close` → `CloseButton`, `content` → `div.bb-offcanvas__content`, `footer` → `div.bb-offcanvas__footer`; documented CSS variables: `--stack-x`, `--stack-fill`, `--stack-transition-duration`, `--px`, `--handle-w`, `--handle-h`, `--handle-bg`, `--safe-top`, `--close-size`
|
|
2256
2266
|
- `CloseButton` _(internal — not importable, reach it through `BbOffCanvas`)_ — documented CSS variables: `--size`, `--p`
|
|
2257
|
-
- `BbButton` _(public — [contract](./BbButton.md))_ — its own pt parts (`BbButton`): `root` → `BbBaseButton`, `spinner` → `BbSpinner`, `icon` → `BbIcon`, `text` → `span.bb-button__text`; documented CSS variables: `--h-xs`, `--h`, `--icon-size`, `--px`, `--fs`, `--r`, `--gap`, `--bg`, `--bg-hover`, `--bg-pressed`, `--fg`, `--border-color`, `--ring-color`, `--ring-size`, `--bw`, `--fg-hover`, `--border-hover`, `--fg-pressed`, `--border-pressed`, `--bg-disabled`, `--fg-disabled`, `--border-disabled`, `--opacity-disabled`, `--elev-tier`, `--elev`; also mounts `BbIcon`, `
|
|
2267
|
+
- `BbButton` _(public — [contract](./BbButton.md))_ — its own pt parts (`BbButton`): `root` → `BbBaseButton`, `spinner` → `BbSpinner`, `icon` → `BbIcon`, `text` → `span.bb-button__text`; documented CSS variables: `--h-xs`, `--h`, `--icon-size`, `--px`, `--fs`, `--r`, `--gap`, `--bg`, `--bg-hover`, `--bg-pressed`, `--fg`, `--border-color`, `--ring-color`, `--ring-size`, `--bw`, `--fg-hover`, `--border-hover`, `--fg-pressed`, `--border-pressed`, `--bg-disabled`, `--fg-disabled`, `--border-disabled`, `--opacity-disabled`, `--elev-tier`, `--elev`; also mounts `BbIcon`, `BbSpinner`
|
|
2268
|
+
- `BbBaseButton` _(public — [contract](./BbBaseButton.md))_ — its own pt parts (`BbBaseButton`): `root` → `RouterComponent`, `root` → `a`, `root` → `component`; also mounts `RouterComponent`
|
|
2258
2269
|
- Also mounts `CommonPopover`, `DropdownPipelineResolver`
|
|
2259
2270
|
|
|
2260
2271
|
## See Also
|