Skip to content

Project switcher

Shows the current project and opens a menu to switch to another or create one. Place it at the top of a Sidebar or Top navigation.

Code
demo.tsx
import {AddIcon} from '@earendil-works/elanor-icons-react';
import {ProjectSwitcher, Stack, Text} from '@earendil-works/elanor-react';
import {useState} from 'react';

const projects = ['Website redesign', 'Design system'];

export default function ProjectSwitcherDemo() {
  const [project, setProject] = useState('Website redesign');
  const [status, setStatus] = useState('');

  return (
    <Stack gap="small">
      <ProjectSwitcher.Root>
        <ProjectSwitcher.Trigger>{project}</ProjectSwitcher.Trigger>
        <ProjectSwitcher.Portal>
          <ProjectSwitcher.Positioner align="start">
            <ProjectSwitcher.Popup>
              <ProjectSwitcher.Group>
                <ProjectSwitcher.GroupLabel>Projects</ProjectSwitcher.GroupLabel>
                {projects.map((name) => (
                  <ProjectSwitcher.Item
                    key={name}
                    onClick={() => {
                      setProject(name);
                      setStatus(`Switched to ${name}.`);
                    }}
                  >
                    {name}
                  </ProjectSwitcher.Item>
                ))}
              </ProjectSwitcher.Group>
              <ProjectSwitcher.Separator />
              <ProjectSwitcher.Group>
                <ProjectSwitcher.Item
                  icon={<AddIcon />}
                  onClick={() => setStatus('Selected: New project.')}
                >
                  New project
                </ProjectSwitcher.Item>
              </ProjectSwitcher.Group>
            </ProjectSwitcher.Popup>
          </ProjectSwitcher.Positioner>
        </ProjectSwitcher.Portal>
      </ProjectSwitcher.Root>
      <Text role="status">{status}</Text>
    </Stack>
  );
}

Usage

import {ProjectSwitcher} from '@earendil-works/elanor-react';

<ProjectSwitcher.Root>
  <ProjectSwitcher.Trigger>Website redesign</ProjectSwitcher.Trigger>
  <ProjectSwitcher.Portal>
    <ProjectSwitcher.Positioner align="start">
      <ProjectSwitcher.Popup>
        <ProjectSwitcher.Group>
          <ProjectSwitcher.GroupLabel />
          <ProjectSwitcher.Item />
        </ProjectSwitcher.Group>
      </ProjectSwitcher.Popup>
    </ProjectSwitcher.Positioner>
  </ProjectSwitcher.Portal>
</ProjectSwitcher.Root>;

Apart from Trigger, the parts are the Menu parts. The trigger ends with a chevron; pass indicator={null} to hide it or another icon to replace it.

API

ProjectSwitcher.Root

Accepts Base UI Menu.Root props.

ProjectSwitcher.Trigger

PropTypeDefaultDescription
childrenReactNode-The current project name.
indicatorReactNode<KeyboardArrowDownIcon aria-hidden="true" />Icon after the name. Pass null to hide it.

Also accepts Base UI Menu.Trigger props.

ProjectSwitcher.Portal

Accepts Base UI Menu.Portal props.

ProjectSwitcher.Positioner

Accepts Base UI Menu.Positioner props.

ProjectSwitcher.Popup

Accepts Base UI Menu.Popup props.

ProjectSwitcher.Group

Accepts Base UI Menu.Group props.

ProjectSwitcher.GroupLabel

Accepts Base UI Menu.GroupLabel props.

ProjectSwitcher.Item

PropTypeDefaultDescription
childrenReactNode-The item label.
iconReactNode-Decorative icon before the label.
endAdornmentReactNode-Content after the label, such as an icon.

Also accepts Base UI Menu.Item props.

ProjectSwitcher.LinkItem

PropTypeDefaultDescription
childrenReactNode-The item label.
iconReactNode-Decorative icon before the label.
endAdornmentReactNode-Content after the label, such as an icon.

Also accepts Base UI Menu.LinkItem props.

ProjectSwitcher.Separator

PropTypeDefaultDescription
orientation'horizontal'-Only horizontal is supported.

Also accepts Base UI Menu props.