npm package: @gsa-tts/graymatter-ui
Description: A comprehensive UI component library built with Svelte 5, providing reusable components, layouts, and utilities for modern web applications.
Latest version: 0.5.1

# @gsa-tts/graymatter-ui

A comprehensive UI component library built with Svelte 5, providing reusable components, layouts, and utilities for modern web applications.

## Package Responsibilities

The GrayMatter UI package (`@gsa-tts/graymatter-ui`) is a UI component library that provides:

### Primary Responsibilities:

- **Reusable UI Components** - A comprehensive set of accessible, customizable components
- **Design System Implementation** - Built using tokens from `@gsa-tts/graymatter-style-tokens`
- **Layout Components** - Consistent page structures and navigation patterns
- **Utility Functions** - Helper functions for UI-related operations
- **Cross-Framework Support** - Components available as both Svelte components and web components

### Package Boundaries:

- **SHOULD** contain UI components, layouts, and styles
- **SHOULD** consume design tokens from the style-tokens package
- **SHOULD** be framework-agnostic where possible (via web components)
- **SHOULD NOT** contain application-specific business logic
- **SHOULD NOT** contain data fetching or API integration code
- **SHOULD NOT** depend on application-specific packages

## Installation

```bash
npm install @gsa-tts/graymatter-ui @gsa-tts/graymatter-style-tokens
```

**Note:** The `@gsa-tts/graymatter-style-tokens` package is required for proper styling and design tokens.

## Usage

The UI package can be used in two ways:

### 1. Svelte Components (for Svelte/Astro applications)

```svelte
<script>
  import { DesktopSideNav, ProfileMenu } from '@gsa-tts/graymatter-ui';
</script>

<DesktopSideNav showAppIcons={true} ssrSelectedItem="api">
  <!-- Sub navigation content -->
</DesktopSideNav>
```

### 2. Utility Functions

For utility functions like navigation control, use the dedicated `/utils` import path:

```javascript
// ✅ Recommended for Svelte-only projects
import { toggleNavigation } from '@gsa-tts/graymatter-ui/utils';

// ❌ Avoid this in Svelte-only projects (may cause build issues)
import { toggleNavigation } from '@gsa-tts/graymatter-ui';
```

**Note:** The `/utils` path only exports TypeScript files and doesn't pull in Astro components, making it safe for Svelte-only projects that don't have Astro configured in their build system.

### 3. Web Components (for any framework or vanilla JS)

```html
<graymatter-desktop-side-nav show-app-icons="true" ssr-selected-item="api">
  <!-- Sub navigation content -->
</graymatter-desktop-side-nav>
```

## Navigation URL Configuration

Navigation components (`DesktopSideNav`, `MobileBottomNav`) support flexible URL configuration via props:

### Option 1: Component Props (Recommended)
```svelte
<DesktopSideNav 
  showAppIcons={true}
  hideDiscover={false}
  apiUrl="https://custom-api.com"
  chatUrl="https://custom-chat.com"
  consoleUrl="https://custom-console.com"
  discoverUrl="https://custom-discover.com"
>
  <!-- Sub navigation content -->
</DesktopSideNav>
```

### Option 2: Minimal Usage (Uses # fallbacks)
```svelte
<DesktopSideNav showAppIcons={true}>
  <!-- All navigation links will use # as href -->
</DesktopSideNav>
```

### Option 3: Mixed Approach
```svelte
<DesktopSideNav 
  showAppIcons={true}
  apiUrl="https://custom-api.com"
  <!-- chatUrl, consoleUrl, discoverUrl will fallback to # -->
>
  <!-- Sub navigation content -->
</DesktopSideNav>
```

**Fallback Behavior:** When no URL is provided for a navigation item, it will use `#` as the href, preventing navigation and keeping users on the current page.

### Discover Icon Control

The discover icon can be conditionally shown/hidden using the `hideDiscover` prop for both desktop and mobile navigation:

```svelte
<!-- Hide discover icon (default) -->
<DesktopSideNav showAppIcons={true} hideDiscover={true}>
<MobileBottomNav showAppIcons={true} hideDiscover={true}>

<!-- Show discover icon -->
<DesktopSideNav showAppIcons={true} hideDiscover={false}>
<MobileBottomNav showAppIcons={true} hideDiscover={false}>
```

**Note:** The discover icon is hidden by default (`hideDiscover={true}`) since the discover page may not be available in all deployments. This gives you control over when to enable the discover functionality across all consuming applications.

## Available Components

### Web Components (Universal - Any Framework)

All components with `.webcomponent.svelte` extension are available as web components:

- `graymatter-desktop-side-nav` - Desktop sidebar navigation
- `graymatter-mobile-top-nav` - Mobile header navigation  
- `graymatter-mobile-bottom-nav` - Mobile bottom navigation bar
- `graymatter-mobile-side-menu` - Mobile slide-out navigation menu
- `graymatter-desktop-header` - Desktop header component
- `graymatter-button` - Accessible button component
- `graymatter-logo` - Brand logo component

