Skip to content

Commit

Permalink
refactor: hyphenate space and position sections
Browse files Browse the repository at this point in the history
Slightly refactored both space and position sections. Moved property
maps from scrub and keyboard to dedicated sections.

Also fixed keyboard highlighting in space and inset controls.
  • Loading branch information
TrySound committed Mar 9, 2025
1 parent 3c8ac56 commit 65a2015
Show file tree
Hide file tree
Showing 12 changed files with 232 additions and 178 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import { Grid, theme } from "@webstudio-is/design-system";
import { useRef, useState } from "react";
import { movementMapInset, useKeyboardNavigation } from "../shared/keyboard";
import { Grid, theme } from "@webstudio-is/design-system";
import type { CssProperty, StyleValue } from "@webstudio-is/css-engine";
import { useKeyboardNavigation } from "../shared/keyboard";
import { createBatchUpdate, deleteProperty } from "../../shared/use-style-data";
import { getInsetModifiersGroup, useScrub } from "../shared/scrub";
import { useScrub } from "../shared/scrub";
import { ValueText } from "../shared/value-text";
import type { StyleValue } from "@webstudio-is/css-engine";
import { InputPopover } from "../shared/input-popover";
import { InsetLayout, type InsetProperty } from "./inset-layout";
import { InsetTooltip } from "./inset-tooltip";
import { useComputedStyleDecl, useComputedStyles } from "../../shared/model";
import { useModifierKeys, type Modifiers } from "../../shared/modifier-keys";
import { InputPopover } from "../shared/input-popover";
import { InsetLayout, type InsetProperty } from "./inset-layout";
import { getInsetModifiersGroup, InsetTooltip } from "./inset-tooltip";

const movementMapInset = {
top: ["bottom", "right", "bottom", "left"],
right: ["top", "left", "bottom", "left"],
bottom: ["top", "right", "top", "left"],
left: ["top", "right", "bottom", "right"],
} as const;

