# @plumile/ui

Shared React UI primitives, layouts, and theme foundations for Kronex
applications.

## Status

Specialized public package. This package is intended for teams adopting the
Kronex design language and component conventions. It is not a generic UI kit
for arbitrary React applications.

## Purpose

`@plumile/ui` is the visual layer of the Kronex ecosystem. It provides:

- theme contracts and tokens
- low-level form and feedback primitives
- shared layouts and page shells
- data-heavy and admin-oriented widgets
- reusable backoffice visual components

It does not provide:

- application business logic
- GraphQL orchestration
- router orchestration beyond consuming router links where needed

## Installation

```bash
npm install @plumile/ui
```

Peer dependencies:

```bash
npm install react react-dom i18next react-i18next
```

If you use components that depend on router links, also install
`@plumile/router`.

## Main Public Surface

The package entry point groups exports by UI family instead of exposing a single
flat mental model.

### Theme and styling

- `ThemeProvider`
- `BackofficeThemeProvider`
- `useTheme`
- theme contracts, tokens, and accessibility helpers
- `sprinkles`, `stateSprinkles`, and shared style recipes such as `focusRing`,
  `controlFocusRing`, `disabledControl`, `surfaceInteractive`,
  `interactiveControlSurface`, `interactiveLinkSurface`, `ghostIconButton`,
  `pillLink`, `entityReferenceLink`, `insetFocusRing`, `truncate`,
  `iconBox`, `iconBoxCompact`, `loadingShimmer`, and `visuallyHidden`

### Primitives and forms

- `Button`, `LinkButton`, `Input`, `Textarea`, `Checkbox`
- `Label`, `Form`, `FormField`, `FormGroup`
- `ErrorMessage` is the field-level error text primitive. Use it for messages
  tied to a single control through `aria-describedby`.
- `FormError` is the canonical form-level error block for submit failures and
  validation summaries inside form surfaces.
- `InlineBanner` is the canonical general notice/banner primitive for
  non-field feedback. It supports info, success, warning, and danger tones,
  titles, descriptions, actions, dismiss controls, and explicit live-region
  overrides.
- `EmptyState` is the canonical empty-state component. Use
  `variant="framed"` for card-backed surfaces, `variant="plain"` for inline
  backoffice-style surfaces, `density="compact"` for dense lists, and `tone`
  for neutral, muted, info, success, warning, or danger emphasis.
- `ToastProvider`, `ToastViewport`

### Layouts and shells

- `PageShell`, `AdminShellLayout`, `SidebarNavigation`
- `Surface` is the canonical structured surface primitive for titled content,
  optional descriptions, actions, body content, and footers. It supports
  `div`, `section`, and `article` roots plus visual variants for brand,
  neutral, muted, and plain surfaces.
- `SurfaceSection` wraps `Surface` for accessible titled sections and wires
  `aria-labelledby` automatically when a title is present.
- `ContentLayout`, `ResizableSplitView`, `PanelShell`
- `ResizableSplitView` is the canonical split-view primitive for optional,
  resizable side panels. It supports controlled and persisted widths,
  pointer and keyboard resizing, stacked layouts below a breakpoint, and
  accessible separator semantics.
- `Toolbar`, `ToolbarGroup`, `ToolbarSpacer`, `ToolbarSeparator`
- `SettingsLayout` for settings-oriented content with local navigation
- `Card`, `PanelShell`, `ActionPanel`, and `BackofficeFormSection` remain
  compatible wrappers or specialized compositions on top of the canonical
  surface primitives.

### Data-heavy and dashboard components

- `DataTable` is the canonical high-level table for static and paginated data.
- `DataTableRoot`, `DataTableHeader`, `DataTableBody`, `DataTableRow`, and
  `DataTableEmptyRow` expose the same public rendering primitives for advanced
  table composition without duplicating cell, header, density, breakpoint, empty
  state, or contained-scroll behavior.
- `VirtualizedConnectionTable` is the specialized table for virtualized
  connection lists and infinite loading. It shares the `DataTable` primitives
  for table rendering while keeping virtualization and scroll-trigger behavior
  separate from the base table API.
