Portabletexteditor integration to Retool app

  1. My goal: To build an app and integrate PortableTextEditor. I will be needing it for my app to generate a json from the text entered in the editor.

  2. Issue: I was not able to import the said plugin/library because it doesn't have CDN.

  3. Steps I've taken to troubleshoot: Currently checking for other way how to import this library on my retool app.

1 Like

Hi @rlmnl!

The best way to get a component like the Portable Text Editor to work with Retool is by deploying it as a custom component.

This takes a little more work than just including it in your existing app but the results can be rewarding.

Here's a quick proof of concept I did in about 20 minutes to prove it out:
portable

You can learn more about how to work with custom components here: Build custom React components | Retool Docs -- it helps to already be comfortable on the command line and with Node.js and React.

Once you adapt the code to load and pass state from React to Retool's expectations, you can keep on customizing the editor.

Let me know if you run into any issues and I can help debug.

  • Taylor
2 Likes

hi @episod thanks for sharing this. I was able to load the PortableTextEditor to my Retool app.

I can get/retrieve the generated json value from the text editor.

This is the code added in the retool component library.

export const PortableTextEditor: FC = () => {

  const [value, setValue] = Retool.useStateString({
      name: 'value',
      label: 'Value',
      description: 'Get/ assign value entered into the editor.  Expected output in JSON format.',
    });

  return (
      
      <div className="grid gap-2 items-start grid-cols-1 md:grid-cols-2 border p-2 shadow-sm">
        <EditorProvider
          initialConfig={
            schemaDefinition
          }
        >        
          <div className="flex flex-col gap-2">
            <PortableTextToolbar schemaDefinition={schemaDefinition} />

            <div className="flex gap-2 items-center">
              <PortableTextEditable
                renderDecorator={renderDecorator}          
                renderAnnotation={renderAnnotation}          
                renderBlock={RenderBlock}          
                renderStyle={renderStyle}          
                renderPlaceholder={renderPlaceholder}                              
                renderListItem={renderListItem}
              />
            </div>
          </div>
        </EditorProvider>
      </div>
    )
};

The issue I have right now is I cannot set/assign a value to the text editor programmatically.

use case: I have a button that when triggered, it will assign a value to the text editor.

Looking forward to your reply.

Great work! I got a little closer to setting the initial value programmatically, but I can't get it to successfully update the rendered value if it changes in real time. (I've been able to get that to work successfully with a different React-based Markdown editor).

Here's what I did:

  1. I created a new page-level variable that will hold an array (PortableTextEditor wants an array of markup objects): editorContent
  2. I created a new page-level JS query that sets the value of the variable with editorContent.setValue(new_object); where new_content contains the new array of markup objects.
  3. I configured the custom component in Retool to set the value for the component to be the value of editorContent.value (so whatever is that value at the moment)
  4. Back in the custom component code, I changed this back to consuming an array and then use it to initialize the render (I've shortened this a bit):
  const [value, setValue] = Retool.useStateArray({
      name: 'value',
      label: 'Value',
      description: 'Get/ assign value entered into the editor.  Expected output in JSON array format.',
    });
  return (
    <>
      <EditorProvider
        initialConfig={{
          schemaDefinition,
          initialValue: value as PortableTextBlock[]
        }}
      >

Now if you re-render the component, you'll see whatever you placed in the variable open up at default.

I'm not familiar enough with this library to see where to hook into change events but maybe you are! Hope this is helpful.

Taylor

Thanks @episod Taylor for the reply. I really appreciate it.
I am also familiarizing myself with this library and can't see where to hook the change event.

You've mentioned that you been able to get this work with other React-based Markdown editor. May I know what is the name of that editor so I can also try?
Does it also have a json schema output?

Thanks!