@zentauri-ui/zentauri-components 1.4.64 → 1.4.70

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.
Files changed (88) hide show
  1. package/README.md +97 -51
  2. package/cli/index.mjs +45 -26
  3. package/cli/registry.json +9 -1
  4. package/cli/rewrite-imports.mjs +8 -3
  5. package/dist/charts/area/Area.d.ts +6 -0
  6. package/dist/charts/area/Area.d.ts.map +1 -0
  7. package/dist/charts/area/index.d.ts +4 -0
  8. package/dist/charts/area/index.d.ts.map +1 -0
  9. package/dist/charts/area.js +119 -0
  10. package/dist/charts/area.js.map +1 -0
  11. package/dist/charts/area.mjs +106 -0
  12. package/dist/charts/area.mjs.map +1 -0
  13. package/dist/charts/bar/Bar.d.ts +6 -0
  14. package/dist/charts/bar/Bar.d.ts.map +1 -0
  15. package/dist/charts/bar/index.d.ts +4 -0
  16. package/dist/charts/bar/index.d.ts.map +1 -0
  17. package/dist/charts/bar.js +110 -0
  18. package/dist/charts/bar.js.map +1 -0
  19. package/dist/charts/bar.mjs +97 -0
  20. package/dist/charts/bar.mjs.map +1 -0
  21. package/dist/charts/bubble/Bubble.d.ts +6 -0
  22. package/dist/charts/bubble/Bubble.d.ts.map +1 -0
  23. package/dist/charts/bubble/index.d.ts +4 -0
  24. package/dist/charts/bubble/index.d.ts.map +1 -0
  25. package/dist/charts/bubble.js +122 -0
  26. package/dist/charts/bubble.js.map +1 -0
  27. package/dist/charts/bubble.mjs +109 -0
  28. package/dist/charts/bubble.mjs.map +1 -0
  29. package/dist/charts/line/Line.d.ts +6 -0
  30. package/dist/charts/line/Line.d.ts.map +1 -0
  31. package/dist/charts/line/index.d.ts +4 -0
  32. package/dist/charts/line/index.d.ts.map +1 -0
  33. package/dist/charts/line.js +113 -0
  34. package/dist/charts/line.js.map +1 -0
  35. package/dist/charts/line.mjs +100 -0
  36. package/dist/charts/line.mjs.map +1 -0
  37. package/dist/charts/shared/chart-frame.d.ts +32 -0
  38. package/dist/charts/shared/chart-frame.d.ts.map +1 -0
  39. package/dist/charts/shared/colors.d.ts +43 -0
  40. package/dist/charts/shared/colors.d.ts.map +1 -0
  41. package/dist/charts/shared/types.d.ts +43 -0
  42. package/dist/charts/shared/types.d.ts.map +1 -0
  43. package/dist/charts/shared/variants.d.ts +93 -0
  44. package/dist/charts/shared/variants.d.ts.map +1 -0
  45. package/dist/chunk-CIN5JDN4.js +174 -0
  46. package/dist/chunk-CIN5JDN4.js.map +1 -0
  47. package/dist/chunk-IQZROQNJ.mjs +165 -0
  48. package/dist/chunk-IQZROQNJ.mjs.map +1 -0
  49. package/dist/ui/accordion/variants.d.ts +2 -2
  50. package/dist/ui/alert/variants.d.ts +1 -1
  51. package/dist/ui/avatar/variants.d.ts +1 -1
  52. package/dist/ui/badge/variants.d.ts +2 -2
  53. package/dist/ui/breadcrumb/variants.d.ts +1 -1
  54. package/dist/ui/buttons/variants.d.ts +2 -2
  55. package/dist/ui/card/variants.d.ts +1 -1
  56. package/dist/ui/divider/variants.d.ts +2 -2
  57. package/dist/ui/drawer/variants.d.ts +3 -3
  58. package/dist/ui/dropdown/variants.d.ts +4 -4
  59. package/dist/ui/file-upload/variants.d.ts +1 -1
  60. package/dist/ui/inputs/variants.d.ts +2 -2
  61. package/dist/ui/modal/variants.d.ts +2 -2
  62. package/dist/ui/pagination/pagination.d.ts +2 -2
  63. package/dist/ui/pagination/variants.d.ts +3 -3
  64. package/dist/ui/progress/variants.d.ts +1 -1
  65. package/dist/ui/select/variants.d.ts +4 -4
  66. package/dist/ui/skeleton/variants.d.ts +2 -2
  67. package/dist/ui/slider/variants.d.ts +1 -1
  68. package/dist/ui/spinner/animated/variants.d.ts +1 -1
  69. package/dist/ui/stepper/variants.d.ts +1 -1
  70. package/dist/ui/table/variants.d.ts +3 -3
  71. package/dist/ui/tabs/variants.d.ts +1 -1
  72. package/dist/ui/toast/variants.d.ts +1 -1
  73. package/dist/ui/toggle/variants.d.ts +1 -1
  74. package/dist/ui/tooltip/variants.d.ts +1 -1
  75. package/dist/ui/typography/variants.d.ts +3 -3
  76. package/package.json +32 -12
  77. package/src/charts/area/Area.tsx +103 -0
  78. package/src/charts/area/index.ts +9 -0
  79. package/src/charts/bar/Bar.tsx +94 -0
  80. package/src/charts/bar/index.ts +9 -0
  81. package/src/charts/bubble/Bubble.tsx +113 -0
  82. package/src/charts/bubble/index.ts +9 -0
  83. package/src/charts/line/Line.tsx +97 -0
  84. package/src/charts/line/index.ts +9 -0
  85. package/src/charts/shared/chart-frame.tsx +107 -0
  86. package/src/charts/shared/colors.ts +31 -0
  87. package/src/charts/shared/types.ts +60 -0
  88. package/src/charts/shared/variants.ts +87 -0