const Cell = ({
scrubStatus,
Expand All @@ -23,7 +30,7 @@ const Cell = ({
onPopoverClose: () => void;
scrubStatus: ReturnType<typeof useScrub>;
property: InsetProperty;
getActiveProperties: (modifiers?: Modifiers) => readonly InsetProperty[];
getActiveProperties: (modifiers?: Modifiers) => CssProperty[];
onHover: (target: HoverTarget | undefined) => void;
}) => {
const styleDecl = useComputedStyleDecl(property);
Expand Down Expand Up @@ -93,7 +100,7 @@ export const InsetControl = () => {

const [openProperty, setOpenProperty] = useState<InsetProperty>();
const [activePopoverProperties, setActivePopoverProperties] = useState<
undefined | readonly InsetProperty[]
undefined | CssProperty[]
>();
const modifiers = useModifierKeys();
const handleOpenProperty = (property: undefined | InsetProperty) => {
Expand All @@ -111,11 +118,14 @@ export const InsetControl = () => {
});

// by deafult highlight hovered or scrubbed properties
// if keyboard navigation is active, highlight its active property
// if popover is open, highlight its property and hovered properties
const activeProperties = [
...(activePopoverProperties ?? scrubStatus.properties),
];
// if keyboard navigation is active, highlight its active property
if (keyboardNavigation.isActive) {
activeProperties.push(keyboardNavigation.activeProperty);
}
const getActiveProperties = (modifiers?: Modifiers) => {
return modifiers && openProperty
? getInsetModifiersGroup(openProperty, modifiers)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Grid, Box, theme, styled } from "@webstudio-is/design-system";
import type { MouseEvent } from "react";
import { Grid, Box, theme, styled } from "@webstudio-is/design-system";
import type { CssProperty } from "@webstudio-is/css-engine";
import type { Modifiers } from "../../shared/modifier-keys";

const RECT_HEIGHT = 6;
Expand Down Expand Up @@ -42,7 +43,7 @@ type InsetLayoutProps = {
onHover: (
args: { element: HTMLElement; property: InsetProperty } | undefined
) => void;
getActiveProperties: (modifiers?: Modifiers) => readonly InsetProperty[];
getActiveProperties: (modifiers?: Modifiers) => CssProperty[];
};
/**
* Grid schema for graphical layout
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
import { useState, type ReactElement } from "react";
import { Tooltip } from "@webstudio-is/design-system";
import type { CssProperty } from "@webstudio-is/css-engine";
import { useModifierKeys } from "../../shared/modifier-keys";
import { getInsetModifiersGroup } from "../shared/scrub";
import { createBatchUpdate } from "../../shared/use-style-data";
import type { InsetProperty } from "./inset-layout";
import { PropertyInfo } from "../../property-label";
import { useComputedStyles } from "../../shared/model";

const opposingInsetGroups = [
["top", "bottom"],
["left", "right"],
] satisfies CssProperty[][];

const circleInsetGroups = [
["top", "right", "bottom", "left"],
] satisfies CssProperty[][];

export const getInsetModifiersGroup = (
property: CssProperty,
modifiers: { shiftKey: boolean; altKey: boolean }
) => {
let groups: CssProperty[][] = [];

if (modifiers.shiftKey) {
groups = circleInsetGroups;
} else if (modifiers.altKey) {
groups = opposingInsetGroups;
}

return groups.find((group) => group.includes(property)) ?? [property];
};

const sides = {
top: "top",
right: "left",
Expand All @@ -15,7 +39,7 @@ const sides = {
} as const;

const propertyContents: {
properties: InsetProperty[];
properties: CssProperty[];
label: string;
description: string;
}[] = [
Expand All @@ -41,9 +65,9 @@ const propertyContents: {
},
];

const isSameUnorderedArrays = (
arrA: readonly string[],
arrB: readonly string[]
const isSameUnorderedArrays = <Item,>(
arrA: readonly Item[],
arrB: readonly Item[]
) => {
if (arrA.length !== arrB.length) {
return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { toValue, type StyleProperty } from "@webstudio-is/css-engine";
import { toValue, type CssProperty } from "@webstudio-is/css-engine";
import { Grid, theme } from "@webstudio-is/design-system";
import { propertyDescriptions } from "@webstudio-is/css-data";
import { StyleSection } from "../../shared/style-section";
Expand All @@ -13,12 +13,12 @@ import { InsetControl } from "./inset-control";

export const properties = [
"position",
"zIndex",
"z-index",
"top",
"right",
"bottom",
"left",
] satisfies Array<StyleProperty>;
] satisfies CssProperty[];

export const Section = () => {
const position = useComputedStyleDecl("position");
Expand Down Expand Up @@ -56,9 +56,9 @@ export const Section = () => {
<PropertyLabel
label="Z Index"
description={propertyDescriptions.zIndex}
properties={["zIndex"]}
properties={["z-index"]}
/>
<TextControl property="zIndex" />
<TextControl property="z-index" />
</>
)}
</Grid>
Expand All @@ -69,9 +69,9 @@ export const Section = () => {
<PropertyLabel
label="Z Index"
description={propertyDescriptions.zIndex}
properties={["zIndex"]}
properties={["z-index"]}
/>
<TextControl property="zIndex" />
<TextControl property="z-index" />
</Grid>
</Grid>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
Flex,
theme,
} from "@webstudio-is/design-system";
import type { StyleProperty, StyleValue } from "@webstudio-is/css-engine";
import type { CssProperty, StyleValue } from "@webstudio-is/css-engine";
import { propertyDescriptions } from "@webstudio-is/css-data";
import {
CssValueInput,
Expand All @@ -34,8 +34,8 @@ const Input = ({
onClosePopover,
}: {
styleSource: StyleValueSourceColor;
property: StyleProperty;
getActiveProperties: (modifiers?: Modifiers) => readonly StyleProperty[];
property: CssProperty;
getActiveProperties: (modifiers?: Modifiers) => CssProperty[];
value: StyleValue;
onClosePopover: () => void;
}) => {
Expand Down Expand Up @@ -147,8 +147,8 @@ export const InputPopover = ({
onClose,
}: {
styleSource: StyleValueSourceColor;
property: StyleProperty;
getActiveProperties: (modifiers?: Modifiers) => readonly StyleProperty[];
property: CssProperty;
getActiveProperties: (modifiers?: Modifiers) => CssProperty[];
value: StyleValue;
isOpen: boolean;
onClose: () => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,6 @@ const movementKeys = [
"ArrowLeft",
] as const;

export const movementMapSpace = {
marginTop: ["marginBottom", "marginRight", "paddingTop", "marginLeft"],
marginRight: ["marginTop", "marginLeft", "marginBottom", "paddingRight"],
marginBottom: ["paddingBottom", "marginRight", "marginTop", "marginLeft"],
marginLeft: ["marginTop", "paddingLeft", "marginBottom", "marginRight"],
paddingTop: ["marginTop", "paddingRight", "paddingBottom", "paddingLeft"],
paddingRight: ["paddingTop", "marginRight", "paddingBottom", "paddingBottom"],
paddingBottom: ["paddingTop", "paddingRight", "marginBottom", "paddingLeft"],
paddingLeft: ["paddingTop", "paddingTop", "paddingBottom", "marginLeft"],
} as const;

export const movementMapInset = {
top: ["bottom", "right", "bottom", "left"],
right: ["top", "left", "bottom", "left"],
bottom: ["top", "right", "top", "left"],
left: ["top", "right", "bottom", "right"],
} as const;

/**
* useFocusWithin does't work with popovers, implement it using debounce
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import { useState, useEffect, useRef } from "react";
import type {
StyleProperty,
CssProperty,
StyleValue,
UnitValue,
} from "@webstudio-is/css-engine";
import { toValue } from "@webstudio-is/css-engine";
import { numericScrubControl } from "@webstudio-is/design-system";
import { useState, useEffect, useRef } from "react";
import { camelCaseProperty, isValidDeclaration } from "@webstudio-is/css-data";
import { useModifierKeys } from "../../shared/modifier-keys";
import type { StyleUpdateOptions } from "../../shared/use-style-data";
import type { SpaceStyleProperty } from "../space/types";
import { isValidDeclaration } from "@webstudio-is/css-data";
import { parseIntermediateOrInvalidValue } from "../../shared/css-value-input/parse-intermediate-or-invalid-value";
import { toValue } from "@webstudio-is/css-engine";
import type { CssValueInputValue } from "../../shared/css-value-input/css-value-input";
import type { InsetProperty } from "../position/inset-layout";

type ScrubStatus<P extends string> = {
isActive: boolean;
Expand All @@ -34,7 +32,7 @@ type HoverTarget<P> = {
element: HTMLElement | SVGElement;
};

export const useScrub = <P extends StyleProperty>(props: {
export const useScrub = <P extends CssProperty>(props: {
value?: StyleValue;
target: HoverTarget<P> | undefined;
getModifiersGroup: (
Expand Down Expand Up @@ -87,7 +85,7 @@ export const useScrub = <P extends StyleProperty>(props: {
} as const;

if (isValidDeclaration(property, toValue(value)) === false) {
value = parseIntermediateOrInvalidValue(property, {
value = parseIntermediateOrInvalidValue(camelCaseProperty(property), {
type: "intermediate",
value: `${value.value}`,
unit: value.unit,
Expand Down Expand Up @@ -154,52 +152,3 @@ export const useScrub = <P extends StyleProperty>(props: {
values,
};
};

const opposingSpaceGroups = [
["paddingTop", "paddingBottom"],
["paddingRight", "paddingLeft"],
["marginTop", "marginBottom"],
["marginRight", "marginLeft"],
] as const;

const circleSpaceGroups = [
["paddingTop", "paddingRight", "paddingBottom", "paddingLeft"],
["marginTop", "marginRight", "marginBottom", "marginLeft"],
] as const;

export const getSpaceModifiersGroup = (
property: SpaceStyleProperty,
modifiers: { shiftKey: boolean; altKey: boolean }
) => {
let groups: ReadonlyArray<ReadonlyArray<SpaceStyleProperty>> = [];

if (modifiers.shiftKey) {
groups = circleSpaceGroups;
} else if (modifiers.altKey) {
groups = opposingSpaceGroups;
}

return groups.find((group) => group.includes(property)) ?? [property];
};

const opposingInsetGroups = [
["top", "bottom"],
["left", "right"],
] as const;

const circleInsetGroups = [["top", "right", "bottom", "left"]] as const;

export const getInsetModifiersGroup = (
property: InsetProperty,
modifiers: { shiftKey: boolean; altKey: boolean }
) => {
let groups: ReadonlyArray<ReadonlyArray<InsetProperty>> = [];

if (modifiers.shiftKey) {
groups = circleInsetGroups;
} else if (modifiers.altKey) {
groups = opposingInsetGroups;
}

return groups.find((group) => group.includes(property)) ?? [property];
};
Loading

0 comments on commit 65a2015

Please sign in to comment.