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

Dynamically generate Items for Menu #200

Open
Xuroth opened this issue Nov 18, 2021 · 5 comments
Open

Dynamically generate Items for Menu #200

Xuroth opened this issue Nov 18, 2021 · 5 comments

Comments

@Xuroth
Copy link

Xuroth commented Nov 18, 2021

Do you want to request a feature or report a bug?
This may be a feature request, or I may simply be missing something.
What is the current behavior?
Currently, you have to explicitly define the specific Items to render as JSX components. I'm attempting to get the passed props in a component so I can render a dynamic list.

To clarify, I am trying to use this in MySeparateComponent:

const { show } = useContextMenu({
  id: 'my-separate-component'
 });
 
 //...
 
 const onContextClick = (ev) => {
  show(ev, {
    items: [itemA, itemB, itemC,]
  })
}

And then I want to access the items array in the context menu to generate the list of Items:

function MyCustomContextMenu(props) {

  const handleItemClick = (itemClicked) => {
    //... (Do something with the item that was passed from props)
  }

  return (
    <Menu
      id="my-separate-component"
    >
      {props.items.map(( item, index ) => <Item onClick={() => handleItemClick(item)} key={index}>{item.name}</Item>)}
    </Menu>
}

Am I missing something? Or is this outside the scope of this library?

@eirikhm
Copy link

eirikhm commented Nov 19, 2021

The props are passed to the onClick. I solved this w mobx by having MyCustomContextMenu fetch items from observable state.

@Xuroth
Copy link
Author

Xuroth commented Nov 19, 2021

Hmm... interesting. I use a combination of redux and context (redux handles app data, context is for passing derived data (from expensive calculations)).

I'll look into creating a context for this. Thanks for your help @eirikhm!!

EDIT: I'll close this issue after I've had some time to build and test.

@DrStriky
Copy link

@Xuroth can you post your final solution.
I face the same problem.

thx

@galexandrade
Copy link

Yeah. This feature is exactly what we need ❤️

@wilmerterrero
Copy link

I solved using a React.Children because the limitation of use ReactFragment

That's the code:

ContextMenu

import { useMemo } from 'react';
import { Menu, Item, Separator, Submenu, ItemParams } from 'react-contexify';
import 'react-contexify/dist/ReactContexify.css';

export type ContextMenuItem = {
  label: string;
  subMenuItems?: ContextMenuItem[];
  hasSubmenu?: boolean;
  disabled?: boolean;
  handleItemClick: (args: ItemParams<any, any>) => void;
};
type Props = {
  menuId: string;
  items: ContextMenuItem[];
};

export default function ContextMenu({ menuId, items }: Props) {
  const children = useMemo(() => {
    const elements: React.ReactNode[] = [];
    for (let index = 0; index < items.length; index++) {
      const item = items[index];
      elements.push(
        <Item
          key={item.label}
          onClick={item.handleItemClick}
          disabled={item.disabled}
        >
          {item.label}
        </Item>,
      );
      if (index !== items.length - 1) elements.push(<Separator />);
      if (item.hasSubmenu)
        elements.push(
          <Submenu label={item.label}>
            {item.subMenuItems?.map((subMenuItem) => (
              <Item
                key={subMenuItem.label}
                onClick={subMenuItem.handleItemClick}
                disabled={subMenuItem.disabled}
              >
                {subMenuItem.label}
              </Item>
            ))}
          </Submenu>,
        );
    }

    return elements;
  }, []);

  return <Menu id={menuId}>{children}</Menu>;
}

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

6 participants