### Svelte 5 Components

Available for Svelte, SvelteKit, and Astro applications:

```javascript
import { 
  // Navigation Components
  DesktopSideNav,
  MobileTopNav,
  MobileBottomNav,
  MobileSideMenu,
  DesktopHeader,
  
  // UI Components
  Button,
  Logo,
  ProfileMenu,
  
  // Utility Components
  UsaBanner,
  UsaSkipNav,
  NavigationInitializer,
  
  // Icon Components
  // (all icons from ./icons/index.js)
} from '@gsa-tts/graymatter-ui/components';
```

### Astro Components

Available for Astro applications:

```javascript
import { 
  Head,
  BaseLayout,
  GlobalAppLayout
} from '@gsa-tts/graymatter-ui/layouts';
```

## Component Categories

### Navigation Components
- **DesktopSideNav** - Desktop sidebar navigation with external control support
- **MobileTopNav** - Mobile header navigation
- **MobileBottomNav** - Mobile bottom navigation bar
- **MobileSideMenu** - Mobile slide-out navigation menu

### Layout Components
- **GlobalAppLayout** - Main application layout wrapper
- **BaseLayout** - Base page layout structure
- **DocsLayout** - Documentation layout with dynamic navigation (Astro only)

### UI Components
- **ProfileMenu** - User profile dropdown menu with event-driven actions
- **Button** - Accessible button component with multiple variants
- **Logo** - Brand logo component

### Utility Components
- **UsaBanner** - Government banner component
- **UsaSkipNav** - Skip navigation link for accessibility

### Utility Functions
Available via the `/utils` import path:

```javascript
import { toggleNavigation } from '@gsa-tts/graymatter-ui/utils';
```

- **toggleNavigation()** - Toggle desktop navigation visibility
- **controlDesktopNavigation()** - Advanced navigation control

## Key Features

### Event-Driven Architecture
Many components use custom events for external control and communication:

- **DesktopSideNav** - External control via `graymatter-desktop-nav-control` events
- **ProfileMenu** - Action handling via `profileMenuAction` events

### Cross-App Communication
Components support communication between different applications:

- **Navigation Control** - Control desktop navigation from external apps
- **Event Bubbling** - Events work across Shadow DOM boundaries

### Accessibility
- **WCAG 2.1 AA Compliant** - Built with accessibility in mind
- **Keyboard Navigation** - Full keyboard support
- **Screen Reader Support** - Proper ARIA labels and roles

## Component Documentation

Detailed documentation for specific components is available in the package:

- **[NAVIGATION_CONTROL.md](https://github.com/GSA-TTS/usai-gov/blob/main/packages/ui/NAVIGATION_CONTROL.md)** - DesktopSideNav external control system with event-based API
- **[PROFILE_MENU.md](https://github.com/GSA-TTS/usai-gov/blob/main/packages/ui/PROFILE_MENU.md)** - ProfileMenu component usage and event handling
- **[README_DocsLayout.md](https://github.com/GSA-TTS/usai-gov/blob/main/packages/ui/README_DocsLayout.md)** - DocsLayout component with dynamic navigation generation (Astro only)

These files are also included with the package in your `node_modules/@gsa-tts/graymatter-ui/` directory. If you don't have access to the private repository, you can find the documentation files locally after installation.

## Framework Support

- **Svelte 5** - Native Svelte components (individual components only)
- **Astro** - Full support with client-side hydration (including DocsLayout)
- **React/Vue/Angular** - Via web components (individual components only)
- **Vanilla JavaScript** - Via web components (individual components only)

**Note:** The `DocsLayout` component is Astro-specific and cannot be used in other frameworks. For non-Astro applications, use the individual Svelte components and shared utilities instead.

## Troubleshooting

### Build Issues with Astro Files

If you're getting build errors related to Astro files in a Svelte-only project, use the dedicated import paths:

```javascript
// ✅ For Svelte-only projects using web components
import { toggleNavigation } from '@gsa-tts/graymatter-ui/utils';
// Use web components in HTML: <graymatter-button>, <graymatter-logo>, etc.

// ❌ Avoid in Svelte-only projects
import { toggleNavigation } from '@gsa-tts/graymatter-ui';
```

**Common Error:** `Unexpected token '{'. Expected '.' or '('` when importing from the main package in Svelte-only projects.

**Solution:** Use the `/utils` path for utility functions. For UI components, use web components instead of importing Svelte components directly.

## Browser Support

- **Modern Browsers** - Chrome, Firefox, Safari, Edge (latest 2 versions)
- **Web Components** - Native support or polyfill required
- **Custom Events** - Native support in all modern browsers