@zvoove/unity-ui 2.26.2 → 2.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- #!/usr/bin/env node
2
+ import{createRequire}from"module";const require=createRequire(import.meta.url);
3
3
  var __create = Object.create;
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -91,7 +91,7 @@ var init_config = __esm({
91
91
  },
92
92
  rules: {
93
93
  output: ".",
94
- targets: ["cursorrules", "claude"]
94
+ filename: "UNITYUI.md"
95
95
  }
96
96
  }
97
97
  };
@@ -3668,31 +3668,7 @@ function ask(rl, question, defaultValue) {
3668
3668
  );
3669
3669
  });
3670
3670
  }
3671
- function askChoice(rl, question, options, defaultValue) {
3672
- const optionsList = options.map((o) => o.label).join(" / ");
3673
- return new Promise((resolve) => {
3674
- rl.question(
3675
- ` \x1B[36m?\x1B[0m ${question} \x1B[90m(${defaultValue})\x1B[0m [${optionsList}] `,
3676
- (answer) => {
3677
- const trimmed = answer.trim().toLowerCase();
3678
- const match = options.find(
3679
- (o) => o.label.toLowerCase() === trimmed || o.alias === trimmed
3680
- );
3681
- if (match) {
3682
- resolve(match.value);
3683
- } else {
3684
- const defaultOption = options.find(
3685
- (o) => o.label.toLowerCase() === defaultValue.toLowerCase() || o.alias === defaultValue.toLowerCase()
3686
- );
3687
- resolve(defaultOption ? defaultOption.value : options[0].value);
3688
- }
3689
- }
3690
- );
3691
- });
3692
- }
3693
3671
  function generateConfigContent(config) {
3694
- const targets = config.ai.rules.targets;
3695
- const targetsStr = targets.map((t) => `'${t}'`).join(", ");
3696
3672
  return `// unity-ui.config.mjs \u2014 generated by \`npx unity-ui init\`
3697
3673
  import { defineConfig } from '@zvoove/unity-ui/config';
3698
3674
 
@@ -3707,7 +3683,6 @@ export default defineConfig({
3707
3683
  },
3708
3684
  rules: {
3709
3685
  output: '${config.ai.rules.output}',
3710
- targets: [${targetsStr}],
3711
3686
  },
3712
3687
  },
3713
3688
  });
@@ -3735,17 +3710,6 @@ async function runInit() {
3735
3710
  "Where is your main index/barrel file?",
3736
3711
  DEFAULTS.components.indexFile
3737
3712
  );
3738
- const rulesTargets = await askChoice(
3739
- rl,
3740
- "Generate AI rules for which tools?",
3741
- [
3742
- { label: "Both", alias: "b", value: ["cursorrules", "claude"] },
3743
- { label: "Claude", alias: "c", value: ["claude"] },
3744
- { label: "Cursor", alias: "u", value: ["cursorrules"] },
3745
- { label: "None", alias: "n", value: [] }
3746
- ],
3747
- "Both"
3748
- );
3749
3713
  const skillsOutput = await ask(
3750
3714
  rl,
3751
3715
  "Where should Agent Skills be generated?",
@@ -3764,7 +3728,7 @@ async function runInit() {
3764
3728
  },
3765
3729
  ai: {
3766
3730
  skills: { output: skillsOutput },
3767
- rules: { output: rulesOutput, targets: rulesTargets }
3731
+ rules: { output: rulesOutput }
3768
3732
  }
3769
3733
  };
3770
3734
  const content = generateConfigContent(config);
@@ -3775,31 +3739,151 @@ async function runInit() {
3775
3739
  console.log(` Components: ${config.components.directory}/`);
3776
3740
  console.log(` Index file: ${config.components.indexFile}`);
3777
3741
  console.log(` Skills dir: ${config.ai.skills.output}/skills/`);
3778
- if (config.ai.rules.targets.length > 0) {
3779
- console.log(
3780
- ` Rules: ${config.ai.rules.targets.join(", ")} \u2192 ${config.ai.rules.output}/`
3781
- );
3782
- } else {
3783
- console.log(` Rules: disabled`);
3784
- }
3742
+ console.log(` Rules: ${config.ai.rules.output}/UNITYUI.md`);
3785
3743
  console.log("");
3786
3744
  }
3787
3745
 
3788
3746
  // bin/commands/rules.mjs
3789
3747
  init_config();
3790
-
3791
- // bin/commands/skills.mjs
3792
3748
  import fs4 from "fs";
3793
3749
  import path4 from "path";
3750
+ function generateRulesContent() {
3751
+ return `# Unity UI \u2014 Rules
3752
+
3753
+ > Auto-generated by \`npx unity-ui rules\`. Do not edit manually.
3754
+ > Full API docs live in Agent Skills \u2014 this file contains only conventions and routing.
3755
+
3756
+ ## General Rules
3757
+
3758
+ - Always import components from \`@zvoove/unity-ui\`
3759
+ - Never recreate components that exist in this library
3760
+ - Use responsive props where applicable (single value or breakpoint object)
3761
+ - Use design tokens from theme.css \u2014 never hardcode colors, spacing, or shadows
3762
+ - Use \`tv()\` from tailwind-variants for component styling \u2014 never inline conditional classes
3763
+ - Dark mode uses \`data-theme="dark"\` attribute, not \`className="dark"\`
3764
+ - Default/placeholder texts should be in German
3765
+ - Font (Source Sans 3) is bundled via \`@font-face\` in theme.css \u2014 no extra setup needed
3766
+ - NEVER pass \`className\` or \`style\` to ANY Unity UI component \u2014 use their props API only; put token-based Tailwind on native HTML wrappers (\`div\`, \`section\`, etc.) when you need extra layout or chrome
3767
+ - Stack \`align\` defaults to \`baseline\` \u2014 always set \`align\` explicitly when centering or stretching is needed
3768
+ - Stack with a Divider needs \`width="100%"\` \u2014 otherwise the divider will not span the full container width
3769
+ - Use Stack and Grid for layout \u2014 do not use Card, div, or CSS for layout
3770
+ - Card is a visual container, NOT a layout tool \u2014 use Stack/Grid INSIDE a Card
3771
+ - Use Typography for all text \u2014 never use raw \`<p>\`, \`<h1>\`, \`<span>\` etc.
3772
+ - Use the spacing scale for gap/padding/margin \u2014 never use arbitrary pixel values
3773
+ - Icons use semantic names as strings (e.g., \`"search"\`, \`"delete"\`, \`"edit"\`) \u2014 never import Phosphor icon components directly
3774
+
3775
+ ## Skill Routing
3776
+
3777
+ Before building UI with Unity UI, load the relevant skill for your task:
3778
+
3779
+ | Task | Skill to load |
3780
+ |------|---------------|
3781
+ | Installation & setup | \`unity-ui-setup\` |
3782
+ | Find the right component | \`unity-ui-index\` |
3783
+ | Page layout / app shell | \`unity-ui-layouts\` |
3784
+ | Build a form (with validation) | \`unity-ui-forms\` |
3785
+ | Styling / Tailwind / design tokens | \`unity-ui-styling\` |
3786
+ | Create a custom component | \`unity-ui-custom-component\` |
3787
+ | Dark mode / theme toggle | \`unity-ui-dark-mode\` |
3788
+ | Icon names | \`unity-ui-icons\` |
3789
+ | Migrate from shadcn/ui | \`unity-ui-migrate-shadcn\` |
3790
+ | Migrate from MUI | \`unity-ui-migrate-mui\` |
3791
+ | Figma Code Connect | \`unity-ui-figma-code-connect\` |
3792
+
3793
+ ## Component Directory
3794
+
3795
+ Load the matching skill for full props, examples, and rules:
3796
+
3797
+ | Component | Skill |
3798
+ |-----------|-------|
3799
+ | Accordion | \`unity-ui-accordion\` |
3800
+ | Avatar / AvatarGroup | \`unity-ui-avatar\` |
3801
+ | Badge | \`unity-ui-badge\` |
3802
+ | Breadcrumbs | \`unity-ui-breadcrumbs\` |
3803
+ | Button | \`unity-ui-button\` |
3804
+ | Card | \`unity-ui-card\` |
3805
+ | Checkbox | \`unity-ui-checkbox\` |
3806
+ | Chip | \`unity-ui-chip\` |
3807
+ | CodeBlock | \`unity-ui-code-block\` |
3808
+ | ConfirmationCard | \`unity-ui-confirmation-card\` |
3809
+ | ContentBlock | \`unity-ui-content-block\` |
3810
+ | DatePicker | \`unity-ui-date-picker\` |
3811
+ | Dialog | \`unity-ui-dialog\` |
3812
+ | Divider | \`unity-ui-divider\` |
3813
+ | Expandable | \`unity-ui-expandable\` |
3814
+ | Flag Icons | \`unity-ui-flag-icons\` |
3815
+ | FormLabel | \`unity-ui-form-label\` |
3816
+ | Grid | \`unity-ui-grid\` |
3817
+ | Icon | \`unity-ui-icon\` |
3818
+ | InfoBox | \`unity-ui-info-box\` |
3819
+ | ListMenu | \`unity-ui-list-menu\` |
3820
+ | MidSectionMenus | \`unity-ui-mid-section-menus\` |
3821
+ | Pagination | \`unity-ui-pagination\` |
3822
+ | PopUpMenu | \`unity-ui-pop-up-menu\` |
3823
+ | ProgressIndicator | \`unity-ui-progress-indicator\` |
3824
+ | Radio / RadioGroup | \`unity-ui-radio\` |
3825
+ | Segment / SegmentGroup | \`unity-ui-segment\` |
3826
+ | Select | \`unity-ui-select\` |
3827
+ | Sheet | \`unity-ui-sheet\` |
3828
+ | SideNavigation | \`unity-ui-side-navigation\` |
3829
+ | Skeleton | \`unity-ui-skeleton\` |
3830
+ | Snackbar | \`unity-ui-snackbar\` |
3831
+ | Stack | \`unity-ui-stack\` |
3832
+ | Switch | \`unity-ui-switch\` |
3833
+ | Table | \`unity-ui-table\` |
3834
+ | Tabs | \`unity-ui-tabs\` |
3835
+ | Tag | \`unity-ui-tag\` |
3836
+ | TextField | \`unity-ui-text-field\` |
3837
+ | Textarea | \`unity-ui-textarea\` |
3838
+ | Tooltip | \`unity-ui-tooltip\` |
3839
+ | TopBar | \`unity-ui-top-bar\` |
3840
+ | Typography | \`unity-ui-typography\` |
3841
+ | Uploader | \`unity-ui-uploader\` |
3842
+ | useBreakpoint | \`unity-ui-use-breakpoint\` |
3843
+ | useClickOutside | \`unity-ui-use-click-outside\` |
3844
+
3845
+ > If unsure which component to use, load \`unity-ui-index\` for the full equivalence table (shadcn/ui \u2192 Unity UI).
3846
+ `;
3847
+ }
3848
+ async function runRules({ output: outputDir } = {}) {
3849
+ const config = await loadConfig();
3850
+ const resolvedDir = path4.resolve(
3851
+ process.cwd(),
3852
+ outputDir || config.ai.rules.output
3853
+ );
3854
+ const filename = config.ai.rules.filename || "UNITYUI.md";
3855
+ const rulesContent = generateRulesContent();
3856
+ fs4.mkdirSync(resolvedDir, { recursive: true });
3857
+ const rulesPath = path4.join(resolvedDir, filename);
3858
+ fs4.writeFileSync(rulesPath, rulesContent, "utf8");
3859
+ const relativePath = path4.relative(process.cwd(), rulesPath);
3860
+ console.log(`
3861
+ \u2705 Generated ${relativePath}
3862
+ `);
3863
+ console.log(` Add a reference to your AI rules file:
3864
+ `);
3865
+ console.log(` \x1B[36mCLAUDE.md / .cursorrules / .windsurfrules:\x1B[0m`);
3866
+ console.log(` See @${relativePath} for Unity UI design system rules.
3867
+ `);
3868
+ console.log(` \x1B[36m.github/copilot-instructions.md:\x1B[0m`);
3869
+ console.log(
3870
+ ` This project uses Unity UI. See ${relativePath} for conventions.
3871
+ `
3872
+ );
3873
+ }
3874
+
3875
+ // bin/commands/skills.mjs
3876
+ import fs5 from "fs";
3877
+ import path5 from "path";
3794
3878
  import { fileURLToPath as fileURLToPath2 } from "url";
