Skip to content

Custom Component For Slash Menu Styling #582

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

Closed
natti-tamnoon opened this issue Feb 15, 2024 · 2 comments · Fixed by #609
Closed

Custom Component For Slash Menu Styling #582

natti-tamnoon opened this issue Feb 15, 2024 · 2 comments · Fixed by #609
Labels
enhancement New feature or request

Comments

@natti-tamnoon
Copy link

Is your feature request related to a problem? Please describe.
Reviewing the documentation I see the ability to modify the order and groupings of the slash menu items, but I want to customize the styling of the Slash menu itself.

For example, be able to add vertical line separators between the grouped sections, and change the styling of the icons to remove the grey background.

Perhaps this is already possible, but I couldn't figure this out from the documentation.

Describe the solution you'd like
Requesting way to uniformly style the menu. If this feature exists, requesting a simple documentation example.

Thanks!

@natti-tamnoon natti-tamnoon added the enhancement New feature or request label Feb 15, 2024
@nicholasdavidbrown
Copy link

The <SlashMenuPositioner editor={editor} slashMenu={CustomSlashMenu} /> takes an optional prop similar to the others.

So just stealing from the source code works, you just need to re-import components from their libraries.

export function CustomSlashMenu<BSchema extends BlockSchema>(
  props: SlashMenuProps<BSchema>
) {
  const renderedItems: any[] = [];
  let index = 0;

  const groups = groupBy(props.filteredItems, (i) => i.group);

  forEach(groups, (groupedItems) => {
    renderedItems.push(
      <Menu.Label key={groupedItems[0].group}>
        {groupedItems[0].group}
      </Menu.Label>
    );

    for (const item of groupedItems) {
      renderedItems.push(
        <SlashMenuItem
          key={item.name}
          name={item.name}
          icon={item.icon}
          hint={item.hint}
          shortcut={item.shortcut}
          isSelected={props.keyboardHoveredItemIndex === index}
          set={() => props.itemCallback(item)}
        />
      );
      index++;
    }
  });

  return (
    <Menu
      withinPortal={false}
      trapFocus={false}
      /** Hacky fix to get the desired menu behaviour. The trigger="hover"
       * attribute allows focus to remain on the editor, allowing for suggestion
       * filtering. The closeDelay=10000000 attribute allows the menu to stay open
       * practically indefinitely, as normally hovering off it would cause it to
       * close due to trigger="hover".
       */
      defaultOpened={true}
      trigger={'hover'}
      closeDelay={10000000}
    >
      <Menu.Dropdown
        // TODO: This should go back in the plugin.
        onMouseDown={(event) => event.preventDefault()}
        className={'bn-slash-menu'}
      >
        {renderedItems.length > 0 ? (
          renderedItems
        ) : (
          <Menu.Item>No match found</Menu.Item>
        )}
      </Menu.Dropdown>
    </Menu>
  );
}

I've used this in my project as well.

@YousefED
Copy link
Collaborator

YousefED commented Mar 5, 2024 via email

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

Successfully merging a pull request may close this issue.

3 participants