package/README.md CHANGED
@@ -6,7 +6,7 @@ A React UI kit for building product interfaces with Tailwind CSS. Components are
6
6
 
7
7
  The library targets **React 18+** apps that use **Tailwind CSS v4** (or an equivalent setup where Tailwind can scan this package via `@source`). Styling uses utility classes; **class-variance-authority** powers variant APIs (size, appearance, and similar props), with **clsx** and **tailwind-merge** for predictable `className` composition. **Framer Motion** backs motion where a feature ships animated variants, and **react-icons** is used for iconography where applicable.
8
8
 
9
- Published artifacts live under `dist/`. Imports use **per-entry subpaths**: `@zentauri-ui/zentauri-components/ui/<area>` for static UI, `@zentauri-ui/zentauri-components/ui/<area>/animated` where a motion bundle exists, and `@zentauri-ui/zentauri-components/hooks/<entry>` for React hooks (and shared helpers under `hooks/utils`). Base UI entries do **not** re-export animated components; motion lives on its own entry so optional `framer-motion` usage stays tree-shakeable and chunk-friendly. Each entry resolves to its own ESM (`.mjs`), CJS (`.js`), and types (`.d.ts`) so bundlers pull only what you import. Most apps rely on Tailwind scanning the package sources (see installation); a separate CSS import is not required for that setup.
9
+ Published artifacts live under `dist/`. Imports use **per-entry subpaths**: `@zentauri-ui/zentauri-components/ui/<area>` for static UI, `@zentauri-ui/zentauri-components/ui/<area>/animated` where a motion bundle exists, `@zentauri-ui/zentauri-components/charts/<type>` for Recharts-powered chart primitives, and `@zentauri-ui/zentauri-components/hooks/<entry>` for React hooks (and shared helpers under `hooks/utils`). Base UI entries do **not** re-export animated components; motion lives on its own entry so optional `framer-motion` usage stays tree-shakeable and chunk-friendly. Each entry resolves to its own ESM (`.mjs`), CJS (`.js`), and types (`.d.ts`) so bundlers pull only what you import. Most apps rely on Tailwind scanning the package sources (see installation); a separate CSS import is not required for that setup.
10
10
 
11
11
  ## Package exports
12
12
 
