1

I am creating a SlateJS editor using @udecode/slate-plugins. I got most of the editor working but, are trying to create a toolbar for table blocks that should be visible above the table when it is selected/active.

The toolbar are currently showing correctly above the table but, when I insert multiple tables in the editor the toolbar is visible above every table when one of the tables is selected/active.

How can I get the toolbar to only be visible on the active table and hidden on the rest?

Demo: Codesandbox.io

The Table block code

const Table = ({
  attributes,
  children,
  className,
  nodeProps
}: StyledElementProps) => {
  const editor = useTSlate();

  const isActive = someNode(editor, { match: { type: ELEMENT_TABLE } });

  return (
    <table {...attributes} className={className} {...nodeProps}>
      <Tippy
        interactive={true}
        arrow={false}
        visible={isActive}
        onClickOutside={(instance) => instance.hide()}
        content={
          <div style={{ display: "flex", flexDirection: "row" }}>
            <ToolbarTable
              icon={<CgExtensionRemove />}
              transform={deleteTable}
              tooltip={{ content: "Delete Table" }}
            />
            <ToolbarTable
              icon={<AiOutlineInsertRowBelow />}
              transform={addRow}
              tooltip={{ content: "Insert Row" }}
            />
            <ToolbarTable
              icon={<AiOutlineDeleteRow />}
              transform={deleteRow}
              tooltip={{ content: "Delete Row" }}
            />
            <ToolbarTable
              icon={<AiOutlineInsertRowRight />}
              transform={addColumn}
              tooltip={{ content: "Insert Column" }}
            />
            <ToolbarTable
              icon={<AiOutlineDeleteColumn />}
              transform={deleteColumn}
              tooltip={{ content: "Delete Column" }}
            />
          </div>
        }
      >
        <tbody>{children}</tbody>
      </Tippy>
    </table>
  );
};
Rajohan
  • 1,411
  • 2
  • 10
  • 27

1 Answers1

1

Solved it by getting the current selection and checking if the table block contains the selection.

const [isActive, setIsActive] = useState(false);
const domSelection = window.getSelection();

useEffect(() => {
    setIsActive(
        !!(
            someNode(editor, { match: { type: ELEMENT_TABLE } }) &&
            domSelection &&
            attributes.ref.current &&
            attributes.ref.current.contains(domSelection.anchorNode)
        )
    );
}, [attributes, domSelection, editor]);
Rajohan
  • 1,411
  • 2
  • 10
  • 27
  • I am in the similar need to show a toolbar but for links. How would you suggest me to go ahead? Also why did you use domSelection? – Ayan Dec 11 '21 at 20:49