diff --git a/editor/src/components/canvas/canvas-strategies/strategies/grid-helpers.ts b/editor/src/components/canvas/canvas-strategies/strategies/grid-helpers.ts index aa54f900d266..a2fb1f7c525e 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/grid-helpers.ts +++ b/editor/src/components/canvas/canvas-strategies/strategies/grid-helpers.ts @@ -653,9 +653,13 @@ function alterGridTemplateDimensions(params: { if (before.length + after.length === 0) { return null } - return gridCSSRepeat(dim.times, [...before, ...after]) + return gridCSSRepeat(dim.times, [...before, ...after], dim.areaName) case 'REPLACE': - return gridCSSRepeat(dim.times, [...before, params.patch.newValue, ...after]) + return gridCSSRepeat( + dim.times, + [...before, params.patch.newValue, ...after], + dim.areaName, + ) default: assertNever(params.patch) } diff --git a/editor/src/components/editor/store/store-deep-equality-instances.ts b/editor/src/components/editor/store/store-deep-equality-instances.ts index 9bf286061a5c..c988b328bcfb 100644 --- a/editor/src/components/editor/store/store-deep-equality-instances.ts +++ b/editor/src/components/editor/store/store-deep-equality-instances.ts @@ -2023,11 +2023,13 @@ export const GridDimensionKeepDeepEquality: KeepDeepEqualityCall ) export const GridCSSRepeatKeepDeepEquality: KeepDeepEqualityCall = - combine2EqualityCalls( + combine3EqualityCalls( (p) => p.times, createCallWithTripleEquals(), (p) => p.value, arrayDeepEquality(GridDimensionKeepDeepEquality), + (p) => p.areaName, + NullableStringKeepDeepEquality, gridCSSRepeat, ) diff --git a/editor/src/components/inspector/common/css-utils.spec.ts b/editor/src/components/inspector/common/css-utils.spec.ts index a534399c8552..60e85271648f 100644 --- a/editor/src/components/inspector/common/css-utils.spec.ts +++ b/editor/src/components/inspector/common/css-utils.spec.ts @@ -1827,33 +1827,45 @@ describe('stringifyGridDimension', () => { it('repeat', async () => { expect( stringifyGridDimension( - gridCSSRepeat(3, [ - gridCSSKeyword(cssKeyword('auto'), null), - gridCSSKeyword(cssKeyword('min-content'), null), - gridCSSNumber(cssNumber(123, 'px'), null), - ]), + gridCSSRepeat( + 3, + [ + gridCSSKeyword(cssKeyword('auto'), null), + gridCSSKeyword(cssKeyword('min-content'), null), + gridCSSNumber(cssNumber(123, 'px'), null), + ], + null, + ), ), ).toBe(`repeat(3, auto min-content 123px)`) expect( stringifyGridDimension( - gridCSSRepeat(3, [ - gridCSSKeyword(cssKeyword('auto'), 'foo'), - gridCSSKeyword(cssKeyword('min-content'), 'bar'), - gridCSSNumber(cssNumber(123, 'px'), null), - ]), + gridCSSRepeat( + 3, + [ + gridCSSKeyword(cssKeyword('auto'), 'foo'), + gridCSSKeyword(cssKeyword('min-content'), 'bar'), + gridCSSNumber(cssNumber(123, 'px'), null), + ], + 'the-area', + ), ), ).toBe(`repeat(3, [foo] auto [bar] min-content 123px)`) expect( stringifyGridDimension( - gridCSSRepeat(cssKeyword('auto-fit'), [ - gridCSSMinmax( - gridCSSNumber(cssNumber(400, 'px'), null), - gridCSSNumber(cssNumber(1, 'fr'), null), - null, - ), - ]), + gridCSSRepeat( + cssKeyword('auto-fit'), + [ + gridCSSMinmax( + gridCSSNumber(cssNumber(400, 'px'), null), + gridCSSNumber(cssNumber(1, 'fr'), null), + null, + ), + ], + null, + ), ), ).toBe(`repeat(auto-fit, minmax(400px, 1fr))`) }) @@ -1898,33 +1910,45 @@ describe('printGridDimensionCSS', () => { it('repeat', async () => { expect( printGridDimensionCSS( - gridCSSRepeat(3, [ - gridCSSKeyword(cssKeyword('auto'), null), - gridCSSKeyword(cssKeyword('min-content'), null), - gridCSSNumber(cssNumber(123, 'px'), null), - ]), + gridCSSRepeat( + 3, + [ + gridCSSKeyword(cssKeyword('auto'), null), + gridCSSKeyword(cssKeyword('min-content'), null), + gridCSSNumber(cssNumber(123, 'px'), null), + ], + null, + ), ), ).toBe(`repeat(3, auto min-content 123px)`) expect( printGridDimensionCSS( - gridCSSRepeat(3, [ - gridCSSKeyword(cssKeyword('auto'), 'foo'), - gridCSSKeyword(cssKeyword('min-content'), 'bar'), - gridCSSNumber(cssNumber(123, 'px'), null), - ]), + gridCSSRepeat( + 3, + [ + gridCSSKeyword(cssKeyword('auto'), 'foo'), + gridCSSKeyword(cssKeyword('min-content'), 'bar'), + gridCSSNumber(cssNumber(123, 'px'), null), + ], + 'the-area', + ), ), - ).toBe(`repeat(3, [foo] auto [bar] min-content 123px)`) + ).toBe(`[the-area] repeat(3, [foo] auto [bar] min-content 123px)`) expect( printGridDimensionCSS( - gridCSSRepeat(cssKeyword('auto-fit'), [ - gridCSSMinmax( - gridCSSNumber(cssNumber(400, 'px'), null), - gridCSSNumber(cssNumber(1, 'fr'), null), - null, - ), - ]), + gridCSSRepeat( + cssKeyword('auto-fit'), + [ + gridCSSMinmax( + gridCSSNumber(cssNumber(400, 'px'), null), + gridCSSNumber(cssNumber(1, 'fr'), null), + null, + ), + ], + null, + ), ), ).toBe(`repeat(auto-fit, minmax(400px, 1fr))`) }) diff --git a/editor/src/components/inspector/common/css-utils.ts b/editor/src/components/inspector/common/css-utils.ts index f7a0c80a2064..b2c28db037f9 100644 --- a/editor/src/components/inspector/common/css-utils.ts +++ b/editor/src/components/inspector/common/css-utils.ts @@ -598,14 +598,17 @@ export type GridCSSKeyword = BaseGridDimension & { type BaseGridCSSRepeat = { type: 'REPEAT' value: Array - areaName: null + areaName: string | null } -function baseGridCSSRepeat(value: Array): BaseGridCSSRepeat { +function baseGridCSSRepeat( + value: Array, + areaName: string | null, +): BaseGridCSSRepeat { return { type: 'REPEAT', value: value, - areaName: null, + areaName: areaName, } } @@ -613,9 +616,13 @@ type GridCSSRepeatStatic = BaseGridCSSRepeat & { times: number } -function gridCSSRepeatStatic(times: number, value: Array): GridCSSRepeatStatic { +function gridCSSRepeatStatic( + times: number, + value: Array, + areaName: string | null, +): GridCSSRepeatStatic { return { - ...baseGridCSSRepeat(value), + ...baseGridCSSRepeat(value, areaName), times: times, } } @@ -627,9 +634,10 @@ type GridCSSRepeatDynamic = BaseGridCSSRepeat & { function gridCSSRepeatDynamic( times: CSSKeyword<'auto-fill' | 'auto-fit'>, value: Array, + areaName: string | null, ): GridCSSRepeatDynamic { return { - ...baseGridCSSRepeat(value), + ...baseGridCSSRepeat(value, areaName), times: times, } } @@ -682,11 +690,15 @@ export function gridCSSKeyword( } } -export function gridCSSRepeat(times: GridCSSRepeatTimes, value: GridDimension[]): GridCSSRepeat { +export function gridCSSRepeat( + times: GridCSSRepeatTimes, + value: GridDimension[], + areaName: string | null, +): GridCSSRepeat { if (typeof times === 'number') { - return gridCSSRepeatStatic(times, value) + return gridCSSRepeatStatic(times, value, areaName) } else { - return gridCSSRepeatDynamic(times, value) + return gridCSSRepeatDynamic(times, value, areaName) } } @@ -1230,6 +1242,8 @@ export function parseGridChildren( return left('Invalid grid CSS repeat times.') } + const areaName = getAreaName() + const values = new csstree.List().fromArray( otherChildren.filter( (c) => @@ -1241,7 +1255,7 @@ export function parseGridChildren( ) const parsedDimensions = parseGridChildren(values) if (isRight(parsedDimensions)) { - dimensions.push(gridCSSRepeat(times, parsedDimensions.value)) + dimensions.push(gridCSSRepeat(times, parsedDimensions.value, areaName)) } else { return left('Invalid grid CSS repeat values.') } diff --git a/editor/src/components/inspector/flex-section.tsx b/editor/src/components/inspector/flex-section.tsx index 80473de131fa..6eed0980a59a 100644 --- a/editor/src/components/inspector/flex-section.tsx +++ b/editor/src/components/inspector/flex-section.tsx @@ -542,12 +542,20 @@ function AxisDimensionControl({ setIsOpen(isDropdownOpen) }, []) + const isDynamic = React.useMemo(() => { + return indexFrom !== indexTo + }, [indexFrom, indexTo]) + + const dynamicIndexTitle = React.useMemo(() => { + return `${indexFrom} → ${indexTo}` + }, [indexFrom, indexTo]) + const title = React.useMemo(() => { - if (indexFrom === indexTo) { - return value.areaName ?? indexFrom + if (isDynamic) { + return value.areaName ?? dynamicIndexTitle } - return value.areaName ?? `${indexFrom} → ${indexTo}` - }, [value, indexFrom, indexTo]) + return value.areaName ?? indexFrom + }, [value, indexFrom, isDynamic, dynamicIndexTitle]) const gridExpressionInputFocused = useGridExpressionInputFocused() @@ -574,7 +582,7 @@ function AxisDimensionControl({ textOverflow: 'ellipsis', whiteSpace: 'nowrap', }} - title={value.areaName ?? undefined} + title={isDynamic ? dynamicIndexTitle : undefined} > {title}