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

[EuiContextMenu] renderItem wildcard content #7507

Closed
mdefazio opened this issue Feb 2, 2024 · 5 comments · Fixed by #7510
Closed

[EuiContextMenu] renderItem wildcard content #7507

mdefazio opened this issue Feb 2, 2024 · 5 comments · Fixed by #7510
Assignees

Comments

@mdefazio
Copy link
Contributor

mdefazio commented Feb 2, 2024

Describe the solution you'd like
We would like to have more flexibility on the structure of the context menu when passing in an array of panel objects.

Background

Currently it is possible to pass an array of panel objects that generate the panel structure (alongside being able to build out the context menu by individual components). We would like to be able to have a bit more flexibility with the display of these panels when passing in an array.

cc/ @umbopepato @XavierM @andreadelrio

Expectation

We would like the option to include an option for 'inline' (or whatever makes sense) to a panel which would display this alongside the previous panel, and not a nested panel.

Note: this is just an initial thought, we are absolutely open to better implementation ideas here

An example of this could be the following:

Current setup:

const currentPanels=[
{
 id: 0,
 title: "Fruit",
 items: [
  {
    name: "Bananas",
    onClick: ()=>{...},
  },
  {
    name: "Oranges",
    onClick: ()=>{...},
  },
  {
    name: "Papayas",
    onClick: ()=>{...},
  },
  {
    name: "More fruit",
    icon: “boxesVertical”
    panel: 1,
  },
 ].
},
{
 id: 1,
 title: "More fruit",
 items: [
  {
    name: "Apples",
    onClick: ()=>{...},
  },
  {
    name: "Grapes",
    onClick: ()=>{...},
  },
  {
    name: "Pineapples",
    onClick: ()=>{...},
  },
 ].
}
]

image

Proposal:

const newPanels=[
{
 id: 0,
 title: "Fruit",
 items: [
  {
    name: "Bananas",
    onClick: ()=>{...},
  },
  {
    name: "Oranges",
    onClick: ()=>{...},
  },
  {
    name: "Papayas",
    onClick: ()=>{...},
  },
  {
    name: "More fruit",
    panel: 1,
  },
  {
    name: "Exotic fruit",
    icon: “starFilled”
    panel: 2,
  },
 ].
},
{
 id: 1,
 inline: true, // New option
 items: [
  {
    name: "Apples",
    onClick: ()=>{...},
  },
  {
    name: "Grapes",
    onClick: ()=>{...},
  },
  {
    name: "Pineapples",
    onClick: ()=>{...},
  },
 ].
},
{
 id: 2,
 inline: false, // New option
 items: [
  {
    name: "Durian",
    onClick: ()=>{...},
  },
  {
    name: "Carambola",
    onClick: ()=>{...},
  },
  {
    name: "Jackfruit",
    onClick: ()=>{...},
  },
 ].
}
]

image

@cee-chen
Copy link
Contributor

cee-chen commented Feb 2, 2024

From a DOM/animation perspective, this doesn't really make sense for us to do and would convolute the underlying code fairly severely. Could we instead give you individual items to render, e.g.

const panels = [
  {
    id: 0,
    title: 'Fruit',
    items: [
      // normal EuiContextMenuItem props
      { isSeparator: true },
      { isSubTitle: true, title: 'More fruit' },
      // more EuiContextMenuItems
  },
  {
    id: 1,
    title: 'More',
    items: [...],
  },
];

This matches the API we have in place for EuiCollapsibleNavBeta FWIW.

EDIT: actually, the most flexible API (which still matches what we do for EuiCollapsibleNavBeta) would be to give you a render prop for an item obj, e.g.

items: [
  { render: EuiHorizontalRule },
  { render: () => <EuiTitle size="xxxs"><h3>Subtitle</h3></EuiTitle> },
  { render: CustomComponent, }
]

@umbopepato
Copy link
Member

Hey @cee-chen, thanks for your input! I think any of these solutions would work perfectly for our use case 🙂

@cee-chen
Copy link
Contributor

cee-chen commented Feb 5, 2024

renderItem prop it is! :) Thanks for your flexibility all!

edit: I misremembered the prop name!

@cee-chen cee-chen changed the title Context Menu Inline Panel option [EuiContextMenu] render wildcard content Feb 5, 2024
@cee-chen cee-chen self-assigned this Feb 5, 2024
@mdefazio
Copy link
Contributor Author

mdefazio commented Feb 5, 2024

Thank you!!

@cee-chen cee-chen changed the title [EuiContextMenu] render wildcard content [EuiContextMenu] renderItem wildcard content Feb 5, 2024
@cee-chen
Copy link
Contributor

cee-chen commented Feb 7, 2024

Hey y'all! This should be in Kibana main sometime this week.

Example usage:

const CustomComponent = () => (
  <div data-test-subj="custom">Hello world</div>
);

<EuiContextMenu
  initialPanelId={1}
  panels={[
    {
      id: 1,
      title: 'Testing renderItem',
      items: [
        // Default context menu item
        {
          name: 'Renders an EuiContextMenuItem',
          panel: 2,
        },
        // Custom items
        {
          renderItem: () => <EuiTitle size="xxs"><h3>Subtitle</h3></EuiTitle>,
        },
        {
          key: 'custom',
          renderItem: CustomComponent,
        },
      ],
    },
  ]}
/>

You can also see a custom subtitle here, on the second panel:

https://eui.elastic.co/pr_7510/storybook/index.html?path=/story/euicontextmenu--playground

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants