@zentauri-ui/zentauri-components 2.1.1 → 2.1.2

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
@@ -30,7 +30,7 @@ Generated from the component package Vitest JSON report via `pnpm --filter @zent
30
30
  | Metric | Result |
31
31
  | ---------- | ---------------- |
32
32
  | Test files | 92 passed (92) |
33
- | Tests | 707 passed (707) |
33
+ | Tests | 713 passed (713) |
34
34
 
35
35
  | Area | Test files | Tests |
36
36
  | --------------------------- | ---------- | ----- |
@@ -38,7 +38,7 @@ Generated from the component package Vitest JSON report via `pnpm --filter @zent
38
38
  | Standalone animations | 1 | 45 |
39
39
  | React hooks | 41 | 174 |
40
40
  | Design system facade | 1 | 11 |
41
- | CLI and import rewriting | 2 | 18 |
41
+ | CLI and import rewriting | 2 | 24 |
42
42
  | Axe core test cases | 1 | 6 |
43
43
 
44
44
  ### Per-suite snapshot
@@ -50,9 +50,9 @@ Generated from the component package Vitest JSON report via `pnpm --filter @zent
50
50
  | `src/ui/inputs/input.test.tsx` | 40 |
51
51
  | `src/ui/peer-isolation.test.ts` | 29 |
52
52
  | `src/ui/combobox/combobox.test.tsx` | 24 |
53
+ | `cli/cli.integration.test.ts` | 19 |
53
54
  | `src/ui/pagination/pagination.test.tsx` | 15 |
54
55
  | `src/ui/timeline/timeline.test.tsx` | 14 |
55
- | `cli/cli.integration.test.ts` | 13 |
56
56
  | `src/lib/facade.test.ts` | 11 |
57
57
  | `src/ui/alert/alert.test.tsx` | 11 |
58
58
  | `src/ui/rating/rating.test.tsx` | 11 |
@@ -846,7 +846,7 @@ From this package directory in the monorepo:
846
846
 
847
847
  - `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/`, animation entry under `dist/animations/`, chart entry under `dist/charts/`, and `dist/ui/<name>/animated.*` starts with `"use client"` where needed)
848
848
  - `pnpm dev` — `tsup` watch mode (same `onSuccess` hook after each rebuild)
849
- - `pnpm test` / `pnpm test:watch` — **Vitest** and **Testing Library** unit tests // currently covered 707 test cases in total
849
+ - `pnpm test` / `pnpm test:watch` — **Vitest** and **Testing Library** unit tests // currently covered 713 test cases in total
850
850
  - `pnpm test:a11y` — focused **axe-core** accessibility smoke coverage for package-level UI primitives and compound components
851
851
  - `pnpm check:tokens` — enforce the `--zui-*` token contract across design-system, variant, and local custom-property usage without generating a large checked-in token catalog
852
852
  - **`pnpm run generate:registry`** — runs `scripts/generate-registry.mjs`, which reads **`uiComponentNames`**, **`uiAnimatedComponentNames`**, **`animationEntryNames`**, **`chartEntryNames`**, and **`hooksEntryNames`** from `tsup.config.ts`, applies fixed **`nameAliases`**, scans each component/chart source to build **`peerHints`**, and writes **`cli/registry.json`** (`components` + `animations` + `hooks` + `peerHints`). Run this after adding or renaming UI, animation, chart, or hook entries so the CLI stays in sync (the script prints counts).
@@ -17,7 +17,122 @@ function runCli(cwd: string, args: string[]): string {
17
17
  });
18
18
  }
19
19
 
20
+ function runCliError(cwd: string, args: string[]): string {
21
+ try {
22
+ runCli(cwd, args);
23
+ throw new Error("Expected CLI command to fail");
24
+ } catch (error) {
25
+ if (error && typeof error === "object" && "stderr" in error) {
26
+ return Buffer.isBuffer(error.stderr)
27
+ ? error.stderr.toString("utf8")
28
+ : String(error.stderr);
29
+ }
30
+ throw error;
31
+ }
32
+ }
33
+
20
34
  describe("zentauri-ui CLI", () => {
35
+ it("should init with framework-aware Tailwind source guidance", () => {
36
+ const dir = mkdtempSync(join(tmpdir(), "zentauri-cli-init-next-"));
37
+ try {
38
+ const packageJsonPath = join(dir, "package.json");
39
+ execFileSync(
40
+ process.execPath,
41
+ [
42
+ "-e",
43
+ `require("node:fs").writeFileSync(${JSON.stringify(
44
+ packageJsonPath,
45
+ )}, JSON.stringify({ dependencies: { next: "16.0.0" } }))`,
46
+ ],
47
+ { cwd: dir },
48
+ );
49
+ const out = runCli(dir, ["init"]);
50
+ expect(out).toContain("Detected framework: Next.js");
51
+ expect(out).toContain('@source "./src/components/ui";');
52
+ expect(out).toContain("pnpm add react react-dom");
53
+ expect(existsSync(join(dir, "components.json"))).toBe(true);
54
+ } finally {
55
+ rmSync(dir, { recursive: true, force: true });
56
+ }
57
+ });
58
+
59
+ it("should detect Remix over Vite when both dependencies are present", () => {
60
+ const dir = mkdtempSync(join(tmpdir(), "zentauri-cli-init-remix-"));
61
+ try {
62
+ const packageJsonPath = join(dir, "package.json");
63
+ execFileSync(
64
+ process.execPath,
65
+ [
66
+ "-e",
67
+ `require("node:fs").writeFileSync(${JSON.stringify(
68
+ packageJsonPath,
69
+ )}, JSON.stringify({ dependencies: { "@remix-run/react": "2.0.0" }, devDependencies: { vite: "5.0.0" } }))`,
70
+ ],
71
+ { cwd: dir },
72
+ );
73
+ const out = runCli(dir, ["init"]);
74
+ expect(out).toContain("Detected framework: Remix");
75
+ expect(out).toContain('@source "./app/components/ui";');
76
+ } finally {
77
+ rmSync(dir, { recursive: true, force: true });
78
+ }
79
+ });
80
+
81
+ it("should list addable UI, chart, animation, and hook entries", () => {
82
+ const dir = mkdtempSync(join(tmpdir(), "zentauri-cli-list-"));
83
+ try {
84
+ const out = runCli(dir, ["list"]);
85
+ expect(out).toContain("UI components");
86
+ expect(out).toContain("buttons");
87
+ expect(out).toContain("charts/line");
88
+ expect(out).toContain("animations/fade-in");
89
+ expect(out).toContain("Hooks");
90
+ expect(out).toContain("useWindowSize");
91
+ } finally {
92
+ rmSync(dir, { recursive: true, force: true });
93
+ }
94
+ });
95
+
96
+ it("should print component info with install and import commands", () => {
97
+ const dir = mkdtempSync(join(tmpdir(), "zentauri-cli-info-"));
98
+ try {
99
+ const out = runCli(dir, ["info", "button"]);
100
+ expect(out).toContain("Name: buttons");
101
+ expect(out).toContain("npx zentauri-ui add button");
102
+ expect(out).toContain("@zentauri-ui/zentauri-components/ui/buttons");
103
+ expect(out).toContain("--animated");
104
+ } finally {
105
+ rmSync(dir, { recursive: true, force: true });
106
+ }
107
+ });
108
+
109
+ it("should add an animated component explicitly and report missing peers", () => {
110
+ const dir = mkdtempSync(join(tmpdir(), "zentauri-cli-add-animated-"));
111
+ try {
112
+ runCli(dir, ["init"]);
113
+ const out = runCli(dir, ["add", "--animated", "button"]);
114
+ expect(
115
+ existsSync(join(dir, "src/components/ui/buttons/animated/index.ts")),
116
+ ).toBe(true);
117
+ expect(out).toContain("Including animated entry for buttons");
118
+ expect(out).toContain("Missing peer dependencies in this project");
119
+ expect(out).toContain("framer-motion");
120
+ } finally {
121
+ rmSync(dir, { recursive: true, force: true });
122
+ }
123
+ });
124
+
125
+ it("should reject --animated for components without an animated entry", () => {
126
+ const dir = mkdtempSync(join(tmpdir(), "zentauri-cli-add-static-only-"));
127
+ try {
128
+ runCli(dir, ["init"]);
129
+ const stderr = runCliError(dir, ["add", "--animated", "pagination"]);
130
+ expect(stderr).toContain('Component "pagination" has no animated entry');
131
+ } finally {
132
+ rmSync(dir, { recursive: true, force: true });
133
+ }
134
+ });
135
+
21
136
  it("should init, add accordion, and rewrite internal imports", () => {
22
137
  const dir = mkdtempSync(join(tmpdir(), "zentauri-cli-int-"));
23
138
  try {
package/cli/index.mjs CHANGED
@@ -136,7 +136,7 @@ function loadRegistry() {
136
136
  */
137
137
  function printHelp() {
138
138
  const reg = loadRegistry();
139
- const componentsList = (reg.components ?? []).join("\n");
139
+ const componentsList = (reg.uiComponents ?? reg.components ?? []).join("\n");
140
140
  const animationsList = (reg.animations ?? []).join("\n");
141
141
  const hooksList = (reg.hooks ?? []).join("\n");
142
142
 
@@ -145,7 +145,10 @@ function printHelp() {
145
145
  Usage:
146
146
  zentauri-components init [options] Create components.json with defaults
147
147
  zentauri-components add <component> [...] Copy UI components (and their hooks)
148
+ zentauri-components add --animated <component> Copy and validate an animated UI entry
148
149
  zentauri-components add hook <hook> [...] Copy hook source only (plus transitive hook deps)
150
+ zentauri-components list Show addable components, charts, animations, and hooks
151
+ zentauri-components info <name> Show install/import details for one entry
149
152
  zentauri-components theme <hex> Generate compact global --zui-* theme tokens
150
153
 
151
154
  List of components:
@@ -301,6 +304,136 @@ function defaultConfig() {
301
304
  };
302
305
  }
303
306
 
307
+ const CORE_PEERS = [
308
+ "react",
309
+ "react-dom",
310
+ "class-variance-authority",
311
+ "clsx",
312
+ "tailwind-merge",
313
+ ];
314
+
315
+ // Ordered by specificity: meta-frameworks first, generic Vite last. Vite-era
316
+ // Remix (and other Vite-based setups) also depend on `vite`, so a first-match
317
+ // scan with Vite earlier would misclassify them.
318
+ const FRAMEWORKS = [
319
+ {
320
+ name: "Next.js",
321
+ deps: ["next"],
322
+ files: ["next.config.js", "next.config.mjs", "next.config.ts"],
323
+ source: '@source "./src/components/ui";',
324
+ note: "Place the @source line in your global CSS file, often app/globals.css.",
325
+ },
326
+ {
327
+ name: "Remix",
328
+ deps: ["@remix-run/react", "@remix-run/node"],
329
+ files: ["remix.config.js", "remix.config.mjs"],
330
+ source: '@source "./app/components/ui";',
331
+ note: "If components.json keeps the default src/ paths, use @source \"./src/components/ui\" instead.",
332
+ },
333
+ {
334
+ name: "Astro",
335
+ deps: ["astro"],
336
+ files: ["astro.config.js", "astro.config.mjs", "astro.config.ts"],
337
+ source: '@source "./src/components/ui";',
338
+ note: "Use this in the global stylesheet loaded by your Astro React integration.",
339
+ },
340
+ {
341
+ name: "Vite",
342
+ deps: ["vite"],
343
+ files: ["vite.config.js", "vite.config.mjs", "vite.config.ts"],
344
+ source: '@source "./src/components/ui";',
345
+ note: "Place the @source line in src/index.css or the CSS file imported by your app entry.",
346
+ },
347
+ ];
348
+
349
+ function readProjectPackageJson(cwd) {
350
+ const packagePath = join(cwd, "package.json");
351
+ if (!existsSync(packagePath)) {
352
+ return undefined;
353
+ }
354
+ try {
355
+ return JSON.parse(readFileSync(packagePath, "utf8"));
356
+ } catch {
357
+ return undefined;
358
+ }
359
+ }
360
+
361
+ function packageDependencyMap(pkg) {
362
+ return {
363
+ ...(pkg?.dependencies ?? {}),
364
+ ...(pkg?.devDependencies ?? {}),
365
+ ...(pkg?.peerDependencies ?? {}),
366
+ ...(pkg?.optionalDependencies ?? {}),
367
+ };
368
+ }
369
+
370
+ function detectFramework(cwd) {
371
+ const deps = packageDependencyMap(readProjectPackageJson(cwd));
372
+ return (
373
+ FRAMEWORKS.find((framework) =>
374
+ framework.deps.some((dep) => deps[dep]),
375
+ ) ??
376
+ FRAMEWORKS.find((framework) =>
377
+ framework.files.some((file) => existsSync(join(cwd, file))),
378
+ )
379
+ );
380
+ }
381
+
382
+ function printInitGuidance(cwd) {
383
+ const framework = detectFramework(cwd);
384
+ const missingCorePeers = getMissingDependencies(cwd, CORE_PEERS);
385
+ console.log(
386
+ `Detected framework: ${framework?.name ?? "React app (framework not detected)"}`,
387
+ );
388
+ console.log("\nInstall core peer dependencies:");
389
+ console.log(` pnpm add ${CORE_PEERS.join(" ")}`);
390
+ console.log(` npm install ${CORE_PEERS.join(" ")}`);
391
+ if (missingCorePeers.length > 0) {
392
+ console.log(
393
+ ` Missing now: ${missingCorePeers.join(", ")}`,
394
+ );
395
+ }
396
+ console.log("\nTailwind v4 source scanning:");
397
+ console.log(` ${framework?.source ?? '@source "./src/components/ui";'}`);
398
+ console.log(
399
+ ` ${framework?.note ?? "Place the @source line in the global CSS file processed by Tailwind."}`,
400
+ );
401
+ console.log("\nOptional peers:");
402
+ console.log(" framer-motion # animated UI and animation entries");
403
+ console.log(" react-icons # icon-heavy components such as rating");
404
+ console.log(" recharts # chart entries");
405
+ }
406
+
407
+ function findPackageJson(startDir) {
408
+ let d = startDir;
409
+ for (;;) {
410
+ const p = join(d, "package.json");
411
+ if (existsSync(p)) {
412
+ return p;
413
+ }
414
+ const parent = dirname(d);
415
+ if (parent === d) {
416
+ return undefined;
417
+ }
418
+ d = parent;
419
+ }
420
+ }
421
+
422
+ function getMissingDependencies(cwd, deps) {
423
+ const packagePath = findPackageJson(cwd);
424
+ if (!packagePath) {
425
+ return deps;
426
+ }
427
+ try {
428
+ const installed = packageDependencyMap(
429
+ JSON.parse(readFileSync(packagePath, "utf8")),
430
+ );
431
+ return deps.filter((dep) => !installed[dep]);
432
+ } catch {
433
+ return deps;
434
+ }
435
+ }
436
+
304
437
  /**
305
438
  * Ensures `add` has everything it needs to compute destination paths and rewrite
306
439
  * imports. Throws a single clear error if the config is incomplete.
@@ -396,6 +529,87 @@ function resolveHookName(input, registry) {
396
529
  );
397
530
  }
398
531
 
532
+ function resolveAnyRegistryName(input, registry) {
533
+ try {
534
+ return { kind: "component", name: resolveComponentName(input, registry) };
535
+ } catch {
536
+ try {
537
+ return { kind: "hook", name: resolveHookName(input, registry) };
538
+ } catch {
539
+ throw new Error(
540
+ `Unknown entry "${input}". Run: zentauri-ui list`,
541
+ );
542
+ }
543
+ }
544
+ }
545
+
546
+ function isAnimatedComponent(name, registry) {
547
+ return (registry.animatedComponents ?? []).includes(name);
548
+ }
549
+
550
+ function printList(registry) {
551
+ const ui = Array.from(
552
+ new Set([
553
+ ...(registry.uiComponents ?? registry.components ?? []),
554
+ ...(registry.animatedComponents ?? []).filter(
555
+ (name) => !(registry.uiComponents ?? []).includes(name),
556
+ ),
557
+ ]),
558
+ );
559
+ const charts = registry.charts ?? [];
560
+ const animations = registry.animations ?? [];
561
+ const hooks = registry.hooks ?? [];
562
+
563
+ console.log("UI components:");
564
+ console.log(ui.join("\n"));
565
+ console.log("\nCharts:");
566
+ console.log(charts.join("\n"));
567
+ console.log("\nAnimations:");
568
+ console.log(animations.join("\n"));
569
+ console.log("\nHooks:");
570
+ console.log(hooks.join("\n"));
571
+ }
572
+
573
+ function importPathFor(name, kind, registry) {
574
+ const uiComponents = registry.uiComponents ?? [];
575
+
576
+ if (kind === "hook") {
577
+ return `@zentauri-ui/zentauri-components/hooks/${name}`;
578
+ }
579
+ if (name.startsWith("charts/")) {
580
+ return `@zentauri-ui/zentauri-components/${name}`;
581
+ }
582
+ if (name.startsWith("animations/")) {
583
+ return `@zentauri-ui/zentauri-components/${name}`;
584
+ }
585
+ if (isAnimatedComponent(name, registry) && !uiComponents.includes(name)) {
586
+ return `@zentauri-ui/zentauri-components/ui/${name}/animated`;
587
+ }
588
+ return `@zentauri-ui/zentauri-components/ui/${name}`;
589
+ }
590
+
591
+ function printInfo(input, registry) {
592
+ const { kind, name } = resolveAnyRegistryName(input, registry);
593
+ const peers = kind === "component" ? (registry.peerHints?.[name] ?? []) : [];
594
+
595
+ console.log(`Name: ${name}`);
596
+ console.log(`Type: ${kind === "hook" ? "hook" : "addable entry"}`);
597
+ console.log(`Add command: npx zentauri-ui add ${input}`);
598
+ if (kind === "hook") {
599
+ console.log(`Hook-only command: npx zentauri-ui add hook ${name}`);
600
+ }
601
+ console.log(`Import: ${importPathFor(name, kind, registry)}`);
602
+ if (kind === "component" && isAnimatedComponent(name, registry)) {
603
+ console.log(
604
+ `Animated import: @zentauri-ui/zentauri-components/ui/${name}/animated`,
605
+ );
606
+ console.log(`Animated vendoring: npx zentauri-ui add --animated ${input}`);
607
+ }
608
+ if (peers.length > 0) {
609
+ console.log(`Peer hints: ${peers.join(", ")}`);
610
+ }
611
+ }
612
+
399
613
  const THEME_COLOR_NAMES = [
400
614
  "blue",
401
615
  "cyan",
@@ -901,7 +1115,7 @@ const PEER_HINT_REASONS = {
901
1115
  * @param {object} registry — from `loadRegistry()`
902
1116
  * @param {object} config — validated `components.json` (for resolvedPaths.ui)
903
1117
  */
904
- function printAdoptionHints(resolvedNames, registry, config) {
1118
+ function printAdoptionHints(resolvedNames, registry, config, configDir) {
905
1119
  const peerHints = registry.peerHints ?? {};
906
1120
  /** @type {Map<string, string[]>} peer -> component names that need it */
907
1121
  const needed = new Map();
@@ -923,6 +1137,14 @@ function printAdoptionHints(resolvedNames, registry, config) {
923
1137
  );
924
1138
  }
925
1139
  console.log(` Install with: npm i ${[...needed.keys()].join(" ")}`);
1140
+ const missing = getMissingDependencies(configDir, [...needed.keys()]);
1141
+ if (missing.length > 0) {
1142
+ console.log("\nMissing peer dependencies in this project:");
1143
+ for (const peer of missing) {
1144
+ console.log(` - ${peer}`);
1145
+ }
1146
+ console.log(` Install with: pnpm add ${missing.join(" ")}`);
1147
+ }
926
1148
  }
927
1149
 
928
1150
  const uiPath = config?.resolvedPaths?.ui ?? "your components directory";
@@ -962,6 +1184,7 @@ async function cmdInit(cwd) {
962
1184
  const body = `${JSON.stringify(defaultConfig(), null, 2)}\n`;
963
1185
  await writeFile(target, body, "utf8");
964
1186
  console.log(`Wrote ${target}`);
1187
+ printInitGuidance(cwd);
965
1188
  }
966
1189
 
967
1190
  /**
@@ -983,7 +1206,7 @@ async function cmdInit(cwd) {
983
1206
  * // No components.json in cwd or parents — stderr:
984
1207
  * // No components.json found. Run: zentauri-components init (or: zentauri-ui init)
985
1208
  */
986
- async function cmdAdd(names, cwd) {
1209
+ async function cmdAdd(names, cwd, options = {}) {
987
1210
  const configPath = await findComponentsJson(cwd);
988
1211
  if (!configPath) {
989
1212
  console.error(
@@ -997,6 +1220,7 @@ async function cmdAdd(names, cwd) {
997
1220
  validateConfig(config);
998
1221
 
999
1222
  const registry = loadRegistry();
1223
+ const animated = Boolean(options.animated);
1000
1224
  const hookMode = names.length > 0 && names[0].toLowerCase() === "hook";
1001
1225
  const payload = hookMode ? names.slice(1) : names;
1002
1226
 
@@ -1009,6 +1233,11 @@ async function cmdAdd(names, cwd) {
1009
1233
  }
1010
1234
 
1011
1235
  if (hookMode) {
1236
+ if (animated) {
1237
+ console.error("--animated can only be used with UI component entries.");
1238
+ process.exitCode = 1;
1239
+ return;
1240
+ }
1012
1241
  await ensureUtilsFile(config, configDir, packageRoot);
1013
1242
  const resolvedHooks = payload.map((n) => resolveHookName(n, registry));
1014
1243
  const finalHooks = await collectHookTransitiveClosure(
@@ -1024,6 +1253,15 @@ async function cmdAdd(names, cwd) {
1024
1253
  }
1025
1254
 
1026
1255
  const resolvedNames = payload.map((n) => resolveComponentName(n, registry));
1256
+ if (animated) {
1257
+ for (const name of resolvedNames) {
1258
+ if (!isAnimatedComponent(name, registry)) {
1259
+ console.error(`Component "${name}" has no animated entry.`);
1260
+ process.exitCode = 1;
1261
+ return;
1262
+ }
1263
+ }
1264
+ }
1027
1265
 
1028
1266
  await ensureUtilsFile(config, configDir, packageRoot);
1029
1267
  await copyDesignSystemFolder(config, configDir, packageRoot);
@@ -1031,6 +1269,9 @@ async function cmdAdd(names, cwd) {
1031
1269
  const allHooks = new Set();
1032
1270
  for (const name of resolvedNames) {
1033
1271
  console.log(`Adding ${name}…`);
1272
+ if (animated) {
1273
+ console.log(`Including animated entry for ${name}…`);
1274
+ }
1034
1275
  const uh = await copyUiComponent(name, config, configDir, packageRoot);
1035
1276
  for (const h of uh) {
1036
1277
  allHooks.add(h);
@@ -1047,7 +1288,7 @@ async function cmdAdd(names, cwd) {
1047
1288
  }
1048
1289
 
1049
1290
  console.log("Done.");
1050
- printAdoptionHints(resolvedNames, registry, config);
1291
+ printAdoptionHints(resolvedNames, registry, config, configDir);
1051
1292
  }
1052
1293
 
1053
1294
  async function cmdTheme(hex, options, cwd) {
@@ -1102,6 +1343,7 @@ async function main() {
1102
1343
  out: { type: "string" },
1103
1344
  selector: { type: "string" },
1104
1345
  dark: { type: "string" },
1346
+ animated: { type: "boolean" },
1105
1347
  },
1106
1348
  });
1107
1349
 
@@ -1131,6 +1373,19 @@ async function main() {
1131
1373
  await cmdInit(cwd);
1132
1374
  return;
1133
1375
  }
1376
+ if (cmd === "list") {
1377
+ printList(loadRegistry());
1378
+ return;
1379
+ }
1380
+ if (cmd === "info") {
1381
+ if (rest.length === 0) {
1382
+ console.error("Usage: zentauri-components info <component|hook>");
1383
+ process.exitCode = 1;
1384
+ return;
1385
+ }
1386
+ printInfo(rest[0], loadRegistry());
1387
+ return;
1388
+ }
1134
1389
  if (cmd === "add") {
1135
1390
  if (rest.length === 0) {
1136
1391
  console.error(
@@ -1139,7 +1394,7 @@ async function main() {
1139
1394
  process.exitCode = 1;
1140
1395
  return;
1141
1396
  }
1142
- await cmdAdd(rest, cwd);
1397
+ await cmdAdd(rest, cwd, { animated: values.animated });
1143
1398
  return;
1144
1399
  }
1145
1400
  if (cmd === "theme") {
package/cli/registry.json CHANGED
@@ -1,6 +1,90 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "description": "Addable UI components (src/ui), animation entries (src/animations/*), chart entries (src/charts/*), and hooks (src/hooks). Generated by scripts/generate-registry.mjs.",
4
+ "uiComponents": [
5
+ "accordion",
6
+ "alert",
7
+ "animated-number",
8
+ "avatar",
9
+ "badge",
10
+ "breadcrumb",
11
+ "buttons",
12
+ "card",
13
+ "checkbox",
14
+ "combobox",
15
+ "command",
16
+ "context-menu",
17
+ "copy-button",
18
+ "divider",
19
+ "drawer",
20
+ "dropdown",
21
+ "dynamic-stepper",
22
+ "empty-state",
23
+ "file-upload",
24
+ "inputs",
25
+ "kbd",
26
+ "marquee",
27
+ "modal",
28
+ "otp-input",
29
+ "pagination",
30
+ "popover",
31
+ "progress",
32
+ "radio-group",
33
+ "rating",
34
+ "scroll-area",
35
+ "search",
36
+ "select",
37
+ "skeleton",
38
+ "slider",
39
+ "table",
40
+ "tabs",
41
+ "timeline",
42
+ "toast",
43
+ "toggle",
44
+ "tooltip",
45
+ "tree-view",
46
+ "typography"
47
+ ],
48
+ "animatedComponents": [
49
+ "accordion",
50
+ "alert",
51
+ "avatar",
52
+ "badge",
53
+ "buttons",
54
+ "card",
55
+ "checkbox",
56
+ "command",
57
+ "copy-button",
58
+ "divider",
59
+ "drawer",
60
+ "empty-state",
61
+ "inputs",
62
+ "kbd",
63
+ "modal",
64
+ "popover",
65
+ "progress",
66
+ "radio-group",
67
+ "skeleton",
68
+ "spinner",
69
+ "table",
70
+ "tabs",
71
+ "timeline",
72
+ "toast",
73
+ "toggle",
74
+ "tooltip",
75
+ "tree-view"
76
+ ],
77
+ "charts": [
78
+ "charts/area",
79
+ "charts/bar",
80
+ "charts/bubble",
81
+ "charts/funnel",
82
+ "charts/line",
83
+ "charts/pie",
84
+ "charts/radar",
85
+ "charts/scatter",
86
+ "charts/stacked-bar"
87
+ ],
4
88
  "components": [
5
89
  "accordion",
6
90
  "alert",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zentauri-ui/zentauri-components",
3
- "version": "2.1.1",
3
+ "version": "2.1.2",
4
4
  "description": "React + Tailwind UI kit with charts, ESM/CJS builds, per-entry exports, and a zentauri-components / zentauri-ui CLI to vendor UI or hook source into your app",
5
5
  "keywords": [
6
6
  "react",
@@ -103,7 +103,8 @@
103
103
  "prepack": "npm run build && node scripts/generate-registry.mjs && node scripts/check-design-tokens.mjs && node scripts/check-exports.mjs",
104
104
  "test": "vitest run",
105
105
  "test:a11y": "vitest run src/accessibility/axe-core.test.tsx",
106
- "test:watch": "vitest"
106
+ "test:watch": "vitest",
107
+ "test:all": "pnpm test && pnpm test:a11y"
107
108
  },
108
109
  "peerDependencies": {
109
110
  "class-variance-authority": "*",