Skip to content

Commit

Permalink
Icons for grid autoflow dropdown (#6214)
Browse files Browse the repository at this point in the history
**Problem:**

The grid autoflow dropdown should have meaningful icons.

**Fix:**

- Add the icons to the dropdown select options
- Reorder the values to match intended designs
- Add a wrapper for radix-ui's select component in order to be able to
use separators/placeholders/etc.



https://github.com/user-attachments/assets/7f9ac9c2-9610-4ea9-ba98-a76f77976698



Fixes #6213
  • Loading branch information
ruggi authored Aug 9, 2024
1 parent 0c64aa8 commit 865c30d
Show file tree
Hide file tree
Showing 5 changed files with 301 additions and 35 deletions.
1 change: 1 addition & 0 deletions editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@
"@liveblocks/yjs": "1.10.0",
"@popperjs/core": "2.4.4",
"@radix-ui/react-dropdown-menu": "2.1.1",
"@radix-ui/react-select": "2.1.1",
"@remix-run/react": "2.0.1",
"@remix-run/server-runtime": "2.3.1",
"@root/encoding": "1.0.1",
Expand Down
79 changes: 79 additions & 0 deletions editor/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 28 additions & 1 deletion editor/src/components/inspector/common/css-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ import type { ParseError } from '../../../utils/value-parser-utils'
import { descriptionParseError } from '../../../utils/value-parser-utils'
import * as csstree from 'css-tree'
import { expandCssTreeNodeValue, parseCssTreeNodeValue } from './css-tree-utils'
import type { IcnProps } from '../../../uuiui'

var combineRegExp = function (regexpList: Array<RegExp | string>, flags?: string) {
let source: string = ''
Expand Down Expand Up @@ -982,9 +983,35 @@ export function parseGridPosition(
}
}

export const GridAutoFlowValues = ['row', 'column', 'dense', 'row dense', 'column dense'] as const
export const GridAutoFlowValues = ['column', 'column dense', 'row', 'row dense', 'dense'] as const
export type GridAutoFlow = (typeof GridAutoFlowValues)[number]

export function gridAutoFlowIcon(value: GridAutoFlow): IcnProps {
switch (value) {
case 'column':
case 'column dense':
return {
category: 'inspector-element',
type: 'arrowDown',
color: 'black',
width: 16,
height: 16,
}
case 'dense':
case 'row':
case 'row dense':
return {
category: 'inspector-element',
type: 'arrowRight',
color: 'black',
width: 16,
height: 16,
}
default:
assertNever(value)
}
}

export function parseGridAutoFlow(rawValue: string): GridAutoFlow | null {
if (GridAutoFlowValues.some((v) => v === rawValue)) {
return rawValue as GridAutoFlow
Expand Down
76 changes: 43 additions & 33 deletions editor/src/components/inspector/flex-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import type { DetectedLayoutSystem } from 'utopia-shared/src/types'
import { NO_OP } from '../../core/shared/utils'
import { assertNever } from '../../core/shared/utils'
import {
PopupList,
FlexRow,
Icons,
InspectorSectionIcons,
Expand All @@ -44,6 +43,7 @@ import {
cssKeyword,
cssNumber,
cssNumberToString,
gridAutoFlowIcon,
gridCSSKeyword,
gridCSSNumber,
isCSSKeyword,
Expand All @@ -54,11 +54,7 @@ import {
isValidGridDimensionKeyword,
type GridDimension,
} from './common/css-utils'
import {
applyCommandsAction,
setProp_UNSAFE,
transientActions,
} from '../editor/actions/action-creators'
import { applyCommandsAction, transientActions } from '../editor/actions/action-creators'
import type { PropertyToUpdate } from '../canvas/commands/set-property-command'
import {
propertyToDelete,
Expand All @@ -73,19 +69,22 @@ import type {
GridPosition,
} from '../../core/shared/element-template'
import {
emptyComments,
gridPositionValue,
jsExpressionValue,
type ElementInstanceMetadata,
type GridElementProperties,
} from '../../core/shared/element-template'
import { setGridPropsCommands } from '../canvas/canvas-strategies/strategies/grid-helpers'
import { type CanvasCommand } from '../canvas/commands/commands'
import type { DropdownMenuItem } from '../../uuiui/radix-components'
import { DropdownMenu, regularDropdownMenuItem } from '../../uuiui/radix-components'
import {
DropdownMenu,
RadixSelect,
regularDropdownMenuItem,
regularRadixSelectOption,
separatorRadixSelectOption,
} from '../../uuiui/radix-components'
import { useInspectorLayoutInfo, useInspectorStyleInfo } from './common/property-path-hooks'
import { NumberOrKeywordControl } from '../../uuiui/inputs/number-or-keyword-control'
import type { SelectOption } from './controls/select-control'
import { optionalMap } from '../../core/shared/optional-utils'
import { cssNumberEqual } from '../canvas/controls/select-mode/controls-common'
import type { EditorAction } from '../editor/action-types'
Expand Down Expand Up @@ -825,12 +824,25 @@ GapRowColumnControl.displayName = 'GapRowColumnControl'

const AutoFlowPopupId = 'auto-flow-control'

const selectOption = (value: GridAutoFlow | 'unset'): SelectOption => ({
label: value,
value: value,
function selectOption(value: GridAutoFlow) {
return regularRadixSelectOption({
label: value,
value: value,
icon: gridAutoFlowIcon(value),
})
}

const unsetSelectOption = regularRadixSelectOption({
label: 'unset',
value: 'unset',
placeholder: true,
})

const GRID_AUTO_FLOW_DROPDOWN_OPTIONS: Array<SelectOption> = GridAutoFlowValues.map(selectOption)
const autoflowOptions = [
unsetSelectOption,
separatorRadixSelectOption(),
...GridAutoFlowValues.map(selectOption),
]

const AutoFlowControl = React.memo(() => {
const dispatch = useDispatch()
Expand All @@ -853,28 +865,30 @@ const AutoFlowControl = React.memo(() => {
'AutoFlowControl gridAutoFlowValue',
)

const { controlStyles, controlStatus } = useInspectorStyleInfo('gridAutoFlow')
const { controlStatus } = useInspectorStyleInfo('gridAutoFlow')

const currentValue = React.useMemo(
() =>
controlStatus === 'detected'
? selectOption('unset')
: optionalMap((v) => selectOption(v), gridAutoFlowValue) ?? undefined,
? unsetSelectOption
: optionalMap(selectOption, gridAutoFlowValue) ?? undefined,
[controlStatus, gridAutoFlowValue],
)

const onSubmit = React.useCallback(
(option: SelectOption) => {
(value: string) => {
if (selectededViewsRef.current.length === 0) {
return
}
dispatch(
selectededViewsRef.current.map((target) =>
setProp_UNSAFE(
target,
PP.create('style', 'gridAutoFlow'),
jsExpressionValue(option.value, emptyComments),
),
selectededViewsRef.current.map((path) =>
applyCommandsAction([
updateBulkProperties('always', path, [
value === 'unset'
? propertyToDelete(PP.create('style', 'gridAutoFlow'))
: propertyToSet(PP.create('style', 'gridAutoFlow'), value),
]),
]),
),
)
},
Expand All @@ -884,16 +898,12 @@ const AutoFlowControl = React.memo(() => {
return (
<FlexRow style={{ gap: 6 }}>
<div style={{ fontWeight: 600 }}>Auto Flow</div>
<PopupList
<RadixSelect
id={AutoFlowPopupId}
value={currentValue}
options={GRID_AUTO_FLOW_DROPDOWN_OPTIONS}
onSubmitValue={onSubmit}
controlStyles={controlStyles}
style={{
background: 'transparent',
opacity: controlStatus !== 'detected' ? undefined : 0.5,
}}
style={{ flex: 1 }}
value={currentValue ?? null}
options={autoflowOptions}
onValueChange={onSubmit}
/>
</FlexRow>
)
Expand Down
Loading

0 comments on commit 865c30d

Please sign in to comment.