Skip to content

Commit e9a0980

Browse files
update stories to display the result
1 parent 12d8002 commit e9a0980

File tree

3 files changed

+67
-58
lines changed

3 files changed

+67
-58
lines changed
Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,65 @@
11
import {
22
parseLinearGradient,
3+
reconstructLinearGradient,
34
type ParsedGradient,
45
} from "@webstudio-is/css-data";
56
import { GradientControl } from "./gradient-control";
6-
import { toValue } from "@webstudio-is/css-engine";
7+
import { Flex, Text } from "@webstudio-is/design-system";
8+
import { useState } from "react";
79

810
export default {
911
title: "Library/GradientControl",
1012
};
1113

1214
export const GradientWithoutAngle = () => {
15+
const gradientString = "linear-gradient(#e66465 0%, #9198e5 100%)";
16+
const [gradient, setGradient] = useState<string>(gradientString);
17+
1318
return (
14-
<GradientControl
15-
gradient={
16-
parseLinearGradient(
17-
"linear-gradient(#e66465 0%, #9198e5 100%)"
18-
) as ParsedGradient
19-
}
20-
onChange={() => {}}
21-
/>
19+
<Flex direction="column" gap="4">
20+
<GradientControl
21+
gradient={parseLinearGradient(gradientString) as ParsedGradient}
22+
onChange={(value) => {
23+
setGradient(reconstructLinearGradient(value));
24+
}}
25+
/>
26+
<Text>{gradient}</Text>
27+
</Flex>
2228
);
2329
};
2430

25-
// The GradientControl is to just modify the stop values or add new ones.
26-
// It always shows the angle as 90deg, unless the stops can't be showin in a rectangle.
27-
// So, the gradient shouldn't modify even if the stop values are changed at the end,
28-
export const GradientWithAngle = () => {
31+
export const GradientWithAngleAndHints = () => {
32+
const gradientString =
33+
"linear-gradient(145deg, #ff00fa 0%, #00f497 34% 34%, #ffa800 56% 56%, #00eaff 100%)";
34+
const [gradient, setGradient] = useState<string>(gradientString);
35+
2936
return (
30-
<GradientControl
31-
gradient={
32-
parseLinearGradient(
33-
"linear-gradient(145deg, #ff00fa 0%, #00f497 34% 34%, #ffa800 56% 56%, #00eaff 100%)"
34-
) as ParsedGradient
35-
}
36-
onChange={(value) => {
37-
if (toValue(value.angle) !== "145deg") {
38-
throw new Error(
39-
`Gradient control modified the angle that is passed. \nReceived ${JSON.stringify(value.angle, null, 2)}`
40-
);
41-
}
42-
}}
43-
/>
37+
<Flex direction="column" gap="4">
38+
<GradientControl
39+
gradient={parseLinearGradient(gradientString) as ParsedGradient}
40+
onChange={(value) => {
41+
setGradient(reconstructLinearGradient(value));
42+
}}
43+
/>
44+
<Text>{gradient}</Text>
45+
</Flex>
4446
);
4547
};
4648

4749
export const GradientWithSideOrCorner = () => {
50+
const gradientString = "linear-gradient(to left top, blue 0%, red 100%)";
51+
52+
const [gradient, setGradient] = useState<string>(gradientString);
53+
4854
return (
49-
<GradientControl
50-
gradient={
51-
parseLinearGradient(
52-
"linear-gradient(to left top, blue 0%, red 100%)"
53-
) as ParsedGradient
54-
}
55-
onChange={(value) => {
56-
if (toValue(value.sideOrCorner) !== "to left top") {
57-
throw new Error(
58-
`Gradient control modified the side-or-corner value that is passed. \nReceived ${JSON.stringify(value.sideOrCorner, null, 2)}`
59-
);
60-
}
61-
}}
62-
/>
55+
<Flex direction="column" gap="4">
56+
<GradientControl
57+
gradient={parseLinearGradient(gradientString) as ParsedGradient}
58+
onChange={(value) => {
59+
setGradient(reconstructLinearGradient(value));
60+
}}
61+
/>
62+
<Text>{gradient}</Text>
63+
</Flex>
6364
);
6465
};

apps/builder/app/builder/features/style-panel/sections/backgrounds/gradient-control.tsx

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { toValue, UnitValue } from "@webstudio-is/css-engine";
22
import { Root, Range, Thumb, Track } from "@radix-ui/react-slider";
3-
import { useEffect, useState, useCallback } from "react";
3+
import { useState, useCallback } from "react";
44
import {
55
reconstructLinearGradient,
66
type GradientStop,
77
type ParsedGradient,
88
} from "@webstudio-is/css-data";
99
import { styled, theme, Flex } from "@webstudio-is/design-system";
10+
import { ChevronBigUpIcon } from "@webstudio-is/icons";
1011

1112
type GradientControlProps = {
1213
gradient: ParsedGradient;
@@ -22,26 +23,16 @@ const defaultAngle: UnitValue = {
2223
export const GradientControl = (props: GradientControlProps) => {
2324
const [stops, setStops] = useState<Array<GradientStop>>(props.gradient.stops);
2425
const [selectedStop, setSelectedStop] = useState<number | undefined>();
25-
const positions = stops.map((stop) => stop.position?.value) as number[];
26+
const positions = stops.map((stop) => stop.position?.value);
27+
const hints = props.gradient.stops
28+
.map((stop) => stop.hint?.value)
29+
.filter(Boolean);
2630
const background = reconstructLinearGradient({
2731
stops,
2832
sideOrCorner: props.gradient.sideOrCorner,
2933
angle: defaultAngle,
3034
});
3135

32-
useEffect(() => {
33-
const newStops: Array<GradientStop> = [];
34-
for (const stop of props.gradient.stops || []) {
35-
if (stop.color !== undefined && stop.position?.value !== undefined) {
36-
newStops.push({
37-
color: stop.color,
38-
position: stop.position,
39-
});
40-
}
41-
}
42-
setStops(newStops);
43-
}, [props.gradient]);
44-
4536
const handleValueChange = useCallback(
4637
(newPositions: number[]) => {
4738
const newStops: GradientStop[] = stops.map((stop, index) => ({
@@ -52,7 +43,7 @@ export const GradientControl = (props: GradientControlProps) => {
5243
setStops(newStops);
5344
props.onChange({
5445
angle: props.gradient.angle,
55-
stops,
46+
stops: newStops,
5647
sideOrCorner: props.gradient.sideOrCorner,
5748
});
5849
},
@@ -101,6 +92,23 @@ export const GradientControl = (props: GradientControlProps) => {
10192
}}
10293
/>
10394
))}
95+
96+
{hints.map((hint) => {
97+
return (
98+
<Flex
99+
key={hint}
100+
align="center"
101+
justify="center"
102+
css={{
103+
position: "absolute",
104+
left: `${hint}%`,
105+
top: theme.spacing[9],
106+
}}
107+
>
108+
<ChevronBigUpIcon color={theme.colors.borderMain} />
109+
</Flex>
110+
);
111+
})}
104112
</SliderRoot>
105113
</Flex>
106114
);

packages/css-data/src/property-parsers/linear-gradient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ const getColor = (
182182
};
183183

184184
export const reconstructLinearGradient = (parsed: ParsedGradient): string => {
185-
const direction = parsed.angle || parsed.sideOrCorner;
185+
const direction = parsed?.angle || parsed?.sideOrCorner;
186186
const stops = parsed.stops
187187
.map((stop: GradientStop) => {
188188
let result = toValue(stop.color);

0 commit comments

Comments
 (0)