mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-11-09 05:26:24 +09:00
refactor: migrate outline section to style object model (#4074)
Ref https://github.com/webstudio-is/webstudio/issues/1536 https://github.com/webstudio-is/webstudio/issues/3399 - refactored outline section into single module for simplicity - replaced css value input container with text control - visually aligned color input and length inputs <img width="253" alt="Screenshot 2024-09-05 at 16 44 37" src="https://github.com/user-attachments/assets/888335a7-e562-4dc2-b8cb-9c4f568cb688"> <img width="267" alt="Screenshot 2024-09-05 at 16 44 19" src="https://github.com/user-attachments/assets/fd977d46-3f3f-46a0-a6e7-2ea7cc806b79">
This commit is contained in:
1 parent
61eec6815b
commit
cafba33352
4 files changed
+57
-183
No files matched your search
@@ -1,54 +0,0 @@
|
||||
import { propertyDescriptions } from "@webstudio-is/css-data";
|
||||
import type { StyleProperty, UnitValue } from "@webstudio-is/css-engine";
|
||||
import { Grid, theme } from "@webstudio-is/design-system";
|
||||
import { CssValueInputContainer } from "../../shared/css-value-input";
|
||||
import type { SectionProps } from "../shared/section";
|
||||
import { styleConfigByName } from "../../shared/configs";
|
||||
import { getStyleSource } from "../../shared/style-info";
|
||||
import { PropertyLabel } from "../../property-label";
|
||||
|
||||
const property: StyleProperty = "outlineOffset";
|
||||
const defaultOutlineOffsetValue: UnitValue = {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
};
|
||||
|
||||
export const OutlineOffset = (
|
||||
props: Pick<SectionProps, "currentStyle" | "setProperty" | "deleteProperty">
|
||||
) => {
|
||||
const { deleteProperty, setProperty, currentStyle } = props;
|
||||
const outlineOffsetValue =
|
||||
currentStyle[property]?.value ?? defaultOutlineOffsetValue;
|
||||
const outlineOffsetStyleConfig = styleConfigByName(property);
|
||||
const outlineOffsetWidthKeywords = outlineOffsetStyleConfig.items.map(
|
||||
(item) => ({
|
||||
type: "keyword" as const,
|
||||
value: item.name,
|
||||
})
|
||||
);
|
||||
|
||||
return (
|
||||
<Grid
|
||||
css={{
|
||||
gridTemplateColumns: `1fr ${theme.spacing[20]}`,
|
||||
}}
|
||||
gap={2}
|
||||
>
|
||||
<PropertyLabel
|
||||
label="Offset"
|
||||
description={propertyDescriptions.outlineOffset}
|
||||
properties={["outlineOffset"]}
|
||||
/>
|
||||
|
||||
<CssValueInputContainer
|
||||
property={property}
|
||||
styleSource={getStyleSource(currentStyle[property])}
|
||||
keywords={outlineOffsetWidthKeywords}
|
||||
setValue={setProperty(property)}
|
||||
deleteProperty={deleteProperty}
|
||||
value={outlineOffsetValue}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -1,39 +0,0 @@
|
||||
import { Grid, theme, Box } from "@webstudio-is/design-system";
|
||||
import {
|
||||
DashBorderIcon,
|
||||
DashedBorderIcon,
|
||||
DottedBorderIcon,
|
||||
SmallXIcon,
|
||||
} from "@webstudio-is/icons";
|
||||
import { propertyDescriptions } from "@webstudio-is/css-data";
|
||||
import { PropertyLabel } from "../../property-label";
|
||||
import { ToggleGroupControl } from "../../controls/toggle-group/toggle-group-control";
|
||||
|
||||
export const OutlineStyle = () => {
|
||||
return (
|
||||
<Grid
|
||||
css={{
|
||||
gridTemplateColumns: `1fr ${theme.spacing[20]} ${theme.spacing[12]}`,
|
||||
}}
|
||||
gap={2}
|
||||
>
|
||||
<PropertyLabel
|
||||
label="Style"
|
||||
description={propertyDescriptions.outlineStyle}
|
||||
properties={["outlineStyle"]}
|
||||
/>
|
||||
<Box css={{ gridColumn: `span 2`, justifySelf: "end" }}>
|
||||
<ToggleGroupControl
|
||||
label="Style"
|
||||
properties={["outlineStyle"]}
|
||||
items={[
|
||||
{ child: <SmallXIcon />, value: "none" },
|
||||
{ child: <DashBorderIcon />, value: "solid" },
|
||||
{ child: <DashedBorderIcon />, value: "dashed" },
|
||||
{ child: <DottedBorderIcon />, value: "dotted" },
|
||||
]}
|
||||
/>
|
||||
</Box>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -1,47 +0,0 @@
|
||||
import { propertyDescriptions } from "@webstudio-is/css-data";
|
||||
import type { StyleProperty } from "@webstudio-is/css-engine";
|
||||
import { Grid, theme } from "@webstudio-is/design-system";
|
||||
import type { SectionProps } from "../shared/section";
|
||||
import { CssValueInputContainer } from "../../shared/css-value-input";
|
||||
import { styleConfigByName } from "../../shared/configs";
|
||||
import { getStyleSource } from "../../shared/style-info";
|
||||
import { PropertyLabel } from "../../property-label";
|
||||
|
||||
const property: StyleProperty = "outlineWidth";
|
||||
|
||||
export const OutlineWidth = (
|
||||
props: Pick<SectionProps, "currentStyle" | "setProperty" | "deleteProperty">
|
||||
) => {
|
||||
const { deleteProperty, setProperty, currentStyle } = props;
|
||||
const outlineWidthValue = currentStyle[property]?.value;
|
||||
const outlineStyleConfig = styleConfigByName(property);
|
||||
const outlineStyleWidthKeywords = outlineStyleConfig.items.map((item) => ({
|
||||
type: "keyword" as const,
|
||||
value: item.name,
|
||||
}));
|
||||
|
||||
return (
|
||||
<Grid
|
||||
css={{
|
||||
gridTemplateColumns: `1fr ${theme.spacing[20]}`,
|
||||
}}
|
||||
gap={2}
|
||||
>
|
||||
<PropertyLabel
|
||||
label="Width"
|
||||
description={propertyDescriptions.outlineWidth}
|
||||
properties={["outlineWidth"]}
|
||||
/>
|
||||
|
||||
<CssValueInputContainer
|
||||
key={property}
|
||||
property={property}
|
||||
styleSource={getStyleSource(currentStyle[property])}
|
||||
keywords={outlineStyleWidthKeywords}
|
||||
setValue={setProperty(property)}
|
||||
deleteProperty={deleteProperty}
|
||||
value={outlineWidthValue}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -1,13 +1,17 @@
|
||||
import { Flex, Grid, theme, Box } from "@webstudio-is/design-system";
|
||||
import { theme, Grid, Box } from "@webstudio-is/design-system";
|
||||
import {
|
||||
DashBorderIcon,
|
||||
DashedBorderIcon,
|
||||
DottedBorderIcon,
|
||||
SmallXIcon,
|
||||
} from "@webstudio-is/icons";
|
||||
import { propertyDescriptions } from "@webstudio-is/css-data";
|
||||
import type { StyleProperty } from "@webstudio-is/css-engine";
|
||||
import { ColorControl } from "../../controls";
|
||||
import { toValue, type StyleProperty } from "@webstudio-is/css-engine";
|
||||
import { ColorControl, TextControl } from "../../controls";
|
||||
import { StyleSection } from "../../shared/style-section";
|
||||
import type { SectionProps } from "../shared/section";
|
||||
import { OutlineStyle } from "./outline-style";
|
||||
import { OutlineWidth } from "./outline-width";
|
||||
import { OutlineOffset } from "./outline-offset";
|
||||
import { PropertyLabel } from "../../property-label";
|
||||
import { useComputedStyleDecl } from "../../shared/model";
|
||||
import { ToggleGroupControl } from "../../controls/toggle-group/toggle-group-control";
|
||||
|
||||
export const properties = [
|
||||
"outlineStyle",
|
||||
@@ -16,50 +20,60 @@ export const properties = [
|
||||
"outlineOffset",
|
||||
] satisfies Array<StyleProperty>;
|
||||
|
||||
export const Section = (props: SectionProps) => {
|
||||
const { currentStyle, setProperty, deleteProperty } = props;
|
||||
const { outlineStyle } = currentStyle;
|
||||
|
||||
if (outlineStyle?.value.type !== "keyword") {
|
||||
return;
|
||||
}
|
||||
export const Section = () => {
|
||||
const outlineStyle = useComputedStyleDecl("outlineStyle");
|
||||
const outlineStyleValue = toValue(outlineStyle.cascadedValue);
|
||||
|
||||
return (
|
||||
<StyleSection label="Outline" properties={properties}>
|
||||
<Flex direction="column" gap={2}>
|
||||
<OutlineStyle />
|
||||
{outlineStyle.value.value !== "none" && (
|
||||
<Grid
|
||||
css={{
|
||||
// label gap (input gap expand)
|
||||
gridTemplateColumns: `1fr calc(${theme.spacing[20]} + ${theme.spacing[5]} + ${theme.spacing[12]})`,
|
||||
}}
|
||||
gap={2}
|
||||
>
|
||||
<PropertyLabel
|
||||
label="Style"
|
||||
description={propertyDescriptions.outlineStyle}
|
||||
properties={["outlineStyle"]}
|
||||
/>
|
||||
<Box css={{ justifySelf: "end" }}>
|
||||
<ToggleGroupControl
|
||||
label="Style"
|
||||
properties={["outlineStyle"]}
|
||||
items={[
|
||||
{ child: <SmallXIcon />, value: "none" },
|
||||
{ child: <DashBorderIcon />, value: "solid" },
|
||||
{ child: <DashedBorderIcon />, value: "dashed" },
|
||||
{ child: <DottedBorderIcon />, value: "dotted" },
|
||||
]}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{outlineStyleValue !== "none" && (
|
||||
<>
|
||||
<Grid
|
||||
css={{
|
||||
gridTemplateColumns: `1fr ${theme.spacing[20]} ${theme.spacing[12]}`,
|
||||
}}
|
||||
gapX={2}
|
||||
>
|
||||
<PropertyLabel
|
||||
label="Color"
|
||||
description={propertyDescriptions.outlineColor}
|
||||
properties={["outlineColor"]}
|
||||
/>
|
||||
<Box css={{ gridColumn: `span 2` }}>
|
||||
<ColorControl property="outlineColor" />
|
||||
</Box>
|
||||
</Grid>
|
||||
|
||||
<OutlineWidth
|
||||
currentStyle={currentStyle}
|
||||
setProperty={setProperty}
|
||||
deleteProperty={deleteProperty}
|
||||
<PropertyLabel
|
||||
label="Color"
|
||||
description={propertyDescriptions.outlineColor}
|
||||
properties={["outlineColor"]}
|
||||
/>
|
||||
|
||||
<OutlineOffset
|
||||
currentStyle={currentStyle}
|
||||
setProperty={setProperty}
|
||||
deleteProperty={deleteProperty}
|
||||
<ColorControl property="outlineColor" />
|
||||
<PropertyLabel
|
||||
label="Width"
|
||||
description={propertyDescriptions.outlineWidth}
|
||||
properties={["outlineWidth"]}
|
||||
/>
|
||||
<TextControl property="outlineWidth" />
|
||||
<PropertyLabel
|
||||
label="Offset"
|
||||
description={propertyDescriptions.outlineOffset}
|
||||
properties={["outlineOffset"]}
|
||||
/>
|
||||
<TextControl property="outlineOffset" />
|
||||
</>
|
||||
)}
|
||||
</Flex>
|
||||
</Grid>
|
||||
</StyleSection>
|
||||
);
|
||||
};
|
||||
Reference in new issue
Block a user