Skip to content

Commit

Permalink
Open grid template row/col inspector menu with right click on title (#…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
ruggi authored and liady committed Dec 13, 2024
1 parent efc20aa commit 63d3f4c
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 7 deletions.
39 changes: 33 additions & 6 deletions editor/src/components/inspector/flex-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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(() => {
Expand Down Expand Up @@ -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 (
<div
key={`col-${value}-${index}`}
Expand Down Expand Up @@ -611,8 +625,16 @@ function AxisDimensionControl({
whiteSpace: 'nowrap',
}}
title={isDynamic ? dynamicIndexTitle : undefined}
onContextMenu={onContextMenuTitle}
>
{title}
<DropdownMenu
align='start'
items={items}
opener={invisibleOpener}
onOpenChange={onOpenChangeTitleMenu}
forceOpen={isTitleMenuOpen}
/>
</Subdued>
<GridExpressionInput
testId={testId}
Expand All @@ -625,9 +647,14 @@ function AxisDimensionControl({
defaultValue={gridCSSKeyword(cssKeyword('auto'), null)}
/>
{when(
(isHovered && !gridExpressionInputFocused.focused) || isOpen,
(isHovered && !gridExpressionInputFocused.focused) || isDotsMenuOpen,
<SquareButton>
<DropdownMenu align='end' items={items} opener={opener} onOpenChange={onOpenChange} />
<DropdownMenu
align='end'
items={items}
opener={opener}
onOpenChange={onOpenChangeDotsMenu}
/>
</SquareButton>,
)}
</div>
Expand Down
4 changes: 3 additions & 1 deletion editor/src/uuiui/radix-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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}`
Expand All @@ -103,7 +105,7 @@ export const DropdownMenu = React.memo<DropdownMenuProps>((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,
Expand Down

0 comments on commit 63d3f4c

Please sign in to comment.