diff --git a/apps/designer/app/designer/features/style-panel/controls/toggle/toggle-control.tsx b/apps/designer/app/designer/features/style-panel/controls/toggle/toggle-control.tsx index f49a3f0626..23d1555cb9 100644 --- a/apps/designer/app/designer/features/style-panel/controls/toggle/toggle-control.tsx +++ b/apps/designer/app/designer/features/style-panel/controls/toggle/toggle-control.tsx @@ -1,24 +1,30 @@ -import { ToggleGroup } from "@webstudio-is/design-system"; -import { - TextAlignLeftIcon, - TextAlignCenterIcon, - TextAlignRightIcon, -} from "@webstudio-is/icons"; +import { ToggleGroup, Tooltip } from "@webstudio-is/design-system"; -export const ToggleGroupControl = () => ( +export type ToggleGroupControlProps = { + value: string; + items: { child: JSX.Element; label: string; value: string }[]; + onValueChange?: (value: string) => void; +}; + +export const ToggleGroupControl = ({ + value = "", + items = [], + onValueChange, +}: ToggleGroupControlProps) => ( - - - - - - - - - + {items.map(({ child, label, value }, index) => { + return ( + + + {child} + + + ); + })} ); diff --git a/apps/designer/app/designer/features/style-panel/sections/flex-child/flex-child.tsx b/apps/designer/app/designer/features/style-panel/sections/flex-child/flex-child.tsx new file mode 100644 index 0000000000..3c29a8a0c1 --- /dev/null +++ b/apps/designer/app/designer/features/style-panel/sections/flex-child/flex-child.tsx @@ -0,0 +1,193 @@ +import { Flex, Grid } from "@webstudio-is/design-system"; +import type { RenderCategoryProps } from "../../style-sections"; +import { ToggleGroupControl } from "../../controls"; +import { PropertyName } from "../../shared/property-name"; +import { + CrossSmallIcon, + AlignSelfStartIcon, + AlignSelfEndIcon, + AlignSelfCenterIcon, + AlignSelfBaselineIcon, + AlignSelfStretchIcon, + FlexSizingShrinkIcon, + FlexSizingGrowIcon, + OrderFirstIcon, + OrderLastIcon, + EllipsesIcon, +} from "@webstudio-is/icons"; + +export const FlexChildSection = ({ + setProperty, + createBatchUpdate, + currentStyle, + sectionStyle, +}: RenderCategoryProps) => { + const setAlignSelf = setProperty("alignSelf"); + const setOrder = setProperty("order"); + const setSizing = createBatchUpdate(); + + return ( + + + + setAlignSelf(value)} + value={String(currentStyle.alignSelf?.value)} + items={[ + { + child: , + label: "Do not align items", + value: "auto", + }, + { + child: , + label: "align-items: flex-start", + value: "start", + }, + { + child: , + label: "align-items: flex-end", + value: "end", + }, + { + child: , + label: "align-items: center", + value: "center", + }, + { + child: , + label: "align-items: stretch", + value: "stretch", + }, + { + child: , + label: "align-items: baseline", + value: "baseline", + }, + ]} + /> + + + + { + switch (value) { + case "none": { + setSizing.setProperty("flexGrow")("0"); + setSizing.setProperty("flexShrink")("0"); + setSizing.publish(); + break; + } + case "grow": { + setSizing.setProperty("flexGrow")("1"); + setSizing.setProperty("flexShrink")("0"); + setSizing.publish(); + break; + } + case "shrink": { + setSizing.setProperty("flexGrow")("0"); + setSizing.setProperty("flexShrink")("1"); + setSizing.publish(); + break; + } + default: { + alert("@todo render sizing popup"); + } + } + }} + value={(() => { + switch ( + String(currentStyle.flexGrow?.value) + + String(currentStyle.flexShrink?.value) + ) { + case "00": { + return "none"; + } + case "10": { + return "grow"; + } + case "01": { + return "shrink"; + } + default: { + return ""; + } + } + })()} + items={[ + { + child: , + label: "Don't grow or shrink", + value: "none", + }, + { + child: , + label: "Grow if possible", + value: "grow", + }, + { + child: , + label: "Shrink if needed", + value: "shrink", + }, + { + child: , + label: "More sizing options", + value: "", + }, + ]} + /> + + + + { + switch (value) { + case "0": + case "1": + case "-1": { + setOrder(value); + break; + } + default: { + alert("@todo render order popup"); + } + } + }} + value={String(currentStyle.order?.value)} + items={[ + { + child: , + label: "Dont't change", + value: "0", + }, + { + child: , + label: "Make first", + value: "1", + }, + { + child: , + label: "Make last", + value: "-1", + }, + { + child: , + label: "Customize order", + value: "", + }, + ]} + /> + + + ); +}; diff --git a/apps/designer/app/designer/features/style-panel/sections/flexChild/flexChild.tsx b/apps/designer/app/designer/features/style-panel/sections/flexChild/flexChild.tsx deleted file mode 100644 index f09d23207f..0000000000 --- a/apps/designer/app/designer/features/style-panel/sections/flexChild/flexChild.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import type { RenderCategoryProps } from "../../style-sections"; -import { ShowMore } from "../../shared/show-more"; -import { renderProperty } from "../../style-sections"; -import { ToggleGroupControl } from "../../controls"; - -export const FlexChildSection = ({ - styleConfigsByCategory, - moreStyleConfigsByCategory, -}: RenderCategoryProps) => { - return ( - <> - - {styleConfigsByCategory.map((entry) => renderProperty(entry))} - - renderProperty(entry) - )} - /> - - ); -}; diff --git a/apps/designer/app/designer/features/style-panel/sections/gridChild/gridChild.tsx b/apps/designer/app/designer/features/style-panel/sections/grid-child/grid-child.tsx similarity index 100% rename from apps/designer/app/designer/features/style-panel/sections/gridChild/gridChild.tsx rename to apps/designer/app/designer/features/style-panel/sections/grid-child/grid-child.tsx diff --git a/apps/designer/app/designer/features/style-panel/sections/index.ts b/apps/designer/app/designer/features/style-panel/sections/index.ts index 4a750c30bc..6e82bdbb6e 100644 --- a/apps/designer/app/designer/features/style-panel/sections/index.ts +++ b/apps/designer/app/designer/features/style-panel/sections/index.ts @@ -1,6 +1,6 @@ export * from "./layout/layout"; -export * from "./flexChild/flexChild"; -export * from "./gridChild/gridChild"; +export * from "./flex-child/flex-child"; +export * from "./grid-child/grid-child"; export * from "./spacing/spacing"; export * from "./size/size"; export * from "./position/position"; diff --git a/apps/designer/app/designer/features/style-panel/sections/layout/layout.tsx b/apps/designer/app/designer/features/style-panel/sections/layout/layout.tsx index d36cb8ace5..b8f2b22988 100644 --- a/apps/designer/app/designer/features/style-panel/sections/layout/layout.tsx +++ b/apps/designer/app/designer/features/style-panel/sections/layout/layout.tsx @@ -2,12 +2,7 @@ import { Box, Flex, Grid } from "@webstudio-is/design-system"; import type { RenderCategoryProps } from "../../style-sections"; import { FlexGrid } from "./shared/flex-grid"; import { Lock } from "./shared/lock"; -import { - MenuControl, - SelectControl, - TextControl, - ToggleGroupControl, -} from "../../controls"; +import { MenuControl, SelectControl, TextControl } from "../../controls"; import { PropertyName } from "../../shared/property-name"; const LayoutSectionFlex = ({ diff --git a/apps/designer/app/designer/features/style-panel/style-sections.tsx b/apps/designer/app/designer/features/style-panel/style-sections.tsx index 755c9b8db9..71f24fe578 100644 --- a/apps/designer/app/designer/features/style-panel/style-sections.tsx +++ b/apps/designer/app/designer/features/style-panel/style-sections.tsx @@ -15,7 +15,6 @@ import { MenuControl, FontFamilyControl, } from "./controls"; -import { ShowMore } from "./shared/show-more"; import { LayoutSection, FlexChildSection, diff --git a/packages/design-system/src/components/toggle-group.tsx b/packages/design-system/src/components/toggle-group.tsx index d3b86afd09..c16781252c 100644 --- a/packages/design-system/src/components/toggle-group.tsx +++ b/packages/design-system/src/components/toggle-group.tsx @@ -3,38 +3,36 @@ import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"; export const Root = styled(ToggleGroupPrimitive.Root, { display: "inline-flex", - backgroundColor: "$slate5", - borderRadius: 4, - boxShadow: `0 2px 10px $blackA7`, + borderRadius: "$1", + boxShadow: `0 0 0 1px $colors$slate7`, + padding: 2, }); export const Item = styled(ToggleGroupPrimitive.Item, { all: "unset", - backgroundColor: "$panel", + backgroundColor: "$loContrast", color: "$hiContrast", display: "flex", - whiteSpace: "nowrap", - fontSize: 15, - lineHeight: 1, + width: "$5", + height: "$5", + borderRadius: 2, alignItems: "center", justifyContent: "center", - marginLeft: 1, - "&": { - px: "$2", - py: "$1", - }, - "&:first-child": { - marginLeft: 0, - borderTopLeftRadius: 4, - borderBottomLeftRadius: 4, - }, - "&:last-child": { borderTopRightRadius: 4, borderBottomRightRadius: 4 }, - "&:hover": { backgroundColor: "$slateA3" }, - "&[data-state=on]": { - backgroundColor: "$slateA5", - }, - "&:focus": { - position: "relative", - boxShadow: `0 0 0 2px black`, - }, + "&:hover": { backgroundColor: "$slate5" }, + "&:focus": { boxShadow: "0 0 0 2px $colors$blue10", zIndex: 1 }, + "&[data-state=on]": { backgroundColor: "$slate5" }, + // whiteSpace: "nowrap", + // fontSize: 15, + // lineHeight: 1, + // marginLeft: 1, + // "&": { + // px: "$2", + // py: "$1", + // }, + // "&:first-child": { + // marginLeft: 0, + // borderTopLeftRadius: 4, + // borderBottomLeftRadius: 4, + // }, + // "&:last-child": { borderTopRightRadius: 4, borderBottomRightRadius: 4 }, }); diff --git a/packages/icons/src/align-self-baseline.tsx b/packages/icons/src/align-self-baseline.tsx new file mode 100644 index 0000000000..806450615b --- /dev/null +++ b/packages/icons/src/align-self-baseline.tsx @@ -0,0 +1,47 @@ +import * as React from "react"; +import { IconProps } from "./types"; + +export const AlignSelfBaselineIcon = React.forwardRef( + ({ color = "currentColor", ...props }, forwardedRef) => { + return ( + + + + + + + + + ); + } +); +AlignSelfBaselineIcon.displayName = "AlignSelfBaselineIcon"; diff --git a/packages/icons/src/align-self-center.tsx b/packages/icons/src/align-self-center.tsx new file mode 100644 index 0000000000..5b8f8e0a37 --- /dev/null +++ b/packages/icons/src/align-self-center.tsx @@ -0,0 +1,27 @@ +import * as React from "react"; +import { IconProps } from "./types"; + +export const AlignSelfCenterIcon = React.forwardRef( + ({ color = "currentColor", ...props }, forwardedRef) => { + return ( + + + + + ); + } +); +AlignSelfCenterIcon.displayName = "AlignSelfCenterIcon"; diff --git a/packages/icons/src/align-self-end.tsx b/packages/icons/src/align-self-end.tsx new file mode 100644 index 0000000000..0c99ee9245 --- /dev/null +++ b/packages/icons/src/align-self-end.tsx @@ -0,0 +1,35 @@ +import * as React from "react"; +import { IconProps } from "./types"; + +export const AlignSelfEndIcon = React.forwardRef( + ({ color = "currentColor", ...props }, forwardedRef) => { + return ( + + + + + ); + } +); +AlignSelfEndIcon.displayName = "AlignSelfEndIcon"; diff --git a/packages/icons/src/align-self-start.tsx b/packages/icons/src/align-self-start.tsx new file mode 100644 index 0000000000..b705dd7827 --- /dev/null +++ b/packages/icons/src/align-self-start.tsx @@ -0,0 +1,27 @@ +import * as React from "react"; +import { IconProps } from "./types"; + +export const AlignSelfStartIcon = React.forwardRef( + ({ color = "currentColor", ...props }, forwardedRef) => { + return ( + + + + + ); + } +); +AlignSelfStartIcon.displayName = "AlignSelfStartIcon"; diff --git a/packages/icons/src/align-self-stretch.tsx b/packages/icons/src/align-self-stretch.tsx new file mode 100644 index 0000000000..26c738d71c --- /dev/null +++ b/packages/icons/src/align-self-stretch.tsx @@ -0,0 +1,41 @@ +import * as React from "react"; +import { IconProps } from "./types"; + +export const AlignSelfStretchIcon = React.forwardRef( + ({ color = "currentColor", ...props }, forwardedRef) => { + return ( + + + + + + ); + } +); +AlignSelfStretchIcon.displayName = "AlignSelfStretchIcon"; diff --git a/packages/icons/src/cross-large.tsx b/packages/icons/src/cross-large.tsx new file mode 100644 index 0000000000..0b1c591b1c --- /dev/null +++ b/packages/icons/src/cross-large.tsx @@ -0,0 +1,26 @@ +import * as React from "react"; +import { IconProps } from "./types"; + +export const CrossLargeIcon = React.forwardRef( + ({ color = "currentColor", ...props }, forwardedRef) => { + return ( + + + + ); + } +); +CrossLargeIcon.displayName = "CrossLargeIcon"; diff --git a/packages/icons/src/cross-small.tsx b/packages/icons/src/cross-small.tsx new file mode 100644 index 0000000000..f930d59adf --- /dev/null +++ b/packages/icons/src/cross-small.tsx @@ -0,0 +1,26 @@ +import * as React from "react"; +import { IconProps } from "./types"; + +export const CrossSmallIcon = React.forwardRef( + ({ color = "currentColor", ...props }, forwardedRef) => { + return ( + + + + ); + } +); +CrossSmallIcon.displayName = "CrossSmallIcon"; diff --git a/packages/icons/src/ellipses.tsx b/packages/icons/src/ellipses.tsx new file mode 100644 index 0000000000..bcca0255fb --- /dev/null +++ b/packages/icons/src/ellipses.tsx @@ -0,0 +1,23 @@ +import * as React from "react"; +import { IconProps } from "./types"; + +export const EllipsesIcon = React.forwardRef( + ({ color = "currentColor", ...props }, forwardedRef) => { + return ( + + + + + + ); + } +); +EllipsesIcon.displayName = "EllipsesIcon"; diff --git a/packages/icons/src/flex-sizing-grow.tsx b/packages/icons/src/flex-sizing-grow.tsx new file mode 100644 index 0000000000..a91ba276fd --- /dev/null +++ b/packages/icons/src/flex-sizing-grow.tsx @@ -0,0 +1,34 @@ +import * as React from "react"; +import { IconProps } from "./types"; + +export const FlexSizingGrowIcon = React.forwardRef( + ({ color = "currentColor", ...props }, forwardedRef) => { + return ( + + + + + + ); + } +); +FlexSizingGrowIcon.displayName = "FlexSizingGrowIcon"; diff --git a/packages/icons/src/flex-sizing-shrink.tsx b/packages/icons/src/flex-sizing-shrink.tsx new file mode 100644 index 0000000000..db9977fe43 --- /dev/null +++ b/packages/icons/src/flex-sizing-shrink.tsx @@ -0,0 +1,30 @@ +import * as React from "react"; +import { IconProps } from "./types"; + +export const FlexSizingShrinkIcon = React.forwardRef( + ({ color = "currentColor", ...props }, forwardedRef) => { + return ( + + + + + ); + } +); +FlexSizingShrinkIcon.displayName = "FlexSizingGrowIcon"; diff --git a/packages/icons/src/index.ts b/packages/icons/src/index.ts index a15ffb67ce..48a3c9f430 100644 --- a/packages/icons/src/index.ts +++ b/packages/icons/src/index.ts @@ -48,3 +48,15 @@ export { TrashIcon } from "./trash"; export { SizeIcon } from "./size"; export { UploadIcon } from "./upload"; export { GearIcon, gearIconCssVars } from "./gear"; +export * from "./align-self-start"; +export * from "./align-self-end"; +export * from "./align-self-center"; +export * from "./align-self-stretch"; +export * from "./align-self-baseline"; +export * from "./flex-sizing-grow"; +export * from "./flex-sizing-shrink"; +export * from "./order-first"; +export * from "./order-last"; +export * from "./cross-small"; +export * from "./cross-large"; +export * from "./ellipses"; diff --git a/packages/icons/src/order-first.tsx b/packages/icons/src/order-first.tsx new file mode 100644 index 0000000000..d001f8eb38 --- /dev/null +++ b/packages/icons/src/order-first.tsx @@ -0,0 +1,47 @@ +import * as React from "react"; +import { IconProps } from "./types"; + +export const OrderFirstIcon = React.forwardRef( + ({ color = "currentColor", ...props }, forwardedRef) => { + return ( + + + + + + + + + + + + ); + } +); +OrderFirstIcon.displayName = "OrderFirstIcon"; diff --git a/packages/icons/src/order-last.tsx b/packages/icons/src/order-last.tsx new file mode 100644 index 0000000000..2d90e443a3 --- /dev/null +++ b/packages/icons/src/order-last.tsx @@ -0,0 +1,48 @@ +import * as React from "react"; +import { IconProps } from "./types"; + +export const OrderLastIcon = React.forwardRef( + ({ color = "currentColor", ...props }, forwardedRef) => { + return ( + + + + + + + + + + + + ); + } +); +OrderLastIcon.displayName = "OrderFirstIcon";