@firna/ui
v0.6.0
Published
Shared React Native and React Native Web UI primitives for Firna apps.
Downloads
923
Maintainers
Readme
ui
Shared UI component library for Firna React Native and React Native Web surfaces. The first consumers are the accounting app and the Juno app.
Key Features
- Shared dropdown menu, selector, combobox, drag-select, segmented control, radio card, switch, spinner, button, labelled input/textarea, data table, modal, toast provider/controller, avatar, status badge, calendar heatmap, and full event-calendar (month/week/day/agenda, recurring events, drag-to-create) primitives.
- A shared
sm/md/lgsize scale (ControlSize) across the interactive controls — buttons, inputs, dropdown selectors, date fields, segmented controls, and switches. - Themeable visual tokens so consumers can use their own brand primary color.
- High-layer date, dropdown, and popover overlays with z-index escape hatches for custom consumer stacking contexts.
- Expo and React Native Web compatible platform files.
- Focused unit tests, browser interaction tests, and package export checks.
- Storybook previews for visual review on same-repository non-release PRs.
- Release-please release PRs and npm trusted publishing for
@firna/ui.
User-Facing Interface
The package name is @firna/ui. Public exports are available from:
@firna/uifor all public components and helpers.@firna/ui/avatarfor the themed circular initials avatar.@firna/ui/badgefor the themed status badge pill with tone, variant, and size variants.@firna/ui/buttonfor the themed button with tone, size, and block variants.@firna/ui/calendarfor the full event calendar (month, week, day, and agenda views, recurring events, and drag-to-create).@firna/ui/datefor single-date and date-range fields.@firna/ui/drag-selectfor web drag-selection providers, target hooks, and geometry helpers.@firna/ui/dropdownfor dropdown menu, selector, combobox, and layer helpers.@firna/ui/heatmapfor the calendar contribution heatmap and its pure layout and color-scale helpers.@firna/ui/inputfor the labelled text input, textarea, and bare input frame.@firna/ui/listfor the vertical list with between-item separators, optional clickable items, and theListItemrow.@firna/ui/modalfor web modal frame, portal, model, and layer helpers.@firna/ui/popoverfor generic anchored popovers.@firna/ui/radiofor themed titled radio-option cards.@firna/ui/segmentedfor themed single-select segmented controls.@firna/ui/spinnerfor the themed indeterminate spinning loading indicator.@firna/ui/switchfor themed binary on/off switches.@firna/ui/tablefor the data table with optional headers and clickable rows.@firna/ui/themeforSharedUiThemeProvider, default accounting-style tokens, the Juno token preset, andcreateSharedUiTheme.@firna/ui/toastfor the toast provider, theuseToasthook, thetoastControllermethod API, and transient notification toasts including card and solid variants with optional custom leading icons.
Installation
npm install @firna/uiConsumers must provide the peer dependencies listed in package.json: React,
React DOM, React Native, React Native Web, React Native SVG, and
lucide-react-native.
Developer Get Started
npm ci
npm test
npm run typecheck
npm run build
npm run test:package
npm run storybook
npm run storybook:build
npm run test:browserRun the full JavaScript verification suite with:
cargo xtask checkRun the same read-only AI review wrapper used by the accounting repo with:
cargo xtask reviewBrowser interaction tests start Storybook automatically through Playwright.
Storybook is built to storybook-static. npm run test:package builds a
packed tarball, installs it into temporary consumers, imports every public
package subpath with Node's native ESM resolver, typechecks those subpaths with
TypeScript's NodeNext resolver, and then verifies the same subpaths through a
Vite build.
The package export map intentionally separates runtime targets:
- The standard
importcondition points atdist/node/**, where relative ESM specifiers include explicit.jsfiles and web platform files are selected when they exist. - Type declarations also point at
dist/node/**, where relative declaration specifiers use NodeNext-compatible.jspaths. - The
react-nativecondition points atdist/**, preserving extensionless specifiers so Metro and React Native platform resolution can choose native or web files.
Package Releases
- Release-please opens and updates the release PR for
@firna/uifrom Conventional Commits. - The release PR updates
CHANGELOG.md,package.json, andpackage-lock.jsonthrough release-please'snoderelease type. - When release-please creates or updates a release PR, the release workflow
checks out that generated PR branch, runs
npm run format, and pushes achore: format release PRcommit only if the generated files need Prettier cleanup. - Merging the release PR lets release-please create the
vX.Y.Ztag and GitHub release. Ordinary non-release pushes tomainonly update the release PR. - npm publishing runs in the same
.github/workflows/release-plz.ymlinvocation that creates the GitHub release, using npm trusted publishing. The npm package must configure this repository andrelease-plz.ymlas the trusted publisher, with allowed actionnpm publish. - The workflow file keeps the historical
release-plz.ymlfilename because npm trusted publishing validates the workflow filename configured on npmjs.com. The workflow implementation itself uses release-please. - The workflow falls back to
GITHUB_TOKENfor release-please, but a repository secret namedRELEASE_PLEASE_TOKENcan be added if release PRs need to trigger normal PR checks. - Before publishing, the release workflow installs dependencies, installs the
Playwright browser, verifies the release tag matches
package.json, runscargo xtask check, and skips publishing if the version already exists on npm. - If publish fails after the GitHub release was created, manually dispatch the
release workflow with
publish_refset to the existingvX.Y.Ztag. The retry path checks out that tag and runs the same verification and publish steps. - Scoped npm packages default to private, so
publishConfig.accessis set topublic.
Storybook Deployments
- Main branch Storybook deploys to Cloudflare Pages project
futex-ui-storybook. - Main URL:
https://futex-ui-storybook.pages.dev. - Same-repository non-release PR previews deploy to Cloudflare branch
pr-<number>. - PR preview URL shape:
https://pr-<number>.futex-ui-storybook.pages.dev. - PR previews are posted through a sticky comment marked
<!-- futex-ui-storybook-preview -->. - Release Please PRs are skipped by the Storybook preview deploy job; their component changes were already previewed in the source PRs.
- Closing a same-repository PR marks the sticky comment inactive and attempts to delete aliased preview deployments for that PR branch; if Cloudflare cleanup cannot complete safely, the comment reports the retained reason.
- Storybook examples are grouped under one top-level folder per family:
Avatar/Examples,Badge/Examples,Button/Examples,Calendar/Examples,Date/Examples,Drag Select/Examples,Dropdown/Examples,Heatmap/Examples,Input/Examples,List/Examples,Modal/Examples,Popover/Examples,Radio/Examples,Segmented/Examples,Spinner/Examples,Switch/Examples,Table/Examples,Theme/Examples, andToast/Examples. - Required repository variable:
CLOUDFLARE_ACCOUNT_ID. - Required repository secret:
CLOUDFLARE_PAGES_API_TOKENorCLOUDFLARE_API_TOKEN.
Key Code Jumping Points
- Shared theme boundary: src/theme.tsx
- Avatar component: src/avatar/README.md
- Badge component: src/badge/README.md
- Shared control-size scale: src/controlSize.ts
- Button component: src/button/README.md
- Calendar component: src/calendar/README.md
- Input and textarea components: src/input/README.md
- List component: src/list/README.md
- Dropdown components: src/dropdown/README.md
- Drag-select components: src/drag-select/README.md
- Heatmap component: src/heatmap/README.md
- Modal components: src/modal/README.md
- Radio card component: src/radio/README.md
- Segmented control component: src/segmented/README.md
- Spinner component: src/spinner/README.md
- Switch component: src/switch/README.md
- Table component: src/table/README.md
- Toast component: src/toast/README.md
- Browser tests: tests/browser/storybook.spec.ts
- Repository automation: xtask/README.md
- Shared component protocol: docs/protocol/shared-ui-components.md
- Consumer migration handoff: docs/consumer-migration.md
- Active and completed implementation plans: plans/README.md
Related Repositories
- Accounting consumer/source components:
/Users/calummoore/projects/futex/accounting - Juno consumer:
/Users/calummoore/projects/futex/juno
