From dd4cff1717e1d87abaf635b2ee6f9485c3321ffd Mon Sep 17 00:00:00 2001
From: Federico Ruggi <1081051+ruggi@users.noreply.github.com>
Date: Mon, 15 Jul 2024 15:09:50 +0200
Subject: [PATCH 1/4] support labels in grid templates
---
.../canvas/controls/grid-controls.tsx | 5 ++
.../store/store-deep-equality-instances.ts | 4 +-
.../inspector/common/css-utils.spec.ts | 32 ++++++++++++
.../components/inspector/common/css-utils.ts | 52 +++++++++++++++++--
4 files changed, 88 insertions(+), 5 deletions(-)
diff --git a/editor/src/components/canvas/controls/grid-controls.tsx b/editor/src/components/canvas/controls/grid-controls.tsx
index 960b10bbe3c8..ada9bca19e2e 100644
--- a/editor/src/components/canvas/controls/grid-controls.tsx
+++ b/editor/src/components/canvas/controls/grid-controls.tsx
@@ -229,6 +229,7 @@ export const GridResizingControl = React.memo((props: GridResizingControlProps)
justifyContent: 'center',
cursor: gridEdgeToCSSCursor(props.axis === 'column' ? 'column-start' : 'row-start'),
fontSize: 8,
+ position: 'relative',
}}
css={{
opacity: resizing ? 1 : 0.5,
@@ -239,6 +240,10 @@ export const GridResizingControl = React.memo((props: GridResizingControlProps)
onMouseDown={mouseDownHandler}
>
{props.axis === 'row' ? '↕' : '↔'}
+ {when(
+ props.dimension.label != null,
+ {props.dimension.label},
+ )}
{when(
resizing,
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 7c0227f6db6d..e9a2bf790014 100644
--- a/editor/src/components/editor/store/store-deep-equality-instances.ts
+++ b/editor/src/components/editor/store/store-deep-equality-instances.ts
@@ -1970,11 +1970,13 @@ export const CSSNumberKeepDeepEquality: KeepDeepEqualityCall = combin
)
export const GridCSSNumberKeepDeepEquality: KeepDeepEqualityCall =
- combine2EqualityCalls(
+ combine3EqualityCalls(
(cssNum) => cssNum.value,
createCallWithTripleEquals(),
(cssNum) => cssNum.unit,
nullableDeepEquality(createCallWithTripleEquals()),
+ (cssNum) => cssNum.label,
+ nullableDeepEquality(StringKeepDeepEquality),
gridCSSNumber,
)
diff --git a/editor/src/components/inspector/common/css-utils.spec.ts b/editor/src/components/inspector/common/css-utils.spec.ts
index ae3151c0e63e..0f29b2a36d0d 100644
--- a/editor/src/components/inspector/common/css-utils.spec.ts
+++ b/editor/src/components/inspector/common/css-utils.spec.ts
@@ -71,6 +71,7 @@ import {
RegExpLibrary,
toggleSimple,
toggleStylePropPath,
+ tokenizeGridTemplate,
} from './css-utils'
describe('toggleStyleProp', () => {
@@ -1807,3 +1808,34 @@ describe('printBackgroundSize', () => {
`)
})
})
+
+describe('tokenizeGridTemplate', () => {
+ it('tokenizes the grid template strings (no units)', async () => {
+ expect(tokenizeGridTemplate('123 456 78 9')).toEqual(['123', '456', '78', '9'])
+ })
+ it('tokenizes the grid template strings (with units)', async () => {
+ expect(tokenizeGridTemplate('123 456px 78 9rem')).toEqual(['123', '456px', '78', '9rem'])
+ })
+ it('tokenizes the grid template strings (with some labels)', async () => {
+ expect(tokenizeGridTemplate('[foo] 123 456px 78 9rem')).toEqual([
+ '[foo] 123',
+ '456px',
+ '78',
+ '9rem',
+ ])
+ expect(tokenizeGridTemplate('123 [foo]456px 78 [bar] 9rem')).toEqual([
+ '123',
+ '[foo] 456px',
+ '78',
+ '[bar] 9rem',
+ ])
+ })
+ it('tokenizes the grid template strings (with all labels)', async () => {
+ expect(tokenizeGridTemplate('[foo] 123 [bar]456px [baz] 78 [QUX]9rem')).toEqual([
+ '[foo] 123',
+ '[bar] 456px',
+ '[baz] 78',
+ '[QUX] 9rem',
+ ])
+ })
+})
diff --git a/editor/src/components/inspector/common/css-utils.ts b/editor/src/components/inspector/common/css-utils.ts
index 4e00df8c85a0..53e5c7e920ec 100644
--- a/editor/src/components/inspector/common/css-utils.ts
+++ b/editor/src/components/inspector/common/css-utils.ts
@@ -589,12 +589,18 @@ const GridCSSNumberUnits: Array = [...LengthUnits, ...Resolut
export interface GridCSSNumber {
value: number
unit: GridCSSNumberUnit | null
+ label: string | null
}
-export function gridCSSNumber(value: number, unit: GridCSSNumberUnit | null): GridCSSNumber {
+export function gridCSSNumber(
+ value: number,
+ unit: GridCSSNumberUnit | null,
+ label: string | null,
+): GridCSSNumber {
return {
value,
unit,
+ label,
}
}
@@ -762,7 +768,9 @@ export function printArrayCSSNumber(array: Array): string {
return array
.map((dimension) => {
const printed = printCSSNumber(dimension, null)
- return typeof printed === 'string' ? printed : `${printed}`
+ const label = dimension.label != null ? `[${dimension.label}] ` : ''
+ const value = typeof printed === 'string' ? printed : `${printed}`
+ return `${label}${value}`
})
.join(' ')
}
@@ -834,13 +842,30 @@ export const parseCSSUnitlessAsNumber = (input: unknown): Either
}
}
+const gridCSSTemplateNumberRegex = /^\[(.+)\]\s*(.+)$/
+
export function parseToCSSGridNumber(input: unknown): Either {
+ function getParts() {
+ if (typeof input === 'string') {
+ const match = input.match(gridCSSTemplateNumberRegex)
+ if (match != null) {
+ return {
+ label: match[1],
+ inputToParse: match[2],
+ }
+ }
+ }
+ return { label: null, inputToParse: input }
+ }
+ const { label, inputToParse } = getParts()
+
return mapEither((value) => {
return {
value: value.value,
unit: value.unit as GridCSSNumberUnit | null,
+ label: label,
}
- }, parseCSSGrid(input))
+ }, parseCSSGrid(inputToParse))
}
export const parseCSSNumber = (
@@ -887,6 +912,25 @@ export function parseGridRange(input: unknown): Either {
}
}
+export function tokenizeGridTemplate(str: string): string[] {
+ let tokens: string[] = []
+ let parts = str.replace(/\]/g, '] ').split(/\s+/)
+
+ while (parts.length > 0) {
+ const part = parts.shift()?.trim()
+ if (part == null) {
+ break
+ }
+ if (part.match(/^\[.+\]$/) != null && parts.length > 0) {
+ const withLabel = `${part} ${parts.shift()}`
+ tokens.push(withLabel)
+ } else {
+ tokens.push(part)
+ }
+ }
+ return tokens
+}
+
export function parseGridAutoOrTemplateBase(
input: unknown,
): Either {
@@ -895,7 +939,7 @@ export function parseGridAutoOrTemplateBase(
return leftMapEither(descriptionParseError, result)
}
if (typeof input === 'string') {
- const parsedCSSArray = parseCSSArray([numberParse])(input.split(/ +/))
+ const parsedCSSArray = parseCSSArray([numberParse])(tokenizeGridTemplate(input))
return bimapEither(
(error) => {
if (error.type === 'DESCRIPTION_PARSE_ERROR') {
From 366c79da7175f1aacdc7d4e8251c4b9d61d8f287 Mon Sep 17 00:00:00 2001
From: Federico Ruggi <1081051+ruggi@users.noreply.github.com>
Date: Mon, 15 Jul 2024 15:15:53 +0200
Subject: [PATCH 2/4] rename
---
.../canvas/controls/grid-controls.tsx | 4 +--
.../store/store-deep-equality-instances.ts | 2 +-
.../components/inspector/common/css-utils.ts | 30 ++++++++++---------
3 files changed, 19 insertions(+), 17 deletions(-)
diff --git a/editor/src/components/canvas/controls/grid-controls.tsx b/editor/src/components/canvas/controls/grid-controls.tsx
index ada9bca19e2e..e4ab421f7280 100644
--- a/editor/src/components/canvas/controls/grid-controls.tsx
+++ b/editor/src/components/canvas/controls/grid-controls.tsx
@@ -241,8 +241,8 @@ export const GridResizingControl = React.memo((props: GridResizingControlProps)
>
{props.axis === 'row' ? '↕' : '↔'}
{when(
- props.dimension.label != null,
- {props.dimension.label},
+ props.dimension.areaName != null,
+ {props.dimension.areaName},
)}
{when(
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 e9a2bf790014..68a7ab75d6e3 100644
--- a/editor/src/components/editor/store/store-deep-equality-instances.ts
+++ b/editor/src/components/editor/store/store-deep-equality-instances.ts
@@ -1975,7 +1975,7 @@ export const GridCSSNumberKeepDeepEquality: KeepDeepEqualityCall
createCallWithTripleEquals(),
(cssNum) => cssNum.unit,
nullableDeepEquality(createCallWithTripleEquals()),
- (cssNum) => cssNum.label,
+ (cssNum) => cssNum.areaName,
nullableDeepEquality(StringKeepDeepEquality),
gridCSSNumber,
)
diff --git a/editor/src/components/inspector/common/css-utils.ts b/editor/src/components/inspector/common/css-utils.ts
index 53e5c7e920ec..54d87582806d 100644
--- a/editor/src/components/inspector/common/css-utils.ts
+++ b/editor/src/components/inspector/common/css-utils.ts
@@ -589,18 +589,18 @@ const GridCSSNumberUnits: Array = [...LengthUnits, ...Resolut
export interface GridCSSNumber {
value: number
unit: GridCSSNumberUnit | null
- label: string | null
+ areaName: string | null
}
export function gridCSSNumber(
value: number,
unit: GridCSSNumberUnit | null,
- label: string | null,
+ areaName: string | null,
): GridCSSNumber {
return {
- value,
- unit,
- label,
+ value: value,
+ unit: unit,
+ areaName: areaName,
}
}
@@ -768,9 +768,9 @@ export function printArrayCSSNumber(array: Array): string {
return array
.map((dimension) => {
const printed = printCSSNumber(dimension, null)
- const label = dimension.label != null ? `[${dimension.label}] ` : ''
+ const areaName = dimension.areaName != null ? `[${dimension.areaName}] ` : ''
const value = typeof printed === 'string' ? printed : `${printed}`
- return `${label}${value}`
+ return `${areaName}${value}`
})
.join(' ')
}
@@ -850,20 +850,20 @@ export function parseToCSSGridNumber(input: unknown): Either {
return {
value: value.value,
unit: value.unit as GridCSSNumberUnit | null,
- label: label,
+ areaName: areaName,
}
}, parseCSSGrid(inputToParse))
}
@@ -912,6 +912,8 @@ export function parseGridRange(input: unknown): Either {
}
}
+const reGridAreaNameBrackets = /^\[.+\]$/
+
export function tokenizeGridTemplate(str: string): string[] {
let tokens: string[] = []
let parts = str.replace(/\]/g, '] ').split(/\s+/)
@@ -921,9 +923,9 @@ export function tokenizeGridTemplate(str: string): string[] {
if (part == null) {
break
}
- if (part.match(/^\[.+\]$/) != null && parts.length > 0) {
- const withLabel = `${part} ${parts.shift()}`
- tokens.push(withLabel)
+ if (part.match(reGridAreaNameBrackets) != null && parts.length > 0) {
+ const withAreaName = `${part} ${parts.shift()}`
+ tokens.push(withAreaName)
} else {
tokens.push(part)
}
From 280539c7250e9aeef828fc700941b36b96e681a3 Mon Sep 17 00:00:00 2001
From: Federico Ruggi <1081051+ruggi@users.noreply.github.com>
Date: Mon, 15 Jul 2024 15:16:34 +0200
Subject: [PATCH 3/4] rename
---
editor/src/components/inspector/common/css-utils.spec.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/editor/src/components/inspector/common/css-utils.spec.ts b/editor/src/components/inspector/common/css-utils.spec.ts
index 0f29b2a36d0d..cc0fb96037fa 100644
--- a/editor/src/components/inspector/common/css-utils.spec.ts
+++ b/editor/src/components/inspector/common/css-utils.spec.ts
@@ -1816,7 +1816,7 @@ describe('tokenizeGridTemplate', () => {
it('tokenizes the grid template strings (with units)', async () => {
expect(tokenizeGridTemplate('123 456px 78 9rem')).toEqual(['123', '456px', '78', '9rem'])
})
- it('tokenizes the grid template strings (with some labels)', async () => {
+ it('tokenizes the grid template strings (with some area names)', async () => {
expect(tokenizeGridTemplate('[foo] 123 456px 78 9rem')).toEqual([
'[foo] 123',
'456px',
@@ -1830,7 +1830,7 @@ describe('tokenizeGridTemplate', () => {
'[bar] 9rem',
])
})
- it('tokenizes the grid template strings (with all labels)', async () => {
+ it('tokenizes the grid template strings (with all area names)', async () => {
expect(tokenizeGridTemplate('[foo] 123 [bar]456px [baz] 78 [QUX]9rem')).toEqual([
'[foo] 123',
'[bar] 456px',
From f5573860c5356073d009f153df9ea3a60b7b7b9a Mon Sep 17 00:00:00 2001
From: Federico Ruggi <1081051+ruggi@users.noreply.github.com>
Date: Mon, 15 Jul 2024 15:45:37 +0200
Subject: [PATCH 4/4] clean up
---
editor/src/components/inspector/common/css-utils.ts | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/editor/src/components/inspector/common/css-utils.ts b/editor/src/components/inspector/common/css-utils.ts
index 54d87582806d..5d063f951951 100644
--- a/editor/src/components/inspector/common/css-utils.ts
+++ b/editor/src/components/inspector/common/css-utils.ts
@@ -769,8 +769,7 @@ export function printArrayCSSNumber(array: Array): string {
.map((dimension) => {
const printed = printCSSNumber(dimension, null)
const areaName = dimension.areaName != null ? `[${dimension.areaName}] ` : ''
- const value = typeof printed === 'string' ? printed : `${printed}`
- return `${areaName}${value}`
+ return `${areaName}${printed}`
})
.join(' ')
}