Skip to content

Commit

Permalink
fix(inspector) Grid Template Field Dropdowns (#6498)
Browse files Browse the repository at this point in the history
- Integrated some similar logic into `GridExpressionInput` that is in
`NumberOrKeywordControl`.
- Resurrected `gridDimensionDropdownKeywords` from the previous code so
that it can be passed to `GridExpressionInput`.
  • Loading branch information
seanparsons authored Oct 9, 2024
1 parent 9dce309 commit 9ba3fe1
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 17 deletions.
35 changes: 27 additions & 8 deletions editor/src/components/inspector/flex-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
SquareButton,
Subdued,
Tooltip,
UtopiaTheme,
} from '../../uuiui'
import type {
CSSKeyword,
Expand Down Expand Up @@ -513,6 +514,12 @@ const TemplateDimensionControl = React.memo(
)
TemplateDimensionControl.displayName = 'TemplateDimensionControl'

const gridDimensionDropdownKeywords = [
{ label: 'Auto', value: cssKeyword('auto') },
{ label: 'Min-Content', value: cssKeyword('min-content') },
{ label: 'Max-Content', value: cssKeyword('max-content') },
]

function AxisDimensionControl({
value,
index,
Expand Down Expand Up @@ -574,10 +581,21 @@ function AxisDimensionControl({
},
}}
>
<div style={{ display: 'flex', alignItems: 'center', gap: 6, flex: 1 }}>
<div
style={{
display: 'grid',
gridAutoFlow: 'column',
alignItems: 'center',
gap: 6,
gridTemplateColumns: gridExpressionInputFocused.focused
? `40px auto`
: `40px auto ${UtopiaTheme.layout.inputHeight.default}px`,
gridTemplateRows: '1fr',
width: `100%`,
}}
>
<Subdued
style={{
width: 40,
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
Expand All @@ -593,14 +611,15 @@ function AxisDimensionControl({
onUpdateDimension={onUpdateDimension(index)}
onFocus={gridExpressionInputFocused.onFocus}
onBlur={gridExpressionInputFocused.onBlur}
keywords={gridDimensionDropdownKeywords}
/>
{unless(
gridExpressionInputFocused.focused,
<SquareButton className={axisDropdownMenuButton}>
<DropdownMenu align='end' items={items} opener={opener} onOpenChange={onOpenChange} />
</SquareButton>,
)}
</div>
{unless(
gridExpressionInputFocused.focused,
<SquareButton className={axisDropdownMenuButton}>
<DropdownMenu align='end' items={items} opener={opener} onOpenChange={onOpenChange} />
</SquareButton>,
)}
</div>
)
}
Expand Down
147 changes: 138 additions & 9 deletions editor/src/uuiui/inputs/grid-expression-input.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/** @jsxRuntime classic */
/** @jsx jsx */
import { jsx } from '@emotion/react'
import type { CSSProperties } from 'react'
import React from 'react'
import {
cssKeyword,
Expand All @@ -13,6 +17,16 @@ import {
} from '../../components/inspector/common/css-utils'
import { isRight } from '../../core/shared/either'
import { StringInput } from './string-input'
import type { DropdownMenuItem } from '../radix-components'
import {
DropdownMenu,
regularDropdownMenuItem,
separatorDropdownMenuItem,
} from '../radix-components'
import { Icons, SmallerIcons } from '../icons'
import { NO_OP } from '../../core/shared/utils'
import { unless } from '../../utils/react-conditionals'
import { useColorTheme } from '../styles/theme'

interface GridExpressionInputProps {
testId: string
Expand All @@ -21,8 +35,12 @@ interface GridExpressionInputProps {
onUpdateDimension: (v: GridDimension) => void
onFocus: () => void
onBlur: () => void
keywords: Array<{ label: string; value: CSSKeyword<any> }>
style?: CSSProperties
}

const DropdownWidth = 25

export const GridExpressionInput = React.memo(
({
testId,
Expand All @@ -31,7 +49,11 @@ export const GridExpressionInput = React.memo(
onUpdateDimension,
onFocus,
onBlur,
keywords,
style = {},
}: GridExpressionInputProps) => {
const colorTheme = useColorTheme()

const [printValue, setPrintValue] = React.useState<string>(stringifyGridDimension(value))
React.useEffect(() => setPrintValue(stringifyGridDimension(value)), [value])

Expand Down Expand Up @@ -71,16 +93,123 @@ export const GridExpressionInput = React.memo(
[printValue, onUpdateNumberOrKeyword, onUpdateDimension, value],
)

const [hover, setHover] = React.useState(false)
const [dropdownOpen, setDropdownOpen] = React.useState(false)
const onMouseOver = React.useCallback(() => {
setHover(true)
}, [])
const onMouseOut = React.useCallback(() => {
setHover(false)
}, [])

const dropdownButtonId = `${testId}-dropdown`

const dropdownButton = React.useCallback(
() => (
<SmallerIcons.ExpansionArrowDown
testId={dropdownButtonId}
style={{
visibility: hover || dropdownOpen ? 'visible' : 'hidden',
cursor: 'pointer',
marginRight: 5,
}}
/>
),
[dropdownButtonId, hover, dropdownOpen],
)

const dropdownItems = React.useMemo((): DropdownMenuItem[] => {
let items: DropdownMenuItem[] = []
items.push(
regularDropdownMenuItem({
id: 'dropdown-input-value',
icon: <Icons.Checkmark color='white' width={16} height={16} />,
label: printValue,
disabled: true,
onSelect: NO_OP,
}),
)
if (keywords.length > 0) {
items.push(separatorDropdownMenuItem('dropdown-separator'))
}
items.push(
...keywords.map((keyword, idx): DropdownMenuItem => {
return regularDropdownMenuItem({
id: `dropdown-label-${keyword.value.value}`,
icon: <div style={{ width: 16, height: 16 }} />,
label: keyword.label,
onSelect: () => onUpdateNumberOrKeyword(keyword.value),
})
}),
)
return items
}, [keywords, printValue, onUpdateNumberOrKeyword])

const [inputFocused, setInputFocused] = React.useState(false)

const inputOnFocus = React.useCallback(() => {
setInputFocused(true)
onFocus()
}, [onFocus])

const inputOnBlur = React.useCallback(() => {
setInputFocused(false)
onBlur()
}, [onBlur])

return (
<StringInput
style={{ width: '100%' }}
testId={testId}
value={printValue}
onChange={onChange}
onKeyDown={onKeyDown}
onFocus={onFocus}
onBlur={onBlur}
/>
<div
style={style}
css={{
borderRadius: 2,
display: 'flex',
alignItems: 'center',
flexGrow: 1,
flexDirection: 'row',
'&:hover': {
boxShadow: `inset 0px 0px 0px 1px ${
dropdownOpen ? colorTheme.dynamicBlue.value : colorTheme.fg7.value
}`,
},
'&:focus-within': {
boxShadow: `inset 0px 0px 0px 1px ${colorTheme.dynamicBlue.value}`,
},
}}
onMouseOver={onMouseOver}
onMouseOut={onMouseOut}
>
<StringInput
testId={testId}
value={printValue}
onChange={onChange}
onKeyDown={onKeyDown}
onFocus={inputOnFocus}
onBlur={inputOnBlur}
showBorder={false}
includeBoxShadow={false}
style={{
width: inputFocused ? '100%' : `calc(100% - ${DropdownWidth}px)`,
}}
/>
{unless(
inputFocused,
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: `${DropdownWidth}px`,
}}
>
<DropdownMenu
align='end'
items={dropdownItems}
opener={dropdownButton}
onOpenChange={setDropdownOpen}
/>
</div>,
)}
</div>
)
},
)
Expand Down

0 comments on commit 9ba3fe1

Please sign in to comment.