@@ -14,6 +14,7 @@ Published artifacts live under `dist/`. Imports use **per-entry subpaths**: `@ze
14
14
  | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
15
15
  | `@zentauri-ui/zentauri-components/ui/<name>` | Single UI area: static primitives, compound parts, variants, and types. Does **not** include Framer Motion–based animated exports. |
16
16
  | `@zentauri-ui/zentauri-components/ui/<name>/animated` | Motion entry for that area when published: animated components, motion presets, and related types (depends on **framer-motion**). |
17
+ | `@zentauri-ui/zentauri-components/charts/<type>` | Responsive Recharts chart entry for `area`, `bar`, `bubble`, or `line`, with shared variants, palettes, and exported chart prop types. |
17
18
  | `@zentauri-ui/zentauri-components/hooks/<entry>` | One hook module or `utils` (`cn`, `clampPage`, `range` from `src/lib/utils.ts`). Entries match files under `src/hooks/` (see **React hooks**). |
18
19
 
19
20
  The UI `<name>` segment matches the folder under `src/ui/` (for example `accordion`, `select`, `empty-state`, `buttons` for `Button`, `inputs` for `Input`, `typography` for `Heading` / `Text` and related primitives). The hooks `<entry>` is the file stem (for example `useMediaQuery`, `usePagination`) or `utils`.
@@ -23,7 +24,7 @@ Only a subset of UI areas publish a `/animated` entry (see **Components**). Some
23
24
  ## Animated components (`ui/<name>/animated`)
24
25
 
25
26
  - **Why a separate subpath:** animated modules import **framer-motion**. Keeping them on `…/ui/<name>/animated` avoids pulling motion into pages that only use the static `…/ui/<name>` entry and keeps server/client boundaries predictable in app routers.
26
- - **When to install `framer-motion`:** add it when your app imports any `@zentauri-ui/zentauri-components/ui/*/animated` path (see **Optional: animations and icons** under installation).
27
+ - **When to install `framer-motion`:** add it when your app imports any `@zentauri-ui/zentauri-components/ui/*/animated` path (see **Optional: animations, icons, and charts** under installation).
27
28
 
28
29
  Published motion entries (same `<name>` as the base UI folder):
29
30
 
@@ -38,38 +39,39 @@ Published motion entries (same `<name>` as the base UI folder):
38
39
 
39
40
  ## Components
40
41
 
41
- Import static primitives from `@zentauri-ui/zentauri-components/ui/<subpath>` when the **Base** column lists a path. When the **Animated** column lists a path, motion components and preset helpers come from `@zentauri-ui/zentauri-components/ui/<subpath>/animated` (they are not exported from the base entry). **Spinner** has no static bundle—use only the animated subpath.
42
-
43
- | Area | Base subpath `…/ui/…` | Animated subpath `…/ui/…/animated` |
44
- | ----------- | --------------------- | ---------------------------------- |
45
- | Accordion | `accordion` | `accordion/animated` |
46
- | Alert | `alert` | `alert/animated` |
47
- | Avatar | `avatar` | `avatar/animated` |
48
- | Badge | `badge` | `badge/animated` |
49
- | Breadcrumb | `breadcrumb` | — |
50
- | Button | `buttons` | `buttons/animated` |
51
- | Card | `card` | `card/animated` |
52
- | Divider | `divider` | `divider/animated` |
53
- | Drawer | `drawer` | `drawer/animated` |
54
- | Dropdown | `dropdown` | |
55
- | Empty state | `empty-state` | `empty-state/animated` |
56
- | File upload | `file-upload` | |
57
- | Input | `inputs` | `inputs/animated` |
58
- | Modal | `modal` | `modal/animated` |
59
- | Pagination | `pagination` | |
60
- | Progress | `progress` | `progress/animated` |
61
- | Search | `search` | - |
62
- | Select | `select` | |
63
- | Skeleton | `skeleton` | `skeleton/animated` |
64
- | Slider | `slider` | |
65
- | Spinner | — | `spinner/animated` |
66
- | Stepper | `stepper` | — |
67
- | Table | `table` | `table/animated` |
68
- | Tabs | `tabs` | `tabs/animated` |
69
- | Toast | `toast` | `toast/animated` |
70
- | Toggle | `toggle` | `toggle/animated` |
71
- | Tooltip | `tooltip` | `tooltip/animated` |
72
- | Typography | `typography` | |
42
+ Import static primitives from `@zentauri-ui/zentauri-components/ui/<subpath>` when the **Base** column lists a path. Charts use `@zentauri-ui/zentauri-components/charts/<type>`. When the **Animated** column lists a path, motion components and preset helpers come from `@zentauri-ui/zentauri-components/ui/<subpath>/animated` (they are not exported from the base entry). **Spinner** has no static bundle—use only the animated subpath.
43
+
44
+ | Area | Base subpath | Animated subpath `…/ui/…/animated` |
45
+ | ----------- | --------------- | ---------------------------------- |
46
+ | Accordion | `accordion` | `accordion/animated` |
47
+ | Alert | `alert` | `alert/animated` |
48
+ | Avatar | `avatar` | `avatar/animated` |
49
+ | Badge | `badge` | `badge/animated` |
50
+ | Breadcrumb | `breadcrumb` | — |
51
+ | Button | `buttons` | `buttons/animated` |
52
+ | Card | `card` | `card/animated` |
53
+ | Charts | `charts/<type>` | |
54
+ | Divider | `divider` | `divider/animated` |
55
+ | Drawer | `drawer` | `drawer/animated` |
56
+ | Dropdown | `dropdown` | |
57
+ | Empty state | `empty-state` | `empty-state/animated` |
58
+ | File upload | `file-upload` | |
59
+ | Input | `inputs` | `inputs/animated` |
60
+ | Modal | `modal` | `modal/animated` |
61
+ | Pagination | `pagination` | |
62
+ | Progress | `progress` | `progress/animated` |
63
+ | Search | `search` | - |
64
+ | Select | `select` | |
65
+ | Skeleton | `skeleton` | `skeleton/animated` |
66
+ | Slider | `slider` | — |
67
+ | Spinner | — | `spinner/animated` |
68
+ | Stepper | `stepper` | |
69
+ | Table | `table` | `table/animated` |
70
+ | Tabs | `tabs` | `tabs/animated` |
71
+ | Toast | `toast` | `toast/animated` |
72
+ | Toggle | `toggle` | `toggle/animated` |
73
+ | Tooltip | `tooltip` | `tooltip/animated` |
74
+ | Typography | `typography` | — |
73
75
 
74
76
  ## Typography
75
77
 
@@ -131,6 +133,48 @@ export function ArticleIntro() {
131
133
  }
132
134
  ```
133
135
 
136
+ ## Charts
137
+
138
+ Import the chart you need from `@zentauri-ui/zentauri-components/charts/<type>`, or vendor it with `zentauri-components add charts/<type>`. It is built on **Recharts**, so install `recharts` when you use these entries.
139
+
140
+ **Components:** `AreaChart`, `BarChart`, `BubbleChart`, `LineChart`.
141
+
142
+ **Types:** `AreaChartProps`, `BarChartProps`, `BubbleChartProps`, `LineChartProps`, plus shared `ChartSeries`, `ChartDatum`, `ChartColor`, `ChartMargin`, and `ChartSharedStatic`.
143
+
144
+ **Chart entries:** `charts/area`, `charts/bar`, `charts/bubble`, `charts/line`.
145
+
146
+ **Variants:** `appearance` (`default`, `muted`, `outline`, `glass`) and `density` (`compact`, `comfortable`, `spacious`). Color presets are exported via `chartPalette` and `chartColorValues`.
147
+
148
+ ```tsx
149
+ import {
150
+ AreaChart,
151
+ type ChartSeries,
152
+ } from "@zentauri-ui/zentauri-components/charts/area";
153
+
154
+ const data = [
155
+ { month: "Jan", revenue: 4200, signups: 240 },
156
+ { month: "Feb", revenue: 5100, signups: 280 },
157
+ { month: "Mar", revenue: 6800, signups: 360 },
158
+ ];
159
+
160
+ const series: ChartSeries[] = [
161
+ { dataKey: "revenue", name: "Revenue", color: "cyan" },
162
+ { dataKey: "signups", name: "Signups", color: "emerald" },
163
+ ];
164
+
165
+ export function RevenueChart() {
166
+ return (
167
+ <AreaChart
168
+ xKey="month"
169
+ data={data}
170
+ series={series}
171
+ appearance="outline"
172
+ showLegend
173
+ />
174
+ );
175
+ }
176
+ ```
177
+
134
178
  ## React hooks
135
179
 
