@publicplan/kern-react-kit 1.3.1 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,316 @@
1
+ # Technical Reference: Kern React Kit
2
+
3
+ ## Installation & Setup
4
+
5
+ ### NPM Installation
6
+ ```bash
7
+ npm install @publicplan/kern-react-kit react react-dom
8
+ ```
9
+
10
+ ### Required Peer Dependencies
11
+ - React 18.2.0 or higher
12
+ - React DOM 18.2.0 or higher (or React 19.1.0+)
13
+
14
+ ### ESM/CommonJS Support
15
+ The library ships with:
16
+ - **ESM**: `dist/index.js` (default for `import`)
17
+ - **CommonJS**: `dist/index.cjs` (for `require()`)
18
+ - **Types**: `dist/index.d.ts` (ESM), `dist/index.d.cts` (CJS)
19
+ - **Styles**: `dist/index.css`
20
+
21
+ ### Basic Setup in React App
22
+ ```typescript
23
+ // src/main.tsx (or App.tsx)
24
+ import React from 'react';
25
+ import ReactDOM from 'react-dom/client';
26
+ import App from './App';
27
+
28
+ // Import styles globally
29
+ import '@publicplan/kern-react-kit/index.css';
30
+
31
+ ReactDOM.createRoot(document.getElementById('root')!).render(
32
+ <React.StrictMode>
33
+ <App />
34
+ </React.StrictMode>
35
+ );
36
+ ```
37
+
38
+ ## API Stability & Import Contracts
39
+
40
+ ### Public API (Stable)
41
+ The following are guaranteed to be stable and forward-compatible:
42
+ 1. **Named exports from main entry**: `import { Button, Card, ... } from '@publicplan/kern-react-kit'`
43
+ 2. **Type exports**: `import type { ButtonProps, CardProps, ... } from '@publicplan/kern-react-kit'`
44
+ 3. **Subpath exports**: `import { Button } from '@publicplan/kern-react-kit/Button'`
45
+ 4. **Style sheet**: `@publicplan/kern-react-kit/index.css`
46
+ 5. **Input components**: `TextInput`, `TextareaInput`, `CheckboxInput`, `RadioInput`, `SelectInput`,
47
+ `EmailInput`, `UrlInput`, `TelInput`, `DateInput`, `PasswordInput`, `NumberInput`, `FileInput`, `CheckboxList`
48
+
49
+ ### Internal/Unstable (Do Not Use)
50
+ Avoid importing:
51
+ - Anything from `dist/` or `dist/components/*/internal`
52
+ - Context or hook internals (unless explicitly re-exported at top level)
53
+ - SCSS files (use CSS variables instead)
54
+ - Test utilities from `__tests__/`
55
+
56
+ ### Deprecation Policy
57
+ Breaking changes will be announced via:
58
+ - CHANGELOG.md updates
59
+ - Major version bump in semver
60
+ - Notice in release notes on GitHub
61
+
62
+ ## Theming & CSS Variables
63
+
64
+ ### Theme Customization
65
+ All components use CSS custom properties. Override them at the `:root` level or scoped to a parent:
66
+
67
+ ```css
68
+ /* Global override */
69
+ :root {
70
+ --kern-color-primary: #0066cc;
71
+ --kern-color-secondary: #666666;
72
+ --kern-spacing-xs: 0.5rem;
73
+ --kern-spacing-sm: 1rem;
74
+ --kern-spacing-md: 1.5rem;
75
+ --kern-spacing-lg: 2rem;
76
+ --kern-spacing-xl: 3rem;
77
+ --kern-radius-sm: 0.25rem;
78
+ --kern-radius-md: 0.5rem;
79
+ --kern-radius-lg: 1rem;
80
+ --kern-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1);
81
+ --kern-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
82
+ --kern-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
83
+ }
84
+
85
+ /* Scoped override (e.g., for a specific card) */
86
+ .my-special-card {
87
+ --kern-color-primary: #ff6600;
88
+ --kern-spacing-lg: 4rem;
89
+ }
90
+ ```
91
+
92
+ ### Available CSS Variables
93
+ - **Colors**: `--kern-color-{primary,secondary,success,warning,error,neutral,*}`
94
+ - **Spacing**: `--kern-spacing-{xs,sm,md,lg,xl}`
95
+ - **Radius**: `--kern-radius-{sm,md,lg}`
96
+ - **Shadows**: `--kern-shadow-{sm,md,lg}`
97
+ - **Typography**: `--kern-font-{body,heading,mono,*}`, `--kern-font-size-{sm,md,lg,xl}`
98
+ - **Z-index**: `--kern-z-{dropdown,sticky,fixed,modal,tooltip}`
99
+
100
+ See `src/styles/_variables.scss` in the repository for the complete list.
101
+
102
+ ## Styling & CSS Architecture
103
+
104
+ ### Class Naming Convention
105
+ All component classes use the `kern-` prefix:
106
+ - `.kern-btn` (Button)
107
+ - `.kern-card` (Card)
108
+ - `.kern-input` (Input)
109
+ - `.kern-label` (Label)
110
+ - `.kern-modal` (Dialog modal)
111
+ - `.kern-sr-only` (Screen reader only utility)
112
+
113
+ ### CSS Utility Classes
114
+ Commonly used utility classes:
115
+ - `.kern-sr-only`: Hide visually but keep accessible to screen readers
116
+ - `.kern-flex`, `.kern-grid`: Layout utilities
117
+ - `.kern-text-{sm,md,lg}`: Typography sizes
118
+
119
+ ### Custom Styling Components
120
+ ```css
121
+ /* my-custom-styles.css */
122
+ .my-button-wrapper .kern-btn {
123
+ --kern-color-primary: #my-color;
124
+ border-radius: 999px; /* Override radius if needed */
125
+ }
126
+ ```
127
+
128
+ ### SCSS & PostCSS
129
+ The library uses SCSS internally, but **do not depend on SCSS exports**. The compiled CSS is the public interface.
130
+
131
+ ## Accessibility Guidelines
132
+
133
+ ### Components Guarantee
134
+ - **Semantic HTML**: All components use correct HTML elements (`button`, `input`, etc.)
135
+ - **ARIA Labels**: Interactive components have `aria-label`, `aria-labelledby`, or explicit text content
136
+ - **Keyboard Accessible**: Tab navigation, Enter/Space to activate, Escape to close modals
137
+ - **Focus Management**: Focus is managed appropriately (e.g., returns to trigger after modal closes)
138
+ - **Color Contrast**: All text meets WCAG AA standards (4.5:1 for normal text)
139
+ - **Testing**: Components are tested with axe-core and vitest-axe
140
+
141
+ ### Developer Responsibilities
142
+ When using components:
143
+ 1. **Provide context**: Use `TextInput`'s `label` prop or `Label` with `htmlFor`
144
+ 2. **Handle focus**: Manage focus for dynamic content
145
+ 3. **Use semantic HTML**: Don't repurpose components for unintended purposes
146
+ 4. **Test accessibility**: Run accessibility tests in your own code (axe, jest-axe, etc.)
147
+ 5. **Provide alt text**: For images and icons, use `alt` or `aria-label`
148
+ 6. **Icons in Alert/Link**: Icons are `aria-hidden="true"` by default; if the icon conveys meaning, set `aria-hidden={false}` and provide `aria-label`.
149
+
150
+ Example:
151
+ ```typescript
152
+ import { TextInput } from '@publicplan/kern-react-kit';
153
+
154
+ // ✅ Correct: Labeled input with helper text
155
+ <TextInput
156
+ id="username"
157
+ name="username"
158
+ label="Username"
159
+ hintText="Your login username"
160
+ aria-describedby="help-text"
161
+ />
162
+ <span id="help-text">Your login username</span>
163
+
164
+ // ❌ Incorrect: Orphaned input, no label
165
+ <TextInput placeholder="Username" />
166
+ ```
167
+
168
+ ### WCAG 2.1 Level AA Compliance
169
+ All components are designed to meet WCAG 2.1 Level AA standards. Agents must not modify component behavior in ways that break accessibility.
170
+
171
+ ## Testing Expectations
172
+
173
+ ### Unit Testing with Vitest
174
+ - Test files use `vitest` and `@testing-library/react`
175
+ - Pattern: `ComponentName.test.tsx` in `__tests__/components/`
176
+ - Expect components to accept standard React props (ref, className, etc.)
177
+ - Use `render()` from `@testing-library/react`
178
+
179
+ ```typescript
180
+ import { render, screen } from '@testing-library/react';
181
+ import userEvent from '@testing-library/user-event';
182
+ import { Button } from '@publicplan/kern-react-kit';
183
+
184
+ describe('Button', () => {
185
+ test('renders with text', () => {
186
+ render(<Button>Click me</Button>);
187
+ expect(screen.getByRole('button', { name: /click me/i })).toBeInTheDocument();
188
+ });
189
+
190
+ test('fires onClick handler', async () => {
191
+ const user = userEvent.setup();
192
+ const handleClick = vi.fn();
193
+ render(<Button onClick={handleClick}>Click</Button>);
194
+ await user.click(screen.getByRole('button'));
195
+ expect(handleClick).toHaveBeenCalled();
196
+ });
197
+ });
198
+ ```
199
+
200
+ ### Storybook Stories
201
+ - All components have Storybook stories for isolated development
202
+ - Location: `ComponentName.stories.tsx` co-located with component
203
+ - Stories demonstrate default, variant, and edge-case states
204
+ - Use Storybook Docs addon for automatically generated documentation
205
+
206
+ ### E2E Testing with Playwright
207
+ - E2E tests live in `__tests__/e2e/`
208
+ - Test real user workflows in a browser
209
+ - Pattern: Playwright test files (`.spec.ts`)
210
+
211
+ ## Build Artifacts
212
+
213
+ ### What Gets Published
214
+ The `package.json` has `"files": ["dist/"]`, so only the `dist/` folder is published to npm:
215
+ - `dist/index.js` (ESM)
216
+ - `dist/index.cjs` (CommonJS)
217
+ - `dist/index.css` (Compiled stylesheet)
218
+ - `dist/index.d.ts` (Type definitions)
219
+ - `dist/components/*/index.{js,cjs,d.ts}` (Component exports)
220
+ - `dist/skills/` (This skill documentation—included!)
221
+
222
+ ### Build Command
223
+ ```bash
224
+ npm run build
225
+ ```
226
+
227
+ This runs:
228
+ 1. `build:skills` – Copy skill docs from `skills/` to `dist/skills/`
229
+ 2. `tsdown` – Transpile TypeScript and output ESM/CJS to `dist/`
230
+ 3. `sass` – Compile global styles to `dist/index.css`
231
+
232
+ ### Incremental Builds
233
+ For development, use:
234
+ ```bash
235
+ npm run dev
236
+ ```
237
+
238
+ This starts Vite in dev mode for fast iteration.
239
+
240
+ ## CommonJS & ESM Compatibility
241
+
242
+ ### Module Resolution
243
+ The package exports both ESM and CommonJS entry points:
244
+
245
+ **ESM (Node 12+, modern bundlers)**:
246
+ ```javascript
247
+ import { Button } from '@publicplan/kern-react-kit';
248
+ ```
249
+
250
+ **CommonJS (Node.js)**:
251
+ ```javascript
252
+ const { Button } = require('@publicplan/kern-react-kit');
253
+ ```
254
+
255
+ Both are compiled from the same TypeScript source and have identical behavior.
256
+
257
+ ### Tree-Shaking
258
+ ESM builds support tree-shaking. Unused components are removed during bundling:
259
+ ```javascript
260
+ // Only Button code is included in the bundle
261
+ import { Button } from '@publicplan/kern-react-kit';
262
+ ```
263
+
264
+ ## Performance Considerations
265
+
266
+ ### Component Rendering
267
+ - Components are optimized with `React.memo` where beneficial
268
+ - Avoid passing inline objects as props (memoize or use useMemo)
269
+ - Use `ref` for imperative operations sparingly
270
+
271
+ Example:
272
+ ```typescript
273
+ // ✅ Good: Stable object
274
+ const buttonProps = { variant: 'primary' as const };
275
+ <Button {...buttonProps}>Click</Button>
276
+
277
+ // ❌ Avoid: Inline object recreated on each render
278
+ <Button {...{ variant: 'primary' }}>Click</Button>
279
+ ```
280
+
281
+ ### Bundle Size
282
+ Kern React Kit is a lean library (~45KB gzipped including CSS). Avoid importing unused components; modern bundlers tree-shake unused code automatically.
283
+
284
+ ## Debugging
285
+
286
+ ### Enable Debug Logging
287
+ Some components log development hints (e.g., missing required props) in development mode. Check the browser console.
288
+
289
+ ### Check Compiled Styles
290
+ If styles don't apply, verify:
291
+ 1. `@publicplan/kern-react-kit/index.css` is imported in your app
292
+ 2. CSS custom properties are defined (fallback values apply if missing)
293
+ 3. No CSS specificity conflicts override component styles
294
+
295
+ ### Type Checking
296
+ Run TypeScript compiler in watch mode:
297
+ ```bash
298
+ npx tsc --noEmit --watch
299
+ ```
300
+
301
+ ## Versioning & Compatibility Matrix
302
+
303
+ | React Version | Kern Kit Support |
304
+ |---|---|
305
+ | 18.2.0 – 18.x | ✅ Full |
306
+ | 19.1.0+ | ✅ Full |
307
+ | < 18.2.0 | ❌ Not supported |
308
+
309
+ Semantic versioning is used:
310
+ - **Major**: Breaking changes (e.g., removed components, prop signature changes)
311
+ - **Minor**: New features, new components (backward compatible)
312
+ - **Patch**: Bug fixes, security updates
313
+
314
+ ---
315
+
316
+ *Last updated: 2026-03-03*
@@ -0,0 +1,10 @@
1
+ {
2
+ "package": "@publicplan/kern-react-kit",
3
+ "skills": [
4
+ {
5
+ "name": "kern-react-kit",
6
+ "path": "dist/skills/kern-react-kit/SKILL.md",
7
+ "entry": "dist/skills/kern-react-kit/SKILL.md"
8
+ }
9
+ ]
10
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@publicplan/kern-react-kit",
3
- "version": "1.3.1",
3
+ "version": "1.3.3",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -19,6 +19,8 @@
19
19
  }
