Draw the sidebar with Reicon glyphs
Navigation icons now come from reicon-react (tree-shaken SVG components, currentColor by default): Home, Briefcase, Users, ChatRoundDots, Send, Folder, ShieldCheck, DocumentText2, Plug2, Buildings2, and Gear map to their routes through one NavIcon component, so the glyph set lives in a single place and NavSpec no longer carries per-item icon names.
This commit is contained in:
1 parent
a11d2dfa07
commit
4775b23d94
4 files changed
+73
-14
No files matched your search
@@ -34,6 +34,7 @@
|
||||
"lucide-react": "0.468.0",
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4",
|
||||
"reicon-react": "^1.1.2",
|
||||
"zod": "4.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
Generated
+25
@@ -23,6 +23,9 @@ importers:
|
||||
react-dom:
|
||||
specifier: 19.2.4
|
||||
version: 19.2.4(react@19.2.4)
|
||||
reicon-react:
|
||||
specifier: ^1.1.2
|
||||
version: 1.1.2(react@19.2.4)
|
||||
zod:
|
||||
specifier: 4.3.6
|
||||
version: 4.3.6
|
||||
@@ -707,66 +710,79 @@ packages:
|
||||
resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.60.4':
|
||||
resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.60.4':
|
||||
resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.60.4':
|
||||
resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-loong64-gnu@4.60.4':
|
||||
resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-loong64-musl@4.60.4':
|
||||
resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.60.4':
|
||||
resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-musl@4.60.4':
|
||||
resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.60.4':
|
||||
resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.60.4':
|
||||
resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.60.4':
|
||||
resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.60.4':
|
||||
resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.60.4':
|
||||
resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-openbsd-x64@4.60.4':
|
||||
resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==}
|
||||
@@ -2164,6 +2180,11 @@ packages:
|
||||
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
reicon-react@1.1.2:
|
||||
resolution: {integrity: sha512-dbp1CPEPKFjWfG41lGRMWi74YKfKJlb2JcB/TRBAUQF6jalZYW1dRZisRPCpze5TfQwRBD30p40qnoY+oYi7MQ==}
|
||||
peerDependencies:
|
||||
react: '>=16.8.0'
|
||||
|
||||
require-directory@2.1.1:
|
||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -4824,6 +4845,10 @@ snapshots:
|
||||
string_decoder: 1.1.1
|
||||
util-deprecate: 1.0.2
|
||||
|
||||
reicon-react@1.1.2(react@19.2.4):
|
||||
dependencies:
|
||||
react: 19.2.4
|
||||
|
||||
require-directory@2.1.1: {}
|
||||
|
||||
require-from-string@2.0.2: {}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import {
|
||||
Briefcase,
|
||||
Buildings2,
|
||||
ChatRoundDots,
|
||||
DocumentText2,
|
||||
Folder,
|
||||
Gear,
|
||||
Home,
|
||||
Plug2,
|
||||
Send,
|
||||
ShieldCheck,
|
||||
Users,
|
||||
} from "reicon-react";
|
||||
import type { RouteId } from "./Shell";
|
||||
|
||||
/** One glyph per navigation surface, from the Reicon set. */
|
||||
const NAV_ICONS: Record<RouteId, typeof Home> = {
|
||||
home: Home,
|
||||
work: Briefcase,
|
||||
team: Users,
|
||||
chat: ChatRoundDots,
|
||||
runs: Send,
|
||||
files: Folder,
|
||||
approvals: ShieldCheck,
|
||||
docs: DocumentText2,
|
||||
social: Plug2,
|
||||
office: Buildings2,
|
||||
settings: Gear,
|
||||
};
|
||||
|
||||
export function NavIcon({ route, size = 18 }: { route: RouteId; size?: number }) {
|
||||
const Glyph = NAV_ICONS[route];
|
||||
return <Glyph size={size} />;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useState, type ReactNode } from "react";
|
||||
import type { AppSnapshot } from "../../../shared/domain";
|
||||
import { Avatar, Icon, IconButton } from "./ui";
|
||||
import type { IconName } from "./Icon";
|
||||
import { NavIcon } from "./NavIcon";
|
||||
import { OrgSwitcher } from "./OrgSwitcher";
|
||||
import { SearchDialog } from "./SearchDialog";
|
||||
import { TopbarSlotContext } from "./topbar-context";
|
||||
@@ -22,7 +22,6 @@ export type RouteId =
|
||||
interface NavSpec {
|
||||
id: RouteId;
|
||||
label: string;
|
||||
icon: IconName;
|
||||
}
|
||||
|
||||
/** Routes whose pages own a full-height, multi-pane layout with their own
|
||||
@@ -31,20 +30,20 @@ const FLUSH_ROUTES = new Set<RouteId>(["chat", "settings", "files", "social", "r
|
||||
|
||||
/** The daily-driver surfaces — the core operating loop. */
|
||||
const primaryNav: NavSpec[] = [
|
||||
{ id: "home", label: "Home", icon: "home" },
|
||||
{ id: "work", label: "Work", icon: "work" },
|
||||
{ id: "team", label: "Team", icon: "team" },
|
||||
{ id: "chat", label: "Messages", icon: "chat" },
|
||||
{ id: "runs", label: "Runs", icon: "send" },
|
||||
{ id: "files", label: "Files", icon: "folder" },
|
||||
{ id: "approvals", label: "Approvals", icon: "approve" },
|
||||
{ id: "home", label: "Home" },
|
||||
{ id: "work", label: "Work" },
|
||||
{ id: "team", label: "Team" },
|
||||
{ id: "chat", label: "Messages" },
|
||||
{ id: "runs", label: "Runs" },
|
||||
{ id: "files", label: "Files" },
|
||||
{ id: "approvals", label: "Approvals" },
|
||||
];
|
||||
|
||||
/** Less-frequent surfaces, demoted under a divider so the primary set leads. */
|
||||
const secondaryNav: NavSpec[] = [
|
||||
{ id: "docs", label: "Documents", icon: "file" },
|
||||
{ id: "social", label: "Social", icon: "social" },
|
||||
{ id: "office", label: "Office", icon: "team" },
|
||||
{ id: "docs", label: "Documents" },
|
||||
{ id: "social", label: "Social" },
|
||||
{ id: "office", label: "Office" },
|
||||
];
|
||||
|
||||
const allNav: NavSpec[] = [...primaryNav, ...secondaryNav];
|
||||
@@ -123,7 +122,7 @@ export function Shell({
|
||||
className={`nav-item ${route === "settings" ? "active" : ""}`.trim()}
|
||||
onClick={() => setRoute("settings")}
|
||||
>
|
||||
<span className="icon-box"><Icon name="settings" size={18} /></span>
|
||||
<span className="icon-box"><NavIcon route="settings" /></span>
|
||||
<span>Settings</span>
|
||||
</button>
|
||||
</nav>
|
||||
@@ -184,7 +183,7 @@ function NavButton({
|
||||
className={`nav-item ${active ? "active" : ""}`.trim()}
|
||||
onClick={() => onSelect(item.id)}
|
||||
>
|
||||
<span className="icon-box"><Icon name={item.icon} size={18} /></span>
|
||||
<span className="icon-box"><NavIcon route={item.id} /></span>
|
||||
<span>{item.label}</span>
|
||||
{renderBadge(badge)}
|
||||
</button>
|
||||
|
||||
Reference in new issue
Block a user