diff --git a/apps/builder/app/builder/features/style-panel/sections/grid-child/grid-child.tsx b/apps/builder/app/builder/features/style-panel/sections/grid-child/grid-child.tsx index a68eb59bfc..47ba3e8f51 100644 --- a/apps/builder/app/builder/features/style-panel/sections/grid-child/grid-child.tsx +++ b/apps/builder/app/builder/features/style-panel/sections/grid-child/grid-child.tsx @@ -13,6 +13,7 @@ import { } from "@webstudio-is/design-system"; import type { CssProperty, StyleValue } from "@webstudio-is/css-engine"; import { toValue } from "@webstudio-is/css-engine"; +import { parseGridAreas, type AreaInfo } from "@webstudio-is/css-data"; import { StyleSection } from "../../shared/style-section"; import { PropertyLabel } from "../../property-label"; import { ToggleGroupTooltip } from "../../controls/toggle-group/toggle-group-control"; @@ -30,8 +31,8 @@ import { deleteProperty, resetEphemeralStyles, } from "../../shared/use-style-data"; -import { parseGridAreas } from "@webstudio-is/css-data"; import { getGridDimensions } from "../layout/shared/grid-areas"; +import { GridAreaPicker } from "../layout/shared/grid-area-picker"; import { GridPositionInputs, type GridPosition, @@ -41,6 +42,7 @@ import { AlignSelfControl, JustifySelfControl } from "../shared/align-self"; import { OrderControl } from "../shared/order"; import { useStore } from "@nanostores/react"; import { $selectedInstancePath, selectInstance } from "~/shared/awareness"; +import { $isStylePanelGridVisible } from "~/builder/shared/nano-states"; import { ExternalLinkIcon } from "@webstudio-is/icons"; export const properties = [ @@ -112,6 +114,19 @@ const derivePositionMode = ( return "auto"; }; +/** + * Shows grid guides on the canvas while this component is mounted. + */ +const GridChildGuides = () => { + useEffect(() => { + $isStylePanelGridVisible.set(true); + return () => { + $isStylePanelGridVisible.set(false); + }; + }, []); + return null; +}; + export const Section = () => { const [columnStart, columnEnd, rowStart, rowEnd] = useComputedStyles([ "grid-column-start", @@ -221,6 +236,7 @@ export const Section = () => { ) } > + { batch.publish({ isEphemeral: true }); }; + const handlePickerChange = (area: AreaInfo) => { + const newPosition: GridPosition = { + columnStart: area.columnStart, + columnEnd: area.columnEnd, + rowStart: area.rowStart, + rowEnd: area.rowEnd, + }; + localValue.set(newPosition); + handleChange(newPosition); + localValue.save(); + resetEphemeralStyles(); + }; + return ( - -
- { - localValue.save(); - resetEphemeralStyles(); + + +
+ { + localValue.save(); + resetEphemeralStyles(); + }} + gridColumns={gridColumns} + gridRows={gridRows} + /> + + - + ); }; diff --git a/apps/builder/app/builder/features/style-panel/sections/layout/layout.tsx b/apps/builder/app/builder/features/style-panel/sections/layout/layout.tsx index edfcfdd696..0f26d00e0d 100644 --- a/apps/builder/app/builder/features/style-panel/sections/layout/layout.tsx +++ b/apps/builder/app/builder/features/style-panel/sections/layout/layout.tsx @@ -61,7 +61,7 @@ import { FlexAlignment } from "./shared/flex-alignment"; import { GridGenerator } from "./shared/grid-generator"; import { GridSettings } from "./shared/grid-settings"; import { GridAlignment } from "./shared/grid-alignment"; -import { $openGridEditorPanel } from "~/builder/shared/nano-states"; +import { $isStylePanelGridVisible } from "~/builder/shared/nano-states"; import { humanizeString } from "~/shared/string-utils"; import { DEFAULT_GRID_TRACK_COUNT, DEFAULT_GRID_GAP } from "./shared/constants"; @@ -573,21 +573,27 @@ const applyDefaultGridStyles = (columnsValue: string, rowsValue: string) => { }; const LayoutSectionGrid = () => { - const openPanel = useStore($openGridEditorPanel); + const [openPanel, setOpenPanel] = useState({ + generator: false, + settings: false, + }); + + useEffect(() => { + $isStylePanelGridVisible.set(true); + return () => { + $isStylePanelGridVisible.set(false); + }; + }, []); return ( - $openGridEditorPanel.set({ ...openPanel, generator: open }) - } + onOpenChange={(open) => setOpenPanel({ ...openPanel, generator: open })} /> - $openGridEditorPanel.set({ ...openPanel, settings: open }) - } + onOpenChange={(open) => setOpenPanel({ ...openPanel, settings: open })} /> { const instances = useStore($instances); const scale = useStore($scale); const clampingRect = useStore($clampingRect); - const openGridEditorPanel = useStore($openGridEditorPanel); + const isStylePanelGridVisible = useStore($isStylePanelGridVisible); if (!canvasToolsVisible) { return; @@ -86,9 +86,7 @@ export const CanvasTools = () => { <> {isPreviewMode === false && ( <> - {(openGridEditorPanel.generator || openGridEditorPanel.settings) && ( - - )} + {isStylePanelGridVisible && } diff --git a/apps/builder/app/builder/shared/nano-states.ts b/apps/builder/app/builder/shared/nano-states.ts index f59312ae81..ea7395e788 100644 --- a/apps/builder/app/builder/shared/nano-states.ts +++ b/apps/builder/app/builder/shared/nano-states.ts @@ -168,12 +168,6 @@ export type GridEditingArea = { export const $gridEditingArea = atom(undefined); -// Which grid editor panels are open. -// Used to conditionally show grid guides on the canvas. -export const $openGridEditorPanel = atom<{ - generator: boolean; - settings: boolean; -}>({ - generator: false, - settings: false, -}); +// Whether a grid-related section is visible in the style panel. +// Grid guides are shown on the canvas when true. +export const $isStylePanelGridVisible = atom(false);