3795
3879
  var __filename2 = fileURLToPath2(import.meta.url);
3796
- var __dirname2 = path4.dirname(__filename2);
3797
- var packageRoot = path4.resolve(__dirname2, "..", "..");
3880
+ var __dirname2 = path5.dirname(__filename2);
3881
+ var packageRoot = path5.resolve(__dirname2, "..", "..");
3798
3882
  function findLlmsTxt() {
3799
- const fromDist = path4.resolve(packageRoot, "dist", "llms.txt");
3800
- if (fs4.existsSync(fromDist)) return fromDist;
3801
- const fromRoot = path4.resolve(packageRoot, "llms.txt");
3802
- if (fs4.existsSync(fromRoot)) return fromRoot;
3883
+ const fromDist = path5.resolve(packageRoot, "dist", "llms.txt");
3884
+ if (fs5.existsSync(fromDist)) return fromDist;
3885
+ const fromRoot = path5.resolve(packageRoot, "llms.txt");
3886
+ if (fs5.existsSync(fromRoot)) return fromRoot;
3803
3887
  return null;
3804
3888
  }
3805
3889
  var NAME_MAP = {
@@ -5408,9 +5492,9 @@ If the project contains components from shadcn/ui, MUI, Ant Design, Lovable, Fig
5408
5492
  `;
5409
5493
  }
5410
5494
  function writeSkill(outputDir, slug, content) {
5411
- const skillDir = path4.join(outputDir, slug);
5412
- fs4.mkdirSync(skillDir, { recursive: true });
5413
- fs4.writeFileSync(path4.join(skillDir, "SKILL.md"), content, "utf8");
5495
+ const skillDir = path5.join(outputDir, slug);
5496
+ fs5.mkdirSync(skillDir, { recursive: true });
5497
+ fs5.writeFileSync(path5.join(skillDir, "SKILL.md"), content, "utf8");
5414
5498
  }
5415
5499
  async function runSkills({ output: outputBase } = {}) {
5416
5500
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
@@ -5424,13 +5508,13 @@ async function runSkills({ output: outputBase } = {}) {
5424
5508
  process.exit(1);
5425
5509
  }
5426
5510
  const projectRoot = process.cwd();
5427
- const outputDir = path4.resolve(projectRoot, resolvedOutput, "skills");
5428
- const content = fs4.readFileSync(llmsPath, "utf8");
5511
+ const outputDir = path5.resolve(projectRoot, resolvedOutput, "skills");
5512
+ const content = fs5.readFileSync(llmsPath, "utf8");
5429
5513
  const parsed = parseLlmsTxt(content);
5430
- if (fs4.existsSync(outputDir)) {
5431
- for (const entry of fs4.readdirSync(outputDir)) {
5514
+ if (fs5.existsSync(outputDir)) {
5515
+ for (const entry of fs5.readdirSync(outputDir)) {
5432
5516
  if (entry.startsWith("unity-ui-")) {
5433
- fs4.rmSync(path4.join(outputDir, entry), { recursive: true });
5517
+ fs5.rmSync(path5.join(outputDir, entry), { recursive: true });
5434
5518
  }
5435
5519
  }
5436
5520
  }
@@ -5473,7 +5557,7 @@ async function runSkills({ output: outputBase } = {}) {
5473
5557
  generateFigmaCodeConnectSkill()
5474
5558
  );
5475
5559
  count += 12;
5476
- const relOutput = path4.relative(projectRoot, outputDir);
5560
+ const relOutput = path5.relative(projectRoot, outputDir);
5477
5561
  console.log(`
5478
5562
  Unity UI \u2014 Agent Skills Generator
5479
5563
  `);
@@ -5512,96 +5596,6 @@ async function runSkills({ output: outputBase } = {}) {
5512
5596
  `);
