@cube-dev/ui-kit 0.154.1 → 0.156.0
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/dist/CHANGELOG.md +99 -0
- package/dist/_internal/hooks/use-chained-callback.js +1 -1
- package/dist/_internal/hooks/use-debounced-value.js +1 -1
- package/dist/_internal/hooks/use-deprecation-warning.js +1 -1
- package/dist/_internal/hooks/use-event.js +1 -1
- package/dist/_internal/hooks/use-is-first-render.js +1 -1
- package/dist/_internal/hooks/use-sync-ref.js +1 -1
- package/dist/_internal/hooks/use-timer/timer.js +1 -1
- package/dist/_internal/hooks/use-timer/use-timer.js +1 -1
- package/dist/_internal/hooks/use-warn.js +1 -1
- package/dist/components/Block.js +1 -1
- package/dist/components/CollectionItem.js +1 -1
- package/dist/components/GlobalStyles.js +1 -1
- package/dist/components/GridProvider.js +1 -1
- package/dist/components/HiddenInput.js +1 -1
- package/dist/components/Root.js +1 -1
- package/dist/components/actions/Action/Action.js +1 -1
- package/dist/components/actions/Banner/Banner.js +1 -1
- package/dist/components/actions/Button/Button.js +1 -1
- package/dist/components/actions/ButtonGroup/ButtonGroup.js +1 -1
- package/dist/components/actions/ButtonSplit/ButtonSplit.js +1 -1
- package/dist/components/actions/ButtonSplit/context.js +1 -1
- package/dist/components/actions/CommandMenu/CommandMenu.d.ts +10 -1
- package/dist/components/actions/CommandMenu/CommandMenu.js +4 -3
- package/dist/components/actions/CommandMenu/CommandMenu.js.map +1 -1
- package/dist/components/actions/CommandMenu/styled.js +1 -1
- package/dist/components/actions/ItemAction/ItemAction.js +1 -1
- package/dist/components/actions/ItemActionContext.js +1 -1
- package/dist/components/actions/ItemButton/ItemButton.js +1 -1
- package/dist/components/actions/Link/Link.js +1 -1
- package/dist/components/actions/Menu/Menu.js +1 -1
- package/dist/components/actions/Menu/MenuItem.js +1 -1
- package/dist/components/actions/Menu/MenuSection.js +1 -1
- package/dist/components/actions/Menu/MenuTrigger.js +1 -1
- package/dist/components/actions/Menu/SubMenuTrigger.js +1 -1
- package/dist/components/actions/Menu/SubmenuTriggerContext.js +1 -1
- package/dist/components/actions/Menu/context.js +1 -1
- package/dist/components/actions/Menu/styled.js +1 -1
- package/dist/components/actions/index.js +1 -1
- package/dist/components/actions/use-action.js +1 -1
- package/dist/components/actions/use-anchored-menu.js +1 -1
- package/dist/components/actions/use-context-menu.js +1 -1
- package/dist/components/content/ActiveZone/ActiveZone.js +1 -1
- package/dist/components/content/Alert/Alert.js +1 -1
- package/dist/components/content/Alert/use-alert.js +1 -1
- package/dist/components/content/Avatar/Avatar.js +1 -1
- package/dist/components/content/Badge/Badge.js +1 -1
- package/dist/components/content/Card/Card.js +1 -1
- package/dist/components/content/Content.js +1 -1
- package/dist/components/content/CopyPasteBlock/CopyPasteBlock.js +1 -1
- package/dist/components/content/CopySnippet/CopySnippet.js +1 -1
- package/dist/components/content/Disclosure/Disclosure.js +1 -1
- package/dist/components/content/Divider.js +1 -1
- package/dist/components/content/Footer.js +1 -1
- package/dist/components/content/Header.js +1 -1
- package/dist/components/content/HotKeys/HotKeys.js +1 -1
- package/dist/components/content/InfoBadge/InfoBadge.js +1 -1
- package/dist/components/content/InlineInput/InlineInput.js +1 -1
- package/dist/components/content/Item/Item.d.ts +2 -1
- package/dist/components/content/Item/Item.js +1 -1
- package/dist/components/content/Item/Item.js.map +1 -1
- package/dist/components/content/ItemBadge/ItemBadge.js +1 -1
- package/dist/components/content/ItemCard/ItemCard.js +1 -1
- package/dist/components/content/Layout/GridLayout.js +1 -1
- package/dist/components/content/Layout/Layout.js +1 -1
- package/dist/components/content/Layout/LayoutBlock.js +1 -1
- package/dist/components/content/Layout/LayoutCenter.js +1 -1
- package/dist/components/content/Layout/LayoutContainer.js +1 -1
- package/dist/components/content/Layout/LayoutContent.js +1 -1
- package/dist/components/content/Layout/LayoutContext.js +1 -1
- package/dist/components/content/Layout/LayoutFlex.js +1 -1
- package/dist/components/content/Layout/LayoutFooter.js +1 -1
- package/dist/components/content/Layout/LayoutGrid.js +1 -1
- package/dist/components/content/Layout/LayoutHeader.js +1 -1
- package/dist/components/content/Layout/LayoutPane.js +1 -1
- package/dist/components/content/Layout/LayoutPanel.js +1 -1
- package/dist/components/content/Layout/LayoutPanelHeader.js +1 -1
- package/dist/components/content/Layout/LayoutToolbar.js +1 -1
- package/dist/components/content/Layout/hooks/useTinyScrollbar.js +1 -1
- package/dist/components/content/Layout/index.js +1 -1
- package/dist/components/content/Layout/utils.js +1 -1
- package/dist/components/content/Paragraph.js +1 -1
- package/dist/components/content/Placeholder/Placeholder.js +1 -1
- package/dist/components/content/PrismCode/PrismCode.js +1 -1
- package/dist/components/content/PrismCode/prismSetup.js +1 -1
- package/dist/components/content/PrismDiffCode/PrismDiffCode.js +1 -1
- package/dist/components/content/Result/Result.js +1 -1
- package/dist/components/content/Skeleton/Skeleton.js +1 -1
- package/dist/components/content/Tag/Tag.js +1 -1
- package/dist/components/content/Text.d.ts +21 -42
- package/dist/components/content/Text.js +4 -5
- package/dist/components/content/Text.js.map +1 -1
- package/dist/components/content/TextItem/TextItem.js +1 -1
- package/dist/components/content/Title.js +2 -3
- package/dist/components/content/Title.js.map +1 -1
- package/dist/components/content/Tree/Tree.js +1 -1
- package/dist/components/content/Tree/TreeNode.js +1 -1
- package/dist/components/content/Tree/styled.js +1 -1
- package/dist/components/content/Tree/tree-index.js +1 -1
- package/dist/components/content/Tree/use-checkbox-tree.js +1 -1
- package/dist/components/content/Tree/use-load-data.js +1 -1
- package/dist/components/content/highlightText.js +1 -1
- package/dist/components/content/use-auto-tooltip.d.ts +0 -1
- package/dist/components/content/use-auto-tooltip.js +1 -1
- package/dist/components/content/use-auto-tooltip.js.map +1 -1
- package/dist/components/fields/Checkbox/Checkbox.js +1 -1
- package/dist/components/fields/Checkbox/CheckboxGroup.js +1 -1
- package/dist/components/fields/Checkbox/context.js +1 -1
- package/dist/components/fields/ColorPicker/ColorPicker.d.ts +67 -0
- package/dist/components/fields/ColorPicker/ColorPicker.js +240 -0
- package/dist/components/fields/ColorPicker/ColorPicker.js.map +1 -0
- package/dist/components/fields/ColorPicker/ColorPickerPanel.js +149 -0
- package/dist/components/fields/ColorPicker/ColorPickerPanel.js.map +1 -0
- package/dist/components/fields/ColorPicker/channels.d.ts +13 -0
- package/dist/components/fields/ColorPicker/channels.js +194 -0
- package/dist/components/fields/ColorPicker/channels.js.map +1 -0
- package/dist/components/fields/ColorPicker/color.d.ts +15 -0
- package/dist/components/fields/ColorPicker/color.js +282 -0
- package/dist/components/fields/ColorPicker/color.js.map +1 -0
- package/dist/components/fields/ColorPicker/index.d.ts +4 -0
- package/dist/components/fields/ComboBox/ComboBox.js +1 -1
- package/dist/components/fields/CommandTextArea/CommandTextArea.js +1 -1
- package/dist/components/fields/CommandTextArea/caretPosition.js +1 -1
- package/dist/components/fields/CommandTextArea/useCaretAnchor.js +1 -1
- package/dist/components/fields/DatePicker/DateInput.js +1 -1
- package/dist/components/fields/DatePicker/DateInputBase.js +1 -1
- package/dist/components/fields/DatePicker/DateInputBase.js.map +1 -1
- package/dist/components/fields/DatePicker/DatePicker.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerButton.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerElement.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerInput.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerSegment.js +1 -1
- package/dist/components/fields/DatePicker/DateRangePicker.js +1 -1
- package/dist/components/fields/DatePicker/DateRangeSeparatedPicker.js +1 -1
- package/dist/components/fields/DatePicker/MonthPicker.js +1 -1
- package/dist/components/fields/DatePicker/PeriodPicker.js +1 -1
- package/dist/components/fields/DatePicker/QuarterPicker.js +1 -1
- package/dist/components/fields/DatePicker/TimeInput.js +1 -1
- package/dist/components/fields/DatePicker/WeekPicker.js +1 -1
- package/dist/components/fields/DatePicker/YearPicker.js +1 -1
- package/dist/components/fields/DatePicker/parseDate.js +1 -1
- package/dist/components/fields/DatePicker/period.js +1 -1
- package/dist/components/fields/DatePicker/props.js +1 -1
- package/dist/components/fields/DatePicker/utils.js +1 -1
- package/dist/components/fields/FileInput/FileInput.d.ts +2 -1
- package/dist/components/fields/FileInput/FileInput.js +1 -1
- package/dist/components/fields/FileInput/FileInput.js.map +1 -1
- package/dist/components/fields/FilterListBox/FilterListBox.d.ts +3 -3
- package/dist/components/fields/FilterListBox/FilterListBox.js +7 -6
- package/dist/components/fields/FilterListBox/FilterListBox.js.map +1 -1
- package/dist/components/fields/FilterPicker/FilterPicker.js +1 -1
- package/dist/components/fields/Input/Input.js +1 -1
- package/dist/components/fields/ListBox/DraggableListBox.js +1 -1
- package/dist/components/fields/ListBox/ListBox.js +1 -1
- package/dist/components/fields/ListBoxPopover/ListBoxPopover.js +1 -1
- package/dist/components/fields/ListBoxPopover/listNavigation.js +1 -1
- package/dist/components/fields/ListBoxPopover/useCompositeFocus.js +1 -1
- package/dist/components/fields/NumberInput/NumberInput.js +1 -1
- package/dist/components/fields/NumberInput/StepButton.js +1 -1
- package/dist/components/fields/PasswordInput/PasswordInput.js +1 -1
- package/dist/components/fields/Picker/Picker.js +1 -1
- package/dist/components/fields/RadioGroup/Radio.js +1 -1
- package/dist/components/fields/RadioGroup/RadioGroup.js +1 -1
- package/dist/components/fields/RadioGroup/context.js +1 -1
- package/dist/components/fields/SearchComboBox/SearchComboBox.js +1 -1
- package/dist/components/fields/SearchInput/SearchInput.js +1 -1
- package/dist/components/fields/Select/Select.d.ts +2 -1
- package/dist/components/fields/Select/Select.js +1 -1
- package/dist/components/fields/Select/Select.js.map +1 -1
- package/dist/components/fields/Slider/Gradation.js +1 -1
- package/dist/components/fields/Slider/HueSlider.js +1 -1
- package/dist/components/fields/Slider/RangeSlider.js +1 -1
- package/dist/components/fields/Slider/Slider.js +1 -1
- package/dist/components/fields/Slider/SliderBase.js +1 -1
- package/dist/components/fields/Slider/SliderThumb.js +1 -1
- package/dist/components/fields/Slider/SliderTrack.js +1 -1
- package/dist/components/fields/Slider/elements.js +1 -1
- package/dist/components/fields/Slider/index.js +1 -1
- package/dist/components/fields/Switch/Switch.js +1 -1
- package/dist/components/fields/TextArea/TextArea.js +1 -1
- package/dist/components/fields/TextInput/TextInput.js +1 -1
- package/dist/components/fields/TextInput/TextInputBase.d.ts +2 -1
- package/dist/components/fields/TextInput/TextInputBase.js +1 -1
- package/dist/components/fields/TextInput/TextInputBase.js.map +1 -1
- package/dist/components/fields/TextInputMapper/TextInputMapper.js +1 -1
- package/dist/components/fields/index.d.ts +4 -0
- package/dist/components/form/FieldWrapper/FieldWrapper.d.ts +2 -1
- package/dist/components/form/FieldWrapper/FieldWrapper.js +1 -1
- package/dist/components/form/FieldWrapper/types.d.ts +2 -1
- package/dist/components/form/Form/Field.js +1 -1
- package/dist/components/form/Form/Form.js +1 -1
- package/dist/components/form/Form/ResetButton/ResetButton.js +1 -1
- package/dist/components/form/Form/SubmitButton/SubmitButton.js +1 -1
- package/dist/components/form/Form/SubmitError.js +1 -1
- package/dist/components/form/Form/index.js +1 -1
- package/dist/components/form/Form/use-field/use-field-props.js +1 -1
- package/dist/components/form/Form/use-field/use-field.js +1 -1
- package/dist/components/form/Form/use-form.js +1 -1
- package/dist/components/form/Form/validation.js +1 -1
- package/dist/components/form/Label.js +1 -1
- package/dist/components/form/validation/ValidationIndicator.js +1 -1
- package/dist/components/form/validation/resolve-validation-props.js +1 -1
- package/dist/components/form/validation/use-validation-props.js +1 -1
- package/dist/components/form/wrapper.js +1 -1
- package/dist/components/helpers/DisplayTransition/DisplayTransition.js +1 -1
- package/dist/components/helpers/IconSwitch/IconSwitch.js +1 -1
- package/dist/components/layout/Board/Board.d.ts +55 -1
- package/dist/components/layout/Board/Board.js +278 -75
- package/dist/components/layout/Board/Board.js.map +1 -1
- package/dist/components/layout/Board/BoardProvider.js +1 -1
- package/dist/components/layout/Board/BoardResponsive.js +1 -1
- package/dist/components/layout/Board/Widget.d.ts +16 -0
- package/dist/components/layout/Board/Widget.js +6 -3
- package/dist/components/layout/Board/Widget.js.map +1 -1
- package/dist/components/layout/Board/WidgetHost.js +81 -14
- package/dist/components/layout/Board/WidgetHost.js.map +1 -1
- package/dist/components/layout/Board/board-context.js +1 -1
- package/dist/components/layout/Board/board-context.js.map +1 -1
- package/dist/components/layout/Board/board-store.js +2 -2
- package/dist/components/layout/Board/board-store.js.map +1 -1
- package/dist/components/layout/Board/grid-core/calculate.js +1 -1
- package/dist/components/layout/Board/grid-core/collision.js +1 -1
- package/dist/components/layout/Board/grid-core/compactors.js +1 -1
- package/dist/components/layout/Board/grid-core/constraints.js +1 -1
- package/dist/components/layout/Board/grid-core/group-move.js +132 -0
- package/dist/components/layout/Board/grid-core/group-move.js.map +1 -0
- package/dist/components/layout/Board/grid-core/layout.js +1 -1
- package/dist/components/layout/Board/grid-core/sort.js +1 -1
- package/dist/components/layout/Board/index.d.ts +2 -1
- package/dist/components/layout/Board/index.js +2 -2
- package/dist/components/layout/Board/index.js.map +1 -1
- package/dist/components/layout/Board/responsive-utils.js +1 -1
- package/dist/components/layout/Board/use-board-layout.js +17 -12
- package/dist/components/layout/Board/use-board-layout.js.map +1 -1
- package/dist/components/layout/Board/use-board-registry.js +139 -20
- package/dist/components/layout/Board/use-board-registry.js.map +1 -1
- package/dist/components/layout/Board/use-board-select-modifier-key.js +24 -0
- package/dist/components/layout/Board/use-board-select-modifier-key.js.map +1 -0
- package/dist/components/layout/Board/use-board-selection.d.ts +8 -0
- package/dist/components/layout/Board/use-board-selection.js +113 -0
- package/dist/components/layout/Board/use-board-selection.js.map +1 -0
- package/dist/components/layout/Flex.js +1 -1
- package/dist/components/layout/Flow.js +1 -1
- package/dist/components/layout/Grid.js +1 -1
- package/dist/components/layout/Panel.js +1 -1
- package/dist/components/layout/Prefix.js +1 -1
- package/dist/components/layout/ResizablePanel.js +1 -1
- package/dist/components/layout/Space.js +1 -1
- package/dist/components/layout/Suffix.js +1 -1
- package/dist/components/navigation/Tabs/DraggableTabList.js +1 -1
- package/dist/components/navigation/Tabs/TabButton.js +1 -1
- package/dist/components/navigation/Tabs/TabDropIndicator.js +1 -1
- package/dist/components/navigation/Tabs/TabPanel.js +1 -1
- package/dist/components/navigation/Tabs/TabPicker.js +1 -1
- package/dist/components/navigation/Tabs/Tabs.js +1 -1
- package/dist/components/navigation/Tabs/TabsAction.js +1 -1
- package/dist/components/navigation/Tabs/TabsContext.js +1 -1
- package/dist/components/navigation/Tabs/popover-placement.js +1 -1
- package/dist/components/navigation/Tabs/styled.js +1 -1
- package/dist/components/navigation/Tabs/types.js +1 -1
- package/dist/components/navigation/Tabs/use-tab-editing.js +1 -1
- package/dist/components/navigation/Tabs/use-tab-indicator.js +1 -1
- package/dist/components/organisms/FileTabs/FileTabs.js +1 -1
- package/dist/components/organisms/StatsCard/StatsCard.js +1 -1
- package/dist/components/other/Calendar/Calendar.js +1 -1
- package/dist/components/other/Calendar/CalendarCell.js +1 -1
- package/dist/components/other/Calendar/CalendarGrid.js +1 -1
- package/dist/components/other/Calendar/PeriodCalendar.js +1 -1
- package/dist/components/other/Calendar/RangeCalendar.js +1 -1
- package/dist/components/other/CubeLogo/CubeLogo.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialog.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialogApiProvider.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialogZone.js +1 -1
- package/dist/components/overlays/Dialog/Dialog.js +1 -1
- package/dist/components/overlays/Dialog/DialogContainer.js +1 -1
- package/dist/components/overlays/Dialog/DialogForm.js +1 -1
- package/dist/components/overlays/Dialog/DialogTrigger.js +1 -1
- package/dist/components/overlays/Dialog/context.js +1 -1
- package/dist/components/overlays/Dialog/use-dialog-container.js +1 -1
- package/dist/components/overlays/Modal/Modal.js +1 -1
- package/dist/components/overlays/Modal/Modal.js.map +1 -1
- package/dist/components/overlays/Modal/OpenTransitionContext.js +1 -1
- package/dist/components/overlays/Modal/Overlay.js +1 -1
- package/dist/components/overlays/Modal/Overlay.js.map +1 -1
- package/dist/components/overlays/Modal/Popover.js +1 -1
- package/dist/components/overlays/Modal/Tray.js +1 -1
- package/dist/components/overlays/Modal/Tray.js.map +1 -1
- package/dist/components/overlays/Modal/Underlay.js +1 -1
- package/dist/components/overlays/Notifications/Notification.js +1 -1
- package/dist/components/overlays/Notifications/NotificationAction.js +1 -1
- package/dist/components/overlays/Notifications/NotificationCard.js +1 -1
- package/dist/components/overlays/Notifications/NotificationContext.js +1 -1
- package/dist/components/overlays/Notifications/NotificationItem.js +1 -1
- package/dist/components/overlays/Notifications/OverlayContainer.js +1 -1
- package/dist/components/overlays/Notifications/OverlayProvider.js +1 -1
- package/dist/components/overlays/Notifications/PersistentNotificationsList.js +1 -1
- package/dist/components/overlays/Notifications/dismissed-storage.js +1 -1
- package/dist/components/overlays/Notifications/format-relative-time.js +1 -1
- package/dist/components/overlays/Notifications/index.js +1 -1
- package/dist/components/overlays/Notifications/use-notification-state.js +1 -1
- package/dist/components/overlays/Notifications/use-notifications.js +1 -1
- package/dist/components/overlays/Notifications/use-overlay-timers.js +1 -1
- package/dist/components/overlays/Notifications/use-persistent-notifications.js +1 -1
- package/dist/components/overlays/Notifications/use-persistent-state.js +1 -1
- package/dist/components/overlays/Notifications/use-toast-state.js +1 -1
- package/dist/components/overlays/Toast/ToastItem.js +1 -1
- package/dist/components/overlays/Toast/index.js +1 -1
- package/dist/components/overlays/Toast/useProgressToast.js +1 -1
- package/dist/components/overlays/Toast/useToast.js +1 -1
- package/dist/components/overlays/Tooltip/Tooltip.js +1 -1
- package/dist/components/overlays/Tooltip/TooltipProvider.js +1 -1
- package/dist/components/overlays/Tooltip/TooltipTrigger.js +1 -1
- package/dist/components/overlays/Tooltip/context.js +1 -1
- package/dist/components/overlays/Tooltip/context.js.map +1 -1
- package/dist/components/portal/Portal.js +1 -1
- package/dist/components/portal/PortalProvider.js +1 -1
- package/dist/components/portal/usePortal.js +1 -1
- package/dist/components/shared/DraggableCollection.js +1 -1
- package/dist/components/shared/InvalidIcon.js +1 -1
- package/dist/components/shared/ValidIcon.js +1 -1
- package/dist/components/status/LoadingAnimation/LoadingAnimation.js +1 -1
- package/dist/components/status/Spin/Cube.js +1 -1
- package/dist/components/status/Spin/InternalSpinner.js +1 -1
- package/dist/components/status/Spin/Spin.js +1 -1
- package/dist/components/status/Spin/SpinsContainer.js +1 -1
- package/dist/data/item-themes.js +1 -1
- package/dist/data/themes.js +1 -1
- package/dist/eslint-plugin/defaults.generated.js +9 -1
- package/dist/eslint-plugin/defaults.generated.js.map +1 -1
- package/dist/eslint-plugin/index.js +1 -1
- package/dist/eslint-plugin/rules/no-redundant-default-prop.js +1 -1
- package/dist/i18n/I18nProvider.js +1 -1
- package/dist/i18n/createFormatter.js +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/instance.js +1 -1
- package/dist/i18n/locales/de-DE/uikit.js +9 -1
- package/dist/i18n/locales/en-US/uikit.js +9 -1
- package/dist/i18n/locales/en-US/uikit.json.d.ts +9 -1
- package/dist/i18n/locales/es-ES/uikit.js +9 -1
- package/dist/i18n/locales/es-MX/uikit.js +9 -1
- package/dist/i18n/locales/fr-FR/uikit.js +9 -1
- package/dist/i18n/locales/it-IT/uikit.js +9 -1
- package/dist/i18n/locales/ja-JP/uikit.js +9 -1
- package/dist/i18n/locales/nb-NO/uikit.js +9 -1
- package/dist/i18n/locales/pt-BR/uikit.js +9 -1
- package/dist/i18n/locales/pt-PT/uikit.js +9 -1
- package/dist/i18n/locales/sv-SE/uikit.js +9 -1
- package/dist/i18n/locales/vi-VN/uikit.js +9 -1
- package/dist/i18n/locales.js +1 -1
- package/dist/i18n/useFormatter.js +1 -1
- package/dist/i18n/useI18n.js +1 -1
- package/dist/icons/AdjustmentsHorizontalIcon.js +1 -1
- package/dist/icons/AdjustmentsIcon.js +1 -1
- package/dist/icons/AiIcon.js +1 -1
- package/dist/icons/AreaChartIcon.js +1 -1
- package/dist/icons/BackwardIcon.js +1 -1
- package/dist/icons/BarChartIcon.js +1 -1
- package/dist/icons/BellFilledIcon.js +1 -1
- package/dist/icons/BellIcon.js +1 -1
- package/dist/icons/BooleanIcon.js +1 -1
- package/dist/icons/CalendarEditIcon.js +1 -1
- package/dist/icons/CalendarIcon.js +1 -1
- package/dist/icons/CaretDownIcon.js +1 -1
- package/dist/icons/CaretUpIcon.js +1 -1
- package/dist/icons/ChartAreaStackedIcon.js +1 -1
- package/dist/icons/ChartAreaStackedPercentageIcon.js +1 -1
- package/dist/icons/ChartBarGroupedHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarGroupedIcon.js +1 -1
- package/dist/icons/ChartBarHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarLineIcon.js +1 -1
- package/dist/icons/ChartBarStackedHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarStackedIcon.js +1 -1
- package/dist/icons/ChartBarStackedPercentageHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarStackedPercentageIcon.js +1 -1
- package/dist/icons/ChartBoxPlot2Icon.js +1 -1
- package/dist/icons/ChartBoxPlotIcon.js +1 -1
- package/dist/icons/ChartBubbleIcon.js +1 -1
- package/dist/icons/ChartDonut2Icon.js +1 -1
- package/dist/icons/ChartFunnelIcon.js +1 -1
- package/dist/icons/ChartHeatmapIcon.js +1 -1
- package/dist/icons/ChartKPIIcon.js +1 -1
- package/dist/icons/ChartPie2Icon.js +1 -1
- package/dist/icons/ChartScatterIcon.js +1 -1
- package/dist/icons/CheckCircleFilledIcon.js +1 -1
- package/dist/icons/CheckCircleIcon.js +1 -1
- package/dist/icons/CheckIcon.js +1 -1
- package/dist/icons/CircleFilledIcon.js +1 -1
- package/dist/icons/ClearIcon.js +1 -1
- package/dist/icons/CloseCircleFilledIcon.js +1 -1
- package/dist/icons/CloseCircleIcon.js +1 -1
- package/dist/icons/CloseIcon.js +1 -1
- package/dist/icons/CodeIcon.js +1 -1
- package/dist/icons/ColumnTotalIcon.js +1 -1
- package/dist/icons/CopyIcon.js +1 -1
- package/dist/icons/CountIcon.js +1 -1
- package/dist/icons/CubeIcon.js +1 -1
- package/dist/icons/CubePauseIcon.js +1 -1
- package/dist/icons/CubePlayIcon.js +1 -1
- package/dist/icons/CurrencyDollarIcon.js +1 -1
- package/dist/icons/DangerIcon.js +1 -1
- package/dist/icons/DashboardIcon.js +1 -1
- package/dist/icons/DatabaseIcon.js +1 -1
- package/dist/icons/DecimalDecreaseIcon.js +1 -1
- package/dist/icons/DecimalIncreaseIcon.js +1 -1
- package/dist/icons/DirectionIcon.js +1 -1
- package/dist/icons/DonutIcon.js +1 -1
- package/dist/icons/DownIcon.js +1 -1
- package/dist/icons/EditIcon.js +1 -1
- package/dist/icons/ExclamationCircleFilledIcon.js +1 -1
- package/dist/icons/ExclamationCircleIcon.js +1 -1
- package/dist/icons/ExclamationIcon.js +1 -1
- package/dist/icons/EyeIcon.js +1 -1
- package/dist/icons/EyeInvisibleIcon.js +1 -1
- package/dist/icons/FilterIcon.js +1 -1
- package/dist/icons/FolderFilledIcon.js +1 -1
- package/dist/icons/FolderIcon.js +1 -1
- package/dist/icons/FolderOpenFilledIcon.js +1 -1
- package/dist/icons/FolderOpenIcon.js +1 -1
- package/dist/icons/ForwardIcon.js +1 -1
- package/dist/icons/GripVerticalIcon.js +1 -1
- package/dist/icons/HierarchyIcon.js +1 -1
- package/dist/icons/HierarchyOpenIcon.js +1 -1
- package/dist/icons/Icon.js +1 -1
- package/dist/icons/InfoCircleIcon.js +1 -1
- package/dist/icons/InfoIcon.js +1 -1
- package/dist/icons/KeyIcon.js +1 -1
- package/dist/icons/LeftIcon.js +1 -1
- package/dist/icons/LineChartIcon.js +1 -1
- package/dist/icons/LoadingIcon.js +1 -1
- package/dist/icons/LockFilledIcon.js +1 -1
- package/dist/icons/LockIcon.js +1 -1
- package/dist/icons/MoreIcon.js +1 -1
- package/dist/icons/NotAllowedIcon.js +1 -1
- package/dist/icons/Number123Icon.js +1 -1
- package/dist/icons/NumberIcon.js +1 -1
- package/dist/icons/PauseCircleFilledIcon.js +1 -1
- package/dist/icons/PauseCircleIcon.js +1 -1
- package/dist/icons/PauseIcon.js +1 -1
- package/dist/icons/PercentageIcon.js +1 -1
- package/dist/icons/PieChartIcon.js +1 -1
- package/dist/icons/PipetteIcon.d.ts +12 -0
- package/dist/icons/PipetteIcon.js +11 -0
- package/dist/icons/PipetteIcon.js.map +1 -0
- package/dist/icons/PlayCircleIcon.js +1 -1
- package/dist/icons/PlayIcon.js +1 -1
- package/dist/icons/PlusIcon.js +1 -1
- package/dist/icons/ProgressBarIcon.js +1 -1
- package/dist/icons/ReloadIcon.js +1 -1
- package/dist/icons/ReportIcon.js +1 -1
- package/dist/icons/ReturnIcon.js +1 -1
- package/dist/icons/RightIcon.js +1 -1
- package/dist/icons/RowTotalsIcon.js +1 -1
- package/dist/icons/SchemeIcon.js +1 -1
- package/dist/icons/SearchIcon.js +1 -1
- package/dist/icons/SemanticQueryIcon.js +1 -1
- package/dist/icons/SettingsIcon.js +1 -1
- package/dist/icons/ShieldFilledIcon.js +1 -1
- package/dist/icons/ShieldIcon.js +1 -1
- package/dist/icons/SlashIcon.js +1 -1
- package/dist/icons/SparklesIcon.js +1 -1
- package/dist/icons/SqlIcon.js +1 -1
- package/dist/icons/StatsIcon.js +1 -1
- package/dist/icons/StopIcon.js +1 -1
- package/dist/icons/StringIcon.js +1 -1
- package/dist/icons/SubtotalsIcon.js +1 -1
- package/dist/icons/SwitchIcon.js +1 -1
- package/dist/icons/TableIcon.js +1 -1
- package/dist/icons/ThumbsDownIcon.js +1 -1
- package/dist/icons/ThumbsUpIcon.js +1 -1
- package/dist/icons/ThunderboltCrossedIcon.js +1 -1
- package/dist/icons/ThunderboltFilledIcon.js +1 -1
- package/dist/icons/ThunderboltIcon.js +1 -1
- package/dist/icons/TimeIcon.js +1 -1
- package/dist/icons/TrashIcon.js +1 -1
- package/dist/icons/UnlockIcon.js +1 -1
- package/dist/icons/UpIcon.js +1 -1
- package/dist/icons/UserGroupIcon.js +1 -1
- package/dist/icons/UserIcon.js +1 -1
- package/dist/icons/UserLockIcon.js +1 -1
- package/dist/icons/ViewIcon.js +1 -1
- package/dist/icons/WarningFilledIcon.js +1 -1
- package/dist/icons/WarningIcon.js +1 -1
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/wrap-icon.js +1 -1
- package/dist/index.d.ts +9 -3
- package/dist/index.js +13 -8
- package/dist/index.js.map +1 -1
- package/dist/props.d.ts +13 -0
- package/dist/provider.d.ts +1 -1
- package/dist/provider.js +1 -1
- package/dist/provider.js.map +1 -1
- package/dist/providers/TrackingProvider.js +1 -1
- package/dist/providers/navigationAdapter.default.js +1 -1
- package/dist/shared/form.d.ts +2 -1
- package/dist/tokens/base.js +1 -1
- package/dist/tokens/colors.js +1 -1
- package/dist/tokens/index.js +1 -1
- package/dist/tokens/layout.js +1 -1
- package/dist/tokens/lazy-styles.js +1 -1
- package/dist/tokens/palette-config.js +1 -1
- package/dist/tokens/palette.js +1 -1
- package/dist/tokens/shadows.js +1 -1
- package/dist/tokens/sizes.js +1 -1
- package/dist/tokens/spacing.js +1 -1
- package/dist/tokens/typography.js +1 -1
- package/dist/utils/ResizeSensor.js +1 -1
- package/dist/utils/is-dev-env.js +1 -1
- package/dist/utils/modules.js +1 -1
- package/dist/utils/promise.js +1 -1
- package/dist/utils/raf.js +1 -1
- package/dist/utils/random.js +1 -1
- package/dist/utils/range.js +1 -1
- package/dist/utils/react/RenderCache.js +1 -1
- package/dist/utils/react/Slots.js +1 -1
- package/dist/utils/react/chain.js +1 -1
- package/dist/utils/react/forwardRefWithGenerics.js +1 -1
- package/dist/utils/react/index.js +1 -1
- package/dist/utils/react/interactions.js +1 -1
- package/dist/utils/react/isTextOnly.js +1 -1
- package/dist/utils/react/mapProps.js +1 -1
- package/dist/utils/react/mergeProps.d.ts +1 -1
- package/dist/utils/react/mergeProps.js +1 -1
- package/dist/utils/react/mergeProps.js.map +1 -1
- package/dist/utils/react/nullableValue.d.ts +1 -1
- package/dist/utils/react/nullableValue.js +1 -1
- package/dist/utils/react/nullableValue.js.map +1 -1
- package/dist/utils/react/resolveIcon.js +1 -1
- package/dist/utils/react/sharedStore.js +1 -1
- package/dist/utils/react/useCombinedRefs.js +1 -1
- package/dist/utils/react/useControlledFocusVisible.js +1 -1
- package/dist/utils/react/useEventBus.js +1 -1
- package/dist/utils/react/useId.js +1 -1
- package/dist/utils/react/useIsDarwin.js +1 -1
- package/dist/utils/react/useKeySymbols.js +1 -1
- package/dist/utils/react/useLayoutEffect.js +1 -1
- package/dist/utils/react/useLocalStorage.js +1 -1
- package/dist/utils/react/useMergeStyles.js +1 -1
- package/dist/utils/react/usePopoverSync.js +1 -1
- package/dist/utils/react/useQaProps.js +1 -1
- package/dist/utils/react/useViewportSize.js +1 -1
- package/dist/utils/react/wrapNodeIfPlain.js +1 -1
- package/dist/utils/selection.js +1 -1
- package/dist/utils/styles.js +1 -1
- package/dist/utils/tree.js +1 -1
- package/dist/utils/warnings.js +1 -1
- package/dist/version.js +3 -3
- package/docs/components/content/Text.md +1 -2
- package/docs/components/fields/ColorPicker.md +271 -0
- package/docs/components/layout/Board.md +154 -6
- package/docs/tasty/README.md +3 -1
- package/docs/tasty/ai-agents.md +21 -7
- package/docs/tasty/configuration.md +220 -30
- package/docs/tasty/debug.md +7 -7
- package/docs/tasty/design-system.md +2 -2
- package/docs/tasty/dsl.md +68 -8
- package/docs/tasty/injector.md +31 -4
- package/docs/tasty/methodology.md +1 -1
- package/docs/tasty/migration-v3.md +285 -0
- package/docs/tasty/pipeline.md +3 -3
- package/docs/tasty/plugins.md +349 -0
- package/docs/tasty/react-api.md +61 -1
- package/docs/tasty/ssr.md +41 -33
- package/docs/tasty/styles.md +27 -9
- package/docs/tasty/tasty-static.md +8 -6
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WidgetHost.js","names":["mergeProps"],"sources":["../../../../src/components/layout/Board/WidgetHost.tsx"],"sourcesContent":["import { Styles, tasty } from '@tenphi/tasty';\nimport { CSSProperties, useMemo, useRef, useState } from 'react';\nimport { useFocusRing, useFocusWithin, useHover, useMove } from 'react-aria';\nimport { createPortal } from 'react-dom';\n\nimport { useEvent } from '../../../_internal/hooks';\nimport { mergeProps } from '../../../utils/react';\n\nimport {\n BoardDragState,\n BoardHost,\n BoardHostContext,\n BoardRegistryContextValue,\n ViewportRect,\n} from './board-context';\nimport { WidgetRegistration } from './board-store';\nimport {\n calcGridColWidth,\n calcGridItemPosition,\n LayoutItem,\n PositionParams,\n ResizeHandleAxis,\n} from './grid-core';\n\nexport type ResizePhase = 'start' | 'move' | 'end';\n\n/**\n * Slack (px) absorbed when converting an auto-height widget's content height to\n * whole rows, so sub-pixel measurement/rounding noise never bumps an extra row.\n */\nconst AUTO_HEIGHT_TOLERANCE = 4;\n\nconst WidgetElement = tasty({\n qa: 'BoardWidget',\n styles: {\n position: 'absolute',\n top: 0,\n left: 0,\n // Widgets always carry a `#surface-2` fill and rounded corners. The `card`\n // modifier (board-level `widgetProps.isCard` or per-widget `isCard`) adds a\n // border on top; a non-card widget is borderless so nested boards can align\n // their columns flush with the parent grid.\n fill: '#surface-2',\n radius: '1cr',\n border: {\n '': false,\n card: true,\n },\n shadow: {\n '': false,\n 'hovered & !card & (draggable | resizing)': '0 0 0 1bw #border',\n // `$dialog-shadow` uses Glaze `#shadow-lg`, which adapts to dark / high-contrast schemes.\n 'drag | resizing': '$dialog-shadow',\n },\n outline: {\n '': '1bw #primary-text.0',\n 'focus-visible': '1bw #primary-text',\n },\n outlineOffset: '1bw',\n zIndex: {\n '': 1,\n 'drag | resizing': 10,\n },\n // The pointer-drag ghost (the clone that floats in the overlay) is slightly\n // translucent so the user can see through it to whatever it hovers over -\n // e.g. a Tabs header underneath - and land a precise drop / tab switch. The\n // in-place host (keyboard drags, which never float) stays fully opaque.\n opacity: {\n '': 1,\n floating: 0.8,\n },\n // Reflowing widgets animate their position and size. The actively\n // dragged/resized element - and the floating overlay clone - must track the\n // pointer with no lag, so they drop geometry from the list. Geometry is also\n // dropped until the board reports `settled`: on init widgets jump to their\n // first measured positions, and without this gate they would slide/grow in\n // from their default box. The board lifts the gate after the first\n // positioned paint so subsequent reflows animate normally.\n transition: {\n '': 'theme, shadow, opacity',\n settled: 'theme, shadow, opacity, inset, width, height',\n 'drag | floating | resizing': 'theme, shadow, opacity',\n },\n boxSizing: 'border-box',\n userSelect: {\n '': 'auto',\n 'drag | resizing': 'none',\n },\n cursor: {\n '': 'auto',\n draggable: 'grab',\n drag: 'grabbing',\n },\n touchAction: 'none',\n overflow: 'hidden',\n },\n});\n\nconst HandleElement = tasty({\n qa: 'BoardResizeHandle',\n styles: {\n position: 'absolute',\n zIndex: 20,\n fill: '#clear',\n // Overhang: how far the hit-zone extends beyond the widget edge.\n '--handle-size': '3x',\n '--handle-overhang': '-8px',\n '--handle-inset': '1x',\n width: {\n '': '$handle-size',\n '[data-axis=\"n\"] | [data-axis=\"s\"]': 'auto',\n },\n height: {\n '': '$handle-size',\n '[data-axis=\"e\"] | [data-axis=\"w\"]': 'auto',\n },\n top: {\n '': 'auto',\n '[data-axis=\"n\"] | [data-axis=\"ne\"] | [data-axis=\"nw\"]':\n '$handle-overhang',\n '[data-axis=\"e\"] | [data-axis=\"w\"]': '$handle-inset',\n },\n bottom: {\n '': 'auto',\n '[data-axis=\"s\"] | [data-axis=\"se\"] | [data-axis=\"sw\"]':\n '$handle-overhang',\n '[data-axis=\"e\"] | [data-axis=\"w\"]': '$handle-inset',\n },\n left: {\n '': 'auto',\n '[data-axis=\"w\"] | [data-axis=\"nw\"] | [data-axis=\"sw\"]':\n '$handle-overhang',\n '[data-axis=\"n\"] | [data-axis=\"s\"]': '$handle-inset',\n },\n right: {\n '': 'auto',\n '[data-axis=\"e\"] | [data-axis=\"ne\"] | [data-axis=\"se\"]':\n '$handle-overhang',\n '[data-axis=\"n\"] | [data-axis=\"s\"]': '$handle-inset',\n },\n cursor: {\n '': 'default',\n '[data-axis=\"n\"] | [data-axis=\"s\"]': 'ns-resize',\n '[data-axis=\"e\"] | [data-axis=\"w\"]': 'ew-resize',\n '[data-axis=\"ne\"] | [data-axis=\"sw\"]': 'nesw-resize',\n '[data-axis=\"nw\"] | [data-axis=\"se\"]': 'nwse-resize',\n },\n touchAction: 'none',\n },\n});\n\nconst GripElement = tasty({\n qa: 'BoardResizeGrip',\n styles: {\n position: 'absolute',\n width: '10px',\n height: '10px',\n boxSizing: 'border-box',\n pointerEvents: 'none',\n opacity: {\n '': 0,\n revealed: 1,\n },\n transition: 'opacity 120ms ease-in-out',\n borderTop: {\n '': '0',\n '[data-axis=\"ne\"] | [data-axis=\"nw\"]': '2px solid #dark.40',\n },\n borderBottom: {\n '': '0',\n '[data-axis=\"se\"] | [data-axis=\"sw\"]': '2px solid #dark.40',\n },\n borderLeft: {\n '': '0',\n '[data-axis=\"nw\"] | [data-axis=\"sw\"]': '2px solid #dark.40',\n },\n borderRight: {\n '': '0',\n '[data-axis=\"ne\"] | [data-axis=\"se\"]': '2px solid #dark.40',\n },\n radius: {\n '': '0',\n '[data-axis=\"se\"]': '4px bottom-right',\n '[data-axis=\"sw\"]': '4px bottom-left',\n '[data-axis=\"ne\"]': '4px top-right',\n '[data-axis=\"nw\"]': '4px top-left',\n },\n top: {\n '': 'auto',\n '[data-axis=\"ne\"] | [data-axis=\"nw\"]': '4px',\n },\n bottom: {\n '': 'auto',\n '[data-axis=\"se\"] | [data-axis=\"sw\"]': '4px',\n },\n left: {\n '': 'auto',\n '[data-axis=\"nw\"] | [data-axis=\"sw\"]': '4px',\n },\n right: {\n '': 'auto',\n '[data-axis=\"ne\"] | [data-axis=\"se\"]': '4px',\n },\n },\n});\n\n// Edge axes (n/s/e/w) get a dotted grip affordance, revealed on\n// hover/focus/resize. The dots line up along the edge (a vertical column for the\n// e/w handles, a horizontal row for n/s), matching the design-system pane grip\n// (see `Layout.Pane`). Purely visual - the interaction still lives on the\n// transparent `HandleElement` hit-zone above.\nconst EdgeGripElement = tasty({\n qa: 'BoardResizeEdgeGrip',\n styles: {\n position: 'absolute',\n display: 'grid',\n gap: '2bw',\n boxSizing: 'border-box',\n pointerEvents: 'none',\n opacity: {\n '': 0,\n revealed: 1,\n },\n transition: 'opacity 120ms ease-in-out',\n // A column of 5 dots for the vertical edges (e/w), a row of 5 for n/s.\n gridColumns: {\n '': '3px',\n '[data-axis=\"n\"] | [data-axis=\"s\"]': '3px 3px 3px 3px 3px',\n },\n gridRows: {\n '': '3px 3px 3px 3px 3px',\n '[data-axis=\"n\"] | [data-axis=\"s\"]': '3px',\n },\n // Anchor to the relevant edge and center along it.\n top: {\n '': '50%',\n '[data-axis=\"n\"]': '3px',\n '[data-axis=\"s\"]': 'auto',\n },\n bottom: {\n '': 'auto',\n '[data-axis=\"s\"]': '3px',\n },\n left: {\n '': 'auto',\n '[data-axis=\"w\"]': '3px',\n '[data-axis=\"n\"] | [data-axis=\"s\"]': '50%',\n },\n right: {\n '': 'auto',\n '[data-axis=\"e\"]': '3px',\n },\n transform: {\n '': 'translate(0, 0)',\n '[data-axis=\"e\"] | [data-axis=\"w\"]': 'translate(0, -50%)',\n '[data-axis=\"n\"] | [data-axis=\"s\"]': 'translate(-50%, 0)',\n },\n\n Dot: {\n width: '3px',\n height: '3px',\n radius: 'round',\n fill: {\n '': '#dark-03',\n resizing: '#dark-02',\n },\n },\n },\n});\n\n/** Corner axes get a visible grip affordance on hover/focus/resize. */\nfunction isCornerAxis(axis: ResizeHandleAxis): boolean {\n return axis.length === 2;\n}\n\n/** Edge axes (n/s/e/w) get a dotted grip affordance. */\nfunction isEdgeAxis(axis: ResizeHandleAxis): boolean {\n return axis.length === 1;\n}\n\ninterface ResizeHandleProps {\n axis: ResizeHandleAxis;\n onResize: (\n axis: ResizeHandleAxis,\n phase: ResizePhase,\n dx: number,\n dy: number,\n ) => void;\n}\n\nfunction ResizeHandle({ axis, onResize }: ResizeHandleProps) {\n const { moveProps } = useMove({\n onMoveStart() {\n onResize(axis, 'start', 0, 0);\n },\n onMove(e) {\n onResize(axis, 'move', e.deltaX, e.deltaY);\n },\n onMoveEnd() {\n onResize(axis, 'end', 0, 0);\n },\n });\n\n const stopProps = {\n onPointerDown: (e: React.PointerEvent) => e.stopPropagation(),\n onMouseDown: (e: React.MouseEvent) => e.stopPropagation(),\n onTouchStart: (e: React.TouchEvent) => e.stopPropagation(),\n };\n\n return (\n <HandleElement\n data-axis={axis}\n {...mergeProps(stopProps, moveProps)}\n aria-hidden=\"true\"\n />\n );\n}\n\nexport interface WidgetHostProps {\n boardId: string;\n item: LayoutItem;\n positionParams: PositionParams;\n registration: WidgetRegistration | undefined;\n /**\n * Whether this widget renders with card chrome (fill/border/radius). Resolved\n * by the owning `Board` from the per-widget `isCard` and the board-level\n * `widgetProps.isCard` default.\n */\n isCard: boolean;\n /**\n * Resolved style overrides for the rendered widget element (per-widget\n * `styles` falling back to the board-level `widgetProps.styles`).\n */\n styles?: Styles;\n isDraggable: boolean;\n isResizable: boolean;\n resizeHandles: ResizeHandleAxis[];\n /**\n * Whether this widget grows to fit its content. Resolved by the owning\n * `Board` from the per-widget `isAutoHeight` and the board-level\n * `widgetProps.isAutoHeight` default.\n */\n isAutoHeight: boolean;\n /**\n * Test id / accessible name for the rendered widget element. Resolved by the\n * owning `Board` from the per-widget `qa` and the board-level `widgetProps.qa`\n * default; falls back to the layout id.\n */\n qa?: string;\n /**\n * CSS selector for elements that must not start a pointer drag (e.g. form\n * controls inside the widget). A pointer-down whose target matches this\n * selector never begins a drag.\n */\n dragCancel?: string;\n /**\n * CSS selector for the only elements from which a pointer drag may start. A\n * pointer-down outside a matching element never begins a drag.\n */\n dragHandle?: string;\n /**\n * Whether the owning board has settled its widgets' initial positions. While\n * false, the widget does not animate `inset` (left/top) so the first\n * positioned paint isn't seen as a transition. Lifted after the board's first\n * measured render.\n */\n settled?: boolean;\n registry: BoardRegistryContextValue;\n dragState: BoardDragState | null;\n onResize: (\n id: string,\n axis: ResizeHandleAxis,\n phase: ResizePhase,\n dx: number,\n dy: number,\n ) => void;\n /**\n * Report the minimum number of rows this widget needs to fit its content\n * (typically a nested board). The owning board grows the item to this height\n * when it is taller than the current one, and treats it as the resize floor\n * so the widget cannot be dragged shorter than its content requires.\n */\n onAutoHeight: (id: string, neededRows: number) => void;\n /**\n * Notify the owning board of a drag gesture's lifecycle so it can emit the\n * public drag callbacks. Fires after the registry has updated drag state.\n */\n onDragLifecycle?: (id: string, phase: ResizePhase) => void;\n}\n\n/**\n * The positioned, interactive wrapper a board renders for each layout item it\n * owns. Content is pulled from the shared store (by id), so any board can host\n * any widget. Dragging uses React Aria `useMove`; during a drag the widget\n * renders into the shared overlay portal so it can float outside its board.\n */\nexport function WidgetHost(props: WidgetHostProps) {\n const {\n boardId,\n item,\n positionParams,\n registration,\n isCard,\n styles: widgetStyles,\n isDraggable,\n isResizable,\n resizeHandles,\n isAutoHeight,\n qa,\n dragCancel,\n dragHandle,\n registry,\n dragState,\n settled,\n onResize,\n onAutoHeight,\n onDragLifecycle,\n } = props;\n\n const hostRef = useRef<HTMLDivElement | null>(null);\n const isActiveDrag = dragState?.itemId === item.i;\n\n // Translate a nested board's reported height deficit (signed px: positive when\n // it is squeezed, negative when it has slack) into the absolute number of rows\n // this widget needs, and report it to the owning board. The widget's chrome\n // cancels out: the needed pixel height is the widget's current pixel height\n // plus the deficit. A small tolerance keeps sub-pixel rounding from bumping an\n // extra row. Skipped during a drag (the widget is floating in the overlay).\n const requestHeightDeficit = useEvent((deficitPx: number) => {\n if (!isAutoHeight || isActiveDrag) return;\n const step = positionParams.rowHeight + positionParams.margin[1];\n if (step <= 0) return;\n const current = calcGridItemPosition(\n positionParams,\n item.x,\n item.y,\n item.w,\n item.h,\n );\n const neededPx = current.height + deficitPx;\n const neededRows = Math.max(\n 1,\n Math.ceil(\n (neededPx + positionParams.margin[1] - AUTO_HEIGHT_TOLERANCE) / step,\n ),\n );\n onAutoHeight(item.i, neededRows);\n });\n\n const hostValue = useMemo<BoardHost>(\n () => ({ isAutoHeight, requestHeightDeficit }),\n [isAutoHeight, requestHeightDeficit],\n );\n // Keyboard drags stay in place: moving the focused element into the overlay\n // portal would unmount it and stop arrow-key move events.\n const useOverlay = isActiveDrag && dragState?.pointerType !== 'keyboard';\n\n const [isResizing, setIsResizing] = useState(false);\n const [isFocusWithin, setIsFocusWithin] = useState(false);\n const { hoverProps, isHovered } = useHover({ isDisabled: isActiveDrag });\n const { focusProps, isFocusVisible } = useFocusRing();\n const { focusWithinProps } = useFocusWithin({\n onFocusWithinChange: setIsFocusWithin,\n });\n\n // Reveal the resize grips when the widget is interacted with (but not while it\n // is being dragged, where the widget floats in the overlay).\n const gripsRevealed =\n isResizable &&\n !item.static &&\n !isActiveDrag &&\n (isHovered || isFocusWithin || isResizing);\n\n const { moveProps } = useMove({\n onMoveStart(e) {\n if (!isDraggable) return;\n const rect = hostRef.current?.getBoundingClientRect();\n const pos = calcGridItemPosition(\n positionParams,\n item.x,\n item.y,\n item.w,\n item.h,\n );\n const vr: ViewportRect = rect\n ? {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n }\n : {\n left: pos.left,\n top: pos.top,\n width: pos.width,\n height: pos.height,\n };\n registry.onDragStart(boardId, item.i, vr, e.pointerType, hostRef.current);\n onDragLifecycle?.(item.i, 'start');\n },\n onMove(e) {\n if (!isDraggable) return;\n if (e.pointerType === 'keyboard') {\n // Amplify arrow-key steps to a full grid cell so items actually move.\n const colWidth = calcGridColWidth(positionParams);\n const stepX = colWidth + positionParams.margin[0];\n const stepY = positionParams.rowHeight + positionParams.margin[1];\n registry.onDragMove(\n Math.sign(e.deltaX) * stepX,\n Math.sign(e.deltaY) * stepY,\n e.pointerType,\n );\n onDragLifecycle?.(item.i, 'move');\n return;\n }\n registry.onDragMove(e.deltaX, e.deltaY, e.pointerType);\n onDragLifecycle?.(item.i, 'move');\n },\n onMoveEnd() {\n if (!isDraggable) return;\n registry.onDragEnd();\n onDragLifecycle?.(item.i, 'end');\n },\n });\n\n const a11yProps = {\n tabIndex: isDraggable ? 0 : undefined,\n 'aria-roledescription': isDraggable ? 'Draggable widget' : undefined,\n 'aria-label': qa ?? item.i,\n };\n\n // When this widget is draggable it owns its gesture, so stop the pointer-down\n // from bubbling to an ancestor widget host (e.g. a container widget hosting a\n // nested board / Tabs). Otherwise the ancestor's `useMove` would start a\n // second drag from the same press and the whole parent widget would move too.\n // Non-draggable widgets let the event bubble so their container stays grabbable\n // through their content.\n const stopBubbleProps = isDraggable\n ? {\n onPointerDown: (e: React.PointerEvent) => e.stopPropagation(),\n onMouseDown: (e: React.MouseEvent) => e.stopPropagation(),\n onTouchStart: (e: React.TouchEvent) => e.stopPropagation(),\n }\n : {};\n\n // Gate a pointer drag by `dragHandle` / `dragCancel` selectors. Returns true\n // when the press must NOT start a drag (outside a `dragHandle`, or matching\n // `dragCancel`).\n const shouldGateDrag = (target: EventTarget | null) => {\n if (!(target instanceof Element)) return false;\n if (dragHandle && !target.closest(dragHandle)) return true;\n return !!(dragCancel && target.closest(dragCancel));\n };\n\n // The gate wraps `useMove`'s own pointer-down handlers rather than a separate\n // capture-phase listener. When a press is gated we simply do not forward it to\n // `useMove`, so the drag never begins. This is deliberate: `useMove`'s\n // pointer-down handler calls both `stopPropagation()` and `preventDefault()`.\n // Calling it (or pre-empting it with a capture-phase `stopPropagation()`)\n // would break the very controls `dragCancel` is meant to protect - a\n // `preventDefault()` on pointer-down cancels a native `<input>`'s focus, and a\n // capture-phase `stopPropagation()` swallows a `<button>`'s own press events.\n // Skipping `useMove` entirely leaves the target's default behavior and its own\n // handlers fully intact.\n //\n // Keyboard moves also go through `useMove` (`onKeyDown`). Arrow keys must only\n // move the widget when the host itself is focused — not when focus is inside a\n // nested input, textarea, or other descendant (those events bubble to the host\n // and would otherwise steal caret / list navigation).\n //\n // A non-draggable widget must not carry `moveProps` at all: `useMove`'s\n // pointer-down handler calls `preventDefault()`, which cancels native text\n // selection inside the widget. Read-only boards (`isDraggable={false}`) still\n // need selectable content, so we drop the handlers entirely instead of relying\n // on the early-returns inside the `onMove*` callbacks.\n const gatedMoveProps = !isDraggable\n ? {}\n : {\n ...moveProps,\n ...(moveProps.onPointerDown && {\n onPointerDown: (e: React.PointerEvent<HTMLDivElement>) => {\n if (shouldGateDrag(e.target)) return;\n hostRef.current?.focus({ preventScroll: true });\n moveProps.onPointerDown!(e);\n },\n }),\n ...(moveProps.onMouseDown && {\n onMouseDown: (e: React.MouseEvent<HTMLDivElement>) => {\n if (shouldGateDrag(e.target)) return;\n hostRef.current?.focus({ preventScroll: true });\n moveProps.onMouseDown!(e);\n },\n }),\n ...(moveProps.onTouchStart && {\n onTouchStart: (e: React.TouchEvent<HTMLDivElement>) => {\n if (shouldGateDrag(e.target)) return;\n moveProps.onTouchStart!(e);\n },\n }),\n ...(moveProps.onKeyDown && {\n onKeyDown: (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.target !== e.currentTarget) return;\n moveProps.onKeyDown!(e);\n },\n }),\n };\n\n const handleResize = (\n axis: ResizeHandleAxis,\n phase: ResizePhase,\n dx: number,\n dy: number,\n ) => {\n if (phase === 'start') setIsResizing(true);\n else if (phase === 'end') setIsResizing(false);\n onResize(item.i, axis, phase, dx, dy);\n };\n\n const mods = {\n drag: isActiveDrag,\n draggable: isDraggable && !isActiveDrag,\n static: !!item.static,\n resizing: isResizing,\n card: isCard,\n hovered: isHovered,\n 'focus-visible': isFocusVisible,\n };\n\n const content = (\n <BoardHostContext.Provider value={hostValue}>\n {registration?.content}\n {isResizable && !item.static ? (\n <>\n {resizeHandles.map((axis) => (\n <ResizeHandle key={axis} axis={axis} onResize={handleResize} />\n ))}\n {resizeHandles.filter(isCornerAxis).map((axis) => (\n <GripElement\n key={`grip-${axis}`}\n data-axis={axis}\n mods={{ revealed: gripsRevealed }}\n aria-hidden=\"true\"\n />\n ))}\n {resizeHandles.filter(isEdgeAxis).map((axis) => (\n <EdgeGripElement\n key={`edge-grip-${axis}`}\n data-axis={axis}\n mods={{ revealed: gripsRevealed, resizing: isResizing }}\n aria-hidden=\"true\"\n >\n <div data-element=\"Dot\" />\n <div data-element=\"Dot\" />\n <div data-element=\"Dot\" />\n <div data-element=\"Dot\" />\n <div data-element=\"Dot\" />\n </EdgeGripElement>\n ))}\n </>\n ) : null}\n </BoardHostContext.Provider>\n );\n\n const pos = calcGridItemPosition(\n positionParams,\n item.x,\n item.y,\n item.w,\n item.h,\n );\n\n // While dragging with a pointer, the widget's visual floats in the shared\n // overlay so it is never clipped by an ancestor's `overflow: hidden`. The\n // gesture-owning element (the one carrying `moveProps`) must NOT be the node\n // that moves into the overlay: React Aria's `useMove` binds its pointer\n // move/end listeners relative to the node that received `onPointerDown`, and\n // relocating that node into the portal tears it down and mounts a fresh one\n // (inside a `pointerEvents: 'none'` layer), which can drop the in-flight\n // gesture. Instead we keep a stable, always-mounted in-grid host that owns the\n // gesture for its whole lifetime, and portal a separate, non-interactive\n // visual clone into the overlay.\n const overlayNode = registry.overlayRef.current;\n const floatInOverlay = useOverlay && !!overlayNode && !!dragState;\n\n const hostStyle: CSSProperties = {\n left: `${pos.left}px`,\n top: `${pos.top}px`,\n width: `${pos.width}px`,\n height: `${pos.height}px`,\n // Kept mounted but hidden while its clone floats, so the gesture stays live\n // on this node (the pointer listeners never get torn down).\n ...(floatInOverlay ? { opacity: 0, pointerEvents: 'none' } : null),\n };\n\n // The floating clone carries the \"drag\" affordance (raised shadow/z-index);\n // keep the hidden host flat. Keyboard drags (which never float) still\n // highlight the in-grid host, so only suppress `drag` when floating.\n const hostMods = { ...mods, drag: isActiveDrag && !floatInOverlay, settled };\n\n // The host is always rendered first, with a stable element shape, so React\n // reuses the same DOM node across the drag transition (never remounts it).\n const host = (\n <WidgetElement\n ref={hostRef}\n // Marks this element as a board widget host so the registry can find the\n // container widget a nested board lives in (used to keep a drag anchored to\n // a nested board while the anchor is still over its host - e.g. the Tabs\n // header above a nested board - instead of reflowing the ancestor board).\n data-board-widget-host=\"\"\n {...mergeProps(\n gatedMoveProps,\n stopBubbleProps,\n hoverProps,\n focusProps,\n focusWithinProps,\n a11yProps,\n { style: hostStyle },\n )}\n qa={qa}\n mods={hostMods}\n styles={widgetStyles as Styles}\n >\n {floatInOverlay ? null : content}\n </WidgetElement>\n );\n\n const overlayClone = floatInOverlay\n ? createPortal(\n <WidgetElement\n style={{\n position: 'absolute',\n left: `${dragState!.rect.left}px`,\n top: `${dragState!.rect.top}px`,\n width: `${dragState!.rect.width}px`,\n height: `${dragState!.rect.height}px`,\n pointerEvents: 'none',\n }}\n mods={{ ...mods, drag: true, floating: true }}\n styles={widgetStyles as Styles}\n aria-hidden=\"true\"\n >\n {content}\n </WidgetElement>,\n overlayNode!,\n )\n : null;\n\n return (\n <>\n {host}\n {overlayClone}\n </>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WidgetHost.js","names":["mergeProps"],"sources":["../../../../src/components/layout/Board/WidgetHost.tsx"],"sourcesContent":["import { Styles, tasty } from '@tenphi/tasty';\nimport { CSSProperties, useMemo, useRef, useState } from 'react';\nimport { useFocusRing, useFocusWithin, useHover, useMove } from 'react-aria';\nimport { createPortal } from 'react-dom';\n\nimport { useEvent } from '../../../_internal/hooks';\nimport { useI18n } from '../../../i18n';\nimport { mergeProps } from '../../../utils/react';\n\nimport {\n BoardDragState,\n BoardHost,\n BoardHostContext,\n BoardRegistryContextValue,\n ViewportRect,\n} from './board-context';\nimport { WidgetRegistration } from './board-store';\nimport {\n calcGridColWidth,\n calcGridItemPosition,\n LayoutItem,\n PositionParams,\n ResizeHandleAxis,\n} from './grid-core';\nimport { BoardSelectModifierKey } from './use-board-select-modifier-key';\n\nexport type ResizePhase = 'start' | 'move' | 'end';\n\n/**\n * Slack (px) absorbed when converting an auto-height widget's content height to\n * whole rows, so sub-pixel measurement/rounding noise never bumps an extra row.\n */\nconst AUTO_HEIGHT_TOLERANCE = 4;\n\nconst WidgetElement = tasty({\n qa: 'BoardWidget',\n styles: {\n position: 'absolute',\n top: 0,\n left: 0,\n // Widgets always carry a `#surface-2` fill and rounded corners. The `card`\n // modifier (board-level `widgetProps.isCard` or per-widget `isCard`) adds a\n // border on top; a non-card widget is borderless so nested boards can align\n // their columns flush with the parent grid.\n fill: '#surface-2',\n radius: '1cr',\n // Selection reads as a focus-like state here - it is transient, it follows\n // what the user is working with, and it is dropped the moment they touch\n // something else - so it is drawn as an edge treatment rather than as a\n // fill. `outline` stays reserved for the real focus ring (the kit's\n // convention everywhere), and the two are kept legible side by side by\n // token: selection is a saturated `#primary` ring, focus a `#primary-text`\n // outline sitting one border-width further out (`outlineOffset`).\n border: {\n '': false,\n card: true,\n selected: '#primary-border',\n },\n shadow: {\n '': false,\n 'hovered & !card & (draggable | resizing)': '0 0 0 1bw #border',\n selected: '0 0 0 1bw #primary',\n // `$dialog-shadow` uses Glaze `#shadow-lg`, which adapts to dark / high-contrast schemes.\n 'drag | resizing': '$dialog-shadow',\n },\n outline: {\n '': '1bw #primary-text.0',\n 'focus-visible': '1bw #primary-text',\n },\n outlineOffset: '1bw',\n zIndex: {\n '': 1,\n 'drag | resizing': 10,\n },\n // The pointer-drag ghost (the clone that floats in the overlay) is slightly\n // translucent so the user can see through it to whatever it hovers over -\n // e.g. a Tabs header underneath - and land a precise drop / tab switch. The\n // in-place host (keyboard drags, which never float) stays fully opaque.\n opacity: {\n '': 1,\n floating: 0.8,\n },\n // Reflowing widgets animate their position and size. The actively\n // dragged/resized element - and the floating overlay clone - must track the\n // pointer with no lag, so they drop geometry from the list. Geometry is also\n // dropped until the board reports `settled`: on init widgets jump to their\n // first measured positions, and without this gate they would slide/grow in\n // from their default box. The board lifts the gate after the first\n // positioned paint so subsequent reflows animate normally.\n transition: {\n '': 'theme, shadow, opacity',\n settled: 'theme, shadow, opacity, inset, width, height',\n 'drag | floating | resizing': 'theme, shadow, opacity',\n },\n boxSizing: 'border-box',\n userSelect: {\n '': 'auto',\n 'drag | resizing': 'none',\n },\n cursor: {\n '': 'auto',\n draggable: 'grab',\n drag: 'grabbing',\n },\n touchAction: 'none',\n // A widget owns its grid cell and must not paint outside it: a nested board\n // with more rows than currently fit, a mid-drag reflow (an auto-height\n // container deliberately cannot grow while a drag is in flight), or a long\n // unbreakable string would otherwise spill over its neighbours. Clipping\n // holds regardless of `isCard` — a borderless widget has no drawn edge, but\n // it still has a cell.\n //\n // The cost is that a descendant's `outline` is cropped at the edge, since an\n // outline is clipped by an *ancestor's* overflow rather than its own. A\n // widget whose content needs to paint outside — a control drawing its own\n // active ring — opts out with `overflow=\"visible\"`, or draws the ring inset\n // with a negative `outlineOffset`.\n overflow: 'hidden',\n },\n});\n\nconst HandleElement = tasty({\n qa: 'BoardResizeHandle',\n styles: {\n position: 'absolute',\n zIndex: 20,\n fill: '#clear',\n // Overhang: how far the hit-zone extends beyond the widget edge.\n '--handle-size': '3x',\n '--handle-overhang': '-8px',\n '--handle-inset': '1x',\n width: {\n '': '$handle-size',\n '[data-axis=\"n\"] | [data-axis=\"s\"]': 'auto',\n },\n height: {\n '': '$handle-size',\n '[data-axis=\"e\"] | [data-axis=\"w\"]': 'auto',\n },\n top: {\n '': 'auto',\n '[data-axis=\"n\"] | [data-axis=\"ne\"] | [data-axis=\"nw\"]':\n '$handle-overhang',\n '[data-axis=\"e\"] | [data-axis=\"w\"]': '$handle-inset',\n },\n bottom: {\n '': 'auto',\n '[data-axis=\"s\"] | [data-axis=\"se\"] | [data-axis=\"sw\"]':\n '$handle-overhang',\n '[data-axis=\"e\"] | [data-axis=\"w\"]': '$handle-inset',\n },\n left: {\n '': 'auto',\n '[data-axis=\"w\"] | [data-axis=\"nw\"] | [data-axis=\"sw\"]':\n '$handle-overhang',\n '[data-axis=\"n\"] | [data-axis=\"s\"]': '$handle-inset',\n },\n right: {\n '': 'auto',\n '[data-axis=\"e\"] | [data-axis=\"ne\"] | [data-axis=\"se\"]':\n '$handle-overhang',\n '[data-axis=\"n\"] | [data-axis=\"s\"]': '$handle-inset',\n },\n cursor: {\n '': 'default',\n '[data-axis=\"n\"] | [data-axis=\"s\"]': 'ns-resize',\n '[data-axis=\"e\"] | [data-axis=\"w\"]': 'ew-resize',\n '[data-axis=\"ne\"] | [data-axis=\"sw\"]': 'nesw-resize',\n '[data-axis=\"nw\"] | [data-axis=\"se\"]': 'nwse-resize',\n },\n touchAction: 'none',\n },\n});\n\nconst GripElement = tasty({\n qa: 'BoardResizeGrip',\n styles: {\n position: 'absolute',\n width: '10px',\n height: '10px',\n boxSizing: 'border-box',\n pointerEvents: 'none',\n opacity: {\n '': 0,\n revealed: 1,\n },\n transition: 'opacity 120ms ease-in-out',\n borderTop: {\n '': '0',\n '[data-axis=\"ne\"] | [data-axis=\"nw\"]': '2px solid #dark.40',\n },\n borderBottom: {\n '': '0',\n '[data-axis=\"se\"] | [data-axis=\"sw\"]': '2px solid #dark.40',\n },\n borderLeft: {\n '': '0',\n '[data-axis=\"nw\"] | [data-axis=\"sw\"]': '2px solid #dark.40',\n },\n borderRight: {\n '': '0',\n '[data-axis=\"ne\"] | [data-axis=\"se\"]': '2px solid #dark.40',\n },\n radius: {\n '': '0',\n '[data-axis=\"se\"]': '4px bottom-right',\n '[data-axis=\"sw\"]': '4px bottom-left',\n '[data-axis=\"ne\"]': '4px top-right',\n '[data-axis=\"nw\"]': '4px top-left',\n },\n top: {\n '': 'auto',\n '[data-axis=\"ne\"] | [data-axis=\"nw\"]': '4px',\n },\n bottom: {\n '': 'auto',\n '[data-axis=\"se\"] | [data-axis=\"sw\"]': '4px',\n },\n left: {\n '': 'auto',\n '[data-axis=\"nw\"] | [data-axis=\"sw\"]': '4px',\n },\n right: {\n '': 'auto',\n '[data-axis=\"ne\"] | [data-axis=\"se\"]': '4px',\n },\n },\n});\n\n// Edge axes (n/s/e/w) get a dotted grip affordance, revealed on\n// hover/focus/resize. The dots line up along the edge (a vertical column for the\n// e/w handles, a horizontal row for n/s), matching the design-system pane grip\n// (see `Layout.Pane`). Purely visual - the interaction still lives on the\n// transparent `HandleElement` hit-zone above.\nconst EdgeGripElement = tasty({\n qa: 'BoardResizeEdgeGrip',\n styles: {\n position: 'absolute',\n display: 'grid',\n gap: '2bw',\n boxSizing: 'border-box',\n pointerEvents: 'none',\n opacity: {\n '': 0,\n revealed: 1,\n },\n transition: 'opacity 120ms ease-in-out',\n // A column of 5 dots for the vertical edges (e/w), a row of 5 for n/s.\n gridColumns: {\n '': '3px',\n '[data-axis=\"n\"] | [data-axis=\"s\"]': '3px 3px 3px 3px 3px',\n },\n gridRows: {\n '': '3px 3px 3px 3px 3px',\n '[data-axis=\"n\"] | [data-axis=\"s\"]': '3px',\n },\n // Anchor to the relevant edge and center along it.\n top: {\n '': '50%',\n '[data-axis=\"n\"]': '3px',\n '[data-axis=\"s\"]': 'auto',\n },\n bottom: {\n '': 'auto',\n '[data-axis=\"s\"]': '3px',\n },\n left: {\n '': 'auto',\n '[data-axis=\"w\"]': '3px',\n '[data-axis=\"n\"] | [data-axis=\"s\"]': '50%',\n },\n right: {\n '': 'auto',\n '[data-axis=\"e\"]': '3px',\n },\n transform: {\n '': 'translate(0, 0)',\n '[data-axis=\"e\"] | [data-axis=\"w\"]': 'translate(0, -50%)',\n '[data-axis=\"n\"] | [data-axis=\"s\"]': 'translate(-50%, 0)',\n },\n\n Dot: {\n width: '3px',\n height: '3px',\n radius: 'round',\n fill: {\n '': '#dark-03',\n resizing: '#dark-02',\n },\n },\n },\n});\n\n/** Corner axes get a visible grip affordance on hover/focus/resize. */\nfunction isCornerAxis(axis: ResizeHandleAxis): boolean {\n return axis.length === 2;\n}\n\n/** Edge axes (n/s/e/w) get a dotted grip affordance. */\nfunction isEdgeAxis(axis: ResizeHandleAxis): boolean {\n return axis.length === 1;\n}\n\ninterface ResizeHandleProps {\n axis: ResizeHandleAxis;\n onResize: (\n axis: ResizeHandleAxis,\n phase: ResizePhase,\n dx: number,\n dy: number,\n ) => void;\n}\n\nfunction ResizeHandle({ axis, onResize }: ResizeHandleProps) {\n const { moveProps } = useMove({\n onMoveStart() {\n onResize(axis, 'start', 0, 0);\n },\n onMove(e) {\n onResize(axis, 'move', e.deltaX, e.deltaY);\n },\n onMoveEnd() {\n onResize(axis, 'end', 0, 0);\n },\n });\n\n const stopProps = {\n onPointerDown: (e: React.PointerEvent) => e.stopPropagation(),\n onMouseDown: (e: React.MouseEvent) => e.stopPropagation(),\n onTouchStart: (e: React.TouchEvent) => e.stopPropagation(),\n };\n\n return (\n <HandleElement\n data-axis={axis}\n {...mergeProps(stopProps, moveProps)}\n aria-hidden=\"true\"\n />\n );\n}\n\nexport interface WidgetHostProps {\n boardId: string;\n item: LayoutItem;\n positionParams: PositionParams;\n registration: WidgetRegistration | undefined;\n /**\n * Whether this widget renders with card chrome (fill/border/radius). Resolved\n * by the owning `Board` from the per-widget `isCard` and the board-level\n * `widgetProps.isCard` default.\n */\n isCard: boolean;\n /**\n * Resolved style overrides for the rendered widget element (per-widget\n * `styles` falling back to the board-level `widgetProps.styles`).\n */\n styles?: Styles;\n isDraggable: boolean;\n isResizable: boolean;\n resizeHandles: ResizeHandleAxis[];\n /**\n * Whether this widget grows to fit its content. Resolved by the owning\n * `Board` from the per-widget `isAutoHeight` and the board-level\n * `widgetProps.isAutoHeight` default.\n */\n isAutoHeight: boolean;\n /**\n * Test id / accessible name for the rendered widget element. Resolved by the\n * owning `Board` from the per-widget `qa` and the board-level `widgetProps.qa`\n * default; falls back to the layout id.\n */\n qa?: string;\n /**\n * CSS selector for elements that must not start a pointer drag (e.g. form\n * controls inside the widget). A pointer-down whose target matches this\n * selector never begins a drag.\n */\n dragCancel?: string;\n /**\n * CSS selector for the only elements from which a pointer drag may start. A\n * pointer-down outside a matching element never begins a drag.\n */\n dragHandle?: string;\n /**\n * Whether the owning board has settled its widgets' initial positions. While\n * false, the widget does not animate `inset` (left/top) so the first\n * positioned paint isn't seen as a transition. Lifted after the board's first\n * measured render.\n */\n settled?: boolean;\n registry: BoardRegistryContextValue;\n dragState: BoardDragState | null;\n onResize: (\n id: string,\n axis: ResizeHandleAxis,\n phase: ResizePhase,\n dx: number,\n dy: number,\n ) => void;\n /**\n * Report the minimum number of rows this widget needs to fit its content\n * (typically a nested board). The owning board grows the item to this height\n * when it is taller than the current one, and treats it as the resize floor\n * so the widget cannot be dragged shorter than its content requires.\n */\n onAutoHeight: (id: string, neededRows: number) => void;\n /**\n * Notify the owning board of a drag gesture's lifecycle so it can emit the\n * public drag callbacks. Fires after the registry has updated drag state.\n */\n onDragLifecycle?: (id: string, phase: ResizePhase) => void;\n /** Whether this widget can be selected (board selection on and not opted out). */\n isSelectable?: boolean;\n isSelected?: boolean;\n /** CSS selector for descendants whose clicks must not change the selection. */\n selectionCancel?: string;\n /** Id of the board-owned node holding the shared \"Selected\" description. */\n selectedHintId?: string;\n /** Apply a selection gesture. `additive` toggles instead of replacing. */\n onSelect?: (id: string, additive: boolean) => void;\n /** Drop the whole selection. Called when the user interacts elsewhere. */\n onSelectionReset?: () => void;\n /** Pointer-event property carrying the platform additive-selection modifier. */\n selectModifierKey?: BoardSelectModifierKey;\n}\n\n/**\n * The positioned, interactive wrapper a board renders for each layout item it\n * owns. Content is pulled from the shared store (by id), so any board can host\n * any widget. Dragging uses React Aria `useMove`; during a drag the widget\n * renders into the shared overlay portal so it can float outside its board.\n */\nexport function WidgetHost(props: WidgetHostProps) {\n const {\n boardId,\n item,\n positionParams,\n registration,\n isCard,\n styles: widgetStyles,\n isDraggable,\n isResizable,\n resizeHandles,\n isAutoHeight,\n qa,\n dragCancel,\n dragHandle,\n registry,\n dragState,\n settled,\n onResize,\n onAutoHeight,\n onDragLifecycle,\n isSelectable = false,\n isSelected = false,\n selectionCancel,\n selectedHintId,\n onSelect,\n onSelectionReset,\n selectModifierKey = 'metaKey',\n } = props;\n\n const { t } = useI18n();\n const ariaLabel = registration?.['aria-label'];\n const hostRef = useRef<HTMLDivElement | null>(null);\n const isActiveDrag = dragState?.itemId === item.i;\n // Every member of a group drag floats, not just the grabbed one — otherwise\n // the rest sit motionless while their placeholders move, which reads as\n // broken. Only the grabbed host owns a live `useMove` gesture, so hiding the\n // others is trivially safe.\n const isDragMember = !!dragState?.itemIds.includes(item.i);\n\n // Translate a nested board's reported height deficit (signed px: positive when\n // it is squeezed, negative when it has slack) into the absolute number of rows\n // this widget needs, and report it to the owning board. The widget's chrome\n // cancels out: the needed pixel height is the widget's current pixel height\n // plus the deficit. A small tolerance keeps sub-pixel rounding from bumping an\n // extra row. Skipped during a drag (the widget is floating in the overlay).\n const requestHeightDeficit = useEvent((deficitPx: number) => {\n if (!isAutoHeight || isActiveDrag) return;\n const step = positionParams.rowHeight + positionParams.margin[1];\n if (step <= 0) return;\n const current = calcGridItemPosition(\n positionParams,\n item.x,\n item.y,\n item.w,\n item.h,\n );\n const neededPx = current.height + deficitPx;\n const neededRows = Math.max(\n 1,\n Math.ceil(\n (neededPx + positionParams.margin[1] - AUTO_HEIGHT_TOLERANCE) / step,\n ),\n );\n onAutoHeight(item.i, neededRows);\n });\n\n const hostValue = useMemo<BoardHost>(\n () => ({ isAutoHeight, requestHeightDeficit }),\n [isAutoHeight, requestHeightDeficit],\n );\n // Keyboard drags stay in place: moving the focused element into the overlay\n // portal would unmount it and stop arrow-key move events.\n const useOverlay = isActiveDrag && dragState?.pointerType !== 'keyboard';\n\n const [isResizing, setIsResizing] = useState(false);\n const [isFocusWithin, setIsFocusWithin] = useState(false);\n const { hoverProps, isHovered } = useHover({ isDisabled: isActiveDrag });\n const { focusProps, isFocusVisible } = useFocusRing();\n const { focusWithinProps } = useFocusWithin({\n onFocusWithinChange: setIsFocusWithin,\n });\n\n // Reveal the resize grips when the widget is interacted with (but not while it\n // is being dragged, where the widget floats in the overlay).\n const gripsRevealed =\n isResizable &&\n !item.static &&\n !isActiveDrag &&\n (isHovered || isFocusWithin || isResizing);\n\n const { moveProps } = useMove({\n onMoveStart(e) {\n if (!isDraggable) return;\n const rect = hostRef.current?.getBoundingClientRect();\n const pos = calcGridItemPosition(\n positionParams,\n item.x,\n item.y,\n item.w,\n item.h,\n );\n const vr: ViewportRect = rect\n ? {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n }\n : {\n left: pos.left,\n top: pos.top,\n width: pos.width,\n height: pos.height,\n };\n registry.onDragStart(boardId, item.i, vr, e.pointerType, hostRef.current);\n onDragLifecycle?.(item.i, 'start');\n },\n onMove(e) {\n if (!isDraggable) return;\n if (e.pointerType === 'keyboard') {\n // Amplify arrow-key steps to a full grid cell so items actually move.\n const colWidth = calcGridColWidth(positionParams);\n const stepX = colWidth + positionParams.margin[0];\n const stepY = positionParams.rowHeight + positionParams.margin[1];\n registry.onDragMove(\n Math.sign(e.deltaX) * stepX,\n Math.sign(e.deltaY) * stepY,\n e.pointerType,\n );\n onDragLifecycle?.(item.i, 'move');\n return;\n }\n registry.onDragMove(e.deltaX, e.deltaY, e.pointerType);\n onDragLifecycle?.(item.i, 'move');\n },\n onMoveEnd() {\n if (!isDraggable) return;\n registry.onDragEnd();\n onDragLifecycle?.(item.i, 'end');\n },\n });\n\n // `role=\"group\"` is what makes `aria-roledescription` legal here - it is\n // invalid on a role-less `div`, which is what this element used to be. A\n // collection role (`option`, `gridcell`, ...) would be the only way to carry a\n // real `aria-selected`, but those require presentational children and a\n // widget hosts arbitrary interactive content, so selection is conveyed by the\n // board's live region plus the shared description below instead.\n const a11yProps = {\n role: 'group',\n tabIndex: isDraggable || isSelectable ? 0 : undefined,\n 'aria-roledescription': isDraggable\n ? t('board.draggableWidget', 'Draggable widget')\n : t('board.widget', 'Widget'),\n 'aria-label': ariaLabel ?? qa ?? item.i,\n 'aria-describedby': isSelected ? selectedHintId : undefined,\n 'aria-keyshortcuts': isSelectable ? 'Space' : undefined,\n };\n\n // True from the moment a real move begins until the click that ends the\n // gesture has been swallowed. `useMove` binds only pointerdown/keydown, never\n // click, so a click handler composes with it cleanly - but the click that\n // *terminates* a drag would otherwise land as a selection. Event order is\n // pointerdown -> onMove* -> pointerup -> onMoveEnd -> click, so this ref is\n // always accurate by the time the click arrives. More reliable than a pixel\n // threshold, which has to guess.\n const isInteractiveTarget = (target: EventTarget | null) => {\n const el = target as HTMLElement | null;\n\n return !!(selectionCancel && el?.closest?.(selectionCancel));\n };\n\n /**\n * Selecting and starting a drag are the *same* gesture: you grab the thing you\n * are about to move. So the press selects immediately and the drag arms behind\n * it — move and it drags, stay still and it was only a selection. This is what\n * every canvas tool does, and it is why there is no ambiguity to resolve with a\n * modifier.\n *\n * - a press on an interactive descendant belongs to that control, so the\n * selection is dropped and the press is left alone;\n * - <kbd>Shift</kbd> or the platform modifier toggles membership;\n * - a press on an unselected widget makes it the selection, so the drag that\n * follows moves exactly what was grabbed;\n * - a press on an already-selected widget changes nothing, so the drag moves\n * the whole group.\n *\n * Runs before the drag handler (see the `mergeProps` order below), so the\n * registry resolves the group against the selection this press just made.\n */\n const handleSelectPointerDown = (e: React.PointerEvent) => {\n if (!isSelectable || !onSelect || e.button !== 0) return;\n\n if (isInteractiveTarget(e.target)) {\n onSelectionReset?.();\n\n return;\n }\n\n // A press this widget owns must never reach an ancestor widget host: in a\n // nested board the outer widget would otherwise select itself on top of the\n // inner selection. This has to cover the already-selected case too, which\n // changes nothing here but is still a press this board handled — and\n // `stopBubbleProps` below only guards draggable widgets.\n e.stopPropagation();\n\n if (e.shiftKey || e[selectModifierKey]) {\n onSelect(item.i, true);\n\n return;\n }\n\n if (!isSelected) {\n onSelect(item.i, false);\n }\n };\n\n const handleSelectKeyDown = (e: React.KeyboardEvent) => {\n // Same guard the arrow keys use: only act when the host itself is focused,\n // so Space inside a nested input or button keeps its meaning.\n if (e.target !== e.currentTarget) return;\n if (!isSelectable || !onSelect) return;\n if (e.key !== ' ' && e.key !== 'Spacebar') return;\n\n // No modifier needed here: focus already says which widget is meant, and\n // Space cannot be mistaken for the start of a drag. Only swallow the key\n // once we know we are acting on it, so a board without selection still\n // scrolls on Space.\n e.preventDefault();\n e.stopPropagation();\n // Space is an explicit selection gesture (a click is also \"interact with\n // this\"), so it toggles - that is the keyboard's way to deselect one widget.\n onSelect(item.i, true);\n };\n\n // When this widget is draggable it owns its gesture, so stop the pointer-down\n // from bubbling to an ancestor widget host (e.g. a container widget hosting a\n // nested board / Tabs). Otherwise the ancestor's `useMove` would start a\n // second drag from the same press and the whole parent widget would move too.\n // Non-draggable widgets let the event bubble so their container stays grabbable\n // through their content.\n const stopBubbleProps = isDraggable\n ? {\n onPointerDown: (e: React.PointerEvent) => e.stopPropagation(),\n onMouseDown: (e: React.MouseEvent) => e.stopPropagation(),\n onTouchStart: (e: React.TouchEvent) => e.stopPropagation(),\n }\n : {};\n\n // Gate a pointer drag by `dragHandle` / `dragCancel` selectors. Returns true\n // when the press must NOT start a drag (outside a `dragHandle`, or matching\n // `dragCancel`).\n const shouldGateDrag = (target: EventTarget | null) => {\n if (!(target instanceof Element)) return false;\n if (dragHandle && !target.closest(dragHandle)) return true;\n if (dragCancel && target.closest(dragCancel)) return true;\n\n // `selectionCancel` already declares which descendants are interactive, and\n // a drag must not start from them either — otherwise `useMove`'s\n // `preventDefault()` on pointer-down swallows the native focus and an input\n // inside a widget cannot be typed into. Only for selectable widgets, so a\n // board that never opted into selection keeps its exact previous behaviour\n // and `dragCancel` stays the only thing that gates a drag there.\n return !!(\n isSelectable &&\n selectionCancel &&\n target.closest(selectionCancel)\n );\n };\n\n // The gate wraps `useMove`'s own pointer-down handlers rather than a separate\n // capture-phase listener. When a press is gated we simply do not forward it to\n // `useMove`, so the drag never begins. This is deliberate: `useMove`'s\n // pointer-down handler calls both `stopPropagation()` and `preventDefault()`.\n // Calling it (or pre-empting it with a capture-phase `stopPropagation()`)\n // would break the very controls `dragCancel` is meant to protect - a\n // `preventDefault()` on pointer-down cancels a native `<input>`'s focus, and a\n // capture-phase `stopPropagation()` swallows a `<button>`'s own press events.\n // Skipping `useMove` entirely leaves the target's default behavior and its own\n // handlers fully intact.\n //\n // Keyboard moves also go through `useMove` (`onKeyDown`). Arrow keys must only\n // move the widget when the host itself is focused — not when focus is inside a\n // nested input, textarea, or other descendant (those events bubble to the host\n // and would otherwise steal caret / list navigation).\n //\n // A non-draggable widget must not carry `moveProps` at all: `useMove`'s\n // pointer-down handler calls `preventDefault()`, which cancels native text\n // selection inside the widget. Read-only boards (`isDraggable={false}`) still\n // need selectable content, so we drop the handlers entirely instead of relying\n // on the early-returns inside the `onMove*` callbacks.\n const gatedMoveProps = !isDraggable\n ? {}\n : {\n ...moveProps,\n ...(moveProps.onPointerDown && {\n onPointerDown: (e: React.PointerEvent<HTMLDivElement>) => {\n if (shouldGateDrag(e.target)) return;\n hostRef.current?.focus({ preventScroll: true });\n moveProps.onPointerDown!(e);\n },\n }),\n ...(moveProps.onMouseDown && {\n onMouseDown: (e: React.MouseEvent<HTMLDivElement>) => {\n if (shouldGateDrag(e.target)) return;\n hostRef.current?.focus({ preventScroll: true });\n moveProps.onMouseDown!(e);\n },\n }),\n ...(moveProps.onTouchStart && {\n onTouchStart: (e: React.TouchEvent<HTMLDivElement>) => {\n if (shouldGateDrag(e.target)) return;\n moveProps.onTouchStart!(e);\n },\n }),\n ...(moveProps.onKeyDown && {\n onKeyDown: (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.target !== e.currentTarget) return;\n handleSelectKeyDown(e);\n if (e.defaultPrevented) return;\n moveProps.onKeyDown!(e);\n },\n }),\n };\n\n // A non-draggable widget gets no `moveProps` at all, so its Space handling and\n // its focusability have to come from here instead.\n const selectionProps = isSelectable\n ? {\n onPointerDown: handleSelectPointerDown,\n // A draggable widget routes Space through the drag gate below, which\n // already enforces the host-focused rule; a non-draggable one gets no\n // `moveProps` at all and needs its own handler.\n ...(isDraggable ? {} : { onKeyDown: handleSelectKeyDown }),\n }\n : {};\n\n const handleResize = (\n axis: ResizeHandleAxis,\n phase: ResizePhase,\n dx: number,\n dy: number,\n ) => {\n if (phase === 'start') setIsResizing(true);\n else if (phase === 'end') setIsResizing(false);\n onResize(item.i, axis, phase, dx, dy);\n };\n\n const mods = {\n drag: isActiveDrag,\n draggable: isDraggable && !isActiveDrag,\n static: !!item.static,\n resizing: isResizing,\n card: isCard,\n hovered: isHovered,\n 'focus-visible': isFocusVisible,\n selected: isSelected,\n };\n\n const content = (\n <BoardHostContext.Provider value={hostValue}>\n {registration?.content}\n {isResizable && !item.static ? (\n <>\n {resizeHandles.map((axis) => (\n <ResizeHandle key={axis} axis={axis} onResize={handleResize} />\n ))}\n {resizeHandles.filter(isCornerAxis).map((axis) => (\n <GripElement\n key={`grip-${axis}`}\n data-axis={axis}\n mods={{ revealed: gripsRevealed }}\n aria-hidden=\"true\"\n />\n ))}\n {resizeHandles.filter(isEdgeAxis).map((axis) => (\n <EdgeGripElement\n key={`edge-grip-${axis}`}\n data-axis={axis}\n mods={{ revealed: gripsRevealed, resizing: isResizing }}\n aria-hidden=\"true\"\n >\n <div data-element=\"Dot\" />\n <div data-element=\"Dot\" />\n <div data-element=\"Dot\" />\n <div data-element=\"Dot\" />\n <div data-element=\"Dot\" />\n </EdgeGripElement>\n ))}\n </>\n ) : null}\n </BoardHostContext.Provider>\n );\n\n const pos = calcGridItemPosition(\n positionParams,\n item.x,\n item.y,\n item.w,\n item.h,\n );\n\n // While dragging with a pointer, the widget's visual floats in the shared\n // overlay so it is never clipped by an ancestor's `overflow: hidden`. The\n // gesture-owning element (the one carrying `moveProps`) must NOT be the node\n // that moves into the overlay: React Aria's `useMove` binds its pointer\n // move/end listeners relative to the node that received `onPointerDown`, and\n // relocating that node into the portal tears it down and mounts a fresh one\n // (inside a `pointerEvents: 'none'` layer), which can drop the in-flight\n // gesture. Instead we keep a stable, always-mounted in-grid host that owns the\n // gesture for its whole lifetime, and portal a separate, non-interactive\n // visual clone into the overlay.\n const overlayNode = registry.overlayRef.current;\n // Non-grabbed group members float too, from their own drag-start rect plus the\n // one shared gesture delta. Measuring them here would be wrong (the board is\n // mid-reflow); the registry measured every member once at drag start, which is\n // the only safe window.\n const memberRect = isDragMember\n ? dragState!.memberRects.get(item.i)\n : undefined;\n const floatInOverlay =\n !!overlayNode &&\n !!dragState &&\n dragState.pointerType !== 'keyboard' &&\n (useOverlay || (isDragMember && !!memberRect));\n\n // Where the floating clone sits. The grabbed widget tracks the live drag rect\n // directly; a member tracks its own start rect offset by the same delta, so\n // the block moves as one.\n const floatRect =\n floatInOverlay && dragState\n ? isActiveDrag || !memberRect\n ? dragState.rect\n : {\n left:\n memberRect.left +\n (dragState.rect.left - dragState.startRect.left),\n top:\n memberRect.top + (dragState.rect.top - dragState.startRect.top),\n width: memberRect.width,\n height: memberRect.height,\n }\n : null;\n\n const hostStyle: CSSProperties = {\n left: `${pos.left}px`,\n top: `${pos.top}px`,\n width: `${pos.width}px`,\n height: `${pos.height}px`,\n // Kept mounted but hidden while its clone floats, so the gesture stays live\n // on this node (the pointer listeners never get torn down).\n ...(floatInOverlay ? { opacity: 0, pointerEvents: 'none' } : null),\n };\n\n // The floating clone carries the \"drag\" affordance (raised shadow/z-index);\n // keep the hidden host flat. Keyboard drags (which never float) still\n // highlight the in-grid host, so only suppress `drag` when floating.\n const hostMods = { ...mods, drag: isActiveDrag && !floatInOverlay, settled };\n\n // The host is always rendered first, with a stable element shape, so React\n // reuses the same DOM node across the drag transition (never remounts it).\n const host = (\n <WidgetElement\n ref={hostRef}\n // Marks this element as a board widget host so the registry can find the\n // container widget a nested board lives in (used to keep a drag anchored to\n // a nested board while the anchor is still over its host - e.g. the Tabs\n // header above a nested board - instead of reflowing the ancestor board).\n data-board-widget-host=\"\"\n // Which widget, as opposed to \"am I inside a widget host\" - the two are\n // separate questions and the existing attribute is used as a presence\n // selector, so overloading it would make every such selector implicitly\n // value-dependent. Namespaced so it cannot collide with an app's own\n // `data-widget-id`.\n data-board-widget-id={item.i}\n {...mergeProps(\n // Before `gatedMoveProps`: the press selects, and only then does the\n // drag start and read that selection to decide what moves.\n selectionProps,\n gatedMoveProps,\n stopBubbleProps,\n hoverProps,\n focusProps,\n focusWithinProps,\n a11yProps,\n { style: hostStyle },\n )}\n qa={qa}\n mods={hostMods}\n styles={widgetStyles as Styles}\n >\n {floatInOverlay ? null : content}\n </WidgetElement>\n );\n\n const overlayClone = floatInOverlay\n ? createPortal(\n <WidgetElement\n style={{\n position: 'absolute',\n left: `${floatRect!.left}px`,\n top: `${floatRect!.top}px`,\n width: `${floatRect!.width}px`,\n height: `${floatRect!.height}px`,\n pointerEvents: 'none',\n }}\n mods={{ ...mods, drag: true, floating: true }}\n styles={widgetStyles as Styles}\n aria-hidden=\"true\"\n >\n {content}\n </WidgetElement>,\n overlayNode!,\n )\n : null;\n\n return (\n <>\n {host}\n {overlayClone}\n </>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"board-context.js","names":[],"sources":["../../../../src/components/layout/Board/board-context.tsx"],"sourcesContent":["import { createContext, MutableRefObject, useContext } from 'react';\n\nimport type { BoardWidgetStore } from './board-store';\nimport type {\n Compactor,\n LayoutConstraint,\n LayoutItem,\n PositionParams,\n} from './grid-core';\n\n/** A rectangle in viewport (client) coordinates. */\nexport interface ViewportRect {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\n/**\n * Everything the cross-board registry needs to read from / write to a single\n * board. Methods read live refs so a single stable entry can be registered once\n * per board and stay current across renders.\n */\nexport interface BoardEntry {\n id: string;\n /** Viewport rect of the content area where widgets are positioned. */\n getContentRect: () => DOMRect | null;\n /** The DOM node of the content area (used to detect nested-in-drag boards). */\n getContentNode: () => HTMLElement | null;\n getPositionParams: () => PositionParams;\n getConstraints: () => LayoutConstraint[];\n getCompactor: () => Compactor;\n getMaxRows: () => number;\n getContainerHeight: () => number;\n getLayout: () => LayoutItem[];\n /** Update the board layout. `commit` fires `onLayoutChange`. */\n applyLayout: (layout: LayoutItem[], commit: boolean) => void;\n
|
|
1
|
+
{"version":3,"file":"board-context.js","names":[],"sources":["../../../../src/components/layout/Board/board-context.tsx"],"sourcesContent":["import { createContext, MutableRefObject, useContext } from 'react';\n\nimport type { BoardWidgetStore } from './board-store';\nimport type {\n Compactor,\n LayoutConstraint,\n LayoutItem,\n PositionParams,\n} from './grid-core';\n\n/** A rectangle in viewport (client) coordinates. */\nexport interface ViewportRect {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\n/**\n * Everything the cross-board registry needs to read from / write to a single\n * board. Methods read live refs so a single stable entry can be registered once\n * per board and stay current across renders.\n */\nexport interface BoardEntry {\n id: string;\n /** Viewport rect of the content area where widgets are positioned. */\n getContentRect: () => DOMRect | null;\n /** The DOM node of the content area (used to detect nested-in-drag boards). */\n getContentNode: () => HTMLElement | null;\n getPositionParams: () => PositionParams;\n getConstraints: () => LayoutConstraint[];\n getCompactor: () => Compactor;\n getMaxRows: () => number;\n getContainerHeight: () => number;\n getLayout: () => LayoutItem[];\n /**\n * Keys of the widgets currently selected on this board, or `null` when the\n * board has no selection. Read at drag start to decide whether the gesture\n * moves one widget or a whole group.\n */\n getSelectedKeys: () => ReadonlySet<string> | null;\n /** Update the board layout. `commit` fires `onLayoutChange`. */\n applyLayout: (layout: LayoutItem[], commit: boolean) => void;\n /** Replace every drop-slot preview. Pass `[]` to clear. */\n setPlaceholders: (items: LayoutItem[]) => void;\n isDroppable: () => boolean;\n}\n\n/** Emitted when a widget is dropped from one board into another. */\nexport interface WidgetTransferInfo {\n widgetId: string;\n fromBoardId: string;\n toBoardId: string;\n item: LayoutItem;\n}\n\n/** Live drag state, shared across boards for overlay + placeholders. */\nexport interface BoardDragState {\n sourceBoardId: string;\n /** Board currently owning the dragged item (changes as it crosses boards). */\n currentBoardId: string;\n itemId: string;\n /** Snapshot of the dragged item (grid units; w/h preserved across boards). */\n item: LayoutItem;\n /**\n * Every widget moving in this gesture, the grabbed one first. Length 1 for an\n * ordinary drag, so `itemIds[0] === itemId` always holds and any check against\n * this set is a strict superset of the equivalent check against `itemId`.\n */\n itemIds: string[];\n /** Drag-start snapshots of `itemIds`, in the same order. */\n items: LayoutItem[];\n /** Dragged widget rect in viewport coordinates (follows the pointer). */\n rect: ViewportRect;\n /** `rect` as measured at drag start — lets any host derive the gesture delta. */\n startRect: ViewportRect;\n /**\n * Viewport rect of every group member's host, measured once at drag start.\n * Drag start is the only safe window to measure (see `frozenRectsRef` in the\n * registry); measuring later would feed the preview back into itself.\n */\n memberRects: Map<string, ViewportRect>;\n pointerType: string;\n /**\n * Ids of boards nested inside the dragged widget, captured at drag start.\n * Such a board is never a drop target, and it suppresses its own grid-line\n * overlay while its host widget is being dragged (the whole widget floats, so\n * the inner grid lines would only add clutter).\n */\n nestedBoardIds: Set<string>;\n}\n\nexport interface BoardRegistryContextValue {\n store: BoardWidgetStore;\n overlayRef: MutableRefObject<HTMLDivElement | null>;\n registerBoard: (entry: BoardEntry) => () => void;\n onDragStart: (\n boardId: string,\n itemId: string,\n rect: ViewportRect,\n pointerType: string,\n /** The dragged widget's host node, used to exclude boards nested inside it. */\n widgetNode: HTMLElement | null,\n ) => void;\n onDragMove: (deltaX: number, deltaY: number, pointerType: string) => void;\n onDragEnd: () => void;\n dragState: BoardDragState | null;\n /**\n * Synchronously-updated mirror of `dragState`. `dragState` is React state, so\n * a handler running in the same tick as `onDragStart` — such as the drag\n * lifecycle `WidgetHost` fires immediately afterwards — still sees the\n * previous value and must read this instead.\n */\n getDragState: () => BoardDragState | null;\n}\n\nexport const BoardRegistryContext =\n createContext<BoardRegistryContextValue | null>(null);\n\nexport function useBoardRegistry(): BoardRegistryContextValue | null {\n return useContext(BoardRegistryContext);\n}\n\n/**\n * A stable boolean signalling whether a Board widget is currently being\n * dragged. Provided by `BoardProvider` (and therefore by any standalone\n * `Board`, which self-wraps in one). Unlike the full `dragState`, this only\n * flips on drag start/end, so components that only care about \"is a drag in\n * progress\" (e.g. `Tabs` spring-loading a tab on hover) can subscribe without\n * re-rendering on every pointer move. Defaults to `false` outside any Board.\n */\nexport const BoardDragActiveContext = createContext<boolean>(false);\n\nexport function useBoardDragActive(): boolean {\n return useContext(BoardDragActiveContext);\n}\n\n/**\n * Whether an ancestor `Board` has its grid-line overlay enabled. A nested board\n * that does not set `showGridLines` explicitly reads this to inherit the\n * behaviour, showing its own grid lines while a drag is in progress. Defaults to\n * `false` outside any grid-lined board.\n */\nexport const BoardGridLinesContext = createContext<boolean>(false);\n\nexport function useBoardGridLines(): boolean {\n return useContext(BoardGridLinesContext);\n}\n\n/**\n * The resolved grid metrics a `Board` exposes to any boards nested inside its\n * widgets. A nested board with `isAligned` reads these to inherit the parent's\n * column pitch (column width + horizontal margin) and target row height, so its\n * cells line up with the surrounding layout instead of stretching.\n */\nexport interface BoardMetrics {\n /** Resolved pixel width of one parent column. */\n colWidth: number;\n /** Resolved parent row height in pixels (the alignment target). */\n rowHeight: number;\n /** Parent [horizontal, vertical] margin between widgets in pixels. */\n margin: readonly [number, number];\n /** Parent [horizontal, vertical] container padding in pixels. */\n containerPadding: readonly [number, number];\n}\n\nexport const BoardMetricsContext = createContext<BoardMetrics | null>(null);\n\nexport function useBoardMetrics(): BoardMetrics | null {\n return useContext(BoardMetricsContext);\n}\n\n/**\n * Information a `WidgetHost` exposes to the content it renders (including a\n * nested `Board`). Lets a nested board know whether its host widget auto-sizes\n * its height and, if so, ask the host to grow to fit the board's natural size.\n */\nexport interface BoardHost {\n /** Whether the host widget grows its height to fit its content. */\n isAutoHeight: boolean;\n /**\n * Ask the host widget to grow so it provides `px` more content height. Only\n * ever increases the host's height. No-op when the host does not auto-size.\n */\n requestHeightDeficit: (px: number) => void;\n}\n\nexport const BoardHostContext = createContext<BoardHost | null>(null);\n\nexport function useBoardHost(): BoardHost | null {\n return useContext(BoardHostContext);\n}\n"],"mappings":";;;;AAoHA,MAAa,uBACX,cAAgD,KAAK;AAEvD,SAAgB,mBAAqD;AACnE,QAAO,WAAW,qBAAqB;;;;;;;;;;AAWzC,MAAa,yBAAyB,cAAuB,MAAM;AAEnE,SAAgB,qBAA8B;AAC5C,QAAO,WAAW,uBAAuB;;;;;;;;AAS3C,MAAa,wBAAwB,cAAuB,MAAM;AAElE,SAAgB,oBAA6B;AAC3C,QAAO,WAAW,sBAAsB;;AAoB1C,MAAa,sBAAsB,cAAmC,KAAK;AAE3E,SAAgB,kBAAuC;AACrD,QAAO,WAAW,oBAAoB;;AAkBxC,MAAa,mBAAmB,cAAgC,KAAK;AAErE,SAAgB,eAAiC;AAC/C,QAAO,WAAW,iBAAiB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.156.0 | Cube Dev Team */
|
|
2
2
|
//#region src/components/layout/Board/board-store.ts
|
|
3
3
|
/**
|
|
4
4
|
* A tiny external store mapping widget id -> registration.
|
|
@@ -16,7 +16,7 @@ var BoardWidgetStore = class {
|
|
|
16
16
|
const prev = this.map.get(reg.id);
|
|
17
17
|
this.map.set(reg.id, reg);
|
|
18
18
|
this.owners.set(reg.id, owner);
|
|
19
|
-
if (!prev || prev.content !== reg.content || prev.isDraggable !== reg.isDraggable || prev.isResizable !== reg.isResizable || prev.resizeHandles !== reg.resizeHandles || prev.isCard !== reg.isCard || prev.minW !== reg.minW || prev.maxW !== reg.maxW || prev.minH !== reg.minH || prev.maxH !== reg.maxH || prev.constraints !== reg.constraints || prev.qa !== reg.qa || prev.styles !== reg.styles || prev.isAutoHeight !== reg.isAutoHeight || prev.dragCancel !== reg.dragCancel || prev.dragHandle !== reg.dragHandle) {
|
|
19
|
+
if (!prev || prev.content !== reg.content || prev.isDraggable !== reg.isDraggable || prev.isResizable !== reg.isResizable || prev.resizeHandles !== reg.resizeHandles || prev.isCard !== reg.isCard || prev.minW !== reg.minW || prev.maxW !== reg.maxW || prev.minH !== reg.minH || prev.maxH !== reg.maxH || prev.constraints !== reg.constraints || prev.qa !== reg.qa || prev.styles !== reg.styles || prev.isAutoHeight !== reg.isAutoHeight || prev.dragCancel !== reg.dragCancel || prev.dragHandle !== reg.dragHandle || prev.isSelectable !== reg.isSelectable || prev.selectionCancel !== reg.selectionCancel || prev["aria-label"] !== reg["aria-label"]) {
|
|
20
20
|
this.version++;
|
|
21
21
|
this.emit();
|
|
22
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"board-store.js","names":[],"sources":["../../../../src/components/layout/Board/board-store.ts"],"sourcesContent":["import type { Styles } from '@tenphi/tasty';\nimport type { ReactNode } from 'react';\nimport type { LayoutConstraint, ResizeHandleAxis } from './grid-core';\n\n/**\n * Declarative registration for a single widget.\n *\n * Widget *content* is decoupled from widget *position*: content is registered\n * here by `Board.Widget` keyed by id, while positioning/ownership lives in a\n * board's layout state. This decoupling is what allows a widget to be hosted\n * (and transferred) between different boards under the same `BoardProvider`.\n */\nexport interface WidgetRegistration {\n id: string;\n content: ReactNode;\n isDraggable?: boolean;\n isResizable?: boolean;\n resizeHandles?: ResizeHandleAxis[];\n /**\n * Add a card border to this widget (widgets are always filled and rounded).\n * Falls back to the owning board's `widgetProps.isCard` when unset here.\n */\n isCard?: boolean;\n /** Minimum width in grid columns (fallback when the layout item omits `minW`). */\n minW?: number;\n /** Maximum width in grid columns (fallback when the layout item omits `maxW`). */\n maxW?: number;\n /** Minimum height in grid rows (fallback when the layout item omits `minH`). */\n minH?: number;\n /** Maximum height in grid rows (fallback when the layout item omits `maxH`). */\n maxH?: number;\n constraints?: LayoutConstraint[];\n qa?: string;\n styles?: Styles;\n /** Grow this widget's height to fit its content (only ever increases). */\n isAutoHeight?: boolean;\n /** Override the board's `dragCancel` selector for this widget. */\n dragCancel?: string;\n /** Override the board's `dragHandle` selector for this widget. */\n dragHandle?: string;\n}\n\n/**\n * A tiny external store mapping widget id -> registration.\n *\n * Boards read from it via `useSyncExternalStore`, so a change to any widget's\n * content or config re-renders the hosting board without prop drilling through\n * the (possibly cross-board) tree.\n */\nexport class BoardWidgetStore {\n private map = new Map<string, WidgetRegistration>();\n // Tracks which mounted `Board.Widget` instance currently owns each id. This\n // guards against a stale unregister from an unmounting instance clobbering a\n // freshly-mounted instance's registration - which happens when a widget's\n // subtree is relocated (e.g. dragging a container widget that hosts a nested\n // board moves it into the overlay portal, remounting the inner widgets).\n private owners = new Map<string, object>();\n private listeners = new Set<() => void>();\n private version = 0;\n\n register(reg: WidgetRegistration, owner: object): void {\n const prev = this.map.get(reg.id);\n this.map.set(reg.id, reg);\n this.owners.set(reg.id, owner);\n\n // Notify on any reference change. The hosting board reads registrations\n // during render, but `Board.Widget` registers in a layout effect (after\n // commit), so a content/config change lands one commit late and would never\n // be shown without an emit. Reference comparison is loop-safe: a board's own\n // re-render reuses the same `children` element references from its\n // (un-rerendered) parent, so `content` only differs on a genuine parent\n // update -> we emit once and then settle.\n const changed =\n !prev ||\n prev.content !== reg.content ||\n prev.isDraggable !== reg.isDraggable ||\n prev.isResizable !== reg.isResizable ||\n prev.resizeHandles !== reg.resizeHandles ||\n prev.isCard !== reg.isCard ||\n prev.minW !== reg.minW ||\n prev.maxW !== reg.maxW ||\n prev.minH !== reg.minH ||\n prev.maxH !== reg.maxH ||\n prev.constraints !== reg.constraints ||\n prev.qa !== reg.qa ||\n prev.styles !== reg.styles ||\n prev.isAutoHeight !== reg.isAutoHeight ||\n prev.dragCancel !== reg.dragCancel ||\n prev.dragHandle !== reg.dragHandle;\n\n if (changed) {\n this.version++;\n this.emit();\n }\n }\n\n unregister(id: string, owner: object): void {\n // Ignore unregister calls from an instance that no longer owns the id (a\n // newer instance has already taken over).\n if (this.owners.get(id) !== owner) return;\n\n this.owners.delete(id);\n if (this.map.delete(id)) {\n this.version++;\n this.emit();\n }\n }\n\n get(id: string): WidgetRegistration | undefined {\n return this.map.get(id);\n }\n\n getVersion = (): number => this.version;\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n private emit(): void {\n this.listeners.forEach((listener) => listener());\n }\n}\n"],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"board-store.js","names":[],"sources":["../../../../src/components/layout/Board/board-store.ts"],"sourcesContent":["import type { Styles } from '@tenphi/tasty';\nimport type { ReactNode } from 'react';\nimport type { LayoutConstraint, ResizeHandleAxis } from './grid-core';\n\n/**\n * Declarative registration for a single widget.\n *\n * Widget *content* is decoupled from widget *position*: content is registered\n * here by `Board.Widget` keyed by id, while positioning/ownership lives in a\n * board's layout state. This decoupling is what allows a widget to be hosted\n * (and transferred) between different boards under the same `BoardProvider`.\n */\nexport interface WidgetRegistration {\n id: string;\n content: ReactNode;\n isDraggable?: boolean;\n isResizable?: boolean;\n resizeHandles?: ResizeHandleAxis[];\n /**\n * Add a card border to this widget (widgets are always filled and rounded).\n * Falls back to the owning board's `widgetProps.isCard` when unset here.\n */\n isCard?: boolean;\n /** Minimum width in grid columns (fallback when the layout item omits `minW`). */\n minW?: number;\n /** Maximum width in grid columns (fallback when the layout item omits `maxW`). */\n maxW?: number;\n /** Minimum height in grid rows (fallback when the layout item omits `minH`). */\n minH?: number;\n /** Maximum height in grid rows (fallback when the layout item omits `maxH`). */\n maxH?: number;\n constraints?: LayoutConstraint[];\n qa?: string;\n styles?: Styles;\n /** Grow this widget's height to fit its content (only ever increases). */\n isAutoHeight?: boolean;\n /** Override the board's `dragCancel` selector for this widget. */\n dragCancel?: string;\n /** Override the board's `dragHandle` selector for this widget. */\n dragHandle?: string;\n /** Disable selection for this widget while the board's selection is on. */\n isSelectable?: boolean;\n /** Override the board's `selectionCancel` selector for this widget. */\n selectionCancel?: string;\n /** Accessible name; falls back to `qa`, then the layout item id. */\n 'aria-label'?: string;\n}\n\n/**\n * A tiny external store mapping widget id -> registration.\n *\n * Boards read from it via `useSyncExternalStore`, so a change to any widget's\n * content or config re-renders the hosting board without prop drilling through\n * the (possibly cross-board) tree.\n */\nexport class BoardWidgetStore {\n private map = new Map<string, WidgetRegistration>();\n // Tracks which mounted `Board.Widget` instance currently owns each id. This\n // guards against a stale unregister from an unmounting instance clobbering a\n // freshly-mounted instance's registration - which happens when a widget's\n // subtree is relocated (e.g. dragging a container widget that hosts a nested\n // board moves it into the overlay portal, remounting the inner widgets).\n private owners = new Map<string, object>();\n private listeners = new Set<() => void>();\n private version = 0;\n\n register(reg: WidgetRegistration, owner: object): void {\n const prev = this.map.get(reg.id);\n this.map.set(reg.id, reg);\n this.owners.set(reg.id, owner);\n\n // Notify on any reference change. The hosting board reads registrations\n // during render, but `Board.Widget` registers in a layout effect (after\n // commit), so a content/config change lands one commit late and would never\n // be shown without an emit. Reference comparison is loop-safe: a board's own\n // re-render reuses the same `children` element references from its\n // (un-rerendered) parent, so `content` only differs on a genuine parent\n // update -> we emit once and then settle.\n const changed =\n !prev ||\n prev.content !== reg.content ||\n prev.isDraggable !== reg.isDraggable ||\n prev.isResizable !== reg.isResizable ||\n prev.resizeHandles !== reg.resizeHandles ||\n prev.isCard !== reg.isCard ||\n prev.minW !== reg.minW ||\n prev.maxW !== reg.maxW ||\n prev.minH !== reg.minH ||\n prev.maxH !== reg.maxH ||\n prev.constraints !== reg.constraints ||\n prev.qa !== reg.qa ||\n prev.styles !== reg.styles ||\n prev.isAutoHeight !== reg.isAutoHeight ||\n prev.dragCancel !== reg.dragCancel ||\n prev.dragHandle !== reg.dragHandle ||\n prev.isSelectable !== reg.isSelectable ||\n prev.selectionCancel !== reg.selectionCancel ||\n prev['aria-label'] !== reg['aria-label'];\n\n if (changed) {\n this.version++;\n this.emit();\n }\n }\n\n unregister(id: string, owner: object): void {\n // Ignore unregister calls from an instance that no longer owns the id (a\n // newer instance has already taken over).\n if (this.owners.get(id) !== owner) return;\n\n this.owners.delete(id);\n if (this.map.delete(id)) {\n this.version++;\n this.emit();\n }\n }\n\n get(id: string): WidgetRegistration | undefined {\n return this.map.get(id);\n }\n\n getVersion = (): number => this.version;\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n private emit(): void {\n this.listeners.forEach((listener) => listener());\n }\n}\n"],"mappings":";;;;;;;;;AAuDA,IAAa,mBAAb,MAA8B;CAC5B,AAAQ,sBAAM,IAAI,KAAiC;CAMnD,AAAQ,yBAAS,IAAI,KAAqB;CAC1C,AAAQ,4BAAY,IAAI,KAAiB;CACzC,AAAQ,UAAU;CAElB,SAAS,KAAyB,OAAqB;EACrD,MAAM,OAAO,KAAK,IAAI,IAAI,IAAI,GAAG;AACjC,OAAK,IAAI,IAAI,IAAI,IAAI,IAAI;AACzB,OAAK,OAAO,IAAI,IAAI,IAAI,MAAM;AA8B9B,MApBE,CAAC,QACD,KAAK,YAAY,IAAI,WACrB,KAAK,gBAAgB,IAAI,eACzB,KAAK,gBAAgB,IAAI,eACzB,KAAK,kBAAkB,IAAI,iBAC3B,KAAK,WAAW,IAAI,UACpB,KAAK,SAAS,IAAI,QAClB,KAAK,SAAS,IAAI,QAClB,KAAK,SAAS,IAAI,QAClB,KAAK,SAAS,IAAI,QAClB,KAAK,gBAAgB,IAAI,eACzB,KAAK,OAAO,IAAI,MAChB,KAAK,WAAW,IAAI,UACpB,KAAK,iBAAiB,IAAI,gBAC1B,KAAK,eAAe,IAAI,cACxB,KAAK,eAAe,IAAI,cACxB,KAAK,iBAAiB,IAAI,gBAC1B,KAAK,oBAAoB,IAAI,mBAC7B,KAAK,kBAAkB,IAAI,eAEhB;AACX,QAAK;AACL,QAAK,MAAM;;;CAIf,WAAW,IAAY,OAAqB;AAG1C,MAAI,KAAK,OAAO,IAAI,GAAG,KAAK,MAAO;AAEnC,OAAK,OAAO,OAAO,GAAG;AACtB,MAAI,KAAK,IAAI,OAAO,GAAG,EAAE;AACvB,QAAK;AACL,QAAK,MAAM;;;CAIf,IAAI,IAA4C;AAC9C,SAAO,KAAK,IAAI,IAAI,GAAG;;CAGzB,mBAA2B,KAAK;CAEhC,aAAa,aAAuC;AAClD,OAAK,UAAU,IAAI,SAAS;AAC5B,eAAa;AACX,QAAK,UAAU,OAAO,SAAS;;;CAInC,AAAQ,OAAa;AACnB,OAAK,UAAU,SAAS,aAAa,UAAU,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.156.0 | Cube Dev Team */
|
|
2
2
|
//#region src/components/layout/Board/grid-core/calculate.ts
|
|
3
3
|
/** Calculate the width of a single grid column in pixels. */
|
|
4
4
|
function calcGridColWidth(positionParams) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.156.0 | Cube Dev Team */
|
|
2
2
|
import { collides, getFirstCollision } from "./collision.js";
|
|
3
3
|
import { sortLayoutItemsByColRow, sortLayoutItemsByRowCol } from "./sort.js";
|
|
4
4
|
import { bottom, cloneLayout, cloneLayoutItem, getStatics } from "./layout.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.156.0 | Cube Dev Team */
|
|
2
2
|
//#region src/components/layout/Board/grid-core/constraints.ts
|
|
3
3
|
function clamp(value, min, max) {
|
|
4
4
|
return Math.max(min, Math.min(max, value));
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.156.0 | Cube Dev Team */
|
|
2
|
+
import { collides, getFirstCollision } from "./collision.js";
|
|
3
|
+
import { bottom, cloneLayout } from "./layout.js";
|
|
4
|
+
|
|
5
|
+
//#region src/components/layout/Board/grid-core/group-move.ts
|
|
6
|
+
/**
|
|
7
|
+
* Rigid multi-item movement.
|
|
8
|
+
*
|
|
9
|
+
* `moveElement` (see ./layout.ts) moves exactly one item and is free to displace
|
|
10
|
+
* any other item — including one the caller also wanted to move — as a collision
|
|
11
|
+
* victim. That makes it unusable for moving a *selection* as a block: the shape
|
|
12
|
+
* of the group would be destroyed by the very collision resolution meant to make
|
|
13
|
+
* room for it.
|
|
14
|
+
*
|
|
15
|
+
* `moveElements` moves a set of items rigidly instead. Every mover receives the
|
|
16
|
+
* same `(dx, dy)`, so the group's shape is invariant *by construction* rather
|
|
17
|
+
* than by repair.
|
|
18
|
+
*
|
|
19
|
+
* This module is UI-Kit-specific; it is not part of the vendored react-grid-layout
|
|
20
|
+
* core (see ./NOTICE.md).
|
|
21
|
+
*/
|
|
22
|
+
/** An item may be moved unless it is static and does not opt back in. */
|
|
23
|
+
function isMovable(item) {
|
|
24
|
+
return !item.static || item.isDraggable === true;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Move every item in `ids` by the same delta, resolving collisions with the
|
|
28
|
+
* items that are *not* moving.
|
|
29
|
+
*
|
|
30
|
+
* Semantics, all deliberate:
|
|
31
|
+
*
|
|
32
|
+
* - **Group-clamped, not item-clamped.** The delta is clamped once against the
|
|
33
|
+
* whole group, so dragging into an edge parks the block against it. Clamping
|
|
34
|
+
* each item into bounds separately would collapse the group's shape the first
|
|
35
|
+
* time it touched a wall, and it would never recover.
|
|
36
|
+
* - **All-or-nothing.** If the frame cannot be resolved, nothing moves.
|
|
37
|
+
* - **Movers never collide with each other.** They keep their relative
|
|
38
|
+
* positions, so only mover↔non-mover and non-mover↔non-mover overlaps resolve.
|
|
39
|
+
* - **A static item is never a mover**, matching `moveElement`'s own guard, and
|
|
40
|
+
* a mover can never displace a static item — that frame is rejected instead.
|
|
41
|
+
*
|
|
42
|
+
* Returns a new layout in the input's item order; the input is never mutated.
|
|
43
|
+
*/
|
|
44
|
+
function moveElements(layout, ids, dx, dy, options) {
|
|
45
|
+
const { compactor, cols, maxRows = Infinity } = options;
|
|
46
|
+
const working = cloneLayout(layout);
|
|
47
|
+
const movers = working.filter((it) => ids.has(it.i) && isMovable(it));
|
|
48
|
+
if (movers.length === 0) return {
|
|
49
|
+
layout: working,
|
|
50
|
+
dx: 0,
|
|
51
|
+
dy: 0,
|
|
52
|
+
moved: false
|
|
53
|
+
};
|
|
54
|
+
const moverIds = new Set(movers.map((it) => it.i));
|
|
55
|
+
const others = working.filter((it) => !moverIds.has(it.i));
|
|
56
|
+
let minDx = -Infinity;
|
|
57
|
+
let maxDx = Infinity;
|
|
58
|
+
let minDy = -Infinity;
|
|
59
|
+
let maxDy = Infinity;
|
|
60
|
+
for (const it of movers) {
|
|
61
|
+
minDx = Math.max(minDx, -it.x);
|
|
62
|
+
maxDx = Math.min(maxDx, cols - it.w - it.x);
|
|
63
|
+
minDy = Math.max(minDy, -it.y);
|
|
64
|
+
maxDy = Math.min(maxDy, maxRows - it.h - it.y);
|
|
65
|
+
}
|
|
66
|
+
maxDx = Math.max(minDx, maxDx);
|
|
67
|
+
maxDy = Math.max(minDy, maxDy);
|
|
68
|
+
const clampedDx = Math.min(Math.max(dx, minDx), maxDx) || 0;
|
|
69
|
+
const clampedDy = Math.min(Math.max(dy, minDy), maxDy) || 0;
|
|
70
|
+
for (const it of movers) {
|
|
71
|
+
it.x = it.x + clampedDx;
|
|
72
|
+
it.y = it.y + clampedDy;
|
|
73
|
+
}
|
|
74
|
+
const rejected = {
|
|
75
|
+
layout: cloneLayout(layout),
|
|
76
|
+
dx: 0,
|
|
77
|
+
dy: 0,
|
|
78
|
+
moved: false
|
|
79
|
+
};
|
|
80
|
+
if (!compactor.allowOverlap) {
|
|
81
|
+
for (const it of others) if (it.static && getFirstCollision(movers, it)) return rejected;
|
|
82
|
+
if (compactor.preventCollision) {
|
|
83
|
+
for (const it of movers) if (getFirstCollision(others, it)) return rejected;
|
|
84
|
+
} else if (compactor.type === null && !pushOthersDown(movers, others)) return rejected;
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
layout: [...compactor.compact(working, cols)],
|
|
88
|
+
dx: clampedDx,
|
|
89
|
+
dy: clampedDy,
|
|
90
|
+
moved: true
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Push every non-mover that overlaps the group (or another displaced item)
|
|
95
|
+
* straight down until nothing overlaps.
|
|
96
|
+
*
|
|
97
|
+
* Down, always — even under horizontal compaction. Downward is the one direction
|
|
98
|
+
* a grid always has room in, so the pass is guaranteed to terminate; the
|
|
99
|
+
* compactor then re-packs along its own axis immediately afterwards. Pushing
|
|
100
|
+
* sideways would need overflow wrapping here and could ping-pong an item between
|
|
101
|
+
* two neighbours.
|
|
102
|
+
*
|
|
103
|
+
* Mutates `others` in place. Returns `false` if the cascade fails to settle,
|
|
104
|
+
* which the caller turns into a rejected frame.
|
|
105
|
+
*/
|
|
106
|
+
function pushOthersDown(movers, others) {
|
|
107
|
+
const ordered = [...others].sort((a, b) => a.y === b.y ? a.x - b.x : a.y - b.y);
|
|
108
|
+
const placed = [...movers];
|
|
109
|
+
const limit = bottom(movers) + bottom(others) + others.length + 1;
|
|
110
|
+
for (const item of ordered) {
|
|
111
|
+
if (item.static) {
|
|
112
|
+
placed.push(item);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
let steps = 0;
|
|
116
|
+
let shifted = true;
|
|
117
|
+
while (shifted) {
|
|
118
|
+
shifted = false;
|
|
119
|
+
for (const other of placed) if (collides(item, other)) {
|
|
120
|
+
item.y = other.y + other.h;
|
|
121
|
+
shifted = true;
|
|
122
|
+
}
|
|
123
|
+
if (++steps > limit) return false;
|
|
124
|
+
}
|
|
125
|
+
placed.push(item);
|
|
126
|
+
}
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
//#endregion
|
|
131
|
+
export { moveElements };
|
|
132
|
+
//# sourceMappingURL=group-move.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group-move.js","names":[],"sources":["../../../../../src/components/layout/Board/grid-core/group-move.ts"],"sourcesContent":["/**\n * Rigid multi-item movement.\n *\n * `moveElement` (see ./layout.ts) moves exactly one item and is free to displace\n * any other item — including one the caller also wanted to move — as a collision\n * victim. That makes it unusable for moving a *selection* as a block: the shape\n * of the group would be destroyed by the very collision resolution meant to make\n * room for it.\n *\n * `moveElements` moves a set of items rigidly instead. Every mover receives the\n * same `(dx, dy)`, so the group's shape is invariant *by construction* rather\n * than by repair.\n *\n * This module is UI-Kit-specific; it is not part of the vendored react-grid-layout\n * core (see ./NOTICE.md).\n */\n\nimport { collides, getFirstCollision } from './collision';\nimport { bottom, cloneLayout } from './layout';\n\nimport type { Compactor, Layout, LayoutItem, Mutable } from './types';\n\nexport interface MoveElementsOptions {\n /**\n * The board's compactor. Supplies `type`, `allowOverlap` and\n * `preventCollision` as one consistent unit, and performs the tidy-up pass —\n * taking it whole is what keeps this function from ever disagreeing with the\n * board about compaction mode.\n */\n compactor: Compactor;\n cols: number;\n /** @default Infinity */\n maxRows?: number;\n}\n\nexport interface MoveElementsResult {\n layout: LayoutItem[];\n /** The delta actually applied, after clamping the group to the grid. */\n dx: number;\n dy: number;\n /**\n * Whether a valid arrangement was produced. `false` means the frame must be\n * discarded and the previous one kept — never partially applied, since a\n * partial delta is precisely what shears the group apart.\n */\n moved: boolean;\n}\n\n/** An item may be moved unless it is static and does not opt back in. */\nfunction isMovable(item: LayoutItem): boolean {\n return !item.static || item.isDraggable === true;\n}\n\n/**\n * Move every item in `ids` by the same delta, resolving collisions with the\n * items that are *not* moving.\n *\n * Semantics, all deliberate:\n *\n * - **Group-clamped, not item-clamped.** The delta is clamped once against the\n * whole group, so dragging into an edge parks the block against it. Clamping\n * each item into bounds separately would collapse the group's shape the first\n * time it touched a wall, and it would never recover.\n * - **All-or-nothing.** If the frame cannot be resolved, nothing moves.\n * - **Movers never collide with each other.** They keep their relative\n * positions, so only mover↔non-mover and non-mover↔non-mover overlaps resolve.\n * - **A static item is never a mover**, matching `moveElement`'s own guard, and\n * a mover can never displace a static item — that frame is rejected instead.\n *\n * Returns a new layout in the input's item order; the input is never mutated.\n */\nexport function moveElements(\n layout: Layout,\n ids: ReadonlySet<string>,\n dx: number,\n dy: number,\n options: MoveElementsOptions,\n): MoveElementsResult {\n const { compactor, cols, maxRows = Infinity } = options;\n\n const working = cloneLayout(layout);\n const movers = working.filter((it) => ids.has(it.i) && isMovable(it));\n\n if (movers.length === 0) {\n return { layout: working, dx: 0, dy: 0, moved: false };\n }\n\n const moverIds = new Set(movers.map((it) => it.i));\n const others = working.filter((it) => !moverIds.has(it.i));\n\n // ---- Clamp the delta to the group ----------------------------------------\n //\n // The group can travel until its *first* item hits an edge. `Math.max` on the\n // upper bounds guards the degenerate case of an item wider/taller than the\n // grid, where the max would otherwise fall below the min and invert the range.\n let minDx = -Infinity;\n let maxDx = Infinity;\n let minDy = -Infinity;\n let maxDy = Infinity;\n\n for (const it of movers) {\n minDx = Math.max(minDx, -it.x);\n maxDx = Math.min(maxDx, cols - it.w - it.x);\n minDy = Math.max(minDy, -it.y);\n maxDy = Math.min(maxDy, maxRows - it.h - it.y);\n }\n maxDx = Math.max(minDx, maxDx);\n maxDy = Math.max(minDy, maxDy);\n\n // `|| 0` collapses `-0`, which `Math.max` produces whenever a mover sits at\n // coordinate 0. It compares equal to `0` but not under `Object.is`, and it\n // would otherwise be handed back to callers as a delta.\n const clampedDx = Math.min(Math.max(dx, minDx), maxDx) || 0;\n const clampedDy = Math.min(Math.max(dy, minDy), maxDy) || 0;\n\n for (const it of movers) {\n (it as Mutable<LayoutItem>).x = it.x + clampedDx;\n (it as Mutable<LayoutItem>).y = it.y + clampedDy;\n }\n\n const rejected: MoveElementsResult = {\n layout: cloneLayout(layout),\n dx: 0,\n dy: 0,\n moved: false,\n };\n\n if (!compactor.allowOverlap) {\n // A static non-mover cannot be pushed out of the way, so overlapping one is\n // never resolvable.\n for (const it of others) {\n if (it.static && getFirstCollision(movers, it)) {\n return rejected;\n }\n }\n\n if (compactor.preventCollision) {\n // `compact=\"free\"` / legacy no-compaction with collisions prevented: the\n // group may only land where it fits outright.\n for (const it of movers) {\n if (getFirstCollision(others, it)) {\n return rejected;\n }\n }\n } else if (compactor.type === null && !pushOthersDown(movers, others)) {\n // Only when nothing else will: a compacting compactor resolves overlaps\n // itself (and floats items back up afterwards), so pre-pushing there just\n // shoves neighbours further than needed and makes the board look like it\n // is lagging a step behind the pointer.\n return rejected;\n }\n }\n\n // Compact exactly as the single-widget path does — the group is not held in\n // place. On a vertically-compacted board a lone widget can never be parked in\n // empty space, and a group must not be able to either: neighbours have to\n // close the gap the moment it opens, or the board reads as a step behind.\n const out = [...compactor.compact(working, cols)];\n\n return { layout: out, dx: clampedDx, dy: clampedDy, moved: true };\n}\n\n/**\n * Push every non-mover that overlaps the group (or another displaced item)\n * straight down until nothing overlaps.\n *\n * Down, always — even under horizontal compaction. Downward is the one direction\n * a grid always has room in, so the pass is guaranteed to terminate; the\n * compactor then re-packs along its own axis immediately afterwards. Pushing\n * sideways would need overflow wrapping here and could ping-pong an item between\n * two neighbours.\n *\n * Mutates `others` in place. Returns `false` if the cascade fails to settle,\n * which the caller turns into a rejected frame.\n */\nfunction pushOthersDown(movers: LayoutItem[], others: LayoutItem[]): boolean {\n // Place one at a time, in reading order, against a set that starts as the\n // group. Each push moves an item strictly past a placed item's bottom edge, so\n // it advances monotonically and the loop is bounded by the stack height.\n const ordered = [...others].sort((a, b) =>\n a.y === b.y ? a.x - b.x : a.y - b.y,\n );\n const placed: LayoutItem[] = [...movers];\n const limit = bottom(movers) + bottom(others) + others.length + 1;\n\n for (const item of ordered) {\n if (item.static) {\n // Verified collision-free against the movers by the caller; other statics\n // are pre-existing and not ours to resolve.\n placed.push(item);\n continue;\n }\n\n let steps = 0;\n let shifted = true;\n\n while (shifted) {\n shifted = false;\n for (const other of placed) {\n if (collides(item, other)) {\n (item as Mutable<LayoutItem>).y = other.y + other.h;\n shifted = true;\n }\n }\n if (++steps > limit) {\n return false;\n }\n }\n\n placed.push(item);\n }\n\n return true;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAiDA,SAAS,UAAU,MAA2B;AAC5C,QAAO,CAAC,KAAK,UAAU,KAAK,gBAAgB;;;;;;;;;;;;;;;;;;;;AAqB9C,SAAgB,aACd,QACA,KACA,IACA,IACA,SACoB;CACpB,MAAM,EAAE,WAAW,MAAM,UAAU,aAAa;CAEhD,MAAM,UAAU,YAAY,OAAO;CACnC,MAAM,SAAS,QAAQ,QAAQ,OAAO,IAAI,IAAI,GAAG,EAAE,IAAI,UAAU,GAAG,CAAC;AAErE,KAAI,OAAO,WAAW,EACpB,QAAO;EAAE,QAAQ;EAAS,IAAI;EAAG,IAAI;EAAG,OAAO;EAAO;CAGxD,MAAM,WAAW,IAAI,IAAI,OAAO,KAAK,OAAO,GAAG,EAAE,CAAC;CAClD,MAAM,SAAS,QAAQ,QAAQ,OAAO,CAAC,SAAS,IAAI,GAAG,EAAE,CAAC;CAO1D,IAAI,QAAQ;CACZ,IAAI,QAAQ;CACZ,IAAI,QAAQ;CACZ,IAAI,QAAQ;AAEZ,MAAK,MAAM,MAAM,QAAQ;AACvB,UAAQ,KAAK,IAAI,OAAO,CAAC,GAAG,EAAE;AAC9B,UAAQ,KAAK,IAAI,OAAO,OAAO,GAAG,IAAI,GAAG,EAAE;AAC3C,UAAQ,KAAK,IAAI,OAAO,CAAC,GAAG,EAAE;AAC9B,UAAQ,KAAK,IAAI,OAAO,UAAU,GAAG,IAAI,GAAG,EAAE;;AAEhD,SAAQ,KAAK,IAAI,OAAO,MAAM;AAC9B,SAAQ,KAAK,IAAI,OAAO,MAAM;CAK9B,MAAM,YAAY,KAAK,IAAI,KAAK,IAAI,IAAI,MAAM,EAAE,MAAM,IAAI;CAC1D,MAAM,YAAY,KAAK,IAAI,KAAK,IAAI,IAAI,MAAM,EAAE,MAAM,IAAI;AAE1D,MAAK,MAAM,MAAM,QAAQ;AACvB,EAAC,GAA2B,IAAI,GAAG,IAAI;AACvC,EAAC,GAA2B,IAAI,GAAG,IAAI;;CAGzC,MAAM,WAA+B;EACnC,QAAQ,YAAY,OAAO;EAC3B,IAAI;EACJ,IAAI;EACJ,OAAO;EACR;AAED,KAAI,CAAC,UAAU,cAAc;AAG3B,OAAK,MAAM,MAAM,OACf,KAAI,GAAG,UAAU,kBAAkB,QAAQ,GAAG,CAC5C,QAAO;AAIX,MAAI,UAAU,kBAGZ;QAAK,MAAM,MAAM,OACf,KAAI,kBAAkB,QAAQ,GAAG,CAC/B,QAAO;aAGF,UAAU,SAAS,QAAQ,CAAC,eAAe,QAAQ,OAAO,CAKnE,QAAO;;AAUX,QAAO;EAAE,QAFG,CAAC,GAAG,UAAU,QAAQ,SAAS,KAAK,CAAC;EAE3B,IAAI;EAAW,IAAI;EAAW,OAAO;EAAM;;;;;;;;;;;;;;;AAgBnE,SAAS,eAAe,QAAsB,QAA+B;CAI3E,MAAM,UAAU,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,MACnC,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EACnC;CACD,MAAM,SAAuB,CAAC,GAAG,OAAO;CACxC,MAAM,QAAQ,OAAO,OAAO,GAAG,OAAO,OAAO,GAAG,OAAO,SAAS;AAEhE,MAAK,MAAM,QAAQ,SAAS;AAC1B,MAAI,KAAK,QAAQ;AAGf,UAAO,KAAK,KAAK;AACjB;;EAGF,IAAI,QAAQ;EACZ,IAAI,UAAU;AAEd,SAAO,SAAS;AACd,aAAU;AACV,QAAK,MAAM,SAAS,OAClB,KAAI,SAAS,MAAM,MAAM,EAAE;AACzB,IAAC,KAA6B,IAAI,MAAM,IAAI,MAAM;AAClD,cAAU;;AAGd,OAAI,EAAE,QAAQ,MACZ,QAAO;;AAIX,SAAO,KAAK,KAAK;;AAGnB,QAAO"}
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
import { Compactor, Layout, LayoutConstraint, LayoutItem, ResizeHandleAxis } from "./grid-core/types.js";
|
|
3
3
|
import { getCompactor, horizontalCompactor, noCompactor, verticalCompactor } from "./grid-core/compactors.js";
|
|
4
4
|
import { aspectRatio, boundedX, boundedY, containerBounds, gridBounds, maxSize, minMaxSize, minSize, snapToGrid } from "./grid-core/constraints.js";
|
|
5
|
+
import { BoardSelectionMode } from "./use-board-selection.js";
|
|
5
6
|
import { CubeBoardWidgetProps, Widget } from "./Widget.js";
|
|
6
|
-
import { BoardCompactType, BoardGridLines, BoardInteractionInfo, CubeBoardProps } from "./Board.js";
|
|
7
|
+
import { BOARD_SELECTION_CANCEL, BoardCompactType, BoardGridLines, BoardInteractionInfo, CubeBoardProps } from "./Board.js";
|
|
7
8
|
import { BreakpointCols, Breakpoints, ResponsiveLayouts } from "./responsive-utils.js";
|
|
8
9
|
import { BoardResponsive, CubeBoardResponsiveProps } from "./BoardResponsive.js";
|
|
9
10
|
import { WidgetTransferInfo } from "./board-context.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.156.0 | Cube Dev Team */
|
|
2
2
|
import { getCompactor, horizontalCompactor, noCompactor, verticalCompactor } from "./grid-core/compactors.js";
|
|
3
3
|
import { aspectRatio, boundedX, boundedY, containerBounds, gridBounds, maxSize, minMaxSize, minSize, snapToGrid } from "./grid-core/constraints.js";
|
|
4
4
|
import { BoardProvider } from "./BoardProvider.js";
|
|
5
|
-
import { Board as Board$1 } from "./Board.js";
|
|
5
|
+
import { BOARD_SELECTION_CANCEL, Board as Board$1 } from "./Board.js";
|
|
6
6
|
import { BoardResponsive } from "./BoardResponsive.js";
|
|
7
7
|
import { Widget } from "./Widget.js";
|
|
8
8
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["BoardBase"],"sources":["../../../../src/components/layout/Board/index.tsx"],"sourcesContent":["import { Board as BoardBase } from './Board';\nimport { BoardProvider } from './BoardProvider';\nimport { BoardResponsive } from './BoardResponsive';\nimport { Widget } from './Widget';\n\nconst Board = Object.assign(BoardBase, {\n Widget,\n Provider: BoardProvider,\n Responsive: BoardResponsive,\n});\n\nexport { Board };\nexport { BoardProvider };\nexport { BoardResponsive };\nexport { Widget as BoardWidget };\n\nexport type {\n CubeBoardProps,\n BoardCompactType,\n BoardGridLines,\n BoardInteractionInfo,\n} from './Board';\nexport type { CubeBoardResponsiveProps } from './BoardResponsive';\nexport type { CubeBoardWidgetProps } from './Widget';\nexport type { CubeBoardProviderProps } from './BoardProvider';\nexport type { WidgetTransferInfo } from './board-context';\nexport type {\n Breakpoints as BoardBreakpoints,\n BreakpointCols as BoardBreakpointCols,\n ResponsiveLayouts as BoardResponsiveLayouts,\n} from './responsive-utils';\n\nexport type {\n Layout,\n LayoutItem,\n ResizeHandleAxis,\n Compactor,\n LayoutConstraint,\n PositionParams,\n} from './grid-core';\n\nexport {\n verticalCompactor,\n horizontalCompactor,\n noCompactor,\n getCompactor,\n gridBounds,\n minMaxSize,\n containerBounds,\n boundedX,\n boundedY,\n aspectRatio,\n snapToGrid,\n minSize,\n maxSize,\n} from './grid-core';\n"],"mappings":";;;;;;;;;AAKA,MAAM,QAAQ,OAAO,OAAOA,SAAW;CACrC;CACA,UAAU;CACV,YAAY;CACb,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["BoardBase"],"sources":["../../../../src/components/layout/Board/index.tsx"],"sourcesContent":["import { Board as BoardBase } from './Board';\nimport { BoardProvider } from './BoardProvider';\nimport { BoardResponsive } from './BoardResponsive';\nimport { Widget } from './Widget';\n\nconst Board = Object.assign(BoardBase, {\n Widget,\n Provider: BoardProvider,\n Responsive: BoardResponsive,\n});\n\nexport { Board };\nexport { BoardProvider };\nexport { BoardResponsive };\nexport { Widget as BoardWidget };\nexport { BOARD_SELECTION_CANCEL } from './Board';\n\nexport type {\n CubeBoardProps,\n BoardCompactType,\n BoardGridLines,\n BoardInteractionInfo,\n} from './Board';\nexport type { BoardSelectionMode } from './use-board-selection';\nexport type { CubeBoardResponsiveProps } from './BoardResponsive';\nexport type { CubeBoardWidgetProps } from './Widget';\nexport type { CubeBoardProviderProps } from './BoardProvider';\nexport type { WidgetTransferInfo } from './board-context';\nexport type {\n Breakpoints as BoardBreakpoints,\n BreakpointCols as BoardBreakpointCols,\n ResponsiveLayouts as BoardResponsiveLayouts,\n} from './responsive-utils';\n\nexport type {\n Layout,\n LayoutItem,\n ResizeHandleAxis,\n Compactor,\n LayoutConstraint,\n PositionParams,\n} from './grid-core';\n\nexport {\n verticalCompactor,\n horizontalCompactor,\n noCompactor,\n getCompactor,\n gridBounds,\n minMaxSize,\n containerBounds,\n boundedX,\n boundedY,\n aspectRatio,\n snapToGrid,\n minSize,\n maxSize,\n} from './grid-core';\n"],"mappings":";;;;;;;;;AAKA,MAAM,QAAQ,OAAO,OAAOA,SAAW;CACrC;CACA,UAAU;CACV,YAAY;CACb,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.156.0 | Cube Dev Team */
|
|
2
2
|
import { useEvent } from "../../../_internal/hooks/use-event.js";
|
|
3
3
|
import { cloneLayout } from "./grid-core/layout.js";
|
|
4
4
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
@@ -17,11 +17,13 @@ function useBoardLayout(options) {
|
|
|
17
17
|
const [layout, setLayout] = useState(() => cloneLayout(controlledLayout ?? defaultLayout ?? []));
|
|
18
18
|
const layoutRef = useRef(layout);
|
|
19
19
|
layoutRef.current = layout;
|
|
20
|
-
const [
|
|
20
|
+
const [placeholders, setPlaceholdersState] = useState([]);
|
|
21
|
+
const placeholdersRef = useRef([]);
|
|
21
22
|
const placeholderRef = useRef(null);
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
const setPlaceholders = useCallback((items) => {
|
|
24
|
+
placeholdersRef.current = items;
|
|
25
|
+
placeholderRef.current = items[0] ?? null;
|
|
26
|
+
setPlaceholdersState(items);
|
|
25
27
|
}, []);
|
|
26
28
|
const onLayoutChangeEvent = useEvent((next) => onLayoutChange?.(next));
|
|
27
29
|
const prevControlledRef = useRef(controlledLayout);
|
|
@@ -33,17 +35,20 @@ function useBoardLayout(options) {
|
|
|
33
35
|
setLayout(next);
|
|
34
36
|
}
|
|
35
37
|
}, [controlledLayout, isControlled]);
|
|
38
|
+
const applyLayout = useCallback((next, commit) => {
|
|
39
|
+
layoutRef.current = next;
|
|
40
|
+
setLayout(next);
|
|
41
|
+
if (commit) onLayoutChangeEvent(next);
|
|
42
|
+
}, [onLayoutChangeEvent]);
|
|
36
43
|
return {
|
|
37
44
|
layout,
|
|
38
45
|
layoutRef,
|
|
39
|
-
|
|
46
|
+
placeholders,
|
|
47
|
+
placeholder: placeholders[0] ?? null,
|
|
48
|
+
placeholdersRef,
|
|
40
49
|
placeholderRef,
|
|
41
|
-
|
|
42
|
-
applyLayout
|
|
43
|
-
layoutRef.current = next;
|
|
44
|
-
setLayout(next);
|
|
45
|
-
if (commit) onLayoutChangeEvent(next);
|
|
46
|
-
}, [onLayoutChangeEvent])
|
|
50
|
+
setPlaceholders,
|
|
51
|
+
applyLayout
|
|
47
52
|
};
|
|
48
53
|
}
|
|
49
54
|
|