From 63d3f4c712887191014f5edb15ae2513867d2592 Mon Sep 17 00:00:00 2001 From: Federico Ruggi <1081051+ruggi@users.noreply.github.com> Date: Tue, 22 Oct 2024 14:45:48 +0200 Subject: [PATCH] Open grid template row/col inspector menu with right click on title (#6573) **Problem:** It should be possible to open the dropdown/context menu for grid template rows/cols in the inspector by right-clicking the item's title. **Fix:** Add an invisible context menu in the title component and trigger it conditionally by right clicking the title itself. This solution works better than conditionally opening the same dropdown menu as the three dots button because it will correctly position it. https://github.com/user-attachments/assets/2c25fc94-b039-4423-9a3f-0c6e0f71b562 Fixes #6572 --- .../src/components/inspector/flex-section.tsx | 39 ++++++++++++++++--- editor/src/uuiui/radix-components.tsx | 4 +- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/editor/src/components/inspector/flex-section.tsx b/editor/src/components/inspector/flex-section.tsx index 5114495c30a3..5d27487c3357 100644 --- a/editor/src/components/inspector/flex-section.tsx +++ b/editor/src/components/inspector/flex-section.tsx @@ -4,7 +4,7 @@ import { jsx } from '@emotion/react' import React from 'react' import { createSelector } from 'reselect' -import { unless, when } from '../../utils/react-conditionals' +import { when } from '../../utils/react-conditionals' import { Substores, useEditorState, useRefEditorState } from '../editor/store/store-hook' import { AddRemoveLayoutSystemControl } from './add-remove-layout-system-control' import { FlexDirectionToggle } from './flex-direction-control' @@ -554,9 +554,15 @@ function AxisDimensionControl({ opener: (isOpen: boolean) => React.ReactElement }) { const testId = `grid-dimension-${axis}-${index}` - const [isOpen, setIsOpen] = React.useState(false) - const onOpenChange = React.useCallback((isDropdownOpen: boolean) => { - setIsOpen(isDropdownOpen) + const [isDotsMenuOpen, setDotsMenuOpen] = React.useState(false) + const [isTitleMenuOpen, setTitleMenuOpen] = React.useState(false) + + const onOpenChangeDotsMenu = React.useCallback((isDropdownOpen: boolean) => { + setDotsMenuOpen(isDropdownOpen) + }, []) + + const onOpenChangeTitleMenu = React.useCallback(() => { + setTitleMenuOpen(false) }, []) const isDynamic = React.useMemo(() => { @@ -584,6 +590,14 @@ function AxisDimensionControl({ setIsHovered(false) }, []) + const onContextMenuTitle = React.useCallback((e: React.MouseEvent) => { + e.preventDefault() + e.stopPropagation() + setTitleMenuOpen(true) + }, []) + + const invisibleOpener = React.useCallback(() => null, []) + return (
{title} + {when( - (isHovered && !gridExpressionInputFocused.focused) || isOpen, + (isHovered && !gridExpressionInputFocused.focused) || isDotsMenuOpen, - + , )}
diff --git a/editor/src/uuiui/radix-components.tsx b/editor/src/uuiui/radix-components.tsx index 86ed787124af..189d596eac52 100644 --- a/editor/src/uuiui/radix-components.tsx +++ b/editor/src/uuiui/radix-components.tsx @@ -11,6 +11,7 @@ import { Icons, SmallerIcons } from './icons' import { when } from '../utils/react-conditionals' import { Icn, type IcnProps } from './icn' import { forceNotNull } from '../core/shared/optional-utils' +import { usePropControlledStateV2 } from '../components/inspector/common/inspector-utils' // Keep this in sync with the radix-components-portal div in index.html. export const RadixComponentsPortalId = 'radix-components-portal' @@ -90,6 +91,7 @@ export interface DropdownMenuProps { alignOffset?: number onOpenChange?: (open: boolean) => void style?: CSSProperties + forceOpen?: boolean } export const ItemContainerTestId = (id: string) => `item-container-${id}` @@ -103,7 +105,7 @@ export const DropdownMenu = React.memo((props) => { }, []) const onEscapeKeyDown = React.useCallback((e: KeyboardEvent) => e.stopPropagation(), []) - const [open, setOpen] = React.useState(false) + const [open, setOpen] = usePropControlledStateV2(props.forceOpen || false) const shouldShowCheckboxes = props.items.some( (i) => !isSeparatorDropdownMenuItem(i) && i.checked != null,