@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.
- package/dist/index.cjs +235 -187
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +24 -0
- package/dist/index.d.cts +52 -44
- package/dist/index.d.ts +52 -44
- package/dist/index.js +235 -188
- package/dist/index.js.map +1 -1
- package/dist/skills/kern-react-kit/SKILL.md +343 -0
- package/dist/skills/kern-react-kit/references/COMPONENTS.md +686 -0
- package/dist/skills/kern-react-kit/references/REFERENCE.md +316 -0
- package/dist/skills/skills.index.json +10 -0
- package/package.json +10 -4
|
@@ -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*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@publicplan/kern-react-kit",
|
|
3
|
-
"version": "1.3.
|
|
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": "
|
|
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.
|
|
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",
|