mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-11-09 05:26:24 +09:00
Send selected instance data from connector (#637)
Ref https://github.com/webstudio-is/webstudio-designer/issues/628 Same issue as with selected outline. Styles were sent from detached element when tag prop is changed. Moving it to selected instance connector just works because styles already applied when effect is called and it's remounted on every style change.
This commit is contained in:
1 parent
703a9fe215
commit
83060cd94a
3 files changed
+48
-45
No files matched your search
@@ -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<typeof useUserProps>;
|
||||
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;
|
||||
|
||||
@@ -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 <Component ref={ref} {...props} contentEditable={true} />;
|
||||
};
|
||||
|
||||
type UserProps = Record<UserProp["prop"], string | number | boolean>;
|
||||
|
||||
type WrapperComponentDevProps = {
|
||||
instance: Instance;
|
||||
children: Array<JSX.Element | string>;
|
||||
@@ -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<HTMLElement>();
|
||||
|
||||
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 = ({
|
||||
<SelectedInstanceConnector
|
||||
instanceElementRef={instanceElementRef}
|
||||
instance={instance}
|
||||
instanceProps={userProps}
|
||||
instanceProps={instanceProps}
|
||||
/>
|
||||
)}
|
||||
{/* Component includes many types and it's hard to provide right ref type with useRef */}
|
||||
|
||||
@@ -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 = () => {
|
||||
|
||||
Reference in new issue
Block a user