Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace meta.children with meta.template #1676

Merged
merged 1 commit into from
May 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 104 additions & 53 deletions apps/builder/app/shared/copy-paste/plugin-markdown.test.ts

Large diffs are not rendered by default.

23 changes: 13 additions & 10 deletions apps/builder/app/shared/copy-paste/plugin-markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,7 @@ export const parse = (clipboardData: string, options?: Options) => {
const instances: Instance[] = [];
const props: Prop[] = [];
const children = toInstanceData(instances, props, ast, options);
// assume text is not top level
const rootIds = children.flatMap((child) =>
child.type === "id" ? [child.value] : []
);
return { props, instances, rootIds };
return { props, instances, children };
};

export const onPaste = (clipboardData: string) => {
Expand All @@ -213,10 +209,12 @@ export const onPaste = (clipboardData: string) => {
];
const instances = instancesStore.get();
const dragComponents = [];
for (const instanceId of data.rootIds) {
const component = instances.get(instanceId)?.component;
if (component !== undefined) {
dragComponents.push(component);
for (const child of data.children) {
if (child.type === "id") {
const component = instances.get(child.value)?.component;
if (component !== undefined) {
dragComponents.push(component);
}
}
}
const dropTarget = findClosestDroppableTarget(
Expand All @@ -228,7 +226,12 @@ export const onPaste = (clipboardData: string) => {
return;
}
store.createTransaction([instancesStore, propsStore], (instances, props) => {
insertInstancesMutable(instances, data.instances, data.rootIds, dropTarget);
insertInstancesMutable(
instances,
data.instances,
data.children,
dropTarget
);
for (const prop of data.props) {
props.set(prop.id, prop);
}
Expand Down
21 changes: 18 additions & 3 deletions apps/builder/app/shared/instance-utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import store from "immerhin";
import { findTreeInstanceIdsExcludingSlotDescendants } from "@webstudio-is/project-build";
import {
generateDataFromEmbedTemplate,
getComponentMeta,
} from "@webstudio-is/react-sdk";
import {
propsStore,
stylesStore,
Expand All @@ -14,7 +18,6 @@ import {
import {
type DroppableTarget,
type InstanceSelector,
createComponentInstance,
findLocalStyleSourcesWithinInstances,
insertInstancesMutable,
reparentInstanceMutable,
Expand All @@ -34,16 +37,28 @@ export const insertNewComponentInstance = (
const breakpoints = breakpointsStore.get();
const breakpointValues = Array.from(breakpoints.values());
const baseBreakpoint = breakpointValues.find(isBaseBreakpoint);
const componentMeta = getComponentMeta(component);
if (baseBreakpoint === undefined) {
return;
}
const {
children,
instances: insertedInstances,
props: insertedProps,
styleSourceSelections: insertedStyleSourceSelections,
styleSources: insertedStyleSources,
styles: insertedStyles,
} = createComponentInstance(component, baseBreakpoint.id);
} = generateDataFromEmbedTemplate(
// when template not specified fallback to template with the component
componentMeta?.template ?? [
{
type: "instance",
component,
children: [],
},
],
baseBreakpoint.id
);
const rootInstanceId = insertedInstances[0].id;
store.createTransaction(
[
Expand All @@ -57,7 +72,7 @@ export const insertNewComponentInstance = (
insertInstancesMutable(
instances,
insertedInstances,
[rootInstanceId],
children,
dropTarget
);
insertPropsCopyMutable(props, insertedProps, new Map());
Expand Down
4 changes: 2 additions & 2 deletions apps/builder/app/shared/tree-utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ test("insert instances tree into target", () => {
createInstance("inserted1", "Box", [{ type: "id", value: "inserted2" }]),
createInstance("inserted2", "Box", []),
],
["inserted1"],
[{ type: "id", value: "inserted1" }],
{
parentSelector: ["box1", "root"],
position: 1,
Expand Down Expand Up @@ -267,7 +267,7 @@ test("insert instances tree into target", () => {
createInstance("inserted3", "Box", [{ type: "id", value: "inserted4" }]),
createInstance("inserted4", "Box", []),
],
["inserted3"],
[{ type: "id", value: "inserted3" }],
{
parentSelector: ["box1", "root"],
position: "end",
Expand Down
53 changes: 11 additions & 42 deletions apps/builder/app/shared/tree-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@ import {
StyleSourceSelectionsList,
StyleSourcesList,
} from "@webstudio-is/project-build";
import {
canAcceptComponent,
generateDataFromEmbedTemplate,
getComponentMeta,
} from "@webstudio-is/react-sdk";
import { canAcceptComponent } from "@webstudio-is/react-sdk";
import { equalMedia } from "@webstudio-is/css-engine";

// slots can have multiple parents so instance should be addressed
Expand Down Expand Up @@ -54,32 +50,6 @@ export const areInstanceSelectorsEqual = (
return left.join(",") === right.join(",");
};

export const createComponentInstance = (
component: Instance["component"],
defaultBreakpointId: Breakpoint["id"]
) => {
const componentMeta = getComponentMeta(component);
const {
children,
instances,
props,
styleSourceSelections,
styleSources,
styles,
} = generateDataFromEmbedTemplate(
componentMeta?.children ?? [],
defaultBreakpointId
);
// put first to be interpreted as root
instances.unshift({
type: "instance",
id: nanoid(),
component,
children,
});
return { instances, props, styleSourceSelections, styleSources, styles };
};

export type DroppableTarget = {
parentSelector: InstanceSelector;
position: number | "end";
Expand Down Expand Up @@ -283,7 +253,7 @@ export const findLocalStyleSourcesWithinInstances = (
export const insertInstancesMutable = (
instances: Instances,
insertedInstances: Instance[],
rootIds: Instance["id"][],
children: Instance["children"],
dropTarget: DroppableTarget
) => {
const parentInstance = getInstanceOrCreateFragmentIfNecessary(
Expand All @@ -306,16 +276,10 @@ export const insertInstancesMutable = (
}

const { position } = dropTarget;
const dropTargetChildren: Instance["children"] = rootIds.map(
(instanceId) => ({
type: "id",
value: instanceId,
})
);
if (position === "end") {
parentInstance.children.push(...dropTargetChildren);
parentInstance.children.push(...children);
} else {
parentInstance.children.splice(position, 0, ...dropTargetChildren);
parentInstance.children.splice(position, 0, ...children);
}
};

Expand Down Expand Up @@ -385,8 +349,13 @@ export const insertInstancesCopyMutable = (
insertInstancesMutable(
instances,
copiedInstancesWithNewIds,
// consider the first instance as the root
[copiedInstancesWithNewIds[0].id],
// consider the first instance as child
[
{
type: "id",
value: copiedInstancesWithNewIds[0].id,
},
],
dropTarget
);

Expand Down
86 changes: 47 additions & 39 deletions packages/react-sdk/src/app/custom-components/form.ws.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,55 +25,63 @@ export const meta: WsComponentMeta = {
{ selector: "[data-state=error]", label: "Error" },
{ selector: "[data-state=success]", label: "Success" },
],
children: [
template: [
{
type: "instance",
component: "Label",
children: [{ type: "text", value: "Name" }],
},
{
type: "instance",
component: "Input",
props: [{ type: "string", name: "name", value: "name" }],
children: [],
},
{
type: "instance",
component: "Label",
children: [{ type: "text", value: "Email" }],
},
{
type: "instance",
component: "Input",
props: [{ type: "string", name: "name", value: "email" }],
children: [],
},
{
type: "instance",
component: "Button",
children: [{ type: "text", value: "Submit" }],
},
{
type: "instance",
component: "SuccessMessage",
component: "Form",
children: [
{
type: "instance",
component: "TextBlock",
component: "Label",
children: [{ type: "text", value: "Name" }],
},
{
type: "instance",
component: "Input",
props: [{ type: "string", name: "name", value: "name" }],
children: [],
},
{
type: "instance",
component: "Label",
children: [{ type: "text", value: "Email" }],
},
{
type: "instance",
component: "Input",
props: [{ type: "string", name: "name", value: "email" }],
children: [],
},
{
type: "instance",
component: "Button",
children: [{ type: "text", value: "Submit" }],
},
{
type: "instance",
component: "SuccessMessage",
children: [
{ type: "text", value: "Thank you for getting in touch!" },
{
type: "instance",
component: "TextBlock",
children: [
{ type: "text", value: "Thank you for getting in touch!" },
],
},
],
},
],
},
{
type: "instance",
component: "ErrorMessage",
children: [
{
type: "instance",
component: "TextBlock",
children: [{ type: "text", value: "Sorry, something went wrong." }],
component: "ErrorMessage",
children: [
{
type: "instance",
component: "TextBlock",
children: [
{ type: "text", value: "Sorry, something went wrong." },
],
},
],
},
],
},
Expand Down
8 changes: 7 additions & 1 deletion packages/react-sdk/src/components/blockquote.ws.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,13 @@ export const meta: WsComponentMeta = {
icon: BlockquoteIcon,
states: defaultStates,
presetStyle,
children: [{ type: "text", value: "Blockquote you can edit" }],
template: [
{
type: "instance",
component: "Blockquote",
children: [{ type: "text", value: "Blockquote you can edit" }],
},
],
};

export const propsMeta: WsComponentPropsMeta = {
Expand Down
18 changes: 12 additions & 6 deletions packages/react-sdk/src/components/checkbox-field.ws.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,20 @@ export const meta: WsComponentMeta = {
icon: CheckboxCheckedIcon,
states: defaultStates,
presetStyle,
children: [
{ type: "instance", component: "Checkbox", props: [], children: [] },
template: [
{
type: "instance",
component: "TextBlock",
label: "Checkbox Label",
props: [],
children: [{ type: "text", value: "Checkbox" }],
component: "CheckboxField",
children: [
{ type: "instance", component: "Checkbox", children: [] },
{
type: "instance",
component: "TextBlock",
label: "Checkbox Label",
props: [],
children: [{ type: "text", value: "Checkbox" }],
},
],
},
],
};
Expand Down
8 changes: 7 additions & 1 deletion packages/react-sdk/src/components/code-text.ws.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@ export const meta: WsComponentMeta = {
icon: CodeTextIcon,
states: defaultStates,
presetStyle,
children: [{ type: "text", value: "Code you can edit" }],
template: [
{
type: "instance",
component: "CodeText",
children: [{ type: "text", value: "Code you can edit" }],
},
],
};

export const propsMeta: WsComponentPropsMeta = {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-sdk/src/components/component-meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const WsComponentMeta = z.object({
icon: z.string(),
presetStyle: z.optional(z.record(z.string(), EmbedTemplateStyleDecl)),
states: z.optional(z.array(ComponentState)),
children: z.optional(WsEmbedTemplate),
template: z.optional(WsEmbedTemplate),
});

export type WsComponentMeta = Omit<
Expand Down
Loading