Skip to content

Commit

Permalink
Fix/inspector mixed values (#4208)
Browse files Browse the repository at this point in the history
  • Loading branch information
ruggi authored Sep 20, 2023
1 parent 1c669ac commit d637f42
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 50 deletions.
10 changes: 9 additions & 1 deletion editor/src/components/inspector/common/control-styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,17 @@ const controlStylesByStatus: { [key: string]: ControlStyles } = mapArrayToDictio
trackColor = 'var(--control-styles-interactive-unset-track-color)'
railColor = 'var(--control-styles-interactive-unset-rail-color)'
break
case 'multiselect-mixed-simple-or-unset':
mixed = true
interactive = true
showContent = true
mainColor = colorTheme.fg6Opacity50.value
secondaryColor = colorTheme.fg6Opacity50.value
trackColor = colorTheme.fg6Opacity50.value
strokePrimaryColor = colorTheme.fg6Opacity50.value
break
case 'controlled':
case 'multiselect-controlled':
case 'multiselect-mixed-simple-or-unset':
interactive = true
mainColor = colorTheme.dynamicBlue.value
secondaryColor = colorTheme.dynamicBlue.value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import { MetadataUtils } from '../../../core/model/element-metadata-utils'
import type { InvalidGroupState } from '../../canvas/canvas-strategies/strategies/group-helpers'
import { invalidGroupStateToString } from '../../canvas/canvas-strategies/strategies/group-helpers'
import selectEvent from 'react-select-event'
import { MixedPlaceholder } from '../../../uuiui/inputs/base-input'

async function getControl(
controlTestId: string,
Expand Down Expand Up @@ -371,28 +372,32 @@ describe('inspector tests with real metadata', () => {
)) as HTMLInputElement

matchInlineSnapshotBrowser(metadata.computedStyle?.['width'], `"266px"`)
matchInlineSnapshotBrowser(widthControl.value, `"266"`)
matchInlineSnapshotBrowser(widthControl.value, '""')
matchInlineSnapshotBrowser(widthControl.placeholder, `"${MixedPlaceholder}"`)
matchInlineSnapshotBrowser(
widthControl.attributes.getNamedItemNS(null, 'data-controlstatus')?.value,
`"multiselect-mixed-simple-or-unset"`,
)

matchInlineSnapshotBrowser(metadata.computedStyle?.['height'], `"124px"`)
matchInlineSnapshotBrowser(heightControl.value, `"124"`)
matchInlineSnapshotBrowser(heightControl.value, `""`)
matchInlineSnapshotBrowser(heightControl.placeholder, `"${MixedPlaceholder}"`)
matchInlineSnapshotBrowser(
heightControl.attributes.getNamedItemNS(null, 'data-controlstatus')?.value,
`"multiselect-mixed-simple-or-unset"`,
)

matchInlineSnapshotBrowser(metadata.computedStyle?.['top'], `"98px"`)
matchInlineSnapshotBrowser(topControl.value, `"98"`)
matchInlineSnapshotBrowser(topControl.value, `""`)
matchInlineSnapshotBrowser(topControl.placeholder, `"${MixedPlaceholder}"`)
matchInlineSnapshotBrowser(
topControl.attributes.getNamedItemNS(null, 'data-controlstatus')?.value,
`"multiselect-mixed-simple-or-unset"`,
)

matchInlineSnapshotBrowser(metadata.computedStyle?.['left'], `"55px"`)
matchInlineSnapshotBrowser(leftControl.value, `"55"`)
matchInlineSnapshotBrowser(leftControl.value, `""`)
matchInlineSnapshotBrowser(leftControl.placeholder, `"${MixedPlaceholder}"`)
matchInlineSnapshotBrowser(
leftControl.attributes.getNamedItemNS(null, 'data-controlstatus')?.value,
`"multiselect-mixed-simple-or-unset"`,
Expand Down
5 changes: 3 additions & 2 deletions editor/src/components/inspector/fill-hug-fixed-control.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import { unsetProperty, setProp_UNSAFE } from '../editor/actions/action-creators
import { FlexCol } from 'utopia-api'
import { PinControl } from './controls/pin-control'
import type { FramePinsInfo } from './common/layout-property-path-hooks'
import { MixedPlaceholder } from '../../uuiui/inputs/base-input'

export const FillFixedHugControlId = (segment: 'width' | 'height'): string =>
`hug-fixed-fill-${segment}`
Expand Down Expand Up @@ -610,7 +611,7 @@ const GroupConstraintSelect = React.memo(
case 'constrained':
return colorTheme.brandNeonPink.value
case 'mixed':
return colorTheme.primary.value
return colorTheme.fg6Opacity50.value
case 'not-constrained':
return colorTheme.subduedForeground.value
default:
Expand Down Expand Up @@ -752,7 +753,7 @@ function checkGroupChildConstraint(
const groupChildConstraintOptionValues = {
constrained: groupChildConstraintOption('constrained'),
notConstrained: groupChildConstraintOption('not-constrained'),
mixed: { value: 'mixed', label: 'Mixed' },
mixed: { value: 'mixed', label: MixedPlaceholder },
}

const groupChildConstraintOptions: Array<SelectOption> = [
Expand Down
46 changes: 23 additions & 23 deletions editor/src/components/inspector/inspector-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ import {
parseCSSLengthPercent,
parseCSSNumber,
} from './common/css-utils'
import { assertNever, fastForEach } from '../../core/shared/utils'
import { assertNever } from '../../core/shared/utils'
import { defaultEither, foldEither, isLeft, isRight, right } from '../../core/shared/either'
import { elementOnlyHasTextChildren } from '../../core/model/element-template-utils'
import { forceNotNull, optionalMap } from '../../core/shared/optional-utils'
import { optionalMap } from '../../core/shared/optional-utils'
import type { CSSProperties } from 'react'
import type { CanvasCommand } from '../canvas/commands/commands'
import { deleteProperties } from '../canvas/commands/delete-properties-command'
Expand All @@ -45,17 +45,7 @@ import {
setPropHugStrategies,
} from './inspector-strategies/inspector-strategies'
import { commandsForFirstApplicableStrategy } from './inspector-strategies/inspector-strategy'
import {
CanvasRectangle,
roundUpToNearestHalf,
SimpleRectangle,
} from '../../core/shared/math-utils'
import {
canvasRectangle,
isFiniteRectangle,
isInfinityRectangle,
zeroRectIfNullOrInfinity,
} from '../../core/shared/math-utils'
import { isFiniteRectangle, isInfinityRectangle } from '../../core/shared/math-utils'
import { inlineHtmlElements } from '../../utils/html-elements'
import { intersection } from '../../core/shared/set-utils'
import { showToastCommand } from '../canvas/commands/show-toast-command'
Expand Down Expand Up @@ -733,24 +723,34 @@ export function detectFillHugFixedStateMultiselect(
if (elementPaths.length === 1) {
return detectFillHugFixedState(axis, metadata, elementPaths[0])
} else {
function fixedHugFillWithControlStatus(
fixedHugFill: FixedHugFill | null,
controlStatus: ControlStatus,
) {
return {
fixedHugFill: fixedHugFill,
controlStatus: controlStatus,
}
}

const results = elementPaths.map((path) => detectFillHugFixedState(axis, metadata, path))
let controlStatus: ControlStatus = results[0]?.controlStatus ?? 'off'
let value: FixedHugFill | null = results[0]?.fixedHugFill
const value: FixedHugFill | null = results[0]?.fixedHugFill

fastForEach(results, (result) => {
if (!isFixedHugFillEqual(result, results[0])) {
controlStatus = 'multiselect-mixed-simple-or-unset'
}
const isMixed = results.some((result) => {
return !isFixedHugFillEqual(result, results[0])
})
if (isMixed) {
return fixedHugFillWithControlStatus(value, 'multiselect-mixed-simple-or-unset')
}

const allControlStatus = uniq(results.map((result) => result.controlStatus))
if (allControlStatus.includes('unoverwritable')) {
controlStatus = 'multiselect-unoverwritable'
return fixedHugFillWithControlStatus(value, 'multiselect-unoverwritable')
} else if (allControlStatus.includes('controlled')) {
controlStatus = 'multiselect-controlled'
return fixedHugFillWithControlStatus(value, 'multiselect-controlled')
} else {
return fixedHugFillWithControlStatus(value, results[0]?.controlStatus ?? 'off')
}

return { fixedHugFill: value, controlStatus: controlStatus }
}
}

Expand Down
2 changes: 1 addition & 1 deletion editor/src/core/shared/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function identity<T>(t: T): T {
return t
}

export function fastForEach<T>(a: readonly T[], fn: (t: T, index: number) => void) {
export function fastForEach<T>(a: readonly T[], fn: (t: T, index: number) => void): void {
for (var i = 0, len = a.length; i < len; i++) {
if (i in a) {
fn(a[i]!, i)
Expand Down
13 changes: 13 additions & 0 deletions editor/src/uuiui/inputs/base-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,16 @@ export const InspectorInput = React.memo(
)
}),
)

export const MixedPlaceholder = 'Mixed'
export const UnknownPlaceholer = 'Unknown'

export function getInputPlaceholder(controlStyles: ControlStyles): string {
if (controlStyles.unknown) {
return UnknownPlaceholer
} else if (controlStyles.mixed) {
return MixedPlaceholder
} else {
return ''
}
}
29 changes: 18 additions & 11 deletions editor/src/uuiui/inputs/number-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import { Icn } from '../icn'
import { useColorTheme, UtopiaTheme } from '../styles/theme'
import { FlexRow } from '../widgets/layout/flex-row'
import type { BaseInputProps, BoxCorners, ChainedType } from './base-input'
import { getBorderRadiusStyles, InspectorInput } from './base-input'
import { getBorderRadiusStyles, getInputPlaceholder, InspectorInput } from './base-input'
import { usePropControlledStateV2 } from '../../components/inspector/common/inspector-utils'

export type LabelDragDirection = 'horizontal' | 'vertical'
Expand Down Expand Up @@ -179,17 +179,30 @@ export const NumberInput = React.memo<NumberInputProps>(
onMouseLeave,
}) => {
const ref = React.useRef<HTMLInputElement>(null)
const controlStyles = getControlStyles(controlStatus)
const colorTheme = useColorTheme()

const { showContent } = controlStyles
const controlStyles = React.useMemo(() => {
return getControlStyles(controlStatus)
}, [controlStatus])

const [mixed, setMixed] = React.useState<boolean>(controlStyles.mixed)
const { mixed, showContent } = React.useMemo(
() => ({
mixed: controlStyles.mixed,
showContent: controlStyles.showContent,
}),
[controlStyles],
)

const [value, setValue] = usePropControlledStateV2(propsValue ?? null)
const [displayValue, setDisplayValue] = usePropControlledStateV2(
getDisplayValue(value, defaultUnitToHide, mixed, showContent),
)
React.useEffect(() => {
if (mixed) {
setDisplayValue('')
}
}, [mixed, setDisplayValue])

const valueUnit = React.useMemo(() => value?.unit ?? null, [value])

const [isActuallyFocused, setIsActuallyFocused] = React.useState<boolean>(false)
Expand Down Expand Up @@ -496,7 +509,6 @@ export const NumberInput = React.memo<NumberInputProps>(
inputProps.onChange(e)
}
setValueChangedSinceFocus(true)
setMixed(false)
setDisplayValue(e.target.value)
},
[inputProps, setDisplayValue],
Expand Down Expand Up @@ -606,12 +618,7 @@ export const NumberInput = React.memo<NumberInputProps>(
[scrubOnMouseMove, scrubOnMouseUp, setGlobalCursor, value],
)

let placeholder: string = ''
if (controlStyles.unknown) {
placeholder = 'unknown'
} else if (controlStyles.mixed) {
placeholder = 'mixed'
}
const placeholder = getInputPlaceholder(controlStyles)

const chainedStyles: Interpolation<any> | undefined =
(chained === 'first' || chained === 'middle') && !isFocused
Expand Down
11 changes: 3 additions & 8 deletions editor/src/uuiui/inputs/string-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import type { ControlStatus } from '../../components/inspector/common/control-st
import type { ControlStyles } from '../../components/inspector/common/control-styles'
import { getControlStyles } from '../../components/inspector/common/control-styles'
import { preventDefault, stopPropagation } from '../../components/inspector/common/inspector-utils'
import { useColorTheme, UtopiaTheme } from '../styles/theme'
import { InspectorInput, InspectorInputEmotionStyle } from './base-input'
import { useColorTheme } from '../styles/theme'
import { InspectorInputEmotionStyle, getInputPlaceholder } from './base-input'

interface StringInputOptions {
focusOnMount?: boolean
Expand Down Expand Up @@ -73,12 +73,7 @@ export const StringInput = React.memo(
[inputPropsKeyDown],
)

let placeholder = initialPlaceHolder
if (controlStyles.unknown) {
placeholder = 'unknown'
} else if (controlStyles.mixed) {
placeholder = 'mixed'
}
const placeholder = getInputPlaceholder(controlStyles)

return (
<form
Expand Down

0 comments on commit d637f42

Please sign in to comment.