136
180
  Hooks live in `src/hooks/`. Each hook is a separate published entry under `@zentauri-ui/zentauri-components/hooks/<name>` (same pattern as UI areas). Types are exported where the implementation defines them (for example `UseDisclosureResult`, `PaginationPageItem`). For class-name merging and pagination helpers used alongside hooks, import from `@zentauri-ui/zentauri-components/hooks/utils`.
@@ -214,23 +258,23 @@ pnpm add react react-dom class-variance-authority clsx tailwind-merge
214
258
  yarn add react react-dom class-variance-authority clsx tailwind-merge
215
259
  ```
216
260
 
217
- #### Optional: animations and icons
261
+ #### Optional: animations, icons, and charts
218
262
 
219
- Add **`framer-motion`** when you import any `@zentauri-ui/zentauri-components/ui/<name>/animated` entry (including **Spinner**, which is only published under `ui/spinner/animated`). Add **`react-icons`** when using icon sets from that package.
263
+ Add **`framer-motion`** when you import any `@zentauri-ui/zentauri-components/ui/<name>/animated` entry (including **Spinner**, which is only published under `ui/spinner/animated`). Add **`react-icons`** when using icon sets from that package. Add **`recharts`** when you import any `@zentauri-ui/zentauri-components/charts/<type>` entry or vendor charts with the CLI.
220
264
 
221
265
  ```bash
222
- npm install framer-motion react-icons
266
+ npm install framer-motion react-icons recharts
223
267
  ```
224
268
 
225
269
  ```bash
226
- pnpm add framer-motion react-icons
270
+ pnpm add framer-motion react-icons recharts
227
271
  ```
228
272
 
229
273
  ```bash
230
- yarn add framer-motion react-icons
274
+ yarn add framer-motion react-icons recharts
231
275
  ```
232
276
 
233
- Published `dist/` files **import** these packages; they are **not** vendored inside `@zentauri-ui/zentauri-components`. Static `ui/<name>` bundles do not depend on `framer-motion`; only `ui/<name>/animated` entries do. Your app installs peers via `dependencies` where needed, and your bundler resolves them from `node_modules`.
277
+ Published `dist/` files **import** these packages; they are **not** vendored inside `@zentauri-ui/zentauri-components`. Static `ui/<name>` bundles do not depend on `framer-motion`; only `ui/<name>/animated` entries do. Chart bundles are isolated to `charts/<type>` entries and depend on `recharts`. Your app installs peers via `dependencies` where needed, and your bundler resolves them from `node_modules`.
234
278
 
235
279
  ### Next.js: smaller route chunks
236
280
 
@@ -242,7 +286,7 @@ import type { NextConfig } from "next";
242
286
 
243
287
  const nextConfig: NextConfig = {
244
288
  experimental: {
245
- optimizePackageImports: ["framer-motion", "react-icons"],
289
+ optimizePackageImports: ["framer-motion", "react-icons", "recharts"],
246
290
  },
247
291
  };
248
292
 
@@ -291,6 +335,7 @@ import {
291
335
  ```tsx
292
336
  import { useDisclosure } from "@zentauri-ui/zentauri-components/hooks/useDisclosure";
293
337
  import { Button } from "@zentauri-ui/zentauri-components/ui/buttons";
338
+ import { AreaChart } from "@zentauri-ui/zentauri-components/charts/area";
294
339
  ```
295
340
 
296
341
  #### Imports (animated / Framer Motion)
@@ -336,9 +381,9 @@ import { Spinner } from "@zentauri-ui/zentauri-components/ui/spinner/animated";
336
381
 
337
382
  ## CLI — copy component source into your app
338
383
 
339
- The package ships a small **Node CLI** (`zentauri-components` and `zentauri-ui` point to the same `cli/index.mjs`) that copies **selected** folders from this package’s `src/ui` and `src/hooks` into your repository—similar to shadcn/ui. You keep the files, control paths via `components.json`, and imports are rewritten to your path aliases (`@/components/ui`, `@/hooks`, `@/lib/utils`, and so on).
384
+ The package ships a small **Node CLI** (`zentauri-components` and `zentauri-ui` point to the same `cli/index.mjs`) that copies **selected** folders from this package’s `src/ui`, `src/charts`, and `src/hooks` into your repository—similar to shadcn/ui. You keep the files, control paths via `components.json`, and imports are rewritten to your path aliases (`@/components/ui`, `@/hooks`, `@/lib/utils`, and so on).
340
385
 
341
- Which UI folders are valid for `add` is driven by **`cli/registry.json`**: a generated manifest listing every addable directory name (matching `src/ui/<name>`) plus optional **`nameAliases`** so the CLI accepts friendly tokens (for example `button` → `buttons`).
386
+ Which UI folders are valid for `add` is driven by **`cli/registry.json`**: a generated manifest listing every addable directory name (matching `src/ui/<name>` plus chart entries like `src/charts/area`) plus optional **`nameAliases`** so the CLI accepts friendly tokens (for example `button` → `buttons`).
342
387
 
343
388
  ### Commands
344
389
 
@@ -347,6 +392,7 @@ Call the published binary by name after the package (recommended so `npx` does n
347
392
  ```bash
348
393
  npx @zentauri-ui/zentauri-components init
349
394
  npx @zentauri-ui/zentauri-components add buttons inputs
395
+ npx @zentauri-ui/zentauri-components add charts/area charts/line
350
396
  npx @zentauri-ui/zentauri-components -h
351
397
  ```
352
398
 
@@ -372,11 +418,11 @@ node node_modules/@zentauri-ui/zentauri-components/cli/index.mjs add accordion
372
418
  node node_modules/@zentauri-ui/zentauri-components/cli/index.mjs add hook useWindowSize
373
419
  ```
