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

How to use methods as a prop in craft js #677

Open
gaurav-simpplr opened this issue Jul 16, 2024 · 1 comment
Open

How to use methods as a prop in craft js #677

gaurav-simpplr opened this issue Jul 16, 2024 · 1 comment

Comments

@gaurav-simpplr
Copy link

Hello,

Thanks for this library. Amazing project.

I'm trying to build a HTML builder and I need help in one of my use case
I have a Text UI element in my editor.
I'm dragging and dropping this element to create a text node.
I'm also applying some transformations on the rendered text content. I'm using transformer prop for that.

This is my UI element code :

import { Typography, TypographyProps } from "@simpplr/athena-ui";
import ContentEditable from "react-contenteditable";
import { useEditor, useNode } from "@craftjs/core";
import { useState } from "react";
import { useApiValue } from "../../../Data/ApiContext";
import { TextSettings } from "./TextSettings";
import { formatContent } from "../utils";
import { NodeProps } from "./types";
import styles from "./Text.module.css";
import { transform } from "lodash";

type TextProps = {
  text: string;
  color: TypographyProps["color"];
  weight: TypographyProps["weight"];
  name: TypographyProps["name"];
  dataBind: string | string[];
  shouldTransform: boolean;
  strategy: "firstValid" | "all";
  transformer: (text: string) => string;
};

export const Text = ({
  text,
  color,
  weight,
  name,
  dataBind,
  transformer,
}: Partial<TextProps>) => {
  const {
    connectors: { connect, drag },
    actions: { setProp },
  } = useNode();

  const { enabled } = useEditor((state) => ({
    enabled: state.options.enabled,
  }));

  const [editable, setEditable] = useState(false);

  const apiValue = useApiValue(dataBind);
  const data = apiValue ? apiValue[0] : null;

  const content = formatContent(data);

  const transformedText = transformer ? transformer(content) : content;

  return (
    <div
      ref={(ref) => ref && connect(drag(ref))}
      className={styles.TextWrapper}
    >
      <Typography color={color} weight={weight} name={name}>
        {dataBind ? (
          transformedText
        ) : (
          <ContentEditable
            html={text || "Add your text here"}
            onClick={() => setEditable(true)}
            onChange={(e) =>
              setProp(
                // eslint-disable-next-line no-return-assign -- This is expected by CraftJs
                (nodeProps: NodeProps) =>
                  // eslint-disable-next-line no-param-reassign -- This is expected by CraftJs
                  (nodeProps.text = e.target.value.replace(
                    /<\/?[^>]+(>|$)/g,
                    "",
                  )),
              )
            }
            disabled={!enabled || !editable}
          />
        )}
      </Typography>
    </div>
  );
};

Text.craft = {
  displayName: "Text",
  related: { settings: TextSettings },
  props: {
    color: "typeBody",
    weight: "normal",
    name: "heading1",
    strategy: "firstValid",
    transformer: (content) => content,
  },
};

And this is how I'm using it :

              <Text
                name="heading3"
                color="typeTitleLight"
                dataBind="$.WorkdayJobPosting.postedOnDate"
                transformer={(content) => timeSince(content, 'Posted')}
              />

It works fine when used by dragging and dropping. But when I create its schema to store in my database and then use that schema at other place, the transformer methods do not get applied. Content directly renders as it is.
Could you please advise how this needs to be done.
Thanks.

@addlistener
Copy link

props will be serialized. Try info #578

It's not documented well enough. I stumbled across it the other day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants