@zvoove/unity-ui 2.28.0 → 2.29.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/dist/bin/cli.mjs CHANGED
@@ -3649,9 +3649,9 @@ async function runCreate(componentName) {
3649
3649
 
3650
3650
  // bin/commands/init.mjs
3651
3651
  init_config();
3652
- import fs3 from "fs";
3653
- import path3 from "path";
3654
- import readline from "readline";
3652
+ import fs3 from "node:fs";
3653
+ import path3 from "node:path";
3654
+ import readline from "node:readline";
3655
3655
  function createRL() {
3656
3656
  return readline.createInterface({
3657
3657
  input: process.stdin,
@@ -3668,6 +3668,16 @@ function ask(rl, question, defaultValue) {
3668
3668
  );
3669
3669
  });
3670
3670
  }
3671
+ function serializeOutput(value) {
3672
+ if (Array.isArray(value)) {
3673
+ return "[" + value.map((v) => "'" + v + "'").join(", ") + "]";
3674
+ }
3675
+ return "'" + value + "'";
3676
+ }
3677
+ function parseOutputAnswer(answer) {
3678
+ const parts = answer.split(",").map((s) => s.trim()).filter(Boolean);
3679
+ return parts.length > 1 ? parts : parts[0];
3680
+ }
3671
3681
  function generateConfigContent(config) {
3672
3682
  return `// unity-ui.config.mjs \u2014 generated by \`npx unity-ui init\`
3673
3683
  import { defineConfig } from '@zvoove/unity-ui/config';
@@ -3679,7 +3689,7 @@ export default defineConfig({
3679
3689
  },
3680
3690
  ai: {
3681
3691
  skills: {
3682
- output: '${config.ai.skills.output}',
3692
+ output: ${serializeOutput(config.ai.skills.output)},
3683
3693
  },
3684
3694
  rules: {
3685
3695
  output: '${config.ai.rules.output}',
@@ -3710,11 +3720,12 @@ async function runInit() {
3710
3720
  "Where is your main index/barrel file?",
3711
3721
  DEFAULTS.components.indexFile
3712
3722
  );
3713
- const skillsOutput = await ask(
3723
+ const skillsOutputRaw = await ask(
3714
3724
  rl,
3715
- "Where should Agent Skills be generated?",
3725
+ "Where should Agent Skills be generated? (comma-separate for multiple)",
3716
3726
  DEFAULTS.ai.skills.output
3717
3727
  );
3728
+ const skillsOutput = parseOutputAnswer(skillsOutputRaw);
3718
3729
  const rulesOutput = await ask(
3719
3730
  rl,
3720
3731
  "Where should rules files be generated?",
@@ -3738,7 +3749,8 @@ async function runInit() {
3738
3749
  `);
3739
3750
  console.log(` Components: ${config.components.directory}/`);
3740
3751
  console.log(` Index file: ${config.components.indexFile}`);
3741
- console.log(` Skills dir: ${config.ai.skills.output}/skills/`);
3752
+ const skillsDirs = Array.isArray(config.ai.skills.output) ? config.ai.skills.output.map((o) => o + "/skills/").join(", ") : config.ai.skills.output + "/skills/";
3753
+ console.log(` Skills dir: ${skillsDirs}`);
3742
3754
  console.log(` Rules: ${config.ai.rules.output}/UNITYUI.md`);
3743
3755
  console.log("");
3744
3756
  }