5513
5597
  }
5514
5598
 
5515
- // bin/commands/rules.mjs
5516
- import fs5 from "fs";
5517
- import path5 from "path";
5518
- function generateRulesContent(llmsContent) {
5519
- return `# Unity UI \u2014 AI Rules
5520
-
5521
- > Auto-generated by \`npx unity-ui rules\`. Do not edit manually.
5522
- > Source: @zvoove/unity-ui llms.txt
5523
-
5524
- ## General Rules
5525
-
5526
- - Always import components from \`@zvoove/unity-ui\`
5527
- - Never recreate components that exist in this library
5528
- - Use responsive props where applicable (single value or breakpoint object)
5529
- - Use design tokens from theme.css \u2014 never hardcode colors, spacing, or shadows
5530
- - Use \`tv()\` from tailwind-variants for component styling \u2014 never inline conditional classes
5531
- - Dark mode uses \`data-theme="dark"\` attribute, not \`className="dark"\`
5532
- - Default/placeholder texts should be in German
5533
- - Font (Source Sans 3) is bundled via \`@font-face\` in theme.css \u2014 no extra setup needed
5534
- - Never pass \`className\` or \`style\` to Unity UI components \u2014 use their props only; put token-based Tailwind on native HTML wrappers (\`div\`, \`section\`, etc.) when you need extra layout or chrome
5535
-
5536
- ## Setup
5537
-
5538
- \`\`\`bash
5539
- npm install @zvoove/unity-ui
5540
- \`\`\`
5541
-
5542
- \`\`\`css
5543
- @import '@zvoove/unity-ui/theme.css';
5544
- @import '@zvoove/unity-ui/unity-ui.css';
5545
- \`\`\`
5546
-
5547
- ## Responsive Props
5548
-
5549
- Breakpoints: minimum (0px), mobile (320px), tablet (768px), laptop (1024px), desktop (1440px).
5550
-
5551
- \`\`\`tsx
5552
- <Button size="md" />
5553
- <Button size={{ mobile: 'sm', tablet: 'md', desktop: 'lg' }} />
5554
- \`\`\`
5555
-
5556
- ## Component Reference
5557
-
5558
- ${llmsContent}
5559
- `;
5560
- }
5561
- async function runRules({ output: outputDir } = {}) {
5562
- const config = await loadConfig();
5563
- const resolvedDir = path5.resolve(
5564
- process.cwd(),
5565
- outputDir || config.ai.rules.output
5566
- );
5567
- const targets = config.ai.rules.targets;
5568
- const llmsPath = findLlmsTxt();
5569
- if (!llmsPath) {
5570
- console.error(
5571
- "Could not find llms.txt. Make sure @zvoove/unity-ui is installed and built."
5572
- );
5573
- process.exit(1);
5574
- }
5575
- const llmsContent = fs5.readFileSync(llmsPath, "utf8");
5576
- const rulesContent = generateRulesContent(llmsContent);
5577
- fs5.mkdirSync(resolvedDir, { recursive: true });
5578
- if (targets.includes("cursorrules")) {
5579
- const cursorRulesPath = path5.join(resolvedDir, ".cursorrules");
5580
- fs5.writeFileSync(cursorRulesPath, rulesContent, "utf8");
5581
- console.log(
5582
- `\u2705 Generated ${path5.relative(process.cwd(), cursorRulesPath)}`
5583
- );
5584
- }
5585
- if (targets.includes("claude")) {
5586
- const claudeMdPath = path5.join(resolvedDir, "CLAUDE.md");
5587
- fs5.writeFileSync(claudeMdPath, rulesContent, "utf8");
5588
- console.log(`\u2705 Generated ${path5.relative(process.cwd(), claudeMdPath)}`);
5589
- }
5590
- if (targets.length > 0) {
5591
- console.log(
5592
- `
5593
- Your AI assistant now knows how to use Unity UI components.
5594
- `
5595
- );
5596
- } else {
5597
- console.log(
5598
- `
5599
- No rule targets configured. Set targets in unity-ui.config.mjs.
5600
- `
5601
- );
5602
- }
5603
- }
5604
-
5605
5599
  // node_modules/.pnpm/commander@14.0.3/node_modules/commander/esm.mjs
