reactjs - React ile Mantine UI kullanarak çok seviyeli/iç içe menüler oluşturmak mümkün mü?


Mantine Kütüphanesi tarafından sağlanan Menü bileşenini kullanarak iç içe geçmiş bir menü oluşturmaya çalışıyorum. Ancak, bunu resmi belgelerinde bile bulamadım. Bu mümkün mü? NavLink bileşeninin kullanılabileceğini biliyorum, ama bunu özellikle Menü bileşeni ile yapmak istiyorum. Kodu şöyle gömmeyi denedim, ama yan tarafta ayrı bir Menü oluşuyor ve nedense, kullanıcı arayüzünü bozuyor.

import './App.css';
import { Menu, Button, Text } from '@mantine/core';
import { IconSettings, IconSearch, IconPhoto, IconMessageCircle, IconTrash, IconArrowsLeftRight } from '@tabler/icons-react';

function App() {
    return (
        <div className="App">
            <Menu shadow="md" width={200}>
                <Menu.Target>
                    <Button>Toggle menu</Button>
                </Menu.Target>

                <Menu.Dropdown>
                    <Menu.Label>Application</Menu.Label>
                    <Menu.Item icon={<IconSettings size={14} />}>Settings</Menu.Item>
                    <Menu.Dropdown>
                        <Menu.Label>Text Format</Menu.Label>
                        <Menu.Label>Document</Menu.Label>
                        <Menu.Label>Other Settings</Menu.Label>
                    </Menu.Dropdown>
                    <Menu.Item icon={<IconMessageCircle size={14} />}>Messages</Menu.Item>
                    <Menu.Item icon={<IconPhoto size={14} />}>Gallery</Menu.Item>
                    <Menu.Item
                        icon={<IconSearch size={14} />}
                        rightSection={<Text size="xs" color="dimmed">⌘K</Text>}
                    >
                        Search
                    </Menu.Item>

                    <Menu.Divider />

                    <Menu.Label>Danger zone</Menu.Label>
                    <Menu.Item icon={<IconArrowsLeftRight size={14} />}>Transfer my data</Menu.Item>
                    <Menu.Item color="red" icon={<IconTrash size={14} />}>Delete my account</Menu.Item>
                </Menu.Dropdown>
            </Menu>
        </div>
    );
}

export default App;

Düzenle :

mantine sürüm 6.0.6 kullanıyorum. Katmanlı/çok seviyeli meniden kastım buna benzer bir şey:

Sadece ne başarmak istediğimi ilettiği için bu resmi rastgele seçtiğimi unutmayın, yani bir alt menü altında bir menü.

Yukarıdaki kodu kullanarak Menu.Dropdown öğesini bir Menu.Item içine gömdüğümde, alt menü ana menüden tamamen farklı şekilde aşağıdaki sonucu elde ediyorum.

Cevap #1

Kodunuza aşağıdaki şekilde başvurabilirsiniz

önemli: withinPortal https://mantine.dev/core/popover/#nested-popovers

İç içe popover'lar, Portal olmadan çocuk bileşenlerin render edilmesini gerektirir. Genellikle, popover içeriğini render eden bileşenin propsları ile portalı devre dışı bırakmalısınız; örneğin, Select bileşeninin comboboxProps={{ withinPortal: false }} prop’u vardır. Popover içeriğini render etmek için kullandığınız bileşenin dokümantasyonunu kontrol ederek portalın nasıl devre dışı bırakılacağını öğrenin. Portal devre dışı bırakılmazsa, dışa tıklama tüm popover'ları kapatacaktır.

Örnek :

 {/* parent */}
      <Popover width={300} position="bottom" withArrow shadow="md">
        <Popover.Target>
          <Button>Toggle popover</Button>
        </Popover.Target>
        <Popover.Dropdown bg="var(--mantine-color-body)">

         {/* children */}
          <Popover width={300} position="bottom" withArrow shadow="md" withinPortal={false}>
            <Popover.Target>
              <Button>Toggle popover</Button>
            </Popover.Target>
            <Popover.Dropdown bg="var(--mantine-color-body)">
              <Select
                label="Select within Popover"
                placeholder="Select within Popover"
                comboboxProps={{ withinPortal: false }}
                data={["React", "Angular", "Svelte", "Vue"]}
              />
              <Select
                label="Select within Popover"
                placeholder="Select within Popover"
                comboboxProps={{ withinPortal: false }}
                data={["React", "Angular", "Svelte", "Vue"]}
              />
              <Select
                label="Select within Popover"
                placeholder="Select within Popover"
                comboboxProps={{ withinPortal: false }}
                data={["React", "Angular", "Svelte", "Vue"]}
              />
            </Popover.Dropdown>
          </Popover>

          <Select
            label="Select within Popover"
            placeholder="Select within Popover"
            comboboxProps={{ withinPortal: false }}
            data={["React", "Angular", "Svelte", "Vue"]}
          />
          <Select
            label="Select within Popover"
            placeholder="Select within Popover"
            comboboxProps={{ withinPortal: false }}
            data={["React", "Angular", "Svelte", "Vue"]}
          />
          <Select
            label="Select within Popover"
            placeholder="Select within Popover"
            comboboxProps={{ withinPortal: false }}
            data={["React", "Angular", "Svelte", "Vue"]}
          />
        </Popover.Dropdown>
      </Popover>

Cevap #2

Yukarıdaki yorumumu genişleterek, tüm alt menüyü bir Menu.Item bileşeninin çocuğu olarak render etmeyi denemek. Çalışıp çalışmadığını merak ediyorum; test etmek için Mantine 6 elimde yok.

import './App.css';
import { Menu, Button, Text } from '@mantine/core';
import { IconSettings, IconSearch, IconPhoto, IconMessageCircle, IconTrash, IconArrowsLeftRight } from '@tabler/icons-react';

function App() {
    return (
        <div className="App">
            <Menu shadow="md" width={200}>
                <Menu.Target>
                    <Button>Toggle menu</Button>
                </Menu.Target>

                <Menu.Dropdown>
                    <Menu.Label>Application</Menu.Label>
                    <Menu.Item icon={<IconSettings size={14} />}>
                        <Menu shadow="md" width={200}>
                            <Menu.Target>
                                Settings
                            </Menu.Target>
                            <Menu.Dropdown>
                                <Menu.Label>Text Format</Menu.Label>
                                <Menu.Label>Document</Menu.Label>
                                <Menu.Label>Other Settings</Menu.Label>
                            </Menu.Dropdown>
                        </Menu>
                    </Menu.Item>
                    
                    <Menu.Item icon={<IconMessageCircle size={14} />}>Messages</Menu.Item>
                    <Menu.Item icon={<IconPhoto size={14} />}>Gallery</Menu.Item>
                    <Menu.Item
                        icon={<IconSearch size={14} />}
                        rightSection={<Text size="xs" color="dimmed">⌘K</Text>}
                    >
                        Search
                    </Menu.Item>

                    <Menu.Divider />

                    <Menu.Label>Danger zone</Menu.Label>
                    <Menu.Item icon={<IconArrowsLeftRight size={14} />}>Transfer my data</Menu.Item>
                    <Menu.Item color="red" icon={<IconTrash size={14} />}>Delete my account</Menu.Item>
                </Menu.Dropdown>
            </Menu>
        </div>
    );
}

export default App;