diff --git a/editor/src/components/inspector/common/css-utils.spec.ts b/editor/src/components/inspector/common/css-utils.spec.ts index 243f75f26ec2..a534399c8552 100644 --- a/editor/src/components/inspector/common/css-utils.spec.ts +++ b/editor/src/components/inspector/common/css-utils.spec.ts @@ -52,6 +52,10 @@ import { defaultCSSRadialGradientSize, defaultCSSRadialOrConicGradientCenter, disabledFunctionName, + gridCSSKeyword, + gridCSSMinmax, + gridCSSNumber, + gridCSSRepeat, parseBackgroundColor, parseBackgroundImage, parseBorderRadius, @@ -66,7 +70,9 @@ import { parseTransform, printBackgroundImage, printBackgroundSize, + printGridDimensionCSS, RegExpLibrary, + stringifyGridDimension, toggleSimple, toggleStylePropPath, } from './css-utils' @@ -1805,3 +1811,153 @@ describe('printBackgroundSize', () => { `) }) }) + +describe('stringifyGridDimension', () => { + it('keyword', async () => { + expect(stringifyGridDimension(gridCSSKeyword(cssKeyword('auto'), null))).toBe('auto') + expect(stringifyGridDimension(gridCSSKeyword(cssKeyword('auto'), 'the-area'))).toBe('auto') + }) + + it('number', async () => { + expect(stringifyGridDimension(gridCSSNumber(cssNumber(123), null))).toBe('123') + expect(stringifyGridDimension(gridCSSNumber(cssNumber(123, 'px'), null))).toBe('123px') + expect(stringifyGridDimension(gridCSSNumber(cssNumber(123), 'the-area'))).toBe('123') + }) + + it('repeat', async () => { + expect( + stringifyGridDimension( + gridCSSRepeat(3, [ + gridCSSKeyword(cssKeyword('auto'), null), + gridCSSKeyword(cssKeyword('min-content'), null), + gridCSSNumber(cssNumber(123, 'px'), 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), + ]), + ), + ).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, + ), + ]), + ), + ).toBe(`repeat(auto-fit, minmax(400px, 1fr))`) + }) + + it('minmax', async () => { + expect( + stringifyGridDimension( + gridCSSMinmax( + gridCSSKeyword(cssKeyword('auto'), null), + gridCSSKeyword(cssKeyword('min-content'), null), + null, + ), + ), + ).toBe('minmax(auto, min-content)') + + expect( + stringifyGridDimension( + gridCSSMinmax( + gridCSSKeyword(cssKeyword('auto'), null), + gridCSSKeyword(cssKeyword('min-content'), null), + 'the-area', + ), + ), + ).toBe('minmax(auto, min-content)') + }) +}) + +describe('printGridDimensionCSS', () => { + it('keyword', async () => { + expect(printGridDimensionCSS(gridCSSKeyword(cssKeyword('auto'), null))).toBe('auto') + expect(printGridDimensionCSS(gridCSSKeyword(cssKeyword('auto'), 'the-area'))).toBe( + '[the-area] auto', + ) + }) + + it('number', async () => { + expect(printGridDimensionCSS(gridCSSNumber(cssNumber(123), null))).toBe('123') + expect(printGridDimensionCSS(gridCSSNumber(cssNumber(123, 'px'), null))).toBe('123px') + expect(printGridDimensionCSS(gridCSSNumber(cssNumber(123), 'the-area'))).toBe('[the-area] 123') + }) + + it('repeat', async () => { + expect( + printGridDimensionCSS( + gridCSSRepeat(3, [ + gridCSSKeyword(cssKeyword('auto'), null), + gridCSSKeyword(cssKeyword('min-content'), null), + gridCSSNumber(cssNumber(123, 'px'), 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), + ]), + ), + ).toBe(`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, + ), + ]), + ), + ).toBe(`repeat(auto-fit, minmax(400px, 1fr))`) + }) + + it('minmax', async () => { + expect( + printGridDimensionCSS( + gridCSSMinmax( + gridCSSKeyword(cssKeyword('auto'), null), + gridCSSKeyword(cssKeyword('min-content'), null), + null, + ), + ), + ).toBe('minmax(auto, min-content)') + + expect( + printGridDimensionCSS( + gridCSSMinmax( + gridCSSKeyword(cssKeyword('auto'), null), + gridCSSKeyword(cssKeyword('min-content'), null), + 'the-area', + ), + ), + ).toBe('[the-area] minmax(auto, min-content)') + + expect( + printGridDimensionCSS( + gridCSSMinmax( + gridCSSKeyword(cssKeyword('auto'), 'foo'), + gridCSSKeyword(cssKeyword('min-content'), 'bar'), + 'the-area', + ), + ), + ).toBe('[the-area] minmax(auto, min-content)') + }) +}) diff --git a/editor/src/components/inspector/common/css-utils.ts b/editor/src/components/inspector/common/css-utils.ts index feec3148dc00..f7a0c80a2064 100644 --- a/editor/src/components/inspector/common/css-utils.ts +++ b/editor/src/components/inspector/common/css-utils.ts @@ -904,27 +904,28 @@ export function printCSSNumber( } } -export function printGridDimension(dimension: GridDimension, hideAreaName?: boolean): string { - const areaName = - dimension.areaName != null && hideAreaName !== true ? `[${dimension.areaName}] ` : '' +export function printGridDimensionCSS(dimension: GridDimension): string { + const areaName = dimension.areaName != null ? `[${dimension.areaName}] ` : '' + return areaName + stringifyGridDimension(dimension) +} + +export function stringifyGridDimension(dimension: GridDimension): string { switch (dimension.type) { case 'KEYWORD': { - return `${areaName}${dimension.value.value}` + return dimension.value.value } case 'NUMBER': { - const printed = printCSSNumber(dimension.value, null) - return `${areaName}${printed}` + return `${printCSSNumber(dimension.value, null)}` } case 'REPEAT': { - return `repeat(${ - isCSSKeyword(dimension.times) ? dimension.times.value : dimension.times - }, ${printArrayGridDimensions(dimension.value)})` + const times = isCSSKeyword(dimension.times) ? dimension.times.value : dimension.times + const values = dimension.value.map(printGridDimensionCSS).join(' ') + return `repeat(${times}, ${values})` } case 'MINMAX': { - return ( - areaName + - `minmax(${printGridDimension(dimension.min)}, ${printGridDimension(dimension.max)})` - ) + const min = stringifyGridDimension(dimension.min) + const max = stringifyGridDimension(dimension.max) + return `minmax(${min}, ${max})` } default: assertNever(dimension) @@ -932,7 +933,7 @@ export function printGridDimension(dimension: GridDimension, hideAreaName?: bool } export function printArrayGridDimensions(array: Array): string { - return array.map((v) => printGridDimension(v)).join(' ') + return array.map(printGridDimensionCSS).join(' ') } export function printGridAutoOrTemplateBase(input: GridAutoOrTemplateBase): string { diff --git a/editor/src/components/inspector/flex-section.spec.browser2.tsx b/editor/src/components/inspector/flex-section.spec.browser2.tsx index 1cdcc970fb6d..e624cd80e3ef 100644 --- a/editor/src/components/inspector/flex-section.spec.browser2.tsx +++ b/editor/src/components/inspector/flex-section.spec.browser2.tsx @@ -61,12 +61,18 @@ describe('flex section', () => { await selectComponentsForTest(renderResult, [EP.fromString('sb/grid')]) const grid = await renderResult.renderedDOM.findByTestId('grid') - - await typeIntoField( - await screen.findByTestId('grid-dimension-column-1'), - 'repeat(2, 0.5fr 42px)', - ) + const input: HTMLInputElement = await screen.findByTestId('grid-dimension-column-1') + await typeIntoField(input, 'repeat(2, 0.5fr 42px)') expect(grid.style.gridTemplateColumns).toEqual('[area1] 1fr repeat(2, 0.5fr 42px) 2fr') + expect(input.value).toBe('repeat(2, 0.5fr 42px)') + }) + it('does not show area names in the input', async () => { + const renderResult = await renderTestEditorWithCode(gridProject, 'await-first-dom-report') + await selectComponentsForTest(renderResult, [EP.fromString('sb/grid')]) + const control: HTMLInputElement = await screen.findByTestId('grid-dimension-column-0') + const grid = await renderResult.renderedDOM.findByTestId('grid') + expect(grid.style.gridTemplateColumns).toEqual('[area1] 1fr 1fr 1fr 1fr 1fr') + expect(control.value).toBe('1fr') }) }) }) diff --git a/editor/src/uuiui/inputs/grid-expression-input.tsx b/editor/src/uuiui/inputs/grid-expression-input.tsx index d3c0217663f9..b5a5bf3a1830 100644 --- a/editor/src/uuiui/inputs/grid-expression-input.tsx +++ b/editor/src/uuiui/inputs/grid-expression-input.tsx @@ -5,7 +5,7 @@ import { isValidGridDimensionKeyword, parseCSSNumber, parseGridCSSMinmaxOrRepeat, - printGridDimension, + stringifyGridDimension, type CSSKeyword, type CSSNumber, type GridDimension, @@ -32,8 +32,8 @@ export const GridExpressionInput = React.memo( onFocus, onBlur, }: GridExpressionInputProps) => { - const [printValue, setPrintValue] = React.useState(printGridDimension(value)) - React.useEffect(() => setPrintValue(printGridDimension(value)), [value]) + const [printValue, setPrintValue] = React.useState(stringifyGridDimension(value)) + React.useEffect(() => setPrintValue(stringifyGridDimension(value)), [value]) const onChange = React.useCallback((e: React.ChangeEvent) => { setPrintValue(e.target.value) @@ -66,7 +66,7 @@ export const GridExpressionInput = React.memo( return onUpdateNumberOrKeyword(cssKeyword('auto')) } - setPrintValue(printGridDimension(value)) + setPrintValue(stringifyGridDimension(value)) }, [printValue, onUpdateNumberOrKeyword, onUpdateDimension, value], )