@cube-dev/ui-kit 0.136.1 → 0.137.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CHANGELOG.md +36 -0
- package/dist/_internal/hooks/use-chained-callback.js +1 -1
- package/dist/_internal/hooks/use-debounced-value.js +1 -1
- package/dist/_internal/hooks/use-deprecation-warning.js +1 -1
- package/dist/_internal/hooks/use-event.js +1 -1
- package/dist/_internal/hooks/use-is-first-render.js +1 -1
- package/dist/_internal/hooks/use-sync-ref.js +1 -1
- package/dist/_internal/hooks/use-timer/timer.js +1 -1
- package/dist/_internal/hooks/use-timer/use-timer.js +1 -1
- package/dist/_internal/hooks/use-warn.js +1 -1
- package/dist/components/Block.js +1 -1
- package/dist/components/CollectionItem.js +1 -1
- package/dist/components/GlobalStyles.js +1 -1
- package/dist/components/GridProvider.js +1 -1
- package/dist/components/HiddenInput.js +1 -1
- package/dist/components/Root.js +6 -6
- package/dist/components/Root.js.map +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.d.ts +0 -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 +1 -1
- package/dist/components/actions/ItemActionContext.js +1 -1
- package/dist/components/actions/ItemButton/ItemButton.js +1 -1
- package/dist/components/actions/Link/Link.js +1 -1
- package/dist/components/actions/Menu/Menu.js +1 -1
- package/dist/components/actions/Menu/MenuItem.js +1 -1
- package/dist/components/actions/Menu/MenuSection.js +1 -1
- package/dist/components/actions/Menu/MenuTrigger.js +1 -1
- package/dist/components/actions/Menu/SubMenuTrigger.js +1 -1
- package/dist/components/actions/Menu/SubmenuTriggerContext.js +1 -1
- package/dist/components/actions/Menu/context.js +1 -1
- package/dist/components/actions/Menu/styled.js +1 -1
- package/dist/components/actions/index.js +1 -1
- package/dist/components/actions/use-action.js +1 -1
- package/dist/components/actions/use-anchored-menu.js +1 -1
- package/dist/components/actions/use-context-menu.js +1 -1
- package/dist/components/content/ActiveZone/ActiveZone.js +1 -1
- package/dist/components/content/Alert/Alert.js +1 -1
- package/dist/components/content/Alert/use-alert.js +1 -1
- package/dist/components/content/Avatar/Avatar.js +1 -1
- package/dist/components/content/Badge/Badge.js +1 -1
- package/dist/components/content/Card/Card.js +1 -1
- package/dist/components/content/Content.js +1 -1
- package/dist/components/content/CopyPasteBlock/CopyPasteBlock.js +1 -1
- package/dist/components/content/CopySnippet/CopySnippet.js +1 -1
- package/dist/components/content/Disclosure/Disclosure.js +1 -1
- package/dist/components/content/Divider.js +1 -1
- package/dist/components/content/Footer.js +1 -1
- package/dist/components/content/Header.js +1 -1
- package/dist/components/content/HotKeys/HotKeys.js +1 -1
- package/dist/components/content/InlineInput/InlineInput.d.ts +109 -0
- package/dist/components/content/InlineInput/InlineInput.js +329 -0
- package/dist/components/content/InlineInput/InlineInput.js.map +1 -0
- package/dist/components/content/InlineInput/index.d.ts +2 -0
- package/dist/components/content/Item/Item.js +1 -1
- package/dist/components/content/ItemBadge/ItemBadge.js +1 -1
- package/dist/components/content/ItemCard/ItemCard.js +1 -1
- package/dist/components/content/Layout/GridLayout.js +1 -1
- package/dist/components/content/Layout/Layout.js +1 -1
- package/dist/components/content/Layout/LayoutBlock.js +1 -1
- package/dist/components/content/Layout/LayoutCenter.js +1 -1
- package/dist/components/content/Layout/LayoutContainer.js +1 -1
- package/dist/components/content/Layout/LayoutContent.js +1 -1
- package/dist/components/content/Layout/LayoutContext.js +1 -1
- package/dist/components/content/Layout/LayoutFlex.js +1 -1
- package/dist/components/content/Layout/LayoutFooter.js +1 -1
- package/dist/components/content/Layout/LayoutGrid.js +1 -1
- package/dist/components/content/Layout/LayoutHeader.js +1 -1
- package/dist/components/content/Layout/LayoutPane.js +1 -1
- package/dist/components/content/Layout/LayoutPanel.js +1 -1
- package/dist/components/content/Layout/LayoutPanelHeader.js +1 -1
- package/dist/components/content/Layout/LayoutToolbar.js +1 -1
- package/dist/components/content/Layout/hooks/useTinyScrollbar.js +1 -1
- package/dist/components/content/Layout/index.js +1 -1
- package/dist/components/content/Layout/utils.js +1 -1
- package/dist/components/content/Paragraph.js +1 -1
- package/dist/components/content/Placeholder/Placeholder.js +1 -1
- package/dist/components/content/PrismCode/PrismCode.js +1 -1
- package/dist/components/content/PrismCode/prismSetup.js +1 -1
- package/dist/components/content/PrismDiffCode/PrismDiffCode.js +1 -1
- package/dist/components/content/Result/Result.js +1 -1
- package/dist/components/content/Skeleton/Skeleton.js +1 -1
- package/dist/components/content/Tag/Tag.js +1 -1
- package/dist/components/content/Text.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/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/ComboBox/ComboBox.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/TimeInput.js +1 -1
- package/dist/components/fields/DatePicker/intl.js +1 -1
- package/dist/components/fields/DatePicker/parseDate.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/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/NumberInput/NumberInput.js +1 -1
- package/dist/components/fields/NumberInput/StepButton.js +1 -1
- package/dist/components/fields/PasswordInput/PasswordInput.js +1 -1
- package/dist/components/fields/Picker/Picker.js +1 -1
- package/dist/components/fields/RadioGroup/Radio.js +1 -1
- package/dist/components/fields/RadioGroup/RadioGroup.js +1 -1
- package/dist/components/fields/RadioGroup/context.js +1 -1
- package/dist/components/fields/SearchInput/SearchInput.js +1 -1
- package/dist/components/fields/Select/Select.js +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/form/FieldWrapper/FieldWrapper.js +1 -1
- package/dist/components/form/FieldWrapper/extract-field-wrapper-props.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/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/Flex.js +1 -1
- package/dist/components/layout/Flow.js +1 -1
- package/dist/components/layout/Grid.js +1 -1
- package/dist/components/layout/Panel.js +1 -1
- package/dist/components/layout/Prefix.js +1 -1
- package/dist/components/layout/ResizablePanel.js +1 -1
- package/dist/components/layout/Space.js +1 -1
- package/dist/components/layout/Suffix.js +1 -1
- package/dist/components/navigation/Tabs/DraggableTabList.js +1 -1
- package/dist/components/navigation/Tabs/TabButton.js +28 -22
- 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 +2 -6
- package/dist/components/navigation/Tabs/Tabs.js.map +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/TabsContext.js.map +1 -1
- package/dist/components/navigation/Tabs/styled.js +2 -24
- package/dist/components/navigation/Tabs/styled.js.map +1 -1
- package/dist/components/navigation/Tabs/types.js +1 -1
- package/dist/components/navigation/Tabs/use-tab-editing.js +7 -13
- package/dist/components/navigation/Tabs/use-tab-editing.js.map +1 -1
- package/dist/components/navigation/Tabs/use-tab-indicator.js +1 -1
- package/dist/components/organisms/FileTabs/FileTabs.js +1 -1
- package/dist/components/organisms/StatsCard/StatsCard.js +1 -1
- package/dist/components/other/Calendar/Calendar.js +1 -1
- package/dist/components/other/Calendar/CalendarCell.js +1 -1
- package/dist/components/other/Calendar/CalendarGrid.js +1 -1
- package/dist/components/other/Calendar/RangeCalendar.js +1 -1
- package/dist/components/other/CloudLogo/CloudLogo.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialog.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialogApiProvider.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialogZone.js +1 -1
- package/dist/components/overlays/Dialog/Dialog.js +1 -1
- package/dist/components/overlays/Dialog/DialogContainer.js +1 -1
- package/dist/components/overlays/Dialog/DialogForm.js +1 -1
- package/dist/components/overlays/Dialog/DialogTrigger.js +1 -1
- package/dist/components/overlays/Dialog/context.js +1 -1
- package/dist/components/overlays/Dialog/use-dialog-container.js +1 -1
- package/dist/components/overlays/Modal/Modal.d.ts +1 -2
- package/dist/components/overlays/Modal/Modal.js +1 -1
- package/dist/components/overlays/Modal/OpenTransitionContext.js +1 -1
- package/dist/components/overlays/Modal/Overlay.d.ts +0 -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/Modal/types.d.ts +0 -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.d.ts +0 -2
- 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/index.d.ts +0 -1
- package/dist/components/portal/usePortal.js +1 -1
- package/dist/components/shared/DraggableCollection.js +1 -1
- package/dist/components/shared/InvalidIcon.js +1 -1
- package/dist/components/shared/ValidIcon.js +1 -1
- package/dist/components/status/LoadingAnimation/LoadingAnimation.js +1 -1
- package/dist/components/status/Spin/Cube.js +1 -1
- package/dist/components/status/Spin/InternalSpinner.js +1 -1
- package/dist/components/status/Spin/Spin.js +1 -1
- package/dist/components/status/Spin/SpinsContainer.js +1 -1
- package/dist/data/item-themes.js +1 -1
- package/dist/data/themes.js +1 -1
- package/dist/icons/AdjustmentsHorizontalIcon.js +1 -1
- package/dist/icons/AdjustmentsIcon.js +1 -1
- package/dist/icons/AiIcon.js +1 -1
- package/dist/icons/AreaChartIcon.js +1 -1
- package/dist/icons/BackwardIcon.js +1 -1
- package/dist/icons/BarChartIcon.js +1 -1
- package/dist/icons/BellFilledIcon.js +1 -1
- package/dist/icons/BellIcon.js +1 -1
- package/dist/icons/BooleanIcon.js +1 -1
- package/dist/icons/CalendarEditIcon.js +1 -1
- package/dist/icons/CalendarIcon.js +1 -1
- package/dist/icons/CaretDownIcon.js +1 -1
- package/dist/icons/CaretUpIcon.js +1 -1
- package/dist/icons/ChartAreaStackedIcon.js +1 -1
- package/dist/icons/ChartAreaStackedPercentageIcon.js +1 -1
- package/dist/icons/ChartBarGroupedHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarGroupedIcon.js +1 -1
- package/dist/icons/ChartBarHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarLineIcon.js +1 -1
- package/dist/icons/ChartBarStackedHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarStackedIcon.js +1 -1
- package/dist/icons/ChartBarStackedPercentageHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarStackedPercentageIcon.js +1 -1
- package/dist/icons/ChartBoxPlot2Icon.js +1 -1
- package/dist/icons/ChartBoxPlotIcon.js +1 -1
- package/dist/icons/ChartBubbleIcon.js +1 -1
- package/dist/icons/ChartDonut2Icon.js +1 -1
- package/dist/icons/ChartFunnelIcon.js +1 -1
- package/dist/icons/ChartHeatmapIcon.js +1 -1
- package/dist/icons/ChartKPIIcon.js +1 -1
- package/dist/icons/ChartPie2Icon.js +1 -1
- package/dist/icons/ChartScatterIcon.js +1 -1
- package/dist/icons/CheckCircleFilledIcon.js +1 -1
- package/dist/icons/CheckCircleIcon.js +1 -1
- package/dist/icons/CheckIcon.js +1 -1
- package/dist/icons/CircleFilledIcon.js +1 -1
- package/dist/icons/ClearIcon.js +1 -1
- package/dist/icons/CloseCircleFilledIcon.js +1 -1
- package/dist/icons/CloseCircleIcon.js +1 -1
- package/dist/icons/CloseIcon.js +1 -1
- package/dist/icons/CodeIcon.js +1 -1
- package/dist/icons/ColumnTotalIcon.js +1 -1
- package/dist/icons/CopyIcon.js +1 -1
- package/dist/icons/CountIcon.js +1 -1
- package/dist/icons/CubeIcon.js +1 -1
- package/dist/icons/CubePauseIcon.js +1 -1
- package/dist/icons/CubePlayIcon.js +1 -1
- package/dist/icons/CurrencyDollarIcon.js +1 -1
- package/dist/icons/DangerIcon.js +1 -1
- package/dist/icons/DashboardIcon.js +1 -1
- package/dist/icons/DatabaseIcon.js +1 -1
- package/dist/icons/DecimalDecreaseIcon.js +1 -1
- package/dist/icons/DecimalIncreaseIcon.js +1 -1
- package/dist/icons/DirectionIcon.js +1 -1
- package/dist/icons/DonutIcon.js +1 -1
- package/dist/icons/DownIcon.js +1 -1
- package/dist/icons/EditIcon.js +1 -1
- package/dist/icons/ExclamationCircleFilledIcon.js +1 -1
- package/dist/icons/ExclamationCircleIcon.js +1 -1
- package/dist/icons/ExclamationIcon.js +1 -1
- package/dist/icons/EyeIcon.js +1 -1
- package/dist/icons/EyeInvisibleIcon.js +1 -1
- package/dist/icons/FilterIcon.js +1 -1
- package/dist/icons/FolderFilledIcon.js +1 -1
- package/dist/icons/FolderIcon.js +1 -1
- package/dist/icons/FolderOpenFilledIcon.js +1 -1
- package/dist/icons/FolderOpenIcon.js +1 -1
- package/dist/icons/ForwardIcon.js +1 -1
- package/dist/icons/GripVerticalIcon.js +1 -1
- package/dist/icons/HierarchyIcon.js +1 -1
- package/dist/icons/HierarchyOpenIcon.js +1 -1
- package/dist/icons/Icon.js +1 -1
- package/dist/icons/InfoCircleIcon.js +1 -1
- package/dist/icons/InfoIcon.js +1 -1
- package/dist/icons/KeyIcon.js +1 -1
- package/dist/icons/LeftIcon.js +1 -1
- package/dist/icons/LineChartIcon.js +1 -1
- package/dist/icons/LoadingIcon.js +1 -1
- package/dist/icons/LockFilledIcon.js +1 -1
- package/dist/icons/LockIcon.js +1 -1
- package/dist/icons/MoreIcon.js +1 -1
- package/dist/icons/NotAllowedIcon.js +1 -1
- package/dist/icons/Number123Icon.js +1 -1
- package/dist/icons/NumberIcon.js +1 -1
- package/dist/icons/PauseCircleFilledIcon.js +1 -1
- package/dist/icons/PauseCircleIcon.js +1 -1
- package/dist/icons/PauseIcon.js +1 -1
- package/dist/icons/PercentageIcon.js +1 -1
- package/dist/icons/PieChartIcon.js +1 -1
- package/dist/icons/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.d.ts +3 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +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/colors.js +1 -1
- package/dist/tokens/index.js +1 -1
- package/dist/tokens/layout.js +1 -1
- package/dist/tokens/shadows.js +1 -1
- package/dist/tokens/sizes.js +1 -1
- package/dist/tokens/spacing.js +1 -1
- package/dist/tokens/typography.js +1 -1
- package/dist/utils/ResizeSensor.js +1 -1
- package/dist/utils/is-dev-env.js +1 -1
- package/dist/utils/modules.js +1 -1
- package/dist/utils/promise.js +1 -1
- package/dist/utils/raf.js +1 -1
- package/dist/utils/random.js +1 -1
- package/dist/utils/range.js +1 -1
- package/dist/utils/react/RenderCache.js +1 -1
- package/dist/utils/react/Slots.js +1 -1
- package/dist/utils/react/chain.js +1 -1
- package/dist/utils/react/forwardRefWithGenerics.js +1 -1
- package/dist/utils/react/index.js +1 -1
- package/dist/utils/react/interactions.js +1 -1
- package/dist/utils/react/isTextOnly.js +1 -1
- package/dist/utils/react/mapProps.js +1 -1
- package/dist/utils/react/mergeProps.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/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/content/InlineInput.md +323 -0
- package/docs/components/navigation/Tabs.md +3 -1
- package/package.json +1 -1
- package/dist/components/navigation/Tabs/EditableTitle.js +0 -100
- package/dist/components/navigation/Tabs/EditableTitle.js.map +0 -1
- package/dist/components/portal/PortalProvider.d.ts +0 -2
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
# InlineInput
|
|
2
|
+
|
|
3
|
+
Inline editable text. Displays a value as inline content and swaps to an auto-sizing text input when entering edit mode. Designed to drop into any text context (tab title, heading, paragraph, table cell) without style customization — typography, color, and font family all inherit from the parent.
|
|
4
|
+
|
|
5
|
+
Unlike `TextInput`, `InlineInput` is intentionally **not** a form field. It manages its own commit lifecycle (`onSubmit` / `onCancel`) rather than participating in form validation.
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
- **Renameable items**: Tab titles, file names, board columns, list items
|
|
10
|
+
- **Edit-in-place fields**: Inline document titles, profile names, project labels
|
|
11
|
+
- **Lightweight string edits**: Cases where launching a modal or full form would be heavy
|
|
12
|
+
|
|
13
|
+
## When Not to Use
|
|
14
|
+
|
|
15
|
+
- **Form fields**: Use `TextInput` (with `<Form>` + `Field`) for inputs that need validation rules
|
|
16
|
+
- **Multi-line text**: Single-line only in this version (multiline planned)
|
|
17
|
+
- **Complex inputs**: Use a proper input component when you need masks, prefixes/suffixes, or rich validation
|
|
18
|
+
|
|
19
|
+
## Component
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
### Properties
|
|
24
|
+
|
|
25
|
+
- **`value`** `string` — Controlled value. When provided, the component is controlled.
|
|
26
|
+
- **`defaultValue`** `string` — Initial value for uncontrolled usage.
|
|
27
|
+
- **`onChange`** `(value: string) => void` — Fires on commit **only when the value actually changed**. Use this to update external state (controlled pattern).
|
|
28
|
+
- **`isEditing`** `boolean` — Controlled editing state. When provided, the editing state is controlled.
|
|
29
|
+
- **`defaultIsEditing`** `boolean` (default: `false`) — Default editing state for uncontrolled usage.
|
|
30
|
+
- **`onEditingChange`** `(isEditing: boolean) => void` — Called when editing mode starts or ends.
|
|
31
|
+
- **`onSubmit`** `(value: string) => void` — Fires every commit (Enter / submit-on-blur / `ref.stopEditing(true)`), even when the value did not change. Use for side effects (analytics, save toasts).
|
|
32
|
+
- **`onCancel`** `() => void` — Called when editing is cancelled (Escape or empty submit when `allowEmpty` is `false`).
|
|
33
|
+
- **`editTrigger`** `'dblclick' | 'click' | 'none'` (default: `dblclick`) — How edit mode is activated from the display element. Programmatic entry via `ref.startEditing()` works regardless.
|
|
34
|
+
- **`keyboardActivation`** `boolean` (default: `true`) — When `true`, the display element is keyboard-focusable (`tabIndex=0`, `role="button"`) and responds to `Enter`, `F2` and `Space` to enter edit mode. Set to `false` when the host already owns keyboard activation (e.g. an editable tab inside a `<button>`) — exposing the display as a separate tab stop would otherwise nest focus inside the host.
|
|
35
|
+
- **`submitOnBlur`** `boolean` (default: `true`) — Whether to submit when focus leaves the input.
|
|
36
|
+
- **`trimOnSubmit`** `boolean` (default: `true`) — Whether to trim the value on submit.
|
|
37
|
+
- **`allowEmpty`** `boolean` (default: `false`) — When `false`, submitting an empty/whitespace value cancels instead.
|
|
38
|
+
- **`isDisabled`** `boolean` (default: `false`) — When `true`, edit mode cannot be entered (programmatically or otherwise).
|
|
39
|
+
- **`isReadOnly`** `boolean` (default: `false`) — When `true`, edit mode cannot be entered, but the display reads as enabled.
|
|
40
|
+
- **`placeholder`** `string` — Placeholder text shown in the input when the draft is empty.
|
|
41
|
+
- **`renderDisplay`** `(value: string) => ReactNode` — Custom render for display (non-editing) mode.
|
|
42
|
+
- **`tooltip`** `boolean | string | AutoTooltipValue` (default: `true`) — Tooltip behaviour for the display value. `true` enables auto-tooltip on overflow (showing the full text when truncated). A string always shows that text. `false` disables the tooltip. Suppressed automatically while editing and when `renderDisplay` is used.
|
|
43
|
+
- **`tooltipPlacement`** `'top' | 'bottom' | 'left' | 'right' | ...` (default: `'top'`) — Default tooltip placement.
|
|
44
|
+
- **`inputStyles`** `Styles` — Convenience prop for styling the `Input` sub-element.
|
|
45
|
+
|
|
46
|
+
### Base Properties
|
|
47
|
+
|
|
48
|
+
Supports [Base properties](../../BaseProperties.md).
|
|
49
|
+
|
|
50
|
+
### Imperative Ref
|
|
51
|
+
|
|
52
|
+
The component exposes a ref with these methods:
|
|
53
|
+
|
|
54
|
+
- **`startEditing()`** — Programmatically enter edit mode. Always works regardless of `editTrigger`; blocked only by `isDisabled` / `isReadOnly`.
|
|
55
|
+
- **`stopEditing(submit?: boolean)`** — Programmatically exit edit mode. `submit=true` (default) commits, `submit=false` cancels.
|
|
56
|
+
- **`focus()`** — Focus the underlying element (input when editing, root span otherwise).
|
|
57
|
+
- **`getValue()`** — Get the current committed value.
|
|
58
|
+
|
|
59
|
+
### Styling Properties
|
|
60
|
+
|
|
61
|
+
#### styles
|
|
62
|
+
|
|
63
|
+
Customizes the root element of the component. The root is `inline-flex` with `align-items: baseline` so it integrates cleanly into any inline text context (tabs, headings, paragraphs) without shifting surrounding text. Truncation lives on the inner `Display` sub-element so the root's baseline is not perturbed.
|
|
64
|
+
|
|
65
|
+
**Sub-elements:**
|
|
66
|
+
|
|
67
|
+
- `Display` — The block-level wrapper that holds the value in display mode and applies `overflow: hidden` / `text-overflow: ellipsis` for truncation
|
|
68
|
+
- `Input` — The text input rendered in edit mode
|
|
69
|
+
- `Placeholder` — The placeholder text rendered in display mode when the value is empty
|
|
70
|
+
- `Measure` — The hidden text used to auto-size the input (rarely targeted)
|
|
71
|
+
|
|
72
|
+
#### inputStyles
|
|
73
|
+
|
|
74
|
+
Convenience prop equivalent to `styles={{ Input: { ... } }}`.
|
|
75
|
+
|
|
76
|
+
### Style Properties
|
|
77
|
+
|
|
78
|
+
These properties allow direct style application without using the `styles` prop:
|
|
79
|
+
|
|
80
|
+
- **Position:** `gridArea`, `order`, `gridColumn`, `gridRow`, `placeSelf`, `alignSelf`, `justifySelf`, `zIndex`, `margin`, `inset`, `position`, `scrollMargin`
|
|
81
|
+
- **Dimension:** `width`, `height`, `flexBasis`, `flexGrow`, `flexShrink`, `flex`
|
|
82
|
+
- **Block:** `border`, `radius`, `shadow`, `outline`, `padding`, `paddingInline`, `paddingBlock`, `overflow`, `scrollbar`, `textAlign`
|
|
83
|
+
- **Color:** `color`, `fill`, `fade`, `image`
|
|
84
|
+
|
|
85
|
+
### Modifiers
|
|
86
|
+
|
|
87
|
+
The `mods` property is automatically populated. Consumers can target these in their own `styles`:
|
|
88
|
+
|
|
89
|
+
| Modifier | Type | Description |
|
|
90
|
+
| ---------- | --------- | -------------------------------------------------------------------------- |
|
|
91
|
+
| editing | `boolean` | Currently in edit mode |
|
|
92
|
+
| editable | `boolean` | `editTrigger` is `dblclick` or `click` and not disabled/read-only |
|
|
93
|
+
| focused | `boolean` | Display element is keyboard-focused (`isFocusVisible`) and editable |
|
|
94
|
+
| disabled | `boolean` | `isDisabled` is `true` |
|
|
95
|
+
| read-only | `boolean` | `isReadOnly` is `true` |
|
|
96
|
+
| empty | `boolean` | The committed value is empty |
|
|
97
|
+
|
|
98
|
+
## Examples
|
|
99
|
+
|
|
100
|
+
### Basic Usage
|
|
101
|
+
|
|
102
|
+
```jsx
|
|
103
|
+
<InlineInput defaultValue="Edit me" />
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Single-click Trigger
|
|
107
|
+
|
|
108
|
+
Enter edit mode on a single click instead of double-click:
|
|
109
|
+
|
|
110
|
+
```jsx
|
|
111
|
+
<InlineInput defaultValue="Click me to edit" editTrigger="click" />
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Manual / Programmatic Trigger
|
|
115
|
+
|
|
116
|
+
When `editTrigger` is `none`, the display element is inert. Use the imperative ref to enter edit mode:
|
|
117
|
+
|
|
118
|
+
```jsx
|
|
119
|
+
const ref = useRef<CubeInlineInputRef>(null);
|
|
120
|
+
|
|
121
|
+
<>
|
|
122
|
+
<InlineInput ref={ref} editTrigger="none" defaultValue="Use the button" />
|
|
123
|
+
<Button onPress={() => ref.current?.startEditing()}>Rename</Button>
|
|
124
|
+
</>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Controlled Value
|
|
128
|
+
|
|
129
|
+
Track the value externally:
|
|
130
|
+
|
|
131
|
+
```jsx
|
|
132
|
+
const [value, setValue] = useState('Controlled value');
|
|
133
|
+
|
|
134
|
+
<InlineInput value={value} onChange={setValue} />
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Controlled Editing State
|
|
138
|
+
|
|
139
|
+
Drive the editing state from outside (e.g. from a "Rename" button in a parent menu):
|
|
140
|
+
|
|
141
|
+
```jsx
|
|
142
|
+
const [editing, setEditing] = useState(false);
|
|
143
|
+
|
|
144
|
+
<InlineInput
|
|
145
|
+
isEditing={editing}
|
|
146
|
+
onEditingChange={setEditing}
|
|
147
|
+
defaultValue="Controlled isEditing"
|
|
148
|
+
editTrigger="none"
|
|
149
|
+
/>
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Inside a Heading
|
|
153
|
+
|
|
154
|
+
The component inherits all typography from its parent:
|
|
155
|
+
|
|
156
|
+
```jsx
|
|
157
|
+
<Title level={2}>
|
|
158
|
+
<InlineInput defaultValue="Editable heading" />
|
|
159
|
+
</Title>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Inline in Paragraph
|
|
163
|
+
|
|
164
|
+
Sits naturally inside text flow:
|
|
165
|
+
|
|
166
|
+
```jsx
|
|
167
|
+
<p>
|
|
168
|
+
Hello, my name is <InlineInput defaultValue="John Doe" /> and I love editing
|
|
169
|
+
text in place.
|
|
170
|
+
</p>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Placeholder for Empty Values
|
|
174
|
+
|
|
175
|
+
```jsx
|
|
176
|
+
<InlineInput defaultValue="" placeholder="Untitled" />
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Allow Empty Values
|
|
180
|
+
|
|
181
|
+
By default, submitting an empty value cancels. Set `allowEmpty` to keep the empty value:
|
|
182
|
+
|
|
183
|
+
```jsx
|
|
184
|
+
<InlineInput defaultValue="Clearable" allowEmpty placeholder="Empty allowed" />
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Disabled / Read-only
|
|
188
|
+
|
|
189
|
+
```jsx
|
|
190
|
+
<InlineInput defaultValue="You can't edit me" isDisabled />
|
|
191
|
+
<InlineInput defaultValue="Read-only value" isReadOnly />
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Overflow & Tooltip
|
|
195
|
+
|
|
196
|
+
When the value is wider than its container, the display text is truncated with an ellipsis. The full value is shown as a tooltip on hover/focus — no extra props required.
|
|
197
|
+
|
|
198
|
+
```jsx
|
|
199
|
+
<div style={{ width: 200 }}>
|
|
200
|
+
<InlineInput defaultValue="A very long inline value that gets truncated…" />
|
|
201
|
+
</div>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
To always show a custom tooltip (regardless of overflow), pass a string. To disable the tooltip entirely, pass `false`:
|
|
205
|
+
|
|
206
|
+
```jsx
|
|
207
|
+
<InlineInput defaultValue="Hover me" tooltip="Click to rename" />
|
|
208
|
+
<InlineInput defaultValue="No tooltip" tooltip={false} />
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
The truncation behaviour is automatically disabled while editing so the input is never visually clipped while the user types.
|
|
212
|
+
|
|
213
|
+
### Keyboard Activation
|
|
214
|
+
|
|
215
|
+
By default the display element is keyboard-focusable (`tabIndex=0`, `role="button"`, `aria-roledescription="editable text"`). Pressing `Enter`, `F2` or `Space` enters edit mode without requiring a pointer. A keyboard focus ring (`#primary` token, rounded) is shown only when the element receives keyboard focus — clicks never trigger the ring.
|
|
216
|
+
|
|
217
|
+
When `InlineInput` is embedded in a host that already owns keyboard activation (e.g. `Tabs` — each tab is a `<button>` that listens for `F2` itself), pass `keyboardActivation={false}` to avoid creating a nested tab stop inside the host. The imperative `ref.startEditing()` always works regardless of this setting, and the focus ring is suppressed in this mode (the host's focus ring is the one users see).
|
|
218
|
+
|
|
219
|
+
```jsx
|
|
220
|
+
<InlineInput defaultValue="Press Enter to edit" />
|
|
221
|
+
|
|
222
|
+
<InlineInput keyboardActivation={false} defaultValue="Host owns the keyboard" />
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Accessibility
|
|
226
|
+
|
|
227
|
+
### Keyboard Navigation
|
|
228
|
+
|
|
229
|
+
**Display mode** (when `keyboardActivation` is `true`):
|
|
230
|
+
|
|
231
|
+
- `Tab` — Moves focus to the value
|
|
232
|
+
- `Enter`, `F2`, `Space` — Enter edit mode
|
|
233
|
+
|
|
234
|
+
**Edit mode**:
|
|
235
|
+
|
|
236
|
+
- `Enter` — Commit the current draft
|
|
237
|
+
- `Escape` — Cancel and revert to the previous value
|
|
238
|
+
- `Tab` / focus loss — Commits when `submitOnBlur` is `true` (default), otherwise no-op
|
|
239
|
+
- Arrow keys, Space, Delete, Backspace — Work normally inside the input and do not bubble to the host
|
|
240
|
+
|
|
241
|
+
### ARIA Properties
|
|
242
|
+
|
|
243
|
+
- The display element receives `role="button"` and `aria-roledescription="editable text"` when keyboard-focusable, so screen readers announce that the value can be activated for editing.
|
|
244
|
+
- **`aria-label`** — Provide a label when the value alone doesn't convey purpose. Forwarded to both the display element (when focusable) and the inner input. Recommended in all cases.
|
|
245
|
+
- **`aria-labelledby`** — Reference the id of a visible label element. Forwarded the same way.
|
|
246
|
+
- **`aria-disabled`** / **`aria-readonly`** — Set automatically from `isDisabled` / `isReadOnly`.
|
|
247
|
+
|
|
248
|
+
### Focus Management
|
|
249
|
+
|
|
250
|
+
When entering edit mode, focus is taken explicitly by a `FocusScope` with `autoFocus`. This makes the transition deterministic even when triggered from a closing menu (which would otherwise restore focus to the menu trigger). The text content is selected automatically.
|
|
251
|
+
|
|
252
|
+
When leaving edit mode, focus is not restored automatically — the host is responsible for moving focus back to a meaningful element (e.g. the parent button or row).
|
|
253
|
+
|
|
254
|
+
## Best Practices
|
|
255
|
+
|
|
256
|
+
1. **Do**: Always provide an `aria-label` or `aria-labelledby` for screen reader users.
|
|
257
|
+
|
|
258
|
+
```jsx
|
|
259
|
+
<InlineInput defaultValue="My document" aria-label="Document name" />
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
2. **Do**: Use `editTrigger="dblclick"` for items that are also clickable for selection (the default).
|
|
263
|
+
|
|
264
|
+
3. **Don't**: Use `InlineInput` as a form field. Use `TextInput` inside a `<Form>` for that.
|
|
265
|
+
|
|
266
|
+
4. **Don't**: Rely on `onChange` for keystroke-by-keystroke updates — it fires only on commit. Use `isEditing` + `onEditingChange` if you need to observe the editing lifecycle.
|
|
267
|
+
|
|
268
|
+
### onChange vs onSubmit
|
|
269
|
+
|
|
270
|
+
These look similar but fire under different conditions. Pick the one that matches your intent:
|
|
271
|
+
|
|
272
|
+
| Event | Fires when | Typical use |
|
|
273
|
+
| ----------- | ------------------------------------------------------------------------- | ---------------------------------------- |
|
|
274
|
+
| `onChange` | The committed value is **different** from the previous value | Updating state (controlled pattern) |
|
|
275
|
+
| `onSubmit` | The user commits (Enter / blur / `ref.stopEditing(true)`) — always fires | Side effects (server save, toasts) |
|
|
276
|
+
| `onCancel` | Escape, empty submit (when `allowEmpty=false`), or `ref.stopEditing(false)` | Reverting UI, cleanup |
|
|
277
|
+
|
|
278
|
+
### Optimistic Display
|
|
279
|
+
|
|
280
|
+
When the component is **controlled** and the parent updates `value` asynchronously, the component shows the just-committed value optimistically until the parent's `value` catches up. This prevents a flicker back to the old value between commit and re-render.
|
|
281
|
+
|
|
282
|
+
### Async Save & Rollback
|
|
283
|
+
|
|
284
|
+
`onSubmit` may return a `Promise`. The component does not block the UI on the promise, but it watches the outcome:
|
|
285
|
+
|
|
286
|
+
- **Promise resolves** — the parent is expected to have updated `value` (or chose not to). Optimistic display clears when `value` next changes.
|
|
287
|
+
- **Promise rejects** — the component treats this as a save failure and **automatically reverts** the optimistic display back to the actual `value` prop. Stale optimistic state never lingers.
|
|
288
|
+
|
|
289
|
+
A typical async-save pattern:
|
|
290
|
+
|
|
291
|
+
```jsx
|
|
292
|
+
<InlineInput
|
|
293
|
+
value={title}
|
|
294
|
+
onSubmit={async (next) => {
|
|
295
|
+
await saveToServer(next); // throws on failure
|
|
296
|
+
setTitle(next); // only on success
|
|
297
|
+
}}
|
|
298
|
+
/>
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
If `saveToServer` throws, `InlineInput` reverts to `title` automatically. If you want to show a toast on failure, wrap inside `onSubmit` and re-throw to keep the rollback:
|
|
302
|
+
|
|
303
|
+
```jsx
|
|
304
|
+
<InlineInput
|
|
305
|
+
value={title}
|
|
306
|
+
onSubmit={async (next) => {
|
|
307
|
+
try {
|
|
308
|
+
await saveToServer(next);
|
|
309
|
+
setTitle(next);
|
|
310
|
+
} catch (err) {
|
|
311
|
+
showToast('Save failed');
|
|
312
|
+
throw err;
|
|
313
|
+
}
|
|
314
|
+
}}
|
|
315
|
+
/>
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
If the user starts a new edit before a pending promise settles, the older promise's outcome is ignored (no late rollback can clobber the newer commit).
|
|
319
|
+
|
|
320
|
+
## Related Components
|
|
321
|
+
|
|
322
|
+
- [TextInput](../fields/TextInput.md) — Full form-aware text input
|
|
323
|
+
- [Tabs](../navigation/Tabs.md) — Uses `InlineInput` internally for editable tab titles
|
|
@@ -343,7 +343,9 @@ Add dropdown menus to tabs using the `menu` prop. This replaces the need for man
|
|
|
343
343
|
|
|
344
344
|
### Editable Tabs with Menu
|
|
345
345
|
|
|
346
|
-
Combine editable tabs with a menu for rename, duplicate, and delete actions.
|
|
346
|
+
Combine editable tabs with a menu for rename, duplicate, and delete actions. The inline editing UI is provided by [InlineInput](../content/InlineInput.md), which can also be used standalone elsewhere.
|
|
347
|
+
|
|
348
|
+
> For editable tabs the `tooltip` prop is rendered by `InlineInput` rather than by the surrounding tab button. This keeps the tooltip in sync with the editing UI (and avoids a double tooltip) — the trigger area is the title content, not the entire tab button. Long titles also get an automatic ellipsis + overflow tooltip without any extra configuration.
|
|
347
349
|
|
|
348
350
|
```jsx
|
|
349
351
|
<Tabs
|
package/package.json
CHANGED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.136.1 | Cube Dev Team */
|
|
2
|
-
import { useEvent } from "../../../_internal/hooks/use-event.js";
|
|
3
|
-
import { EditableTitleInputElement, HiddenMeasure } from "./styled.js";
|
|
4
|
-
import { useLayoutEffect, useRef, useState } from "react";
|
|
5
|
-
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
-
import { useTextField } from "react-aria";
|
|
7
|
-
|
|
8
|
-
//#region src/components/navigation/Tabs/EditableTitle.tsx
|
|
9
|
-
/**
|
|
10
|
-
* Inline editable title component for tab labels.
|
|
11
|
-
*
|
|
12
|
-
* When not editing, displays the title as a span with double-click to edit.
|
|
13
|
-
* When editing, displays an auto-sizing input field.
|
|
14
|
-
*/
|
|
15
|
-
function EditableTitle({ title, isEditing, editValue, onEditValueChange, onStartEditing, onSubmit, onCancel }) {
|
|
16
|
-
const inputRef = useRef(null);
|
|
17
|
-
const measureRef = useRef(null);
|
|
18
|
-
const [inputWidth, setInputWidth] = useState(null);
|
|
19
|
-
const justEnteredEditModeRef = useRef(false);
|
|
20
|
-
const { inputProps } = useTextField({
|
|
21
|
-
"aria-label": "Edit tab title",
|
|
22
|
-
value: editValue,
|
|
23
|
-
onChange: onEditValueChange
|
|
24
|
-
}, inputRef);
|
|
25
|
-
useLayoutEffect(() => {
|
|
26
|
-
if (isEditing && inputRef.current) {
|
|
27
|
-
const input = inputRef.current;
|
|
28
|
-
justEnteredEditModeRef.current = true;
|
|
29
|
-
input.focus();
|
|
30
|
-
requestAnimationFrame(() => {
|
|
31
|
-
input.select();
|
|
32
|
-
requestAnimationFrame(() => {
|
|
33
|
-
requestAnimationFrame(() => {
|
|
34
|
-
justEnteredEditModeRef.current = false;
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
} else justEnteredEditModeRef.current = false;
|
|
39
|
-
}, [isEditing]);
|
|
40
|
-
useLayoutEffect(() => {
|
|
41
|
-
if (isEditing && measureRef.current) {
|
|
42
|
-
const width = measureRef.current.scrollWidth;
|
|
43
|
-
setInputWidth(width);
|
|
44
|
-
}
|
|
45
|
-
}, [isEditing, editValue]);
|
|
46
|
-
const handleKeyDown = useEvent((e) => {
|
|
47
|
-
if (e.key === "Enter") {
|
|
48
|
-
e.preventDefault();
|
|
49
|
-
onSubmit();
|
|
50
|
-
} else if (e.key === "Escape") {
|
|
51
|
-
e.preventDefault();
|
|
52
|
-
onCancel();
|
|
53
|
-
} else if (e.key === "ArrowLeft" || e.key === "ArrowRight" || e.key === " " || e.key === "Delete" || e.key === "Backspace") e.stopPropagation();
|
|
54
|
-
});
|
|
55
|
-
const handleBlur = useEvent(() => {
|
|
56
|
-
if (justEnteredEditModeRef.current) {
|
|
57
|
-
requestAnimationFrame(() => {
|
|
58
|
-
inputRef.current?.focus();
|
|
59
|
-
inputRef.current?.select();
|
|
60
|
-
});
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
onSubmit();
|
|
64
|
-
});
|
|
65
|
-
const handleDoubleClick = useEvent((e) => {
|
|
66
|
-
e.preventDefault();
|
|
67
|
-
e.stopPropagation();
|
|
68
|
-
onStartEditing();
|
|
69
|
-
});
|
|
70
|
-
if (isEditing) {
|
|
71
|
-
const mergedProps = {
|
|
72
|
-
...inputProps,
|
|
73
|
-
onKeyDown: (e) => {
|
|
74
|
-
handleKeyDown(e);
|
|
75
|
-
inputProps.onKeyDown?.(e);
|
|
76
|
-
},
|
|
77
|
-
onBlur: (e) => {
|
|
78
|
-
handleBlur();
|
|
79
|
-
inputProps.onBlur?.(e);
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(HiddenMeasure, {
|
|
83
|
-
ref: measureRef,
|
|
84
|
-
"aria-hidden": "true",
|
|
85
|
-
children: editValue || " "
|
|
86
|
-
}), /* @__PURE__ */ jsx(EditableTitleInputElement, {
|
|
87
|
-
...mergedProps,
|
|
88
|
-
ref: inputRef,
|
|
89
|
-
tokens: { "$input-width": inputWidth ? `${inputWidth}px` : "auto" }
|
|
90
|
-
})] });
|
|
91
|
-
}
|
|
92
|
-
return /* @__PURE__ */ jsx("span", {
|
|
93
|
-
onDoubleClick: handleDoubleClick,
|
|
94
|
-
children: title
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
//#endregion
|
|
99
|
-
export { EditableTitle };
|
|
100
|
-
//# sourceMappingURL=EditableTitle.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EditableTitle.js","names":[],"sources":["../../../../src/components/navigation/Tabs/EditableTitle.tsx"],"sourcesContent":["import { useLayoutEffect, useRef, useState } from 'react';\nimport { useTextField } from 'react-aria';\n\nimport { useEvent } from '../../../_internal/hooks';\n\nimport { EditableTitleInputElement, HiddenMeasure } from './styled';\n\nimport type { FocusEvent, KeyboardEvent, MouseEvent, ReactNode } from 'react';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface EditableTitleProps {\n /** The current title to display (when not editing) */\n title: ReactNode;\n /** Whether the title is currently being edited */\n isEditing: boolean;\n /** Current edit input value */\n editValue: string;\n /** Callback when edit value changes */\n onEditValueChange: (value: string) => void;\n /** Callback to start editing (e.g., on double-click) */\n onStartEditing: () => void;\n /** Callback when editing is submitted (Enter or blur) */\n onSubmit: () => void;\n /** Callback when editing is cancelled (Escape) */\n onCancel: () => void;\n}\n\n// =============================================================================\n// Component\n// =============================================================================\n\n/**\n * Inline editable title component for tab labels.\n *\n * When not editing, displays the title as a span with double-click to edit.\n * When editing, displays an auto-sizing input field.\n */\nexport function EditableTitle({\n title,\n isEditing,\n editValue,\n onEditValueChange,\n onStartEditing,\n onSubmit,\n onCancel,\n}: EditableTitleProps) {\n const inputRef = useRef<HTMLInputElement>(null);\n const measureRef = useRef<HTMLSpanElement>(null);\n const [inputWidth, setInputWidth] = useState<number | null>(null);\n const justEnteredEditModeRef = useRef(false);\n\n // React Aria text field hook\n const { inputProps } = useTextField(\n {\n 'aria-label': 'Edit tab title',\n value: editValue,\n onChange: onEditValueChange,\n },\n inputRef,\n );\n\n // Focus and select input when entering edit mode\n useLayoutEffect(() => {\n if (isEditing && inputRef.current) {\n const input = inputRef.current;\n\n // Set flag to ignore immediate blur events\n justEnteredEditModeRef.current = true;\n\n input.focus();\n // Use requestAnimationFrame to ensure selection happens after focus\n requestAnimationFrame(() => {\n input.select();\n // Clear the flag after focus is established (allow 2 frames for menu to fully close)\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n justEnteredEditModeRef.current = false;\n });\n });\n });\n } else {\n justEnteredEditModeRef.current = false;\n }\n }, [isEditing]);\n\n // Measure text width and update input width\n useLayoutEffect(() => {\n if (isEditing && measureRef.current) {\n const width = measureRef.current.scrollWidth;\n setInputWidth(width);\n }\n }, [isEditing, editValue]);\n\n const handleKeyDown = useEvent((e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n onSubmit();\n } else if (e.key === 'Escape') {\n e.preventDefault();\n onCancel();\n } else if (\n e.key === 'ArrowLeft' ||\n e.key === 'ArrowRight' ||\n e.key === ' ' ||\n e.key === 'Delete' ||\n e.key === 'Backspace'\n ) {\n // Stop propagation to prevent tab navigation/deletion while editing\n e.stopPropagation();\n }\n });\n\n const handleBlur = useEvent(() => {\n // Ignore blur events immediately after entering edit mode (menu closing causes focus loss)\n if (justEnteredEditModeRef.current) {\n // Re-focus the input since something else stole focus\n requestAnimationFrame(() => {\n inputRef.current?.focus();\n inputRef.current?.select();\n });\n return;\n }\n // Submit on blur\n onSubmit();\n });\n\n const handleDoubleClick = useEvent((e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n onStartEditing();\n });\n\n if (isEditing) {\n // Merge our handlers with React Aria's inputProps\n const mergedProps = {\n ...inputProps,\n onKeyDown: (e: KeyboardEvent<HTMLInputElement>) => {\n handleKeyDown(e);\n inputProps.onKeyDown?.(e);\n },\n onBlur: (e: FocusEvent<HTMLInputElement>) => {\n handleBlur();\n inputProps.onBlur?.(e);\n },\n };\n\n return (\n <>\n <HiddenMeasure ref={measureRef} aria-hidden=\"true\">\n {editValue || ' '}\n </HiddenMeasure>\n <EditableTitleInputElement\n {...mergedProps}\n ref={inputRef}\n tokens={{ '$input-width': inputWidth ? `${inputWidth}px` : 'auto' }}\n />\n </>\n );\n }\n\n return <span onDoubleClick={handleDoubleClick}>{title}</span>;\n}\n"],"mappings":";;;;;;;;;;;;;;AAwCA,SAAgB,cAAc,EAC5B,OACA,WACA,WACA,mBACA,gBACA,UACA,YACqB;CACrB,MAAM,WAAW,OAAyB,KAAK;CAC/C,MAAM,aAAa,OAAwB,KAAK;CAChD,MAAM,CAAC,YAAY,iBAAiB,SAAwB,KAAK;CACjE,MAAM,yBAAyB,OAAO,MAAM;CAG5C,MAAM,EAAE,eAAe,aACrB;EACE,cAAc;EACd,OAAO;EACP,UAAU;EACX,EACD,SACD;AAGD,uBAAsB;AACpB,MAAI,aAAa,SAAS,SAAS;GACjC,MAAM,QAAQ,SAAS;AAGvB,0BAAuB,UAAU;AAEjC,SAAM,OAAO;AAEb,+BAA4B;AAC1B,UAAM,QAAQ;AAEd,gCAA4B;AAC1B,iCAA4B;AAC1B,6BAAuB,UAAU;OACjC;MACF;KACF;QAEF,wBAAuB,UAAU;IAElC,CAAC,UAAU,CAAC;AAGf,uBAAsB;AACpB,MAAI,aAAa,WAAW,SAAS;GACnC,MAAM,QAAQ,WAAW,QAAQ;AACjC,iBAAc,MAAM;;IAErB,CAAC,WAAW,UAAU,CAAC;CAE1B,MAAM,gBAAgB,UAAU,MAAqB;AACnD,MAAI,EAAE,QAAQ,SAAS;AACrB,KAAE,gBAAgB;AAClB,aAAU;aACD,EAAE,QAAQ,UAAU;AAC7B,KAAE,gBAAgB;AAClB,aAAU;aAEV,EAAE,QAAQ,eACV,EAAE,QAAQ,gBACV,EAAE,QAAQ,OACV,EAAE,QAAQ,YACV,EAAE,QAAQ,YAGV,GAAE,iBAAiB;GAErB;CAEF,MAAM,aAAa,eAAe;AAEhC,MAAI,uBAAuB,SAAS;AAElC,+BAA4B;AAC1B,aAAS,SAAS,OAAO;AACzB,aAAS,SAAS,QAAQ;KAC1B;AACF;;AAGF,YAAU;GACV;CAEF,MAAM,oBAAoB,UAAU,MAAkB;AACpD,IAAE,gBAAgB;AAClB,IAAE,iBAAiB;AACnB,kBAAgB;GAChB;AAEF,KAAI,WAAW;EAEb,MAAM,cAAc;GAClB,GAAG;GACH,YAAY,MAAuC;AACjD,kBAAc,EAAE;AAChB,eAAW,YAAY,EAAE;;GAE3B,SAAS,MAAoC;AAC3C,gBAAY;AACZ,eAAW,SAAS,EAAE;;GAEzB;AAED,SACE,8CACE,oBAAC;GAAc,KAAK;GAAY,eAAY;aACzC,aAAa;IACA,EAChB,oBAAC;GACC,GAAI;GACJ,KAAK;GACL,QAAQ,EAAE,gBAAgB,aAAa,GAAG,WAAW,MAAM,QAAQ;IACnE,IACD;;AAIP,QAAO,oBAAC;EAAK,eAAe;YAAoB;GAAa"}
|