- `ResponsiveRecordList` adapts the same table columns between table and mobile
  card layouts.
- `BackofficeDataTable` composes selection, bulk actions, and toolbar behavior
  on top of `DataTable`; virtualized backoffice lists use
  `VirtualizedConnectionTable` directly.
- `MetricCard` and `MetricTileGroup` are the canonical KPI primitives. They
  support metric tones, compact density, copyable values, and configurable
  responsive tile widths without changing their default rendering.
- `DashboardPanel`, `DashboardMetricGroup`, `DashboardQuickActions`, and
  `DashboardStatusList` provide the canonical visual widgets for dashboard
  panels, linked metric groups, shortcut lists, and status summaries.
- `StatusSummaryPanel`
- `ActivityFeed`, `TimelineEventRow`, `InfoTile`
- `TimelineEventRow` is the reusable dashboard timeline row primitive. It uses
  the canonical event vocabulary (`title`, `time` or `timestamp`,
  `description`, `meta`, `metrics`, `details`, and semantic `tone`) while
  keeping relative timestamp rendering available through `RelativeTimeText`.

### Formatting helpers

- `HighlightCode` is the general code-display primitive. It supports a badge,
  copy action, placeholder text, highlighted HTML/React content, and a plain
  preformatted fallback.
- `copyTextToClipboard`, `copyRichClipboard`, and `useClipboardCopy` provide
  shared clipboard behavior with rich multi-format writes where browsers
  support them and text fallbacks everywhere else.
- `BackofficeJsonViewer` is the canonical structured JSON viewer for
  backoffice surfaces. It safely stringifies unknown values, exposes copy and
  collapse/expand controls, and accepts max-height and label overrides.
- `BackofficePayloadViewer` is the canonical backoffice payload viewer for
  `json`, `markdown`, `text`, and `code` payloads. Use it inside detail
  sections or tool output surfaces for empty states, summaries, collapsible
  details, copyable text/code, markdown rendering, and JSON rendering through
  `BackofficeJsonViewer`.
- `MoneyAmount` renders a currency amount from `amount` and `currency`
  props with fixed two-decimal formatting.
- `formatCurrencyAmount({ amount, currency })` provides the same formatting
  for plain-text usage such as charts, table configs, and tooltips.

### Backoffice visual components

- `Badge` is the low-level inline visual marker. It supports neutral, info,
  success, warning, danger, and accent tones plus a loading shimmer.
- `StatusBadge` maps semantic status tones to badge tones and can show an
  optional status dot.
- `Tag` is the compact pill component for short labels and optional removable
  filters. Use `title`, `onRemove`, and `removeLabel` for accessible removable
  tags.
- `EnvironmentBadge` and `BackofficeIdBadge` remain specialized public badge
  compositions for environment labels and copyable IDs.
- Detail badge/value compositions are available for backoffice entity pages:
  `BackofficeStatusMetaBadge`, `BackofficeStatusGroup`,
  `BackofficeDetailFlagTag`, `BackofficeDetailTaggedValue`,
  `BackofficeReferenceValue`, and `BackofficeEnumLabel`.
- `BackofficeKeyValueList` is the canonical definition-list renderer for
  backoffice label/value metadata. It supports surface or plain rendering,
  split, stack, and grid layouts, custom empty labels, and React node values.
- spinners and skeletons
- `BackofficeToolbar` is the canonical list/table toolbar for search, filters,
  sorting, actions, and active chips.
- `BackofficeListFooter` is the canonical infinite-list footer for status-only
  and button-driven loading flows. Keep load-more status, loaded counts,
  spinners, and manual load buttons there rather than rebuilding list footers
  around `InfiniteScrollTrigger`.
- `BackofficeEmptyState` is a compatibility wrapper around `EmptyState` with the
  plain, compact backoffice defaults.
