Max

@teammanager/ui (0.6.0)

Published 2026-08-24 10:44:14 +02:00 by Max

Installation

@teammanager:registry=
npm install @teammanager/ui@0.6.0
"@teammanager/ui": "0.6.0"

About this package

TeamManager UI

Shared React visual primitives for TeamManager Web and Race Engineer.

The package owns a small, versionable visual foundation: design tokens, accessible buttons and dialogs, structural panels, explicit status treatment, and workflow orientation. It is deliberately not a race-strategy engine, data client, application shell, or Wails/browser abstraction.

Authority boundary

  • TeamManager Server owns Team Event strategy and revisions.
  • TeamManager Web is the Team Event planning and decision surface.
  • Race Engineer owns local/solo strategy, SafetyGate, telemetry interpretation, and every simulator-control decision.
  • This package only renders values and dispatches ordinary UI interactions.

Consumer contract

Consumers import @teammanager/ui/styles.css once and wrap their app in ThemeProvider: choose cockpit for the dark desktop and web for the neutral operational Web theme. It keeps CSS variables on both the visible app frame and portaled Radix controls. Consumers retain ownership of data, routing, mutations, i18n, authority labels, and product-specific tests.

@teammanager/ui/tailwind.css contains the package's compiled base layers and semantic focus rules. It is not an arbitrary consumer-utility bundle. A consumer compiles its own application layouts with the published @teammanager/ui/tailwind-preset in its Tailwind configuration and its own content globs. This gives Web and Race Engineer the same semantic tokens without copying a primitive library or depending on a stale static class list.

import "@teammanager/ui/styles.css";
import { Button, Panel, Status, ThemeProvider } from "@teammanager/ui";

export function App() {
  return <ThemeProvider theme="web"><Status label="Evidence current" /></ThemeProvider>;
}

Component catalogue

Need Primitives
Foundation Button, Input, Label, Select, Checkbox, Switch, Dialog, Tabs, Accordion, Collapsible, DropdownMenu, Tooltip, Popover, Progress, Separator, ScrollArea, Table, Badge, Alert, Panel, Status, Metric, EvidenceLedger
Persistent orientation ContextBar, TopNavigation, WorkspaceMenu, WorkflowRail, Tabs
Explicit operator attention Attention
Planning and review PlannerBoard, StintTimeline, PitWindow, PitServicePlan, PlanRevisionTrail, StrategyComparison, SegmentedControl, Field, Input, Select
Pitwall and relative order OperationTable, RaceTimingTable, TrackMap, RelativeGapList, RejoinForecast, RaceIntelligenceList, RaceControlFeed
Live operator requests LiveScenarioRequest

The catalogue deliberately has no strategy calculator, mutable dashboard layout, telemetry projection, chart engine, routing, or state store. A product adds an extension only after a concrete operator question, typed data contract, and validation scenario exist.

Race-operations primitives

Metric, StintTimeline, PitWindow, RejoinForecast, StrategyComparison, RaceIntelligenceList, and TrackMap are visual-only helpers for a Pitwall or plan review. StintTimeline receives pre-computed axis positions. PitWindow receives an explicit open/close state. RejoinForecast receives a supplied range, adjacent cars, and assumptions; it does not estimate a rejoin itself. StrategyComparison presents supplied baseline and candidate values without selecting a winner. RaceIntelligenceList uses native disclosures for supplied opponent/race evidence, including an explicit unavailable state. TrackMap receives circuit SVG geometry or normalized progress and explicit marker positions, including an optional projected marker. None of these components projects telemetry, derives a stint, or labels evidence by itself.

RelativeGapList presents a supplied class-relative order, gap, and own-car marker. LiveScenarioRequest is a native form frame for a human to request a what-if evaluation; the consumer validates and submits its fields, then renders the separate authority-owned candidate. It never calculates a candidate or issues a simulator command.

RaceTimingTable is the concrete, read-only class timing table for Pitwall. Consumers supply its already ordered rows, formatted timing labels, class and pit/status state, own-car marker, plus source, freshness, availability, and confidence labels. Its native Evidence disclosure keeps row rationale keyboard-operable. The table never sorts, calculates a gap or interval, subscribes to timing, infers pit/opponent state, or replaces unavailable values with zero; narrow screens retain its dense table in a scrollable region.

PlannerBoard is the controlled planning interaction primitive. It receives named driver lanes and stints and emits only { stintID, fromDriverID, toDriverID, toIndex }. Pointer drag is an optional enhancement for reordering and lane transfers; keyboard drag reorders within a driver lane. The native move controls provide the keyboard-safe, operation- equivalent lane transfer by choosing the destination and exact insertion index before emitting the same intent. A request is announced as a request, not as a saved or accepted plan, until the consumer reflects the new controlled lanes. The consumer owns revision checks, conflicts, explicit save, and persistence. disabled disables movement only, so supplied card content remains selectable and editable. Supplied form content must be controlled by its owner because transferring a card remounts it.