@@ -3816,6 +3828,7 @@ Load the matching skill for full props, examples, and rules:
3816
3828
  | Grid | \`unity-ui-grid\` |
3817
3829
  | Icon | \`unity-ui-icon\` |
3818
3830
  | InfoBox | \`unity-ui-info-box\` |
3831
+ | List | \`unity-ui-list\` |
3819
3832
  | ListMenu | \`unity-ui-list-menu\` |
3820
3833
  | MidSectionMenus | \`unity-ui-mid-section-menus\` |
3821
3834
  | Pagination | \`unity-ui-pagination\` |
@@ -3956,6 +3969,7 @@ var SHADCN_MAP = {
3956
3969
  name: "Alert",
3957
3970
  url: "https://ui.shadcn.com/docs/components/alert"
3958
3971
  },
3972
+ List: null,
3959
3973
  MessageActions: null,
3960
3974
  Pagination: {
3961
3975
  name: "Pagination",
@@ -4062,6 +4076,7 @@ var MUI_MAP = {
4062
4076
  Grid: { name: "Grid", url: `${MUI_BASE}grid/` },
4063
4077
  Icon: { name: "SvgIcon", url: `${MUI_BASE}icons/` },
4064
4078
  InfoBox: { name: "Alert", url: `${MUI_BASE}alert/` },
4079
+ List: null,
4065
4080
  MessageActions: null,
4066
4081
  Pagination: { name: "Pagination", url: `${MUI_BASE}pagination/` },
4067
4082
  PopUpMenu: { name: "Menu", url: `${MUI_BASE}menu/` },
@@ -4142,6 +4157,7 @@ var STORYBOOK_MAP = {
4142
4157
  Grid: "Layout/Grid",
4143
4158
  Icon: "Components/Icon",
4144
4159
  InfoBox: "Components/InfoBox",
4160
+ List: "Components/List",
4145
4161
  MessageActions: "Chat/MessageActions",
4146
4162
  Pagination: "Components/Pagination",
4147
4163
  PopUpMenu: "Components/PopUpMenu",
@@ -4198,6 +4214,7 @@ var CATEGORIES = {
4198
4214
  Avatar: "data-display",
4199
4215
  Badge: "data-display",
4200
4216
  Icon: "data-display",
4217
+ List: "data-display",
4201
4218
  Skeleton: "data-display",
4202
4219
  ProgressIndicator: "data-display",
4203
4220
  CodeBlock: "data-display",
@@ -5496,21 +5513,7 @@ function writeSkill(outputDir, slug, content) {
5496
5513
  fs5.mkdirSync(skillDir, { recursive: true });
5497
5514
  fs5.writeFileSync(path5.join(skillDir, "SKILL.md"), content, "utf8");
5498
5515
  }
5499
- async function runSkills({ output: outputBase } = {}) {
5500
- const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
5501
- const config = await loadConfig2();
5502
- const resolvedOutput = outputBase || config.ai.skills.output;
5503
- const llmsPath = findLlmsTxt();
5504
- if (!llmsPath) {
5505
- console.error(
5506
- "Could not find llms.txt. Make sure @zvoove/unity-ui is installed and built."
5507
- );
5508
- process.exit(1);
5509
- }
5510
- const projectRoot = process.cwd();
5511
- const outputDir = path5.resolve(projectRoot, resolvedOutput, "skills");
5512
- const content = fs5.readFileSync(llmsPath, "utf8");
5513
- const parsed = parseLlmsTxt(content);
5516
+ function writeAllSkills(outputDir, parsed, componentNames) {
5514
5517
  if (fs5.existsSync(outputDir)) {
5515
5518
  for (const entry of fs5.readdirSync(outputDir)) {
5516
5519
  if (entry.startsWith("unity-ui-")) {
@@ -5518,15 +5521,12 @@ async function runSkills({ output: outputBase } = {}) {
5518
5521
  }
5519
5522
  }
5520
5523
  }
5521
- const componentNames = Object.keys(parsed.components).sort();
5522
- let count = 0;
5523
5524
  for (const [name, componentContent] of Object.entries(parsed.components)) {
5524
5525
  writeSkill(
5525
5526
  outputDir,
5526
5527
  `unity-ui-${kebabCase(name)}`,
5527
5528
  generateComponentSkill(name, componentContent)
5528
5529
  );
5529
- count++;
5530
5530
  }
5531
5531
  writeSkill(outputDir, "unity-ui", generateUmbrellaSkill(componentNames));
5532
5532
  writeSkill(outputDir, "unity-ui-setup", generateSetupSkill(parsed));
@@ -5556,12 +5556,37 @@ async function runSkills({ output: outputBase } = {}) {
5556
5556
  "unity-ui-figma-code-connect",
5557
5557
  generateFigmaCodeConnectSkill()
5558
5558
  );
5559
- count += 12;
5560
- const relOutput = path5.relative(projectRoot, outputDir);
5559
+ }
5560
+ async function runSkills({ output: outputBase } = {}) {
5561
+ const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
5562
+ const config = await loadConfig2();
5563
+ const rawOutput = outputBase || config.ai.skills.output;
5564
+ const outputBases = Array.isArray(rawOutput) ? rawOutput : [rawOutput];
5565
+ const llmsPath = findLlmsTxt();
5566
+ if (!llmsPath) {
5567
+ console.error(
5568
+ "Could not find llms.txt. Make sure @zvoove/unity-ui is installed and built."
5569
+ );
5570
+ process.exit(1);
5571
+ }
5572
+ const projectRoot = process.cwd();
5573
+ const content = fs5.readFileSync(llmsPath, "utf8");
5574
+ const parsed = parseLlmsTxt(content);
5575
+ const componentNames = Object.keys(parsed.components).sort(
5576
+ (a, b) => a.localeCompare(b)
5577
+ );
5578
+ for (const base of outputBases) {
5579
+ const outputDir = path5.resolve(projectRoot, base, "skills");
5580
+ writeAllSkills(outputDir, parsed, componentNames);
5581
+ }
5582
+ const count = componentNames.length + 12;
5583
+ const relOutputs = outputBases.map(
5584
+ (b) => path5.relative(projectRoot, path5.resolve(projectRoot, b, "skills"))
5585
+ );
5561
5586
  console.log(`
5562
5587
  Unity UI \u2014 Agent Skills Generator
5563
5588
  `);
5564
- console.log(` \u2705 Generated ${count} skills in ${relOutput}/
5589
+ console.log(` \u2705 Generated ${count} skills \u2192 ${relOutputs.join(", ")}/
5565
5590
  `);
5566
5591
  console.log(` ${componentNames.length} component skills`);
5567
5592
  console.log(` 1 umbrella routing skill (entry point + migration rules)`);
@@ -153,6 +153,7 @@ var SHADCN_MAP = {
153
153
  name: "Alert",
154
154
  url: "https://ui.shadcn.com/docs/components/alert"
155
155
  },
156
+ List: null,
156
157
  MessageActions: null,
157
158
  Pagination: {
158
159
  name: "Pagination",
@@ -259,6 +260,7 @@ var MUI_MAP = {
259
260
  Grid: { name: "Grid", url: `${MUI_BASE}grid/` },
260
261
  Icon: { name: "SvgIcon", url: `${MUI_BASE}icons/` },
261
262
  InfoBox: { name: "Alert", url: `${MUI_BASE}alert/` },
263
+ List: null,
262
264
  MessageActions: null,
263
265
  Pagination: { name: "Pagination", url: `${MUI_BASE}pagination/` },
264
266
  PopUpMenu: { name: "Menu", url: `${MUI_BASE}menu/` },
@@ -339,6 +341,7 @@ var STORYBOOK_MAP = {
339
341
  Grid: "Layout/Grid",
340
342
  Icon: "Components/Icon",
341
343
  InfoBox: "Components/InfoBox",
344
+ List: "Components/List",
342
345
  MessageActions: "Chat/MessageActions",
343
346
  Pagination: "Components/Pagination",
344
347
  PopUpMenu: "Components/PopUpMenu",
@@ -395,6 +398,7 @@ var CATEGORIES = {
395
398
  Avatar: "data-display",
396
399
  Badge: "data-display",
397
400
  Icon: "data-display",
401
+ List: "data-display",
398
402
  Skeleton: "data-display",
399
403
  ProgressIndicator: "data-display",
400
404
  CodeBlock: "data-display",
@@ -1693,21 +1697,7 @@ function writeSkill(outputDir, slug, content) {
1693
1697
  fs2.mkdirSync(skillDir, { recursive: true });
1694
1698
  fs2.writeFileSync(path2.join(skillDir, "SKILL.md"), content, "utf8");
1695
1699
  }
1696
- async function runSkills({ output: outputBase } = {}) {
1697
- const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
1698
- const config = await loadConfig2();
1699
- const resolvedOutput = outputBase || config.ai.skills.output;
1700
- const llmsPath = findLlmsTxt();
1701
- if (!llmsPath) {
1702
- console.error(
1703
- "Could not find llms.txt. Make sure @zvoove/unity-ui is installed and built."
1704
- );
1705
- process.exit(1);
1706
- }
1707
- const projectRoot = process.cwd();
1708
- const outputDir = path2.resolve(projectRoot, resolvedOutput, "skills");
1709
- const content = fs2.readFileSync(llmsPath, "utf8");
1710
- const parsed = parseLlmsTxt(content);
1700
+ function writeAllSkills(outputDir, parsed, componentNames) {
1711
1701
  if (fs2.existsSync(outputDir)) {
1712
1702
  for (const entry of fs2.readdirSync(outputDir)) {
1713
1703
  if (entry.startsWith("unity-ui-")) {
@@ -1715,15 +1705,12 @@ async function runSkills({ output: outputBase } = {}) {
1715
1705
  }
1716
1706
  }
1717
1707
  }
1718
- const componentNames = Object.keys(parsed.components).sort();
1719
- let count = 0;
1720
1708
  for (const [name, componentContent] of Object.entries(parsed.components)) {
1721
1709
  writeSkill(
1722
1710
  outputDir,
1723
1711
  `unity-ui-${kebabCase(name)}`,
1724
1712
  generateComponentSkill(name, componentContent)
1725
1713
  );
1726
- count++;
1727
1714
  }
1728
1715
  writeSkill(outputDir, "unity-ui", generateUmbrellaSkill(componentNames));
1729
1716
  writeSkill(outputDir, "unity-ui-setup", generateSetupSkill(parsed));
@@ -1753,12 +1740,37 @@ async function runSkills({ output: outputBase } = {}) {
1753
1740
  "unity-ui-figma-code-connect",
1754
1741
  generateFigmaCodeConnectSkill()
1755
1742
  );
1756
- count += 12;
1757
- const relOutput = path2.relative(projectRoot, outputDir);
1743
+ }
1744
+ async function runSkills({ output: outputBase } = {}) {
1745
+ const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
1746
+ const config = await loadConfig2();
1747
+ const rawOutput = outputBase || config.ai.skills.output;
1748
+ const outputBases = Array.isArray(rawOutput) ? rawOutput : [rawOutput];
1749
+ const llmsPath = findLlmsTxt();
1750
+ if (!llmsPath) {
1751
+ console.error(
1752
+ "Could not find llms.txt. Make sure @zvoove/unity-ui is installed and built."
1753
+ );
1754
+ process.exit(1);
1755
+ }
1756
+ const projectRoot = process.cwd();
1757
+ const content = fs2.readFileSync(llmsPath, "utf8");
1758
+ const parsed = parseLlmsTxt(content);
1759
+ const componentNames = Object.keys(parsed.components).sort(
1760
+ (a, b) => a.localeCompare(b)
1761
+ );
1762
+ for (const base of outputBases) {
1763
+ const outputDir = path2.resolve(projectRoot, base, "skills");
1764
+ writeAllSkills(outputDir, parsed, componentNames);
1765
+ }
1766
+ const count = componentNames.length + 12;
1767
+ const relOutputs = outputBases.map(
1768
+ (b) => path2.relative(projectRoot, path2.resolve(projectRoot, b, "skills"))
1769
+ );
1758
1770
  console.log(`
1759
1771
  Unity UI \u2014 Agent Skills Generator
1760
1772
  `);
1761
- console.log(` \u2705 Generated ${count} skills in ${relOutput}/
1773
+ console.log(` \u2705 Generated ${count} skills \u2192 ${relOutputs.join(", ")}/
1762
1774
  `);
1763
1775
  console.log(` ${componentNames.length} component skills`);
1764
1776
  console.log(` 1 umbrella routing skill (entry point + migration rules)`);
package/dist/llms.txt CHANGED
@@ -759,6 +759,68 @@ import { CodeBlock } from '@zvoove/unity-ui';
759
759
  />
760
760
  ```
761
761
 
762
+ ### List
763
+ Simple list that renders an array of items with optional dividers and hover highlights. Each item accepts arbitrary `ReactNode` content and extra props are forwarded to the rendered element.
764
+ ```tsx
765
+ import { List } from '@zvoove/unity-ui';
766
+
767
+ <List
768
+ items={[ // ListItem<T>[] (required) — each item: { id: string, content: ReactNode, ...elementProps }
769
+ { id: 'item-1', content: 'Item 1' },
770
+ { id: 'item-2', content: 'Item 2' },
771
+ ]}
772
+ showDividers={true} // boolean (default: true) — show dividers between items
773
+ linkComponent="div" // T | 'div' (default: 'div') — set to 'a' for native links or pass a custom router Link
774
+ />
775
+ ```
776
+
777
+ Common patterns:
778
+ ```tsx
779
+ // Rich content items
780
+ <List
781
+ items={[
782
+ {
783
+ id: 'inbox',
784
+ content: (
785
+ <Stack direction="row" gap="sm" align="center">
786
+ <Icon name="remark" size="xs" />
787
+ <Typography variant="body" size="medium">Inbox</Typography>
788
+ <div className="ml-auto"><Tag label="3" color="error" size="small" /></div>
789
+ </Stack>
790
+ ),
791
+ },
792
+ ]}
793
+ />
794
+
795
+ // Native anchor links — extra item props forwarded to <a>
796
+ <List
797
+ linkComponent="a"
798
+ items={[
799
+ { id: 'google', content: 'Google', href: 'https://google.com', target: '_blank', rel: 'noopener noreferrer' },
800
+ ]}
801
+ />
802
+
803
+ // Custom router link (e.g. React Router)
804
+ import { Link } from 'react-router-dom';
805
+ <List
806
+ linkComponent={Link}
807
+ items={[
808
+ { id: 'home', content: 'Home', to: '/' },
809
+ { id: 'settings', content: 'Settings', to: '/settings' },
810
+ ]}
811
+ />
812
+
813
+ // Inside a Card with header
814
+ <Card padding="none" width={320} variant="outlined">
815
+ <Stack padding="md" direction="row" gap="sm" align="center">
816
+ <Icon name="users" size="md" weight="light" />
817
+ <Typography variant="label" size="large">Team members</Typography>
818
+ </Stack>
819
+ <Divider />
820
+ <List items={[{ id: 'anna', content: 'Anna Mueller' }]} />
821
+ </Card>
822
+ ```
823
+
762
824
  ---
763
825
 
764
826
  ## NAVIGATION COMPONENTS