@glamcor/dna-shared-nav
v1.0.0
Published
Shared navigation component for DNA microsites
Downloads
82
Maintainers
Readme
DNA Shared Navigation
Universal navigation component for all DNA microsites. Provides a consistent two-row navigation header across Dashboard, SPOT, Water, Pulse, Hydrogen, and Oxygen apps.
Architecture
The navigation consists of two rows (80px total height):
Row 1 - Header (44px): [DNA Logo] [Inter-app Nav: Dashboard | SPOT | Water | Pulse | Hydrogen | Oxygen] [Avatar]
Row 2 - App Subnav (36px): [App Name] [App-specific pages] ......................... [Pinned Jobs →]- Header: Logo links to Dashboard, inter-app navigation for switching between DNA apps, avatar menu with user info and logout
- App Subnav: Current app name, app-specific page links, pinned jobs carousel (right-aligned)
Installation
In a DNA monorepo workspace, add to your app's package.json:
{
"dependencies": {
"dna-shared-nav": "*"
}
}Then run npm install from the monorepo root.
Usage
Basic Setup
import { DNANavigation } from 'dna-shared-nav';
import 'dna-shared-nav/dist/styles.css';
export function Layout({ children }) {
const user = {
id: '1',
email: '[email protected]',
name: 'John Doe',
role: 'admin',
};
return (
<>
<DNANavigation
user={user}
currentApp="Water"
appName="Water"
subnavItems={[
{ name: 'Dashboard', href: '/water', isActive: true },
{ name: 'Customers', href: '/water/customers' },
{ name: 'Jobs', href: '/water/jobs' },
{ name: 'Analytics', href: '/water/analytics' },
]}
onLogout={() => signOut()}
/>
<main>{children}</main>
</>
);
}With Pinned Jobs
Pinned jobs appear on the right side of the app subnav. They show progress rings and support a carousel when there are more than 2 jobs.
<DNANavigation
user={user}
currentApp="Water"
appName="Water"
subnavItems={subnavItems}
pinnedJobs={[
{
id: '1',
appName: 'Water',
appColor: '#38bdf8',
jobName: 'Q4 Data Enrichment',
progress: 59,
},
{
id: '2',
appName: 'SPOT',
appColor: '#a78bfa',
jobName: 'Lead Scoring Batch',
progress: 23,
},
]}
onUnpinJob={(jobId) => handleUnpin(jobId)}
onLogout={() => signOut()}
/>Props
DNANavigationProps
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| user | DNAUser \| null | Yes | Current user object, or null if not logged in |
| currentApp | string | No | Name of active app in header nav (e.g., "Water", "SPOT") |
| appName | string | Yes | Display name shown in app subnav |
| headerItems | DNANavItem[] | No | Override default inter-app navigation items |
| subnavItems | AppSubnavItem[] | Yes | App-specific page links |
| pinnedJobs | PinnedJob[] | No | Jobs to show in pinned carousel |
| logoSrc | string | No | Custom logo image URL (defaults to "DNA" text) |
| onLogout | () => void | No | Callback when user clicks logout |
| onUnpinJob | (jobId: string) => void | No | Callback when user unpins a job |
DNAUser
interface DNAUser {
id: string;
email: string;
name: string;
role?: 'superadmin' | 'admin' | 'editor' | 'viewer';
avatar?: string;
}AppSubnavItem
interface AppSubnavItem {
name: string; // Display text
href: string; // Link URL
isActive?: boolean; // Highlight as current page
}PinnedJob
interface PinnedJob {
id: string;
appName: string; // Short name (e.g., "Water", "SPOT")
appColor?: string; // Hex color for progress ring (e.g., '#38bdf8')
jobName: string; // Job display name
progress: number; // 0-100 percentage
meta?: string; // Optional metadata (e.g., "142 / 240 records")
}Environment Variables
The default inter-app navigation uses these environment variables for URLs:
NEXT_PUBLIC_DNA_DASHBOARD_URL=https://dashboard.dna.example.com
NEXT_PUBLIC_SPOT_URL=https://spot.dna.example.com
NEXT_PUBLIC_DNA_WATER_URL=https://water.dna.example.com
NEXT_PUBLIC_DNA_PULSE_URL=https://pulse.dna.example.com
NEXT_PUBLIC_DNA_HYDROGEN_URL=https://hydrogen.dna.example.com
NEXT_PUBLIC_DNA_OXYGEN_URL=https://oxygen.dna.example.comIf not set, links fall back to relative paths (/, /spot, /water, etc.).
App Colors
Recommended colors for each app's pinned jobs:
| App | Color | Hex |
|-----|-------|-----|
| Water | Sky Blue | #38bdf8 |
| SPOT | Purple | #a78bfa |
| Pulse | Rose | #fb7185 |
| Hydrogen | Emerald | #34d399 |
| Oxygen | Amber | #fbbf24 |
Individual Components
For advanced use cases, you can import components individually:
import { DNAHeader, AppSubnav, PinnedJobs, AvatarMenu } from 'dna-shared-nav';Styling
The navigation uses CSS classes prefixed with dna-, app-subnav-, and pinned-. Styles require these fonts:
- DM Sans - Primary text
- JetBrains Mono - Logo, progress values
Add to your app's <head>:
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600&family=JetBrains+Mono:wght@500;600&display=swap" rel="stylesheet">Role-Based Navigation
Navigation items can be restricted by role. The role hierarchy is:
viewer < editor < admin < superadmin
const headerItems = [
{ name: 'Dashboard', href: '/' },
{ name: 'Admin', href: '/admin', requiredRole: 'admin' }, // Only admin+ see this
];
<DNANavigation headerItems={headerItems} ... />