diff --git a/apps/designer/app/canvas/features/wrapper-component/selected-instance-connector.ts b/apps/designer/app/canvas/features/wrapper-component/selected-instance-connector.ts index 828778a248..1fb729c043 100644 --- a/apps/designer/app/canvas/features/wrapper-component/selected-instance-connector.ts +++ b/apps/designer/app/canvas/features/wrapper-component/selected-instance-connector.ts @@ -1,6 +1,6 @@ import { useCallback, useEffect } from "react"; -import type { Instance } from "@webstudio-is/react-sdk"; -import { useUserProps } from "@webstudio-is/react-sdk"; +import type { Instance, InstanceProps } from "@webstudio-is/react-sdk"; +import { getBrowserStyle } from "@webstudio-is/react-sdk"; import { publish, subscribeAll } from "~/shared/pubsub"; import { useScrollState } from "~/shared/dom-hooks"; @@ -13,11 +13,12 @@ const publishSelectedRect = (element: HTMLElement) => { export const SelectedInstanceConnector = ({ instanceElementRef, + instance, instanceProps, }: { instanceElementRef: { current: undefined | HTMLElement }; instance: Instance; - instanceProps: ReturnType; + instanceProps: undefined | InstanceProps; }) => { useEffect(() => { const element = instanceElementRef.current; @@ -67,6 +68,18 @@ export const SelectedInstanceConnector = ({ }); } + // trigger style recomputing every time instance styles are changed + publish({ + type: "selectInstance", + payload: { + id: instance.id, + component: instance.component, + cssRules: instance.cssRules, + browserStyle: getBrowserStyle(element), + props: instanceProps, + }, + }); + return () => { resizeObserver.disconnect(); mutationObserver.disconnect(); @@ -74,7 +87,7 @@ export const SelectedInstanceConnector = ({ }; // instance props may change dom element - }, [instanceElementRef, instanceProps]); + }, [instanceElementRef, instance, instanceProps]); const onScrollEnd = useCallback(() => { const element = instanceElementRef.current; diff --git a/apps/designer/app/canvas/features/wrapper-component/wrapper-component.tsx b/apps/designer/app/canvas/features/wrapper-component/wrapper-component.tsx index 2e545f8615..3091259b69 100644 --- a/apps/designer/app/canvas/features/wrapper-component/wrapper-component.tsx +++ b/apps/designer/app/canvas/features/wrapper-component/wrapper-component.tsx @@ -1,14 +1,15 @@ -import type { MouseEvent, FormEvent } from "react"; +import { type MouseEvent, type FormEvent, useMemo } from "react"; import { useRef } from "react"; import { Suspense, lazy, useCallback } from "react"; import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext"; import { - useUserProps, - renderWrapperComponentChildren, - getComponent, type Instance, type OnChangeChildren, + type UserProp, + renderWrapperComponentChildren, + getComponent, idAttribute, + useAllUserProps, } from "@webstudio-is/react-sdk"; import { useTextEditingInstanceId } from "~/shared/nano-states"; import { @@ -42,6 +43,8 @@ const ContentEditable = ({ return ; }; +type UserProps = Record; + type WrapperComponentDevProps = { instance: Instance; children: Array; @@ -60,6 +63,21 @@ export const WrapperComponentDev = ({ const [selectedInstance] = useSelectedInstance(); const [, setSelectedElement] = useSelectedElement(); + const [allUserProps] = useAllUserProps(); + const instanceProps = allUserProps[instance.id]; + const userProps = useMemo(() => { + const result: UserProps = {}; + if (instanceProps === undefined) { + return result; + } + for (const item of instanceProps.props) { + if (item.type !== "asset") { + result[item.prop] = item.value; + } + } + return result; + }, [instanceProps]); + const instanceElementRef = useRef(); const refCallback = useCallback( @@ -73,7 +91,6 @@ export const WrapperComponentDev = ({ [setSelectedElement] ); - const userProps = useUserProps(instance.id); const readonlyProps = instance.component === "Input" ? { readOnly: true } : undefined; @@ -108,7 +125,7 @@ export const WrapperComponentDev = ({ )} {/* Component includes many types and it's hard to provide right ref type with useRef */} diff --git a/apps/designer/app/canvas/shared/instance.ts b/apps/designer/app/canvas/shared/instance.ts index f5e124714e..0331a795fc 100644 --- a/apps/designer/app/canvas/shared/instance.ts +++ b/apps/designer/app/canvas/shared/instance.ts @@ -1,12 +1,10 @@ -import { useCallback, useEffect, useReducer, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { type Instance, type UserProp, type Tree, getComponentMeta, allUserPropsContainer, - getBrowserStyle, - useAllUserProps, } from "@webstudio-is/react-sdk"; import { useSubscribe } from "~/shared/pubsub"; @@ -17,11 +15,7 @@ import { type SelectedInstanceData, } from "@webstudio-is/project"; import store from "immerhin"; -import { - useSelectedInstance, - useSelectedElement, - useHoveredInstance, -} from "./nano-states"; +import { useSelectedInstance, useHoveredInstance } from "./nano-states"; import { rootInstanceContainer, useBreakpoints, @@ -189,37 +183,16 @@ export const useDeleteInstance = () => { export const usePublishSelectedInstanceData = () => { const [instance] = useSelectedInstance(); - const [selectedElement] = useSelectedElement(); - const [allUserProps] = useAllUserProps(); - - // trigger style recomputing every time - // new updates for this node are sent from designer - const [styleKey, recomputeStyles] = useReducer((d) => d + 1, 0); - useSubscribe("updateStyle", ({ id }) => { - if (id === instance?.id) { - recomputeStyles(); - } - }); useEffect(() => { // Unselects the instance by `undefined` - let payload: undefined | SelectedInstanceData; - if (instance !== undefined) { - const props = allUserProps[instance.id]; - const browserStyle = getBrowserStyle(selectedElement); - payload = { - id: instance.id, - component: instance.component, - cssRules: instance.cssRules, - browserStyle, - props, - }; + if (instance === undefined) { + publish({ + type: "selectInstance", + payload: undefined, + }); } - publish({ - type: "selectInstance", - payload, - }); - }, [instance, allUserProps, selectedElement, styleKey]); + }, [instance]); }; export const usePublishHoveredInstanceData = () => {