@aracreate/test-arm-ui
v3.4.0
Published
A modern, lightweight, and customizable React UI library built with TypeScript, UnoCSS, and Storybook
Maintainers
Readme
ARM UI Library
The shared React component library for the ARM platform, published to npm as
@aracreate/test-arm-ui. It is the single
source of the platform's design system — 42 components plus the UnoCSS preset that carries the brand
scales — consumed by arm-core-fe, the calendar frontend and the admin frontend so all three look
like one product.
- Ships the components and the UnoCSS preset (
acPreset) that generates their classes; a consuming app installs both or the components render unstyled - Purpose-built for ARM rather than general-purpose: the catalogue is calendar-, auth- and
dashboard-shaped (
SyncDetailsDialog,ImportCalendarsDialog,BigCalendarView,OtpVerifyStep) - Every component has a colocated test, and all 42 are covered by axe accessibility tests
- Storybook is the browsable catalogue and the place to develop a component in isolation
This library is consumed as a pinned npm dependency, not a workspace link. A change here has to be published and the version bumped in each consuming app before it is visible to them — a library change and a consumer change cannot land in one commit, and a new prop will compile silently against the previously published types until the bump happens.
Stack
| Layer | Tool |
| --- | --- |
| Framework | React 19 (peer: >=18) |
| Bundler | tsup — ESM + CJS + .d.ts |
| Styling | UnoCSS, shipped as the acPreset preset and a pre-built style.css |
| Primitives | Radix (@radix-ui/react-icons, Radix Themes in consumers) |
| Calendar grid | react-big-calendar, with brand overrides shipped separately |
| Catalogue | Storybook |
| Tests | Vitest — two configs (components, Storybook) — plus axe accessibility tests |
| Release | semantic-release → npm |
| Language | TypeScript |
| Package manager | pnpm |
Architecture
src/
├── index.ts ← Public entry — re-exports components, types, theme and class helpers
├── components/ ← The 42 components, each with a colocated *.test.tsx
│ ├── index.ts ← Named exports; this file defines the public component API
│ ├── tokens.css ← Design tokens, shipped to consumers as /tokens.css
│ └── big-calendar-overrides.css ← react-big-calendar brand overrides, shipped separately
├── preset.ts ← acPreset — wraps presetWind4 and adds the brand scales
├── styles/ ← radix-brand-tokens.css, theme.css
├── lib/ ← theme object, getColor, and the class-building helpers
├── types/ ← Shared prop types (Size, Variant, polymorphic helpers)
└── stories/ ← Storybook storiesPackage exports
| Entry | Contents |
| --- | --- |
| . | Components, types, theme/getColor/colors, class helpers |
| ./preset | acPreset for a consuming app's uno.config.ts |
| ./style.css | Pre-built stylesheet — the alternative to scanning library sources |
| ./tokens.css | Design tokens alone |
| ./big-calendar-overrides.css | react-big-calendar brand overrides |
Only dist/ is published (files: ["dist"]), so anything a consumer needs must be exported from
src/index.ts or emitted by the CSS build — a file that exists in src/ but is not reachable
through an export does not ship.
The component catalogue
Grouped by what they are for; src/components/index.ts is the authoritative list, and Storybook
is the way to actually look at them.
| Group | Components |
| --- | --- |
| Calendar | BigCalendarView, CalendarMergedView, MonthGrid, MiniMonthPicker, CalendarToolbar, CalendarDayHeader, CalendarPickList, EventBlock |
| Sync & accounts | SyncDetailsDialog, SyncPreviewRail, ImportCalendarsDialog, AccountCalendarsDialog, ConnectedAccountCard, AccountCard, AddAccountMenu, ConnectProviderList, ConnectProviderRows, PausedBadge |
| Auth & onboarding | AuthCard, BrandPanel, OtpInput, OtpVerifyStep, OnboardingStepDots, WizardStepper |
| Shell | Sidebar, Topbar, SearchOverlay |
| Data display | DataTableRow, MetricCard, AppCard, ActivityRow, AccentHeader, CardFooter, IconTile |
| Feedback & state | Toast, ConfirmDialog, Skeleton, EmptyCard, DashboardErrorCard |
| Icons | ProviderIcon, GoogleIcon, MicrosoftIcon |
There is deliberately no Button or Input here — consumers use Radix Themes for those primitives
and this library for the ARM-specific compositions above.
Installation and setup in a consuming app
pnpm add @aracreate/test-arm-uiPeer dependencies: react and react-dom (>=18), react-router-dom (>=7), unocss,
@unocss/preset-wind4, @unocss/preset-attributify (all >=0.60), and @radix-ui/react-icons
(>=1).
Then wire the preset into the app's uno.config.ts:
import { defineConfig } from "unocss";
import { acPreset } from "@aracreate/test-arm-ui/preset";
export default defineConfig({
presets: [acPreset()],
content: {
pipeline: {
include: [
"src/**/*.{ts,tsx}",
// Scan library sources so UnoCSS generates every class the components use
"node_modules/@aracreate/test-arm-ui/src/**/*.{ts,tsx}",
],
},
},
});The library scan path is not optional. UnoCSS only generates CSS for class names it finds in scanned files, and the components' classes live in library sources the app never imports directly — omit the path and components render unstyled. The alternative is to skip scanning and import the pre-built stylesheet instead:
import "@aracreate/test-arm-ui/style.css";Use acPreset(), never a bare presetWind4() — the preset is what adds the brand scales, and the
consuming apps' ESLint configs fail the build on a direct @unocss/preset-wind4 import and on
stock-palette classes (text-gray-500, bg-blue-600) for exactly this reason.
Commands
This repo has no Makefile (unlike every other repo in the workspace), so it is driven through
package.json scripts:
pnpm install
pnpm dev # build CSS once, then tsup --watch
pnpm build # build:js (tsup) + build:css (UnoCSS + token CSS copy)
pnpm storybook # Storybook on :6006 — the component catalogue
pnpm test # component tests (vitest.components.config.ts)
pnpm test:storybook # Storybook tests (vitest.config.ts) — a genuinely separate suite
pnpm type-check # tsc --noEmit
pnpm lint # eslint src
pnpm format # prettier --write
pnpm release # semantic-release (CI)
pnpm clean # rm -rf distprepublishOnly runs clean then build, so a publish cannot ship a stale dist/.
Conventions
Repo conventions (file headers, naming, versioning, Makefile targets) follow
aracreate-conventions — formerly
aracreate-template-codebase, still checked out locally under that name at
../../aracreate-template-codebase. Template-conformance work
for this repo is tracked in TASK_SHEET.md; this repo is currently short a Makefile and a
VERSION file, so its version lives in package.json and is managed by semantic-release.
Project-specific rules:
- Every class a component renders must be reachable by the CSS build. A class assembled at
runtime from fragments UnoCSS cannot see will not exist in
style.css. - Add a colocated
*.test.tsxwith the component, including its axe accessibility assertion. - Bump and publish before a consumer can use a change — see the pinned-dependency note above.
Deeper internals — the tsup build, why there are two Vitest configs, how to add a component, the
token system, and the publishing flow — are in DEVELOPER.md, which this README
deliberately does not duplicate.
License
GPL-3.0 — see LICENSE.
