Skip to content

Commit 73dd80a

Browse files
authored
refactor: control floating panel open state (#4331)
Slightly change floating panel "open" state to make it controlled from outside. This is important with form validations.
1 parent 7c23583 commit 73dd80a

File tree

3 files changed

+16
-23
lines changed

3 files changed

+16
-23
lines changed

apps/builder/app/builder/features/style-panel/controls/font-family/font-family-control.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ export const FontFamilyControl = () => {
6868
suffix={
6969
<FloatingPanel
7070
title="Fonts"
71-
onOpenChange={setIsFontMangerOpen}
71+
isOpen={isFontManagerOpen}
72+
onIsOpenChange={setIsFontMangerOpen}
7273
content={
7374
<FontsManager
7475
value={value.type === "fontFamily" ? value : undefined}

apps/builder/app/builder/features/style-panel/sections/backgrounds/background-content.stories.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useRef } from "react";
1+
import { useRef, useState } from "react";
22
import { getStyleDeclKey, type StyleDecl } from "@webstudio-is/sdk";
33
import {
44
FloatingPanel,
@@ -35,14 +35,16 @@ $selectedInstanceSelector.set(["box"]);
3535

3636
export const BackgroundContentStory = () => {
3737
const elementRef = useRef<HTMLDivElement>(null);
38+
const [isOpen, setIsOpen] = useState(true);
3839

3940
return (
4041
<>
4142
<div ref={elementRef} style={{ marginLeft: "400px" }}></div>
4243

4344
<FloatingPanelProvider container={elementRef}>
4445
<FloatingPanel
45-
open={true}
46+
isOpen={isOpen}
47+
onIsOpenChange={setIsOpen}
4648
title="Background"
4749
content={<BackgroundContent index={0} />}
4850
>

apps/builder/app/builder/shared/floating-panel.tsx

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -74,24 +74,13 @@ export const FloatingPanelProvider = ({
7474
</FloatingPanelContext.Provider>
7575
);
7676

77-
const useLogic = (open?: boolean, onOpenChange?: (isOpen: boolean) => void) => {
78-
const { container: containerRef } = useContext(FloatingPanelContext);
79-
const [isOpen, setIsOpen] = useState(Boolean(open));
80-
const [triggerRef, sideOffset] = useSideOffset({ isOpen, containerRef });
81-
const handleOpenChange = (open: boolean) => {
82-
setIsOpen(open);
83-
onOpenChange?.(open);
84-
};
85-
return { isOpen, handleOpenChange, triggerRef, sideOffset };
86-
};
87-
8877
// @todo add support for positioning next to the left panel
8978
type FloatingPanelProps = {
9079
title: string;
9180
content: JSX.Element;
9281
children: JSX.Element;
93-
open?: boolean;
94-
onOpenChange?: (isOpen: boolean) => void;
82+
isOpen?: boolean;
83+
onIsOpenChange?: (isOpen: boolean) => void;
9584
// collisionPadding is the distance in pixels from the boundary edges where collision detection should occur.
9685
collisionPadding?:
9786
| number
@@ -107,18 +96,19 @@ export const FloatingPanel = ({
10796
title,
10897
content,
10998
children,
110-
open,
99+
isOpen: externalIsOpen,
111100
align,
112-
onOpenChange,
101+
onIsOpenChange: setExternalIsOpen,
113102
collisionPadding,
114103
}: FloatingPanelProps) => {
115-
const { isOpen, handleOpenChange, triggerRef, sideOffset } = useLogic(
116-
open,
117-
onOpenChange
118-
);
104+
const [internalIsOpen, setInternalIsOpen] = useState(false);
105+
const isOpen = externalIsOpen ?? internalIsOpen;
106+
const setIsOpen = setExternalIsOpen ?? setInternalIsOpen;
107+
const { container: containerRef } = useContext(FloatingPanelContext);
108+
const [triggerRef, sideOffset] = useSideOffset({ isOpen, containerRef });
119109

120110
return (
121-
<FloatingPanelPopover open={isOpen} onOpenChange={handleOpenChange} modal>
111+
<FloatingPanelPopover open={isOpen} onOpenChange={setIsOpen} modal>
122112
<FloatingPanelPopoverTrigger asChild ref={triggerRef}>
123113
{children}
124114
</FloatingPanelPopoverTrigger>

0 commit comments

Comments
 (0)