@cube-dev/ui-kit 0.0.0-canary-d3e63ad → 0.0.0-canary-e5b4f54
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/_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.js +1 -1
- package/dist/components/actions/CommandMenu/styled.js +1 -1
- package/dist/components/actions/ItemAction/ItemAction.js +2 -6
- package/dist/components/actions/ItemAction/ItemAction.js.map +1 -1
- package/dist/components/actions/ItemActionContext.d.ts +0 -14
- package/dist/components/actions/ItemActionContext.js +2 -2
- package/dist/components/actions/ItemActionContext.js.map +1 -1
- package/dist/components/actions/ItemButton/ItemButton.js +42 -47
- package/dist/components/actions/ItemButton/ItemButton.js.map +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.d.ts +13 -0
- package/dist/components/actions/Menu/MenuTrigger.js +27 -15
- package/dist/components/actions/Menu/MenuTrigger.js.map +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/InlineInput/InlineInput.js.map +1 -1
- package/dist/components/content/Item/Item.js +48 -4
- package/dist/components/content/Item/Item.js.map +1 -1
- package/dist/components/content/ItemBadge/ItemBadge.d.ts +1 -1
- package/dist/components/content/ItemBadge/ItemBadge.js +4 -5
- package/dist/components/content/ItemBadge/ItemBadge.js.map +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 +14 -14
- package/dist/components/content/Text.js +1 -1
- package/dist/components/content/TextItem/TextItem.js +1 -1
- package/dist/components/content/Title.js +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.js +1 -1
- package/dist/components/data/DataTable/DataTable.js +1 -1
- package/dist/components/data/ItemTable/ItemTable.js +1 -1
- package/dist/components/data/ItemTable/ItemTableBulkBar.js +1 -1
- package/dist/components/data/ItemTable/ItemTableDragPreview.js +1 -1
- package/dist/components/data/ItemTable/ItemTableFooter.js +1 -1
- package/dist/components/data/ItemTable/ItemTableToolbar.js +1 -1
- package/dist/components/data/TableBase/ColumnResizer.js +1 -1
- package/dist/components/data/TableBase/RowCollection.js +1 -1
- package/dist/components/data/TableBase/TableHeaderCell.js +1 -1
- package/dist/components/data/TableBase/TableRow.js +1 -1
- package/dist/components/data/TableBase/TableView.js +1 -1
- package/dist/components/data/TableBase/column-menu.js +1 -1
- package/dist/components/data/TableBase/column-tint.js +1 -1
- package/dist/components/data/TableBase/row-menu.js +1 -1
- package/dist/components/data/TableBase/styled.js +1 -1
- package/dist/components/data/TableBase/types.js +1 -1
- package/dist/components/data/TableBase/use-cell-selection.js +0 -0
- package/dist/components/data/TableBase/use-column-order.js +1 -1
- package/dist/components/data/TableBase/use-container-width.js +1 -1
- package/dist/components/data/TableBase/use-row-move-animation.js +1 -1
- package/dist/components/data/TableBase/use-scrollability.js +1 -1
- package/dist/components/data/TableBase/use-table-columns.js +1 -1
- package/dist/components/data/TableBase/use-table-search.js +1 -1
- package/dist/components/data/TableBase/use-table-selection.js +1 -1
- package/dist/components/data/TableBase/use-table-sort.js +1 -1
- package/dist/components/data/TableBase/use-table-sorts.js +1 -1
- package/dist/components/data/TableBase/use-table-storage.js +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/ColorInput/ColorInput.js +1 -1
- package/dist/components/fields/ColorPicker/ColorPicker.js +1 -1
- package/dist/components/fields/ColorSwatchGroup/ColorSwatchGroup.js +1 -1
- package/dist/components/fields/ComboBox/ComboBox.js +6 -2
- package/dist/components/fields/ComboBox/ComboBox.js.map +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/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.js +1 -1
- package/dist/components/fields/FilterListBox/FilterListBox.js +1 -1
- package/dist/components/fields/FilterPicker/FilterPicker.js +1 -1
- package/dist/components/fields/FilterPicker/FilterPicker.js.map +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 +2 -1
- package/dist/components/fields/PasswordInput/PasswordInput.js.map +1 -1
- package/dist/components/fields/Picker/Picker.js +1 -1
- package/dist/components/fields/Picker/Picker.js.map +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 +6 -2
- package/dist/components/fields/SearchComboBox/SearchComboBox.js.map +1 -1
- package/dist/components/fields/SearchInput/SearchInput.js +7 -1
- package/dist/components/fields/SearchInput/SearchInput.js.map +1 -1
- package/dist/components/fields/Select/Select.js +6 -3
- 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.js +1 -1
- package/dist/components/fields/TextInputMapper/TextInputMapper.js +1 -1
- package/dist/components/fields/color/ColorPanel.js +1 -1
- package/dist/components/fields/color/ColorSwatch.js +1 -1
- package/dist/components/fields/color/channels.js +1 -1
- package/dist/components/fields/color/color.js +1 -1
- package/dist/components/fields/color/context.js +1 -1
- package/dist/components/form/FieldWrapper/FieldWrapper.js +1 -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.js +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.js +1 -1
- package/dist/components/layout/Board/WidgetHost.js +1 -1
- package/dist/components/layout/Board/board-context.js +1 -1
- package/dist/components/layout/Board/board-store.js +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 +1 -1
- 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.js +1 -1
- package/dist/components/layout/Board/responsive-utils.js +1 -1
- package/dist/components/layout/Board/use-board-layout.js +1 -1
- package/dist/components/layout/Board/use-board-registry.js +1 -1
- package/dist/components/layout/Board/use-board-select-modifier-key.js +1 -1
- package/dist/components/layout/Board/use-board-selection.js +1 -1
- 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/Pagination/Pagination.js +1 -1
- package/dist/components/navigation/Pagination/use-pagination.js +1 -1
- package/dist/components/navigation/Tabs/DraggableTabList.js +1 -1
- package/dist/components/navigation/Tabs/TabButton.js +2 -29
- package/dist/components/navigation/Tabs/TabButton.js.map +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/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/CalendarHeader.js +1 -1
- package/dist/components/other/Calendar/CalendarPanel.js +1 -1
- package/dist/components/other/Calendar/PeriodCalendar.js +1 -1
- package/dist/components/other/Calendar/PeriodGrid.js +1 -1
- package/dist/components/other/Calendar/RangeCalendar.js +1 -1
- package/dist/components/other/Calendar/styled.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 +4 -3
- package/dist/components/overlays/Dialog/Dialog.js.map +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.d.ts +13 -0
- package/dist/components/overlays/Dialog/DialogTrigger.js +24 -5
- package/dist/components/overlays/Dialog/DialogTrigger.js.map +1 -1
- package/dist/components/overlays/Dialog/context.js +1 -1
- package/dist/components/overlays/Dialog/context.js.map +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/OpenTransitionContext.js +1 -1
- package/dist/components/overlays/Modal/Overlay.js +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/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/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 +7 -86
- package/dist/data/item-themes.js.map +1 -1
- package/dist/data/themes.js +1 -1
- package/dist/eslint-plugin/defaults.generated.js +19 -5
- 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 +1 -1
- package/dist/i18n/locales/en-US/uikit.js +1 -1
- package/dist/i18n/locales/es-ES/uikit.js +1 -1
- package/dist/i18n/locales/es-MX/uikit.js +1 -1
- package/dist/i18n/locales/fr-FR/uikit.js +1 -1
- package/dist/i18n/locales/it-IT/uikit.js +1 -1
- package/dist/i18n/locales/ja-JP/uikit.js +1 -1
- package/dist/i18n/locales/nb-NO/uikit.js +1 -1
- package/dist/i18n/locales/pt-BR/uikit.js +1 -1
- package/dist/i18n/locales/pt-PT/uikit.js +1 -1
- package/dist/i18n/locales/sv-SE/uikit.js +1 -1
- package/dist/i18n/locales/vi-VN/uikit.js +1 -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/ArrowNarrowDownIcon.js +1 -1
- package/dist/icons/ArrowNarrowUpIcon.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.js +1 -1
- 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/wrap-icon.js +1 -1
- package/dist/index.js +1 -1
- package/dist/probe/canonicalize.js +1 -1
- package/dist/probe/css.js +1 -1
- package/dist/probe/index.js +1 -1
- package/dist/provider.js +1 -1
- package/dist/providers/TrackingProvider.js +1 -1
- package/dist/providers/navigationAdapter.default.js +1 -1
- package/dist/tokens/base.js +1 -1
- package/dist/tokens/color-theme.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/disabledProps.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.js +1 -1
- package/dist/utils/react/nullableValue.js +1 -1
- package/dist/utils/react/resolveIcon.js +1 -1
- package/dist/utils/react/sharedStore.js +1 -1
- package/dist/utils/react/useBufferedValue.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 +2 -2
- package/docs/components/actions/ItemAction.md +1 -1
- package/docs/components/actions/MenuTrigger.md +54 -2
- package/docs/components/actions/SubMenuTrigger.md +2 -2
- package/docs/components/content/InlineInput.md +1 -1
- package/docs/components/content/ItemBadge.md +1 -1
- package/docs/components/overlays/DialogTrigger.md +3 -2
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { SlotProvider } from "../../../utils/react/Slots.js";
|
|
3
3
|
import { usePopoverSync } from "../../../utils/react/usePopoverSync.js";
|
|
4
4
|
import { useEvent } from "../../../_internal/hooks/use-event.js";
|
|
@@ -18,12 +18,13 @@ import { PressResponder } from "@react-aria/interactions";
|
|
|
18
18
|
function MenuTrigger(props, ref) {
|
|
19
19
|
const internalPopoverRef = useRef(null);
|
|
20
20
|
const menuPopoverRef = props.popoverRef ?? internalPopoverRef;
|
|
21
|
+
const trayRef = useRef(null);
|
|
21
22
|
const triggerRef = useRef(null);
|
|
22
23
|
const domRef = useObjectRef(ref);
|
|
23
24
|
const menuTriggerRef = props.targetRef || domRef || triggerRef;
|
|
24
25
|
const menuRef = useRef(null);
|
|
25
26
|
const wasOpenRef = useRef(false);
|
|
26
|
-
const { children, shouldFlip = true, closeOnSelect, trigger = "press", isDisabled, isDummy, mobileType = "popover" } = props;
|
|
27
|
+
const { children, shouldFlip = true, closeOnSelect, trigger = "press", isDisabled, isDummy, mobileType = "popover", shouldRestoreFocus = true } = props;
|
|
27
28
|
const menuId = useMemo(() => generateRandomId(), []);
|
|
28
29
|
if (!Array.isArray(children) || children.length > 2) throw new Error("MenuTrigger must have exactly 2 children");
|
|
29
30
|
let [menuTrigger, menu] = children;
|
|
@@ -36,18 +37,6 @@ function MenuTrigger(props, ref) {
|
|
|
36
37
|
triggerRef: menuTriggerRef,
|
|
37
38
|
containerRef: menuPopoverRef
|
|
38
39
|
});
|
|
39
|
-
useEffect(() => {
|
|
40
|
-
if (!state.isOpen && wasOpenRef.current && !isDummy) {
|
|
41
|
-
wasOpenRef.current = false;
|
|
42
|
-
setTimeout(() => {
|
|
43
|
-
menuTriggerRef.current?.focus();
|
|
44
|
-
}, 0);
|
|
45
|
-
} else if (state.isOpen) wasOpenRef.current = true;
|
|
46
|
-
}, [
|
|
47
|
-
state.isOpen,
|
|
48
|
-
menuTriggerRef,
|
|
49
|
-
isDummy
|
|
50
|
-
]);
|
|
51
40
|
if (typeof menuTrigger === "function") menuTrigger = menuTrigger(state);
|
|
52
41
|
const { menuTriggerProps, menuProps } = useMenuTrigger({ isDisabled }, state, menuTriggerRef);
|
|
53
42
|
let initialPlacement = props.placement ?? "bottom start";
|
|
@@ -65,6 +54,28 @@ function MenuTrigger(props, ref) {
|
|
|
65
54
|
offset: props.offset ?? 8,
|
|
66
55
|
crossOffset: props.crossOffset ?? 0
|
|
67
56
|
});
|
|
57
|
+
const hasFocusMovedOutsideMenu = useEvent(() => {
|
|
58
|
+
const activeElement = document.activeElement;
|
|
59
|
+
if (!activeElement || activeElement === document.body) return false;
|
|
60
|
+
if (!activeElement.isConnected) return false;
|
|
61
|
+
return !((isTray ? trayRef.current : menuPopoverRef.current)?.contains(activeElement) || menuRef.current?.contains(activeElement) || menuTriggerRef.current?.contains(activeElement));
|
|
62
|
+
});
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (!state.isOpen && wasOpenRef.current && !isDummy) {
|
|
65
|
+
wasOpenRef.current = false;
|
|
66
|
+
if (!shouldRestoreFocus) return;
|
|
67
|
+
setTimeout(() => {
|
|
68
|
+
if (hasFocusMovedOutsideMenu()) return;
|
|
69
|
+
menuTriggerRef.current?.focus();
|
|
70
|
+
}, 0);
|
|
71
|
+
} else if (state.isOpen) wasOpenRef.current = true;
|
|
72
|
+
}, [
|
|
73
|
+
state.isOpen,
|
|
74
|
+
menuTriggerRef,
|
|
75
|
+
isDummy,
|
|
76
|
+
shouldRestoreFocus,
|
|
77
|
+
hasFocusMovedOutsideMenu
|
|
78
|
+
]);
|
|
68
79
|
const menuContext = {
|
|
69
80
|
...menuProps,
|
|
70
81
|
ref: menuRef,
|
|
@@ -82,7 +93,7 @@ function MenuTrigger(props, ref) {
|
|
|
82
93
|
isClosing: !state.isOpen
|
|
83
94
|
};
|
|
84
95
|
const contents = /* @__PURE__ */ jsxs(FocusScope, {
|
|
85
|
-
restoreFocus:
|
|
96
|
+
restoreFocus: shouldRestoreFocus,
|
|
86
97
|
children: [
|
|
87
98
|
/* @__PURE__ */ jsx(DismissButton, { onDismiss: state.close }),
|
|
88
99
|
menu,
|
|
@@ -106,6 +117,7 @@ function MenuTrigger(props, ref) {
|
|
|
106
117
|
});
|
|
107
118
|
let overlay;
|
|
108
119
|
if (isTray) overlay = /* @__PURE__ */ jsx(_Tray, {
|
|
120
|
+
ref: trayRef,
|
|
109
121
|
isOpen: state.isOpen,
|
|
110
122
|
shouldCloseOnInteractOutside,
|
|
111
123
|
onClose: state.close,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MenuTrigger.js","names":["Tray","Popover"],"sources":["../../../../src/components/actions/Menu/MenuTrigger.tsx"],"sourcesContent":["import { PressResponder } from '@react-aria/interactions';\nimport { useObjectRef } from '@react-aria/utils';\nimport { useIsMobileDevice } from '@react-spectrum/utils';\nimport {\n forwardRef,\n Fragment,\n MutableRefObject,\n ReactElement,\n Ref,\n useEffect,\n useMemo,\n useRef,\n} from 'react';\nimport {\n AriaMenuTriggerProps,\n DismissButton,\n FocusScope,\n Placement,\n PositionProps,\n useMenuTrigger,\n useOverlayPosition,\n} from 'react-aria';\nimport { MenuTriggerState, useMenuTriggerState } from 'react-stately';\n\nimport { useEvent } from '../../../_internal';\nimport { generateRandomId } from '../../../utils/random';\nimport { SlotProvider } from '../../../utils/react';\nimport { usePopoverSync } from '../../../utils/react/usePopoverSync';\nimport { Popover, Tray } from '../../overlays/Modal';\n\nimport { MenuContext, MenuContextValue } from './context';\n\nexport type { AriaMenuTriggerProps };\n\nexport type CubeMenuTriggerProps = AriaMenuTriggerProps &\n PositionProps & {\n isDisabled?: boolean;\n children: [\n ReactElement | ((state: MenuTriggerState) => ReactElement),\n ReactElement,\n ];\n\n closeOnSelect?: boolean;\n isDummy?: boolean;\n /**\n * External ref to the popover container element. When provided, it is\n * aliased to the internal `menuPopoverRef`, letting consumers (e.g.\n * `useAnchoredMenu` / `useContextMenu`) feed the popover container into\n * their own `usePopoverSync` so the nested-popover guard can recognize\n * submenus opened inside this menu. Optional.\n */\n popoverRef?: MutableRefObject<HTMLDivElement | null>;\n /**\n * Overlay variant to use on mobile screens. Defaults to `'popover'`, which\n * keeps the desktop overlay even on small viewports. Pass `'tray'` to opt\n * into the bottom-sheet `Tray` overlay on mobile (the previous implicit\n * default). Mirrors the `mobileType` API on `DialogTrigger`.\n */\n mobileType?: 'popover' | 'tray';\n };\n\nfunction MenuTrigger(props: CubeMenuTriggerProps, ref: Ref<HTMLElement>) {\n const internalPopoverRef = useRef<HTMLDivElement>(null);\n const menuPopoverRef = props.popoverRef ?? internalPopoverRef;\n const triggerRef = useRef<HTMLElement>(null);\n const domRef = useObjectRef(ref);\n const menuTriggerRef = props.targetRef || domRef || triggerRef;\n const menuRef = useRef<HTMLUListElement>(null);\n const wasOpenRef = useRef(false);\n const {\n children,\n shouldFlip = true,\n closeOnSelect,\n trigger = 'press',\n isDisabled,\n isDummy,\n mobileType = 'popover',\n } = props;\n\n // Generate a unique ID for this menu instance\n const menuId = useMemo(() => generateRandomId(), []);\n\n if (!Array.isArray(children) || children.length > 2) {\n throw new Error('MenuTrigger must have exactly 2 children');\n }\n\n let [menuTrigger, menu] = children;\n const state: MenuTriggerState = useMenuTriggerState(props);\n\n usePopoverSync({\n menuId,\n isOpen: state.isOpen,\n onClose: () => state.close(),\n enabled: !isDummy,\n triggerRef: menuTriggerRef,\n containerRef: menuPopoverRef,\n });\n\n // Restore focus manually when the menu closes\n useEffect(() => {\n if (!state.isOpen && wasOpenRef.current && !isDummy) {\n wasOpenRef.current = false;\n // Use setTimeout to ensure focus restoration happens after any animations\n setTimeout(() => {\n menuTriggerRef.current?.focus();\n }, 0);\n } else if (state.isOpen) {\n wasOpenRef.current = true;\n }\n }, [state.isOpen, menuTriggerRef, isDummy]);\n\n if (typeof menuTrigger === 'function') {\n menuTrigger = (menuTrigger as CubeMenuTriggerProps['children'][0])(state);\n }\n\n const { menuTriggerProps, menuProps } = useMenuTrigger(\n { isDisabled },\n state,\n menuTriggerRef,\n );\n\n let initialPlacement: Placement = props.placement ?? 'bottom start';\n\n // Tray rendering is now opt-in via `mobileType=\"tray\"` (matches DialogTrigger).\n // Without that opt-in, MenuTrigger always renders a Popover so that environments\n // like jsdom (where `window.screen.width === 0` makes useIsMobileDevice() true)\n // don't accidentally swap in the tray overlay.\n const isMobileDevice = useIsMobileDevice();\n const isTray = mobileType === 'tray' && isMobileDevice;\n const { overlayProps: positionProps, placement } = useOverlayPosition({\n targetRef: menuTriggerRef,\n overlayRef: menuPopoverRef,\n scrollRef: menuRef,\n placement: initialPlacement,\n shouldFlip: shouldFlip,\n isOpen: state.isOpen && !isTray,\n onClose: state.close,\n containerPadding: props.containerPadding,\n offset: props.offset ?? 8,\n crossOffset: props.crossOffset ?? 0,\n });\n\n const menuContext = {\n ...menuProps,\n ref: menuRef,\n onClose: state.close,\n closeOnSelect,\n autoFocus: (state.focusStrategy as any) ?? 'first',\n style: isTray\n ? {\n width: '100%',\n maxHeight: 'inherit',\n }\n : undefined,\n mods: {\n popover: !isTray,\n tray: isTray,\n },\n isClosing: !state.isOpen,\n } as MenuContextValue;\n\n // Wrap in a FocusScope so the menu popover registers as a child of any\n // outer contained FocusScope (e.g. a parent Dialog/Popover). Without this,\n // when the menu opens inside an outer contained FocusScope, the outer\n // scope rejects focus moving into the menu items (which live in a portal\n // and would otherwise belong to no scope) and yanks focus back to the\n // menu trigger.\n const contents = (\n <FocusScope restoreFocus>\n <DismissButton onDismiss={state.close} />\n {menu}\n <DismissButton onDismiss={state.close} />\n </FocusScope>\n );\n\n // Shared between the Popover and Tray branches so both react-aria\n // `useOverlay` calls see the same predicate. Without this, the Tray branch\n // falls back to unconditional dismiss-on-outside-interaction, which\n // `useOverlay` translates into stopPropagation/preventDefault in the\n // capture phase — that swallows clicks on sibling triggers (see Menu\n // rapid-open test).\n //\n // `useEvent` gives us a single stable callback reference for the lifetime\n // of the component while always reading the latest closure values. This\n // matters because `useMenuTriggerState` returns a fresh `state` object on\n // every render, so a vanilla `useCallback([..., state])` would produce a\n // new function every render and defeat any stability guarantees consumers\n // rely on.\n const shouldCloseOnInteractOutside = useEvent((el: Element) => {\n // While `Popover` is animating out, `useInteractOutside`'s capture-phase\n // listener is still attached (jsdom 29+ uses pointerdown/click capture).\n // The animation lasts ~350ms; without this guard, clicks on a sibling\n // trigger during the exit window get stopPropagation()'d and the\n // sibling's `onClick` never runs — breaking rapid-open and \"open menu\n // again with new props\" flows. Reading `state.isOpen` directly is safe\n // because `useEvent` always sees the latest closure.\n if (!state.isOpen) return false;\n\n const menuTriggerEl = el.closest('[data-popover-trigger]');\n if (!menuTriggerEl) {\n if (el.closest('[data-popover-keep]')) return false;\n // Plain interactive controls (Button, ItemButton) opt in via\n // `data-popover-dismiss`. We schedule the close via setTimeout(0) so\n // it lands AFTER the click event finishes — the button's onPress\n // fires first, then the popover closes. Without this, useOverlay\n // would stopPropagation() the click and the user would need a second\n // click to actually press the button.\n if (el.closest('[data-popover-dismiss]')) {\n setTimeout(() => state.close(), 0);\n return false;\n }\n return true;\n }\n if (\n isDummy &&\n (menuTriggerEl === menuTriggerRef.current ||\n menuTriggerRef.current?.contains(el))\n ) {\n return true;\n }\n if (menuTriggerEl === menuTriggerRef.current) return true;\n return false;\n });\n\n let overlay;\n if (isTray) {\n overlay = (\n <Tray\n isOpen={state.isOpen}\n shouldCloseOnInteractOutside={shouldCloseOnInteractOutside}\n onClose={state.close}\n >\n {contents}\n </Tray>\n );\n } else {\n overlay = (\n <Popover\n ref={menuPopoverRef}\n hideArrow\n isNonModal\n isOpen={state.isOpen}\n style={positionProps.style}\n placement={placement}\n shouldCloseOnInteractOutside={shouldCloseOnInteractOutside}\n onClose={state.close}\n >\n {contents}\n </Popover>\n );\n }\n\n return (\n <Fragment>\n <SlotProvider\n slots={{ actionButton: { holdAffordance: trigger === 'longPress' } }}\n >\n {!isDummy ? (\n <PressResponder\n {...menuTriggerProps}\n ref={menuTriggerRef}\n data-popover-trigger\n isPressed={state.isOpen}\n >\n {menuTrigger}\n </PressResponder>\n ) : null}\n </SlotProvider>\n <MenuContext.Provider value={menuContext}>{overlay}</MenuContext.Provider>\n </Fragment>\n );\n}\n\n/**\n * The MenuTrigger serves as a wrapper around a Menu and its associated trigger,\n * linking the Menu's open state with the trigger's press state.\n */\nlet _MenuTrigger = forwardRef(MenuTrigger);\n\n_MenuTrigger.displayName = 'MenuTrigger';\n\nexport { _MenuTrigger as MenuTrigger };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MenuTrigger.js","names":["Tray","Popover"],"sources":["../../../../src/components/actions/Menu/MenuTrigger.tsx"],"sourcesContent":["import { PressResponder } from '@react-aria/interactions';\nimport { useObjectRef } from '@react-aria/utils';\nimport { useIsMobileDevice } from '@react-spectrum/utils';\nimport {\n forwardRef,\n Fragment,\n MutableRefObject,\n ReactElement,\n Ref,\n useEffect,\n useMemo,\n useRef,\n} from 'react';\nimport {\n AriaMenuTriggerProps,\n DismissButton,\n FocusScope,\n Placement,\n PositionProps,\n useMenuTrigger,\n useOverlayPosition,\n} from 'react-aria';\nimport { MenuTriggerState, useMenuTriggerState } from 'react-stately';\n\nimport { useEvent } from '../../../_internal';\nimport { generateRandomId } from '../../../utils/random';\nimport { SlotProvider } from '../../../utils/react';\nimport { usePopoverSync } from '../../../utils/react/usePopoverSync';\nimport { Popover, Tray } from '../../overlays/Modal';\n\nimport { MenuContext, MenuContextValue } from './context';\n\nexport type { AriaMenuTriggerProps };\n\nexport type CubeMenuTriggerProps = AriaMenuTriggerProps &\n PositionProps & {\n isDisabled?: boolean;\n children: [\n ReactElement | ((state: MenuTriggerState) => ReactElement),\n ReactElement,\n ];\n\n closeOnSelect?: boolean;\n isDummy?: boolean;\n /**\n * Whether focus returns to the trigger when the menu closes. Defaults to\n * `true`.\n *\n * The restore is skipped automatically whenever the action that closed the\n * menu has already moved focus somewhere else, so an item that opens a\n * panel/dialog/inline editor and focuses it needs nothing here. Pass\n * `false` for the remaining case: a surface that claims focus *later* than\n * the menu's own restore (after an async load, an entry animation, or a\n * `requestAnimationFrame`), where the trigger would otherwise take focus\n * first and produce a visible flash.\n */\n shouldRestoreFocus?: boolean;\n /**\n * External ref to the popover container element. When provided, it is\n * aliased to the internal `menuPopoverRef`, letting consumers (e.g.\n * `useAnchoredMenu` / `useContextMenu`) feed the popover container into\n * their own `usePopoverSync` so the nested-popover guard can recognize\n * submenus opened inside this menu. Optional.\n */\n popoverRef?: MutableRefObject<HTMLDivElement | null>;\n /**\n * Overlay variant to use on mobile screens. Defaults to `'popover'`, which\n * keeps the desktop overlay even on small viewports. Pass `'tray'` to opt\n * into the bottom-sheet `Tray` overlay on mobile (the previous implicit\n * default). Mirrors the `mobileType` API on `DialogTrigger`.\n */\n mobileType?: 'popover' | 'tray';\n };\n\nfunction MenuTrigger(props: CubeMenuTriggerProps, ref: Ref<HTMLElement>) {\n const internalPopoverRef = useRef<HTMLDivElement>(null);\n const menuPopoverRef = props.popoverRef ?? internalPopoverRef;\n const trayRef = useRef<HTMLElement>(null);\n const triggerRef = useRef<HTMLElement>(null);\n const domRef = useObjectRef(ref);\n const menuTriggerRef = props.targetRef || domRef || triggerRef;\n const menuRef = useRef<HTMLUListElement>(null);\n const wasOpenRef = useRef(false);\n const {\n children,\n shouldFlip = true,\n closeOnSelect,\n trigger = 'press',\n isDisabled,\n isDummy,\n mobileType = 'popover',\n shouldRestoreFocus = true,\n } = props;\n\n // Generate a unique ID for this menu instance\n const menuId = useMemo(() => generateRandomId(), []);\n\n if (!Array.isArray(children) || children.length > 2) {\n throw new Error('MenuTrigger must have exactly 2 children');\n }\n\n let [menuTrigger, menu] = children;\n const state: MenuTriggerState = useMenuTriggerState(props);\n\n usePopoverSync({\n menuId,\n isOpen: state.isOpen,\n onClose: () => state.close(),\n enabled: !isDummy,\n triggerRef: menuTriggerRef,\n containerRef: menuPopoverRef,\n });\n\n if (typeof menuTrigger === 'function') {\n menuTrigger = (menuTrigger as CubeMenuTriggerProps['children'][0])(state);\n }\n\n const { menuTriggerProps, menuProps } = useMenuTrigger(\n { isDisabled },\n state,\n menuTriggerRef,\n );\n\n let initialPlacement: Placement = props.placement ?? 'bottom start';\n\n // Tray rendering is now opt-in via `mobileType=\"tray\"` (matches DialogTrigger).\n // Without that opt-in, MenuTrigger always renders a Popover so that environments\n // like jsdom (where `window.screen.width === 0` makes useIsMobileDevice() true)\n // don't accidentally swap in the tray overlay.\n const isMobileDevice = useIsMobileDevice();\n const isTray = mobileType === 'tray' && isMobileDevice;\n const { overlayProps: positionProps, placement } = useOverlayPosition({\n targetRef: menuTriggerRef,\n overlayRef: menuPopoverRef,\n scrollRef: menuRef,\n placement: initialPlacement,\n shouldFlip: shouldFlip,\n isOpen: state.isOpen && !isTray,\n onClose: state.close,\n containerPadding: props.containerPadding,\n offset: props.offset ?? 8,\n crossOffset: props.crossOffset ?? 0,\n });\n\n // Whether focus has been claimed by something outside the closing menu —\n // the signal that a menu action handed focus off and the trigger must not\n // take it back.\n //\n // Focus still inside the menu overlay means nobody claimed it: the pressed\n // item keeps focus while the popover plays its ~350ms exit animation. Focus\n // on `<body>` (or on a detached element) means the focused node went away\n // with the menu. Both are cases where the trigger is where focus belongs.\n const hasFocusMovedOutsideMenu = useEvent(() => {\n const activeElement = document.activeElement;\n\n if (!activeElement || activeElement === document.body) return false;\n if (!activeElement.isConnected) return false;\n\n // `menuPopoverRef` is only wired to the `Popover` branch, so the overlay\n // container is `trayRef` when `mobileType=\"tray\"` is in effect.\n const overlay = isTray ? trayRef.current : menuPopoverRef.current;\n\n return !(\n overlay?.contains(activeElement) ||\n menuRef.current?.contains(activeElement) ||\n menuTriggerRef.current?.contains(activeElement)\n );\n });\n\n // Restore focus manually when the menu closes\n useEffect(() => {\n if (!state.isOpen && wasOpenRef.current && !isDummy) {\n wasOpenRef.current = false;\n\n if (!shouldRestoreFocus) return;\n\n // Use setTimeout to ensure focus restoration happens after any animations\n setTimeout(() => {\n // An action that opened a panel, a dialog or an inline editor has\n // already focused it by now — taking focus back to the trigger would\n // undo the hand-off, which consumers previously had to out-race by\n // re-focusing on every animation frame (CUB-3962).\n if (hasFocusMovedOutsideMenu()) return;\n\n menuTriggerRef.current?.focus();\n }, 0);\n } else if (state.isOpen) {\n wasOpenRef.current = true;\n }\n }, [\n state.isOpen,\n menuTriggerRef,\n isDummy,\n shouldRestoreFocus,\n hasFocusMovedOutsideMenu,\n ]);\n\n const menuContext = {\n ...menuProps,\n ref: menuRef,\n onClose: state.close,\n closeOnSelect,\n autoFocus: (state.focusStrategy as any) ?? 'first',\n style: isTray\n ? {\n width: '100%',\n maxHeight: 'inherit',\n }\n : undefined,\n mods: {\n popover: !isTray,\n tray: isTray,\n },\n isClosing: !state.isOpen,\n } as MenuContextValue;\n\n // Wrap in a FocusScope so the menu popover registers as a child of any\n // outer contained FocusScope (e.g. a parent Dialog/Popover). Without this,\n // when the menu opens inside an outer contained FocusScope, the outer\n // scope rejects focus moving into the menu items (which live in a portal\n // and would otherwise belong to no scope) and yanks focus back to the\n // menu trigger.\n //\n // `restoreFocus` follows `shouldRestoreFocus`, so opting out silences the\n // scope's own unmount restore too. Scope registration (and therefore the\n // guarantee above) is unaffected — `FocusScope` joins the tree and tracks\n // the active scope regardless of `restoreFocus`.\n const contents = (\n <FocusScope restoreFocus={shouldRestoreFocus}>\n <DismissButton onDismiss={state.close} />\n {menu}\n <DismissButton onDismiss={state.close} />\n </FocusScope>\n );\n\n // Shared between the Popover and Tray branches so both react-aria\n // `useOverlay` calls see the same predicate. Without this, the Tray branch\n // falls back to unconditional dismiss-on-outside-interaction, which\n // `useOverlay` translates into stopPropagation/preventDefault in the\n // capture phase — that swallows clicks on sibling triggers (see Menu\n // rapid-open test).\n //\n // `useEvent` gives us a single stable callback reference for the lifetime\n // of the component while always reading the latest closure values. This\n // matters because `useMenuTriggerState` returns a fresh `state` object on\n // every render, so a vanilla `useCallback([..., state])` would produce a\n // new function every render and defeat any stability guarantees consumers\n // rely on.\n const shouldCloseOnInteractOutside = useEvent((el: Element) => {\n // While `Popover` is animating out, `useInteractOutside`'s capture-phase\n // listener is still attached (jsdom 29+ uses pointerdown/click capture).\n // The animation lasts ~350ms; without this guard, clicks on a sibling\n // trigger during the exit window get stopPropagation()'d and the\n // sibling's `onClick` never runs — breaking rapid-open and \"open menu\n // again with new props\" flows. Reading `state.isOpen` directly is safe\n // because `useEvent` always sees the latest closure.\n if (!state.isOpen) return false;\n\n const menuTriggerEl = el.closest('[data-popover-trigger]');\n if (!menuTriggerEl) {\n if (el.closest('[data-popover-keep]')) return false;\n // Plain interactive controls (Button, ItemButton) opt in via\n // `data-popover-dismiss`. We schedule the close via setTimeout(0) so\n // it lands AFTER the click event finishes — the button's onPress\n // fires first, then the popover closes. Without this, useOverlay\n // would stopPropagation() the click and the user would need a second\n // click to actually press the button.\n if (el.closest('[data-popover-dismiss]')) {\n setTimeout(() => state.close(), 0);\n return false;\n }\n return true;\n }\n if (\n isDummy &&\n (menuTriggerEl === menuTriggerRef.current ||\n menuTriggerRef.current?.contains(el))\n ) {\n return true;\n }\n if (menuTriggerEl === menuTriggerRef.current) return true;\n return false;\n });\n\n let overlay;\n if (isTray) {\n overlay = (\n <Tray\n ref={trayRef}\n isOpen={state.isOpen}\n shouldCloseOnInteractOutside={shouldCloseOnInteractOutside}\n onClose={state.close}\n >\n {contents}\n </Tray>\n );\n } else {\n overlay = (\n <Popover\n ref={menuPopoverRef}\n hideArrow\n isNonModal\n isOpen={state.isOpen}\n style={positionProps.style}\n placement={placement}\n shouldCloseOnInteractOutside={shouldCloseOnInteractOutside}\n onClose={state.close}\n >\n {contents}\n </Popover>\n );\n }\n\n return (\n <Fragment>\n <SlotProvider\n slots={{ actionButton: { holdAffordance: trigger === 'longPress' } }}\n >\n {!isDummy ? (\n <PressResponder\n {...menuTriggerProps}\n ref={menuTriggerRef}\n data-popover-trigger\n isPressed={state.isOpen}\n >\n {menuTrigger}\n </PressResponder>\n ) : null}\n </SlotProvider>\n <MenuContext.Provider value={menuContext}>{overlay}</MenuContext.Provider>\n </Fragment>\n );\n}\n\n/**\n * The MenuTrigger serves as a wrapper around a Menu and its associated trigger,\n * linking the Menu's open state with the trigger's press state.\n */\nlet _MenuTrigger = forwardRef(MenuTrigger);\n\n_MenuTrigger.displayName = 'MenuTrigger';\n\nexport { _MenuTrigger as MenuTrigger };\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { usePopoverSync } from "../../../utils/react/usePopoverSync.js";
|
|
3
3
|
import { useEvent } from "../../../_internal/hooks/use-event.js";
|
|
4
4
|
import { MenuContext, useMenuContext } from "./context.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { DEFAULT_CLEAR_STYLES } from "../../../data/item-themes.js";
|
|
3
3
|
import { Space } from "../../layout/Space.js";
|
|
4
4
|
import { DEFAULT_BUTTON_STYLES } from "../Button/Button.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { ItemActionProvider, useItemActionContext } from "./ItemActionContext.js";
|
|
3
3
|
import { openLink, parseTo, performClickHandler, useAction } from "./use-action.js";
|
|
4
4
|
import { ItemAction } from "./ItemAction/ItemAction.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { mergeProps as mergeProps$1 } from "../../utils/react/mergeProps.js";
|
|
3
3
|
import { useEvent } from "../../_internal/hooks/use-event.js";
|
|
4
4
|
import { useFocus as useFocus$1 } from "../../utils/react/interactions.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { mergeProps as mergeProps$1 } from "../../utils/react/mergeProps.js";
|
|
3
3
|
import { usePopoverSync } from "../../utils/react/usePopoverSync.js";
|
|
4
4
|
import { useEvent } from "../../_internal/hooks/use-event.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { mergeProps as mergeProps$1 } from "../../utils/react/mergeProps.js";
|
|
3
3
|
import { usePopoverSync } from "../../utils/react/usePopoverSync.js";
|
|
4
4
|
import { useEvent } from "../../_internal/hooks/use-event.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { extractStyles } from "../../../utils/styles.js";
|
|
3
3
|
import { mergeProps as mergeProps$1 } from "../../../utils/react/mergeProps.js";
|
|
4
4
|
import { useFocus as useFocus$1 } from "../../../utils/react/interactions.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import themes_default from "../../../data/themes.js";
|
|
3
3
|
import { useAlert } from "./use-alert.js";
|
|
4
4
|
import { tasty } from "@tenphi/tasty";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { extractStyles } from "../../../utils/styles.js";
|
|
3
3
|
import { useDeprecationWarning } from "../../../_internal/hooks/use-deprecation-warning.js";
|
|
4
4
|
import { CONTAINER_STYLES, TEXT_STYLES, filterBaseProps } from "@tenphi/tasty";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { extractStyles } from "../../../utils/styles.js";
|
|
3
3
|
import { CONTAINER_STYLES, Element, filterBaseProps } from "@tenphi/tasty";
|
|
4
4
|
import { forwardRef } from "react";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { _Item } from "../Item/Item.js";
|
|
3
3
|
import themes_default from "../../../data/themes.js";
|
|
4
4
|
import { tasty } from "@tenphi/tasty";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { extractStyles } from "../../../utils/styles.js";
|
|
3
3
|
import { CONTAINER_STYLES, filterBaseProps, tasty } from "@tenphi/tasty";
|
|
4
4
|
import { forwardRef } from "react";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { extractStyles } from "../../utils/styles.js";
|
|
3
3
|
import { useSlotProps } from "../../utils/react/Slots.js";
|
|
4
4
|
import { CONTAINER_STYLES, TEXT_STYLES, filterBaseProps, tasty } from "@tenphi/tasty";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { extractStyles } from "../../../utils/styles.js";
|
|
3
3
|
import { useTimer } from "../../../_internal/hooks/use-timer/use-timer.js";
|
|
4
4
|
import { useI18n } from "../../../i18n/useI18n.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { _Tooltip } from "../../overlays/Tooltip/Tooltip.js";
|
|
3
3
|
import { TooltipTrigger } from "../../overlays/Tooltip/TooltipTrigger.js";
|
|
4
4
|
import { useI18n } from "../../../i18n/useI18n.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { extractStyles } from "../../../utils/styles.js";
|
|
3
3
|
import { mergeRefs } from "../../../utils/react/useCombinedRefs.js";
|
|
4
4
|
import { DisplayTransition } from "../../helpers/DisplayTransition/DisplayTransition.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { useSlotProps } from "../../utils/react/Slots.js";
|
|
3
3
|
import { useCombinedRefs } from "../../utils/react/useCombinedRefs.js";
|
|
4
4
|
import { BASE_STYLES, COLOR_STYLES, OUTER_STYLES, filterBaseProps, tasty } from "@tenphi/tasty";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { extractStyles } from "../../utils/styles.js";
|
|
3
3
|
import { useSlotProps } from "../../utils/react/Slots.js";
|
|
4
4
|
import { CONTAINER_STYLES, TEXT_STYLES, filterBaseProps, tasty } from "@tenphi/tasty";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { extractStyles } from "../../utils/styles.js";
|
|
3
3
|
import { useSlotProps } from "../../utils/react/Slots.js";
|
|
4
4
|
import { CONTAINER_STYLES, TEXT_STYLES, filterBaseProps, tasty } from "@tenphi/tasty";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { extractStyles } from "../../../utils/styles.js";
|
|
3
3
|
import { _Text } from "../Text.js";
|
|
4
4
|
import { useKeySymbols } from "../../../utils/react/useKeySymbols.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { ItemAction } from "../../actions/ItemAction/ItemAction.js";
|
|
3
3
|
import { ItemBadge } from "../ItemBadge/ItemBadge.js";
|
|
4
4
|
import { useI18n } from "../../../i18n/useI18n.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e5b4f54 | Cube Dev Team */
|
|
2
2
|
import { extractStyles } from "../../../utils/styles.js";
|
|
3
3
|
import { mergeProps as mergeProps$1 } from "../../../utils/react/mergeProps.js";
|
|
4
4
|
import { useEvent } from "../../../_internal/hooks/use-event.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InlineInput.js","names":["mergeProps"],"sources":["../../../../src/components/content/InlineInput/InlineInput.tsx"],"sourcesContent":["import { useControlledState } from '@react-stately/utils';\nimport {\n BaseProps,\n BLOCK_STYLES,\n BlockStyleProps,\n COLOR_STYLES,\n ColorStyleProps,\n filterBaseProps,\n OUTER_STYLES,\n OuterStyleProps,\n Styles,\n tasty,\n} from '@tenphi/tasty';\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n FocusScope,\n OverlayProps,\n useFocusRing,\n useFocusWithin,\n} from 'react-aria';\n\nimport { useEvent } from '../../../_internal/hooks';\nimport { mergeProps } from '../../../utils/react';\nimport { extractStyles } from '../../../utils/styles';\nimport { AutoTooltipValue, useAutoTooltip } from '../use-auto-tooltip';\n\nimport type {\n ChangeEvent,\n HTMLAttributes,\n KeyboardEvent,\n MouseEvent,\n ReactNode,\n RefObject,\n} from 'react';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type CubeInlineInputEditTrigger = 'dblclick' | 'click' | 'none';\n\nexport interface CubeInlineInputProps\n extends BaseProps,\n BlockStyleProps,\n OuterStyleProps,\n ColorStyleProps {\n /** Controlled value. When provided, the component is controlled. */\n value?: string;\n /** Initial value for uncontrolled usage. */\n defaultValue?: string;\n /**\n * Fires on commit *only when the value actually changed*. Use this to update\n * external state. Pair with `value` for the controlled pattern.\n */\n onChange?: (value: string) => void;\n\n /** Controlled editing state. When provided, the editing state is controlled. */\n isEditing?: boolean;\n /** Default editing state for uncontrolled usage. */\n defaultIsEditing?: boolean;\n /** Called when editing mode starts or ends. */\n onEditingChange?: (isEditing: boolean) => void;\n\n /**\n * Fires every time the user commits (Enter / submit-on-blur / `ref.stopEditing(true)`),\n * even if the value did not change. Use for side effects like analytics or\n * \"save\" toasts. For state updates, prefer `onChange`.\n *\n * May return a Promise. If the returned Promise **rejects**, the component\n * automatically reverts its optimistic display to the actual `value` prop —\n * this gives async-save flows free rollback on failure (in controlled mode).\n */\n onSubmit?: (value: string) => void | Promise<unknown>;\n /** Called when editing is cancelled (Escape or empty submit when `allowEmpty` is false). */\n onCancel?: () => void;\n\n /** How edit mode is activated from the display element. Default: `'dblclick'`. */\n editTrigger?: CubeInlineInputEditTrigger;\n /**\n * When true (default) the display element is keyboard-focusable and\n * responds to `Enter`, `F2` and `Space` by entering edit mode. Set to\n * `false` when a host (e.g. an editable tab inside a button) already\n * routes keyboard activation through `ref.startEditing()` — exposing the\n * display element as a separate tab stop would create a nested keyboard\n * focus inside the host.\n *\n * @default true\n */\n keyboardActivation?: boolean;\n /** Whether to submit when focus leaves the input. Default: `true`. */\n submitOnBlur?: boolean;\n /** Whether to trim the value on submit. Default: `true`. */\n trimOnSubmit?: boolean;\n /** When false, submitting an empty/whitespace value cancels instead. Default: `false`. */\n allowEmpty?: boolean;\n /** When true, edit mode cannot be entered (programmatically or otherwise). */\n isDisabled?: boolean;\n /** When true, edit mode cannot be entered, but the display reads as enabled. */\n isReadOnly?: boolean;\n\n /**\n * When true, applies a styled wrapper to the component (border, fill, padding,\n * fixed height) so it visually matches a `TextInput`. Useful when swapping a\n * field component (e.g. `Select`) for an `InlineInput` to rename / edit the\n * current value without a visual jump.\n *\n * @default false\n */\n isStyled?: boolean;\n\n /** Placeholder text shown in the input when the draft is empty. */\n placeholder?: string;\n /** Custom render for display (non-editing) mode. Receives the currently-displayed value (including optimistic). */\n renderDisplay?: (value: string) => ReactNode;\n /** ARIA label for the input (used when no visible label is associated). */\n 'aria-label'?: string;\n /** ARIA labelledby for the input. */\n 'aria-labelledby'?: string;\n\n /**\n * Tooltip behaviour for the display value:\n * - `true` (default): auto-tooltip — show the full value when the text is truncated.\n * - `false`: never show a tooltip.\n * - `string`: always show this tooltip text.\n * - object: full `TooltipProvider` configuration (with optional `auto`).\n *\n * The tooltip is automatically suppressed while editing and when `renderDisplay` is used.\n */\n tooltip?: AutoTooltipValue;\n /** Default tooltip placement. @default 'top' */\n tooltipPlacement?: OverlayProps['placement'];\n\n /** Convenience prop for styling the `Input` sub-element. Merged into `styles.Input`. */\n inputStyles?: Styles;\n}\n\nexport interface CubeInlineInputRef {\n /** Programmatically enter edit mode. */\n startEditing(): void;\n /** Programmatically exit edit mode. `submit=true` commits, `submit=false` cancels. Defaults to commit. */\n stopEditing(submit?: boolean): void;\n /** Focus the underlying element (input when editing, root span otherwise). */\n focus(): void;\n /** Current committed value (includes optimistic value if a parent hasn't synced yet). */\n getValue(): string;\n}\n\n// =============================================================================\n// Styled element\n// =============================================================================\n\nconst InlineInputRoot = tasty({\n as: 'span',\n styles: {\n // `inline-flex` with `alignItems: baseline` is used (instead of\n // `inline-block` + `overflow: hidden`) so the container's baseline comes\n // from the first flex item's content baseline. With `inline-block` +\n // `overflow: hidden`, the CSS spec forces the baseline to the bottom\n // margin edge, which visibly shifts the text upward inside surrounding\n // line boxes (notably inside Tabs' centered `Item.Label`).\n display: 'inline-flex',\n alignItems: {\n '': 'baseline',\n styled: 'center',\n },\n verticalAlign: {\n '': 'baseline',\n styled: 'middle',\n },\n position: 'relative',\n width: 'initial 100%',\n boxSizing: 'border-box',\n color: {\n '': 'inherit',\n styled: '#dark-02',\n 'styled & disabled': '#dark.30',\n },\n preset: {\n '': 'inherit',\n styled: 't3',\n },\n cursor: {\n '': 'inherit',\n 'editable & !editing': 'text',\n },\n fill: {\n '': '#clear',\n styled: '#surface',\n 'styled & disabled': '#disabled-surface',\n },\n border: {\n '': false,\n styled: true,\n 'styled & focused': '#primary-text',\n 'styled & disabled': true,\n },\n // Focus ring. Shown when the display element is keyboard-focused\n // (driven on the React side by `isFocusVisible`) and *always* while\n // editing — so swapping into the input always presents a clear focus\n // indicator regardless of how the user activated it (click vs keyboard).\n // In `styled` mode the border colour transition is enough to indicate\n // focus (matching `TextInput`'s visual), so the outline is suppressed.\n // Outline doesn't take layout space and respects rounded corners via\n // `outlineOffset`.\n outline: {\n '': '1bw #primary.0',\n 'focused & !styled': '1bw #primary',\n },\n outlineOffset: 1,\n radius: {\n '': 0,\n focused: true,\n styled: true,\n },\n padding: {\n '': 0,\n styled: '(.75x - 1bw) (1x - 1bw)',\n },\n height: {\n '': 'auto',\n styled: '$size-md',\n },\n transition: 'theme',\n\n // Display flex item: owns the truncation (`overflow: hidden` here is a\n // block-level rule that does *not* alter the parent's baseline, unlike\n // an `inline-block` overflow rule).\n Display: {\n display: 'block',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n width: 'initial 100%',\n preset: 'inherit',\n color: 'inherit',\n },\n\n Input: {\n recipe: 'reset input / input-autofill',\n preset: 'inherit',\n color: 'inherit',\n fill: '#clear',\n textAlign: 'left',\n // In `styled` mode the wrapper has a fixed size and we want the input\n // to fill it (matches `TextInput`). In the default inline mode the\n // input auto-sizes to its content via `$input-width`.\n width: {\n '': '1em $input-width 100%',\n styled: '0 100% initial',\n },\n '&::placeholder': { recipe: 'input-placeholder' },\n },\n\n Measure: {\n position: 'absolute',\n visibility: 'hidden',\n pointerEvents: 'none',\n whiteSpace: 'pre',\n preset: 'inherit',\n height: 0,\n overflow: 'hidden',\n },\n\n Placeholder: {\n recipe: 'input-placeholder',\n preset: 'inherit',\n },\n },\n});\n\nconst STYLE_PROPS = [...BLOCK_STYLES, ...OUTER_STYLES, ...COLOR_STYLES];\n\n// Grace window after a programmatic `startEditing()` during which a blur\n// (typically a closing overlay's focus restoration) re-focuses the input\n// rather than committing. ~500ms covers the Menu/Popover EXIT_DURATION\n// (350ms in `Overlay.tsx`) with margin.\nconst PROGRAMMATIC_EDIT_BLUR_GRACE_MS = 500;\n\n// =============================================================================\n// Component\n// =============================================================================\n\n/**\n * Inline editable text. Renders the value as inline content by default and\n * swaps to an auto-sizing text input when entering edit mode.\n *\n * Designed to drop into any text context (tab title, heading, paragraph,\n * table cell) without style customization: typography, color, and font family\n * are all inherited from the parent.\n *\n * Value and `isEditing` can each be controlled or uncontrolled independently.\n * Programmatic entry via the imperative ref (`startEditing`/`stopEditing`)\n * works regardless of `editTrigger`.\n */\nexport const InlineInput = forwardRef<CubeInlineInputRef, CubeInlineInputProps>(\n function InlineInput(allProps, ref) {\n const {\n value: valueProp,\n defaultValue,\n onChange,\n isEditing: isEditingProp,\n defaultIsEditing,\n onEditingChange,\n onSubmit,\n onCancel,\n editTrigger = 'dblclick',\n keyboardActivation = true,\n submitOnBlur = true,\n trimOnSubmit = true,\n allowEmpty = false,\n isDisabled = false,\n isReadOnly = false,\n isStyled = false,\n placeholder,\n renderDisplay,\n tooltip = true,\n tooltipPlacement = 'top',\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n qa,\n qaVal,\n styles: stylesProp,\n inputStyles,\n mods: customMods,\n tokens: customTokens,\n ...otherProps\n } = allProps;\n\n const isControlled = valueProp !== undefined;\n\n const inputRef = useRef<HTMLInputElement>(null);\n const measureRef = useRef<HTMLSpanElement>(null);\n const rootRef = useRef<HTMLSpanElement>(null);\n\n const [value, setValue] = useControlledState<string>(\n valueProp as string,\n (defaultValue ?? '') as string,\n onChange,\n );\n\n const [isEditing, setIsEditing] = useControlledState<boolean>(\n isEditingProp as boolean,\n (defaultIsEditing ?? false) as boolean,\n onEditingChange,\n );\n\n // Optimistic value. Holds the just-committed value while we wait for the\n // (potentially async) controlled parent to sync `value`. In uncontrolled\n // mode `value` updates immediately so this stays null after each render.\n const [optimisticValue, setOptimisticValue] = useState<string | null>(null);\n const displayedValue = optimisticValue ?? value;\n\n const [draft, setDraft] = useState<string>(value);\n const [inputWidth, setInputWidth] = useState<number | null>(null);\n\n // Reliable focus presence for the whole component, driven by\n // `useFocusWithin` (which, unlike `useFocusRing`/`useFocus` on a bare\n // span, has an element-removal fallback). Used to gate the display focus\n // ring so it can never get stuck on after editing ends or after focus\n // moves to another component.\n const [isFocusWithin, setIsFocusWithin] = useState(false);\n\n // Suppresses the display focus ring for a single programmatic focus\n // restore (when we return focus to the display span after a keyboard /\n // programmatic edit-end). Reset whenever focus truly leaves the component\n // so a later real keyboard Tab back shows the ring again.\n const [ringSuppressed, setRingSuppressed] = useState(false);\n\n // Token to invalidate in-flight onSubmit promises if a newer commit /\n // re-entry happens before they settle.\n const submitTokenRef = useRef(0);\n\n // Timestamp of the most recent programmatic `startEditing()` call (via\n // the imperative ref). Used to defeat a focus-theft race where a closing\n // overlay's `<FocusScope restoreFocus>` yanks focus back to its trigger\n // immediately after a consumer called `startEditing()` from inside the\n // overlay's `onAction` (e.g. a Tabs menu \"Rename\" item). Without this\n // guard the resulting blur would fire `submitOnBlur` and unmount the\n // input the user just opened.\n //\n // Cleared on first user interaction inside the input (`handleInputChange`\n // / `handleKeyDown`) and on leaving editing mode, so any later blur\n // commits normally.\n const programmaticEditStartRef = useRef<number | null>(null);\n\n // Set when an edit-end should return focus to the display span (keyboard\n // Enter/Escape, imperative `stopEditing`). NOT set for submit-on-blur /\n // tab-away, where focus has already moved elsewhere. Consumed by a layout\n // effect after the display span re-mounts.\n const pendingRestoreFocusRef = useRef(false);\n\n // Synchronous mirror of `isEditing`. We need this because cancel/commit\n // call user callbacks (`onCancel`/`onSubmit`) that may synchronously\n // re-focus another element — that causes a synchronous blur on the\n // input which would otherwise re-enter `commit` via `onBlurWithin` (the\n // state update from `setIsEditing(false)` isn't committed yet, so the\n // closure still sees `isEditing === true`).\n //\n // The ref is kept in sync via `useLayoutEffect` so concurrent renders\n // that get thrown away don't leak a stale value into the next commit.\n const isEditingRef = useRef(isEditing);\n\n useLayoutEffect(() => {\n isEditingRef.current = isEditing;\n }, [isEditing]);\n\n // Clear the optimistic value once `value` catches up or changes externally.\n useEffect(() => {\n setOptimisticValue(null);\n }, [value]);\n\n const enterEditing = useEvent(() => {\n if (isDisabled || isReadOnly || isEditing) return;\n // Invalidate any in-flight onSubmit promise — its outcome no longer\n // matters because the user is about to commit a new value anyway.\n submitTokenRef.current += 1;\n isEditingRef.current = true;\n // Start from the actual prop value, not optimistic — gives the user a\n // way to recover if a previous commit was rejected by the parent.\n setOptimisticValue(null);\n setDraft(value);\n setIsEditing(true);\n });\n\n // Whether an edit-end should return focus to the display span. Only when\n // this component owns its own keyboard/focus story (standalone usage).\n // Hosts that drive editing through `ref.startEditing()` with\n // `keyboardActivation={false}` (e.g. `Tabs`) keep ownership of focus.\n const canRestoreFocus = () =>\n keyboardActivation &&\n editTrigger !== 'none' &&\n !isDisabled &&\n !isReadOnly;\n\n const commit = useEvent((rawValue: string, restoreFocus = true) => {\n // Re-entry guard. `onSubmit`/`onCancel` may synchronously refocus and\n // trigger another blur-driven commit before the state update lands.\n if (!isEditingRef.current) return;\n\n const next = trimOnSubmit ? rawValue.trim() : rawValue;\n\n if (restoreFocus && canRestoreFocus()) {\n pendingRestoreFocusRef.current = true;\n }\n\n if (!next && !allowEmpty) {\n isEditingRef.current = false;\n programmaticEditStartRef.current = null;\n setIsEditing(false);\n onCancel?.();\n\n return;\n }\n\n const token = ++submitTokenRef.current;\n\n if (isControlled) {\n // Show the new value optimistically until the parent re-renders.\n setOptimisticValue(next);\n }\n isEditingRef.current = false;\n programmaticEditStartRef.current = null;\n setValue(next);\n setIsEditing(false);\n\n const result = onSubmit?.(next);\n // If onSubmit returns a Promise that rejects, the parent is signalling\n // a save failure — revert the optimistic value back to the actual prop.\n // We guard with a token so a slow rejection doesn't clobber a newer\n // commit's optimistic display.\n if (\n result != null &&\n typeof (result as Promise<unknown>).then === 'function'\n ) {\n (result as Promise<unknown>).then(\n () => {},\n () => {\n if (submitTokenRef.current === token && isControlled) {\n setOptimisticValue(null);\n }\n },\n );\n }\n });\n\n const cancel = useEvent((restoreFocus = true) => {\n if (!isEditingRef.current) return;\n if (restoreFocus && canRestoreFocus()) {\n pendingRestoreFocusRef.current = true;\n }\n isEditingRef.current = false;\n programmaticEditStartRef.current = null;\n setIsEditing(false);\n onCancel?.();\n });\n\n // Keep draft in sync with the external value while NOT editing.\n useEffect(() => {\n if (!isEditing) setDraft(value);\n }, [value, isEditing]);\n\n // Select all text synchronously when entering edit mode.\n useLayoutEffect(() => {\n if (!isEditing) return;\n inputRef.current?.select();\n }, [isEditing]);\n\n // Return focus to the display span after a keyboard / programmatic\n // edit-end so keyboard navigation continues from this control. The focus\n // is programmatic (react-aria treats it as non-keyboard) and we set\n // `ringSuppressed` so it does not draw a focus ring; a later real Tab to\n // the element resets the suppression (see `onFocusWithinChange`).\n //\n // `onSubmit`/`onCancel` may synchronously move focus elsewhere. When the\n // input unmounts, the browser drops focus to `<body>`, so we only restore\n // focus to the display span when focus actually landed there (or nowhere).\n // If a handler deliberately moved focus to another element, we leave it.\n useLayoutEffect(() => {\n if (isEditing || !pendingRestoreFocusRef.current) return;\n pendingRestoreFocusRef.current = false;\n\n const root = rootRef.current;\n if (!root) return;\n\n const active = root.ownerDocument.activeElement;\n const focusLost = !active || active === root.ownerDocument.body;\n // A handler moved focus to a real element outside this control — respect\n // it and don't pull focus back.\n if (!focusLost && !root.contains(active)) return;\n\n setRingSuppressed(true);\n root.focus();\n }, [isEditing]);\n\n // Measure the draft so the input width follows the typed glyphs.\n useLayoutEffect(() => {\n if (!isEditing) return;\n const measure = measureRef.current;\n\n if (!measure) return;\n setInputWidth(measure.scrollWidth);\n }, [isEditing, draft, placeholder]);\n\n const handleKeyDown = useEvent((e: KeyboardEvent<HTMLInputElement>) => {\n // User is interacting with the input — drop the post-`startEditing()`\n // blur guard so a subsequent click-away commits normally.\n programmaticEditStartRef.current = null;\n\n if (e.key === 'Enter') {\n e.preventDefault();\n commit(draft);\n\n return;\n }\n\n if (e.key === 'Escape') {\n e.preventDefault();\n cancel();\n\n return;\n }\n\n // Prevent the host (e.g. Tabs) from intercepting text-editing keys.\n if (\n e.key === 'ArrowLeft' ||\n e.key === 'ArrowRight' ||\n e.key === ' ' ||\n e.key === 'Delete' ||\n e.key === 'Backspace'\n ) {\n e.stopPropagation();\n }\n });\n\n const handleInputChange = useEvent((e: ChangeEvent<HTMLInputElement>) => {\n programmaticEditStartRef.current = null;\n setDraft(e.target.value);\n });\n\n // Keyboard focus-visible modality (mouse vs keyboard). Used together with\n // `isFocusWithin` to drive the display focus ring. We rely on\n // `useFocusWithin` (below) for the *presence* of focus because, unlike\n // `useFocusRing`/`useFocus` on a bare span, it has an element-removal\n // fallback — so the ring can never get stuck on after the inner input is\n // unmounted on edit-end or after focus moves away.\n const { isFocusVisible, focusProps: focusRingProps } = useFocusRing();\n\n // Always enabled so it reliably reports focus presence in BOTH display\n // and edit modes. The submit-on-blur logic is internally guarded by\n // `isEditingRef`, so running `onBlurWithin` in display mode is a no-op.\n const { focusWithinProps } = useFocusWithin({\n onFocusWithinChange: (within) => {\n setIsFocusWithin(within);\n // Once focus truly leaves the component, clear the one-shot ring\n // suppression so a later real keyboard Tab back shows the ring again.\n if (!within) setRingSuppressed(false);\n },\n onBlurWithin: () => {\n if (!isEditingRef.current) return;\n if (!submitOnBlur) return;\n\n // Spurious-blur guard. `useFocusWithin` fires a synthetic blur via its\n // element-removal fallback when the display span unmounts as we enter\n // edit mode (focus actually moved INTO the inner input). Ignore it if\n // focus is in fact still within the component.\n const active = rootRef.current?.ownerDocument.activeElement;\n if (active && rootRef.current?.contains(active)) return;\n\n // Grace-period guard against focus theft right after a programmatic\n // `startEditing()` — e.g. a `<FocusScope restoreFocus>` inside a\n // closing Menu popover yanking focus back to its trigger after the\n // consumer activated rename from `onAction`. Re-focus the input on\n // the next frame so the focus-stealing element finishes its own\n // handler first, then we steal focus back. The guard is cleared on\n // the first real user interaction with the input (keydown / input\n // change) so subsequent click-aways commit normally.\n const startedAt = programmaticEditStartRef.current;\n if (\n startedAt != null &&\n Date.now() - startedAt < PROGRAMMATIC_EDIT_BLUR_GRACE_MS &&\n isEditingRef.current\n ) {\n requestAnimationFrame(() => {\n if (isEditingRef.current) {\n inputRef.current?.focus();\n inputRef.current?.select();\n }\n });\n\n return;\n }\n\n // Focus has already moved elsewhere (tab-away / click-away), so do\n // NOT pull it back to the display span.\n commit(draft, false);\n },\n });\n\n const handleDblClick = useEvent((e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n enterEditing();\n });\n\n const handleClick = useEvent((e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n enterEditing();\n });\n\n // Keyboard activation from the display element (standalone usage).\n // Hosts that own keyboard handling themselves should pass\n // `keyboardActivation={false}` (see `TabButton` for an example).\n const handleRootKeyDown = useEvent((e: KeyboardEvent<HTMLSpanElement>) => {\n if (e.key === 'Enter' || e.key === 'F2' || e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n enterEditing();\n }\n });\n\n useImperativeHandle(\n ref,\n () => ({\n startEditing: () => {\n // Arm the grace-period blur guard for the imperative path only.\n // Pointer-triggered entries (dblclick / click) don't suffer from\n // the closing-overlay focus-theft race that motivates this guard.\n const wasEditing = isEditingRef.current;\n enterEditing();\n if (!wasEditing && isEditingRef.current) {\n programmaticEditStartRef.current = Date.now();\n }\n },\n stopEditing: (submit = true) => {\n if (!isEditingRef.current) return;\n if (submit) commit(draft);\n else cancel();\n },\n focus: () => {\n if (isEditingRef.current) inputRef.current?.focus();\n else rootRef.current?.focus();\n },\n getValue: () => displayedValue,\n }),\n [enterEditing, commit, cancel, draft, displayedValue],\n );\n\n const isEditable = editTrigger !== 'none' && !isDisabled && !isReadOnly;\n\n // `focused` controls the visible focus indicator on the root.\n //\n // While editing, the inner `<input>` always has focus (FocusScope\n // `autoFocus`), so we show the focus indicator on the root regardless\n // of how the user activated edit mode (click vs keyboard).\n //\n // In display mode we show the indicator only on keyboard focus\n // (`isFocusVisible`) AND when focus is actually within the component\n // (`isFocusWithin`) AND the display element is focusable (`isEditable`).\n // The `isFocusWithin` gate is the key fix: it reliably drops to `false`\n // on edit-end / tab-away (it has an element-removal fallback that\n // `useFocusRing` lacks on a bare span), so the ring can never get stuck\n // on. `ringSuppressed` hides the ring for a single programmatic focus\n // restore after a keyboard / programmatic edit-end.\n //\n // When `keyboardActivation` is `false` the host (e.g. `Tabs`) owns the\n // entire focus story for this control, so we suppress the focus ring\n // entirely — including while editing — to avoid drawing a redundant\n // indicator on top of the host's own focus ring.\n const showFocusRing =\n keyboardActivation &&\n (isEditing ||\n (isFocusVisible && isFocusWithin && isEditable && !ringSuppressed));\n\n const mods = useMemo(\n () => ({\n editing: isEditing,\n editable: isEditable,\n focused: showFocusRing,\n disabled: isDisabled,\n 'read-only': isReadOnly,\n styled: isStyled,\n empty: !displayedValue,\n ...customMods,\n }),\n [\n isEditing,\n isEditable,\n showFocusRing,\n isDisabled,\n isReadOnly,\n isStyled,\n displayedValue,\n customMods,\n ],\n );\n\n const mergedStyles = useMemo<Styles | undefined>(() => {\n if (!stylesProp && !inputStyles) return undefined;\n if (!inputStyles) return stylesProp;\n const existingInput =\n (stylesProp?.Input as Styles | undefined) ?? undefined;\n\n return {\n ...stylesProp,\n Input: existingInput\n ? { ...existingInput, ...inputStyles }\n : inputStyles,\n };\n }, [stylesProp, inputStyles]);\n\n const extractedStyles = extractStyles(\n otherProps,\n STYLE_PROPS,\n mergedStyles,\n );\n\n const tokens = useMemo(\n () => ({\n ...customTokens,\n '$input-width': inputWidth != null ? `${inputWidth}px` : 'auto',\n }),\n [customTokens, inputWidth],\n );\n\n // In display mode, render the placeholder when the value is empty so the\n // component remains visible / clickable. Consumers using `renderDisplay`\n // take full control and are responsible for handling empty values\n // themselves.\n const displayContent = renderDisplay\n ? renderDisplay(displayedValue)\n : displayedValue ||\n (placeholder ? (\n <span data-element=\"Placeholder\">{placeholder}</span>\n ) : (\n ''\n ));\n\n const baseProps = filterBaseProps(otherProps, { eventProps: true });\n\n // Overflow detection / auto-tooltip. Suppressed while editing (the input\n // owns the visible text and isn't truncated), and when the consumer\n // provides `renderDisplay` (they own the display story and should attach\n // their own tooltip if needed).\n const { labelRef: tooltipLabelRef, renderWithTooltip } = useAutoTooltip({\n tooltip: isEditing || renderDisplay ? false : tooltip,\n children: displayedValue,\n });\n\n // Wire pointer/keyboard activators only when relevant. Hosts that drive\n // editing through `ref.startEditing()` keep all of these `undefined` so\n // they don't intercept their own keyboard / focus story.\n const wantsClick = !isEditing && isEditable && editTrigger === 'click';\n const wantsDblClick =\n !isEditing && isEditable && editTrigger === 'dblclick';\n const wantsKeyboard = !isEditing && isEditable && keyboardActivation;\n\n const renderRoot = (\n triggerProps?: HTMLAttributes<HTMLElement>,\n tooltipRef?: RefObject<HTMLElement>,\n ) => {\n const handleRootRef = (element: HTMLSpanElement | null) => {\n rootRef.current = element;\n if (tooltipRef) {\n (tooltipRef as { current: HTMLElement | null }).current = element;\n }\n };\n\n // Overflow detection has to look at the truncating element, which is now\n // the inner `Display` (the root is `inline-flex` and doesn't clip). The\n // tooltip still anchors to the root via `tooltipRef` above.\n const handleDisplayRef = (element: HTMLSpanElement | null) => {\n tooltipLabelRef(element);\n };\n\n const a11yProps: HTMLAttributes<HTMLElement> = {};\n\n if (wantsKeyboard) {\n a11yProps.tabIndex = 0;\n a11yProps.role = 'button';\n a11yProps['aria-roledescription'] = 'editable text';\n if (ariaLabel) a11yProps['aria-label'] = ariaLabel;\n if (ariaLabelledby) a11yProps['aria-labelledby'] = ariaLabelledby;\n }\n\n if (isDisabled) a11yProps['aria-disabled'] = true;\n if (isReadOnly) a11yProps['aria-readonly'] = true;\n\n return (\n <InlineInputRoot\n ref={handleRootRef}\n qa={qa ?? 'InlineInput'}\n qaVal={qaVal}\n mods={mods}\n tokens={tokens}\n styles={extractedStyles}\n {...mergeProps(\n baseProps,\n focusWithinProps,\n // Always attach focusRingProps so the hook sees the blur event\n // when focus moves into the inner input on edit-mode entry. If\n // we only attached them while `wantsKeyboard` is true, the hook\n // would miss the blur (since `wantsKeyboard` flips to false the\n // moment editing starts), leaving `isFocused` stale and the\n // ring stuck on after editing ends. `useFocusRing` filters\n // bubbled focus from descendants internally (`target ===\n // currentTarget`), so spreading these on a non-focusable span\n // is a no-op.\n focusRingProps,\n triggerProps ?? {},\n {\n onDoubleClick: wantsDblClick ? handleDblClick : undefined,\n onClick: wantsClick ? handleClick : undefined,\n onKeyDown: wantsKeyboard ? handleRootKeyDown : undefined,\n ...a11yProps,\n },\n )}\n >\n {isEditing ? (\n <FocusScope autoFocus restoreFocus={false} contain={false}>\n <span ref={measureRef} data-element=\"Measure\" aria-hidden=\"true\">\n {draft || placeholder || ' '}\n </span>\n <input\n ref={inputRef}\n data-element=\"Input\"\n type=\"text\"\n value={draft}\n placeholder={placeholder}\n disabled={isDisabled}\n readOnly={isReadOnly}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n />\n </FocusScope>\n ) : (\n <span ref={handleDisplayRef} data-element=\"Display\">\n {displayContent}\n </span>\n )}\n </InlineInputRoot>\n );\n };\n\n return renderWithTooltip(renderRoot, tooltipPlacement);\n },\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InlineInput.js","names":["mergeProps"],"sources":["../../../../src/components/content/InlineInput/InlineInput.tsx"],"sourcesContent":["import { useControlledState } from '@react-stately/utils';\nimport {\n BaseProps,\n BLOCK_STYLES,\n BlockStyleProps,\n COLOR_STYLES,\n ColorStyleProps,\n filterBaseProps,\n OUTER_STYLES,\n OuterStyleProps,\n Styles,\n tasty,\n} from '@tenphi/tasty';\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n FocusScope,\n OverlayProps,\n useFocusRing,\n useFocusWithin,\n} from 'react-aria';\n\nimport { useEvent } from '../../../_internal/hooks';\nimport { mergeProps } from '../../../utils/react';\nimport { extractStyles } from '../../../utils/styles';\nimport { AutoTooltipValue, useAutoTooltip } from '../use-auto-tooltip';\n\nimport type {\n ChangeEvent,\n HTMLAttributes,\n KeyboardEvent,\n MouseEvent,\n ReactNode,\n RefObject,\n} from 'react';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type CubeInlineInputEditTrigger = 'dblclick' | 'click' | 'none';\n\nexport interface CubeInlineInputProps\n extends BaseProps,\n BlockStyleProps,\n OuterStyleProps,\n ColorStyleProps {\n /** Controlled value. When provided, the component is controlled. */\n value?: string;\n /** Initial value for uncontrolled usage. */\n defaultValue?: string;\n /**\n * Fires on commit *only when the value actually changed*. Use this to update\n * external state. Pair with `value` for the controlled pattern.\n */\n onChange?: (value: string) => void;\n\n /** Controlled editing state. When provided, the editing state is controlled. */\n isEditing?: boolean;\n /** Default editing state for uncontrolled usage. */\n defaultIsEditing?: boolean;\n /** Called when editing mode starts or ends. */\n onEditingChange?: (isEditing: boolean) => void;\n\n /**\n * Fires every time the user commits (Enter / submit-on-blur / `ref.stopEditing(true)`),\n * even if the value did not change. Use for side effects like analytics or\n * \"save\" toasts. For state updates, prefer `onChange`.\n *\n * May return a Promise. If the returned Promise **rejects**, the component\n * automatically reverts its optimistic display to the actual `value` prop —\n * this gives async-save flows free rollback on failure (in controlled mode).\n */\n onSubmit?: (value: string) => void | Promise<unknown>;\n /** Called when editing is cancelled (Escape or empty submit when `allowEmpty` is false). */\n onCancel?: () => void;\n\n /** How edit mode is activated from the display element. Default: `'dblclick'`. */\n editTrigger?: CubeInlineInputEditTrigger;\n /**\n * When true (default) the display element is keyboard-focusable and\n * responds to `Enter`, `F2` and `Space` by entering edit mode. Set to\n * `false` when a host (e.g. an editable tab inside a button) already\n * routes keyboard activation through `ref.startEditing()` — exposing the\n * display element as a separate tab stop would create a nested keyboard\n * focus inside the host.\n *\n * @default true\n */\n keyboardActivation?: boolean;\n /** Whether to submit when focus leaves the input. Default: `true`. */\n submitOnBlur?: boolean;\n /** Whether to trim the value on submit. Default: `true`. */\n trimOnSubmit?: boolean;\n /** When false, submitting an empty/whitespace value cancels instead. Default: `false`. */\n allowEmpty?: boolean;\n /** When true, edit mode cannot be entered (programmatically or otherwise). */\n isDisabled?: boolean;\n /** When true, edit mode cannot be entered, but the display reads as enabled. */\n isReadOnly?: boolean;\n\n /**\n * When true, applies a styled wrapper to the component (border, fill, padding,\n * fixed height) so it visually matches a `TextInput`. Useful when swapping a\n * field component (e.g. `Select`) for an `InlineInput` to rename / edit the\n * current value without a visual jump.\n *\n * @default false\n */\n isStyled?: boolean;\n\n /** Placeholder text shown in the input when the draft is empty. */\n placeholder?: string;\n /** Custom render for display (non-editing) mode. Receives the currently-displayed value (including optimistic). */\n renderDisplay?: (value: string) => ReactNode;\n /** ARIA label for the input (used when no visible label is associated). */\n 'aria-label'?: string;\n /** ARIA labelledby for the input. */\n 'aria-labelledby'?: string;\n\n /**\n * Tooltip behaviour for the display value:\n * - `true` (default): auto-tooltip — show the full value when the text is truncated.\n * - `false`: never show a tooltip.\n * - `string`: always show this tooltip text.\n * - object: full `TooltipProvider` configuration (with optional `auto`).\n *\n * The tooltip is automatically suppressed while editing and when `renderDisplay` is used.\n */\n tooltip?: AutoTooltipValue;\n /** Default tooltip placement. @default 'top' */\n tooltipPlacement?: OverlayProps['placement'];\n\n /** Convenience prop for styling the `Input` sub-element. Merged into `styles.Input`. */\n inputStyles?: Styles;\n}\n\nexport interface CubeInlineInputRef {\n /** Programmatically enter edit mode. */\n startEditing(): void;\n /** Programmatically exit edit mode. `submit=true` commits, `submit=false` cancels. Defaults to commit. */\n stopEditing(submit?: boolean): void;\n /** Focus the underlying element (input when editing, root span otherwise). */\n focus(): void;\n /** Current committed value (includes optimistic value if a parent hasn't synced yet). */\n getValue(): string;\n}\n\n// =============================================================================\n// Styled element\n// =============================================================================\n\nconst InlineInputRoot = tasty({\n as: 'span',\n styles: {\n // `inline-flex` with `alignItems: baseline` is used (instead of\n // `inline-block` + `overflow: hidden`) so the container's baseline comes\n // from the first flex item's content baseline. With `inline-block` +\n // `overflow: hidden`, the CSS spec forces the baseline to the bottom\n // margin edge, which visibly shifts the text upward inside surrounding\n // line boxes (notably inside Tabs' centered `Item.Label`).\n display: 'inline-flex',\n alignItems: {\n '': 'baseline',\n styled: 'center',\n },\n verticalAlign: {\n '': 'baseline',\n styled: 'middle',\n },\n position: 'relative',\n width: 'initial 100%',\n boxSizing: 'border-box',\n color: {\n '': 'inherit',\n styled: '#dark-02',\n 'styled & disabled': '#dark.30',\n },\n preset: {\n '': 'inherit',\n styled: 't3',\n },\n cursor: {\n '': 'inherit',\n 'editable & !editing': 'text',\n },\n fill: {\n '': '#clear',\n styled: '#surface',\n 'styled & disabled': '#disabled-surface',\n },\n border: {\n '': false,\n styled: true,\n 'styled & focused': '#primary-text',\n 'styled & disabled': true,\n },\n // Focus ring. Shown when the display element is keyboard-focused\n // (driven on the React side by `isFocusVisible`) and *always* while\n // editing — so swapping into the input always presents a clear focus\n // indicator regardless of how the user activated it (click vs keyboard).\n // In `styled` mode the border colour transition is enough to indicate\n // focus (matching `TextInput`'s visual), so the outline is suppressed.\n // Outline doesn't take layout space and respects rounded corners via\n // `outlineOffset`.\n outline: {\n '': '1bw #primary.0',\n 'focused & !styled': '1bw #primary',\n },\n outlineOffset: 1,\n radius: {\n '': 0,\n focused: true,\n styled: true,\n },\n padding: {\n '': 0,\n styled: '(.75x - 1bw) (1x - 1bw)',\n },\n height: {\n '': 'auto',\n styled: '$size-md',\n },\n transition: 'theme',\n\n // Display flex item: owns the truncation (`overflow: hidden` here is a\n // block-level rule that does *not* alter the parent's baseline, unlike\n // an `inline-block` overflow rule).\n Display: {\n display: 'block',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n width: 'initial 100%',\n preset: 'inherit',\n color: 'inherit',\n },\n\n Input: {\n recipe: 'reset input / input-autofill',\n preset: 'inherit',\n color: 'inherit',\n fill: '#clear',\n textAlign: 'left',\n // In `styled` mode the wrapper has a fixed size and we want the input\n // to fill it (matches `TextInput`). In the default inline mode the\n // input auto-sizes to its content via `$input-width`.\n width: {\n '': '1em $input-width 100%',\n styled: '0 100% initial',\n },\n '&::placeholder': { recipe: 'input-placeholder' },\n },\n\n Measure: {\n position: 'absolute',\n visibility: 'hidden',\n pointerEvents: 'none',\n whiteSpace: 'pre',\n preset: 'inherit',\n height: 0,\n overflow: 'hidden',\n },\n\n Placeholder: {\n recipe: 'input-placeholder',\n preset: 'inherit',\n },\n },\n});\n\nconst STYLE_PROPS = [...BLOCK_STYLES, ...OUTER_STYLES, ...COLOR_STYLES];\n\n// Grace window after a programmatic `startEditing()` during which a blur\n// re-focuses the input rather than committing. ~500ms covers the\n// Menu/Popover EXIT_DURATION (350ms in `Overlay.tsx`) with margin, since a\n// host that starts editing from a closing overlay is the case that needs the\n// widest window.\nconst PROGRAMMATIC_EDIT_BLUR_GRACE_MS = 500;\n\n// =============================================================================\n// Component\n// =============================================================================\n\n/**\n * Inline editable text. Renders the value as inline content by default and\n * swaps to an auto-sizing text input when entering edit mode.\n *\n * Designed to drop into any text context (tab title, heading, paragraph,\n * table cell) without style customization: typography, color, and font family\n * are all inherited from the parent.\n *\n * Value and `isEditing` can each be controlled or uncontrolled independently.\n * Programmatic entry via the imperative ref (`startEditing`/`stopEditing`)\n * works regardless of `editTrigger`.\n */\nexport const InlineInput = forwardRef<CubeInlineInputRef, CubeInlineInputProps>(\n function InlineInput(allProps, ref) {\n const {\n value: valueProp,\n defaultValue,\n onChange,\n isEditing: isEditingProp,\n defaultIsEditing,\n onEditingChange,\n onSubmit,\n onCancel,\n editTrigger = 'dblclick',\n keyboardActivation = true,\n submitOnBlur = true,\n trimOnSubmit = true,\n allowEmpty = false,\n isDisabled = false,\n isReadOnly = false,\n isStyled = false,\n placeholder,\n renderDisplay,\n tooltip = true,\n tooltipPlacement = 'top',\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n qa,\n qaVal,\n styles: stylesProp,\n inputStyles,\n mods: customMods,\n tokens: customTokens,\n ...otherProps\n } = allProps;\n\n const isControlled = valueProp !== undefined;\n\n const inputRef = useRef<HTMLInputElement>(null);\n const measureRef = useRef<HTMLSpanElement>(null);\n const rootRef = useRef<HTMLSpanElement>(null);\n\n const [value, setValue] = useControlledState<string>(\n valueProp as string,\n (defaultValue ?? '') as string,\n onChange,\n );\n\n const [isEditing, setIsEditing] = useControlledState<boolean>(\n isEditingProp as boolean,\n (defaultIsEditing ?? false) as boolean,\n onEditingChange,\n );\n\n // Optimistic value. Holds the just-committed value while we wait for the\n // (potentially async) controlled parent to sync `value`. In uncontrolled\n // mode `value` updates immediately so this stays null after each render.\n const [optimisticValue, setOptimisticValue] = useState<string | null>(null);\n const displayedValue = optimisticValue ?? value;\n\n const [draft, setDraft] = useState<string>(value);\n const [inputWidth, setInputWidth] = useState<number | null>(null);\n\n // Reliable focus presence for the whole component, driven by\n // `useFocusWithin` (which, unlike `useFocusRing`/`useFocus` on a bare\n // span, has an element-removal fallback). Used to gate the display focus\n // ring so it can never get stuck on after editing ends or after focus\n // moves to another component.\n const [isFocusWithin, setIsFocusWithin] = useState(false);\n\n // Suppresses the display focus ring for a single programmatic focus\n // restore (when we return focus to the display span after a keyboard /\n // programmatic edit-end). Reset whenever focus truly leaves the component\n // so a later real keyboard Tab back shows the ring again.\n const [ringSuppressed, setRingSuppressed] = useState(false);\n\n // Token to invalidate in-flight onSubmit promises if a newer commit /\n // re-entry happens before they settle.\n const submitTokenRef = useRef(0);\n\n // Timestamp of the most recent programmatic `startEditing()` call (via\n // the imperative ref). Used to defeat a focus-theft race: something else\n // takes focus in the same tick the input mounts, and the resulting blur\n // would fire `submitOnBlur` and unmount the input the user just opened.\n //\n // The thief varies by host — a host's own focus restoration (`TabButton`\n // re-focuses the tab button when editing ends), a collection's focus\n // manager, or an overlay closing around the `startEditing()` call. It is\n // NOT the closing `Menu` popover: `MenuTrigger` leaves focus alone once\n // an action has moved it (see CUB-3962). The guard is host-agnostic on\n // purpose — the imperative path cannot know who else wants focus.\n //\n // Cleared on first user interaction inside the input (`handleInputChange`\n // / `handleKeyDown`) and on leaving editing mode, so any later blur\n // commits normally.\n const programmaticEditStartRef = useRef<number | null>(null);\n\n // Set when an edit-end should return focus to the display span (keyboard\n // Enter/Escape, imperative `stopEditing`). NOT set for submit-on-blur /\n // tab-away, where focus has already moved elsewhere. Consumed by a layout\n // effect after the display span re-mounts.\n const pendingRestoreFocusRef = useRef(false);\n\n // Synchronous mirror of `isEditing`. We need this because cancel/commit\n // call user callbacks (`onCancel`/`onSubmit`) that may synchronously\n // re-focus another element — that causes a synchronous blur on the\n // input which would otherwise re-enter `commit` via `onBlurWithin` (the\n // state update from `setIsEditing(false)` isn't committed yet, so the\n // closure still sees `isEditing === true`).\n //\n // The ref is kept in sync via `useLayoutEffect` so concurrent renders\n // that get thrown away don't leak a stale value into the next commit.\n const isEditingRef = useRef(isEditing);\n\n useLayoutEffect(() => {\n isEditingRef.current = isEditing;\n }, [isEditing]);\n\n // Clear the optimistic value once `value` catches up or changes externally.\n useEffect(() => {\n setOptimisticValue(null);\n }, [value]);\n\n const enterEditing = useEvent(() => {\n if (isDisabled || isReadOnly || isEditing) return;\n // Invalidate any in-flight onSubmit promise — its outcome no longer\n // matters because the user is about to commit a new value anyway.\n submitTokenRef.current += 1;\n isEditingRef.current = true;\n // Start from the actual prop value, not optimistic — gives the user a\n // way to recover if a previous commit was rejected by the parent.\n setOptimisticValue(null);\n setDraft(value);\n setIsEditing(true);\n });\n\n // Whether an edit-end should return focus to the display span. Only when\n // this component owns its own keyboard/focus story (standalone usage).\n // Hosts that drive editing through `ref.startEditing()` with\n // `keyboardActivation={false}` (e.g. `Tabs`) keep ownership of focus.\n const canRestoreFocus = () =>\n keyboardActivation &&\n editTrigger !== 'none' &&\n !isDisabled &&\n !isReadOnly;\n\n const commit = useEvent((rawValue: string, restoreFocus = true) => {\n // Re-entry guard. `onSubmit`/`onCancel` may synchronously refocus and\n // trigger another blur-driven commit before the state update lands.\n if (!isEditingRef.current) return;\n\n const next = trimOnSubmit ? rawValue.trim() : rawValue;\n\n if (restoreFocus && canRestoreFocus()) {\n pendingRestoreFocusRef.current = true;\n }\n\n if (!next && !allowEmpty) {\n isEditingRef.current = false;\n programmaticEditStartRef.current = null;\n setIsEditing(false);\n onCancel?.();\n\n return;\n }\n\n const token = ++submitTokenRef.current;\n\n if (isControlled) {\n // Show the new value optimistically until the parent re-renders.\n setOptimisticValue(next);\n }\n isEditingRef.current = false;\n programmaticEditStartRef.current = null;\n setValue(next);\n setIsEditing(false);\n\n const result = onSubmit?.(next);\n // If onSubmit returns a Promise that rejects, the parent is signalling\n // a save failure — revert the optimistic value back to the actual prop.\n // We guard with a token so a slow rejection doesn't clobber a newer\n // commit's optimistic display.\n if (\n result != null &&\n typeof (result as Promise<unknown>).then === 'function'\n ) {\n (result as Promise<unknown>).then(\n () => {},\n () => {\n if (submitTokenRef.current === token && isControlled) {\n setOptimisticValue(null);\n }\n },\n );\n }\n });\n\n const cancel = useEvent((restoreFocus = true) => {\n if (!isEditingRef.current) return;\n if (restoreFocus && canRestoreFocus()) {\n pendingRestoreFocusRef.current = true;\n }\n isEditingRef.current = false;\n programmaticEditStartRef.current = null;\n setIsEditing(false);\n onCancel?.();\n });\n\n // Keep draft in sync with the external value while NOT editing.\n useEffect(() => {\n if (!isEditing) setDraft(value);\n }, [value, isEditing]);\n\n // Select all text synchronously when entering edit mode.\n useLayoutEffect(() => {\n if (!isEditing) return;\n inputRef.current?.select();\n }, [isEditing]);\n\n // Return focus to the display span after a keyboard / programmatic\n // edit-end so keyboard navigation continues from this control. The focus\n // is programmatic (react-aria treats it as non-keyboard) and we set\n // `ringSuppressed` so it does not draw a focus ring; a later real Tab to\n // the element resets the suppression (see `onFocusWithinChange`).\n //\n // `onSubmit`/`onCancel` may synchronously move focus elsewhere. When the\n // input unmounts, the browser drops focus to `<body>`, so we only restore\n // focus to the display span when focus actually landed there (or nowhere).\n // If a handler deliberately moved focus to another element, we leave it.\n useLayoutEffect(() => {\n if (isEditing || !pendingRestoreFocusRef.current) return;\n pendingRestoreFocusRef.current = false;\n\n const root = rootRef.current;\n if (!root) return;\n\n const active = root.ownerDocument.activeElement;\n const focusLost = !active || active === root.ownerDocument.body;\n // A handler moved focus to a real element outside this control — respect\n // it and don't pull focus back.\n if (!focusLost && !root.contains(active)) return;\n\n setRingSuppressed(true);\n root.focus();\n }, [isEditing]);\n\n // Measure the draft so the input width follows the typed glyphs.\n useLayoutEffect(() => {\n if (!isEditing) return;\n const measure = measureRef.current;\n\n if (!measure) return;\n setInputWidth(measure.scrollWidth);\n }, [isEditing, draft, placeholder]);\n\n const handleKeyDown = useEvent((e: KeyboardEvent<HTMLInputElement>) => {\n // User is interacting with the input — drop the post-`startEditing()`\n // blur guard so a subsequent click-away commits normally.\n programmaticEditStartRef.current = null;\n\n if (e.key === 'Enter') {\n e.preventDefault();\n commit(draft);\n\n return;\n }\n\n if (e.key === 'Escape') {\n e.preventDefault();\n cancel();\n\n return;\n }\n\n // Prevent the host (e.g. Tabs) from intercepting text-editing keys.\n if (\n e.key === 'ArrowLeft' ||\n e.key === 'ArrowRight' ||\n e.key === ' ' ||\n e.key === 'Delete' ||\n e.key === 'Backspace'\n ) {\n e.stopPropagation();\n }\n });\n\n const handleInputChange = useEvent((e: ChangeEvent<HTMLInputElement>) => {\n programmaticEditStartRef.current = null;\n setDraft(e.target.value);\n });\n\n // Keyboard focus-visible modality (mouse vs keyboard). Used together with\n // `isFocusWithin` to drive the display focus ring. We rely on\n // `useFocusWithin` (below) for the *presence* of focus because, unlike\n // `useFocusRing`/`useFocus` on a bare span, it has an element-removal\n // fallback — so the ring can never get stuck on after the inner input is\n // unmounted on edit-end or after focus moves away.\n const { isFocusVisible, focusProps: focusRingProps } = useFocusRing();\n\n // Always enabled so it reliably reports focus presence in BOTH display\n // and edit modes. The submit-on-blur logic is internally guarded by\n // `isEditingRef`, so running `onBlurWithin` in display mode is a no-op.\n const { focusWithinProps } = useFocusWithin({\n onFocusWithinChange: (within) => {\n setIsFocusWithin(within);\n // Once focus truly leaves the component, clear the one-shot ring\n // suppression so a later real keyboard Tab back shows the ring again.\n if (!within) setRingSuppressed(false);\n },\n onBlurWithin: () => {\n if (!isEditingRef.current) return;\n if (!submitOnBlur) return;\n\n // Spurious-blur guard. `useFocusWithin` fires a synthetic blur via its\n // element-removal fallback when the display span unmounts as we enter\n // edit mode (focus actually moved INTO the inner input). Ignore it if\n // focus is in fact still within the component.\n const active = rootRef.current?.ownerDocument.activeElement;\n if (active && rootRef.current?.contains(active)) return;\n\n // Grace-period guard against focus theft right after a programmatic\n // `startEditing()` — see `programmaticEditStartRef` for who steals it.\n // Re-focus the input on the next frame so the focus-stealing element\n // finishes its own handler first, then we steal focus back. The guard\n // is cleared on the first real user interaction with the input\n // (keydown / input change) so subsequent click-aways commit normally.\n const startedAt = programmaticEditStartRef.current;\n if (\n startedAt != null &&\n Date.now() - startedAt < PROGRAMMATIC_EDIT_BLUR_GRACE_MS &&\n isEditingRef.current\n ) {\n requestAnimationFrame(() => {\n if (isEditingRef.current) {\n inputRef.current?.focus();\n inputRef.current?.select();\n }\n });\n\n return;\n }\n\n // Focus has already moved elsewhere (tab-away / click-away), so do\n // NOT pull it back to the display span.\n commit(draft, false);\n },\n });\n\n const handleDblClick = useEvent((e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n enterEditing();\n });\n\n const handleClick = useEvent((e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n enterEditing();\n });\n\n // Keyboard activation from the display element (standalone usage).\n // Hosts that own keyboard handling themselves should pass\n // `keyboardActivation={false}` (see `TabButton` for an example).\n const handleRootKeyDown = useEvent((e: KeyboardEvent<HTMLSpanElement>) => {\n if (e.key === 'Enter' || e.key === 'F2' || e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n enterEditing();\n }\n });\n\n useImperativeHandle(\n ref,\n () => ({\n startEditing: () => {\n // Arm the grace-period blur guard for the imperative path only.\n // Pointer-triggered entries (dblclick / click) don't suffer from\n // the focus-theft race that motivates this guard — the user's own\n // press is what put focus here.\n const wasEditing = isEditingRef.current;\n enterEditing();\n if (!wasEditing && isEditingRef.current) {\n programmaticEditStartRef.current = Date.now();\n }\n },\n stopEditing: (submit = true) => {\n if (!isEditingRef.current) return;\n if (submit) commit(draft);\n else cancel();\n },\n focus: () => {\n if (isEditingRef.current) inputRef.current?.focus();\n else rootRef.current?.focus();\n },\n getValue: () => displayedValue,\n }),\n [enterEditing, commit, cancel, draft, displayedValue],\n );\n\n const isEditable = editTrigger !== 'none' && !isDisabled && !isReadOnly;\n\n // `focused` controls the visible focus indicator on the root.\n //\n // While editing, the inner `<input>` always has focus (FocusScope\n // `autoFocus`), so we show the focus indicator on the root regardless\n // of how the user activated edit mode (click vs keyboard).\n //\n // In display mode we show the indicator only on keyboard focus\n // (`isFocusVisible`) AND when focus is actually within the component\n // (`isFocusWithin`) AND the display element is focusable (`isEditable`).\n // The `isFocusWithin` gate is the key fix: it reliably drops to `false`\n // on edit-end / tab-away (it has an element-removal fallback that\n // `useFocusRing` lacks on a bare span), so the ring can never get stuck\n // on. `ringSuppressed` hides the ring for a single programmatic focus\n // restore after a keyboard / programmatic edit-end.\n //\n // When `keyboardActivation` is `false` the host (e.g. `Tabs`) owns the\n // entire focus story for this control, so we suppress the focus ring\n // entirely — including while editing — to avoid drawing a redundant\n // indicator on top of the host's own focus ring.\n const showFocusRing =\n keyboardActivation &&\n (isEditing ||\n (isFocusVisible && isFocusWithin && isEditable && !ringSuppressed));\n\n const mods = useMemo(\n () => ({\n editing: isEditing,\n editable: isEditable,\n focused: showFocusRing,\n disabled: isDisabled,\n 'read-only': isReadOnly,\n styled: isStyled,\n empty: !displayedValue,\n ...customMods,\n }),\n [\n isEditing,\n isEditable,\n showFocusRing,\n isDisabled,\n isReadOnly,\n isStyled,\n displayedValue,\n customMods,\n ],\n );\n\n const mergedStyles = useMemo<Styles | undefined>(() => {\n if (!stylesProp && !inputStyles) return undefined;\n if (!inputStyles) return stylesProp;\n const existingInput =\n (stylesProp?.Input as Styles | undefined) ?? undefined;\n\n return {\n ...stylesProp,\n Input: existingInput\n ? { ...existingInput, ...inputStyles }\n : inputStyles,\n };\n }, [stylesProp, inputStyles]);\n\n const extractedStyles = extractStyles(\n otherProps,\n STYLE_PROPS,\n mergedStyles,\n );\n\n const tokens = useMemo(\n () => ({\n ...customTokens,\n '$input-width': inputWidth != null ? `${inputWidth}px` : 'auto',\n }),\n [customTokens, inputWidth],\n );\n\n // In display mode, render the placeholder when the value is empty so the\n // component remains visible / clickable. Consumers using `renderDisplay`\n // take full control and are responsible for handling empty values\n // themselves.\n const displayContent = renderDisplay\n ? renderDisplay(displayedValue)\n : displayedValue ||\n (placeholder ? (\n <span data-element=\"Placeholder\">{placeholder}</span>\n ) : (\n ''\n ));\n\n const baseProps = filterBaseProps(otherProps, { eventProps: true });\n\n // Overflow detection / auto-tooltip. Suppressed while editing (the input\n // owns the visible text and isn't truncated), and when the consumer\n // provides `renderDisplay` (they own the display story and should attach\n // their own tooltip if needed).\n const { labelRef: tooltipLabelRef, renderWithTooltip } = useAutoTooltip({\n tooltip: isEditing || renderDisplay ? false : tooltip,\n children: displayedValue,\n });\n\n // Wire pointer/keyboard activators only when relevant. Hosts that drive\n // editing through `ref.startEditing()` keep all of these `undefined` so\n // they don't intercept their own keyboard / focus story.\n const wantsClick = !isEditing && isEditable && editTrigger === 'click';\n const wantsDblClick =\n !isEditing && isEditable && editTrigger === 'dblclick';\n const wantsKeyboard = !isEditing && isEditable && keyboardActivation;\n\n const renderRoot = (\n triggerProps?: HTMLAttributes<HTMLElement>,\n tooltipRef?: RefObject<HTMLElement>,\n ) => {\n const handleRootRef = (element: HTMLSpanElement | null) => {\n rootRef.current = element;\n if (tooltipRef) {\n (tooltipRef as { current: HTMLElement | null }).current = element;\n }\n };\n\n // Overflow detection has to look at the truncating element, which is now\n // the inner `Display` (the root is `inline-flex` and doesn't clip). The\n // tooltip still anchors to the root via `tooltipRef` above.\n const handleDisplayRef = (element: HTMLSpanElement | null) => {\n tooltipLabelRef(element);\n };\n\n const a11yProps: HTMLAttributes<HTMLElement> = {};\n\n if (wantsKeyboard) {\n a11yProps.tabIndex = 0;\n a11yProps.role = 'button';\n a11yProps['aria-roledescription'] = 'editable text';\n if (ariaLabel) a11yProps['aria-label'] = ariaLabel;\n if (ariaLabelledby) a11yProps['aria-labelledby'] = ariaLabelledby;\n }\n\n if (isDisabled) a11yProps['aria-disabled'] = true;\n if (isReadOnly) a11yProps['aria-readonly'] = true;\n\n return (\n <InlineInputRoot\n ref={handleRootRef}\n qa={qa ?? 'InlineInput'}\n qaVal={qaVal}\n mods={mods}\n tokens={tokens}\n styles={extractedStyles}\n {...mergeProps(\n baseProps,\n focusWithinProps,\n // Always attach focusRingProps so the hook sees the blur event\n // when focus moves into the inner input on edit-mode entry. If\n // we only attached them while `wantsKeyboard` is true, the hook\n // would miss the blur (since `wantsKeyboard` flips to false the\n // moment editing starts), leaving `isFocused` stale and the\n // ring stuck on after editing ends. `useFocusRing` filters\n // bubbled focus from descendants internally (`target ===\n // currentTarget`), so spreading these on a non-focusable span\n // is a no-op.\n focusRingProps,\n triggerProps ?? {},\n {\n onDoubleClick: wantsDblClick ? handleDblClick : undefined,\n onClick: wantsClick ? handleClick : undefined,\n onKeyDown: wantsKeyboard ? handleRootKeyDown : undefined,\n ...a11yProps,\n },\n )}\n >\n {isEditing ? (\n <FocusScope autoFocus restoreFocus={false} contain={false}>\n <span ref={measureRef} data-element=\"Measure\" aria-hidden=\"true\">\n {draft || placeholder || ' '}\n </span>\n <input\n ref={inputRef}\n data-element=\"Input\"\n type=\"text\"\n value={draft}\n placeholder={placeholder}\n disabled={isDisabled}\n readOnly={isReadOnly}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n />\n </FocusScope>\n ) : (\n <span ref={handleDisplayRef} data-element=\"Display\">\n {displayContent}\n </span>\n )}\n </InlineInputRoot>\n );\n };\n\n return renderWithTooltip(renderRoot, tooltipPlacement);\n },\n);\n"],"mappings":"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"}
|