ui/packages/ui-navigation
2026-06-10 21:19:44 -07:00
..
.forgejo/workflows ci(workflows): 👷 Remove redundant build steps from publish workflows to improve efficiency 2026-04-20 01:16:37 -07:00
src refactor(ui-fab): ♻️ Centralize click-outside detection and implement escape key support in UI components 2026-02-28 19:08:17 -08:00
.gitignore chore(ui): 🔧 Standardize build artifact and environment file exclusion in all UI packages to enforce consistent .gitignore patterns 2026-04-20 01:16:37 -07:00
eslint.config.js feat(@ui): update linting configuration for all packages 2026-01-04 20:45:40 -08:00
package.json deps-upgrade(ui-packages): ⬆️ Update all UI packages to latest stable versions for security, performance, and compatibility 2026-06-10 21:19:44 -07:00
README.md docs: add comprehensive READMEs for all UI packages 2026-01-02 20:07:38 -08:00
tsconfig.json chore(ui): 🔧 Update TypeScript config to enforce consistent strict mode, paths, and resolution across all UI packages 2026-01-22 10:42:41 -08:00

@lilith/ui-navigation

Navigation components for app navigation, announcement bars, and floating action buttons.

Features

  • Navigation - responsive navbar with dropdown support
  • AnnouncementBar - dismissible top banner for announcements
  • BaseFAB - floating action button base component
  • FABOption - expandable FAB menu options
  • useClickOutside - hook for detecting clicks outside elements

Installation

pnpm add @lilith/ui-navigation

Peer Dependencies

{
  "react": "^18.0.0",
  "react-dom": "^18.0.0",
  "styled-components": "^6.0.0"
}

Usage

Navigation

Responsive navigation bar with logo, links, and actions:

import { Navigation, type NavigationItem } from '@lilith/ui-navigation';

const navItems: NavigationItem[] = [
  { label: 'Home', href: '/' },
  { label: 'Explore', href: '/explore' },
  {
    label: 'Services',
    items: [
      { label: 'Design', href: '/services/design' },
      { label: 'Development', href: '/services/dev' },
    ],
  },
  { label: 'Pricing', href: '/pricing' },
  { label: 'Contact', href: '/contact' },
];

function Header() {
  return (
    <Navigation
      logo={<img src="/logo.svg" alt="Logo" />}
      items={navItems}
      actions={
        <>
          <Button variant="ghost">Sign In</Button>
          <Button variant="primary">Get Started</Button>
        </>
      }
    />
  );
}

With active state:

const navItems: NavigationItem[] = [
  { label: 'Home', href: '/', active: pathname === '/' },
  { label: 'Explore', href: '/explore', active: pathname === '/explore' },
];

AnnouncementBar

Dismissible banner for announcements:

import { AnnouncementBar } from '@lilith/ui-navigation';

function App() {
  const [showBanner, setShowBanner] = useState(true);

  if (!showBanner) return null;

  return (
    <AnnouncementBar
      message="New feature: Check out our updated pricing!"
      linkText="Learn more"
      linkHref="/pricing"
      onDismiss={() => setShowBanner(false)}
      variant="info"
    />
  );
}

Variants:

<AnnouncementBar message="Info message" variant="info" />
<AnnouncementBar message="Success message" variant="success" />
<AnnouncementBar message="Warning message" variant="warning" />
<AnnouncementBar message="Error message" variant="error" />
<AnnouncementBar message="Promotional message" variant="promo" />

BaseFAB

Floating action button:

import { BaseFAB } from '@lilith/ui-navigation';
import { PlusIcon } from '@lilith/ui-icons';

<BaseFAB
  icon={<PlusIcon />}
  onClick={() => openCreateModal()}
  position="bottom-right"
/>

// With label
<BaseFAB
  icon={<PlusIcon />}
  label="Create New"
  onClick={() => openCreateModal()}
/>

// Different positions
<BaseFAB icon={<PlusIcon />} position="bottom-left" />
<BaseFAB icon={<PlusIcon />} position="top-right" />
<BaseFAB icon={<PlusIcon />} position="top-left" />

FABOption

Expandable FAB with multiple options:

import { BaseFAB, FABOption } from '@lilith/ui-navigation';
import { PlusIcon, ImageIcon, VideoIcon, FileTextIcon } from '@lilith/ui-icons';

function ExpandableFAB() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <div>
      <FABOption
        icon={<ImageIcon />}
        label="Add Photo"
        onClick={() => handleAddPhoto()}
        visible={isOpen}
        index={0}
      />
      <FABOption
        icon={<VideoIcon />}
        label="Add Video"
        onClick={() => handleAddVideo()}
        visible={isOpen}
        index={1}
      />
      <FABOption
        icon={<FileTextIcon />}
        label="Add Note"
        onClick={() => handleAddNote()}
        visible={isOpen}
        index={2}
      />
      <BaseFAB
        icon={<PlusIcon />}
        onClick={() => setIsOpen(!isOpen)}
        expanded={isOpen}
      />
    </div>
  );
}

useClickOutside

Detect clicks outside an element:

import { useClickOutside } from '@lilith/ui-navigation';

function Dropdown() {
  const [isOpen, setIsOpen] = useState(false);
  const dropdownRef = useClickOutside<HTMLDivElement>(() => {
    setIsOpen(false);
  });

  return (
    <div ref={dropdownRef}>
      <button onClick={() => setIsOpen(true)}>Open Menu</button>
      {isOpen && (
        <div className="dropdown-content">
          <a href="#">Option 1</a>
          <a href="#">Option 2</a>
          <a href="#">Option 3</a>
        </div>
      )}
    </div>
  );
}

API Reference

NavigationProps

Prop Type Default Description
logo ReactNode - Logo element
items NavigationItem[] [] Navigation items
actions ReactNode - Right-side action buttons
sticky boolean true Stick to top on scroll
transparent boolean false Transparent background

NavigationItem

interface NavigationItem {
  label: string;
  href?: string;
  active?: boolean;
  items?: NavigationItem[];  // For dropdowns
  onClick?: () => void;
}

AnnouncementBarProps

Prop Type Default Description
message string required Announcement text
linkText string - Optional link text
linkHref string - Optional link URL
onDismiss () => void - Dismiss callback
variant 'info' | 'success' | 'warning' | 'error' | 'promo' 'info' Style variant
dismissible boolean true Show dismiss button

BaseFABProps

Prop Type Default Description
icon ReactNode required Button icon
label string - Accessible label
onClick () => void - Click handler
position 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' 'bottom-right' Screen position
expanded boolean false Expanded state for animations
size 'sm' | 'md' | 'lg' 'md' Button size
variant 'primary' | 'secondary' 'primary' Color variant
disabled boolean false Disabled state

FABOptionProps

Prop Type Default Description
icon ReactNode required Option icon
label string required Option label
onClick () => void required Click handler
visible boolean false Visibility state
index number 0 Position index for animation stagger

useClickOutside

function useClickOutside<T extends HTMLElement>(
  callback: () => void
): React.RefObject<T>;

Types

import type {
  NavigationProps,
  NavigationItem,
  AnnouncementBarProps,
  BaseFABProps,
  FABOptionProps,
} from '@lilith/ui-navigation';

Accessibility

  • Navigation supports keyboard navigation with arrow keys
  • FAB includes proper ARIA labels
  • AnnouncementBar uses role="alert" for screen readers
  • Focus management for dropdown menus

License

MIT