measuredco / puck

The visual editor for React
https://puckeditor.com
MIT License
5.12k stars 290 forks source link

Feedback for “Data” #395

Closed SicParv1sMagna closed 1 month ago

SicParv1sMagna commented 6 months ago

I have a list of components without <DropZone />, I can add components to some of them in my constructor, but when I decided to use puck and made a parser which transforms my scheme to puck scheme format to render it in , that doesn't work.

I made a parser, that transforms my format to puck format with zones, but it doesn't renders, does it mean, that I should use <DropZone /> inside of my components?

SicParv1sMagna commented 6 months ago

In my scheme, if there is "children" inside of some component, I can add inside of this field other components, so I made a check inside of my parser, if ("children" in scheme) parse it to zone format

chrisvxd commented 6 months ago

@SicParv1sMagna it would be helpful to see your format and parser, if you can share.

SicParv1sMagna commented 6 months ago

This is my page json.

{
    "$type": "container",
    "background": "white",
    "children": [
      {
        "$type": "newsblock",
        "items": [
          {
            "title": "news#1",
            "$type": "newsblock_items"
          },
          {
            "title": "news#2",
            "$type": "newsblock_items"
        },
        ]
      }
    ]
  }
export const formatZonesToPuck = (children, rootType) => {
  const { $type, ...props } = children[0];
  console.log(children, $type);
  const zones: Record<string, any> = {};
  zones[${rootType}-1234] = {
    type: ${$type},
    props: {
      id: ${$type}-1234,
      ...props,
    },
  };
  console.log("zones", zones);
  return zones;
}

export const formatPageToPuck = (page: Record<string, object[]>, title: string): Page => {
    const puckPage: Page = {
      content: [],
      root: {},
      zones: {},
    }
    const content = page.reduce((acc, component) => {
      const { $type, children, ...props } = component;
      if (!children) {
        Object(acc).push({
          type: $type,
          props: props,
        });
      } else {
        Object(acc).push({
          type: $type,
          props: props,
          zones: { ...formatZonesToPuck(children, $type) },
        })
      }

      return acc;
    }, []);
    Object.assign(puckPage.zones, content[0].zones)
    delete content[0].zones;
    Object.assign(puckPage.content, content);
    console.log("PUCK PAGE", puckPage);
    return puckPage;
  }
SicParv1sMagna commented 6 months ago

@chrisvxd, this parser looks shitty, because I was trying with at least one component to understand will it work or not

SicParv1sMagna commented 6 months ago

I guess that I should add <Dropable> inside of my container component?

SicParv1sMagna commented 6 months ago

UPD: I added DropZone to my component, it started work locally, but when Iam doing the same thing with my components library, it doesn't work

chrisvxd commented 6 months ago

Hm it looks like you're adding zones to your component data, but it should be at the root of the data

        Object(acc).push({
          type: $type,
          props: props,
          zones: { ...formatZonesToPuck(children, $type) },
        })

I'd recommend trying to recreate it with Puck first to understand the data model, then reverse engineer to figure out your parser.

it's also worth keeping an eye on #255, as we'll likely be modifying the data model in the near future.

SicParv1sMagna commented 6 months ago

@chrisvxd I know about it, but it was a mistake, thats why I deleting this field at the end of the function and adding it to the zones object

Object.assign(puckPage.zones, content[0].zones)
    delete content[0].zones;
    Object.assign(puckPage.content, content);
    console.log("PUCK PAGE", puckPage);
    return puckPage;

P.S. I know thats this code smells a lot, but I just trying to visualize components, I will rewrite this blocks

SicParv1sMagna commented 6 months ago

UPD: It worked, when I moved my one of my component, which have <DropZone />, inside of my next.js app, but it didn't worked for library components. In next.js, Iam using it with directive 'use client'

SicParv1sMagna commented 6 months ago

@chrisvxd I think, that its some sort of bug:

I had created new components-library with only component for testing and added DropZone inside of this component: PuckEditor doesn't renders it as a component with DropZone, I can add this component in the constructor and it will renders correctly in , but I can't add something inside of it. If I create this component inside of my application with DropZone and try to add it in PuckEditor, it will renders correctly and will allow to add something inside of it.

I tried to recreate it in 0.13.1 and 0.14.0 versions of puck

SicParv1sMagna commented 1 month ago

This bug exists only when you are using yarn link or npm link, because they can't resolve dependencies correctly. I decided to use yalc and this issue had gone