5606
5600
  var import_index = __toESM(require_commander(), 1);
5607
5601
  var {
@@ -5625,5 +5619,5 @@ program2.name("unity-ui").description("Unity UI Design System CLI").version("1.0
5625
5619
  program2.command("init").description("Initialize unity-ui.config.mjs with project settings").action(() => runInit());
5626
5620
  program2.command("skills").description("Generate Agent Skills files from llms.txt").option("-o, --output <dir>", "Base directory for skills output").action((opts) => runSkills(opts));
5627
5621
  program2.command("create").description("Scaffold a new component").argument("<name>", "Component name (PascalCase)").action((name) => runCreate(name));
5628
- program2.command("rules").description("Generate AI rules files (.cursorrules + CLAUDE.md)").option("-o, --output <dir>", "Output directory").action((opts) => runRules(opts));
5622
+ program2.command("rules").description("Generate AI rules file (UNITYUI.md)").option("-o, --output <dir>", "Output directory").action((opts) => runRules(opts));
5629
5623
  program2.parse();
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- #!/usr/bin/env node
2
+ import{createRequire}from"module";const require=createRequire(import.meta.url);
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __esm = (fn, res) => function __init() {
@@ -62,7 +62,7 @@ var init_config = __esm({
62
62
  },
63
63
  rules: {
64
64
  output: ".",
65
- targets: ["cursorrules", "claude"]
65
+ filename: "UNITYUI.md"
66
66
  }
67
67
  }
68
68
  };