-
Notifications
You must be signed in to change notification settings - Fork 708
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
experimental: parse transform css property into tuples (#3704)
## Description Parse `transform` value into tuples. We need to use shorthand transform property for `skew` and `rotate` to support the UX. - **skew** doesn't have individual property yet. So need to use this as backup. - **rotate** doesn support setting individual `x, y, z` properties on the long hand property like in the design. So, we are can use transforms as backup and allow to set individual `rotateX`, `rotateY` and `rotateZ` values. ## Code Review - [ ] hi @TrySound , I need you to do - detailed review (read every line) ## Before requesting a review - [x] made a self-review ## Before merging - [x] tested locally and on preview environment (preview dev login: 5de6) - [x] updated [test cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md) document - [x] added tests
- Loading branch information
1 parent
3c32053
commit 6abceec
Showing
5 changed files
with
185 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import * as csstree from "css-tree"; | ||
import type { | ||
InvalidValue, | ||
LayersValue, | ||
TupleValue, | ||
TupleValueItem, | ||
Unit, | ||
} from "@webstudio-is/css-engine"; | ||
import { cssTryParseValue } from "../parse-css-value"; | ||
|
||
export const parseTransform = (input: string): TupleValue | InvalidValue => { | ||
let tokenStream = input.trim(); | ||
tokenStream = tokenStream.endsWith(";") | ||
? tokenStream.slice(0, -1) | ||
: tokenStream; | ||
|
||
const cleanupKeywords = ["transform:"]; | ||
|
||
for (const cleanupKeyword of cleanupKeywords) { | ||
tokenStream = tokenStream.startsWith(cleanupKeyword) | ||
? tokenStream.slice(cleanupKeyword.length).trim() | ||
: tokenStream; | ||
} | ||
|
||
const cssAst = cssTryParseValue(tokenStream); | ||
if (cssAst === undefined) { | ||
return { | ||
type: "invalid", | ||
value: input, | ||
}; | ||
} | ||
|
||
const parsed = csstree.lexer.matchProperty("transform", cssAst); | ||
if (parsed.error) { | ||
return { | ||
type: "invalid", | ||
value: input, | ||
}; | ||
} | ||
|
||
const transformValue: TupleValueItem[] = []; | ||
|
||
csstree.walk(cssAst, (node) => { | ||
if (node.type === "Value") { | ||
for (const child of node.children) { | ||
if (child.type === "Function") { | ||
const isCommaSeparatedArgs = child.children.some( | ||
(arg) => arg.type === "Operator" && arg.value === "," | ||
); | ||
|
||
const args: TupleValue | LayersValue = isCommaSeparatedArgs | ||
? { type: "layers", value: [] } | ||
: { type: "tuple", value: [] }; | ||
|
||
for (const arg of child.children) { | ||
if (arg.type === "Number") { | ||
args.value.push({ | ||
type: "unit", | ||
value: Number(arg.value), | ||
unit: "number", | ||
}); | ||
} | ||
|
||
if (arg.type === "Dimension") { | ||
args.value.push({ | ||
type: "unit", | ||
value: Number(arg.value), | ||
unit: arg.unit as Unit, | ||
}); | ||
} | ||
|
||
if (arg.type === "Percentage") { | ||
args.value.push({ | ||
type: "unit", | ||
value: Number(arg.value), | ||
unit: "%", | ||
}); | ||
} | ||
} | ||
|
||
transformValue.push({ | ||
type: "function", | ||
name: child.name, | ||
args, | ||
}); | ||
} | ||
} | ||
} | ||
}); | ||
|
||
return { | ||
type: "tuple", | ||
value: transformValue, | ||
}; | ||
}; |