Skip to content

Commit 45649c6

Browse files
authored
fix(canvas) Increment/Decrement Fractional Grid Tracks (#6588)
- Added `isFR` utility function. - Modified `GridExpressionInput.onKeyDown` to handle arrow up and down but only for fractional values.
1 parent 7f377c9 commit 45649c6

File tree

2 files changed

+57
-22
lines changed

2 files changed

+57
-22
lines changed

editor/src/components/inspector/common/css-utils.ts

+4
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,10 @@ const CSSNumberUnits: Array<CSSNumberUnit> = [
574574
'%',
575575
]
576576

577+
export function isFR(unit: CSSNumberUnit): unit is 'fr' {
578+
return unit === 'fr'
579+
}
580+
577581
export interface CSSNumber {
578582
value: number
579583
unit: CSSNumberUnit | null

editor/src/uuiui/inputs/grid-expression-input.tsx

+53-22
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
import { jsx } from '@emotion/react'
44
import type { CSSProperties } from 'react'
55
import React from 'react'
6+
import type { CSSNumberUnit } from '../../components/inspector/common/css-utils'
67
import {
78
cssKeyword,
89
gridDimensionsAreEqual,
10+
isFR,
911
isGridCSSNumber,
1012
isValidGridDimensionKeyword,
1113
parseCSSNumber,
@@ -28,6 +30,9 @@ import { Icons, SmallerIcons } from '../icons'
2830
import { NO_OP } from '../../core/shared/utils'
2931
import { unless } from '../../utils/react-conditionals'
3032
import { useColorTheme, UtopiaTheme } from '../styles/theme'
33+
import type { Optic } from '../../core/shared/optics/optics'
34+
import { fromField, fromTypeGuard, notNull } from '../../core/shared/optics/optic-creators'
35+
import { exists, modify } from '../../core/shared/optics/optic-utilities'
3136

3237
interface GridExpressionInputProps {
3338
testId: string
@@ -43,6 +48,8 @@ interface GridExpressionInputProps {
4348

4449
const DropdownWidth = 25
4550

51+
const ArrowKeyFractionalIncrement = 0.1
52+
4653
export const GridExpressionInput = React.memo(
4754
({
4855
testId,
@@ -66,32 +73,56 @@ export const GridExpressionInput = React.memo(
6673

6774
const onKeyDown = React.useCallback(
6875
(e: React.KeyboardEvent) => {
69-
if (e.key !== 'Enter') {
70-
return
71-
}
72-
if (isValidGridDimensionKeyword(printValue)) {
73-
return onUpdateNumberOrKeyword(cssKeyword(printValue))
74-
}
76+
switch (e.key) {
77+
case 'Enter':
78+
if (isValidGridDimensionKeyword(printValue)) {
79+
return onUpdateNumberOrKeyword(cssKeyword(printValue))
80+
}
7581

76-
const defaultUnit = isGridCSSNumber(value) ? value.value.unit : 'px'
77-
const maybeNumber = parseCSSNumber(printValue, 'AnyValid', defaultUnit)
78-
if (isRight(maybeNumber)) {
79-
return onUpdateNumberOrKeyword(maybeNumber.value)
80-
}
82+
const defaultUnit = isGridCSSNumber(value) ? value.value.unit : 'px'
83+
const maybeNumber = parseCSSNumber(printValue, 'AnyValid', defaultUnit)
84+
if (isRight(maybeNumber)) {
85+
return onUpdateNumberOrKeyword(maybeNumber.value)
86+
}
8187

82-
const maybeMinmax = parseGridCSSMinmaxOrRepeat(printValue)
83-
if (maybeMinmax != null) {
84-
return onUpdateDimension({
85-
...maybeMinmax,
86-
lineName: value.lineName,
87-
} as GridDimension)
88-
}
88+
const maybeMinmax = parseGridCSSMinmaxOrRepeat(printValue)
89+
if (maybeMinmax != null) {
90+
return onUpdateDimension({
91+
...maybeMinmax,
92+
lineName: value.lineName,
93+
} as GridDimension)
94+
}
8995

90-
if (printValue === '') {
91-
return onUpdateNumberOrKeyword(cssKeyword('auto'))
92-
}
96+
if (printValue === '') {
97+
return onUpdateNumberOrKeyword(cssKeyword('auto'))
98+
}
9399

94-
setPrintValue(stringifyGridDimension(value))
100+
setPrintValue(stringifyGridDimension(value))
101+
break
102+
case 'ArrowUp':
103+
case 'ArrowDown':
104+
e.preventDefault()
105+
const gridNumberValueOptic: Optic<GridDimension, CSSNumber> = fromTypeGuard(
106+
isGridCSSNumber,
107+
).compose(fromField('value'))
108+
const valueUnitOptic: Optic<GridDimension, 'fr'> = gridNumberValueOptic
109+
.compose(fromField('unit'))
110+
.compose(notNull())
111+
.compose(fromTypeGuard(isFR))
112+
const gridNumberNumberOptic: Optic<GridDimension, number> =
113+
gridNumberValueOptic.compose(fromField('value'))
114+
if (exists(valueUnitOptic, value)) {
115+
function updateFractional(fractionalValue: number): number {
116+
return (
117+
fractionalValue +
118+
(e.key === 'ArrowUp' ? ArrowKeyFractionalIncrement : -ArrowKeyFractionalIncrement)
119+
)
120+
}
121+
const updatedDimension = modify(gridNumberNumberOptic, updateFractional, value)
122+
onUpdateDimension(updatedDimension)
123+
}
124+
break
125+
}
95126
},
96127
[printValue, onUpdateNumberOrKeyword, onUpdateDimension, value],
97128
)

0 commit comments

Comments
 (0)