@lighthousesports/nxus-ui
v0.2.0
Published
NXUS design system — shared tokens + components, published for consumption by both the Vite prototype app and future Next.js apps.
Readme
@lighthousesports/nxus-ui
The NXUS design system: shared tokens + components, built with Vite library
mode so it can be consumed by both the Vite/React 18 prototype app in this
monorepo (apps/prototype) and, later, React 19 / Next.js apps. ESM-only.
This is a v1, deliberately small: the token layer plus two clean,
prop-driven components (KpiCard, ImageWithFallback). More components land
in a later phase.
Install
Inside this monorepo, apps/prototype already depends on it via
"@lighthousesports/nxus-ui": "workspace:*" — pnpm install at the repo root
wires it up. Outside this monorepo it would be a normal npm install:
npm install @lighthousesports/nxus-uiUse it
Import the compiled stylesheet once, near the root of your app (it ships the whole token layer — colors, type ramp, spacing, shadows, keyframes; see "What's inside" below):
import "@lighthousesports/nxus-ui/styles.css";Then import components as named exports from the package root:
import { KpiCard, ImageWithFallback } from "@lighthousesports/nxus-ui";react and react-dom are peerDependencies (>=18, not pinned to a major)
so this works unmodified in the React 18 prototype app and a React 19 app.
What's inside
- Tokens (
src/tokens.css, →dist/styles.css): the design system's source of truth, ported verbatim from the prototype app's originalsrc/styles/{fonts,default_theme,globals}.csschain, in the same cascade order. 150+ custom properties (light/dark colors, the blue/navy/light 11-step ramps, semantic tokens, shadows, the responsive--fs-*/--lh-*type ramp,--space-*, the "jumper"--pad-*/--gap-*tokens), plus the Tailwind v4@theme inline/@custom-variantauthoring blocks (kept, not stripped — any consumer that still runs its own Tailwind build over this stylesheet, likeapps/prototype, needs them intact to resolve utilities likebg-primaryor thedark:variant). KpiCard— the shared KPI tile used across the Lead/Senior/Video Manager dashboards in the prototype app.ImageWithFallback— an<img>wrapper that swaps in a placeholder on load error.
Developing it against the prototype app
The prototype app depends on this package via workspace:* and imports its
built dist/ output (types + styles.css), not its source — so after
changing anything under packages/nxus-ui/src, rebuild before the prototype
app will see the change:
# from the repo root
pnpm --filter @lighthousesports/nxus-ui build
# then, in another terminal
pnpm --filter prototype devThere's no watch mode yet (v1 is small enough that a manual rebuild is fine).
If this grows, wiring up vite build --watch here plus Vite's own
dependency-optimization invalidation in the prototype app would be the next
step.
Build
pnpm buildVite library mode, ESM only. Emits into dist/:
dist/index.js— single bundled chunk,"use client"as its own first line,react/react-domexternal (peer deps, never bundled).dist/index.d.ts+dist/components/*.d.ts— type declarations (vite-plugin-dts).dist/styles.css— the one compiled stylesheet (tokens first in the cascade; CSS Modules, if a future component uses them, compile to scoped class names into this same file; global CSS like keyframes stays unscoped).
The build never mutates anything under src/ — verified by hashing src/
before and after, and confirmed the build is idempotent (byte-identical
dist/ output) across repeated runs.
prepublishOnly runs this build automatically before npm publish.
Storybook
Every exported component has a colocated *.stories.tsx next to its source,
with autodocs prop tables generated from the real TypeScript types
(react-docgen-typescript, not hand-written) and a light/dark toolbar
toggle. Pure hooks/utilities (no visual output) are documented on one
Hooks & Utils MDX page instead of getting an empty story each.
pnpm --filter @lighthousesports/nxus-ui storybook # dev server, :6006
pnpm --filter @lighthousesports/nxus-ui build-storybook # static site → storybook-static/Both scripts run vite build first (prestorybook / prebuild-storybook
npm hooks) so Storybook always sees this package's current built
dist/styles.css — never a stale one. See .storybook/Introduction.mdx
(rendered as the Storybook landing page) for the token layer, the
.dark-class theming model, and — important if you ever add a component
that ships raw Tailwind utility class names instead of a CSS Module — the
"Tailwind trap" any consuming app (this Storybook included) has to route
around.
