Navigation
Inputs & Forms
Selection
Containers & Overlays
Context Switcher
Switches the workspace, project or version all pages refer to.
Overview
The ContextSwitcher switches the context all pages refer to, e.g. organization, project or version. Several items can be combined for hierarchical or independent contexts. Switching is controlled from outside. The version switch in the bar of this documentation is one.
///
"use client";import React, {useState} from "react";import {ContextSwitcher, ContextSwitcherMenu, ContextSwitcherMenuItem} from "@brynlabs/fusion-ui";const projectsMenu: ContextSwitcherMenu = {sections: [{title: "Projects",items: [{id: "alpha",title: "Alpha",},{id: "beta",title: "Beta",},{id: "gamma",title: "Gamma",},],},],};const workspacesMenu: ContextSwitcherMenu = {sections: [{title: "Workspaces",items: [{id: "workspace-a",title: "Workspace A",},{id: "workspace-b",title: "Workspace B",},],},],};const pagesMenu: ContextSwitcherMenu = {sections: [{title: "Pages",items: [{id: "overview",title: "Overview",},{id: "items",title: "Items",},{id: "settings",title: "Settings",},],},],};export const ContextSwitcherExample = () => {const [project, setProject] = useState<ContextSwitcherMenuItem>(projectsMenu.sections[0]!.items[0]!,);const [workspace, setWorkspace] = useState<ContextSwitcherMenuItem>(workspacesMenu.sections[0]!.items[0]!,);const [page, setPage] = useState<ContextSwitcherMenuItem>(pagesMenu.sections[0]!.items[0]!);return (<ContextSwitcher><ContextSwitcher.Item menu={projectsMenu} activeItem={project} onChange={setProject} /><ContextSwitcher.Item menu={workspacesMenu} activeItem={workspace} onChange={setWorkspace} /><ContextSwitcher.Item menu={pagesMenu} activeItem={page} onChange={setPage} /></ContextSwitcher>);};
Image & icon
image and icon show a picture, an icon or both in the switch and in the menu.
//
"use client";import React, {useState} from "react";import {ContextSwitcher, ContextSwitcherMenu, ContextSwitcherMenuItem} from "@brynlabs/fusion-ui";const iconMenu: ContextSwitcherMenu = {sections: [{title: "Zuletzt verwendet",items: [{id: "recent-consent",title: "Consent",subtitle: "consent.website.com",icon: "π",},{id: "recent-website-cms",title: "Website CMS",subtitle: "consent.website.com",icon: "ποΈ",},],},{title: "Anwendungen",items: [{id: "applications-consent",title: "Consent",subtitle: "consent.website.com",icon: "π",},{id: "applications-website-cms",title: "Website CMS",subtitle: "consent.website.com",icon: "ποΈ",},{id: "digital-assets",title: "Digital Assets",subtitle: "dam.website.com",icon: "π",},{id: "business-account",title: "My Business Account",icon: "π€",},],},],};const imageMenu: ContextSwitcherMenu = {sections: [{title: "Zuletzt verwendet",items: [{id: "recent-consent",title: "Consent",subtitle: "consent.website.com",image: "/test-avatar.png",},{id: "recent-website-cms",title: "Website CMS",subtitle: "consent.website.com",image: "/test-avatar.png",},],},{title: "Anwendungen",items: [{id: "applications-consent",title: "Consent",subtitle: "consent.website.com",image: "/test-avatar.png",},{id: "applications-website-cms",title: "Website CMS",subtitle: "consent.website.com",image: "/test-avatar.png",},{id: "digital-assets",title: "Digital Assets",subtitle: "dam.website.com",image: "/test-avatar.png",},{id: "business-account",title: "My Business Account",image: "/test-avatar.png",},],},],};const bothMenu: ContextSwitcherMenu = {sections: [{title: "Zuletzt verwendet",items: [{id: "recent-consent",title: "Consent",subtitle: "consent.website.com",image: "/test-avatar.png",icon: "π",},{id: "recent-website-cms",title: "Website CMS",subtitle: "consent.website.com",image: "/test-avatar.png",icon: "ποΈ",},],},{title: "Anwendungen",items: [{id: "applications-consent",title: "Consent",subtitle: "consent.website.com",image: "/test-avatar.png",icon: "π",},{id: "applications-website-cms",title: "Website CMS",subtitle: "consent.website.com",image: "/test-avatar.png",icon: "ποΈ",},{id: "digital-assets",title: "Digital Assets",subtitle: "dam.website.com",image: "/test-avatar.png",icon: "π",},{id: "business-account",title: "My Business Account",image: "/test-avatar.png",icon: "π€",},],},],};export const ContextSwitcherImageIconExample = () => {const [iconItem, setIconItem] = useState<ContextSwitcherMenuItem>(iconMenu.sections[0]!.items[0]!,);const [imageItem, setImageItem] = useState<ContextSwitcherMenuItem>(imageMenu.sections[0]!.items[0]!,);const [bothItem, setBothItem] = useState<ContextSwitcherMenuItem>(bothMenu.sections[0]!.items[0]!,);return (<ContextSwitcher startWithSeparator={false}><ContextSwitcher.Item menu={iconMenu} activeItem={iconItem} onChange={setIconItem} /><ContextSwitcher.Item menu={imageMenu} activeItem={imageItem} onChange={setImageItem} /><ContextSwitcher.Item menu={bothMenu} activeItem={bothItem} onChange={setBothItem} /></ContextSwitcher>);};
Dynamic contexts
The items and their menus are derived from state outside the component.
///
"use client";import React, {useMemo, useState} from "react";import {ContextSwitcher, ContextSwitcherMenu, ContextSwitcherMenuItem} from "@brynlabs/fusion-ui";const projectsMenu: ContextSwitcherMenu = {sections: [{title: "Projects",items: [{id: "alpha",title: "Alpha",},{id: "beta",title: "Beta",},{id: "gamma",title: "Gamma",},{id: "delta",title: "Delta",},],},],};const alphaWorkspacesMenu: ContextSwitcherMenu = {sections: [{title: "Workspaces",items: [{id: "workspace-a",title: "Workspace A",},{id: "workspace-b",title: "Workspace B",},],},],};const betaWorkspacesMenu: ContextSwitcherMenu = {sections: [{title: "Workspaces",items: [{id: "workspace-a",title: "Workspace A",},{id: "workspace-c",title: "Workspace C",},],},],};const gammaWorkspacesMenu: ContextSwitcherMenu = {sections: [{title: "Workspaces",items: [{id: "workspace-d",title: "Workspace D",},],},],};const pagesMenu: ContextSwitcherMenu = {sections: [{title: "Pages",items: [{id: "overview",title: "Overview",},{id: "items",title: "Items",},{id: "settings",title: "Settings",},],},],};const limitedPagesMenu: ContextSwitcherMenu = {sections: [{title: "Pages",items: [{id: "overview",title: "Overview",},{id: "settings",title: "Settings",},],},],};const getFirstItem = (menu: ContextSwitcherMenu) =>menu.sections.flatMap(section => section.items)[0];const findItem = (menu: ContextSwitcherMenu, item?: ContextSwitcherMenuItem) => {if (!item) return undefined;return menu.sections.flatMap(section => section.items).find(candidate => candidate.id === item.id);};export const ContextSwitcherDynamicExample = () => {const [project, setProject] = useState<ContextSwitcherMenuItem>(projectsMenu.sections[0]!.items[0]!,);const [workspace, setWorkspace] = useState<ContextSwitcherMenuItem>(alphaWorkspacesMenu.sections[0]!.items[0]!,);const [page, setPage] = useState<ContextSwitcherMenuItem>(pagesMenu.sections[0]!.items[0]!);const workspaceMenu = useMemo(() => {switch (project.id) {case "alpha":return alphaWorkspacesMenu;case "beta":return betaWorkspacesMenu;case "gamma":return gammaWorkspacesMenu;default:return undefined;}}, [project]);const pageMenu = useMemo(() => {if (!workspaceMenu) return undefined;switch (workspace.id) {case "workspace-a":return pagesMenu;case "workspace-b":return limitedPagesMenu;case "workspace-c":return pagesMenu;default:return undefined;}}, [workspaceMenu, workspace]);const handleProjectChange = (nextProject: ContextSwitcherMenuItem) => {setProject(nextProject);let nextWorkspaceMenu: ContextSwitcherMenu | undefined;switch (nextProject.id) {case "alpha":nextWorkspaceMenu = alphaWorkspacesMenu;break;case "beta":nextWorkspaceMenu = betaWorkspacesMenu;break;case "gamma":nextWorkspaceMenu = gammaWorkspacesMenu;break;}if (!nextWorkspaceMenu) return;const nextWorkspace = findItem(nextWorkspaceMenu, workspace) ?? getFirstItem(nextWorkspaceMenu);if (!nextWorkspace) return;setWorkspace(nextWorkspace);let nextPageMenu: ContextSwitcherMenu | undefined;switch (nextWorkspace.id) {case "workspace-a":case "workspace-c":nextPageMenu = pagesMenu;break;case "workspace-b":nextPageMenu = limitedPagesMenu;break;}if (!nextPageMenu) return;const nextPage = findItem(nextPageMenu, page) ?? getFirstItem(nextPageMenu);if (nextPage) {setPage(nextPage);}};const handleWorkspaceChange = (nextWorkspace: ContextSwitcherMenuItem) => {setWorkspace(nextWorkspace);let nextPageMenu: ContextSwitcherMenu | undefined;switch (nextWorkspace.id) {case "workspace-a":case "workspace-c":nextPageMenu = pagesMenu;break;case "workspace-b":nextPageMenu = limitedPagesMenu;break;}if (!nextPageMenu) return;const nextPage = findItem(nextPageMenu, page) ?? getFirstItem(nextPageMenu);if (nextPage) {setPage(nextPage);}};return (<ContextSwitcher><ContextSwitcher.Itemmenu={projectsMenu}activeItem={project}onChange={handleProjectChange}/>{workspaceMenu && (<ContextSwitcher.Itemmenu={workspaceMenu}activeItem={workspace}onChange={handleWorkspaceChange}/>)}{pageMenu && <ContextSwitcher.Item menu={pageMenu} activeItem={page} onChange={setPage} />}</ContextSwitcher>);};

