#Component based Action-Bar

1 messages ยท Page 1 of 1 (latest)

fickle shard
#

Hey there,
with 0.16.0 the action bar can generally be customized, awesome!

Now I was wondering if this could be implemented on a component base.
For context: I am trying to recreate the RichTextEditor from tohuhono with TipTap, due to their easier UI.

So far I ripped this part from tohuhono to get the action bar.

export const getToolbarPortal = (id: string) => {
  const base = document.querySelector("iframe")?.contentDocument || document

  // Iframe selector
  return base
    ?.querySelector(`[data-rfd-draggable-id="draggable-${id}"]`)
    ?.querySelector("button")?.parentElement
}

Now I can use a react portal, just like tohuhono did, this seems a bit sketchy, since the iframe selector might change anytime.

const RichTextToolbar = ({ id, editor }: Props) => {
  const portalTarget = getToolbarPortal(id);

  return (
    <>
      {portalTarget &&
        createPortal(
          <ActionBar.Group>
            <ActionBar.Action
              onClick={() => editor.chain().focus().toggleBold().run()}
            >
              <Bold size={16} />
            </ActionBar.Action>
            <ActionBar.Action
              //active={editor.isActive("italic")}
              onClick={() => editor.chain().focus().toggleItalic().run()}
            >
              <Italic size={16} />
            </ActionBar.Action>
            <ActionBar.Action
              //active={editor.isActive("underline")}
              onClick={() => editor.chain().focus().toggleUnderline().run()}
            >
              <Underline size={16} />
            </ActionBar.Action>
          </ActionBar.Group>,
          portalTarget,
        )}
    </>
  );
};

My idea here would be to have a actionBar property on the ComponentConfig similar to fields

Is this archievable?
Love this project!
Thanks a lot!

elder vessel
#

Hi! I can recommend another pattern, but I haven't tested it using Puck.

The tunnel-rat project is an alternative to portals, and it's fairly simple to use. If the In component is rendered, all its children will be rendered in the Out component. Your case sounds like a perfect fit for it.

Even though the main library works great, I've experienced some HMR issues and some warnings related to the zustand version. Luckily for us, this PR (closed) implements another approach, and it's this version the one I've been using in different projects.

I hope this helps in the meantime.

GitHub

๐Ÿ€ Non gratum anus rodentum. Contribute to pmndrs/tunnel-rat development by creating an account on GitHub.

GitHub

Fixes #4
I was hoping that #9 might've fixed the HMR issue I was seeing in #4, but it doesn't seem to have.
Background
The HMR issue I'm seeing is that when a component that...

fickle shard
#

Uh! This is smart and really sounds like the exact use case! Iโ€˜ll give it a shot! Thank you! ๐Ÿ™‚

fickle shard
#

This works exactly as mentioned. Thank you

elder vessel
blazing rain
#

Awesome ๐Ÿ‘ Smart solution @elder vessel!

Another way of doing this would be to add your own selector to the actionBar override, and then reference that instead of the hacky iframe selector"

import { ActionBar } from "@measured/puck";
 
const overrides = {
  actionBar: ({ children }) => {
    return (
      <ActionBar label="Actions">
        <div id="my-action-bar" />
      </ActionBar>
    )
  }
};

You could use usePuck to get the currently selected item ID if you need to make it more deterministic. Granted, this adds an additional div - would be nice if ActionBar took an id parameter.

fickle shard
#

ha, right. Now we have the Action Bar exposed, we could reference it ๐Ÿ˜„

fickle shard
#

I just stumbled upon the following issue with Tunnelrat:

So I guess, @blazing rains solution will be it

blazing rain
#

Yo dawg I heard you liked formatting. So I put formatting in your formatting so you can format whilst you format.

#

Let me know if you have any issues with my approach ๐Ÿ‘

#

We can also add id to the ActionBar API for next feature release

fickle shard
fickle shard
#

Okay, does puck have a possibility to get elements directly, or do I need to queryselect the iframe first?