UI Library Overview
@elcto/ui is a shared React component library for Heimdall applications. It provides a consistent design system with reusable components, design tokens, and utilities.
Installation
The UI library is part of the monorepo workspace. It's automatically available to all platform apps.
For Platform Apps
Add the dependency to your package.json:
{
"dependencies": {
"@elcto/ui": "workspace:*"
}
}
Then run:
pnpm install
Next.js Configuration
Add the package to transpilePackages in your next.config.ts:
const nextConfig: NextConfig = {
transpilePackages: ["@elcto/ui"],
// ... other config
};
Import Styles
Import the design tokens and component styles in your globals.css:
@import "tailwindcss";
@import "@elcto/ui/styles/tokens.css";
@import "@elcto/ui/styles/components.css";
/* Tell Tailwind to scan the shared UI library for classes */
@source "../../../../shared/ui/src/**/*.tsx";
Usage
Importing Components
// Import from components
import { Button, Modal, Alert } from "@elcto/ui/components";
// Import utilities
import { cn } from "@elcto/ui/utils";
Re-exporting in Your App
Create a local components/ui/index.ts to re-export shared components:
// Re-export from shared UI library
export {
Button,
Modal,
Alert,
// ... other components
} from "@elcto/ui/components";
// Re-export cn utility
export { cn } from "@elcto/ui/utils";
Then import from your local module:
import { Button, Alert } from "@/components/ui";
Package Structure
shared/ui/
├── package.json
├── tsconfig.json
└── src/
├── index.ts # Main barrel export
├── components/ # React components
│ ├── Alert/
│ ├── AnimatedBackground/
│ ├── ApiHealthBanner/
│ ├── AppSwitcher/
│ ├── AuditIcons/
│ ├── Avatar/
│ ├── Badge/
│ ├── Banner/
│ ├── BlurredText/
│ ├── Button/
│ ├── Card/
│ ├── CategorySelect/
│ ├── Checkbox/
│ ├── CodeInput/
│ ├── ColorPicker/
│ ├── CountrySelect/
│ ├── DateTimePicker/
│ ├── Dropdown/
│ ├── DropdownButton/
│ ├── FileUpload/
│ ├── FloatingInput/
│ ├── Icons/
│ ├── ImagePreview/
│ ├── Input/
│ ├── LanguageSwitcher/
│ ├── LoadingSpinner/
│ ├── Logo/
│ ├── Map/ # SSR-excluded — import from '@elcto/ui/map'
│ ├── Modal/
│ ├── PegelWidget/ # SSR-excluded — import from '@elcto/ui/widgets'
│ ├── SearchableSelect/
│ ├── Select/
│ ├── ServiceUnavailable/
│ ├── SubMenuBar/
│ ├── SubNav/
│ ├── Table/
│ ├── Toast/
│ ├── Toggle/
│ ├── Tooltip/
│ ├── Turnstile/
│ └── VesselMarker/ # SSR-excluded — browser-only subpath import
├── hooks/
│ └── index.ts # Custom hooks (browser-only)
├── lib/
│ ├── geocoding.ts # Geocoding helpers ('@elcto/ui/lib/geocoding')
│ └── ais-i18n.ts # AIS nav-status i18n ('@elcto/ui/lib/ais-i18n')
├── styles/
│ ├── tokens.css # CSS design tokens
│ └── components.css # Component utility classes
├── utils/
│ └── cn.ts # Class name utility
└── types/
└── index.ts # Shared types
The main components barrel (@elcto/ui/components) re-exports all SSR-safe
components. Map (and its sub-components), PegelWidget, and VesselMarker
depend on maplibre-gl and are excluded from the barrel — import them from
their dedicated subpaths to avoid SSR issues.
Features
- Dark Theme - Optimized for dark mode interfaces
- TypeScript - Full type safety with exported types
- Tailwind CSS - Built with Tailwind for consistency
- Accessible - ARIA attributes and keyboard navigation
- Composable - Flexible component APIs
Available Components
SSR-safe components
Re-exported from @elcto/ui/components:
| Component | Description |
|---|---|
| Alert | Status messages with variants |
| AnimatedBackground | Animated gradient background with particles |
| ApiHealthBanner | Real-time API health monitoring |
| AppSwitcher | App navigation dropdown |
| AuditIcon | Icons for audit events |
| Avatar | User avatar with fallback |
| Badge | Status badges and labels |
| Banner | Full-width notification banners |
| BlurredText | Privacy-aware text display |
| Button | Interactive buttons with variants |
| Card | Content containers (Card, ActionCard, StatusCard, InfoItem) |
| CategorySelect | Select grouped by category |
| Checkbox | Styled checkbox input |
| CodeInput | OTP/verification code input |
| ColorPicker | Color selection with presets |
| CountrySelect | Country selection with flags |
| DateTimePicker | Date, time, datetime picker |
| Dropdown | Dropdown menus |
| DropdownButton | Split button with dropdown options |
| FileUpload | File upload with dropzone and progress |
| FloatingInput | Inputs with floating labels |
| ImagePreview | Image thumbnails with lightbox |
| Input | Basic text input |
| LanguageSwitcher | Locale selection dropdown |
| LoadingSpinner & Spinner | Loading indicators |
| Logo | Brand logo components |
| Modal | Dialog windows |
| Platform Icons | SVG icons for platforms |
| SearchableSelect | Select with search filtering |
| Select | Custom dropdown select |
| ServiceUnavailable | 503 service unavailable page |
| SubMenuBar | Horizontal sub-navigation bar below header |
| SubNav | Nested navigation tabs |
| Table | Data tables with pagination |
| Toast | Toast notifications |
| Toggle | Switch-style toggle input |
| Tooltip | Hover tooltips |
| Turnstile | Cloudflare bot protection |
Map & SSR-excluded components
These depend on maplibre-gl and are not part of the @elcto/ui/components
barrel. Import them from their subpaths (or via next/dynamic with ssr: false):
| Component | Import from | Description |
|---|---|---|
| Map | @elcto/ui/map | MapLibre map container + useMap hook |
| LiveMarker | @elcto/ui/map | Animated live-position marker |
| MapMarker | @elcto/ui/map | Standard map marker |
| StaticMarker | @elcto/ui/map | Non-interactive marker |
| MapRoute | @elcto/ui/map | Polyline route overlay |
| MapPolygon | @elcto/ui/map | Polygon/geofence overlay |
| FitBounds | @elcto/ui/map | Auto-fit viewport to bounds |
| MapControls | @elcto/ui/map | Zoom/pan control buttons |
| MapTileSelector | @elcto/ui/map | Tile provider switcher |
| MapDevicePanel | @elcto/ui/map | Device list/detail side panel |
| MapLocationPicker | @elcto/ui/map | Click-to-pick location picker |
| PegelWidget | @elcto/ui/widgets | Water-level (Pegel) gauge widget |
| VesselMarker | subpath import | AIS vessel marker for the map |
Next Steps
- Design Tokens - Colors, spacing, and theming
- Components - Component API reference
- Icons - Platform icons