@codefast/ui 0.3.13 → 0.3.14-canary.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @codefast/ui
2
2
 
3
+ ## 0.3.14-canary.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies []:
8
+ - @codefast/tailwind-variants@0.3.14-canary.1
9
+
10
+ ## 0.3.14-canary.0
11
+
12
+ ### Patch Changes
13
+
14
+ - [`b44597c`](https://github.com/codefastlabs/codefast/commit/b44597c9ec3a121a707aa269d7f68550ae1da72a) Thanks [@thevuong](https://github.com/thevuong)! - docs: enhance type annotations and comments for clarity across multiple files
15
+
16
+ - [`8109f4e`](https://github.com/codefastlabs/codefast/commit/8109f4e1f8186b91c296d25d640594b43493cdef) Thanks [@thevuong](https://github.com/thevuong)! - docs: update README.md files across packages for consistency and clarity
17
+
18
+ - [`ab6bf8d`](https://github.com/codefastlabs/codefast/commit/ab6bf8d5b1c421930e391724cbbdcaf63b9bc263) Thanks [@thevuong](https://github.com/thevuong)! - docs(ui): update README.md for clarity and structure
19
+
20
+ - Updated dependencies [[`85e5ac1`](https://github.com/codefastlabs/codefast/commit/85e5ac122d7a75f756ae4c03b5ab5e9489823b59), [`8109f4e`](https://github.com/codefastlabs/codefast/commit/8109f4e1f8186b91c296d25d640594b43493cdef)]:
21
+ - @codefast/tailwind-variants@0.3.14-canary.0
22
+
3
23
  ## 0.3.13
4
24
 
5
25
  ### Patch Changes
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @codefast/ui
2
2
 
3
- Core UI components library built with React, Tailwind CSS, and Radix UI for creating modern, accessible, and customizable user interfaces with a comprehensive design system.
3
+ Accessible, typed React components built on Radix UI primitives and styled with Tailwind CSS 4.
4
4
 
5
5
  [![CI](https://github.com/codefastlabs/codefast/actions/workflows/release.yml/badge.svg)](https://github.com/codefastlabs/codefast/actions/workflows/release.yml)
6
6
  [![npm version](https://img.shields.io/npm/v/@codefast/ui.svg)](https://www.npmjs.com/package/@codefast/ui)
@@ -8,498 +8,398 @@ Core UI components library built with React, Tailwind CSS, and Radix UI for crea
8
8
  [![bundle size](https://img.shields.io/bundlephobia/minzip/@codefast/ui)](https://bundlephobia.com/package/@codefast/ui)
9
9
  [![license](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
10
10
 
11
+ ---
12
+
11
13
  ## Table of Contents
12
14
 
13
- - [Overview](#overview)
15
+ - [Why @codefast/ui](#why-codefastui)
16
+ - [Requirements](#requirements)
14
17
  - [Installation](#installation)
15
- - [Styling Integration](#styling-integration)
16
- - [SSR with Nitro (TanStack Start)](#ssr-with-nitro-tanstack-start)
18
+ - [Styling](#styling)
19
+ - [With an existing Tailwind 4 setup (recommended)](#with-an-existing-tailwind-4-setup-recommended)
20
+ - [Standalone (no Tailwind yet)](#standalone-no-tailwind-yet)
21
+ - [Theme palettes](#theme-palettes)
22
+ - [Dark mode](#dark-mode)
23
+ - [Customizing tokens](#customizing-tokens)
17
24
  - [Quick Start](#quick-start)
18
- - [Components](#components)
19
- - [Layout](#layout)
20
- - [Form](#form)
21
- - [Navigation](#navigation)
22
- - [Overlay](#overlay)
23
- - [Data Display](#data-display)
24
- - [Usage Examples](#usage-examples)
25
- - [Theming and Customization](#theming-and-customization)
26
- - [API Reference](#api-reference)
25
+ - [Component catalog](#component-catalog)
26
+ - [Hooks](#hooks)
27
+ - [Primitives and utilities](#primitives-and-utilities)
28
+ - [SSR with Nitro (TanStack Start)](#ssr-with-nitro-tanstack-start)
29
+ - [Troubleshooting](#troubleshooting)
27
30
  - [Accessibility](#accessibility)
28
- - [Browser Compatibility](#browser-compatibility)
31
+ - [Browser support](#browser-support)
29
32
  - [Contributing](#contributing)
30
33
  - [License](#license)
31
34
  - [Changelog](#changelog)
32
35
 
33
- ## Overview
36
+ ---
34
37
 
35
- `@codefast/ui` provides **60+ accessible components** for building production-grade user interfaces. Every component is built on [Radix UI](https://radix-ui.com/) primitives, styled with [Tailwind CSS 4](https://tailwindcss.com/), and fully typed with TypeScript.
38
+ ## Why @codefast/ui
36
39
 
37
- **Key features:**
40
+ - **62+ components** across layout, form, navigation, overlay, and data-display categories.
41
+ - **Built on [Radix UI](https://www.radix-ui.com/)** — keyboard navigation, focus management, and ARIA semantics come for free.
42
+ - **Tailwind CSS 4** tokens shipped as CSS files (`@codefast/ui/css/*`), with 22 palette variants and a dark-mode scheme.
43
+ - **Fully typed.** Every component exports its props (`ButtonProps`, `DialogContentProps`, …) for use in wrappers.
44
+ - **Side-effect-free ESM** with per-component subpaths — bundlers tree-shake to what you actually import.
45
+ - **Dependency-light.** Only the Radix + headless-UI libraries that each component needs are pulled in.
38
46
 
39
- - **60+ Components** -- Layout, form, navigation, overlay, and data display categories.
40
- - **Accessible by Default** -- WAI-ARIA compliant with keyboard navigation and screen reader support.
41
- - **Fully Typed** -- Complete TypeScript definitions for all components and props.
42
- - **Customizable** -- Extend styles with Tailwind CSS utility classes or Tailwind Variants.
43
- - **Tree-shakeable** -- Import only the components you use.
47
+ ---
44
48
 
45
- ## Installation
49
+ ## Requirements
46
50
 
47
- ```bash
48
- pnpm add @codefast/ui
49
- ```
51
+ - React `^19` and `react-dom` (peer; `@types/*` are optional peers)
52
+ - Tailwind CSS `4.x` at build time (only if you use one of the theme CSS imports)
53
+ - TypeScript `>= 5.9` (recommended)
54
+
55
+ ---
50
56
 
51
- Or using npm:
57
+ ## Installation
52
58
 
53
59
  ```bash
60
+ pnpm add @codefast/ui
61
+ # or
54
62
  npm install @codefast/ui
63
+ # or
64
+ yarn add @codefast/ui
55
65
  ```
56
66
 
57
- **Peer dependencies:**
67
+ Peers:
58
68
 
59
69
  ```bash
60
70
  pnpm add react react-dom
61
71
  pnpm add -D @types/react @types/react-dom
62
72
  ```
63
73
 
64
- **Requirements:**
74
+ ---
65
75
 
66
- - Node.js >= 24.0.0 (LTS)
67
- - React >= 19.0.0
68
- - TypeScript >= 5.9.2 (recommended)
69
- - Tailwind CSS 4.x (for styling)
76
+ ## Styling
70
77
 
71
- ## Styling Integration
78
+ `@codefast/ui` ships theme tokens and component-layer styles as CSS files under `@codefast/ui/css/*`. Pick the integration that matches your project.
72
79
 
73
- `@codefast/ui` requires CSS styles to render correctly. Choose one of the following approaches based on your project setup.
80
+ ### With an existing Tailwind 4 setup (recommended)
74
81
 
75
- ### Option 1: Project Already Uses Tailwind CSS (Recommended)
76
-
77
- If your project already has Tailwind CSS 4.x configured (e.g. Vite, Next.js, TanStack Start), import only the **theme variables** and **preset** to avoid duplicate Tailwind output:
78
-
79
- **1. In your main CSS file** (e.g. `src/styles.css` or `src/index.css`):
82
+ Import the palette and the preset **after** `tailwindcss` so Tailwind isn't duplicated:
80
83
 
81
84
  ```css
85
+ /* src/styles.css (or app/globals.css, …) */
82
86
  @import "tailwindcss";
83
87
 
84
- /* @codefast/ui theme variables & preset (must come after tailwindcss) */
88
+ /* @codefast/ui tokens + preset */
85
89
  @import "@codefast/ui/css/slate.css";
86
90
  @import "@codefast/ui/css/preset.css";
87
91
  ```
88
92
 
89
- **2. Select a theme.** Available themes (replace `slate` with any below):
90
-
91
- | Theme | Import Path |
92
- | ------- | ------------------------------ |
93
- | slate | `@codefast/ui/css/slate.css` |
94
- | gray | `@codefast/ui/css/gray.css` |
95
- | zinc | `@codefast/ui/css/zinc.css` |
96
- | neutral | `@codefast/ui/css/neutral.css` |
97
- | stone | `@codefast/ui/css/stone.css` |
98
- | red | `@codefast/ui/css/red.css` |
99
- | orange | `@codefast/ui/css/orange.css` |
100
- | amber | `@codefast/ui/css/amber.css` |
101
- | yellow | `@codefast/ui/css/yellow.css` |
102
- | lime | `@codefast/ui/css/lime.css` |
103
- | green | `@codefast/ui/css/green.css` |
104
- | emerald | `@codefast/ui/css/emerald.css` |
105
- | teal | `@codefast/ui/css/teal.css` |
106
- | cyan | `@codefast/ui/css/cyan.css` |
107
- | sky | `@codefast/ui/css/sky.css` |
108
- | blue | `@codefast/ui/css/blue.css` |
109
- | indigo | `@codefast/ui/css/indigo.css` |
110
- | violet | `@codefast/ui/css/violet.css` |
111
- | purple | `@codefast/ui/css/purple.css` |
112
- | fuchsia | `@codefast/ui/css/fuchsia.css` |
113
- | pink | `@codefast/ui/css/pink.css` |
114
- | rose | `@codefast/ui/css/rose.css` |
115
-
116
- **3. Dark mode.** All themes include light/dark variants. Add the `.dark` class to `<html>` or `<body>` to enable dark mode:
93
+ Then import the stylesheet once from your app entry:
117
94
 
118
- ```tsx
119
- // Example: toggle dark mode
120
- document.documentElement.classList.toggle("dark", isDark);
95
+ ```ts
96
+ import "./styles.css";
121
97
  ```
122
98
 
123
- ### Option 2: Standalone (No Existing Tailwind)
99
+ Works the same for Vite (`@tailwindcss/vite`), Next.js (App Router), and TanStack Start.
124
100
 
125
- If your project does **not** use Tailwind yet, import the full stylesheet (includes Tailwind + theme + preset):
101
+ ### Standalone (no Tailwind yet)
126
102
 
127
- ```tsx
128
- // In your app entry (e.g. main.tsx, _app.tsx)
103
+ If your app doesn't run Tailwind, import the bundled stylesheet — it includes Tailwind 4 plus the default palette and preset:
104
+
105
+ ```ts
129
106
  import "@codefast/ui/css/style.css";
130
107
  ```
131
108
 
132
- > **Note:** This bundles Tailwind CSS. Ensure your build tool (Vite, webpack, etc.) can process CSS `@import`. You may need `@tailwindcss/vite` or `@tailwindcss/postcss` in devDependencies.
109
+ Make sure your bundler can process CSS `@import` (Vite and Next.js do this out of the box; for other setups, add `@tailwindcss/postcss` or `@tailwindcss/vite`).
133
110
 
134
- ### Option 3: Framework-Specific Setup
111
+ ### Theme palettes
135
112
 
136
- **Vite (with `@tailwindcss/vite`):**
113
+ Replace `slate.css` with any of the palettes below:
137
114
 
138
- ```css
139
- /* src/styles.css */
140
- @import "tailwindcss";
141
- @import "@codefast/ui/css/slate.css";
142
- @import "@codefast/ui/css/preset.css";
143
115
  ```
144
-
145
- **Next.js (App Router):**
146
-
147
- ```css
148
- /* app/globals.css */
149
- @import "tailwindcss";
150
- @import "@codefast/ui/css/slate.css";
151
- @import "@codefast/ui/css/preset.css";
116
+ amber · blue · cyan · emerald · fuchsia · gray · green · indigo · lime · neutral
117
+ orange · pink · purple · red · rose · sky · slate · stone · teal · violet · yellow · zinc
152
118
  ```
153
119
 
154
- **TanStack Start:**
120
+ Each palette defines a light set on `:root` and a dark set under `.dark`.
155
121
 
156
- ```css
157
- /* src/styles.css */
158
- @import "tailwindcss";
159
- @import "@codefast/ui/css/slate.css";
160
- @import "@codefast/ui/css/preset.css";
161
- ```
122
+ ### Dark mode
162
123
 
163
- #### SSR with Nitro (TanStack Start)
164
-
165
- Use this when you ship with **[Nitro](https://v3.nitro.build/)** (e.g. Vercel, Node) and **Vite 8** (Rolldown) via **TanStack Start**.
166
-
167
- **If you see** a server `TypeError` about `__extends` and `__toESM(...).default` (sometimes minified as `__toESM$1`), often during SSR or route loaders, configure `vite.config.ts` as below.
168
-
169
- ##### Recommended: `nitro.exportConditions`
170
-
171
- Prefer ESM entry points from dependencies (`import` / `module` in `package.json` `exports`). That avoids pulling CommonJS builds that `require("tslib")`, which can trip Rolldown’s CJS→ESM interop. Nitro still merges in `production` / `development`, `node`, and related conditions.
172
-
173
- ```ts
174
- // vite.config.ts
175
- import { defineConfig } from "vite";
176
-
177
- export default defineConfig({
178
- nitro: {
179
- exportConditions: ["import", "module", "default"],
180
- },
181
- // plugins: [ tanstackStart(), nitro(), … ]
182
- });
183
- ```
184
-
185
- ##### Fallback: `resolve.alias`
186
-
187
- If the error persists, point `tslib` at its ESM file:
124
+ Toggle the `dark` class on `<html>` (or any ancestor) to switch schemes:
188
125
 
189
126
  ```ts
190
- export default defineConfig({
191
- resolve: {
192
- alias: { tslib: "tslib/tslib.es6.mjs" },
193
- },
194
- });
127
+ document.documentElement.classList.toggle("dark", isDark);
195
128
  ```
196
129
 
197
- ##### Why it happens (short)
130
+ Pair with [`@codefast/theme`](../theme/README.md) for SSR-safe theme management and cross-tab sync.
198
131
 
199
- - **Bundler:** Rolldown may wrap `tslib`’s CJS build and read helpers from `.default` in a way that breaks when the module is marked `__esModule`.
200
- - **Dependencies:** Overlay-related packages (Dialog, Sheet, Menu, …) often pull in utilities such as [`react-remove-scroll-bar`](https://www.npmjs.com/package/react-remove-scroll-bar). Their legacy CJS output can use `require("tslib")` even when your app source is ESM.
132
+ ### Customizing tokens
201
133
 
202
- > **Note:** Don’t use `nitro.alias` for the bare specifier `tslib`. In Nitro v3 that option is for unenv-style path overrides, not npm package names, and can produce broken paths.
203
-
204
- ### Troubleshooting
205
-
206
- | Issue | Solution |
207
- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
208
- | Components look unstyled | Ensure CSS imports run before any component renders (entry point first). |
209
- | Duplicate Tailwind CSS | Use Option 1 (theme + preset only), **not** `style.css`. |
210
- | Dark mode not working | Add `class="dark"` to `<html>` when dark mode is active. |
211
- | Build: CSS not found | Verify path: `@codefast/ui/css/[theme].css` (e.g. `slate.css`). |
212
- | SSR / loaders: `Cannot destructure property '__extends'` | Set `nitro.exportConditions: ['import', 'module', 'default']`, or add `resolve.alias` for `tslib` (see [SSR with Nitro](#ssr-with-nitro-tanstack-start)). |
213
-
214
- ### Customizing Theme
215
-
216
- Override CSS variables in your own CSS after imports:
134
+ Override CSS custom properties after the imports:
217
135
 
218
136
  ```css
219
137
  @import "@codefast/ui/css/slate.css";
220
138
  @import "@codefast/ui/css/preset.css";
221
139
 
222
140
  :root {
223
- --radius: 0.5rem; /* Increase border radius */
224
- --primary: oklch(0.4 0.2 260); /* Custom primary color */
141
+ --radius: 0.5rem;
142
+ --primary: oklch(0.4 0.2 260);
225
143
  }
226
- ```
227
-
228
- ## Quick Start
229
144
 
230
- After integrating styles (see [Styling Integration](#styling-integration)), import and use components:
231
-
232
- ```tsx
233
- import { Button, Card, CardContent, CardHeader, CardTitle } from "@codefast/ui";
234
-
235
- function App() {
236
- return (
237
- <Card className="w-96">
238
- <CardHeader>
239
- <CardTitle>Welcome to CodeFast UI</CardTitle>
240
- </CardHeader>
241
- <CardContent>
242
- <p className="mb-4">
243
- A comprehensive UI components library built with React and Tailwind CSS.
244
- </p>
245
- <Button>Get Started</Button>
246
- </CardContent>
247
- </Card>
248
- );
145
+ .dark {
146
+ --primary: oklch(0.72 0.18 260);
249
147
  }
250
148
  ```
251
149
 
252
- ## Components
253
-
254
- ### Layout
150
+ ---
255
151
 
256
- | Component | Description |
257
- | ----------- | ----------------------------------------------------------- |
258
- | Card | Content container with header, content, and footer sections |
259
- | Separator | Visual divider between content sections |
260
- | AspectRatio | Maintain consistent aspect ratios for media content |
261
-
262
- ### Form
263
-
264
- | Component | Description |
265
- | ---------- | --------------------------------------------------- |
266
- | Button | Interactive button with multiple variants and sizes |
267
- | Input | Text input with validation support |
268
- | Checkbox | Individual checkbox and checkbox groups |
269
- | RadioGroup | Radio button group for single selection |
270
- | Select | Dropdown selection component |
271
- | Switch | Toggle switch for boolean values |
272
- | Slider | Range input slider |
273
- | Label | Form label with accessibility features |
274
-
275
- ### Navigation
276
-
277
- | Component | Description |
278
- | -------------- | -------------------------------------- |
279
- | Breadcrumb | Navigation breadcrumb trail |
280
- | NavigationMenu | Complex navigation menus with submenus |
281
- | Menubar | Application menu bar |
282
- | Tabs | Tabbed interface with content panels |
283
-
284
- ### Overlay
285
-
286
- | Component | Description |
287
- | ----------- | ------------------------------------ |
288
- | Dialog | Modal dialog and popup |
289
- | AlertDialog | Confirmation and alert dialog |
290
- | Popover | Contextual popover |
291
- | Tooltip | Informational tooltip |
292
- | HoverCard | Rich hover card with preview content |
293
-
294
- ### Data Display
295
-
296
- | Component | Description |
297
- | --------- | -------------------------------- |
298
- | Avatar | User profile image with fallback |
299
- | Badge | Status indicator and label |
300
- | Alert | System message and notification |
301
- | Progress | Progress indicator |
302
- | Accordion | Expandable content sections |
303
- | Calendar | Date selection calendar |
304
- | Carousel | Content carousel and slider |
305
-
306
- ## Usage Examples
307
-
308
- ### Form Components
152
+ ## Quick Start
309
153
 
310
154
  ```tsx
311
- import { Button, Input, Label, Card, CardContent, CardHeader, CardTitle } from "@codefast/ui";
312
- import { useState } from "react";
313
-
314
- function ContactForm() {
315
- const [email, setEmail] = useState("");
155
+ import { Button, Card, CardContent, CardHeader, CardTitle } from "@codefast/ui";
316
156
 
157
+ export function Hero() {
317
158
  return (
318
159
  <Card className="w-96">
319
160
  <CardHeader>
320
- <CardTitle>Contact Us</CardTitle>
161
+ <CardTitle>Welcome to Codefast UI</CardTitle>
321
162
  </CardHeader>
322
163
  <CardContent className="space-y-4">
323
- <div>
324
- <Label htmlFor="email">Email</Label>
325
- <Input
326
- id="email"
327
- type="email"
328
- placeholder="Enter your email"
329
- value={email}
330
- onChange={(e) => setEmail(e.target.value)}
331
- />
332
- </div>
333
- <Button className="w-full">Submit</Button>
164
+ <p>A typed React component library built on Radix and Tailwind CSS 4.</p>
165
+ <Button>Get started</Button>
334
166
  </CardContent>
335
167
  </Card>
336
168
  );
337
169
  }
338
170
  ```
339
171
 
340
- ### Navigation Components
172
+ Prefer per-component imports when you care about bundle visibility:
341
173
 
342
174
  ```tsx
343
- import { Tabs, TabsContent, TabsList, TabsTrigger } from "@codefast/ui";
344
-
345
- function TabExample() {
346
- return (
347
- <Tabs defaultValue="account" className="w-96">
348
- <TabsList className="grid w-full grid-cols-2">
349
- <TabsTrigger value="account">Account</TabsTrigger>
350
- <TabsTrigger value="password">Password</TabsTrigger>
351
- </TabsList>
352
- <TabsContent value="account" className="mt-4">
353
- <p>Make changes to your account here.</p>
354
- </TabsContent>
355
- <TabsContent value="password" className="mt-4">
356
- <p>Change your password here.</p>
357
- </TabsContent>
358
- </Tabs>
359
- );
360
- }
175
+ import { Button } from "@codefast/ui/button";
176
+ import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@codefast/ui/dialog";
361
177
  ```
362
178
 
363
- ### Overlay Components
179
+ Every subpath from the table below is tree-shakeable and ships its own types.
180
+
181
+ ---
182
+
183
+ ## Component catalog
184
+
185
+ All components are also re-exported from the root entry `@codefast/ui`.
186
+
187
+ ### Layout & structure
188
+
189
+ | Component | Subpath | Notes |
190
+ | ------------- | --------------------------- | --------------------------------------------- |
191
+ | `AspectRatio` | `@codefast/ui/aspect-ratio` | Maintain a consistent width/height ratio. |
192
+ | `Card` | `@codefast/ui/card` | Container with header/content/footer. |
193
+ | `Resizable` | `@codefast/ui/resizable` | Split-panel layouts (react-resizable-panels). |
194
+ | `ScrollArea` | `@codefast/ui/scroll-area` | Styled scroll container with custom bars. |
195
+ | `Separator` | `@codefast/ui/separator` | Decorative or semantic divider. |
196
+ | `Sidebar` | `@codefast/ui/sidebar` | App shell sidebar primitive. |
197
+ | `Skeleton` | `@codefast/ui/skeleton` | Loading placeholder. |
198
+
199
+ ### Forms & inputs
200
+
201
+ | Component | Subpath | Notes |
202
+ | ---------------- | ----------------------------------------- | ----------------------------------------- |
203
+ | `Button` | `@codefast/ui/button` | Variants + sizes via Tailwind Variants. |
204
+ | `ButtonGroup` | `@codefast/ui/button-group` | Segmented button container. |
205
+ | `Checkbox` | `@codefast/ui/checkbox` | Single checkbox. |
206
+ | `CheckboxCards` | `@codefast/ui/checkbox-cards` | Card-style multi-select. |
207
+ | `CheckboxGroup` | `@codefast/ui/checkbox-group` | Controlled multi-select group. |
208
+ | `Field` / `Form` | `@codefast/ui/field`, `@codefast/ui/form` | Form primitives, integrates with RHF. |
209
+ | `Input` | `@codefast/ui/input` | Standard text input. |
210
+ | `InputGroup` | `@codefast/ui/input-group` | Prefixed / suffixed composite input. |
211
+ | `InputNumber` | `@codefast/ui/input-number` | Numeric stepper with keyboard support. |
212
+ | `InputOTP` | `@codefast/ui/input-otp` | One-time-password code input (input-otp). |
213
+ | `InputPassword` | `@codefast/ui/input-password` | Password field with visibility toggle. |
214
+ | `InputSearch` | `@codefast/ui/input-search` | Search field with clear affordance. |
215
+ | `Label` | `@codefast/ui/label` | Accessible form label. |
216
+ | `NativeSelect` | `@codefast/ui/native-select` | Styled `<select>` wrapper. |
217
+ | `Radio` | `@codefast/ui/radio` | Single radio button. |
218
+ | `RadioCards` | `@codefast/ui/radio-cards` | Card-style single-select. |
219
+ | `RadioGroup` | `@codefast/ui/radio-group` | Controlled single-select group. |
220
+ | `Select` | `@codefast/ui/select` | Rich dropdown (Radix Select). |
221
+ | `Slider` | `@codefast/ui/slider` | Range slider. |
222
+ | `Switch` | `@codefast/ui/switch` | Boolean toggle. |
223
+ | `Textarea` | `@codefast/ui/textarea` | Multi-line input. |
224
+ | `Toggle` | `@codefast/ui/toggle` | Pressable toggle button. |
225
+ | `ToggleGroup` | `@codefast/ui/toggle-group` | Grouped toggles. |
364
226
 
365
- ```tsx
366
- import {
367
- Dialog,
368
- DialogContent,
369
- DialogDescription,
370
- DialogHeader,
371
- DialogTitle,
372
- DialogTrigger,
373
- Button,
374
- } from "@codefast/ui";
375
-
376
- function DialogExample() {
377
- return (
378
- <Dialog>
379
- <DialogTrigger asChild>
380
- <Button variant="outline">Edit Profile</Button>
381
- </DialogTrigger>
382
- <DialogContent className="sm:max-w-md">
383
- <DialogHeader>
384
- <DialogTitle>Edit Profile</DialogTitle>
385
- <DialogDescription>
386
- Make changes to your profile here. Click save when you're done.
387
- </DialogDescription>
388
- </DialogHeader>
389
- <div className="grid gap-4 py-4">{/* Form content */}</div>
390
- </DialogContent>
391
- </Dialog>
392
- );
393
- }
394
- ```
227
+ ### Navigation
395
228
 
396
- ## Theming and Customization
229
+ | Component | Subpath | Notes |
230
+ | ---------------- | ------------------------------ | --------------------------- |
231
+ | `Breadcrumb` | `@codefast/ui/breadcrumb` | Breadcrumb trail. |
232
+ | `Menubar` | `@codefast/ui/menubar` | Desktop-style menubar. |
233
+ | `NavigationMenu` | `@codefast/ui/navigation-menu` | Top-level nav with flyouts. |
234
+ | `Pagination` | `@codefast/ui/pagination` | Page number controls. |
235
+ | `Tabs` | `@codefast/ui/tabs` | Tabbed content. |
236
+
237
+ ### Overlay & feedback
238
+
239
+ | Component | Subpath | Notes |
240
+ | -------------- | ---------------------------- | ------------------------------------- |
241
+ | `AlertDialog` | `@codefast/ui/alert-dialog` | Confirm / destructive dialog. |
242
+ | `Command` | `@codefast/ui/command` | Command palette (cmdk). |
243
+ | `ContextMenu` | `@codefast/ui/context-menu` | Right-click menu. |
244
+ | `Dialog` | `@codefast/ui/dialog` | Modal dialog. |
245
+ | `Drawer` | `@codefast/ui/drawer` | Mobile-friendly drawer (vaul). |
246
+ | `DropdownMenu` | `@codefast/ui/dropdown-menu` | Menu triggered from a button. |
247
+ | `HoverCard` | `@codefast/ui/hover-card` | Rich hover preview. |
248
+ | `Popover` | `@codefast/ui/popover` | Floating panel anchored to a trigger. |
249
+ | `Sheet` | `@codefast/ui/sheet` | Side-sheet (dialog from edge). |
250
+ | `Sonner` | `@codefast/ui/sonner` | Toast stack (sonner). |
251
+ | `Tooltip` | `@codefast/ui/tooltip` | Keyboard-friendly tooltip. |
252
+
253
+ ### Data display & content
254
+
255
+ | Component | Subpath | Notes |
256
+ | ---------------- | ------------------------------ | ------------------------------- |
257
+ | `Accordion` | `@codefast/ui/accordion` | Collapsible sections. |
258
+ | `Alert` | `@codefast/ui/alert` | Inline status message. |
259
+ | `Avatar` | `@codefast/ui/avatar` | User avatar with fallback. |
260
+ | `Badge` | `@codefast/ui/badge` | Status pill. |
261
+ | `Calendar` | `@codefast/ui/calendar` | Date picker (react-day-picker). |
262
+ | `Carousel` | `@codefast/ui/carousel` | Slider (embla-carousel). |
263
+ | `Chart` | `@codefast/ui/chart` | Responsive charts (recharts). |
264
+ | `Collapsible` | `@codefast/ui/collapsible` | Expand/collapse primitive. |
265
+ | `Empty` | `@codefast/ui/empty` | Empty-state illustration block. |
266
+ | `Item` | `@codefast/ui/item` | List-item building block. |
267
+ | `Kbd` | `@codefast/ui/kbd` | Keyboard-key styling. |
268
+ | `Progress` | `@codefast/ui/progress` | Linear progress bar. |
269
+ | `ProgressCircle` | `@codefast/ui/progress-circle` | Circular progress indicator. |
270
+ | `Spinner` | `@codefast/ui/spinner` | Busy indicator. |
271
+ | `Table` | `@codefast/ui/table` | Semantic table + styled cells. |
272
+
273
+ ---
274
+
275
+ ## Hooks
276
+
277
+ Available from `@codefast/ui/hooks/*`:
278
+
279
+ | Hook | Subpath | Purpose |
280
+ | --------------------- | ------------------------------------------ | ------------------------------------------------ |
281
+ | `useAnimatedValue` | `@codefast/ui/hooks/use-animated-value` | Tween a number over time with easing control. |
282
+ | `useCopyToClipboard` | `@codefast/ui/hooks/use-copy-to-clipboard` | Clipboard write with success state. |
283
+ | `useIsMobile` | `@codefast/ui/hooks/use-is-mobile` | Boolean for the standard mobile breakpoint. |
284
+ | `useMediaQuery` | `@codefast/ui/hooks/use-media-query` | Subscribe to a `matchMedia` query, SSR-safe. |
285
+ | `useMutationObserver` | `@codefast/ui/hooks/use-mutation-observer` | Run a callback on DOM mutations. |
286
+ | `usePagination` | `@codefast/ui/hooks/use-pagination` | Page range / ellipsis helper for pagination UIs. |
287
+
288
+ ---
289
+
290
+ ## Primitives and utilities
291
+
292
+ Low-level building blocks, used internally by the styled components, exposed for custom wrappers.
293
+
294
+ | Import | Contents |
295
+ | ----------------------------------------- | -------------------------------------------------------- |
296
+ | `@codefast/ui/primitives/input` | Unstyled controlled-input primitive. |
297
+ | `@codefast/ui/primitives/input-number` | Numeric stepper logic (keyboard, parsing, clamp). |
298
+ | `@codefast/ui/primitives/checkbox-group` | Controlled checkbox-group state machine. |
299
+ | `@codefast/ui/primitives/progress-circle` | Math + a11y primitive for circular progress. |
300
+ | `@codefast/ui/lib/utils` | `cn()` — classname merge helper used by every component. |
301
+ | `@codefast/ui/css/*` | Palette + preset CSS files (see [Styling](#styling)). |
397
302
 
398
- All components use CSS custom properties (`--primary`, `--background`, `--radius`, etc.). You can:
303
+ ```tsx
304
+ import { cn } from "@codefast/ui/lib/utils";
399
305
 
400
- 1. **Switch themes** Import a different theme file (e.g. `zinc.css` instead of `slate.css`).
401
- 2. **Override variables** — Define your own values in `:root` or `.dark` after imports (see [Customizing Theme](#customizing-theme)).
402
- 3. **Use a theme provider** — For system/light/dark switching, add/remove `dark` class on `<html>`; many apps use `next-themes` or similar for persistence.
306
+ const classes = cn("rounded-md px-3 py-1", disabled && "opacity-50");
307
+ ```
403
308
 
404
- ## API Reference
309
+ ---
405
310
 
406
- ### Common Props
311
+ ## SSR with Nitro (TanStack Start)
407
312
 
408
- Most components accept these common props:
313
+ If you ship TanStack Start behind **[Nitro](https://v3.nitro.build/)** and **Vite 8 (Rolldown)**, you may hit a server-side `TypeError` referencing `__extends` or `__toESM(...).default` during route loaders or SSR. It originates from CJS `tslib` usage inside overlay-related dependencies (Dialog, Sheet, Menu, …) that reach for `react-remove-scroll-bar` and friends.
409
314
 
410
- | Prop | Type | Default | Description |
411
- | ----------- | ----------------- | ----------- | ---------------------- |
412
- | `className` | `string` | `undefined` | Additional CSS classes |
413
- | `children` | `React.ReactNode` | `undefined` | Child elements |
315
+ **Preferred fix** make Nitro pick ESM entry points from those packages:
414
316
 
415
- ### TypeScript Support
317
+ ```ts
318
+ // vite.config.ts
319
+ import { defineConfig } from "vite";
416
320
 
417
- All components export their prop types for use in custom wrappers:
321
+ export default defineConfig({
322
+ nitro: {
323
+ exportConditions: ["import", "module", "default"],
324
+ },
325
+ // plugins: [tanstackStart(), nitro(), …],
326
+ });
327
+ ```
418
328
 
419
- ```tsx
420
- import type { ButtonProps, CardProps, InputProps } from "@codefast/ui";
329
+ **Fallback** — alias `tslib` to its ESM build:
421
330
 
422
- function MyCustomButton(props: ButtonProps) {
423
- return <Button {...props} />;
424
- }
331
+ ```ts
332
+ export default defineConfig({
333
+ resolve: {
334
+ alias: { tslib: "tslib/tslib.es6.mjs" },
335
+ },
336
+ });
425
337
  ```
426
338
 
427
- ### Component Prop Types
339
+ > Don't use `nitro.alias` for the bare specifier `tslib`. In Nitro v3 that option is for unenv path overrides, not npm package names, and produces broken resolutions.
428
340
 
429
- **Layout:** `CardProps`, `SeparatorProps`, `AspectRatioProps`
341
+ ---
430
342
 
431
- **Form:** `ButtonProps`, `InputProps`, `LabelProps`, `CheckboxProps`, `RadioGroupProps`, `SelectProps`, `SwitchProps`, `SliderProps`
343
+ ## Troubleshooting
432
344
 
433
- **Navigation:** `TabsProps`, `NavigationMenuProps`, `BreadcrumbProps`, `MenubarProps`
345
+ | Issue | Fix |
346
+ | ------------------------------------------------ | ------------------------------------------------------------------------------------------------- |
347
+ | Components render unstyled | Make sure CSS imports run before the first component mounts (import from the app entry). |
348
+ | Tailwind output is duplicated | Use the palette + `preset.css` import — don't also import `css/style.css` in the same app. |
349
+ | Dark mode doesn't apply | Add the `dark` class to `<html>` (or any ancestor). See [Dark mode](#dark-mode). |
350
+ | `Cannot destructure property '__extends'` in SSR | Set `nitro.exportConditions: ["import", "module", "default"]` (see above). |
351
+ | Missing font or radius after palette switch | Re-import the palette **before** `preset.css`. Preset depends on palette variables being defined. |
434
352
 
435
- **Overlay:** `DialogProps`, `AlertDialogProps`, `PopoverProps`, `TooltipProps`, `HoverCardProps`
353
+ ---
436
354
 
437
355
  ## Accessibility
438
356
 
439
- All components follow [WAI-ARIA](https://www.w3.org/WAI/ARIA/apg/) guidelines and provide:
440
-
441
- - **Keyboard Navigation** -- Full keyboard support for all interactive elements.
442
- - **Screen Reader Support** -- Proper ARIA labels and descriptions.
443
- - **Focus Management** -- Logical focus order and visible focus indicators.
444
- - **High Contrast** -- Support for high contrast themes.
445
- - **Reduced Motion** -- Respects the `prefers-reduced-motion` media query.
357
+ Every component inherits Radix's accessibility guarantees and is audited with `jest-axe` in the test suite:
446
358
 
447
- ### Keyboard Shortcuts
359
+ - Full keyboard navigation (`Tab`, arrows, `Enter` / `Space`, `Escape`, `Home` / `End`).
360
+ - Correct ARIA roles, `aria-expanded`, `aria-controls`, and live regions where relevant.
361
+ - Focus trap + restore for overlays (Dialog, AlertDialog, Sheet, Drawer, DropdownMenu, …).
362
+ - Respects `prefers-reduced-motion`.
363
+ - High-contrast friendly color tokens — palettes use `oklch` and ship explicit `--ring`, `--border` values.
448
364
 
449
- | Key | Action |
450
- | ------------------- | ------------------------------------- |
451
- | `Tab` / `Shift+Tab` | Navigate between focusable elements |
452
- | `Enter` / `Space` | Activate buttons and controls |
453
- | `Arrow Keys` | Navigate within component groups |
454
- | `Escape` | Close overlays and cancel actions |
455
- | `Home` / `End` | Navigate to first/last items in lists |
365
+ ---
456
366
 
457
- ## Browser Compatibility
367
+ ## Browser support
458
368
 
459
- `@codefast/ui` supports all modern browsers:
369
+ Last two versions of Chrome, Edge, Firefox, and Safari. Internet Explorer is not supported.
460
370
 
461
- | Browser | Version |
462
- | ------- | --------------- |
463
- | Chrome | Last 2 versions |
464
- | Firefox | Last 2 versions |
465
- | Safari | Last 2 versions |
466
- | Edge | Last 2 versions |
467
-
468
- > Internet Explorer is not supported.
371
+ ---
469
372
 
470
373
  ## Contributing
471
374
 
472
- We welcome contributions! Please see the [contributing guide](../../README.md#contributing) in the root of this repository for detailed instructions.
473
-
474
- For package-specific development:
375
+ This package lives in the [Codefast monorepo](https://github.com/codefastlabs/codefast). From the repo root:
475
376
 
476
377
  ```bash
477
- # Development mode
478
- pnpm dev --filter=@codefast/ui
479
-
480
- # Run tests
481
- pnpm test --filter=@codefast/ui
482
-
483
- # Run tests with coverage
484
- pnpm test:coverage --filter=@codefast/ui
378
+ pnpm --filter @codefast/ui build
379
+ pnpm --filter @codefast/ui dev # watch build via tsdown
380
+ pnpm --filter @codefast/ui test
381
+ pnpm --filter @codefast/ui test:coverage
382
+ pnpm --filter @codefast/ui check-types
485
383
  ```
486
384
 
487
- Package build/dev scripts use TypeScript directly via `tsc -p tsconfig.build.json` (watch mode for `pnpm dev --filter=@codefast/ui`).
385
+ Adding a component:
488
386
 
489
- CSS entry exports under `@codefast/ui/css/*` are sourced from `src/css/*`.
387
+ 1. Implement it under `src/components/<name>.tsx`.
388
+ 2. Export the component and its prop types from `src/index.ts`.
389
+ 3. Add a new subpath entry in `package.json → exports` following the existing pattern.
390
+ 4. Add tests under `src/components/__tests__` (unit + `jest-axe` if interactive).
391
+ 5. Run `pnpm --filter @codefast/ui build` to verify `tsdown` picks up the new entry.
490
392
 
491
- ### Adding New Components
393
+ CSS entry exports under `@codefast/ui/css/*` are sourced directly from `src/css/*`.
492
394
 
493
- 1. Create component files in `src/components/[component-name]/`.
494
- 2. Export the component and types from the package entry point.
495
- 3. Add comprehensive tests.
496
- 4. Update documentation.
497
- 5. Submit a pull request.
395
+ ---
498
396
 
499
397
  ## License
500
398
 
501
- Distributed under the MIT License. See [LICENSE](../../LICENSE) for more details.
399
+ [MIT](https://opensource.org/licenses/MIT) see [`package.json`](./package.json).
400
+
401
+ ---
502
402
 
503
403
  ## Changelog
504
404
 
505
- See [CHANGELOG.md](./CHANGELOG.md) for a complete list of changes and version history.
405
+ See [CHANGELOG.md](./CHANGELOG.md) for the full version history. Releases are also published on [npm](https://www.npmjs.com/package/@codefast/ui?activeTab=versions).
@@ -1,18 +1,26 @@
1
1
  //#region src/hooks/use-pagination.d.ts
2
2
  interface UsePaginationProps {
3
- /** Current active page number. */
3
+ /**
4
+ * Current active page number.
5
+ */
4
6
  currentPage: number;
5
- /** Number of results displayed per page. */
7
+ /**
8
+ * Number of results displayed per page.
9
+ */
6
10
  resultsPerPage: number;
7
11
  /**
8
12
  * Number of sibling pages to show on each side of the current page.
9
13
  * Defaults to 1.
10
14
  */
11
15
  siblingPagesCount?: number;
12
- /** Total number of results across all pages. */
16
+ /**
17
+ * Total number of results across all pages.
18
+ */
13
19
  totalResults: number;
14
20
  }
15
- /** Ellipsis marker used to collapse ranges in pagination output. */
21
+ /**
22
+ * Ellipsis marker used to collapse ranges in pagination output.
23
+ */
16
24
  declare const ELLIPSIS = "\u2022\u2022\u2022";
17
25
  /**
18
26
  * Compute a pagination structure for result sets.
@@ -1,7 +1,9 @@
1
1
  "use client";
2
2
  import { useMemo } from "react";
3
3
  //#region src/hooks/use-pagination.ts
4
- /** Ellipsis marker used to collapse ranges in pagination output. */
4
+ /**
5
+ * Ellipsis marker used to collapse ranges in pagination output.
6
+ */
5
7
  const ELLIPSIS = "•••";
6
8
  /**
7
9
  * Generate a numeric range from start to end inclusive.
@@ -59,9 +61,13 @@ function usePagination({ currentPage, resultsPerPage, siblingPagesCount = 1, tot
59
61
  * Whether a right-side ellipsis is needed.
60
62
  */
61
63
  const shouldShowRightEllipsis = rightSiblingIndex < totalPages - 2;
62
- /** First page number (always 1). */
64
+ /**
65
+ * First page number (always 1).
66
+ */
63
67
  const firstPage = 1;
64
- /** Last page number (equals totalPages). */
68
+ /**
69
+ * Last page number (equals totalPages).
70
+ */
65
71
  const lastPage = totalPages;
66
72
  /**
67
73
  * Case 2: No left ellipsis, but right ellipsis is necessary.
@@ -8,34 +8,59 @@ import { Scope } from "@radix-ui/react-context";
8
8
  * Props that include an optional scope for the InputNumber component.
9
9
  */
10
10
  type ScopedProps<P> = P & {
11
- /** Optional scope for the InputNumber component context */__scopeInputNumber?: Scope;
11
+ /**
12
+ * Optional scope for the InputNumber component context
13
+ */
14
+ __scopeInputNumber?: Scope;
12
15
  };
13
16
  declare const createInputNumberScope: _$_radix_ui_react_context0.CreateScope;
14
17
  /**
15
18
  * Props for the main InputNumber component.
16
19
  */
17
20
  interface InputNumberProps extends ComponentProps<typeof Input> {
18
- /** Accessible label for the decrement button */
21
+ /**
22
+ * Accessible label for the decrement button
23
+ */
19
24
  ariaDecrementLabel?: string;
20
- /** Accessible label for the increment button */
25
+ /**
26
+ * Accessible label for the increment button
27
+ */
21
28
  ariaIncrementLabel?: string;
22
- /** Initial value when uncontrolled */
29
+ /**
30
+ * Initial value when uncontrolled
31
+ */
23
32
  defaultValue?: number;
24
- /** Options for number formatting */
33
+ /**
34
+ * Options for number formatting
35
+ */
25
36
  formatOptions?: Intl.NumberFormatOptions;
26
- /** Unique identifier for the input */
37
+ /**
38
+ * Unique identifier for the input
39
+ */
27
40
  id?: string;
28
- /** Locale used for number formatting */
41
+ /**
42
+ * Locale used for number formatting
43
+ */
29
44
  locale?: string;
30
- /** Maximum allowed value */
45
+ /**
46
+ * Maximum allowed value
47
+ */
31
48
  max?: number;
32
- /** Minimum allowed value */
49
+ /**
50
+ * Minimum allowed value
51
+ */
33
52
  min?: number;
34
- /** Handler called when the value changes */
53
+ /**
54
+ * Handler called when the value changes
55
+ */
35
56
  onChange?: (value?: number) => void;
36
- /** Step value for increments/decrements */
57
+ /**
58
+ * Step value for increments/decrements
59
+ */
37
60
  step?: number;
38
- /** Current value when controlled */
61
+ /**
62
+ * Current value when controlled
63
+ */
39
64
  value?: number;
40
65
  }
41
66
  declare function InputNumber(numberInputProps: ScopedProps<InputNumberProps>): JSX.Element;
@@ -17,17 +17,25 @@ function InputNumber(numberInputProps) {
17
17
  minimumFractionDigits: 0,
18
18
  style: "decimal"
19
19
  }, id, locale, max, min, onChange, step = 1, value: valueProperty, ...props } = numberInputProps;
20
- /** Scope for the input component */
20
+ /**
21
+ * Scope for the input component
22
+ */
21
23
  const inputScope = useInputScope(__scopeInputNumber);
22
- /** Reference to the input element */
24
+ /**
25
+ * Reference to the input element
26
+ */
23
27
  const inputRef = useRef(null);
24
- /** Controlled or uncontrolled value state */
28
+ /**
29
+ * Controlled or uncontrolled value state
30
+ */
25
31
  const [value, setValue] = useControllableState({
26
32
  defaultProp: defaultValue,
27
33
  onChange,
28
34
  prop: valueProperty
29
35
  });
30
- /** Separators used for number formatting based on locale */
36
+ /**
37
+ * Separators used for number formatting based on locale
38
+ */
31
39
  const { decimalSeparator, thousandSeparator } = useMemo(() => getNumberFormatSeparators(locale), [locale]);
32
40
  /**
33
41
  * Formats a number value into a string representation
@@ -25,25 +25,45 @@ interface Threshold {
25
25
  }
26
26
  declare const createProgressCircleScope: _$_radix_ui_react_context0.CreateScope;
27
27
  interface ProgressCircleProviderProps {
28
- /** React children to be rendered inside the progress circle */
28
+ /**
29
+ * React children to be rendered inside the progress circle
30
+ */
29
31
  children: ReactNode;
30
- /** Custom function to format the numeric value for display */
32
+ /**
33
+ * Custom function to format the numeric value for display
34
+ */
31
35
  formatValue?: (value: number) => string;
32
- /** Unique identifier for the progress circle component */
36
+ /**
37
+ * Unique identifier for the progress circle component
38
+ */
33
39
  id?: string;
34
- /** Maximum value of the progress (defaults to 100) */
40
+ /**
41
+ * Maximum value of the progress (defaults to 100)
42
+ */
35
43
  max?: number;
36
- /** Minimum value of the progress (defaults to 0) */
44
+ /**
45
+ * Minimum value of the progress (defaults to 0)
46
+ */
37
47
  min?: number;
38
- /** Size of the progress circle in pixels */
48
+ /**
49
+ * Size of the progress circle in pixels
50
+ */
39
51
  size?: number;
40
- /** Starting angle of the progress circle in degrees (0 = top) */
52
+ /**
53
+ * Starting angle of the progress circle in degrees (0 = top)
54
+ */
41
55
  startAngle?: number;
42
- /** Width of the progress circle's stroke in pixels */
56
+ /**
57
+ * Width of the progress circle's stroke in pixels
58
+ */
43
59
  strokeWidth?: number;
44
- /** Array of threshold configurations for different value ranges */
60
+ /**
61
+ * Array of threshold configurations for different value ranges
62
+ */
45
63
  thresholds?: Threshold[];
46
- /** Current progress value (null for indeterminate state) */
64
+ /**
65
+ * Current progress value (null for indeterminate state)
66
+ */
47
67
  value?: null | number;
48
68
  }
49
69
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codefast/ui",
3
- "version": "0.3.13",
3
+ "version": "0.3.14-canary.1",
4
4
  "description": "Core UI components library built with React and Tailwind CSS",
5
5
  "keywords": [
6
6
  "components",
@@ -396,7 +396,7 @@
396
396
  "sonner": "^2.0.7",
397
397
  "tw-animate-css": "^1.4.0",
398
398
  "vaul": "^1.1.2",
399
- "@codefast/tailwind-variants": "0.3.13"
399
+ "@codefast/tailwind-variants": "0.3.14-canary.1"
400
400
  },
401
401
  "devDependencies": {
402
402
  "@tailwindcss/postcss": "^4.2.2",
@@ -415,7 +415,7 @@
415
415
  "tailwindcss": "^4.2.2",
416
416
  "typescript": "^6.0.2",
417
417
  "vitest": "^4.1.4",
418
- "@codefast/typescript-config": "0.3.13"
418
+ "@codefast/typescript-config": "0.3.14-canary.1"
419
419
  },
420
420
  "peerDependencies": {
421
421
  "@types/react": "^19.0",