20
20
  },
21
21
  "./index.css": "./dist/index.css",
22
+ "./skills": "./dist/skills/skills.index.json",
23
+ "./skills/kern-react-kit": "./dist/skills/kern-react-kit/SKILL.md",
22
24
  "./*": {
23
25
  "import": {
24
26
  "types": "./dist/components/*/index.d.ts",
@@ -40,14 +42,16 @@
40
42
  "scripts": {
41
43
  "prepare": "husky install",
42
44
  "dev": "vite --config vite.lib.config.ts",
43
- "build": "tsdown && sass src/styles/global.scss dist/index.css --no-source-map",
45
+ "build:skills": "node scripts/build-skills.mjs",
46
+ "build": "tsdown && npm run build:skills && sass src/styles/global.scss dist/index.css --no-source-map",
44
47
  "lint": "eslint \"./src/**/*.{ts,tsx}\" --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
45
48
  "lint:fix": "eslint \"./src/**/*.{ts,tsx}\" --ext ts,tsx --report-unused-disable-directives --fix",
46
49
  "test": "vitest",
47
50
  "test:watch": "vitest --watch",
48
51
  "format": "prettier --ignore-path .gitignore \"./src/**/*.+(ts|js|tsx)\" --write",
49
52
  "storybook": "storybook dev --port 6006",
50
- "storybook:build": "storybook build -o storybooks/public"
53
+ "storybook:build": "storybook build -o storybooks/public",
54
+ "test:e2e": "start-server-and-test storybook http://localhost:6006 'playwright test'"
51
55
  },
52
56
  "keywords": [],
53
57
  "author": "publicplan",
@@ -57,10 +61,11 @@
57
61
  "react-dom": "^18.2.0 || ^19.1.0"
58
62
  },
59
63
  "dependencies": {
60
- "@kern-ux/native": "^2.3.0",
64
+ "@kern-ux/native": "^2.4.0",
61
65
  "tslib": "^2.8.1"
62
66
  },
63
67
  "devDependencies": {
68
+ "@playwright/test": "^1.58.2",
64
69
  "@semantic-release/changelog": "^6.0.3",
65
70
  "@semantic-release/commit-analyzer": "^13.0.1",
66
71
  "@semantic-release/git": "^10.0.1",
@@ -90,6 +95,7 @@
90
95
  "jsdom": "^27.0.0",
91
96
  "prettier": "^3.5.3",
92
97
  "sass": "^1.89.0",
98
+ "start-server-and-test": "^2.1.3",
93
99
  "storybook-addon-pseudo-states": "^9.1.8",
94
100
  "tsdown": "^0.14.1",
95
101
  "typescript": "^5.8.3",