374
420
 
375
- | Command | What it does |
376
- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
377
- | `init` | Writes **`components.json`** in the current working directory (or `--cwd`) with default `aliases` and `resolvedPaths`. Refuses to overwrite an existing file. |
378
- | `add <names...>` | Walks up from `--cwd` (default `.`) to find `components.json`, then copies each resolved **UI** folder under `src/ui`, pulls in hooks those files depend on (including transitive hook imports), and creates **`lib/utils`** at `resolvedPaths.utils` from the package template if it is missing. |
379
- | `add hook <names...>` | Same config lookup; copies only **hook** folders listed under `registry.hooks` (from `hooksEntryNames` in `tsup.config.ts`), including transitive sibling-hook imports. Does not copy UI unless a hook’s imports require you to add a component separately (for example `usePagination` imports types from `ui/pagination`). |
421
+ | Command | What it does |
422
+ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
423
+ | `init` | Writes **`components.json`** in the current working directory (or `--cwd`) with default `aliases` and `resolvedPaths`. Refuses to overwrite an existing file. |
424
+ | `add <names...>` | Walks up from `--cwd` (default `.`) to find `components.json`, then copies each resolved **UI** folder under `src/ui` or chart entry under `src/charts/<type>`, pulls in hooks those files depend on (including transitive hook imports), and creates **`lib/utils`** at `resolvedPaths.utils` from the package template if it is missing. |
425
+ | `add hook <names...>` | Same config lookup; copies only **hook** folders listed under `registry.hooks` (from `hooksEntryNames` in `tsup.config.ts`), including transitive sibling-hook imports. Does not copy UI unless a hook’s imports require you to add a component separately (for example `usePagination` imports types from `ui/pagination`). |
380
426
 
381
427
  Global flags: `-h` / `--help`, `-v` / `--version`, `--cwd <dir>` (relative to `process.cwd()`).
382
428
 
@@ -401,7 +447,7 @@ Defaults look like this; edit `resolvedPaths` and `aliases` so they match your a
401
447
 
402
448
  ### Registry (`cli/registry.json`)
403
449
 
404
- - **`components`**: sorted list of folder names under **`src/ui/`** that `add` may copy. The file is **generated**; the canonical build list lives in **`tsup.config.ts`** as `uiComponentNames`, and the generator always ensures **`spinner`** is included so the CLI stays aligned with the animated-only spinner bundle.
450
+ - **`components`**: sorted list of folder names under **`src/ui/`**, plus chart entries from **`src/charts/<type>`**, that `add` may copy. The file is **generated**; the canonical build list lives in **`tsup.config.ts`** as `uiComponentNames` and `chartEntryNames`, and the generator always ensures **`spinner`** is included so the CLI stays aligned with the animated-only spinner bundle.
405
451
  - **`hooks`**: sorted list of folder names under **`src/hooks/`** that `add hook` may copy; generated from **`hooksEntryNames`** in **`tsup.config.ts`** (same entries as published `…/hooks/<name>` subpaths).
406
452
  - **`nameAliases`**: optional map from a CLI token to a real folder name. Today: `button` → `buttons`, `input` → `inputs` (matching common singular names while folders stay plural).
407
453
 
@@ -431,10 +477,10 @@ https://zentauri-ui.vercel.app/
431
477
 
432
478
  From this package directory in the monorepo:
433
479
 
434
- - `pnpm build` (or `npm run build`) — production bundle via `tsup` (Rollup treeshake + `scripts/prepend-use-client.mjs` via `onSuccess` so each UI entry under `dist/ui/`, including `dist/ui/<name>/animated.*`, starts with `"use client"` where needed)
480
+ - `pnpm build` (or `npm run build`) — production bundle via `tsup` (Rollup treeshake + `scripts/prepend-use-client.mjs` via `onSuccess` so each UI entry under `dist/ui/`, the chart entry under `dist/charts/`, and `dist/ui/<name>/animated.*` starts with `"use client"` where needed)
435
481
  - `pnpm dev` — `tsup` watch mode (same `onSuccess` hook after each rebuild)
436
482
  - `pnpm test` / `pnpm test:watch` — **Vitest** and **Testing Library** unit tests // covered 300+ test cases in total
437
- - **`pnpm run generate:registry`** — runs `scripts/generate-registry.mjs`, which reads **`uiComponentNames`** and **`hooksEntryNames`** from `tsup.config.ts`, merges in **`spinner`**, applies fixed **`nameAliases`**, and writes **`cli/registry.json`** (`components` + `hooks`). Run this after adding or renaming UI areas or hook entries so the CLI stays in sync (the script prints counts).
483
+ - **`pnpm run generate:registry`** — runs `scripts/generate-registry.mjs`, which reads **`uiComponentNames`** and **`hooksEntryNames`** from `tsup.config.ts`, merges in **`spinner`**, applies fixed **`nameAliases`**, and writes **`cli/registry.json`** (`components` + `hooks`). Run this after adding or renaming UI/chart areas or hook entries so the CLI stays in sync (the script prints counts).
438
484
  - **`prepack`** — invokes `generate:registry` automatically before `npm pack` / publish so the published tarball always ships an up-to-date registry alongside `cli/index.mjs`.
439
485
 
440
486
  ## Github Release log
package/cli/index.mjs CHANGED
@@ -20,12 +20,13 @@
20
20
  * ├── cli/index.mjs ← this file (entry when run via bin)
21
21
  * ├── cli/registry.json ← list of installable component folder names
22
22
  * └── src/ui/<name>/ ← source copied by `add`
