Skip to content

Commit

Permalink
experimental: parse perspective-origin property value as tuples for x…
Browse files Browse the repository at this point in the history
… and y values (#3947)

## Description

This PR allows to parse the `perspective-origin` property value as
`tuple`. And added test cases for different possible values.

## Steps for reproduction

- Allows to parse `perspective-origin` values as tuples.

## Code Review

- [ ] hi @TrySound , I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [x] made a self-review
- [x] added inline comments where things may be not obvious (the "why",
not "what")

## 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
JayaKrishnaNamburu authored Aug 16, 2024
1 parent 152405b commit d8edefa
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { describe, test, expect } from "@jest/globals";
import {
extractRotatePropertiesFromTransform,
extractSkewPropertiesFromTransform,
extractTransformOriginValues,
extractTransformOrPerspectiveOriginValues,
} from "./transform-extractors";
import { parseCssValue } from "@webstudio-is/css-data";
import type { TupleValue } from "@webstudio-is/css-engine";
Expand Down Expand Up @@ -108,10 +108,10 @@ describe("extractSkewPropertiesFromTransform", () => {
});
});

describe("extractTransformOriginValues", () => {
describe("extractTransformOrPerspectiveOriginValues", () => {
test("parses transform-origin and returns the individual properties from the value", () => {
expect(
extractTransformOriginValues(
extractTransformOrPerspectiveOriginValues(
parseCssValue("transformOrigin", "center") as TupleValue
)
).toEqual({
Expand All @@ -121,7 +121,7 @@ describe("extractTransformOriginValues", () => {
});

expect(
extractTransformOriginValues(
extractTransformOrPerspectiveOriginValues(
parseCssValue("transformOrigin", "top") as TupleValue
)
).toEqual({
Expand All @@ -131,7 +131,7 @@ describe("extractTransformOriginValues", () => {
});

expect(
extractTransformOriginValues(
extractTransformOrPerspectiveOriginValues(
parseCssValue("transformOrigin", "right") as TupleValue
)
).toEqual({
Expand All @@ -141,7 +141,7 @@ describe("extractTransformOriginValues", () => {
});

expect(
extractTransformOriginValues(
extractTransformOrPerspectiveOriginValues(
parseCssValue("transformOrigin", "45px") as TupleValue
)
).toEqual({
Expand All @@ -151,7 +151,7 @@ describe("extractTransformOriginValues", () => {
});

expect(
extractTransformOriginValues(
extractTransformOrPerspectiveOriginValues(
parseCssValue("transformOrigin", "20px 40px") as TupleValue
)
).toEqual({
Expand All @@ -161,7 +161,7 @@ describe("extractTransformOriginValues", () => {
});

expect(
extractTransformOriginValues(
extractTransformOrPerspectiveOriginValues(
parseCssValue("transformOrigin", "10px 20px 30px") as TupleValue
)
).toEqual({
Expand All @@ -171,7 +171,7 @@ describe("extractTransformOriginValues", () => {
});

expect(
extractTransformOriginValues(
extractTransformOrPerspectiveOriginValues(
parseCssValue("transformOrigin", "left top 30px") as TupleValue
)
).toEqual({
Expand All @@ -181,7 +181,7 @@ describe("extractTransformOriginValues", () => {
});

expect(
extractTransformOriginValues(
extractTransformOrPerspectiveOriginValues(
parseCssValue("transformOrigin", "bottom right 60px") as TupleValue
)
).toEqual({
Expand All @@ -191,7 +191,7 @@ describe("extractTransformOriginValues", () => {
});

expect(
extractTransformOriginValues(
extractTransformOrPerspectiveOriginValues(
parseCssValue("transformOrigin", "left 50% 60px") as TupleValue
)
).toEqual({
Expand All @@ -201,7 +201,7 @@ describe("extractTransformOriginValues", () => {
});

expect(
extractTransformOriginValues(
extractTransformOrPerspectiveOriginValues(
parseCssValue("transformOrigin", "50% bottom 60px") as TupleValue
)
).toEqual({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ const isValidTransformOriginValue = (
return value.type === "unit" || value.type === "keyword";
};

export const extractTransformOriginValues = (
// https://developer.mozilla.org/en-US/docs/Web/CSS/perspective-origin#syntax
// https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin#syntax
// Both transform and perspective origin shares the same syntax for their values.
// The only difference is `transform-origin` can have a 3rd value for z-axis.
export const extractTransformOrPerspectiveOriginValues = (
value: TupleValue
): {
x: KeywordValue | UnitValue;
Expand All @@ -71,7 +75,6 @@ export const extractTransformOriginValues = (
let z: UnitValue | undefined;

// https://www.w3.org/TR/css-transforms-1/#transform-origin-property
// https://github.com/mdn/content/issues/35411
// If only one value is specified, the second value is assumed to be center.
if (value.value.length === 1 && value.value[0].type === "unit") {
x = value.value[0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
import { PropertyName } from "../../shared/property-name";
import { styleConfigByName } from "../../shared/configs";
import { useMemo } from "react";
import { extractTransformOriginValues } from "./transform-extractors";
import { extractTransformOrPerspectiveOriginValues } from "./transform-extractors";
import { CssValueInputContainer } from "../../shared/css-value-input";
import type { StyleUpdateOptions } from "../../shared/use-style-data";

Expand Down Expand Up @@ -62,7 +62,7 @@ export const TransformOrigin = (props: SectionProps) => {
return;
}

return extractTransformOriginValues(value);
return extractTransformOrPerspectiveOriginValues(value);
}, [value]);

const xInfo = useMemo(() => calculateBackgroundPosition(origin?.x), [origin]);
Expand Down
41 changes: 41 additions & 0 deletions packages/css-data/src/parse-css-value.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -957,3 +957,44 @@ test("parse transform-origin", () => {
value: "top left right",
});
});

test("parse perspective-origin", () => {
expect(parseCssValue("perspectiveOrigin", "center")).toEqual({
type: "tuple",
value: [{ type: "keyword", value: "center" }],
});

expect(parseCssValue("perspectiveOrigin", "bottom right")).toEqual({
type: "tuple",
value: [
{ type: "keyword", value: "bottom" },
{ type: "keyword", value: "right" },
],
});

expect(parseCssValue("perspectiveOrigin", "bottom 55%")).toEqual({
type: "invalid",
value: "bottom 55%",
});

expect(parseCssValue("perspectiveOrigin", "75% bottom")).toEqual({
type: "tuple",
value: [
{ type: "unit", value: 75, unit: "%" },
{ type: "keyword", value: "bottom" },
],
});

expect(parseCssValue("perspectiveOrigin", "-175%")).toEqual({
type: "tuple",
value: [{ type: "unit", value: -175, unit: "%" }],
});

expect(parseCssValue("perspectiveOrigin", "50% 50%")).toEqual({
type: "tuple",
value: [
{ type: "unit", value: 50, unit: "%" },
{ type: "unit", value: 50, unit: "%" },
],
});
});
1 change: 1 addition & 0 deletions packages/css-data/src/parse-css-value.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ const tupleProps = new Set<StyleProperty>([
"filter",
"backdropFilter",
"transformOrigin",
"perspectiveOrigin",
]);

const availableUnits = new Set<string>(Object.values(units).flat());
Expand Down

0 comments on commit d8edefa

Please sign in to comment.