Shared React component library for NCI OCPL applications.
Browse the component library and interactive examples at the Storybook documentation site.
This library provides a canonical set of reusable React components used across NCI web applications. Components are organized into two categories:
- Core Components -- Framework-agnostic components with self-contained styling (Spinner, ErrorBoundary, Autocomplete, etc.)
- NCIDS Components -- Components that integrate with the NCI Design System (Button, Accordion, Modal, etc.)
- React
>=17.0.0and React DOM>=17.0.0(the build uses the modernreact/jsx-runtimetransform). @nciocpl/ncids-css>=3.0.0is required to use any NCIDS component (Pager, Collection, etc.). It is declared as an optional peer so apps that only use core components are not forced to install it.
pnpm add @nciocpl/react-components @nciocpl/ncids-cssNCIDS components rely on USWDS CSS classes. The library ships a pre-bundled stylesheet that compiles the relevant NCIDS/USWDS modules. Import it once at your app entry:
// e.g. src/main.tsx
import '@nciocpl/react-components/styles';The bundled CSS resolves USWDS sprite/font URLs against /img. Configure your app to serve node_modules/@nciocpl/ncids-css/uswds-img at that path.
Vite (vite.config.ts):
import { defineConfig } from 'vite';
import path from 'node:path';
export default defineConfig({
publicDir: path.resolve(
__dirname,
'node_modules/@nciocpl/ncids-css/uswds-img'
),
// ...or copy the directory to your existing public/ as `public/img`
});Webpack / Create React App: copy node_modules/@nciocpl/ncids-css/uswds-img into your public/img folder (e.g. via copy-webpack-plugin or a postinstall script).
If your app already compiles NCIDS SCSS for non-React UI, skip the bundled stylesheet — the components render with whatever NCIDS rules you have loaded.
// Import from the package root
import { Pager, Collection, CollectionItem } from '@nciocpl/react-components';
// Or scope imports to a category
import { Pager } from '@nciocpl/react-components/ncids';- Node.js >= 18.0.0
- pnpm >= 8.0.0
# Install dependencies
pnpm install
# Start Storybook for development
pnpm dev
# Run tests
pnpm test
# Build the library
pnpm build
# Type checking
pnpm typecheck| Command | Description |
|---|---|
pnpm dev |
Start Storybook dev server on port 6006 |
pnpm test |
Run test suite |
pnpm test:watch |
Run tests in watch mode |
pnpm test:coverage |
Run tests with coverage report |
pnpm build |
Build the library (ESM + CJS + types) |
pnpm lint |
Lint source files |
pnpm lint:fix |
Lint and auto-fix source files |
pnpm format |
Format source files with Prettier |
pnpm format:check |
Check formatting without writing |
pnpm typecheck |
Run TypeScript type checking |
pnpm storybook:build |
Build static Storybook site |
Tests use Vitest with React Testing Library and vitest-axe for accessibility testing.
# Run all tests
pnpm test
# Run tests in watch mode (re-runs on file changes)
pnpm test:watch
# Run tests with coverage report
pnpm test:coverageTest files should be colocated with the source they test using the *.test.ts or *.test.tsx naming convention:
src/
├── components/
│ └── core/
│ └── Spinner/
│ ├── Spinner.tsx
│ └── Spinner.test.tsx
Coverage thresholds are set to 80% for branches, functions, lines, and statements. The coverage report is generated using the v8 provider.
src/
├── components/
│ ├── core/ # Framework-agnostic components
│ └── ncids/ # NCIDS design system components
├── hooks/ # Shared React hooks
├── utils/ # Utility functions
└── types/ # Shared TypeScript types
See docs/contributing.md for guidelines.
Apache-2.0 -- see LICENSE for details.