Workspace menus

WorkspaceMenu is built on @radix-ui/react-dropdown-menu. The dependency provides keyboard navigation, focus management, escape handling, and safe nested submenus for the application-level workspaces that a pitwall needs. It does not own routing, permissions, saved layouts, or persistence; each product provides those through items and onItemSelect.

Data binding

The package receives formatted, validated props from an owning product. It has no API client, cache, query library, event stream, or calculation layer. The current TeamManager Web and Server contracts, their safe component mappings, and example owner-side projections are documented in data-bindings.md.

Private registry

The Git repository remains private. The package is published only to the private Forgejo npm registry under @teammanager; private: false is required by npm to permit that registry publish and does not make the Git repository public. Consumers configure their own Forgejo owner token outside version control, following Forgejo's npm-registry documentation.

Each package change is independently reviewed in Forgejo before its owner-authorised merge. The next release is a manual Forgejo Actions dispatch of Publish TeamManager UI package from main. Enter the required expected version 0.6.0; the workflow checks both the branch and package.json, checks out without persisted credentials, runs npm ci, check, test, build, and pack:check, then uses TEAMMANAGER_PACKAGE_WRITE_TOKEN only for the final publish step. It publishes to the existing publishConfig.registry; it does not create tags, publish images, or deploy.

Verify that @teammanager/ui@0.6.0 is absent from the private registry before the dispatch. npm package versions are immutable: never retry a successful version or overwrite one that is already present. Stop on an ambiguous registry result and decide the next version through the normal release change before changing the workflow's exact release guard.

Storybook catalogue

Install dependencies with npm ci, then run npm run storybook and open http://127.0.0.1:6006. Browse the sidebar from Foundation, Forms and interaction, Orientation and workspace, Planning and review, Pitwall evidence, and Live strategy contracts; Race operations/Compositions remains a useful whole-workspace reference.

Run npm run build-storybook to check the static catalogue build. Run npm run test:visual for deterministic Playwright screenshots; update an intentional baseline only after inspecting the affected desktop, ultrawide, and narrow views. npm run check, npm test, npm run build, and npm run pack:check remain the package release checks.

If the sidebar seems empty, stop any old Storybook process, run the command from this package root, and reload without cache. Confirm the running server is on port 6006 and that its startup output includes the stories/**/*.stories.tsx files. A stale server commonly lacks newly added catalogue entries.

Every story is fixed mock evidence, not an Alpha session, authenticated Server integration, live iRacing feed, strategy calculation, or simulator-control path. Live strategy samples keep an accepted baseline distinct from a pending, rejected, or evidence-expired candidate and show only the supported review path that the consuming product owns.

Dependencies

Dependencies

ID Version
@dnd-kit/dom ^0.5.0
@dnd-kit/helpers ^0.5.0
@dnd-kit/react ^0.5.0
@radix-ui/react-accordion ^1.2.20
@radix-ui/react-checkbox ^1.3.11
@radix-ui/react-collapsible ^1.1.20
@radix-ui/react-dialog ^1.1.23
@radix-ui/react-dropdown-menu ^2.1.24
@radix-ui/react-popover ^1.1.23
@radix-ui/react-progress ^1.1.16
@radix-ui/react-scroll-area ^1.2.18
@radix-ui/react-separator ^1.1.15
@radix-ui/react-switch ^1.3.7
@radix-ui/react-tabs ^1.1.13
@radix-ui/react-tooltip ^1.2.16
class-variance-authority ^0.7.1
clsx ^2.1.1
lucide-react ^1.31.0
tailwindcss ^3.4.19

Development dependencies

ID Version
@playwright/test ^1.62.1
@storybook/addon-a11y ^10.5.0
@storybook/react-vite ^10.5.0
@types/react ^19.2.18
@types/react-dom ^19.2.4
postcss ^8.5.26
react ^19.1.1
react-dom ^19.1.1
storybook ^10.5.0
tsup ^8.5.1
tsx ^4.23.1
typescript ^5.9.3
vite ^8.1.5

Peer dependencies

ID Version
react ^19.0.0
react-dom ^19.0.0
Details
npm
2026-08-24 10:44:14 +02:00
45
34 KiB
Assets (1)
ui-0.6.0.tgz 34 KiB
Versions (15) View all
0.11.0 2026-10-01
0.10.0 2026-09-29
0.9.0 2026-09-29
0.8.0 2026-09-17
0.7.2 2026-09-16