@base-works/ui (0.2.0)
Installation
@base-works:registry=https://git.muddlab.com/api/packages/ahmadsholehin/npm/npm install @base-works/[email protected]"@base-works/ui": "0.2.0"About this package
@base-works/ui
Canonical BaseWorks L2 components and the cross-domain theme contract, published as a versioned package in the private BaseWorks Gitea npm registry.
Theme foundation
Wrap consuming UI once inside the application's Spectrum Provider:
<SpectrumProvider background="base">
<BaseWorksThemeScope theme="default" density="comfortable">
<Application />
</BaseWorksThemeScope>
</SpectrumProvider>
Spectrum owns scheme, locale, controls, interaction states, and foundational
tokens. BaseWorksThemeScope supplies a small public --bw-* semantic
vocabulary for custom L2/L3 components. It has complete defaults, follows the OS
scheme when Spectrum's colorScheme is omitted, and accepts no runtime colour
object. Applications override documented tokens centrally rather than passing
appearance values to components. See the repository
theme contract.
TimeSlider
TimeSlider is a data-agnostic replay scrubber over a bounded epoch-millisecond
range. A private controller owns controlled/uncontrolled time and playback,
selected step, playback multiplier, scrubbing, reset, manual stepping,
stop/loop/ping-pong boundaries, optional wall-clock following, and tick events.
Both presentations render the same React Aria Slider, track, fill, thumb,
controls, and accessibility behavior; presentation changes only the shared
Spectrum style recipes.
compact is the default and owns a complete raised panel surface matching the
operations-workspace reference. standard is the same component tree with a
surface-less, more spacious recipe for full-width panels. Both are usable with
no application repair CSS and retain optional steppers, absolute readout, and
leading/trailing controls.
The transport concepts are deliberately separate:
stepis the domain-time distance represented by one grid position;playbackMultiplieris the positive integer number of selected steps moved by one playback tick, so operational advance isstep × multiplier;tickIntervalMsis the real number of milliseconds between playback ticks. It is advanced code-only configuration with no rendered selector;playbackchooses the transport behavior:"replay"(default) advances the thumb,"forecast"holds the thumb and emits the live forecast;axischooses absolute labels or relative offsets, either from the range start or from an application-supplied epoch origin represented by0m.
| Concept | Authored through | Input domain |
|---|---|---|
| Range | start, end props |
Bounded epoch-ms window |
| Axis mode | axis={{ mode }} |
absolute or relative (explicit object) |
| Relative origin | axis.origin |
"start" or an epoch-ms timestamp |
| Step | step, stepPresets |
Domain-time ms per grid position |
| Multiplier | playbackMultiplier (+ presets) |
Positive integer steps per playback tick |
| Playback mode | playback |
"replay" (default) or "forecast" |
| Tick interval | tickIntervalMs (code only) |
Real ms between ticks, default 1000 |
| Effective advance | derived | step × playbackMultiplier per tick (replay only) |
The axis labels the range explicitly:
axis={{ mode: "absolute" }}formats epoch timestamps with the configured time formatter and time zone;axis={{ mode: "relative", origin: "start" }}(default) labels offsets from the range start (0m,+30m,+1h);axis={{ mode: "relative", origin: timestamp }}labels offsets from an application-supplied epoch timestamp — for example the current time captured on mount — so a range crossing the origin can show−30m,0m,+30m. The component never callsDate.now()unlessfollowLiveis set or forecast playback is playing.
playback="forecast" turns playback into a NOW-relative forecast emitter and
requires a relative axis. Pressing Play keeps the thumb at the selected offset
and emits the live clock plus that offset on every tickIntervalMs: at 9:30 pm
with the thumb at +30m it emits 10:00 pm, and a minute later, with the same
thumb position, 10:01 pm. The thumb never moves during forecast playback; the
emissions continue until Pause, loop modes do not apply, and the playback
multiplier is hidden and ignored. followLive cannot be combined with
playback="forecast". Interaction ticks (scrub, step, reset,
external) still report the selected offset's grid time; only playback ticks
carry the live forecast instant.
Accessible value text always follows the active axis configuration. Manual
steps and scrubbing move on the selected step grid without applying the
multiplier. followLive hides and ignores the multiplier because the injected
wall clock is authoritative. stepPresets and playbackMultiplierPresets
remain arbitrary application-owned option lists.
OperationsWorkspace
OperationsWorkspace is the L2 static composition boundary for operational
screens. It accepts ordinary React content for a top toolbar, required primary
view, left/right/bottom docks, and a primary overlay layer. Use
WorkspacePanelStack to stack docked panels and WorkspaceOverlay to anchor a
compact surface at one of six logical corners/centres. The application still
owns the route, feature wiring, primary map/canvas, and which panels appear;
the component owns containment, landmarks, default dock dimensions and visual
separation. It intentionally has no drag/drop, resizing, persistence, tabs, or
configuration-to-React renderer.
The component manifest exposes concrete slot instances such as
workspace.left; each accepts a semantic type such as workspace.panel.
Runtime JSX remains independent of catalogue metadata. Intelligence uses that
metadata only during development to check proposed compositions.
The package also ships core.timeline-controlled-workspace, a compact pattern
record backed by the TimelineControlled story. It documents where current
time is owned, how TimeSlider.onTick controls the primary view, and how the
slider occupies the workspace overlay without turning the arrangement into a
runtime layout DSL.
Local commands
pnpm --filter @base-works/ui build
pnpm --filter @base-works/ui test
pnpm --filter @base-works/ui test:visual
pnpm --filter @base-works/ui storybook
pnpm --filter @base-works/ui storybook:build
The test tier includes contract, component, catalogue, dependency-boundary, and
linked derivative-shaped consumer tests. Published-style dist macro behavior
is additionally proven by the Aviation production consumer fixture.
The visual tier covers inspected light, dark, compact, and narrow Chromium
baselines plus containment, typography, and 200% zoom invariants.
Dependencies
Dependencies
| ID | Version |
|---|---|
| @base-works/contracts | ^0.2.0 |
| react-aria-components | ^1.20.0 |
Development Dependencies
| ID | Version |
|---|---|
| @playwright/test | ^1.58.0 |
| @react-spectrum/s2 | ^1.5.1 |
| @storybook/addon-a11y | ^10.2.0 |
| @storybook/react-vite | ^10.2.0 |
| @testing-library/react | ^16.3.0 |
| @types/react | ^19.2.0 |
| @types/react-dom | ^19.2.0 |
| @vitejs/plugin-react | ^6.0.4 |
| jsdom | ^29.1.1 |
| react | ^19.2.8 |
| react-dom | ^19.2.8 |
| storybook | ^10.2.0 |
| unplugin-parcel-macros | ^0.2.0 |
| vite | ^8.1.5 |
Peer Dependencies
| ID | Version |
|---|---|
| @react-spectrum/s2 | ^1.5.1 |
| react | ^19.2.8 |
| react-dom | ^19.2.8 |