jcicl 1.0.73 → 1.0.75

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/README.md CHANGED
@@ -1,106 +1,390 @@
1
- # Welcome to the Johnson County Component Library!
1
+ # Johnson County Component Library (jcicl)
2
2
 
3
- ## Quick Start
3
+ A React component library for Johnson County, Iowa web applications. Built with TypeScript, Vite, MUI, and Emotion. Includes reusable components, form state management, data loading patterns, and page templates.
4
4
 
5
- ### Runtime Enviromnent
5
+ ## Quick Start (for consumers)
6
6
 
7
- 1. Please download and install [NVM for Windows](https://github.com/coreybutler/nvm-windows?tab=readme-ov-file)
7
+ ### Runtime Environment
8
+
9
+ 1. Download and install [NVM for Windows](https://github.com/coreybutler/nvm-windows?tab=readme-ov-file)
8
10
  2. `nvm install 22.11.0`
9
11
  3. `nvm use 22`
10
12
 
11
- ### Usage
13
+ ### Install
12
14
 
13
- `npm install jcicl@latest`
15
+ ```bash
16
+ npm install jcicl@latest
17
+ ```
14
18
 
15
- ```js
16
- import Button, { ButtonProps } from 'jcicl/Button';
17
- import Nav, { NavProps } from 'jcicl/Nav';
19
+ ### Usage
18
20
 
19
- const Component: React.FC<ButtonProps> = ({ ...buttonProps }) => <Button {...buttonProps}>Johnson County Button</Button>;
21
+ ```tsx
22
+ import Button from 'jcicl/Button';
23
+ import DataPage from 'jcicl/DataPage';
24
+ import { BaseApiClient } from 'jcicl/api';
25
+ import { createFormContext } from 'jcicl/FormContext';
20
26
  ```
21
27
 
22
- ### Adding the fonts and scrollbar styles
28
+ ### Required CSS & Fonts
23
29
 
24
- In your project entry point (most likely `main.tsx`), add:
30
+ In your project entry point (`main.tsx`), add:
25
31
 
26
- ```js
32
+ ```tsx
27
33
  import '@fontsource/roboto/300.css';
28
34
  import '@fontsource/roboto/400.css';
29
35
  import '@fontsource/roboto/500.css';
30
36
  import '@fontsource/roboto/700.css';
31
37
  import '@fontsource/material-icons';
38
+ import 'jcicl/assets/tailwind.css';
32
39
  import 'overlayscrollbars/overlayscrollbars.css';
33
40
  ```
34
41
 
35
- Alternatively, add to project root `index.html` `<head />`:
42
+ ---
36
43
 
37
- ```html
38
- <link rel="preconnect" href="https://fonts.googleapis.com" />
39
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
40
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" />
41
- ```
44
+ ## Key Features
45
+
46
+ ### BaseApiClient (`jcicl/api`)
47
+
48
+ Reusable API client base class with timeout, JSON parsing, and standardized error handling. Extend it in your app and add endpoint methods.
42
49
 
43
- #### Viewing Storybook Documentation
50
+ [View documentation](src/utils/api.ts)
44
51
 
45
- We are using [Storybook](https://storybook.js.org/docs/get-started/frameworks/react-vite?renderer=react) to document our component library
52
+ ### DataPage (`jcicl/DataPage`)
46
53
 
47
- Please use `npm run storybook` or `npm start` from the root directory to start the storybook application. You can see helpful documentation links under the `Configure your project` section of the Storybook application.
54
+ Generic component that manages async data fetching with loading, error, empty, and happy-path states. Includes `setData` for optimistic CRUD, `withWarnings` for partial success, and `guards` for data-dependent routing.
55
+
56
+ - [Overview (mid-level)](src/components/templates/DataPage/DATA_PAGE_OVERVIEW.md)
57
+ - [Beginner guide](src/components/templates/DataPage/DATA_PAGE_BEGINNER_OVERVIEW.md)
58
+
59
+ ### FormContext (`jcicl/FormContext`)
60
+
61
+ Factory function that creates typed React Context + Provider pairs for form state management. Handles text, checkbox, dropdown, phone, zip, and multi-select inputs automatically.
62
+
63
+ - [Overview (mid-level)](src/context/FormContext/FORM_CONTEXT_OVERVIEW.md)
64
+ - [Beginner guide](src/context/FormContext/FORM_CONTEXT_BEGINNER_OVERVIEW.md)
65
+ - [Comparison with react-hook-form](src/context/FormContext/AI_PATTERN_ANALYSIS.md)
66
+
67
+ ---
48
68
 
49
69
  ## Development
50
70
 
51
71
  ### Getting started
52
72
 
53
- [Please ensure your react development environment is set up](https://devops.jc.net/JCIT/Business%20Solutions%20Delivery/_wiki/wikis/Business-Solutions-Delivery.wiki?wikiVersion=GBwikiMaster&pagePath=%2FSetting%20Up%20React&pageId=219).
73
+ 1. [Ensure your React development environment is set up](https://devops.jc.net/JCIT/Business%20Solutions%20Delivery/_wiki/wikis/Business-Solutions-Delivery.wiki?wikiVersion=GBwikiMaster&pagePath=%2FSetting%20Up%20React&pageId=219)
74
+ 2. `npm install` from the root project directory
75
+ 3. `npm start` or `npm run storybook` to launch Storybook
76
+
77
+ ### Storybook
54
78
 
55
- From the root project directory, please run `npm install`
79
+ We use [Storybook](https://storybook.js.org/docs/get-started/frameworks/react-vite?renderer=react) for component documentation and visual testing.
80
+
81
+ ```bash
82
+ npm run storybook # Start Storybook dev server
83
+ npm start # Same as above
84
+ ```
85
+
86
+ ### Component directory structure
87
+
88
+ ```
89
+ src/components/
90
+ base/ # Foundational building blocks (Button, Input, Flex, etc.)
91
+ composite/ # Reusable patterns built from base components (Table, Toast, WithLoading, etc.)
92
+ supercomposite/ # Higher complexity composites (FieldGroup, FormFields, etc.)
93
+ templates/ # Full-page layouts (DefaultTemplate, AppContainer, DataPage)
94
+ ```
95
+
96
+ Each component folder contains:
97
+
98
+ - `[Component].tsx` — the component implementation
99
+ - `[Component].stories.tsx` — Storybook documentation
100
+ - `index.ts` — barrel export
56
101
 
57
102
  ### Dependencies
58
103
 
59
- For this component library, we are extending [Material UI](https://mui.com/material-ui/getting-started/) and customizing with [Emotion/Styled](https://emotion.sh/docs/styled)
104
+ - [Material UI](https://mui.com/material-ui/getting-started/) base UI components (legacy, being phased out)
105
+ - [Emotion](https://emotion.sh/docs/styled) — CSS-in-JS styling (legacy, being phased out)
106
+ - [Tailwind CSS v4](https://tailwindcss.com/) — utility-first CSS (new standard)
107
+
108
+ ---
109
+
110
+ ## Styling Migration: MUI/Emotion to Tailwind
111
+
112
+ ### Current state
113
+
114
+ The library is actively migrating from **Material UI + Emotion** to **Tailwind CSS + fully custom components**. During the transition, both approaches coexist:
60
115
 
61
- ### Components Directory Structure
116
+ - **Legacy components** use MUI base components (`MuiButton`, `MuiDrawer`, etc.) with Emotion `styled()` for visual customization
117
+ - **New and migrated components** use Tailwind utility classes directly in JSX, with CSS custom properties for runtime-dynamic values
62
118
 
63
- In each components folder, you should see a `[Component].stories.tsx` file. You can copy the established pattern to create stories for new components, or customize as you please according to the above documentation
119
+ ### Why Tailwind
64
120
 
65
- #### Base
121
+ **Broader ecosystem adoption.** Tailwind is the most widely used CSS framework in the React ecosystem. New developers joining the team are more likely to already know it than Emotion's CSS-in-JS API. This reduces onboarding time.
66
122
 
67
- Base components are intended to be the foundational building blocks of our web pages here at Johnson County
123
+ **Colocated styles.** Tailwind classes live directly on the JSX element they style. There's no need to scroll between a styled component definition and its usage, or to name every wrapper (`const StyledContainer = styled('div')(...)`). You read the element and its styles together:
68
124
 
69
- #### Composite
125
+ ```tsx
126
+ // Emotion — style is defined elsewhere, applied by component name
127
+ const CardHeader = styled('div')(({ color }) => ({
128
+ padding: '12px 16px',
129
+ backgroundColor: color,
130
+ borderRadius: '8px',
131
+ fontWeight: 600,
132
+ }));
133
+ <CardHeader color={themeColor}>Title</CardHeader>
70
134
 
71
- Composite components are intended to be reusable chunks of HTML built from base components and complimentary TSX (TypeScript XML)
135
+ // Tailwind style is on the element
136
+ <div className="p-3 px-4 rounded-lg font-semibold" style={{ backgroundColor: themeColor }}>
137
+ Title
138
+ </div>
139
+ ```
140
+
141
+ **No runtime CSS generation.** Emotion generates CSS at runtime (in the browser), which adds JavaScript execution time on every render. Tailwind generates all CSS at build time — the browser just applies static classes. This improves performance, especially on low-powered devices.
142
+
143
+ **Smaller bundle when tree-shaken.** Emotion ships ~11KB of runtime JavaScript. Tailwind ships zero runtime JS — only the CSS classes you actually use, determined at build time.
144
+
145
+ **Better DevTools experience.** Tailwind classes are visible in the browser's element inspector as real class names. Emotion generates hashed class names (`css-1a2b3c`) that are meaningless in DevTools without the React DevTools extension.
146
+
147
+ **Design token consistency.** Tailwind's theme system (`--spacing`, `--color-*`, etc.) enforces consistent spacing, colors, and typography across components. Emotion relies on manually importing and using a theme object, which is easy to forget or override inconsistently.
148
+
149
+ ### Class objects pattern
150
+
151
+ For components with multiple variants or states, define Tailwind class strings as **named constants** at module level. This keeps JSX clean and makes the style definitions reusable, testable, and easy to scan. See the Button component for the canonical example:
152
+
153
+ ```tsx
154
+ // Define class strings as named constants — one per variant
155
+ const button1Classes =
156
+ '!bg-[#009200] !h-10 !border-2 !border-transparent !text-white transition-all duration-[313ms] ease-in !rounded-[32px] !font-normal !py-3 !px-8 !text-base shadow-[0px_0px_2px_1px_rgba(100,100,100,0.63)] hover:!bg-[#005c00]';
157
+
158
+ const button2Classes =
159
+ '!bg-[#fab62d] !h-10 !border-2 !border-transparent !text-[#131313] transition-all duration-[313ms] ease-in !rounded-[32px] !font-normal !py-3 !px-8 !text-base shadow-[0px_0px_2px_1px_rgba(100,100,100,0.63)] hover:!bg-[#e0a022]';
160
+
161
+ const customButtonClasses =
162
+ '!h-10 !border-2 !border-transparent transition-all duration-[313ms] ease-in !rounded-[32px] !font-normal !py-3 !px-8 !text-base ...';
163
+
164
+ // Use in JSX — clean, one className per element
165
+ if (variant === 1) return <ButtonBase className={button1Classes} {...props}>{children}</ButtonBase>;
166
+ if (variant === 2) return <ButtonBase className={button2Classes} {...props}>{children}</ButtonBase>;
167
+ ```
168
+
169
+ **Why this pattern:**
170
+ - **Readable** — each variant's full visual definition is in one place, not scattered across JSX
171
+ - **Scannable** — you can compare two variants by looking at two adjacent constants
172
+ - **Composable** — use `clsx()` to merge base classes with conditional classes:
173
+ ```tsx
174
+ className={clsx(baseClasses, active ? activeClasses : inactiveClasses)}
175
+ ```
176
+ - **Static** — Tailwind's build can scan these constants for class names (unlike template literals with dynamic interpolation)
72
177
 
73
- #### Superomposite
178
+ ### Migration rules for contributors
74
179
 
75
- Composite with a higher level of complexity
180
+ **All new code must use Tailwind.** No new Emotion `styled()` components, no new `css` template literals.
76
181
 
77
- #### Templates
182
+ **Updating an existing Emotion component? Rewrite it in Tailwind first.** If you need to modify a component that currently uses Emotion, migrate the entire component to Tailwind before making your changes. This ensures we're always moving forward — every PR that touches a legacy component leaves it fully migrated.
183
+
184
+ The only exception is a **critical production bugfix** where the risk of a full rewrite outweighs the migration benefit. In that case, fix the bug in Emotion, file a follow-up ticket for the Tailwind migration, and note it in the PR description.
185
+
186
+ ### Tailwind patterns
187
+
188
+ **Static styles** — use class string constants (see class objects pattern above):
189
+
190
+ ```tsx
191
+ const cardClasses = 'rounded-lg p-4 bg-white shadow-md';
192
+ <div className={cardClasses}>...</div>
193
+ ```
194
+
195
+ **Runtime-dynamic values** (props that change per-instance) — use CSS custom properties with a wrapper `div`:
196
+
197
+ ```tsx
198
+ <div
199
+ style={{
200
+ '--card-bg': backgroundColor,
201
+ '--card-text': textColor,
202
+ display: 'contents',
203
+ } as React.CSSProperties}
204
+ >
205
+ <div className="rounded-lg p-4 !bg-[var(--card-bg)] !text-[var(--card-text)]">
206
+ {children}
207
+ </div>
208
+ </div>
209
+ ```
210
+
211
+ The `display: contents` wrapper is invisible to layout but provides a CSS scope for the custom properties. This avoids Emotion entirely for dynamic values.
212
+
213
+ **Conditional classes** — use `clsx`:
214
+
215
+ ```tsx
216
+ import clsx from 'clsx';
217
+
218
+ <button className={clsx(
219
+ baseClasses,
220
+ active ? '!bg-black !text-white' : '!bg-white !text-black',
221
+ )}>
222
+ ```
78
223
 
79
- Templates are intended to render the HTML for predefined page layouts comprised of composite components, base components, and complimentary TSX
224
+ **MUI overrides** use `!important` prefix (`!bg-*`, `!text-*`) when Tailwind classes need to override MUI's built-in styles during the transition period. Once a component is fully off MUI, the `!` prefixes can be removed.
80
225
 
81
- #### **All of the above component types are inteded to be importable and reusable throughout the suite of Johnson County web applications** 😊
226
+ ### Tailwind CSS output
82
227
 
83
- ### Process
228
+ Tailwind CSS is generated at build time via the `@tailwindcss/cli` postbuild step. The output lives at `dist/assets/tailwind.css`. Consuming apps import it in their entry point:
229
+
230
+ ```tsx
231
+ import 'jcicl/assets/tailwind.css';
232
+ ```
233
+
234
+ Only `tailwindcss/theme` and `tailwindcss/utilities` are included — **not** Tailwind's Preflight base reset, which would conflict with existing app styles.
235
+
236
+ ### Extending library component styles in consuming apps
237
+
238
+ With Tailwind, consuming apps can extend or override a library component's styles directly via `className` — no custom `style` prop, no wrapper `div`, no Emotion override needed:
239
+
240
+ ```tsx
241
+ // Consuming app — add margin and custom width to a library Button
242
+ <Button className="mt-4 w-full" variant={1}>
243
+ Full Width Submit
244
+ </Button>
245
+ ```
246
+
247
+ This works because Tailwind classes are just CSS classes. The consuming app's Tailwind build scans its own source files, generates the utilities, and they merge naturally with the library's classes. The consumer has full control without the library needing to expose a `style` or `className` forwarding prop for every visual property.
248
+
249
+ **Why this replaces the `style` prop pattern:**
250
+
251
+ The common pattern across our apps has been passing inline `style={{}}` objects to customize component appearance:
252
+
253
+ ```tsx
254
+ // Old pattern — inline styles scattered across consuming apps
255
+ <FormContainer style={{ paddingTop: '25px', paddingBottom: '25px' }}>
256
+ <Button style={{ width: '447px', alignSelf: 'center' }}>
257
+ <Flex styles={{ margin: '20px', fontWeight: 500 }}>
258
+ ```
259
+
260
+ This approach has problems:
261
+
262
+ - **Not reusable** — inline styles can't be shared or composed. If three pages need the same padding, each repeats the same object.
263
+ - **Not responsive** — inline styles don't support media queries, hover states, or focus states. You can't write `style={{ '@media (max-width: 768px)': { padding: '10px' } }}`.
264
+ - **Highest specificity** — inline styles override everything, making it impossible for the component to provide sensible defaults that consumers can opt out of.
265
+ - **No design tokens** — inline styles use raw pixel values (`'25px'`) instead of a shared spacing scale. Nothing enforces consistency across pages.
266
+ - **Not scannable by Tailwind** — inline styles exist at runtime. They add no value to Tailwind's build-time optimization.
267
+
268
+ With Tailwind, all of these are solved:
269
+
270
+ ```tsx
271
+ // New pattern — Tailwind classes, composable, responsive, consistent
272
+ <FormContainer className="pt-6 pb-6">
273
+ <Button className="w-[447px] self-center" variant={1}>
274
+ <Flex className="m-5 font-medium">
275
+
276
+ // Responsive? Just add a breakpoint prefix:
277
+ <FormContainer className="pt-4 pb-4 md:pt-6 md:pb-6">
278
+
279
+ // Hover/focus? Just add the state prefix:
280
+ <Button className="w-full hover:w-auto">
281
+ ```
282
+
283
+ **For component authors:** ensure your components forward `className` to the root element so consumers can extend styles. Most components already do this via `...muiProps` or `...rest` spread. As we migrate off MUI, make `className` an explicit prop.
284
+
285
+ **The goal:** eliminate all `style={{}}` props from consuming apps. Every visual customization should be expressible as a Tailwind class. If it can't be (truly dynamic runtime values like theme colors), use the CSS custom property pattern documented above.
286
+
287
+ ---
288
+
289
+ ## Accessibility (a11y)
290
+
291
+ All components should follow [WCAG 2.1 Level AA](https://www.w3.org/WAI/WCAG21/quickref/?levels=aaa) guidelines. Here's a brief overview of the key principles:
292
+
293
+ ### The four principles (POUR)
294
+
295
+ - **Perceivable** — information must be presentable in ways all users can perceive (alt text on images, sufficient color contrast, visible focus indicators)
296
+ - **Operable** — UI must be navigable by keyboard, screen reader, and assistive devices (all interactive elements focusable, no keyboard traps, adequate time limits)
297
+ - **Understandable** — content and operation must be understandable (clear labels, predictable navigation, helpful error messages)
298
+ - **Robust** — content must work with current and future assistive technologies (semantic HTML, proper ARIA attributes, valid markup)
299
+
300
+ ### Practical checklist for component development
301
+
302
+ - **Color contrast** — text must have at least 4.5:1 contrast ratio against its background (3:1 for large text). Use [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/) to verify.
303
+ - **Keyboard navigation** — every interactive element must be reachable and operable via keyboard (Tab, Enter, Escape, arrow keys). Test by unplugging your mouse.
304
+ - **Focus indicators** — focused elements must have a visible outline. Never use `outline: none` without providing an alternative focus style.
305
+ - **Semantic HTML** — use `<button>` for buttons (not `<div onClick>`), `<table>` for tabular data, `<nav>` for navigation, `<h1>`-`<h6>` in order.
306
+ - **ARIA labels** — add `aria-label` or `aria-labelledby` to interactive elements that don't have visible text labels (icon buttons, inputs without visible labels).
307
+ - **Screen reader testing** — test with [NVDA](https://www.nvaccess.org/) (free, Windows) or the browser's built-in accessibility inspector.
308
+ - **Form inputs** — every input must have an associated `<label>`. Our `LabeledInput`, `LabeledDropdown`, and `LabeledCheckbox` components handle this automatically.
309
+ - **Error messages** — form errors should be announced to screen readers via `aria-live="polite"` or `role="alert"`.
310
+
311
+ ### Resources
312
+
313
+ - [WCAG 2.1 Quick Reference](https://www.w3.org/WAI/WCAG21/quickref/)
314
+ - [WebAIM — Web Accessibility in Mind](https://webaim.org/)
315
+ - [MDN Accessibility Guide](https://developer.mozilla.org/en-US/docs/Web/Accessibility)
316
+ - [A11y Project Checklist](https://www.a11yproject.com/checklist/)
317
+ - [Inclusive Components (book/blog)](https://inclusive-components.design/)
318
+
319
+ ---
320
+
321
+ ## Building & Testing Locally
322
+
323
+ ### Build the library
324
+
325
+ ```bash
326
+ npm run build
327
+ ```
328
+
329
+ This runs TypeScript compilation, Vite build, Tailwind CSS generation, and packages everything into `dist/`.
330
+
331
+ ### Test locally in a consuming app (without publishing)
332
+
333
+ Instead of publishing to npm, you can install the built `dist/` folder directly into a consuming app:
334
+
335
+ ```bash
336
+ # 1. Build the library
337
+ cd /path/to/your/local/JCComponentLibrary
338
+ npm run build
339
+
340
+ # 2. Install from local dist in your consuming app
341
+ cd /path/to/your/consumingApplication # or any consuming app
342
+ npm install /path/to/your/local/JCComponentLibrary/dist
343
+
344
+ # 3. Verify it works
345
+ npm run dev
346
+ ```
347
+
348
+ This creates a symlink-like install in `node_modules/jcicl` pointing to the local `dist/` folder. Changes take effect immediately after rebuilding the library — no version bump or publish needed.
349
+
350
+ **To revert to the published version:**
351
+
352
+ ```bash
353
+ npm install jcicl@latest
354
+ ```
355
+
356
+ ### Build + publish (when ready to release)
357
+
358
+ ```bash
359
+ npm run bp # Patch version bump (0.0.x), build, and publish
360
+ npm run bpMinor # Minor version bump (0.x.0)
361
+ npm run bpMajor # Major version bump (x.0.0)
362
+ ```
84
363
 
85
- 1. Add or update any components you wish. For new components, please create the associated `[NewComponent].stories.tsx` file to allow for documentation. In `.storybook/main.ts`, we are using the default string matching pattern to automatically index `*.stories.*` files 😊
86
- 2. Export any newly created components in the relevant index files: `(base/(super)composite/templates)/[NewComponent]/index.ts` and `components/index.ts`.
87
- 3. Export any newly created types for the component from `(base/(super)composite/templates)/[NewComponent]/index.ts`
88
- 4. Publish the library and update relevant project dependencies
364
+ The library also auto-publishes on merges to master via the CI pipeline.
89
365
 
90
- ### Publishing the library
366
+ ---
91
367
 
92
- The library will automatically publish a new minor version on merges to master. If you need to manually publish a new version:
368
+ ## Adding a New Component
93
369
 
94
- `npm run bp`
370
+ 1. Create the component folder: `src/components/base/MyComponent/`
371
+ 2. Create the component: `MyComponent.tsx`
372
+ 3. Create stories: `MyComponent.stories.tsx`
373
+ 4. Create barrel export: `index.ts` — `export { default, type MyComponentProps } from './MyComponent';`
374
+ 5. Add to the main barrel: `src/components/index.ts` — `export { default as MyComponent } from './base/MyComponent';`
375
+ 6. Build and test locally (see above)
376
+ 7. Publish when ready
95
377
 
96
- - Creates a new minor version (`0.0.x`), builds, and publishes the library to the npm registry
378
+ ---
97
379
 
98
- `npm run bpMinor` for minor versions (`0.x.0`), and `npm run bpMajor` for major versions (`x.0.0`)
380
+ ## Deploying Storybook
99
381
 
100
- For more details on scripting commands, please see the [npm CLI documentation](https://docs.npmjs.com/cli/v9/commands)
382
+ Build Storybook with `npm run build-storybook`, then copy all files from `storybook-static/` to the hosting location.
101
383
 
102
- ### Deploying storybook
384
+ ---
103
385
 
104
- TODO: Automate
386
+ ## Useful Links
105
387
 
106
- Build the library with `npm run storybook`, then copy all of the files in `storybook-static` into `windu\E:\ComponentLibrary`
388
+ - [Component Library Repository](https://devops.jc.net/JCIT/Business%20Solutions%20Delivery/_git/JCComponentLibrary)
389
+ - [Setting Up React (internal wiki)](https://devops.jc.net/JCIT/Business%20Solutions%20Delivery/_wiki/wikis/Business-Solutions-Delivery.wiki?wikiVersion=GBwikiMaster&pagePath=%2FSetting%20Up%20React&pageId=219)
390
+ - [npm CLI documentation](https://docs.npmjs.com/cli/v9/commands)
package/Table/Table.d.ts CHANGED
@@ -48,6 +48,11 @@ export interface TableProps {
48
48
  scrollableMinWidth?: string;
49
49
  stickyColumns?: number;
50
50
  columnOrder?: string[];
51
+ /** Unique key for persisting filter/sort/column state to localStorage. If omitted, state is not persisted. */
52
+ persistKey?: string;
53
+ /** Custom renderers for specific columns. Only applied to visible rows — not used for sorting, filtering, or export.
54
+ * Use this for React components (like live Timers) that should only mount on the current page. */
55
+ cellRenderers?: Record<string, (value: any, row: Record<string, any>) => React.ReactNode>;
51
56
  }
52
57
  declare const DataTable: React.FC<TableProps>;
53
58
  export default DataTable;