bitboss-ui 3.0.0-beta.63 → 3.0.0-beta.64
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 +25 -20
- package/bin/bitboss-ui.mjs +73 -7
- package/dist/ai/BbAlert.md +10 -1
- package/dist/ai/BbBadge.md +35 -3
- package/dist/ai/BbBadgeButton.md +4 -2
- package/dist/ai/BbBaseButton.md +9 -3
- package/dist/ai/BbBreadcrumbs.md +2 -2
- package/dist/ai/BbButton.md +113 -8
- package/dist/ai/BbCheckbox.md +1 -1
- package/dist/ai/BbCheckboxGroup.md +94 -6
- package/dist/ai/BbColorInput.md +4 -1
- package/dist/ai/BbColorPalette.md +2 -1
- package/dist/ai/BbConfirm.md +7 -3
- package/dist/ai/BbDatePicker.md +2 -1
- package/dist/ai/BbDatePickerInput.md +4 -1
- package/dist/ai/BbDialog.md +12 -11
- package/dist/ai/BbDropdown.md +189 -38
- package/dist/ai/BbDropdownButton.md +27 -7
- package/dist/ai/BbForm.md +55 -22
- package/dist/ai/BbHost.md +2 -2
- package/dist/ai/BbHoverCard.md +7 -3
- package/dist/ai/BbIcon.md +12 -6
- package/dist/ai/BbIndicator.md +11 -1
- package/dist/ai/BbNumberInput.md +4 -1
- package/dist/ai/BbOffCanvas.md +37 -3
- package/dist/ai/BbPopover.md +2 -1
- package/dist/ai/BbRadio.md +1 -1
- package/dist/ai/BbRadioGroup.md +102 -10
- package/dist/ai/BbSelect.md +52 -17
- package/dist/ai/BbSelectPopover.md +93 -26
- package/dist/ai/BbSwitch.md +1 -1
- package/dist/ai/BbSwitchGroup.md +30 -3
- package/dist/ai/BbTable.md +17 -10
- package/dist/ai/BbTabs.md +8 -3
- package/dist/ai/BbTabsList.md +4 -1
- package/dist/ai/BbTag.md +5 -2
- package/dist/ai/BbTextInput.md +4 -1
- package/dist/ai/BbTextarea.md +4 -1
- package/dist/ai/BbTimePicker.md +2 -1
- package/dist/ai/BbTimePickerInput.md +4 -1
- package/dist/ai/BbToast.md +9 -3
- package/dist/ai/BbTooltip.md +71 -9
- package/dist/ai/ChipsBox.md +1 -1
- package/dist/ai/CommonField.md +1 -1
- package/dist/ai/OptionsContainer.md +42 -0
- package/dist/ai/changelog.json +416 -6
- package/dist/ai/components.json +50 -48
- package/dist/ai/composables/useConfirm.md +39 -1
- package/dist/ai/design-tokens.json +6 -6
- package/dist/ai/guides/agent-contract.md +2 -2
- package/dist/ai/guides/ai-router.md +24 -23
- package/dist/ai/guides/app-layout.md +5 -0
- package/dist/ai/guides/component-picker.md +9 -2
- package/dist/ai/guides/design-language.md +24 -24
- package/dist/ai/guides/design-tokens.md +15 -8
- package/dist/ai/guides/icons-policy.md +9 -2
- package/dist/ai/guides/inertia-helpers.md +79 -49
- package/dist/ai/guides/installation-and-plugin-setup.md +12 -2
- package/dist/ai/guides/migration/adoption-checklist.md +235 -0
- package/dist/ai/guides/migration/components/bb-checkbox-group.md +16 -15
- package/dist/ai/guides/migration/components/bb-dialog.md +9 -9
- package/dist/ai/guides/migration/components/bb-dropdown.md +7 -2
- package/dist/ai/guides/migration/components/bb-popover.md +4 -2
- package/dist/ai/guides/migration/components/bb-select.md +19 -0
- package/dist/ai/guides/migration/components/bb-table.md +1 -0
- package/dist/ai/guides/migration/components/bb-toast.md +4 -0
- package/dist/ai/guides/migration/components/bb-tooltip.md +15 -12
- package/dist/ai/guides/migration/components/use-confirm.md +25 -2
- package/dist/ai/guides/migration/v2-to-v3.md +163 -9
- package/dist/ai/guides/migration/v3-beta-css-classes.md +7 -3
- package/dist/ai/guides/options-items-playbook.md +2 -1
- package/dist/ai/guides/passthrough.md +147 -85
- package/dist/ai/guides/preset-components.md +140 -15
- package/dist/ai/helpers/definePreset.json +7 -0
- package/dist/ai/helpers/definePreset.ts +123 -11
- package/dist/ai/helpers/inertia/manifest.json +15 -9
- package/dist/ai/helpers/inertia/useConfirmOnRouteLeave.ts +4 -4
- package/dist/ai/helpers/inertia/usePaginatedResponseContext.ts +39 -24
- package/dist/ai/helpers/inertia/useRouteQuery.ts +10 -4
- package/dist/ai/index.md +1 -0
- package/dist/ai/manifest/common.json +0 -1
- package/dist/ai/manifest/components/BbAlert.json +7 -2
- package/dist/ai/manifest/components/BbBadge.json +13 -4
- package/dist/ai/manifest/components/BbBadge.tree.json +2 -0
- package/dist/ai/manifest/components/BbBadgeButton.json +4 -2
- package/dist/ai/manifest/components/BbBaseButton.json +4 -2
- package/dist/ai/manifest/components/BbBreadcrumbs.tree.json +1 -1
- package/dist/ai/manifest/components/BbButton.json +14 -3
- package/dist/ai/manifest/components/BbButton.tree.json +5 -1
- package/dist/ai/manifest/components/BbCheckboxGroup.json +13 -8
- package/dist/ai/manifest/components/BbCheckboxGroup.tree.json +11 -1
- package/dist/ai/manifest/components/BbColorInput.json +18 -15
- package/dist/ai/manifest/components/BbColorPalette.json +1 -1
- package/dist/ai/manifest/components/BbConfirm.json +4 -2
- package/dist/ai/manifest/components/BbConfirm.tree.json +1 -1
- package/dist/ai/manifest/components/BbDatePicker.json +1 -1
- package/dist/ai/manifest/components/BbDatePickerInput.json +17 -14
- package/dist/ai/manifest/components/BbDialog.tree.json +2 -1
- package/dist/ai/manifest/components/BbDropdown.json +24 -19
- package/dist/ai/manifest/components/BbDropdown.tree.json +9 -2
- package/dist/ai/manifest/components/BbDropdownButton.json +33 -20
- package/dist/ai/manifest/components/BbDropdownButton.tree.json +2 -2
- package/dist/ai/manifest/components/BbForm.json +2 -2
- package/dist/ai/manifest/components/BbHost.tree.json +1 -1
- package/dist/ai/manifest/components/BbHoverCard.json +1 -1
- package/dist/ai/manifest/components/BbIndicator.json +8 -2
- package/dist/ai/manifest/components/BbNumberInput.json +5 -2
- package/dist/ai/manifest/components/BbOffCanvas.json +2 -2
- package/dist/ai/manifest/components/BbOffCanvas.tree.json +1 -1
- package/dist/ai/manifest/components/BbPopover.json +1 -1
- package/dist/ai/manifest/components/BbRadioGroup.json +17 -12
- package/dist/ai/manifest/components/BbRadioGroup.tree.json +8 -1
- package/dist/ai/manifest/components/BbSelect.json +21 -18
- package/dist/ai/manifest/components/BbSelect.tree.json +2 -2
- package/dist/ai/manifest/components/BbSelectPopover.json +10 -10
- package/dist/ai/manifest/components/BbSelectPopover.tree.json +3 -2
- package/dist/ai/manifest/components/BbSwitchGroup.json +1 -1
- package/dist/ai/manifest/components/BbSwitchGroup.tree.json +3 -1
- package/dist/ai/manifest/components/BbTable.tree.json +14 -1
- package/dist/ai/manifest/components/BbTabs.json +9 -6
- package/dist/ai/manifest/components/BbTabs.tree.json +1 -1
- package/dist/ai/manifest/components/BbTabsList.json +6 -3
- package/dist/ai/manifest/components/BbTag.json +19 -16
- package/dist/ai/manifest/components/BbTag.tree.json +1 -1
- package/dist/ai/manifest/components/BbTextInput.json +6 -3
- package/dist/ai/manifest/components/BbTextarea.json +6 -3
- package/dist/ai/manifest/components/BbTimePicker.json +1 -1
- package/dist/ai/manifest/components/BbTimePickerInput.json +10 -7
- package/dist/ai/manifest/components/BbToast.json +7 -2
- package/dist/ai/manifest/components/BbToast.tree.json +4 -2
- package/dist/ai/manifest/components/BbTooltip.json +6 -5
- package/dist/ai/manifest/components/ChipsBox.tree.json +1 -1
- package/dist/ai/manifest/components/CommonField.json +1 -1
- package/dist/ai/manifest/components/OptionsContainer.json +3 -1
- package/dist/ai/manifest/components/OptionsContainer.tree.json +38 -0
- package/dist/ai/manifest/index.json +3 -3
- package/dist/ai/manifest/meta.json +5 -3
- package/dist/ai/manifest/types.advanced.json +5 -2
- package/dist/ai/manifest/types.api.json +9 -7
- package/dist/ai/recipes/inertia/layout-scaffold.md +19 -6
- package/dist/ai/recipes/inertia/records-workspace.md +49 -13
- package/dist/ai/recipes/nuxt/layout-scaffold.md +19 -6
- package/dist/ai/recipes/nuxt/records-workspace.md +42 -12
- package/dist/ai/recipes/vue/layout-scaffold.md +19 -6
- package/dist/ai/recipes/vue/records-workspace.md +42 -12
- package/dist/ai/source/BbAlert.md +94 -76
- package/dist/ai/source/BbBadge.md +174 -72
- package/dist/ai/source/BbBadgeButton.md +130 -65
- package/dist/ai/source/BbBaseButton.md +46 -124
- package/dist/ai/source/BbBaseCheckboxIcon.md +38 -0
- package/dist/ai/source/BbBaseRadioIcon.md +18 -0
- package/dist/ai/source/BbBaseSwitchIcon.md +51 -0
- package/dist/ai/source/BbButton.md +153 -36
- package/dist/ai/source/BbCheckboxGroup.md +142 -18
- package/dist/ai/source/BbColorInput.md +240 -204
- package/dist/ai/source/BbColorPalette.md +7 -4
- package/dist/ai/source/BbConfirm.md +34 -11
- package/dist/ai/source/BbConfirmPortal.md +24 -9
- package/dist/ai/source/BbDatePicker.md +11 -7
- package/dist/ai/source/BbDatePickerInput.md +306 -269
- package/dist/ai/source/BbDialog.md +49 -14
- package/dist/ai/source/BbDropdown.md +314 -197
- package/dist/ai/source/BbDropdownButton.md +197 -31
- package/dist/ai/source/BbDropdownGroup.md +274 -176
- package/dist/ai/source/BbForm.md +50 -6
- package/dist/ai/source/BbHoverCard.md +12 -5
- package/dist/ai/source/BbIcon.md +4 -3
- package/dist/ai/source/BbIndicator.md +73 -52
- package/dist/ai/source/BbNumberInput.md +293 -257
- package/dist/ai/source/BbOffCanvas.md +55 -29
- package/dist/ai/source/BbPopover.md +14 -10
- package/dist/ai/source/BbRadioGroup.md +413 -297
- package/dist/ai/source/BbSelect.md +549 -435
- package/dist/ai/source/BbSelectPopover.md +128 -33
- package/dist/ai/source/BbSwitchGroup.md +70 -10
- package/dist/ai/source/BbTable.md +369 -37
- package/dist/ai/source/BbTabs.md +115 -39
- package/dist/ai/source/BbTabsList.md +106 -38
- package/dist/ai/source/BbTabsPanels.md +96 -36
- package/dist/ai/source/BbTabsRoot.md +96 -36
- package/dist/ai/source/BbTag.md +267 -233
- package/dist/ai/source/BbTextInput.md +261 -225
- package/dist/ai/source/BbTextarea.md +251 -215
- package/dist/ai/source/BbTimePicker.md +11 -7
- package/dist/ai/source/BbTimePickerInput.md +257 -220
- package/dist/ai/source/BbToast.md +73 -32
- package/dist/ai/source/BbToastPortal.md +65 -30
- package/dist/ai/source/BbTooltip.md +148 -113
- package/dist/ai/source/CommonPopover.md +6 -1
- package/dist/ai/source/FlatListBox.md +19 -9
- package/dist/ai/source/GroupedListBox.md +19 -9
- package/dist/ai/source/OptionsContainer.md +25 -9
- package/dist/components/BbAlert/BbAlert.vue_vue_type_script_setup_true_lang.js +61 -36
- package/dist/components/BbAlert/types.d.ts +9 -5
- package/dist/components/BbAlert/types.js +8 -3
- package/dist/components/BbBadge/BadgeBodyContent.vue.d.ts +3 -3
- package/dist/components/BbBadge/BadgeBodyContent.vue_vue_type_script_setup_true_lang.js +26 -17
- package/dist/components/BbBadge/BbBadge.vue_vue_type_script_setup_true_lang.js +103 -50
- package/dist/components/BbBadge/BbBadgeButton.vue_vue_type_script_setup_true_lang.js +20 -15
- package/dist/components/BbBadge/badgeButtonContext.d.ts +12 -1
- package/dist/components/BbBadge/types.d.ts +45 -15
- package/dist/components/BbBadge/types.js +12 -3
- package/dist/components/BbBaseButton/BbBaseButton.vue_vue_type_script_setup_true_lang.js +89 -126
- package/dist/components/BbBaseButton/types.d.ts +23 -4
- package/dist/components/BbBaseButton/types.js +7 -1
- package/dist/components/BbBaseButton/useLinkState.d.ts +41 -0
- package/dist/components/BbBaseButton/useLinkState.js +70 -0
- package/dist/components/BbButton/BbButton.vue_vue_type_script_setup_true_lang.js +130 -74
- package/dist/components/BbButton/types.d.ts +50 -13
- package/dist/components/BbButton/types.js +10 -3
- package/dist/components/BbCheckboxGroup/BbCheckboxGroup.vue_vue_type_script_setup_true_lang.js +148 -95
- package/dist/components/BbCheckboxGroup/types.d.ts +34 -11
- package/dist/components/BbCheckboxGroup/types.js +9 -4
- package/dist/components/BbCollapsible/BbCollapsible.vue.d.ts +1 -1
- package/dist/components/BbColorInput/BbColorInput.vue_vue_type_script_setup_true_lang.js +134 -93
- package/dist/components/BbColorInput/types.d.ts +11 -4
- package/dist/components/BbColorInput/types.js +9 -3
- package/dist/components/BbConfirm/BbConfirm.vue_vue_type_script_setup_true_lang.js +82 -59
- package/dist/components/BbConfirm/types.d.ts +9 -4
- package/dist/components/BbConfirm/types.js +8 -3
- package/dist/components/BbDatePicker/BbDatePicker.vue.d.ts +1 -1
- package/dist/components/BbDatePicker/BbDatePicker.vue_vue_type_script_setup_true_lang.js +68 -67
- package/dist/components/BbDatePickerInput/BbDatePickerInput.vue.d.ts +1 -1
- package/dist/components/BbDatePickerInput/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +259 -215
- package/dist/components/BbDatePickerInput/types.d.ts +12 -5
- package/dist/components/BbDatePickerInput/types.js +9 -3
- package/dist/components/BbDialog/BbDialog.vue_vue_type_script_setup_true_lang.js +223 -219
- package/dist/components/BbDialog/useDialogStack.d.ts +1 -1
- package/dist/components/BbDropdown/AdaptiveDropdown.vue_vue_type_script_setup_true_lang.js +104 -89
- package/dist/components/BbDropdown/BbDropdown.vue.d.ts +1 -0
- package/dist/components/BbDropdown/BbDropdown.vue_vue_type_script_setup_true_lang.js +323 -285
- package/dist/components/BbDropdown/BbDropdownList.vue.d.ts +1 -0
- package/dist/components/BbDropdown/BbDropdownList.vue_vue_type_script_setup_true_lang.js +411 -319
- package/dist/components/BbDropdown/DropdownPipelineResolver.vue_vue_type_script_setup_true_lang.js +100 -98
- package/dist/components/BbDropdown/DropdownRow.vue.d.ts +4 -3
- package/dist/components/BbDropdown/DropdownRow.vue_vue_type_script_setup_true_lang.js +49 -28
- package/dist/components/BbDropdown/normalizeGroups.d.ts +6 -0
- package/dist/components/BbDropdown/normalizeGroups.js +21 -15
- package/dist/components/BbDropdown/types.d.ts +59 -12
- package/dist/components/BbDropdown/types.js +16 -3
- package/dist/components/BbDropdown/useDropdownContext.d.ts +6 -0
- package/dist/components/BbDropdownButton/BbDropdownButton.vue.d.ts +2 -1
- package/dist/components/BbDropdownButton/BbDropdownButton.vue_vue_type_script_setup_true_lang.js +179 -68
- package/dist/components/BbDropdownButton/types.d.ts +44 -16
- package/dist/components/BbDropdownButton/types.js +28 -3
- package/dist/components/BbForm/BbForm.vue_vue_type_script_setup_true_lang.js +111 -89
- package/dist/components/BbForm/formSchema.d.ts +13 -0
- package/dist/components/BbHoverCard/BbHoverCard.vue_vue_type_script_setup_true_lang.js +100 -100
- package/dist/components/BbIndicator/BbIndicator.vue_vue_type_script_setup_true_lang.js +40 -25
- package/dist/components/BbIndicator/types.d.ts +9 -5
- package/dist/components/BbIndicator/types.js +8 -3
- package/dist/components/BbNumberInput/BbNumberInput.vue_vue_type_script_setup_true_lang.js +243 -202
- package/dist/components/BbNumberInput/types.d.ts +12 -5
- package/dist/components/BbNumberInput/types.js +9 -3
- package/dist/components/BbOffCanvas/BbOffCanvas.vue.d.ts +1 -1
- package/dist/components/BbOffCanvas/BbOffCanvas.vue_vue_type_script_setup_true_lang.js +401 -399
- package/dist/components/BbOffCanvas/types.d.ts +6 -2
- package/dist/components/BbPopover/BbPopover.vue_vue_type_script_setup_true_lang.js +81 -80
- package/dist/components/BbRadioGroup/BbRadioGroup.vue_vue_type_script_setup_true_lang.js +158 -105
- package/dist/components/BbRadioGroup/types.d.ts +21 -7
- package/dist/components/BbRadioGroup/types.js +9 -4
- package/dist/components/BbSelect/BbSelect.vue.d.ts +4 -3
- package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +181 -137
- package/dist/components/BbSelect/types.d.ts +36 -22
- package/dist/components/BbSelect/types.js +22 -3
- package/dist/components/BbSelectPopover/BbSelectPopover.vue.d.ts +4 -4
- package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +543 -532
- package/dist/components/BbSelectPopover/knownItems.d.ts +5 -0
- package/dist/components/BbSelectPopover/types.d.ts +46 -12
- package/dist/components/BbSmoothHeight/BbSmoothHeight.vue.d.ts +1 -1
- package/dist/components/BbSwitchGroup/BbSwitchGroup.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/BbSwitchGroup/types.d.ts +14 -4
- package/dist/components/BbSwitchGroup/types.js +8 -3
- package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +1102 -995
- package/dist/components/BbTable/estimatedFloors.golden.d.ts +25 -0
- package/dist/components/BbTable/measuredFloors.d.ts +46 -0
- package/dist/components/BbTable/measuredFloors.js +322 -0
- package/dist/components/BbTable/measuredFloorsTestKit.d.ts +27 -0
- package/dist/components/BbTable/textRuler.d.ts +71 -0
- package/dist/components/BbTable/textRuler.js +121 -0
- package/dist/components/BbTable/utils.d.ts +113 -6
- package/dist/components/BbTable/utils.js +118 -65
- package/dist/components/BbTabs/BbTabs.vue_vue_type_script_setup_true_lang.js +53 -35
- package/dist/components/BbTabs/BbTabsList.vue_vue_type_script_setup_true_lang.js +62 -45
- package/dist/components/BbTabs/types.d.ts +26 -11
- package/dist/components/BbTabs/types.js +23 -8
- package/dist/components/BbTag/BbTag.vue_vue_type_script_setup_true_lang.js +205 -164
- package/dist/components/BbTag/types.d.ts +11 -4
- package/dist/components/BbTag/types.js +9 -3
- package/dist/components/BbTextInput/BbTextInput.vue_vue_type_script_setup_true_lang.js +98 -57
- package/dist/components/BbTextInput/types.d.ts +12 -5
- package/dist/components/BbTextInput/types.js +9 -3
- package/dist/components/BbTextarea/BbTextarea.vue_vue_type_script_setup_true_lang.js +137 -96
- package/dist/components/BbTextarea/types.d.ts +12 -5
- package/dist/components/BbTextarea/types.js +9 -3
- package/dist/components/BbTimePicker/BbTimePicker.vue_vue_type_script_setup_true_lang.js +105 -104
- package/dist/components/BbTimePickerInput/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +241 -197
- package/dist/components/BbTimePickerInput/types.d.ts +12 -5
- package/dist/components/BbTimePickerInput/types.js +9 -3
- package/dist/components/BbToast/BbToast.vue_vue_type_script_setup_true_lang.js +74 -32
- package/dist/components/BbToast/BbToastMessage.vue_vue_type_script_setup_true_lang.js +47 -47
- package/dist/components/BbToast/types.d.ts +10 -5
- package/dist/components/BbToast/types.js +18 -3
- package/dist/components/BbTooltip/BbTooltip.vue_vue_type_script_setup_true_lang.js +85 -71
- package/dist/components/BbTooltip/types.d.ts +13 -8
- package/dist/components/BbTooltip/types.js +8 -3
- package/dist/components/CommonField/CommonField.vue.d.ts +1 -1
- package/dist/components/CommonPopover/CommonPopover.vue.d.ts +1 -1
- package/dist/components/CommonPopover/CommonPopover.vue_vue_type_script_setup_true_lang.js +69 -69
- package/dist/components/FlatListBox/FlatListBox.vue_vue_type_script_setup_true_lang.js +53 -50
- package/dist/components/GroupedListBox/GroupedListBox.vue_vue_type_script_setup_true_lang.js +146 -143
- package/dist/components/OptionsContainer/OptionsContainer.vue_vue_type_script_setup_true_lang.js +7 -2
- package/dist/components/OptionsContainer/types.d.ts +14 -3
- package/dist/composables/useBbFormContext.d.ts +4 -3
- package/dist/composables/useBbTabsContext.js +99 -85
- package/dist/composables/useChoiceIndicator.d.ts +58 -0
- package/dist/composables/useChoiceIndicator.js +197 -0
- package/dist/composables/useConfirm.d.ts +4 -4
- package/dist/composables/usePassthrough.d.ts +54 -1
- package/dist/composables/usePassthrough.js +100 -71
- package/dist/directives/bbTooltip.d.ts +12 -6
- package/dist/directives/createPopoverDirective.js +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/llms-full.txt +2300 -543
- package/dist/llms-medium.txt +71 -53
- package/dist/llms.txt +2 -1
- package/dist/passthrough-deduper.js +6 -3
- package/dist/project-dts.d.ts +24 -0
- package/dist/project-dts.js +43 -17
- package/dist/styles.css +2 -2
- package/dist/types/AlertVariant.d.ts +14 -0
- package/dist/types/AlertVariant.js +9 -0
- package/dist/types/BadgeVariant.d.ts +14 -0
- package/dist/types/BadgeVariant.js +9 -0
- package/dist/types/ButtonVariant.d.ts +16 -0
- package/dist/types/ButtonVariant.js +11 -0
- package/dist/types/CheckboxVariant.d.ts +38 -0
- package/dist/types/CheckboxVariant.js +4 -0
- package/dist/types/CommonProps.d.ts +4 -3
- package/dist/types/Config.d.ts +7 -0
- package/dist/types/ConfirmVariant.d.ts +12 -0
- package/dist/types/ConfirmVariant.js +4 -0
- package/dist/types/DropdownItemVariant.d.ts +12 -0
- package/dist/types/DropdownItemVariant.js +4 -0
- package/dist/types/IndicatorVariant.d.ts +15 -0
- package/dist/types/IndicatorVariant.js +10 -0
- package/dist/types/InputVariant.d.ts +13 -0
- package/dist/types/InputVariant.js +8 -0
- package/dist/types/RadioVariant.d.ts +38 -0
- package/dist/types/RadioVariant.js +4 -0
- package/dist/types/TabsVariant.d.ts +13 -0
- package/dist/types/TabsVariant.js +8 -0
- package/dist/types/ToastVariant.d.ts +15 -0
- package/dist/types/ToastVariant.js +10 -0
- package/dist/types/TooltipVariant.d.ts +12 -0
- package/dist/types/TooltipVariant.js +4 -0
- package/dist/types/passthrough.d.ts +83 -15
- package/dist/types/passthrough.js +2 -2
- package/dist/types/ptComponentMap.d.ts +35 -23
- package/dist/utilities/functions/extractDomContainer.d.ts +20 -1
- package/dist/utilities/functions/extractDomContainer.js +8 -3
- package/dist/utils/focusVisibility.d.ts +6 -0
- package/dist/utils/focusVisibility.js +4 -1
- package/dist/utils/passthroughDeduper.d.ts +14 -0
- package/dist/utils/versionCheck.js +1 -1
- package/dist/vite-plugin.d.ts +64 -7
- package/dist/vite.js +385 -259
- package/llms.txt +2 -1
- package/package.json +3 -3
- package/scripts/lib/adoption-checklist.json +312 -0
- package/scripts/lib/eslint-plugin.d.ts +13 -0
- package/scripts/lib/eslint-plugin.mjs +75 -11
- package/scripts/lib/idiom-scan.mjs +65 -0
- package/scripts/lib/mcp-config.mjs +203 -9
- package/scripts/lib/migrate-fix.mjs +42 -1
- package/scripts/lib/project-variant-dts.mjs +18 -0
- package/scripts/lib/validate-bb-markup.mjs +99 -2
|
@@ -648,6 +648,7 @@ import {
|
|
|
648
648
|
reactive,
|
|
649
649
|
ref,
|
|
650
650
|
shallowRef,
|
|
651
|
+
toDisplayString,
|
|
651
652
|
toRaw,
|
|
652
653
|
toRef,
|
|
653
654
|
useAttrs,
|
|
@@ -739,12 +740,16 @@ import {
|
|
|
739
740
|
readResolvedTracks,
|
|
740
741
|
rowNameText,
|
|
741
742
|
sameColumnOrder,
|
|
743
|
+
cellRole as valueRoleClasses,
|
|
742
744
|
estimateFromProfile,
|
|
743
745
|
fitFloors,
|
|
744
746
|
profileValues,
|
|
747
|
+
estimateSamples,
|
|
748
|
+
floorTextPx,
|
|
745
749
|
sampleForEstimate,
|
|
746
750
|
} from './utils';
|
|
747
751
|
import type { ColumnProfile, FixedColumnConfig, TrackEstimate } from './utils';
|
|
752
|
+
import { createMeasuredFloors, type MeasuredColumn } from './measuredFloors';
|
|
748
753
|
import { useBbTableContextHost } from '../../composables/useBbTableContext';
|
|
749
754
|
import { useLogger } from '@/composables/useLogger';
|
|
750
755
|
import {
|
|
@@ -4275,9 +4280,16 @@ const mapColumnToCell = (
|
|
|
4275
4280
|
// Lazy for the same reason as `rowClasses` above: `td-class` is the
|
|
4276
4281
|
// consumer's function over the consumer's state.
|
|
4277
4282
|
get classes() {
|
|
4283
|
+
const key = String(column.key);
|
|
4278
4284
|
return mergeCellClasses(
|
|
4279
|
-
fluidColumnKeys.value.has(
|
|
4280
|
-
? [
|
|
4285
|
+
fluidColumnKeys.value.has(key)
|
|
4286
|
+
? [
|
|
4287
|
+
`bb-table__cell--${align}`,
|
|
4288
|
+
'bb-table__cell--fluid',
|
|
4289
|
+
// How the fit holds this value (`cellRole`): static per text,
|
|
4290
|
+
// switched on by the table root's hold level.
|
|
4291
|
+
...roleClassesOf(key, content()),
|
|
4292
|
+
]
|
|
4281
4293
|
: [`bb-table__cell--${align}`],
|
|
4282
4294
|
props.tdClass,
|
|
4283
4295
|
column.tdClass,
|
|
@@ -4320,6 +4332,19 @@ const mapColumnToCell = (
|
|
|
4320
4332
|
* their first batch: a floor there would cut values off rather than wrap
|
|
4321
4333
|
* them), a custom `#thead`, declared or resized widths, or slot columns (no
|
|
4322
4334
|
* text to read: their content floors them as before).
|
|
4335
|
+
*
|
|
4336
|
+
* MEASURED FLOORS. The estimate's character table follows Arial; a wider UI
|
|
4337
|
+
* font drew a date 2px past its floor and broke it. Four layers since:
|
|
4338
|
+
* 1. Classification: which values stay whole is the estimate's (`cellRole`,
|
|
4339
|
+
* a static role class per cell), the same on the server.
|
|
4340
|
+
* 2. The plan: after mount the values that could be a column's widest, and
|
|
4341
|
+
* its heading, are measured in their rendered type (measuredFloors.ts,
|
|
4342
|
+
* textRuler.ts); a measured width only RAISES a reservation.
|
|
4343
|
+
* 3. Geometry: the fit's hold level is one class on the grid root, and the
|
|
4344
|
+
* cells it promises floor their own track (index.css), so the browser
|
|
4345
|
+
* keeps them whole with the real text in the real font.
|
|
4346
|
+
* 4. The guard: a plan that says "fits" but overflows reads its held cells
|
|
4347
|
+
* and headers in place and raises the same store (bounded).
|
|
4323
4348
|
*/
|
|
4324
4349
|
/**
|
|
4325
4350
|
* What each estimated column shows (its text exactly as the body renders it),
|
|
@@ -4328,8 +4353,8 @@ const mapColumnToCell = (
|
|
|
4328
4353
|
* like any other. Apart from the estimate, so a resize, which re-runs that,
|
|
4329
4354
|
* re-reads no rows.
|
|
4330
4355
|
*/
|
|
4331
|
-
const
|
|
4332
|
-
const out: Record<string,
|
|
4356
|
+
const columnValues = computed(() => {
|
|
4357
|
+
const out: Record<string, string[]> = {};
|
|
4333
4358
|
// A custom `#thead` renders its own header cells: no spacer to carry a
|
|
4334
4359
|
// floor, and `--fluid` body cells would leave the columns with none.
|
|
4335
4360
|
if (props.fixed || isInheriting.value || virtualActive.value || slots.thead)
|
|
@@ -4338,15 +4363,87 @@ const columnProfiles = computed(() => {
|
|
|
4338
4363
|
for (const column of orderedColumns.value) {
|
|
4339
4364
|
if (effectiveWidth(column) != null) continue;
|
|
4340
4365
|
if (slots[slotNamesByKey.value[column.key] as keyof typeof slots]) continue;
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4366
|
+
// The text exactly as the cell renders it (an array or an object too).
|
|
4367
|
+
out[String(column.key)] = rows.map((raw) =>
|
|
4368
|
+
toDisplayString(cellContentOf(column, raw))
|
|
4369
|
+
);
|
|
4370
|
+
}
|
|
4371
|
+
return out;
|
|
4372
|
+
});
|
|
4373
|
+
/** The body text's px, apart from the rest of the metrics: a resize must not
|
|
4374
|
+
* re-profile the columns. */
|
|
4375
|
+
const bodyEm = computed(() => floorMetrics.value?.em ?? 0);
|
|
4376
|
+
/** The values' real widths, measured after mount (measuredFloors.ts). */
|
|
4377
|
+
const measured = createMeasuredFloors({
|
|
4378
|
+
table: () => tableRef.value,
|
|
4379
|
+
container: () => containerRef.value,
|
|
4380
|
+
columns: () => measuredColumns(),
|
|
4381
|
+
em: () => bodyEm.value,
|
|
4382
|
+
plan: () => {
|
|
4383
|
+
const { stage, hold, floors, wrapLabels } = fittedFloors.value;
|
|
4384
|
+
return JSON.stringify([stage, hold, floors, [...wrapLabels]]);
|
|
4385
|
+
},
|
|
4386
|
+
});
|
|
4387
|
+
/** Each column profiled, its reservations raised to the measured widths. */
|
|
4388
|
+
const columnProfiles = computed(() => {
|
|
4389
|
+
void measured.version.value;
|
|
4390
|
+
const out: Record<string, ColumnProfile | null> = {};
|
|
4391
|
+
for (const [key, values] of Object.entries(columnValues.value))
|
|
4392
|
+
out[key] = profileValues(values, measured.lookup(key));
|
|
4393
|
+
return out;
|
|
4394
|
+
});
|
|
4395
|
+
|
|
4396
|
+
/**
|
|
4397
|
+
* What `cellRole` reads of each column, as ONE string first (like
|
|
4398
|
+
* `fluidKeyList`): it changes with the rows only, never with a measurement
|
|
4399
|
+
* or a resize, so the cells re-render only when their roles can change.
|
|
4400
|
+
*/
|
|
4401
|
+
const columnRoleKeyList = computed(() => {
|
|
4402
|
+
const parts: string[] = [];
|
|
4403
|
+
for (const [key, p] of Object.entries(columnProfiles.value))
|
|
4404
|
+
if (p) parts.push(`${key}\u0001${p.prose ? 1 : 0}\u0001${p.usual}`);
|
|
4405
|
+
return parts.join('\u0002');
|
|
4406
|
+
});
|
|
4407
|
+
const roleInputs = computed(() => {
|
|
4408
|
+
const out = new Map<string, { prose: boolean; usual: number }>();
|
|
4409
|
+
for (const part of columnRoleKeyList.value.split('\u0002')) {
|
|
4410
|
+
if (!part) continue;
|
|
4411
|
+
const [key, prose, usual] = part.split('\u0001');
|
|
4412
|
+
out.set(key!, { prose: prose === '1', usual: Number(usual) });
|
|
4413
|
+
}
|
|
4414
|
+
return out;
|
|
4415
|
+
});
|
|
4416
|
+
/**
|
|
4417
|
+
* Past 2,000 rows the estimate reads a sample (`sampleForEstimate`): the texts
|
|
4418
|
+
* it read, per column, or `null` when it reads every row. A value only an
|
|
4419
|
+
* unread row shows was never reserved, so it gets no role (fluid, it wraps as
|
|
4420
|
+
* before): held, it would widen its track past the plan. Off the rows and the
|
|
4421
|
+
* columns only (not `columnValues`, which a resize preview re-runs), so a
|
|
4422
|
+
* resize re-renders no cell.
|
|
4423
|
+
*/
|
|
4424
|
+
const sampledTexts = computed(() => {
|
|
4425
|
+
const all = internalItems.value ?? [];
|
|
4426
|
+
if (!estimateSamples(all.length)) return null;
|
|
4427
|
+
const rows = sampleForEstimate(all);
|
|
4428
|
+
const out = new Map<string, Set<string>>();
|
|
4429
|
+
for (const column of orderedColumns.value) {
|
|
4430
|
+
if (slots[slotNamesByKey.value[column.key] as keyof typeof slots]) continue;
|
|
4431
|
+
out.set(
|
|
4432
|
+
String(column.key),
|
|
4433
|
+
new Set(
|
|
4434
|
+
rows.map((raw) => toDisplayString(cellContentOf(column, raw)).trim())
|
|
4435
|
+
)
|
|
4346
4436
|
);
|
|
4347
4437
|
}
|
|
4348
4438
|
return out;
|
|
4349
4439
|
});
|
|
4440
|
+
const roleClassesOf = (key: string, content: unknown): string[] => {
|
|
4441
|
+
const inputs = roleInputs.value.get(key);
|
|
4442
|
+
if (!inputs) return [];
|
|
4443
|
+
const text = toDisplayString(content);
|
|
4444
|
+
if (sampledTexts.value?.get(key)?.has(text.trim()) === false) return [];
|
|
4445
|
+
return valueRoleClasses(text, inputs);
|
|
4446
|
+
};
|
|
4350
4447
|
|
|
4351
4448
|
const columnEstimates = computed(() => {
|
|
4352
4449
|
const out: Record<string, TrackEstimate> = {};
|
|
@@ -4365,29 +4462,25 @@ const columnEstimates = computed(() => {
|
|
|
4365
4462
|
const key = String(column.key);
|
|
4366
4463
|
if (!(key in profiles)) continue;
|
|
4367
4464
|
// The sort arrow: 1em plus the 4px gap, in the header's type.
|
|
4465
|
+
const arrowEm = column.sortable ? 1.3 : 0;
|
|
4368
4466
|
const estimate = estimateFromProfile(
|
|
4369
4467
|
profiles[key]!,
|
|
4370
4468
|
headerType
|
|
4371
4469
|
? casedLabel(column.label ?? '', headerType.transform)
|
|
4372
4470
|
: (column.label ?? ''),
|
|
4373
|
-
|
|
4374
|
-
|
|
4471
|
+
// A body padded wider than its header (a `td-class` `px-6`) reserves
|
|
4472
|
+
// that padding too: the header's spacer then covers it (raise-only).
|
|
4473
|
+
padEm + measured.extraPadOf(key),
|
|
4474
|
+
arrowEm,
|
|
4375
4475
|
headerType,
|
|
4376
|
-
legacyPadEm
|
|
4476
|
+
legacyPadEm,
|
|
4477
|
+
// The heading as it really renders, once measured (raise-only).
|
|
4478
|
+
measured.labelOf(key, arrowEm)
|
|
4377
4479
|
);
|
|
4378
4480
|
estimate.squeeze = (estimate.squeeze - legacyPadEm) * legacyScale + padEm;
|
|
4379
4481
|
// Only our own label wraps (Q76.9 e): a header slot or an affix keeps
|
|
4380
4482
|
// its heading on one line, so the fit must not count on two.
|
|
4381
|
-
|
|
4382
|
-
if (
|
|
4383
|
-
[
|
|
4384
|
-
`${slot}:header`,
|
|
4385
|
-
`${slot}:header:prepend`,
|
|
4386
|
-
`${slot}:header:append`,
|
|
4387
|
-
'header:prepend',
|
|
4388
|
-
'header:append',
|
|
4389
|
-
].some((name) => slots[name as keyof typeof slots])
|
|
4390
|
-
) {
|
|
4483
|
+
if (!ownsHeading(column)) {
|
|
4391
4484
|
estimate.labelWrap = estimate.label;
|
|
4392
4485
|
estimate.wrapped = estimate.hard;
|
|
4393
4486
|
}
|
|
@@ -4396,6 +4489,42 @@ const columnEstimates = computed(() => {
|
|
|
4396
4489
|
return out;
|
|
4397
4490
|
});
|
|
4398
4491
|
|
|
4492
|
+
/** Our own label renders the heading: no header slot, no affix. */
|
|
4493
|
+
const ownsHeading = (column: BbTableColumn<Item>) => {
|
|
4494
|
+
const slot = slotNamesByKey.value[column.key];
|
|
4495
|
+
return ![
|
|
4496
|
+
`${slot}:header`,
|
|
4497
|
+
`${slot}:header:prepend`,
|
|
4498
|
+
`${slot}:header:append`,
|
|
4499
|
+
'header:prepend',
|
|
4500
|
+
'header:append',
|
|
4501
|
+
].some((name) => slots[name as keyof typeof slots]);
|
|
4502
|
+
};
|
|
4503
|
+
/** What the measuring pass reads of each estimated column (not reactive:
|
|
4504
|
+
* read inside the pass). */
|
|
4505
|
+
const measuredColumns = (): MeasuredColumn[] => {
|
|
4506
|
+
const values = columnValues.value;
|
|
4507
|
+
const offset = Number(rowDragActive.value) + Number(!!props.selectable);
|
|
4508
|
+
const out: MeasuredColumn[] = [];
|
|
4509
|
+
orderedColumns.value.forEach((column, index) => {
|
|
4510
|
+
const key = String(column.key);
|
|
4511
|
+
if (!(key in values)) return;
|
|
4512
|
+
out.push({
|
|
4513
|
+
key,
|
|
4514
|
+
index: index + offset,
|
|
4515
|
+
values: values[key]!,
|
|
4516
|
+
placeholder: column.placeholder || undefined,
|
|
4517
|
+
prose: roleInputs.value.get(key)?.prose ?? false,
|
|
4518
|
+
label: ownsHeading(column) ? column.label || undefined : undefined,
|
|
4519
|
+
dynamic:
|
|
4520
|
+
typeof props.tdClass === 'function' ||
|
|
4521
|
+
typeof column.tdClass === 'function' ||
|
|
4522
|
+
typeof props.rowClass === 'function',
|
|
4523
|
+
});
|
|
4524
|
+
});
|
|
4525
|
+
return out;
|
|
4526
|
+
};
|
|
4527
|
+
|
|
4399
4528
|
// The `--fluid` body cells, as a string first (see `clippedKeyList`): a new
|
|
4400
4529
|
// floor or a container resize must not re-render every cell.
|
|
4401
4530
|
const fluidKeyList = computed(() =>
|
|
@@ -4451,6 +4580,17 @@ const floorRoomEm = computed(() => {
|
|
|
4451
4580
|
const fittedFloors = computed(() =>
|
|
4452
4581
|
fitFloors(columnEstimates.value, floorRoomEm.value)
|
|
4453
4582
|
);
|
|
4583
|
+
/**
|
|
4584
|
+
* The table root's hold level (`fitFloors`' `hold`): which of the values the
|
|
4585
|
+
* estimate holds the floors still cover, so their cells may floor their own
|
|
4586
|
+
* track (index.css). One class on the root, so a new level re-renders no row.
|
|
4587
|
+
*/
|
|
4588
|
+
const holdClass = computed(() => {
|
|
4589
|
+
const { hold } = fittedFloors.value;
|
|
4590
|
+
return fluidKeyList.value && hold !== 'none'
|
|
4591
|
+
? `bb-table__table--hold-${hold}`
|
|
4592
|
+
: undefined;
|
|
4593
|
+
});
|
|
4454
4594
|
/** Headings given two lines so the table fits (Q76.9 e): `--wrap`. */
|
|
4455
4595
|
const wrapLabelKeys = computed(() => fittedFloors.value.wrapLabels);
|
|
4456
4596
|
|
|
@@ -4465,7 +4605,7 @@ const columnFloorStyles = computed(() => {
|
|
|
4465
4605
|
const text = Math.max(0, floors[key]! - padEm);
|
|
4466
4606
|
out[key] = {
|
|
4467
4607
|
'--floor': metrics
|
|
4468
|
-
? `${
|
|
4608
|
+
? `${floorTextPx(floors[key]!, padEm, metrics.em)}px`
|
|
4469
4609
|
: // In body-text em like the estimate, whatever the header's type.
|
|
4470
4610
|
`calc(${text.toFixed(2)} * var(--bb-fs, 1em))`,
|
|
4471
4611
|
};
|
|
@@ -4475,6 +4615,41 @@ const columnFloorStyles = computed(() => {
|
|
|
4475
4615
|
|
|
4476
4616
|
let floorObserver: ResizeObserver | undefined;
|
|
4477
4617
|
let floorFrame = 0;
|
|
4618
|
+
/** `--bb-fs` in px, probed once per value of what it resolves from: the
|
|
4619
|
+
* token itself, the root's and the page's font sizes, and the box a viewport
|
|
4620
|
+
* or container unit resolves against (which no style read sees change). */
|
|
4621
|
+
let emProbe: { key: string; em: number } | undefined;
|
|
4622
|
+
/** The sizes of `el`'s query containers, for a `cq` unit's key. */
|
|
4623
|
+
const containerSizes = (el: HTMLElement) => {
|
|
4624
|
+
const sizes: string[] = [];
|
|
4625
|
+
for (let node = el.parentElement; node; node = node.parentElement)
|
|
4626
|
+
if (getComputedStyle(node).containerType !== 'normal')
|
|
4627
|
+
sizes.push(`${node.clientWidth}x${node.clientHeight}`);
|
|
4628
|
+
return sizes.join(',');
|
|
4629
|
+
};
|
|
4630
|
+
const bodyEmOf = (container: HTMLElement) => {
|
|
4631
|
+
const style = getComputedStyle(container);
|
|
4632
|
+
const token = style.getPropertyValue('--bb-fs').trim();
|
|
4633
|
+
const key = [
|
|
4634
|
+
token,
|
|
4635
|
+
style.fontSize,
|
|
4636
|
+
getComputedStyle(document.documentElement).fontSize,
|
|
4637
|
+
// A `cq` unit with no query container resolves against the viewport.
|
|
4638
|
+
/v(w|h|i|b|min|max)|cq/.test(token)
|
|
4639
|
+
? `${window.innerWidth}x${window.innerHeight}`
|
|
4640
|
+
: '',
|
|
4641
|
+
/cq/.test(token) ? containerSizes(container) : '',
|
|
4642
|
+
].join('|');
|
|
4643
|
+
if (emProbe?.key === key) return emProbe.em;
|
|
4644
|
+
const probe = document.createElement('span');
|
|
4645
|
+
probe.style.cssText =
|
|
4646
|
+
'position:absolute;visibility:hidden;font-size:var(--bb-fs,1em)';
|
|
4647
|
+
container.append(probe);
|
|
4648
|
+
const em = parseFloat(getComputedStyle(probe).fontSize);
|
|
4649
|
+
probe.remove();
|
|
4650
|
+
emProbe = { key, em };
|
|
4651
|
+
return em;
|
|
4652
|
+
};
|
|
4478
4653
|
const measureFloors = () => {
|
|
4479
4654
|
const container = containerRef.value;
|
|
4480
4655
|
const table = tableRef.value;
|
|
@@ -4483,13 +4658,10 @@ const measureFloors = () => {
|
|
|
4483
4658
|
const rootEm = parseFloat(style.fontSize) || 16;
|
|
4484
4659
|
// The estimates are in em of the BODY text (`--bb-fs`, 14px by default),
|
|
4485
4660
|
// not the table root's 16px — resolved on a probe, so it holds with no
|
|
4486
|
-
// rows yet and whatever a cell class does to one cell's size.
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
container.append(probe);
|
|
4491
|
-
const em = parseFloat(getComputedStyle(probe).fontSize) || rootEm;
|
|
4492
|
-
probe.remove();
|
|
4661
|
+
// rows yet and whatever a cell class does to one cell's size. Only when
|
|
4662
|
+
// what it resolves from changed: any node added under the root (a grid
|
|
4663
|
+
// scroller) re-lays out every row, 100ms and more at 1000 rows.
|
|
4664
|
+
const em = bodyEmOf(container) || rootEm;
|
|
4493
4665
|
const padEm = (2 * (parseFloat(style.getPropertyValue('--px')) || 12)) / em;
|
|
4494
4666
|
// The structural columns (drag handle, selection, actions) are
|
|
4495
4667
|
// `max-content` tracks of a fixed width: not room for the floors.
|
|
@@ -4526,23 +4698,84 @@ const measureFloors = () => {
|
|
|
4526
4698
|
)
|
|
4527
4699
|
floorMetrics.value = { width, em, rootEm, padEm, head };
|
|
4528
4700
|
};
|
|
4701
|
+
/** The cells each hold level promises (index.css), for the guard. */
|
|
4702
|
+
const HELD_CELLS = {
|
|
4703
|
+
units: {
|
|
4704
|
+
whole:
|
|
4705
|
+
'.bb-table__cell--fluid:is(.bb-table__cell--line, .bb-table__cell--token)',
|
|
4706
|
+
word: '.bb-table__cell--fluid.bb-table__cell--word',
|
|
4707
|
+
},
|
|
4708
|
+
core: {
|
|
4709
|
+
whole:
|
|
4710
|
+
'.bb-table__cell--fluid:is(.bb-table__cell--line, .bb-table__cell--token):not(.bb-table__cell--outlier)',
|
|
4711
|
+
word: '.bb-table__cell--fluid.bb-table__cell--word:not(.bb-table__cell--outlier)',
|
|
4712
|
+
},
|
|
4713
|
+
words: {
|
|
4714
|
+
whole: '.bb-table__cell--fluid.bb-table__cell--token',
|
|
4715
|
+
word: '.bb-table__cell--fluid:is(.bb-table__cell--line, .bb-table__cell--word)',
|
|
4716
|
+
},
|
|
4717
|
+
none: {},
|
|
4718
|
+
} as const;
|
|
4719
|
+
/** After the floors of this pass rendered: a plan that fits must fit. */
|
|
4720
|
+
const guardPlan = () => {
|
|
4721
|
+
const { stage, hold, floors } = fittedFloors.value;
|
|
4722
|
+
if (stage >= 7 || !Object.keys(floors).length) return;
|
|
4723
|
+
measured.guard(hold, HELD_CELLS[hold]);
|
|
4724
|
+
};
|
|
4725
|
+
/**
|
|
4726
|
+
* One pass of the floors: the room and the em (`measureFloors`), a check of
|
|
4727
|
+
* the columns' typography (style reads only), the texts the rows brought
|
|
4728
|
+
* (the ruler, outside the table), then — once Vue has rendered what that
|
|
4729
|
+
* changed — the guard. `mount`: the first pass, before the first paint.
|
|
4730
|
+
*/
|
|
4731
|
+
const floorPass = (mount = false) => {
|
|
4732
|
+
measureFloors();
|
|
4733
|
+
if (virtualActive.value) return;
|
|
4734
|
+
measured.checkTypography();
|
|
4735
|
+
measured.measure(mount);
|
|
4736
|
+
nextTick(guardPlan);
|
|
4737
|
+
};
|
|
4529
4738
|
// Read on the frame AFTER a resize, never inside the callback nor
|
|
4530
4739
|
// synchronously: a new floor re-lays the table out, which resizes the
|
|
4531
4740
|
// container again within the same observer loop (the browser reports that as
|
|
4532
4741
|
// an error), and a forced layout at mount shifts what virtual rows measure.
|
|
4533
4742
|
const scheduleFloors = () => {
|
|
4534
4743
|
cancelAnimationFrame(floorFrame);
|
|
4535
|
-
floorFrame = requestAnimationFrame(
|
|
4744
|
+
floorFrame = requestAnimationFrame(() => floorPass());
|
|
4536
4745
|
};
|
|
4537
4746
|
onMounted(() => {
|
|
4538
4747
|
if (!containerRef.value || typeof ResizeObserver === 'undefined') return;
|
|
4539
4748
|
// A client render reaches its first paint measured (the fitted floors and
|
|
4540
|
-
// the headings' lines already set
|
|
4541
|
-
// under `virtual` (no floors there): a forced
|
|
4542
|
-
// its rows measure.
|
|
4543
|
-
if (!virtualActive.value)
|
|
4749
|
+
// the headings' lines already set, the values' real widths read), not at
|
|
4750
|
+
// the wish for one frame. Not under `virtual` (no floors there): a forced
|
|
4751
|
+
// layout at mount shifts what its rows measure.
|
|
4752
|
+
if (!virtualActive.value) floorPass(true);
|
|
4544
4753
|
floorObserver = new ResizeObserver(scheduleFloors);
|
|
4545
4754
|
floorObserver.observe(containerRef.value);
|
|
4755
|
+
// The grid itself: held cells widen it when a font changes under them
|
|
4756
|
+
// (no event fires for every font), and the guard then looks. Not under
|
|
4757
|
+
// `virtual` (no floors, no held cells): its rows resize the grid as it
|
|
4758
|
+
// scrolls, and every pass forces a layout.
|
|
4759
|
+
if (tableRef.value && !virtualActive.value)
|
|
4760
|
+
floorObserver.observe(tableRef.value);
|
|
4761
|
+
measured.onFontsChanged(() => !virtualActive.value && scheduleFloors());
|
|
4762
|
+
});
|
|
4763
|
+
watch([tableRef, virtualActive], ([table, virtual], [previous]) => {
|
|
4764
|
+
if (!floorObserver) return;
|
|
4765
|
+
if (previous) floorObserver.unobserve(previous);
|
|
4766
|
+
if (table && !virtual) floorObserver.observe(table);
|
|
4767
|
+
});
|
|
4768
|
+
// New rows: their new texts are measured on the next pass. Only when a
|
|
4769
|
+
// column shows other texts: `columnValues` also re-runs when nothing it
|
|
4770
|
+
// shows changed (a resize preview sizes a column, a consumer passes an equal
|
|
4771
|
+
// `columns` array again), and a re-measure walks every candidate.
|
|
4772
|
+
const sameTexts = (a: readonly string[] | undefined, b: readonly string[]) =>
|
|
4773
|
+
a?.length === b.length && a.every((text, i) => text === b[i]);
|
|
4774
|
+
watch(columnValues, (now, old) => {
|
|
4775
|
+
if (Object.entries(now).every(([key, texts]) => sameTexts(old?.[key], texts)))
|
|
4776
|
+
return;
|
|
4777
|
+
measured.rowsChanged();
|
|
4778
|
+
if (floorObserver) scheduleFloors();
|
|
4546
4779
|
});
|
|
4547
4780
|
// The root element swaps (`selectable` turns it into a fieldset): observe
|
|
4548
4781
|
// the new one, or the floors stay on the last read of a detached box. A
|
|
@@ -4560,6 +4793,7 @@ watch(
|
|
|
4560
4793
|
onBeforeUnmount(() => {
|
|
4561
4794
|
floorObserver?.disconnect();
|
|
4562
4795
|
cancelAnimationFrame(floorFrame);
|
|
4796
|
+
measured.dispose();
|
|
4563
4797
|
});
|
|
4564
4798
|
|
|
4565
4799
|
/**
|
|
@@ -7157,7 +7391,7 @@ const tableBindings = computed(() => {
|
|
|
7157
7391
|
...mergeProps(
|
|
7158
7392
|
{
|
|
7159
7393
|
ref: tableRef,
|
|
7160
|
-
class: 'bb-table__table',
|
|
7394
|
+
class: ['bb-table__table', holdClass.value],
|
|
7161
7395
|
role: tableRole.value,
|
|
7162
7396
|
'aria-labelledby': props.caption ? captionId.value : undefined,
|
|
7163
7397
|
'aria-multiselectable':
|
|
@@ -9987,6 +10221,22 @@ export type BbTableSlots<Item = any> = BbTableColumnSlots<Item> & {
|
|
|
9987
10221
|
background-color: var(--row-bg);
|
|
9988
10222
|
}
|
|
9989
10223
|
|
|
10224
|
+
/* Q76.7 (b): on hover a pinned cell takes the row's OWN fill, so an
|
|
10225
|
+
app's `pt:row` hover colour (`hover:bg-*`) reaches it as it reaches
|
|
10226
|
+
the rest of the row (it kept the library's tint before). The row
|
|
10227
|
+
then has to be opaque for the pinned cell to stay opaque (Q56.24 b),
|
|
10228
|
+
so the library's own hover is forced opaque on a row that has one;
|
|
10229
|
+
an opaque theme renders exactly as before. A translucent app hover
|
|
10230
|
+
colour shows through the pinned cell while the row is hovered: give
|
|
10231
|
+
it an opaque one. */
|
|
10232
|
+
&:has(> [style*='sticky']):hover {
|
|
10233
|
+
background-color: rgb(from var(--row-bg) r g b / 1);
|
|
10234
|
+
|
|
10235
|
+
> [style*='sticky'] {
|
|
10236
|
+
background-color: inherit;
|
|
10237
|
+
}
|
|
10238
|
+
}
|
|
10239
|
+
|
|
9990
10240
|
/* A click opens it (`v-model:highlighted`, `highlightable`). */
|
|
9991
10241
|
&--highlightable {
|
|
9992
10242
|
cursor: pointer;
|
|
@@ -10055,7 +10305,8 @@ export type BbTableSlots<Item = any> = BbTableColumnSlots<Item> & {
|
|
|
10055
10305
|
|
|
10056
10306
|
/* Q9.1b: in a column with an estimated floor (see `--floored` above) the
|
|
10057
10307
|
floor is the minimum, not the longest word: a value too long for it
|
|
10058
|
-
wraps, or breaks, rather than widening every row.
|
|
10308
|
+
wraps, or breaks, rather than widening every row. The values the fit
|
|
10309
|
+
promises are held instead, by the root's hold level (below). */
|
|
10059
10310
|
&--fluid {
|
|
10060
10311
|
min-width: 0;
|
|
10061
10312
|
}
|
|
@@ -10085,6 +10336,50 @@ export type BbTableSlots<Item = any> = BbTableColumnSlots<Item> & {
|
|
|
10085
10336
|
}
|
|
10086
10337
|
}
|
|
10087
10338
|
|
|
10339
|
+
/* Measured floors: the values the fit promises (`cellRole`: `--line`,
|
|
10340
|
+
`--token`, `--word`, `--outlier`) floor their own track again, at the
|
|
10341
|
+
hold level the fit reached (`fitFloors`' `hold`, one class on the grid
|
|
10342
|
+
root). The browser then sizes the track with the real text in its real
|
|
10343
|
+
font: a promised value never breaks, whatever the estimate said, and the
|
|
10344
|
+
measured floors make sure it never widens a track past the plan. A whole
|
|
10345
|
+
value also keeps to one line (`nowrap`: a hyphen or a slash would break
|
|
10346
|
+
a date under `min-width: auto` alone); a `--word` value only keeps its
|
|
10347
|
+
longest word. Child combinators only: a nested table's cells follow
|
|
10348
|
+
their own root. Internal classes, not public API (like `--fluid`). */
|
|
10349
|
+
&__table--hold-units
|
|
10350
|
+
> .bb-table__body
|
|
10351
|
+
> [role='row']
|
|
10352
|
+
> .bb-table__cell--fluid:is(.bb-table__cell--line, .bb-table__cell--token),
|
|
10353
|
+
&__table--hold-core
|
|
10354
|
+
> .bb-table__body
|
|
10355
|
+
> [role='row']
|
|
10356
|
+
> .bb-table__cell--fluid:is(
|
|
10357
|
+
.bb-table__cell--line,
|
|
10358
|
+
.bb-table__cell--token
|
|
10359
|
+
):not(.bb-table__cell--outlier),
|
|
10360
|
+
&__table--hold-words
|
|
10361
|
+
> .bb-table__body
|
|
10362
|
+
> [role='row']
|
|
10363
|
+
> .bb-table__cell--fluid.bb-table__cell--token {
|
|
10364
|
+
min-width: auto;
|
|
10365
|
+
white-space: nowrap;
|
|
10366
|
+
}
|
|
10367
|
+
|
|
10368
|
+
&__table--hold-units
|
|
10369
|
+
> .bb-table__body
|
|
10370
|
+
> [role='row']
|
|
10371
|
+
> .bb-table__cell--fluid.bb-table__cell--word,
|
|
10372
|
+
&__table--hold-core
|
|
10373
|
+
> .bb-table__body
|
|
10374
|
+
> [role='row']
|
|
10375
|
+
> .bb-table__cell--fluid.bb-table__cell--word:not(.bb-table__cell--outlier),
|
|
10376
|
+
&__table--hold-words
|
|
10377
|
+
> .bb-table__body
|
|
10378
|
+
> [role='row']
|
|
10379
|
+
> .bb-table__cell--fluid:is(.bb-table__cell--line, .bb-table__cell--word) {
|
|
10380
|
+
min-width: auto;
|
|
10381
|
+
}
|
|
10382
|
+
|
|
10088
10383
|
/* The grid's roving tab stop (`keyboardNavigation`, role="grid" /
|
|
10089
10384
|
"treegrid"): cells, header cells and a treegrid's expand rows take
|
|
10090
10385
|
focus. Same inset ring as the rows and the reorderable headers —
|
|
@@ -10284,4 +10579,41 @@ export type BbTableSlots<Item = any> = BbTableColumnSlots<Item> & {
|
|
|
10284
10579
|
--indent: 0px;
|
|
10285
10580
|
--indent-at: select;
|
|
10286
10581
|
}
|
|
10582
|
+
|
|
10583
|
+
/* The text ruler (textRuler.ts): measured content floors read each held
|
|
10584
|
+
value's real width here, outside every table (a node under a table's grid
|
|
10585
|
+
root would re-lay out all its rows). Off-screen, isolated, never painted;
|
|
10586
|
+
each wrapper carries a rendered cell's computed text properties inline,
|
|
10587
|
+
and its lines inherit them whatever a consumer rule says. Internal, not
|
|
10588
|
+
public API. */
|
|
10589
|
+
.bb-table-ruler {
|
|
10590
|
+
contain: strict;
|
|
10591
|
+
height: 0;
|
|
10592
|
+
inset-inline-start: 0;
|
|
10593
|
+
overflow: hidden;
|
|
10594
|
+
pointer-events: none;
|
|
10595
|
+
position: absolute;
|
|
10596
|
+
top: 0;
|
|
10597
|
+
visibility: hidden;
|
|
10598
|
+
width: 0;
|
|
10599
|
+
|
|
10600
|
+
> * > * {
|
|
10601
|
+
border: 0 !important;
|
|
10602
|
+
direction: inherit !important;
|
|
10603
|
+
display: block !important;
|
|
10604
|
+
font: inherit !important;
|
|
10605
|
+
font-feature-settings: inherit !important;
|
|
10606
|
+
font-variation-settings: inherit !important;
|
|
10607
|
+
letter-spacing: inherit !important;
|
|
10608
|
+
margin: 0 !important;
|
|
10609
|
+
max-width: none !important;
|
|
10610
|
+
min-width: 0 !important;
|
|
10611
|
+
padding: 0 !important;
|
|
10612
|
+
text-rendering: inherit !important;
|
|
10613
|
+
text-transform: inherit !important;
|
|
10614
|
+
white-space: nowrap !important;
|
|
10615
|
+
width: max-content !important;
|
|
10616
|
+
word-spacing: inherit !important;
|
|
10617
|
+
}
|
|
10618
|
+
}
|
|
10287
10619
|
```
|