Skip to content

Commit

Permalink
experimental: improve repeated styles with css variables (#4275)
Browse files Browse the repository at this point in the history
Ref #3399

Here added a few improvements to repeated style to handle variables
properly. For now all changes affects only backgrounds section.

- single layer can use css variable with multiple gradients
- with multiple layers each can have css variable with single gradient
- when single variable inside multiple layers has multiple gradients all
thumbnails become transparent, it should be and indicator of invalid
gradients
- fixed toggling hidden considering variables
- fixed deleting layers considering variables
- now when single layer has variable with multiple gradients only first
gradient can be deleted or toggled
  • Loading branch information
TrySound authored Oct 13, 2024
1 parent 4b9f2c3 commit af931ac
Show file tree
Hide file tree
Showing 5 changed files with 424 additions and 411 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ import {
RepeatRowIcon,
CrossSmallIcon,
} from "@webstudio-is/icons";
import { type StyleValue, toValue } from "@webstudio-is/css-engine";
import {
LayersValue,
type StyleProperty,
type StyleValue,
toValue,
UnparsedValue,
} from "@webstudio-is/css-engine";
import {
theme,
Flex,
Expand All @@ -35,7 +41,11 @@ import {
setRepeatedStyleItem,
} from "../../shared/repeated-style";
import { CssValueInputContainer } from "../../shared/css-value-input";
import { setProperty } from "../../shared/use-style-data";
import {
setProperty,
type StyleUpdateOptions,
} from "../../shared/use-style-data";
import type { ComputedStyleDecl } from "~/shared/style-object-model";

const detectImageOrGradientToggle = (styleValue?: StyleValue) => {
if (styleValue?.type === "image") {
Expand Down Expand Up @@ -63,6 +73,30 @@ const Spacer = styled("div", {
height: theme.spacing[5],
});

const setGradientProperty = (
styleDecl: ComputedStyleDecl,
index: number,
newItem: StyleValue,
options?: StyleUpdateOptions
) => {
const property = styleDecl.property as StyleProperty;
let items: StyleValue[] = [];
if (styleDecl.cascadedValue.type === "var") {
items = [styleDecl.cascadedValue];
}
if (styleDecl.cascadedValue.type === "layers") {
items = styleDecl.cascadedValue.value;
}
const unpackedItem = newItem.type === "layers" ? newItem.value[0] : newItem;
if (items.length === 1 && unpackedItem.type === "var") {
setProperty(property)(unpackedItem, options);
} else {
const newValue = { type: "layers", value: items } as LayersValue;
newValue.value[index] = newItem as UnparsedValue;
setProperty(property)(newValue, options);
}
};

const GradientControl = ({ index }: { index: number }) => {
const styleDecl = useComputedStyleDecl("backgroundImage");
const value =
Expand All @@ -76,17 +110,11 @@ const GradientControl = ({ index }: { index: number }) => {
getOptions={() => $availableVariables.get()}
value={value}
setValue={(newValue, options) => {
if (newValue.type === "var") {
setProperty("backgroundImage")(newValue, options);
} else {
setRepeatedStyleItem(styleDecl, index, newValue, options);
}
setGradientProperty(styleDecl, index, newValue, options);
}}
deleteProperty={() => {
if (styleDecl.cascadedValue.type === "var") {
setProperty("backgroundImage")(styleDecl.cascadedValue);
} else if (value) {
setRepeatedStyleItem(styleDecl, index, value);
if (value) {
setGradientProperty(styleDecl, index, value);
}
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { $assets, $imageLoader } from "~/shared/nano-states";
import brokenImage from "~/shared/images/broken-image-placeholder.svg";
import { toPascalCase } from "../../shared/keyword-utils";
import { useComputedStyles } from "../../shared/model";
import { getRepeatedStyleItem } from "../../shared/repeated-style";
import { getComputedRepeatedItem } from "../../shared/repeated-style";

export const repeatedProperties = [
"backgroundImage",
Expand Down Expand Up @@ -75,9 +75,12 @@ const gradientNames = [
];

export const getBackgroundLabel = (
backgroundImageStyle: StyleValue,
backgroundImageStyle: undefined | StyleValue,
assets: Assets
) => {
if (backgroundImageStyle?.type === "var") {
return `--${backgroundImageStyle.value}`;
}
if (
backgroundImageStyle?.type === "image" &&
backgroundImageStyle.value.type === "asset"
Expand Down Expand Up @@ -113,7 +116,7 @@ export const BackgroundThumbnail = ({ index }: { index: number }) => {
const imageLoader = useStore($imageLoader);
const styles = useComputedStyles(repeatedProperties);
const [backgroundImage] = styles;
const backgroundImageValue = getRepeatedStyleItem(backgroundImage, index);
const backgroundImageValue = getComputedRepeatedItem(backgroundImage, index);

if (
backgroundImageValue?.type === "image" &&
Expand Down Expand Up @@ -152,7 +155,7 @@ export const BackgroundThumbnail = ({ index }: { index: number }) => {
if (backgroundImageValue?.type === "unparsed") {
const cssStyle: { [property in RepeatedProperty]?: string } = {};
for (const styleDecl of styles) {
const itemValue = getRepeatedStyleItem(styleDecl, index);
const itemValue = getComputedRepeatedItem(styleDecl, index);
cssStyle[styleDecl.property as RepeatedProperty] = toValue(itemValue);
}
return <Thumbnail css={cssStyle} />;
Expand Down
Loading

0 comments on commit af931ac

Please sign in to comment.