From 83e2c01dc564ad8d30cc1282ca0171e56ebd58ed Mon Sep 17 00:00:00 2001 From: Ivan Starkov Date: Tue, 28 Mar 2023 15:29:08 +0400 Subject: [PATCH] Border style (#1307) ## Description ref #1169 BorderStyle now is toggle group image ## Steps for reproduction Open borders, set ## Code Review - [ ] hi @kof, 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) - [ ] updated [test cases](https://github.com/webstudio-is/webstudio-builder/blob/main/apps/builder/docs/test-cases.md) document - [ ] added tests - [ ] if any new env variables are added, added them to `.env.example` and the `builder/env-check.js` if mandatory --- .../sections/borders/border-style.tsx | 105 +++++++++++++++--- .../sections/borders/borders.stories.tsx | 1 - .../style-panel/sections/borders/borders.tsx | 14 +-- .../style-panel/shared/property-name.tsx | 2 +- packages/icons/icons/dash-border.svg | 3 + packages/icons/icons/dashed-border.svg | 5 + packages/icons/icons/dotted-border.svg | 6 + packages/icons/icons/small-x.svg | 3 + .../icons/src/__generated__/dash-border.tsx | 15 +++ .../icons/src/__generated__/dashed-border.tsx | 15 +++ .../icons/src/__generated__/dotted-border.tsx | 15 +++ packages/icons/src/__generated__/index.ts | 4 + packages/icons/src/__generated__/small-x.tsx | 15 +++ 13 files changed, 179 insertions(+), 24 deletions(-) create mode 100644 packages/icons/icons/dash-border.svg create mode 100644 packages/icons/icons/dashed-border.svg create mode 100644 packages/icons/icons/dotted-border.svg create mode 100644 packages/icons/icons/small-x.svg create mode 100644 packages/icons/src/__generated__/dash-border.tsx create mode 100644 packages/icons/src/__generated__/dashed-border.tsx create mode 100644 packages/icons/src/__generated__/dotted-border.tsx create mode 100644 packages/icons/src/__generated__/small-x.tsx diff --git a/apps/builder/app/builder/features/style-panel/sections/borders/border-style.tsx b/apps/builder/app/builder/features/style-panel/sections/borders/border-style.tsx index b647b0a525..699080d3a5 100644 --- a/apps/builder/app/builder/features/style-panel/sections/borders/border-style.tsx +++ b/apps/builder/app/builder/features/style-panel/sections/borders/border-style.tsx @@ -1,13 +1,36 @@ import type { StyleProperty } from "@webstudio-is/css-data"; +import { toValue } from "@webstudio-is/css-engine"; +import { + Grid, + theme, + ToggleGroup, + ToggleGroupItem, + Tooltip, +} from "@webstudio-is/design-system"; +import { + DashBorderIcon, + DashedBorderIcon, + DottedBorderIcon, + SmallXIcon, +} from "@webstudio-is/icons"; +import { toPascalCase } from "../../shared/keyword-utils"; +import { PropertyName } from "../../shared/property-name"; import type { RenderCategoryProps } from "../../style-sections"; -import { BorderProperty } from "./border-property"; +import { deleteAllProperties, setAllProperties } from "./border-utils"; -const borderPropertyOptions = { - borderTopStyle: {}, - borderRightStyle: {}, - borderLeftStyle: {}, - borderBottomStyle: {}, -} as const satisfies Partial<{ [property in StyleProperty]: unknown }>; +const borderStyleProperties = [ + "borderTopStyle", + "borderRightStyle", + "borderLeftStyle", + "borderBottomStyle", +] as const satisfies readonly StyleProperty[]; + +const borderStyleValues = [ + { value: "none", Icon: SmallXIcon }, + { value: "solid", Icon: DashBorderIcon }, + { value: "dashed", Icon: DashedBorderIcon }, + { value: "dotted", Icon: DottedBorderIcon }, +] as const; export const BorderStyle = ( props: Pick< @@ -15,14 +38,66 @@ export const BorderStyle = ( "currentStyle" | "setProperty" | "deleteProperty" | "createBatchUpdate" > ) => { + /** + * We do not use shorthand properties such as borderWidth or borderRadius in our code. + * However, in the UI, we can display a single field, and in that case, we can use any property + * from the shorthand property set and pass it instead. + **/ + const firstPropertyName = borderStyleProperties[0]; + + const deleteBorderProperties = deleteAllProperties( + borderStyleProperties, + props.createBatchUpdate + ); + + const setBorderProperties = setAllProperties( + borderStyleProperties, + props.createBatchUpdate + )(firstPropertyName); + + const firstPropertyValue = toValue( + props.currentStyle[firstPropertyName]?.value ?? { + type: "keyword", + value: "none", + } + ); + return ( - + + deleteBorderProperties(firstPropertyName)} + /> + + { + setBorderProperties({ + type: "keyword", + value, + }); + }} + > + {borderStyleValues.map(({ value, Icon }) => ( + + + + + + ))} + + ); }; diff --git a/apps/builder/app/builder/features/style-panel/sections/borders/borders.stories.tsx b/apps/builder/app/builder/features/style-panel/sections/borders/borders.stories.tsx index 7bf9b10c33..9064991066 100644 --- a/apps/builder/app/builder/features/style-panel/sections/borders/borders.stories.tsx +++ b/apps/builder/app/builder/features/style-panel/sections/borders/borders.stories.tsx @@ -20,7 +20,6 @@ const styleInfoInitial: StyleInfo = { const Panel = styled("div", { width: theme.spacing[30], boxSizing: "border-box", - padding: theme.spacing[9], }); export const Borders = () => { diff --git a/apps/builder/app/builder/features/style-panel/sections/borders/borders.tsx b/apps/builder/app/builder/features/style-panel/sections/borders/borders.tsx index 3f5c579fc0..1a2ccc8528 100644 --- a/apps/builder/app/builder/features/style-panel/sections/borders/borders.tsx +++ b/apps/builder/app/builder/features/style-panel/sections/borders/borders.tsx @@ -42,6 +42,13 @@ export const BordersSection = (props: RenderCategoryProps) => { return ( + + { - - ; }; diff --git a/packages/icons/icons/dash-border.svg b/packages/icons/icons/dash-border.svg new file mode 100644 index 0000000000..3800a43236 --- /dev/null +++ b/packages/icons/icons/dash-border.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/icons/icons/dashed-border.svg b/packages/icons/icons/dashed-border.svg new file mode 100644 index 0000000000..b8713a3b1e --- /dev/null +++ b/packages/icons/icons/dashed-border.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/icons/icons/dotted-border.svg b/packages/icons/icons/dotted-border.svg new file mode 100644 index 0000000000..b72136a3c8 --- /dev/null +++ b/packages/icons/icons/dotted-border.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/icons/icons/small-x.svg b/packages/icons/icons/small-x.svg new file mode 100644 index 0000000000..83438b01cc --- /dev/null +++ b/packages/icons/icons/small-x.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/icons/src/__generated__/dash-border.tsx b/packages/icons/src/__generated__/dash-border.tsx new file mode 100644 index 0000000000..290295d1ab --- /dev/null +++ b/packages/icons/src/__generated__/dash-border.tsx @@ -0,0 +1,15 @@ +// Generated from icons/dash-border.svg + +import { forwardRef } from "react"; +import type { IconProps } from "../types"; + +// prettier-ignore +export const DashBorderIcon = forwardRef( + ({ color = "currentColor", size = 16, ...props }, forwardedRef) => { + return ( + + ); + } +); + +DashBorderIcon.displayName = "DashBorderIcon"; diff --git a/packages/icons/src/__generated__/dashed-border.tsx b/packages/icons/src/__generated__/dashed-border.tsx new file mode 100644 index 0000000000..bf1cf29f99 --- /dev/null +++ b/packages/icons/src/__generated__/dashed-border.tsx @@ -0,0 +1,15 @@ +// Generated from icons/dashed-border.svg + +import { forwardRef } from "react"; +import type { IconProps } from "../types"; + +// prettier-ignore +export const DashedBorderIcon = forwardRef( + ({ color = "currentColor", size = 16, ...props }, forwardedRef) => { + return ( + + ); + } +); + +DashedBorderIcon.displayName = "DashedBorderIcon"; diff --git a/packages/icons/src/__generated__/dotted-border.tsx b/packages/icons/src/__generated__/dotted-border.tsx new file mode 100644 index 0000000000..06dfe81616 --- /dev/null +++ b/packages/icons/src/__generated__/dotted-border.tsx @@ -0,0 +1,15 @@ +// Generated from icons/dotted-border.svg + +import { forwardRef } from "react"; +import type { IconProps } from "../types"; + +// prettier-ignore +export const DottedBorderIcon = forwardRef( + ({ color = "currentColor", size = 16, ...props }, forwardedRef) => { + return ( + + ); + } +); + +DottedBorderIcon.displayName = "DottedBorderIcon"; diff --git a/packages/icons/src/__generated__/index.ts b/packages/icons/src/__generated__/index.ts index 328975102a..621859fd7b 100644 --- a/packages/icons/src/__generated__/index.ts +++ b/packages/icons/src/__generated__/index.ts @@ -27,9 +27,12 @@ export * from "./chevron-filled-right"; export * from "./chevron-filled-up"; export * from "./code"; export * from "./commit"; +export * from "./dash-border"; export * from "./dash"; +export * from "./dashed-border"; export * from "./div"; export * from "./dot"; +export * from "./dotted-border"; export * from "./drag-handle"; export * from "./eyecon-closed"; export * from "./eyecon-open"; @@ -51,6 +54,7 @@ export * from "./repeat-grid"; export * from "./repeat-row"; export * from "./scroll"; export * from "./slot-component"; +export * from "./small-x"; export * from "./subscript"; export * from "./subtract"; export * from "./superscript"; diff --git a/packages/icons/src/__generated__/small-x.tsx b/packages/icons/src/__generated__/small-x.tsx new file mode 100644 index 0000000000..47e07dcac3 --- /dev/null +++ b/packages/icons/src/__generated__/small-x.tsx @@ -0,0 +1,15 @@ +// Generated from icons/small-x.svg + +import { forwardRef } from "react"; +import type { IconProps } from "../types"; + +// prettier-ignore +export const SmallXIcon = forwardRef( + ({ color = "currentColor", size = 16, ...props }, forwardedRef) => { + return ( + + ); + } +); + +SmallXIcon.displayName = "SmallXIcon";