23
+ * └── src/charts/<type>/ ← chart source copied by `add charts/area` etc.
23
24
  * └── src/hooks/<name>/ ← hooks pulled in as dependencies
24
25
  * └── src/lib/utils.ts ← template for `cn()` etc. if missing in app
25
26
  * ```
26
27
  *
27
28
  * - **packageRoot**: directory of the published `components` package (parent of
28
- * `cli/`). Used to read `registry.json`, `src/ui`, `src/hooks`, `src/lib`.
29
+ * `cli/`). Used to read `registry.json`, `src/ui`, `src/charts`, `src/hooks`, `src/lib`.
29
30
  * - **configDir**: directory containing `components.json` (may differ from
30
31
  * `--cwd` when the config is found by walking up from `cwd`).
31
32
  *
@@ -88,7 +89,7 @@ import {
88
89
  copyFile,
89
90
  readdir,
90
91
  } from "node:fs/promises";
91
- import { dirname, join, relative } from "node:path";
92
+ import { dirname, join, relative, resolve } from "node:path";
92
93
  import { fileURLToPath } from "node:url";
93
94
  import { parseArgs } from "node:util";
94
95
 
@@ -102,7 +103,7 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
102
103
 
103
104
  /**
104
105
  * Root of the components package (`…/packages/components`), i.e. parent of `cli/`.
105
- * All reads from `src/ui`, `src/hooks`, `registry.json`, and `package.json` are
106
+ * All reads from `src/ui`, `src/charts`, `src/hooks`, `registry.json`, and `package.json` are
106
107
  * relative to this path — not the consumer’s project root.
107
108
  */
108
109
  const packageRoot = join(__dirname, "..");
@@ -189,7 +190,9 @@ If npx does not pick the right binary:
189
190
  * isTestFile("foo.test.utils.ts"); // true (substring ".test.")
190
191
  */
191
192
  function isTestFile(name) {
192
- return /\.(?:test|spec)\.(?:tsx?|jsx?)$/.test(name) || name.includes(".test.");
193
+ return (
194
+ /\.(?:test|spec)\.(?:tsx?|jsx?)$/.test(name) || name.includes(".test.")
195
+ );
193
196
  }
194
197
 
195
198
  /**
@@ -303,7 +306,11 @@ function validateConfig(cfg) {
303
306
  "components.json must define aliases.utils, aliases.hooks, and aliases.ui",
304
307
  );
305
308
  }
306
- if (!cfg.resolvedPaths?.ui || !cfg.resolvedPaths?.utils || !cfg.resolvedPaths?.hooks) {
309
+ if (
310
+ !cfg.resolvedPaths?.ui ||
311
+ !cfg.resolvedPaths?.utils ||
312
+ !cfg.resolvedPaths?.hooks
313
+ ) {
307
314
  throw new Error(
308
315
  "components.json must define resolvedPaths.ui, resolvedPaths.utils, and resolvedPaths.hooks",
309
316
  );
@@ -312,7 +319,7 @@ function validateConfig(cfg) {
312
319
 
313
320
  /**
314
321
  * Maps CLI input (any casing, optional registry alias) to a canonical folder name
315
- * under `src/ui/<name>` in the package.
322
+ * under `src/ui/<name>` or `src/charts/<type>`.
316
323
  *
317
324
  * Resolution order:
318
325
  * 1. Exact key in `registry.nameAliases`
@@ -416,12 +423,12 @@ async function collectHookTransitiveClosure(packageRoot, seedHooks) {
416
423
  }
417
424
 
418
425
  /**
419
- * Copies `packageRoot/src/ui/<componentName>` into
426
+ * Copies `packageRoot/src/ui/<componentName>` or `packageRoot/src/charts/<type>` into
420
427
  * `<configDir>/<resolvedPaths.ui>/<componentName>`, skipping tests, rewriting
421
428
  * imports in TS/JS files, and collecting hook folder names referenced by those
422
429
  * files for later copying.
423
430
  *
424
- * @param {string} componentName — resolved registry name (directory under `src/ui`)
431
+ * @param {string} componentName — resolved registry name (directory under `src/ui`, or `charts/<type>`)
425
432
  * @param {object} config — validated `components.json`
426
433
  * @param {string} configDir — dirname(components.json)
427
434
  * @param {string} packageRoot — package containing source
@@ -433,18 +440,29 @@ async function collectHookTransitiveClosure(packageRoot, seedHooks) {
433
440
  * // src/components/ui/buttons/Button.tsx
434
441
  * // with imports pointing at @/lib/utils, @/hooks/useX, etc.
435
442
  */
436
- async function copyUiComponent(
437
- componentName,
438
- config,
439
- configDir,
440
- packageRoot,
441
- ) {
442
- const srcRoot = join(packageRoot, "src", "ui", componentName);
443
+ async function copyUiComponent(componentName, config, configDir, packageRoot) {
444
+ const isChartEntry = componentName.startsWith("charts/");
445
+ const srcRoot = isChartEntry
446
+ ? join(packageRoot, "src", "charts")
447
+ : join(packageRoot, "src", "ui", componentName);
443
448
  if (!existsSync(srcRoot)) {
444
- throw new Error(`Missing package source: ${relative(packageRoot, srcRoot)}`);
449
+ throw new Error(
450
+ `Missing package source: ${relative(packageRoot, srcRoot)}`,
451
+ );
445
452
  }
446
- const destRoot = join(configDir, config.resolvedPaths.ui, componentName);
447
- const files = await walkFiles(srcRoot);
453
+ const destRoot = isChartEntry
454
+ ? join(configDir, config.resolvedPaths.ui, "charts")
455
+ : join(configDir, config.resolvedPaths.ui, componentName);
456
+ const files = (await walkFiles(srcRoot)).filter((absSrc) => {
457
+ if (!isChartEntry) {
458
+ return true;
459
+ }
460
+ const relFromChartsRoot = relative(srcRoot, absSrc);
461
+ return (
462
+ relFromChartsRoot.startsWith("shared/") ||
463
+ relFromChartsRoot.startsWith(`${componentName.slice("charts/".length)}/`)
464
+ );
465
+ });
448
466
  const usedHooks = new Set();
449
467
 
450
468
  for (const absSrc of files) {
@@ -594,8 +612,7 @@ async function cmdAdd(names, cwd) {
594
612
  validateConfig(config);
595
613
 
596
614
  const registry = loadRegistry();
597
- const hookMode =
598
- names.length > 0 && names[0].toLowerCase() === "hook";
615
+ const hookMode = names.length > 0 && names[0].toLowerCase() === "hook";
599
616
  const payload = hookMode ? names.slice(1) : names;
600
617
 
601
618
  if (hookMode && payload.length === 0) {
@@ -604,9 +621,10 @@ async function cmdAdd(names, cwd) {
604
621
  );
605
622
  process.exitCode = 1;
606
623
  return;
607
- }
624
+ }
608
625
 
609
626
  if (hookMode) {
627
+ await ensureUtilsFile(config, configDir, packageRoot);
610
628
  const resolvedHooks = payload.map((n) => resolveHookName(n, registry));
611
629
  const finalHooks = await collectHookTransitiveClosure(
612
630
  packageRoot,
@@ -622,6 +640,8 @@ async function cmdAdd(names, cwd) {
622
640
 
623
641
  const resolvedNames = payload.map((n) => resolveComponentName(n, registry));
624
642
 
643
+ await ensureUtilsFile(config, configDir, packageRoot);
644
+
625
645
  const allHooks = new Set();
626
646
  for (const name of resolvedNames) {
627
647
  console.log(`Adding ${name}…`);
@@ -631,10 +651,9 @@ async function cmdAdd(names, cwd) {
631
651
  }
632
652
  }
633
653
 
634
- const finalHooks = await collectHookTransitiveClosure(
635
- packageRoot,
636
- [...allHooks],
637
- );
654
+ const finalHooks = await collectHookTransitiveClosure(packageRoot, [
655
+ ...allHooks,
656
+ ]);
638
657
 
639
658
  for (const h of finalHooks) {
640
659
  console.log(`Adding hook ${h}…`);
@@ -685,7 +704,7 @@ async function main() {
685
704
  return;
686
705
  }
687
706
 
688
- const cwd = values.cwd ? join(process.cwd(), values.cwd) : process.cwd();
707
+ const cwd = values.cwd ? resolve(process.cwd(), values.cwd) : process.cwd();
689
708
  const cmd = positionals[0];
690
709
  const rest = positionals.slice(1);
691
710
 
package/cli/registry.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "description": "Addable UI components (src/ui) and hooks (src/hooks). Generated by scripts/generate-registry.mjs.",
3
+ "description": "Addable UI components (src/ui), chart entries (src/charts/*), and hooks (src/hooks). Generated by scripts/generate-registry.mjs.",
4
4
  "components": [
5
5
  "accordion",
6
6
  "alert",
@@ -9,6 +9,10 @@
9
9
  "breadcrumb",
10
10
  "buttons",
11
11
  "card",
12
+ "charts/area",
13
+ "charts/bar",
14
+ "charts/bubble",
15
+ "charts/line",
12
16
  "divider",
13
17
  "drawer",
14
18
  "dropdown",
@@ -60,6 +64,10 @@
60
64
  ],
61
65
  "nameAliases": {
62
66
  "button": "buttons",
67
+ "chart-area": "charts/area",
68
+ "chart-bar": "charts/bar",
69
+ "chart-bubble": "charts/bubble",
70
+ "chart-line": "charts/line",
63
71
  "input": "inputs"
64
72
  }
65
73
  }
@@ -10,8 +10,7 @@ export function rewriteImports(source, options) {
10
10
  const usedHooks = new Set();
11
11
 
12
12
  const collectHooks = (text) => {
13
- const re =
14
- /from\s+(["'])((?:\.\.\/)+)hooks\/([^'"]+)\1/g;
13
+ const re = /from\s+(["'])((?:\.\.\/)+)hooks\/([^'"]+)\1/g;
15
14
  let m;
16
15
  while ((m = re.exec(text)) !== null) {
17
16
  usedHooks.add(m[3]);
@@ -29,7 +28,8 @@ export function rewriteImports(source, options) {
29
28
 
30
29
  code = code.replace(
31
30
  /from\s+(["'])((?:\.\.\/)+)hooks\/([^'"]+)\1/g,
32
- (_, quote, _rel, hookName) => `from ${quote}${hooksAlias}/${hookName}${quote}`,
31
+ (_, quote, _rel, hookName) =>
32
+ `from ${quote}${hooksAlias}/${hookName}${quote}`,
33
33
  );
34
34
 
35
35
  if (uiAlias) {
@@ -37,6 +37,11 @@ export function rewriteImports(source, options) {
37
37
  /from\s+(["'])((?:\.\.\/)+)ui\/([^'"]+)\1/g,
38
38
  (_, quote, _rel, rest) => `from ${quote}${uiAlias}/${rest}${quote}`,
39
39
  );
40
+
41
+ code = code.replace(
42
+ /from\s+(["'])((?:\.\.\/)+)charts([^'"]*)\1/g,
43
+ (_, quote, _rel, rest) => `from ${quote}${uiAlias}/charts${rest}${quote}`,
44
+ );
40
45
  }
41
46
 
42
47
  return { code, usedHooks: [...usedHooks] };
@@ -0,0 +1,6 @@
1
+ import type { AreaChartProps } from "../shared/types";
2
+ export declare function AreaChart<TDatum extends Record<string, number | string | null | undefined>>({ appearance, className, containerStyle, data, density, emptyState, height, margin, series, showGrid, showLegend, showTooltip, tooltipColor, stacked, style, syncId, xKey, ...props }: AreaChartProps<TDatum>): import("react/jsx-runtime").JSX.Element;
3
+ export declare namespace AreaChart {
4
+ var displayName: string;
5
+ }
6
+ //# sourceMappingURL=Area.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Area.d.ts","sourceRoot":"","sources":["../../../src/charts/area/Area.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,wBAAgB,SAAS,CACvB,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EACjE,EACA,UAAU,EACV,SAAS,EACT,cAAc,EACd,IAAI,EACJ,OAAO,EACP,UAAiB,EACjB,MAAY,EACZ,MAA2B,EAC3B,MAAM,EACN,QAAe,EACf,UAAkB,EAClB,WAAkB,EAClB,YAAwB,EACxB,OAAe,EACf,KAAK,EACL,MAAM,EACN,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,MAAM,CAAC,2CAmExB;yBAxFe,SAAS"}
@@ -0,0 +1,4 @@
1
+ export { AreaChart } from "./Area";
2
+ export type { AreaChartProps } from "../shared/types";
3
+ export { chartColorValues, chartPalette, chartVariants, } from "../shared/variants";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/charts/area/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,aAAa,GACd,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,119 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var chunkCIN5JDN4_js = require('../chunk-CIN5JDN4.js');
5
+ require('../chunk-ZS5756ZC.js');
6
+ var recharts = require('recharts');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+
9
+ function AreaChart({
10
+ appearance,
11
+ className,
12
+ containerStyle,
13
+ data,
14
+ density,
15
+ emptyState = null,
16
+ height = 320,
17
+ margin = chunkCIN5JDN4_js.defaultChartMargin,
18
+ series,
19
+ showGrid = true,
20
+ showLegend = false,
21
+ showTooltip = true,
22
+ tooltipColor = "#0f172a",
23
+ stacked = false,
24
+ style,
25
+ syncId,
26
+ xKey,
27
+ ...props
28
+ }) {
29
+ const hasData = data.length > 0 && series.length > 0;
30
+ const xAxisKey = String(xKey);
31
+ return /* @__PURE__ */ jsxRuntime.jsx(
32
+ chunkCIN5JDN4_js.ChartFrame,
33
+ {
34
+ appearance,
35
+ className,
36
+ containerStyle,
37
+ density,
38
+ emptyState,
39
+ hasData,
40
+ height,
41
+ style,
42
+ ...props,
43
+ children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.AreaChart, { data, margin, syncId, children: [
44
+ /* @__PURE__ */ jsxRuntime.jsx(
45
+ chunkCIN5JDN4_js.ChartDecorators,
46
+ {
47
+ axis: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
48
+ /* @__PURE__ */ jsxRuntime.jsx(
49
+ recharts.XAxis,
50
+ {
51
+ dataKey: xAxisKey,
52
+ minTickGap: 24,
53
+ tickLine: false,
54
+ tickMargin: 10,
55
+ axisLine: false,
56
+ fontSize: 12,
57
+ fill: "#ffffff",
58
+ color: "#ffffff"
59
+ }
60
+ ),
61
+ /* @__PURE__ */ jsxRuntime.jsx(
62
+ recharts.YAxis,
63
+ {
64
+ width: 40,
65
+ tickLine: false,
66
+ tickMargin: 8,
67
+ axisLine: false,
68
+ fontSize: 12,
69
+ fill: "#ffffff",
70
+ color: "#ffffff"
71
+ }
72
+ )
73
+ ] }),
74
+ showGrid,
75
+ showLegend,
76
+ showTooltip,
77
+ tooltipColor
78
+ }
79
+ ),
80
+ series.map((item, index) => {
81
+ const color = chunkCIN5JDN4_js.resolveColor(item.color, index);
82
+ const fill = chunkCIN5JDN4_js.getSeriesFill(item, index);
83
+ console.log(fill);
84
+ return /* @__PURE__ */ jsxRuntime.jsx(
85
+ recharts.Area,
86
+ {
87
+ type: "monotone",
88
+ dataKey: item.dataKey,
89
+ name: item.name,
90
+ stackId: stacked ? item.stackId ?? "stack" : item.stackId,
91
+ stroke: color.stroke,
92
+ fill,
93
+ fillOpacity: 1,
94
+ strokeWidth: 2
95
+ },
96
+ item.dataKey
97
+ );
98
+ })
99
+ ] })
100
+ }
101
+ );
102
+ }
103
+ AreaChart.displayName = "AreaChart";
104
+
105
+ Object.defineProperty(exports, "chartColorValues", {
106
+ enumerable: true,
107
+ get: function () { return chunkCIN5JDN4_js.chartColorValues; }
108
+ });
109
+ Object.defineProperty(exports, "chartPalette", {
110
+ enumerable: true,
111
+ get: function () { return chunkCIN5JDN4_js.chartPalette; }
112
+ });
113
+ Object.defineProperty(exports, "chartVariants", {
114
+ enumerable: true,
115
+ get: function () { return chunkCIN5JDN4_js.chartVariants; }
116
+ });
117
+ exports.AreaChart = AreaChart;
118
+ //# sourceMappingURL=area.js.map
119
+ //# sourceMappingURL=area.js.map