- `BackofficePickerShell`, `BackofficePickerList`, and `BackofficePickerRow`
  are the canonical visual primitives for searchable backoffice pickers. They
  own the search input layout, listbox/option rendering, empty state, and row
  truncation; application integrations should pass already-resolved picker
  items and keep manifest, Relay, and domain behavior outside `@plumile/ui`.
- filter drawers and confirm dialogs stay separate from picker primitives
  because their navigation, action, and confirmation semantics differ.
- backoffice data-table wrappers and detail visual helpers, including
  `BackofficeDetailField` and `BackofficeDetailSection` for generic titled
  detail sections and copyable field values, plus `BackofficeScopeStack` and
  `BackofficeAuditMetadataPanel` for canonical scope/context and audit
  metadata sections
- `AuditTimeline` is the canonical visual timeline for backoffice lifecycle and
  audit history. It renders ordered `ol`/`li` events with title, time,
  description, actor, source, meta, metrics, details, density, custom
  `renderEvent`, and neutral/info/success/warning/danger tones. Empty timelines
  render `null` unless `emptyState` is supplied.
- `DetailPageTemplate`, `DetailPageTemplateContent`, and `ListPageTemplate` are
  the canonical backoffice page templates for detail and list screens.
- `SidebarNavigation`, including collapsible sections, collapsed rail mode,
  profile footer composition, and optional sortable sections for backoffice
  navigation groups

Breaking changes in this line: `BackofficeTableToolbar`, `TableToolbar`,
`BackofficeFiltersBar`, `BackofficeLoadMore`,
`BackofficeInfiniteListStatus`, `BackofficeVirtualizedConnectionTable`,
`BackofficeDetailLayout`, `DetailPage`, `DetailPageContent`, `SegmentedNav`,
and `SectionNav` were removed in favor of the canonical components above and
`Tabs`.

For the complete export list, see [`src/index.ts`](./src/index.ts).

## Quick Start

```tsx
import { Button, ThemeProvider, Toolbar, ToolbarGroup } from '@plumile/ui';

export function ExampleScreen(): JSX.Element {
  return (
    <ThemeProvider defaultMode="light">
      <Toolbar ariaLabel="Screen actions">
        <ToolbarGroup>
          <Button>Save</Button>
        </ToolbarGroup>
        <ToolbarGroup justify="end">
          <Button variant="secondary">Cancel</Button>
        </ToolbarGroup>
      </Toolbar>
    </ThemeProvider>
  );
}
```

`ThemeProvider` stores the public shell preference in `plumile-theme-mode`.
`BackofficeThemeProvider` stores the backoffice preference separately in
`plumile-backoffice-theme-mode`, so a backoffice can resolve light, dark, or
system mode independently inside a public page.

## Package Layout

- `theme/*`
  canonical source of shared design tokens and theme primitives
- `atomic/*`
  low-level reusable React building blocks
- `components/*`
  generic cross-application layouts and widgets
- `backoffice/*`
  specialized data-heavy visual components for admin and backoffice screens

## Validation Notes

- public UI behavior should be covered by targeted tests for stable components
- visual breadth is large, so documentation and examples should stay organized by
  component families rather than exhaustive component-by-component prose
- Storybook stories are useful for visual review, but they do not replace
  behavioral tests for stable public components
- styling should prefer shared sprinkles and theme style recipes; raw
  vanilla-extract `style()` is reserved for selectors, pseudo-elements,
  keyframes, container queries, CSS variables, `calc()`, `color-mix()`, or
  highly specific grid/layout cases
- shared UI styling is sprinkles-first: add recurring token-sized values and
  reusable interactive/link/icon classes to `theme/styleRecipes.css.ts` before
  creating local one-off `style()` blocks

## Limitations

- this package assumes Kronex theme tokens and styling conventions
- it is intentionally opinionated for backoffice and admin-style interfaces
- it does not try to be a framework-agnostic design system
- some components assume other Kronex packages, especially `@plumile/router`

## Related Docs

- [Repository README](../../README.md)
- [Documentation Index](../../docs/index.md)
- [Backoffice React README](../backoffice-react/README.md)
