Pathfinderby Commenda
Contributing

Contributing

The workflow for adding a Pathfinder component.

Develop locally

Run the package watcher and docs from the workspace root in separate terminals:

SH
pnpm pathfinder:dev
pnpm pathfinder:docs

pnpm pathfinder:storybook starts Storybook and its own package watcher. When using it, you do not need a second pathfinder:dev process.

The package watcher does not serve a web page. Documentation runs on port 3002; Storybook runs on port 6006. Run development commands without sudo.

Component structure

Keep implementation, props, stories, and behavior tests in packages/pathfinder/src/components/<component>/. Export the intended API through the component's index.ts and the package entry points. Create shared hooks or types only when multiple components need them.

Contribution checklist

  1. Define the use case, API, states, and Base UI primitive.
  2. Use semantic tokens and preserve React 18/19 compatibility.
  3. Verify keyboard behavior, focus, disabled states, and accessible names.
  4. Add stories and meaningful behavior/type tests.
  5. Update these docs with examples, limitations, and accessibility guidance.
  6. Check compiled exports, declarations, and CSS when the package contract changes.
  7. Run applicable worst-case content/layout checks with Emil's break-ui and retain Storybook fixtures. Report verification results in the PR. Follow the development skills guide for UI, motion, API design, and test guidance.

Follow the component conventions and formatting guide when extending the package.

Required checks

pnpm pathfinder:check runs formatting checks, lint, behavior/artifact tests, public API type fixtures, and package/docs type checking. pnpm pathfinder:lint runs lint alone; pnpm --filter @commenda/pathfinder lint:fix applies supported safe fixes.

The scoped ESLint configuration checks strict TypeScript, promise handling, React hooks, JSX accessibility, unused imports, and package boundaries. Published components cannot import Next.js, application code, private workspace packages, or generated output. CI rejects warnings, and inline rule suppressions are disabled. Document justified exceptions in the scoped config. Accessibility lint does not replace browser keyboard tests and Storybook accessibility scans.

Overlay motion regression

After changing overlay motion, build and serve Storybook, then run:

BASH
pnpm --filter @commenda/pathfinder exec playwright install chromium
PATHFINDER_STORYBOOK_URL=http://localhost:6006 pnpm --filter @commenda/pathfinder test:motion

Use the URL of your running Storybook (including a served static build). This browser check samples computed transforms across animation frames, rather than trusting duration classes. It covers Dialog, Popover, side/bottom Sheet entry and exit, interrupted exits, keyboard activation, reduced motion and bottom-sheet drag release. Keep it separate from the unit suite because it requires Chromium and a running browser preview.

Component styling

Author components with Tailwind CSS v4 utilities prefixed with pf:. Shared class recipes belong beside the components that use them. Use generated tokens for color, typography, spacing, radii, and elevation; arbitrary values are for Figma geometry without a matching token.

  • Keep complete utility names in source. Do not build class names from interpolated fragments.
  • Style Base UI states with data-attribute variants. Preserve focus, disabled, read-only, and reduced-motion behavior.
  • Use DirectionProvider and the matching document dir for RTL. Direction-sensitive controls use Base UI's direction context.
  • Keep CSS for generated foundations, fonts, and keyframes. Component-specific selector stylesheets require a documented reason.
  • Build and test the packed CSS: consumers import @commenda/pathfinder/styles.css once after their own base stylesheet and never scan Pathfinder source or install Tailwind.
  • Run Prettier, pnpm pathfinder:check, packed-consumer checks, and affected Storybook/Fumadocs previews before completing a styling change.

The pf-* marker classes in rendered components support documentation selectors; component appearance comes from the prefixed utilities. They are not a public styling API.

Documentation structure

Use readable component names in navigation and headings: “Icon button” and “Data grid”. Preserve exact API identifiers inside code and prop tables. Write explanatory copy in sentence case with complete sentences.

Each component page should contain a live preview, usage, focused examples, API reference, accessibility guidance and its own source-linked design rules. Keep stable rule IDs and reviewed Figma differences when updating a component. Shared accessibility, styling and framework conventions belong in Guides; foundation values belong in Foundations.

Navigation groups are defined in lib/documentation-catalog.json. Add new components to the appropriate group without changing their public documentation URLs. If a page moves, provide redirects for both its HTML and Markdown routes.

The asset browser shares its implementation with Storybook. Keep names visible, categories searchable, and copy examples accurate for the selected artwork and supported size. Test long labels, empty results, keyboard focus and mobile layouts in the Gallery worst case story.

llms.txt, page Markdown and llms-full.txt are generated from the same content. The AI reference check guards migrated rule IDs and example source; do not create a separate manually maintained AI copy.

CI and application integration

Run pnpm pathfinder:check from the repository root. Turbo builds Pathfinder before checking its source, examples, tests, and public types. Documentation type generation runs before documentation lint. pnpm pathfinder:ci also builds the documentation and Storybook and tests packed React consumers. CI enables Next.js consumer checks with PATHFINDER_NEXT_SMOKE=1.

GitHub Actions builds the package once and shares its Turbo build cache with eight parallel jobs: formatting, library lint, library types, unit/contract tests, docs lint/types, docs production build, Storybook, and packed-consumer tests. Each job has a separate runner; heavy tasks remain sequential inside that runner. The final validate check succeeds only when the build and every matrix job succeed. Keep validate as the required branch-protection check. New commits cancel obsolete runs on the same PR. The local pathfinder:ci command still runs the complete set sequentially on one machine.

The Pathfinder workflow owns library validation. Enterprise uses these root commands:

SH
pnpm enterprise:dev
pnpm enterprise:check
pnpm enterprise:build

These commands use the same Turbo graph as CI and deployment. Enterprise builds Pathfinder's compiled exports and validates its own integration; it does not rerun Pathfinder's internal lint or type checks. Enterprise's prisma:generate task runs before development, type checking, and production builds. Prisma generation is not cached because its output lives inside pnpm-managed dependency directories.

The application package scripts are underlying tasks; use the root commands above to prepare their dependencies. The standalone Pathfinder test and test:package commands still build first. The test:unit and test:package:run tasks are scheduled by Turbo after the build; the latter packs the verified output without rerunning package lifecycle scripts. Normal pnpm pack still runs prepack.

Both workflows read Node 22 from .node-version and use pnpm 9.9.0. They share Turbo cache credentials and compatible cache restore keys. Build hashes include Pathfinder's own country data and the generated asset reference; changes to those sources also trigger Pathfinder CI. Enterprise's type-check cache tracks workspace dependency sources through transit tasks without executing their checks.

On this page