From 05e69ac0160c5e62939ade10ef60ec158c6cc210 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Wed, 7 Dec 2022 16:17:33 +0300 Subject: [PATCH] Give body separate type in sdk (#560) Body is the only container which should not be listed. After discussing with Oleg decided to give it separate body type. --- apps/designer/app/canvas/shared/instance.ts | 7 ++++--- apps/designer/app/canvas/shared/use-drag-drop.ts | 7 ++++--- apps/designer/app/designer/shared/tree/index.tsx | 9 +++++++-- packages/react-sdk/src/components/body.ws.tsx | 2 +- packages/react-sdk/src/components/component-type.ts | 12 ++++++++++-- 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/apps/designer/app/canvas/shared/instance.ts b/apps/designer/app/canvas/shared/instance.ts index 34f49428cb..450fcb2f77 100644 --- a/apps/designer/app/canvas/shared/instance.ts +++ b/apps/designer/app/canvas/shared/instance.ts @@ -73,9 +73,10 @@ export const findInsertLocation = ( ); path.reverse(); - const parentIndex = path.findIndex( - ({ item }) => getComponentMeta(item.component).type === "container" - ); + const parentIndex = path.findIndex(({ item }) => { + const { type } = getComponentMeta(item.component); + return type === "body" || type === "container"; + }); // Just in case selected Instance is not in the tree for some reason. if (parentIndex === -1) { diff --git a/apps/designer/app/canvas/shared/use-drag-drop.ts b/apps/designer/app/canvas/shared/use-drag-drop.ts index 2e79d037a5..0aa2406c34 100644 --- a/apps/designer/app/canvas/shared/use-drag-drop.ts +++ b/apps/designer/app/canvas/shared/use-drag-drop.ts @@ -115,9 +115,10 @@ export const useDragAndDrop = () => { path.splice(0, dragItemIndex + 1); } - const data = path.find( - (instance) => getComponentMeta(instance.component).type === "container" - ); + const data = path.find((instance) => { + const { type } = getComponentMeta(instance.component); + return type === "body" || type === "container"; + }); if (data === undefined) { return getDefaultDropTarget(); diff --git a/apps/designer/app/designer/shared/tree/index.tsx b/apps/designer/app/designer/shared/tree/index.tsx index 5c068af186..3dcbc73989 100644 --- a/apps/designer/app/designer/shared/tree/index.tsx +++ b/apps/designer/app/designer/shared/tree/index.tsx @@ -20,14 +20,19 @@ const instanceRelatedProps = { }, canAcceptChild(item: Instance) { const { type } = getComponentMeta(item.component); - return type === "container"; + return type === "body" || type === "container"; }, getItemChildren(item: Instance) { const { type } = getComponentMeta(item.component); // We want to avoid calling .filter() unnecessarily, because this is a hot path for performance. // We rely on the fact that only rich-text or rich-text-child components may have `string` children. - if (type === "container" || type === "control" || type === "embed") { + if ( + type === "body" || + type === "container" || + type === "control" || + type === "embed" + ) { return item.children as Instance[]; } diff --git a/packages/react-sdk/src/components/body.ws.tsx b/packages/react-sdk/src/components/body.ws.tsx index fa8ac6f70a..227259ccb0 100644 --- a/packages/react-sdk/src/components/body.ws.tsx +++ b/packages/react-sdk/src/components/body.ws.tsx @@ -53,7 +53,7 @@ const defaultStyle = { } as const; const meta: WsComponentMeta = { - type: "container", + type: "body", label: "Body", Icon: BodyIcon, props: props as MetaProps, diff --git a/packages/react-sdk/src/components/component-type.ts b/packages/react-sdk/src/components/component-type.ts index 41e20d35ab..50f3b37737 100644 --- a/packages/react-sdk/src/components/component-type.ts +++ b/packages/react-sdk/src/components/component-type.ts @@ -1,19 +1,26 @@ import { z } from "zod"; import type { FunctionComponent } from "react"; -import { IconProps } from "@webstudio-is/icons"; +import type { IconProps } from "@webstudio-is/icons"; import type { Style } from "@webstudio-is/css-data"; export type MetaProps = Partial>; export type WsComponentMeta = { /** + * body - can accept other components with dnd but not listed * container - can accept other components with dnd * control - usually form controls like inputs, without children * embed - images, videos or other embeddable components, without children * rich-text - editable text component * rich-text-child - formatted text fragment, not listed in components list */ - type: "container" | "control" | "embed" | "rich-text" | "rich-text-child"; + type: + | "body" + | "container" + | "control" + | "embed" + | "rich-text" + | "rich-text-child"; label: string; Icon: FunctionComponent; defaultStyle?: Style; @@ -66,6 +73,7 @@ const Props = z.record( export const WsComponentMeta = z.lazy(() => z.object({ type: z.enum([ + "body", "container", "control", "embed",