@ciscode/ui-widget-kit
v1.0.3
Published
Template repository for building reusable React TypeScript **npm libraries** (components + hooks + utilities).
Downloads
12
Readme
@ciscode/ui-widget-kit
Template repository for building reusable React TypeScript npm libraries (components + hooks + utilities).
What you get
- ESM + CJS + Types build (tsup)
- Vitest testing
- ESLint + Prettier (flat config)
- Changesets (manual release flow, no automation PR)
- Husky (pre-commit + pre-push)
- Enforced public API via
src/index.ts - Dependency-free styling (Tailwind-compatible by convention only)
reactandreact-domas peerDependencies
Peer Dependencies & Requirements
- React ecosystem:
reactandreact-dom(host-provided)react-router-dom(required if you useBreadcrumbor any router-integrated components)zod(required if you useControlledZodDynamicForm)@ciscode/ui-translate-core(optional i18n provider used by some components)
Install in host app:
npm i react react-dom react-router-dom zod @ciscode/ui-translate-corePackage structure
src/components– reusable UI componentssrc/hooks– reusable React hookssrc/utils– framework-agnostic utilitiessrc/index.ts– only public API (no deep imports allowed)
Anything not exported from src/index.ts is considered private.
Scripts
Scripts
npm run dev– start Vite dev server (for docs/examples)npm run preview– preview Vite buildnpm run build– build library todist/(tsup: ESM + CJS + dts)npm test– run unit/integration tests (Vitest)npm run test:cov– run tests with coverage reportnpm run e2e/npm run e2e:headed– run Playwright testsnpm run typecheck– TypeScript typechecknpm run type-check:watch– TypeScript typecheck in watch modenpm run lint– ESLintnpm run format/npm run format:write– Prettiernpx changeset– create a changeset Anything not exported fromsrc/index.tsis considered private.
Public API (summary)
Root exports from src/index.ts:
- Components:
Template,Breadcrumb,ControlledZodDynamicForm,TableDataCustom - Hooks:
useLocalStorage,useColorMode,generatePageNumbers - Types:
ColumnConfigTable,FieldConfigDynamicForm,ToolbarItem,SidebarItem,SidebarSection, and layout types (TemplateSidebarConfig,TemplateNavbarConfig,TemplateFooterConfig, etc.)
Internal-only components and utilities are intentionally not exported to avoid coupling (e.g. base-only table components). Use the wrapped components provided by the public API.
Router Integration
Some components (e.g., Breadcrumb) rely on React Router. In host apps, wrap your app with RouterProvider from react-router-dom and ensure Link works:
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
const router = createBrowserRouter([{ path: '/', element: <App /> }]);
export function Root() {
return <RouterProvider router={router} />;
}Usage Examples
Hooks
useLocalStorage:const [theme, setTheme] = useLocalStorage('color-theme', 'light');useLogin:const { values, update, submit, loading, error } = useLogin({ login: async ({ username, password }) => ({ user: { name: username }, token: 't123' }), schema: { parse: (v) => v }, });
Components
Breadcrumb:<Breadcrumb pageName="Dashboard" />TableDataCustom:import { TableDataCustom, type ColumnConfigTable } from '@ciscode/template-fe'; type Row = { id: number; name: string }; const columns: ColumnConfigTable<Row>[] = [ { key: 'id', title: 'ID' }, { key: 'name', title: 'Name' }, ]; <TableDataCustom<Row> columns={columns} data={[{ id: 1, name: 'Alice' }]} pagination={{ currentPage: 1, totalPages: 3, totalItems: 1, onPageChange: (p) => console.log(p), }} />;ControlledZodDynamicForm:import { ControlledZodDynamicForm, type FieldConfigDynamicForm } from '@ciscode/template-fe'; import { z } from 'zod'; const schema = z.object({ name: z.string().min(1) }); const fields: FieldConfigDynamicForm[] = [{ key: 'name', label: 'Name', type: 'text' }]; <ControlledZodDynamicForm fields={fields} schema={schema} values={{ name: '' }} onChangeField={(field, val) => { /* update your form state */ }} onSubmit={(values) => console.log(values)} />;
Migration Guide (from older template)
- Router: switch imports to
react-router-dom(Link,RouterProvider). - Forms:
ControlledZodDynamicFormexpects controlledvaluesandonChangeFieldfor reliability. - Table: use
TableDataCustomwrapper; base-only internals are private. - Exports: import only from the package root — all public APIs are re-exported via
src/index.ts.
Testing & Coverage
- Unit tests live under
tests/unit/and run injsdom. - Coverage uses
v8provider; HTML report is written tocoverage/. - We exclude demo/layout code from coverage to focus on exported library APIs.
RTL Support
- Pagination icons respond to
document.dirand mirror correctly for RTL. - Components use
ltr:/rtl:Tailwind variants where layout matters.
Release flow (summary)
- Work on a
featurebranch fromdevelop - Merge to
develop - Add a changeset for user-facing changes:
npx changeset - Promote
develop→master - Tag
vX.Y.Zto publish (npm OIDC)
Examples App
- Run the local examples to preview components:
npm run dev:examples- The examples import from the local source via an alias
@ciscode/template-fe.
To publish:
- Ensure
npm run prepublishOnlypasses (format, lint, typecheck, tests, build). - Use Changesets to bump versions and generate changelog.
- Publish with
npm publish --provenance.
Publishing Checklist
npm run prepublishOnlysucceeds- Unit coverage ≥ 80%
- E2E smoke/examples pass (optional for host-only packages)
- Changeset created and PR merged
dist/containsindex.js,index.cjs,index.d.ts
This repository is a template. Teams should clone it and focus only on library logic, not tooling or release mechanics.
