Skip to main content

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:

ComponentDescription
AlertStatus messages with variants
AnimatedBackgroundAnimated gradient background with particles
ApiHealthBannerReal-time API health monitoring
AppSwitcherApp navigation dropdown
AuditIconIcons for audit events
AvatarUser avatar with fallback
BadgeStatus badges and labels
BannerFull-width notification banners
BlurredTextPrivacy-aware text display
ButtonInteractive buttons with variants
CardContent containers (Card, ActionCard, StatusCard, InfoItem)
CategorySelectSelect grouped by category
CheckboxStyled checkbox input
CodeInputOTP/verification code input
ColorPickerColor selection with presets
CountrySelectCountry selection with flags
DateTimePickerDate, time, datetime picker
DropdownDropdown menus
DropdownButtonSplit button with dropdown options
FileUploadFile upload with dropzone and progress
FloatingInputInputs with floating labels
ImagePreviewImage thumbnails with lightbox
InputBasic text input
LanguageSwitcherLocale selection dropdown
LoadingSpinner & SpinnerLoading indicators
LogoBrand logo components
ModalDialog windows
Platform IconsSVG icons for platforms
SearchableSelectSelect with search filtering
SelectCustom dropdown select
ServiceUnavailable503 service unavailable page
SubMenuBarHorizontal sub-navigation bar below header
SubNavNested navigation tabs
TableData tables with pagination
ToastToast notifications
ToggleSwitch-style toggle input
TooltipHover tooltips
TurnstileCloudflare 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):

ComponentImport fromDescription
Map@elcto/ui/mapMapLibre map container + useMap hook
LiveMarker@elcto/ui/mapAnimated live-position marker
MapMarker@elcto/ui/mapStandard map marker
StaticMarker@elcto/ui/mapNon-interactive marker
MapRoute@elcto/ui/mapPolyline route overlay
MapPolygon@elcto/ui/mapPolygon/geofence overlay
FitBounds@elcto/ui/mapAuto-fit viewport to bounds
MapControls@elcto/ui/mapZoom/pan control buttons
MapTileSelector@elcto/ui/mapTile provider switcher
MapDevicePanel@elcto/ui/mapDevice list/detail side panel
MapLocationPicker@elcto/ui/mapClick-to-pick location picker
PegelWidget@elcto/ui/widgetsWater-level (Pegel) gauge widget
VesselMarkersubpath importAIS vessel marker for the map

Next Steps