diff --git a/editor/src/components/inspector/common/css-utils.ts b/editor/src/components/inspector/common/css-utils.ts index eb74150ed104..0e982adcfddb 100644 --- a/editor/src/components/inspector/common/css-utils.ts +++ b/editor/src/components/inspector/common/css-utils.ts @@ -4620,6 +4620,11 @@ const flexAlignmentsParser: Parser = isOneOfTheseParser([ FlexAlignment.Center, FlexAlignment.FlexEnd, FlexAlignment.Stretch, + FlexAlignment.Baseline, + FlexAlignment.FirstBaseline, + FlexAlignment.LastBaseline, + FlexAlignment.SafeCenter, + FlexAlignment.UnsafeCenter, ]) const flexJustifyContentParser: Parser = isOneOfTheseParser([ @@ -4629,6 +4634,10 @@ const flexJustifyContentParser: Parser = isOneOfTheseParser( FlexJustifyContent.SpaceAround, FlexJustifyContent.SpaceBetween, FlexJustifyContent.SpaceEvenly, + FlexJustifyContent.Stretch, + FlexJustifyContent.Normal, + FlexJustifyContent.SafeCenter, + FlexJustifyContent.UnsafeCenter, ]) export type CSSPosition = '-webkit-sticky' | 'absolute' | 'fixed' | 'relative' | 'static' | 'sticky' diff --git a/editor/src/components/inspector/controls/advanced-grid-modal.tsx b/editor/src/components/inspector/controls/advanced-grid-modal.tsx index 463dd8ff574e..f42b93c157c9 100644 --- a/editor/src/components/inspector/controls/advanced-grid-modal.tsx +++ b/editor/src/components/inspector/controls/advanced-grid-modal.tsx @@ -14,7 +14,7 @@ import { separatorRadixSelectOption, } from '../../../uuiui/radix-components' import { optionalMap } from '../../../core/shared/optional-utils' -import { FlexAlignment } from 'utopia-api/core' +import { AllFlexAlignments, AllFlexJustifyContents, FlexAlignment } from 'utopia-api/core' import { FlexJustifyContent } from 'utopia-api/core' import { GridAutoColsOrRowsControlInner } from '../grid-auto-cols-or-rows-control' import { Substores, useEditorState, useRefEditorState } from '../../editor/store/store-hook' @@ -82,13 +82,27 @@ export const AdvancedGridModal = React.memo((props: AdvancedGridModalProps) => { const justifyOptions = [ unsetSelectOption, separatorRadixSelectOption(), - ...Object.values(FlexJustifyContent).map(selectOption), + ...[ + FlexJustifyContent.FlexStart, + FlexJustifyContent.Center, + FlexJustifyContent.FlexEnd, + FlexJustifyContent.SpaceAround, + FlexJustifyContent.SpaceBetween, + FlexJustifyContent.SpaceEvenly, + FlexJustifyContent.Stretch, + ].map(selectOption), ] const alignOptions = [ unsetSelectOption, separatorRadixSelectOption(), - ...Object.values(FlexAlignment).map(selectOption), + ...[ + FlexAlignment.Auto, + FlexAlignment.FlexStart, + FlexAlignment.Center, + FlexAlignment.FlexEnd, + FlexAlignment.Stretch, + ].map(selectOption), ] const onSubmitJustifyContent = React.useCallback( @@ -200,6 +214,7 @@ export const AdvancedGridModal = React.memo((props: AdvancedGridModalProps) => { zIndex: 1, }} onOpenChange={toggleJustifyContentDropdown} + allowedValues={AllFlexJustifyContents} /> { zIndex: 1, }} onOpenChange={toggleAlignContentDropdown} + allowedValues={AllFlexAlignments} /> diff --git a/editor/src/uuiui/radix-components.tsx b/editor/src/uuiui/radix-components.tsx index 189d596eac52..77feb64fe1db 100644 --- a/editor/src/uuiui/radix-components.tsx +++ b/editor/src/uuiui/radix-components.tsx @@ -12,6 +12,7 @@ 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' +import { assertNever } from '../core/shared/utils' // Keep this in sync with the radix-components-portal div in index.html. export const RadixComponentsPortalId = 'radix-components-portal' @@ -256,6 +257,29 @@ export function separatorRadixSelectOption(): Separator { export type RadixSelectOption = RegularRadixSelectOption | Separator +function equalRadixSelectOptions( + a: RadixSelectOption | null, + b: RadixSelectOption | null, +): boolean { + if (a == null && b == null) { + return true + } + if (a == null || b == null) { + return false + } + switch (a.type) { + case 'REGULAR': + if (b.type !== 'REGULAR') { + return false + } + return a.value === b.value && a.label === b.label + case 'SEPARATOR': + return b.type === 'SEPARATOR' + default: + assertNever(a) + } +} + function optionLabelToString( option: RegularRadixSelectOption | null, isOpen: boolean, @@ -280,6 +304,7 @@ export const RadixSelect = React.memo( onValueChange?: (value: string) => void contentClassName?: string onOpenChange?: (open: boolean) => void + allowedValues?: string[] }) => { const stopPropagation = React.useCallback((e: React.KeyboardEvent) => { e.stopPropagation() @@ -296,7 +321,27 @@ export const RadixSelect = React.memo( [propsOnOpenChange], ) - const valueLabel = optionLabelToString(props.value ?? null, isOpen, props.value?.value ?? null) + const valueLabel = React.useMemo(() => { + return optionLabelToString(props.value ?? null, isOpen, props.value?.value ?? null) + }, [props.value, isOpen]) + + const options = React.useMemo(() => { + let fullOptions = [...props.options] + + if ( + // the value is not null + props.value != null && + // the value is allowed for this dropdown + props.allowedValues?.some((allowed) => allowed === props.value?.value) && + // the options don't contain the value already + !fullOptions.some((opt) => equalRadixSelectOptions(opt, props.value)) + ) { + // add the given option + separator at the top of the options + fullOptions.unshift(...[props.value, separatorDropdownMenuItem('unknown-dropdown-value')]) + } + + return fullOptions + }, [props.options, props.value, props.allowedValues]) return ( - {props.options.map((option, index) => { + {options.map((option, index) => { if (option.type === 'SEPARATOR') { return ( = [ @@ -206,6 +211,11 @@ export const AllFlexAlignments: Array = [ FlexAlignment.Center, FlexAlignment.FlexEnd, FlexAlignment.Stretch, + FlexAlignment.Baseline, + FlexAlignment.FirstBaseline, + FlexAlignment.LastBaseline, + FlexAlignment.SafeCenter, + FlexAlignment.UnsafeCenter, ] export enum FlexJustifyContent { @@ -216,6 +226,9 @@ export enum FlexJustifyContent { SpaceBetween = 'space-between', SpaceEvenly = 'space-evenly', Stretch = 'stretch', + Normal = 'normal', + SafeCenter = 'safe center', + UnsafeCenter = 'unsafe center', } export const AllFlexJustifyContents: Array = [ @@ -226,6 +239,9 @@ export const AllFlexJustifyContents: Array = [ FlexJustifyContent.SpaceBetween, FlexJustifyContent.SpaceEvenly, FlexJustifyContent.Stretch, + FlexJustifyContent.Normal, + FlexJustifyContent.SafeCenter, + FlexJustifyContent.UnsafeCenter, ] export enum FlexDirection {