velloo 0.0.0 → 0.2.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/BUN-LICENSE.md +91 -0
- package/LICENSE +202 -0
- package/NOTICE +9 -0
- package/README.md +288 -2
- package/THIRD-PARTY-NOTICES.md +467 -0
- package/assets/elsewhere-alps-9fqhv029.jpg +0 -0
- package/assets/elsewhere-bali-vp60g115.jpg +0 -0
- package/assets/elsewhere-forest-xgn23zrj.jpg +0 -0
- package/assets/elsewhere-japan-qs7qkbr2.jpg +0 -0
- package/assets/elsewhere-kyoto-map-n2bvkrya.svg +1 -0
- package/assets/elsewhere-kyoto-qemtn6nk.jpg +0 -0
- package/assets/elsewhere-room-g1gaw7cs.jpg +0 -0
- package/canvas/apple-touch-icon.png +0 -0
- package/canvas/assets/index-BCvDZiBo.css +2 -0
- package/canvas/assets/index-ClaBqcaS.js +28 -0
- package/canvas/assets/lucide-all-iIF-pmzN.js +1 -0
- package/canvas/assets/radix-C3HaOB-d.js +41 -0
- package/canvas/assets/react-D0Ec-185.js +9 -0
- package/canvas/assets/rolldown-runtime-hePW80VL.js +1 -0
- package/canvas/assets/vendor-CKmQ-Zst.js +53 -0
- package/canvas/favicon.ico +0 -0
- package/canvas/favicon.svg +12 -0
- package/canvas/fonts/OFL-1.1.txt +93 -0
- package/canvas/fonts/poppins-700.woff2 +0 -0
- package/canvas/icon-192.png +0 -0
- package/canvas/icon-512.png +0 -0
- package/canvas/index.html +22 -0
- package/canvas/site.webmanifest +11 -0
- package/chunk-08sv3k41.js +4 -0
- package/chunk-0fe83yzt.js +2 -0
- package/chunk-0t68szgr.js +3 -0
- package/chunk-1h55s5he.js +2 -0
- package/chunk-2c7jbx46.js +2 -0
- package/chunk-2smsg2ct.js +7 -0
- package/chunk-308ynsxd.js +2 -0
- package/chunk-3e8vez4d.js +1229 -0
- package/chunk-40xgcth8.js +63 -0
- package/chunk-4dn75m6t.js +3 -0
- package/chunk-4fj5tahv.js +3 -0
- package/chunk-6nqghjda.js +3 -0
- package/chunk-6tx68d90.js +3 -0
- package/chunk-6w6ch4ce.js +2 -0
- package/chunk-735ezz23.js +86 -0
- package/chunk-7eq7nx37.js +7 -0
- package/chunk-7eyb8yrf.js +6 -0
- package/chunk-80fjfyha.js +86 -0
- package/chunk-80r93t2e.js +4 -0
- package/chunk-94vx1yb0.js +3 -0
- package/chunk-9vg3yafz.js +3 -0
- package/chunk-a84n72m2.js +4 -0
- package/chunk-ampmdzz4.js +10 -0
- package/chunk-avns4dbf.js +2 -0
- package/chunk-ayrb3qnm.js +3 -0
- package/chunk-bwnvcncx.js +3 -0
- package/chunk-ccszg02q.js +5 -0
- package/chunk-cvn689d5.js +3 -0
- package/chunk-cxe6jjwj.js +3 -0
- package/chunk-dg6z4vdd.js +3 -0
- package/chunk-dgwjpbp9.js +3 -0
- package/chunk-dy41n60j.js +52 -0
- package/chunk-ek71z2fv.js +226 -0
- package/chunk-er1fxb7d.js +2 -0
- package/chunk-eyr8hrzf.js +2 -0
- package/chunk-fjbzk4sw.js +3 -0
- package/chunk-fsbsksga.js +3 -0
- package/chunk-h6gchare.js +3 -0
- package/chunk-hcb68zt7.js +85 -0
- package/chunk-hggap8fq.js +3 -0
- package/chunk-j11fyeqh.js +2 -0
- package/chunk-jb21jkp1.js +8 -0
- package/chunk-jfx9xjmr.js +18 -0
- package/chunk-jr0ss0mm.js +303 -0
- package/chunk-jrsknzjt.js +3 -0
- package/chunk-jv0xggh0.js +2 -0
- package/chunk-k17gfwq3.js +2 -0
- package/chunk-mh2pr7cq.js +5 -0
- package/chunk-mnapdp1y.js +2 -0
- package/chunk-mzhdrawd.js +3 -0
- package/chunk-n9gs6yx9.js +2 -0
- package/chunk-ngnymg2q.js +3 -0
- package/chunk-nwx5700b.js +3 -0
- package/chunk-pjtg3wnm.js +4 -0
- package/chunk-pp86v6m6.js +3 -0
- package/chunk-r22epxz2.js +3 -0
- package/chunk-rgasy862.js +5 -0
- package/chunk-rpwpeph5.js +3 -0
- package/chunk-s23gtejf.js +3 -0
- package/chunk-sjgqnykd.js +6 -0
- package/chunk-sn3x2m0m.js +6 -0
- package/chunk-t448rrfr.js +2 -0
- package/chunk-tdsk5wxa.js +451 -0
- package/chunk-v40fn08f.js +442 -0
- package/chunk-vbk1qhdz.js +3 -0
- package/chunk-vdkrbzh1.js +2 -0
- package/chunk-vgmr98cv.js +40 -0
- package/chunk-vsv8z729.js +6 -0
- package/chunk-x4f4k9pp.js +26 -0
- package/chunk-xt5ayg7g.js +4 -0
- package/chunk-ydhwv29b.js +244 -0
- package/chunk-zb6hc1y0.js +2 -0
- package/cli.js +3 -0
- package/launcher.cjs +97 -0
- package/package.json +58 -5
- package/pkgs/helpers/src/box.tsx +21 -0
- package/pkgs/helpers/src/cn.ts +32 -0
- package/pkgs/helpers/src/descriptors.ts +270 -0
- package/pkgs/helpers/src/divider.tsx +123 -0
- package/pkgs/helpers/src/gradient.tsx +90 -0
- package/pkgs/helpers/src/heading.tsx +20 -0
- package/pkgs/helpers/src/icon-data.ts +8009 -0
- package/pkgs/helpers/src/icon.tsx +53 -0
- package/pkgs/helpers/src/image.tsx +111 -0
- package/pkgs/helpers/src/index.ts +29 -0
- package/pkgs/helpers/src/layer.tsx +61 -0
- package/pkgs/helpers/src/lowering.ts +53 -0
- package/pkgs/helpers/src/paths.ts +47 -0
- package/pkgs/helpers/src/placeholder.tsx +88 -0
- package/pkgs/helpers/src/prose.tsx +42 -0
- package/pkgs/helpers/src/registry.ts +41 -0
- package/pkgs/helpers/src/svg.tsx +62 -0
- package/pkgs/helpers/src/text.tsx +16 -0
- package/pkgs/provider-antd/src/index.ts +78 -0
- package/pkgs/provider-antd/src/intro.ts +14 -0
- package/pkgs/provider-antd/src/manifest.ts +439 -0
- package/pkgs/provider-antd/src/overlays.ts +176 -0
- package/pkgs/provider-antd/src/registry.ts +104 -0
- package/pkgs/provider-antd/src/render-pass.ts +43 -0
- package/pkgs/provider-antd/src/tailwind-entry.css +21 -0
- package/pkgs/provider-antd/src/theme.ts +132 -0
- package/pkgs/provider-antd/src/version.ts +8 -0
- package/pkgs/provider-chakra/src/index.ts +80 -0
- package/pkgs/provider-chakra/src/intro.ts +14 -0
- package/pkgs/provider-chakra/src/manifest.ts +421 -0
- package/pkgs/provider-chakra/src/overlays.ts +246 -0
- package/pkgs/provider-chakra/src/registry.ts +227 -0
- package/pkgs/provider-chakra/src/render-pass.ts +55 -0
- package/pkgs/provider-chakra/src/tailwind-entry.css +21 -0
- package/pkgs/provider-chakra/src/theme.ts +180 -0
- package/pkgs/provider-chakra/src/version.ts +8 -0
- package/pkgs/provider-mui/src/index.ts +117 -0
- package/pkgs/provider-mui/src/intro.ts +12 -0
- package/pkgs/provider-mui/src/manifest.ts +263 -0
- package/pkgs/provider-mui/src/overlays.ts +124 -0
- package/pkgs/provider-mui/src/registry.ts +120 -0
- package/pkgs/provider-mui/src/render-pass.ts +36 -0
- package/pkgs/provider-mui/src/tailwind-entry.css +21 -0
- package/pkgs/provider-mui/src/theme.ts +129 -0
- package/pkgs/provider-mui/src/version.ts +8 -0
- package/pkgs/provider-none/src/components-inline.tsx +204 -0
- package/pkgs/provider-none/src/components.tsx +155 -0
- package/pkgs/provider-none/src/index.ts +57 -0
- package/pkgs/provider-none/src/intro.ts +18 -0
- package/pkgs/provider-none/src/manifest.ts +163 -0
- package/pkgs/provider-none/src/registry-inline.ts +36 -0
- package/pkgs/provider-none/src/registry.ts +39 -0
- package/pkgs/provider-none/src/tailwind-entry.css +57 -0
- package/pkgs/provider-none/src/version.ts +10 -0
- package/pkgs/schema/src/annotation.ts +120 -0
- package/pkgs/schema/src/asset.ts +66 -0
- package/pkgs/schema/src/board.ts +71 -0
- package/pkgs/schema/src/comment.ts +107 -0
- package/pkgs/schema/src/config.ts +185 -0
- package/pkgs/schema/src/css-sanitize.ts +56 -0
- package/pkgs/schema/src/extension.ts +105 -0
- package/pkgs/schema/src/fonts.ts +690 -0
- package/pkgs/schema/src/frame.ts +40 -0
- package/pkgs/schema/src/icon-name.ts +21 -0
- package/pkgs/schema/src/ids.ts +14 -0
- package/pkgs/schema/src/index.ts +169 -0
- package/pkgs/schema/src/migrate.ts +297 -0
- package/pkgs/schema/src/node.ts +229 -0
- package/pkgs/schema/src/paths.ts +28 -0
- package/pkgs/schema/src/repo.ts +134 -0
- package/pkgs/schema/src/screen.ts +30 -0
- package/pkgs/schema/src/snippet-resolve.ts +193 -0
- package/pkgs/schema/src/snippet.ts +104 -0
- package/pkgs/schema/src/svg-sanitize.ts +487 -0
- package/pkgs/schema/src/theme.ts +218 -0
- package/pkgs/schema/src/typeset.ts +693 -0
- package/pkgs/schema/src/validate-ids.ts +46 -0
- package/pkgs/schema/src/viewport.ts +8 -0
- package/pkgs/shadcn-snapshot/dist/manifest.json +8109 -0
- package/pkgs/shadcn-snapshot/src/components/canvas-portal.tsx +55 -0
- package/pkgs/shadcn-snapshot/src/components/ui/accordion.tsx +122 -0
- package/pkgs/shadcn-snapshot/src/components/ui/alert-dialog.tsx +164 -0
- package/pkgs/shadcn-snapshot/src/components/ui/alert.tsx +74 -0
- package/pkgs/shadcn-snapshot/src/components/ui/aspect-ratio.tsx +13 -0
- package/pkgs/shadcn-snapshot/src/components/ui/attachment.tsx +197 -0
- package/pkgs/shadcn-snapshot/src/components/ui/avatar.tsx +100 -0
- package/pkgs/shadcn-snapshot/src/components/ui/badge.tsx +50 -0
- package/pkgs/shadcn-snapshot/src/components/ui/breadcrumb.tsx +109 -0
- package/pkgs/shadcn-snapshot/src/components/ui/bubble.tsx +130 -0
- package/pkgs/shadcn-snapshot/src/components/ui/button-group.tsx +82 -0
- package/pkgs/shadcn-snapshot/src/components/ui/button.tsx +72 -0
- package/pkgs/shadcn-snapshot/src/components/ui/calendar.tsx +229 -0
- package/pkgs/shadcn-snapshot/src/components/ui/card.tsx +92 -0
- package/pkgs/shadcn-snapshot/src/components/ui/carousel.tsx +235 -0
- package/pkgs/shadcn-snapshot/src/components/ui/chart-option.ts +250 -0
- package/pkgs/shadcn-snapshot/src/components/ui/chart.tsx +177 -0
- package/pkgs/shadcn-snapshot/src/components/ui/checkbox.tsx +41 -0
- package/pkgs/shadcn-snapshot/src/components/ui/collapsible.tsx +32 -0
- package/pkgs/shadcn-snapshot/src/components/ui/combobox.tsx +196 -0
- package/pkgs/shadcn-snapshot/src/components/ui/context-menu.tsx +227 -0
- package/pkgs/shadcn-snapshot/src/components/ui/dialog.tsx +131 -0
- package/pkgs/shadcn-snapshot/src/components/ui/direction.tsx +24 -0
- package/pkgs/shadcn-snapshot/src/components/ui/drawer.tsx +112 -0
- package/pkgs/shadcn-snapshot/src/components/ui/dropdown-menu.tsx +205 -0
- package/pkgs/shadcn-snapshot/src/components/ui/empty.tsx +98 -0
- package/pkgs/shadcn-snapshot/src/components/ui/field.tsx +228 -0
- package/pkgs/shadcn-snapshot/src/components/ui/hover-card.tsx +51 -0
- package/pkgs/shadcn-snapshot/src/components/ui/input-group.tsx +148 -0
- package/pkgs/shadcn-snapshot/src/components/ui/input.tsx +43 -0
- package/pkgs/shadcn-snapshot/src/components/ui/item.tsx +187 -0
- package/pkgs/shadcn-snapshot/src/components/ui/kbd.tsx +30 -0
- package/pkgs/shadcn-snapshot/src/components/ui/label.tsx +25 -0
- package/pkgs/shadcn-snapshot/src/components/ui/marker.tsx +71 -0
- package/pkgs/shadcn-snapshot/src/components/ui/menubar.tsx +243 -0
- package/pkgs/shadcn-snapshot/src/components/ui/message.tsx +89 -0
- package/pkgs/shadcn-snapshot/src/components/ui/native-select.tsx +60 -0
- package/pkgs/shadcn-snapshot/src/components/ui/navigation-menu.tsx +165 -0
- package/pkgs/shadcn-snapshot/src/components/ui/pagination.tsx +117 -0
- package/pkgs/shadcn-snapshot/src/components/ui/popover.tsx +66 -0
- package/pkgs/shadcn-snapshot/src/components/ui/progress.tsx +35 -0
- package/pkgs/shadcn-snapshot/src/components/ui/radio-group.tsx +48 -0
- package/pkgs/shadcn-snapshot/src/components/ui/scroll-area.tsx +59 -0
- package/pkgs/shadcn-snapshot/src/components/ui/select.tsx +180 -0
- package/pkgs/shadcn-snapshot/src/components/ui/separator.tsx +32 -0
- package/pkgs/shadcn-snapshot/src/components/ui/sheet.tsx +107 -0
- package/pkgs/shadcn-snapshot/src/components/ui/skeleton.tsx +17 -0
- package/pkgs/shadcn-snapshot/src/components/ui/slider.tsx +68 -0
- package/pkgs/shadcn-snapshot/src/components/ui/sonner.tsx +91 -0
- package/pkgs/shadcn-snapshot/src/components/ui/spinner.tsx +21 -0
- package/pkgs/shadcn-snapshot/src/components/ui/switch.tsx +41 -0
- package/pkgs/shadcn-snapshot/src/components/ui/table.tsx +93 -0
- package/pkgs/shadcn-snapshot/src/components/ui/tabs.tsx +84 -0
- package/pkgs/shadcn-snapshot/src/components/ui/textarea.tsx +24 -0
- package/pkgs/shadcn-snapshot/src/components/ui/toggle-group.tsx +94 -0
- package/pkgs/shadcn-snapshot/src/components/ui/toggle.tsx +50 -0
- package/pkgs/shadcn-snapshot/src/components/ui/tooltip.tsx +47 -0
- package/pkgs/shadcn-snapshot/src/examples.ts +36 -0
- package/pkgs/shadcn-snapshot/src/groups.ts +87 -0
- package/pkgs/shadcn-snapshot/src/index.ts +43 -0
- package/pkgs/shadcn-snapshot/src/lib/utils.ts +4 -0
- package/pkgs/shadcn-snapshot/src/manifest.ts +12 -0
- package/pkgs/shadcn-snapshot/src/notes.ts +97 -0
- package/pkgs/shadcn-snapshot/src/paths.ts +47 -0
- package/pkgs/shadcn-snapshot/src/registry-files.ts +293 -0
- package/pkgs/shadcn-snapshot/src/registry.ts +631 -0
- package/pkgs/shadcn-snapshot/src/shadcn-tailwind.css +632 -0
- package/pkgs/shadcn-snapshot/src/tailwind-entry.css +159 -0
- package/pkgs/shadcn-snapshot/src/version.ts +8 -0
- package/plugins/claude/velloo/.claude-plugin/plugin.json +6 -0
- package/plugins/claude/velloo/agents/velloo-design-reviewer.md +33 -0
- package/plugins/claude/velloo/agents/velloo-designer.md +39 -0
- package/plugins/claude/velloo/commands/design.md +11 -0
- package/plugins/claude/velloo/commands/implement.md +10 -0
- package/plugins/claude/velloo/commands/review.md +8 -0
- package/plugins/gemini/GEMINI.md +31 -0
- package/plugins/gemini/commands/velloo/design.toml +10 -0
- package/plugins/gemini/commands/velloo/implement.toml +9 -0
- package/plugins/gemini/gemini-extension.json +9 -0
- package/skills/velloo-brand/SKILL.md +124 -0
- package/skills/velloo-design/SKILL.md +144 -0
- package/skills/velloo-design-system/SKILL.md +90 -0
- package/skills/velloo-implement/SKILL.md +101 -0
- package/skills/velloo-logo/SKILL.md +93 -0
- package/skills/velloo-setup/SKILL.md +156 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{registry2,loadManifest2}from"./chunk-hcb68zt7.js";import"./chunk-jb21jkp1.js";import{snapshotVersion2,entryCssPath2,componentsDir2}from"./chunk-cvn689d5.js";export{componentsDir2 as componentsDir,entryCssPath2 as entryCssPath,loadManifest2 as loadManifest,registry2 as registry,snapshotVersion2 as snapshotVersion};
|
package/cli.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// @bun
|
|
3
|
+
import"./chunk-s23gtejf.js";import{COMMANDS}from"./chunk-4fj5tahv.js";import{TOOL_VERSION}from"./chunk-dg6z4vdd.js";import{maybeNotifyAboutUpdate}from"./chunk-xt5ayg7g.js";import{defineCommand,runMain}from"./chunk-2smsg2ct.js";var main=defineCommand({meta:{name:"velloo",version:TOOL_VERSION,description:"Open-source, local-first canvas for agent-driven design."},subCommands:COMMANDS});await runMain(main);var command=process.argv[2];if(!["mcp","__daemon","__update_check","run","upgrade"].includes(command??""))await maybeNotifyAboutUpdate();
|
package/launcher.cjs
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const { existsSync, readFileSync } = require("node:fs");
|
|
5
|
+
const { dirname, join } = require("node:path");
|
|
6
|
+
const { spawnSync } = require("node:child_process");
|
|
7
|
+
|
|
8
|
+
function linuxLibc() {
|
|
9
|
+
if (process.platform !== "linux") return undefined;
|
|
10
|
+
try {
|
|
11
|
+
const report = process.report?.getReport();
|
|
12
|
+
if (report?.header?.glibcVersionRuntime) return "glibc";
|
|
13
|
+
} catch {}
|
|
14
|
+
try {
|
|
15
|
+
if (/musl/i.test(readFileSync("/usr/bin/ldd", "utf8"))) return "musl";
|
|
16
|
+
} catch {}
|
|
17
|
+
return "musl";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function runtimePackage() {
|
|
21
|
+
const arch = process.arch === "x64" ? "x64" : process.arch === "arm64" ? "arm64" : null;
|
|
22
|
+
if (!arch) return null;
|
|
23
|
+
if (process.platform === "darwin") {
|
|
24
|
+
return arch === "arm64" ? "@oven/bun-darwin-aarch64" : "@oven/bun-darwin-x64-baseline";
|
|
25
|
+
}
|
|
26
|
+
if (process.platform === "win32") {
|
|
27
|
+
return arch === "arm64" ? "@oven/bun-windows-aarch64" : "@oven/bun-windows-x64-baseline";
|
|
28
|
+
}
|
|
29
|
+
if (process.platform === "linux") {
|
|
30
|
+
const musl = linuxLibc() === "musl";
|
|
31
|
+
if (arch === "arm64") {
|
|
32
|
+
return musl ? "@oven/bun-linux-aarch64-musl" : "@oven/bun-linux-aarch64";
|
|
33
|
+
}
|
|
34
|
+
return musl ? "@oven/bun-linux-x64-musl-baseline" : "@oven/bun-linux-x64-baseline";
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function die(message) {
|
|
40
|
+
process.stderr.write(`velloo: ${message}\n`);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Windows cannot reliably replace an executable while that executable is
|
|
45
|
+
// running. Handle the bare self-upgrade in the Node launcher before Bun starts;
|
|
46
|
+
// folder migrations and `--check` still go through the normal CLI command.
|
|
47
|
+
if (process.platform === "win32" && process.argv.length === 3 && process.argv[2] === "upgrade") {
|
|
48
|
+
const adjacentNpm = join(dirname(process.execPath), "npm.cmd");
|
|
49
|
+
const npm = existsSync(adjacentNpm) ? adjacentNpm : "npm.cmd";
|
|
50
|
+
const packageName = process.env.VELLOO_NPM_PACKAGE || "velloo";
|
|
51
|
+
const upgrade = spawnSync(npm, ["install", "-g", `${packageName}@latest`], { stdio: "inherit" });
|
|
52
|
+
if (upgrade.error) die(`could not start npm: ${upgrade.error.message}`);
|
|
53
|
+
if (upgrade.status !== 0) process.exit(upgrade.status == null ? 1 : upgrade.status);
|
|
54
|
+
// npm rewrote this launcher's package in place, so re-entering by the same
|
|
55
|
+
// path runs the NEW velloo — which is the one that must migrate the design
|
|
56
|
+
// folder, since only it knows the format it migrated towards.
|
|
57
|
+
const migrate = spawnSync(process.execPath, [__filename, "upgrade", "--design-only"], {
|
|
58
|
+
stdio: "inherit",
|
|
59
|
+
});
|
|
60
|
+
process.exit(migrate.status == null ? 1 : migrate.status);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const runtimeName = runtimePackage();
|
|
64
|
+
if (!runtimeName) {
|
|
65
|
+
die(
|
|
66
|
+
`unsupported platform ${process.platform}/${process.arch}; supported platforms are macOS, Linux, and Windows on x64 or arm64`,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let runtimeRoot;
|
|
71
|
+
try {
|
|
72
|
+
runtimeRoot = dirname(require.resolve(`${runtimeName}/package.json`));
|
|
73
|
+
} catch {
|
|
74
|
+
die(
|
|
75
|
+
`the Bun runtime package ${runtimeName} is missing. Reinstall with \`npm install -g velloo@latest\` and make sure optional dependencies are enabled`,
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const runtime = join(runtimeRoot, "bin", process.platform === "win32" ? "bun.exe" : "bun");
|
|
80
|
+
if (!existsSync(runtime)) die(`the Bun runtime package ${runtimeName} is incomplete`);
|
|
81
|
+
|
|
82
|
+
const app = join(__dirname, "cli.js");
|
|
83
|
+
const child = spawnSync(runtime, [app, ...process.argv.slice(2)], {
|
|
84
|
+
stdio: "inherit",
|
|
85
|
+
env: {
|
|
86
|
+
...process.env,
|
|
87
|
+
VELLOO_INSTALL_METHOD: process.env.VELLOO_INSTALL_METHOD || "npm",
|
|
88
|
+
VELLOO_NPM_PACKAGE: process.env.VELLOO_NPM_PACKAGE || "velloo",
|
|
89
|
+
VELLOO_NODE_EXECUTABLE: process.execPath,
|
|
90
|
+
// The install path is how a Homebrew-managed velloo is told apart from an
|
|
91
|
+
// npm one under a Homebrew-installed Node (both live under /opt/homebrew).
|
|
92
|
+
VELLOO_LAUNCHER_PATH: __filename,
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
if (child.error) die(`could not start the bundled Bun runtime: ${child.error.message}`);
|
|
97
|
+
process.exit(child.status == null ? 1 : child.status);
|
package/package.json
CHANGED
|
@@ -1,11 +1,64 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "velloo",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Local-first, code-shaped design canvas — your AI agent designs with your real components, in your repo",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"homepage": "https://velloo.design",
|
|
6
8
|
"repository": {
|
|
7
9
|
"type": "git",
|
|
8
|
-
"url": "git+https://github.com/velloo-
|
|
10
|
+
"url": "git+https://github.com/velloo-design/velloo.git"
|
|
9
11
|
},
|
|
10
|
-
"
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/velloo-design/velloo/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"design",
|
|
17
|
+
"design-tool",
|
|
18
|
+
"canvas",
|
|
19
|
+
"mcp",
|
|
20
|
+
"ai-agent",
|
|
21
|
+
"claude-code",
|
|
22
|
+
"shadcn",
|
|
23
|
+
"tailwind",
|
|
24
|
+
"mui",
|
|
25
|
+
"local-first",
|
|
26
|
+
"bun"
|
|
27
|
+
],
|
|
28
|
+
"bin": {
|
|
29
|
+
"velloo": "launcher.cjs"
|
|
30
|
+
},
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=18"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"cli.js",
|
|
36
|
+
"launcher.cjs",
|
|
37
|
+
"chunk-*.js",
|
|
38
|
+
"assets",
|
|
39
|
+
"canvas",
|
|
40
|
+
"skills",
|
|
41
|
+
"plugins",
|
|
42
|
+
"pkgs",
|
|
43
|
+
"NOTICE",
|
|
44
|
+
"THIRD-PARTY-NOTICES.md",
|
|
45
|
+
"BUN-LICENSE.md"
|
|
46
|
+
],
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@tailwindcss/node": "4.3.3",
|
|
49
|
+
"@tailwindcss/oxide": "4.3.3",
|
|
50
|
+
"playwright-core": "1.62.1",
|
|
51
|
+
"tailwindcss": "4.3.3",
|
|
52
|
+
"tw-animate-css": "1.4.0"
|
|
53
|
+
},
|
|
54
|
+
"optionalDependencies": {
|
|
55
|
+
"@oven/bun-darwin-aarch64": "1.4.2",
|
|
56
|
+
"@oven/bun-darwin-x64-baseline": "1.4.2",
|
|
57
|
+
"@oven/bun-linux-aarch64": "1.4.2",
|
|
58
|
+
"@oven/bun-linux-aarch64-musl": "1.4.2",
|
|
59
|
+
"@oven/bun-linux-x64-baseline": "1.4.2",
|
|
60
|
+
"@oven/bun-linux-x64-musl-baseline": "1.4.2",
|
|
61
|
+
"@oven/bun-windows-aarch64": "1.4.2",
|
|
62
|
+
"@oven/bun-windows-x64-baseline": "1.4.2"
|
|
63
|
+
}
|
|
11
64
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Velloo-owned generic container. Designs are mostly layout: before Box
|
|
2
|
+
// existed every flex/grid wrapper was a Card with its chrome reset
|
|
3
|
+
// ("ring-0 shadow-none bg-transparent rounded-none p-0"), which bloated
|
|
4
|
+
// trees and invited styling accidents (Card's overflow-hidden clipping
|
|
5
|
+
// children). Box is a plain div: no chrome, no padding, no surprises —
|
|
6
|
+
// className is the whole API. Codegen lowers it to `<as ?? div>`.
|
|
7
|
+
|
|
8
|
+
import type * as React from "react";
|
|
9
|
+
import { createElement } from "react";
|
|
10
|
+
import { cn } from "./cn.ts";
|
|
11
|
+
|
|
12
|
+
// Restrict `as` to a lowercase HTML tag name. Anything else (a component
|
|
13
|
+
// reference, an injection attempt) falls back to div. Rendering the real tag
|
|
14
|
+
// means inline elements (span/strong/a/…) get their natural inline display
|
|
15
|
+
// from the UA stylesheet, instead of a div's block stacking inline runs.
|
|
16
|
+
const TAG = /^[a-z][a-z0-9]*$/;
|
|
17
|
+
|
|
18
|
+
export function Box({ as, className, ...props }: React.ComponentProps<"div"> & { as?: string }) {
|
|
19
|
+
const tag = typeof as === "string" && TAG.test(as) ? as : "div";
|
|
20
|
+
return createElement(tag, { "data-slot": "box", className: cn(className), ...props });
|
|
21
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { TYPESET_SCALE_NAMES } from "@velloo/schema/typeset";
|
|
2
|
+
import { type ClassValue, clsx } from "clsx";
|
|
3
|
+
import { extendTailwindMerge } from "tailwind-merge";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The typeset ladder's utilities are theme-generated, so stock tailwind-merge
|
|
7
|
+
* has never heard of them: it would classify `text-h1` as a *color* (the
|
|
8
|
+
* `text-<color>` group) and `leading-h1` / `tracking-h1` as unknown. That
|
|
9
|
+
* misfiling both kept a component default alive next to an author's override
|
|
10
|
+
* (`<Heading className="text-sm">` still carried `text-h1`, and the larger one
|
|
11
|
+
* won) and dropped a size next to a tone (`text-body text-foreground`).
|
|
12
|
+
*
|
|
13
|
+
* Registering the role names in the right groups restores last-wins per group,
|
|
14
|
+
* which every helper relies on for `className` to be an override.
|
|
15
|
+
*
|
|
16
|
+
* Exported as the ONE merge for velloo-owned class strings — codegen's emit and
|
|
17
|
+
* the snapshot runtime use it too, so a typeset class survives the same way in
|
|
18
|
+
* the canvas and in generated code.
|
|
19
|
+
*/
|
|
20
|
+
export const mergeTailwind = extendTailwindMerge({
|
|
21
|
+
extend: {
|
|
22
|
+
classGroups: {
|
|
23
|
+
"font-size": TYPESET_SCALE_NAMES.map((role) => `text-${role}`),
|
|
24
|
+
leading: TYPESET_SCALE_NAMES.map((role) => `leading-${role}`),
|
|
25
|
+
tracking: TYPESET_SCALE_NAMES.map((role) => `tracking-${role}`),
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export function cn(...inputs: ClassValue[]): string {
|
|
31
|
+
return mergeTailwind(clsx(inputs));
|
|
32
|
+
}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import type { ComponentDescriptor } from "@velloo/provider";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The canonical manifest entries for the velloo helpers (`source: "velloo"`).
|
|
5
|
+
* Single source: the shadcn snapshot's `build.ts` splices these into its
|
|
6
|
+
* generated `dist/manifest.json` (augmenting `Icon.name` with the live
|
|
7
|
+
* lucide-react name list at build time), and `provider-none` composes its
|
|
8
|
+
* hand-authored manifest from them. Keep each entry mirroring the co-located
|
|
9
|
+
* component's props (`./heading.tsx`, `./icon.tsx`, …).
|
|
10
|
+
*/
|
|
11
|
+
export const HELPER_DESCRIPTORS: readonly ComponentDescriptor[] = [
|
|
12
|
+
{
|
|
13
|
+
id: "Box",
|
|
14
|
+
category: "ui",
|
|
15
|
+
group: "layout",
|
|
16
|
+
family: "Box",
|
|
17
|
+
source: "velloo",
|
|
18
|
+
props: [],
|
|
19
|
+
example: { className: "flex flex-col gap-6 px-8 py-12" },
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: "Divider",
|
|
23
|
+
category: "ui",
|
|
24
|
+
group: "layout",
|
|
25
|
+
family: "Divider",
|
|
26
|
+
source: "velloo",
|
|
27
|
+
props: [
|
|
28
|
+
{
|
|
29
|
+
name: "variant",
|
|
30
|
+
type: '"solid" | "dotted" | "dashed" | "gradient" | "pinched" | undefined',
|
|
31
|
+
optional: true,
|
|
32
|
+
control: "enum",
|
|
33
|
+
enumValues: ["solid", "dotted", "dashed", "gradient", "pinched"],
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: "orientation",
|
|
37
|
+
type: '"horizontal" | "vertical" | undefined',
|
|
38
|
+
optional: true,
|
|
39
|
+
control: "enum",
|
|
40
|
+
enumValues: ["horizontal", "vertical"],
|
|
41
|
+
},
|
|
42
|
+
{ name: "label", type: "string | undefined", optional: true, control: "string" },
|
|
43
|
+
{
|
|
44
|
+
name: "color",
|
|
45
|
+
type: '"primary" | "accent" | "muted" | "border" | undefined',
|
|
46
|
+
optional: true,
|
|
47
|
+
control: "enum",
|
|
48
|
+
enumValues: ["primary", "accent", "muted", "border"],
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
example: { variant: "gradient", color: "primary", label: "OR" },
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: "Gradient",
|
|
55
|
+
category: "ui",
|
|
56
|
+
group: "visuals",
|
|
57
|
+
family: "Gradient",
|
|
58
|
+
source: "velloo",
|
|
59
|
+
props: [
|
|
60
|
+
{
|
|
61
|
+
name: "preset",
|
|
62
|
+
type: '"primary" | "accent" | "radial" | "mesh" | "dusk" | "dawn" | undefined',
|
|
63
|
+
optional: true,
|
|
64
|
+
control: "enum",
|
|
65
|
+
enumValues: ["primary", "accent", "radial", "mesh", "dusk", "dawn"],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: "direction",
|
|
69
|
+
type: '"t" | "b" | "l" | "r" | "tl" | "tr" | "bl" | "br" | undefined',
|
|
70
|
+
optional: true,
|
|
71
|
+
control: "enum",
|
|
72
|
+
enumValues: ["t", "b", "l", "r", "tl", "tr", "bl", "br"],
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
example: {
|
|
76
|
+
preset: "dusk",
|
|
77
|
+
direction: "br",
|
|
78
|
+
className: "absolute inset-0 -z-0 pointer-events-none",
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: "Heading",
|
|
83
|
+
category: "typography",
|
|
84
|
+
group: "typography",
|
|
85
|
+
family: "Heading",
|
|
86
|
+
source: "velloo",
|
|
87
|
+
props: [
|
|
88
|
+
{
|
|
89
|
+
name: "level",
|
|
90
|
+
type: "1 | 2 | 3 | 4 | 5 | 6 | undefined",
|
|
91
|
+
optional: true,
|
|
92
|
+
control: "enum",
|
|
93
|
+
enumValues: [1, 2, 3, 4, 5, 6],
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
example: { level: 2, children: "Section title", className: "text-3xl font-semibold" },
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: "Icon",
|
|
100
|
+
category: "ui",
|
|
101
|
+
group: "visuals",
|
|
102
|
+
family: "Icon",
|
|
103
|
+
source: "velloo",
|
|
104
|
+
props: [
|
|
105
|
+
// `enumValues` (the lucide icon name list) is injected at snapshot build
|
|
106
|
+
// time from the installed lucide-react, so it never drifts from what the
|
|
107
|
+
// Icon component can actually resolve.
|
|
108
|
+
{ name: "name", type: "string", optional: false, control: "icon", defaultValue: "Heart" },
|
|
109
|
+
{ name: "size", type: "number | undefined", optional: true, control: "number" },
|
|
110
|
+
{ name: "strokeWidth", type: "number | undefined", optional: true, control: "number" },
|
|
111
|
+
],
|
|
112
|
+
designModeNotes:
|
|
113
|
+
"`name` accepts any lucide-react icon, PascalCase (ArrowRight) or kebab-case (arrow-right); full list at lucide.dev (the enumValues here are sampled). " +
|
|
114
|
+
"`size` sets width/height in px, but a Tailwind sizing class in `className` (e.g. `size-4`) wins via CSS — pass one or the other, not both expecting `size` to apply.",
|
|
115
|
+
example: { name: "Sparkles", className: "size-4 text-primary" },
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
id: "Image",
|
|
119
|
+
category: "ui",
|
|
120
|
+
group: "visuals",
|
|
121
|
+
family: "Image",
|
|
122
|
+
source: "velloo",
|
|
123
|
+
props: [
|
|
124
|
+
{ name: "src", type: "string", optional: false, control: "string" },
|
|
125
|
+
{
|
|
126
|
+
name: "aspect",
|
|
127
|
+
type: '"1/1" | "4/3" | "3/4" | "16/9" | "21/9" | undefined',
|
|
128
|
+
optional: true,
|
|
129
|
+
control: "enum",
|
|
130
|
+
enumValues: ["1/1", "4/3", "3/4", "16/9", "21/9"],
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: "focal",
|
|
134
|
+
type: "{ x: number; y: number; } | undefined",
|
|
135
|
+
optional: true,
|
|
136
|
+
control: "string",
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: "treatment",
|
|
140
|
+
type: '"overlay-dark" | "overlay-light" | "blend-multiply" | "grayscale" | undefined',
|
|
141
|
+
optional: true,
|
|
142
|
+
control: "enum",
|
|
143
|
+
enumValues: ["overlay-dark", "overlay-light", "blend-multiply", "grayscale"],
|
|
144
|
+
},
|
|
145
|
+
{ name: "fill", type: "boolean | undefined", optional: true, control: "boolean" },
|
|
146
|
+
],
|
|
147
|
+
example: {
|
|
148
|
+
src: "/assets/hero.png",
|
|
149
|
+
aspect: "16/9",
|
|
150
|
+
focal: { x: 0.5, y: 0.35 },
|
|
151
|
+
treatment: "overlay-dark",
|
|
152
|
+
className: "rounded-xl",
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
id: "Layer",
|
|
157
|
+
category: "ui",
|
|
158
|
+
group: "layout",
|
|
159
|
+
family: "Layer",
|
|
160
|
+
source: "velloo",
|
|
161
|
+
props: [
|
|
162
|
+
{ name: "top", type: "string | number | undefined", optional: true, control: "string" },
|
|
163
|
+
{ name: "right", type: "string | number | undefined", optional: true, control: "string" },
|
|
164
|
+
{ name: "bottom", type: "string | number | undefined", optional: true, control: "string" },
|
|
165
|
+
{ name: "left", type: "string | number | undefined", optional: true, control: "string" },
|
|
166
|
+
{ name: "z", type: "number | undefined", optional: true, control: "number" },
|
|
167
|
+
{ name: "pointerEvents", type: "boolean | undefined", optional: true, control: "boolean" },
|
|
168
|
+
],
|
|
169
|
+
example: { top: 16, left: 16, z: 2 },
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
id: "Placeholder",
|
|
173
|
+
category: "ui",
|
|
174
|
+
group: "visuals",
|
|
175
|
+
family: "Placeholder",
|
|
176
|
+
source: "velloo",
|
|
177
|
+
props: [
|
|
178
|
+
{
|
|
179
|
+
name: "kind",
|
|
180
|
+
type: '"image" | "avatar" | undefined',
|
|
181
|
+
optional: true,
|
|
182
|
+
control: "enum",
|
|
183
|
+
enumValues: ["image", "avatar"],
|
|
184
|
+
},
|
|
185
|
+
{ name: "label", type: "string | undefined", optional: true, control: "string" },
|
|
186
|
+
{
|
|
187
|
+
name: "aspect",
|
|
188
|
+
type: '"1/1" | "4/3" | "3/4" | "16/9" | "21/9" | undefined',
|
|
189
|
+
optional: true,
|
|
190
|
+
control: "enum",
|
|
191
|
+
enumValues: ["1/1", "4/3", "3/4", "16/9", "21/9"],
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
name: "size",
|
|
195
|
+
type: '"sm" | "lg" | "md" | "xl" | undefined',
|
|
196
|
+
optional: true,
|
|
197
|
+
control: "enum",
|
|
198
|
+
enumValues: ["sm", "lg", "md", "xl"],
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
example: { kind: "image", aspect: "16/9", label: "product screenshot" },
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
id: "Prose",
|
|
205
|
+
category: "typography",
|
|
206
|
+
group: "typography",
|
|
207
|
+
family: "Prose",
|
|
208
|
+
source: "velloo",
|
|
209
|
+
props: [
|
|
210
|
+
{
|
|
211
|
+
name: "preset",
|
|
212
|
+
type: "string | undefined",
|
|
213
|
+
optional: true,
|
|
214
|
+
control: "string",
|
|
215
|
+
},
|
|
216
|
+
{ name: "as", type: "string | undefined", optional: true, control: "string" },
|
|
217
|
+
],
|
|
218
|
+
example: { as: "article", className: "max-w-prose" },
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
id: "SVG",
|
|
222
|
+
category: "ui",
|
|
223
|
+
group: "visuals",
|
|
224
|
+
family: "SVG",
|
|
225
|
+
source: "velloo",
|
|
226
|
+
props: [
|
|
227
|
+
{ name: "content", type: "string | undefined", optional: true, control: "string" },
|
|
228
|
+
{ name: "viewBox", type: "string | undefined", optional: true, control: "string" },
|
|
229
|
+
{ name: "color", type: "string | undefined", optional: true, control: "color" },
|
|
230
|
+
],
|
|
231
|
+
example: {
|
|
232
|
+
content: "<path d='M12 2 2 7l10 5 10-5-10-5z' />",
|
|
233
|
+
viewBox: "0 0 24 24",
|
|
234
|
+
color: "primary",
|
|
235
|
+
className: "h-8 w-8",
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
id: "Text",
|
|
240
|
+
category: "typography",
|
|
241
|
+
group: "typography",
|
|
242
|
+
family: "Text",
|
|
243
|
+
source: "velloo",
|
|
244
|
+
props: [
|
|
245
|
+
{
|
|
246
|
+
name: "variant",
|
|
247
|
+
type: '"muted" | "default" | "small" | "lead" | undefined',
|
|
248
|
+
optional: true,
|
|
249
|
+
control: "enum",
|
|
250
|
+
enumValues: ["muted", "default", "small", "lead"],
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
example: { variant: "muted", children: "Supporting copy." },
|
|
254
|
+
},
|
|
255
|
+
];
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Subset selector mirroring `helpersRegistry` — each provider passes its own
|
|
259
|
+
* deliberate id list and gets the canonical descriptors in that order.
|
|
260
|
+
* Unknown ids are skipped.
|
|
261
|
+
*/
|
|
262
|
+
export function helperDescriptors(ids: readonly string[]): ComponentDescriptor[] {
|
|
263
|
+
const byId = new Map(HELPER_DESCRIPTORS.map((d) => [d.id, d]));
|
|
264
|
+
const out: ComponentDescriptor[] = [];
|
|
265
|
+
for (const id of ids) {
|
|
266
|
+
const descriptor = byId.get(id);
|
|
267
|
+
if (descriptor) out.push(descriptor);
|
|
268
|
+
}
|
|
269
|
+
return out;
|
|
270
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// Velloo-owned decorative divider. shadcn's Separator is a single
|
|
2
|
+
// border-bg-border rule — fine for app chrome but too plain for
|
|
3
|
+
// marketing pages. Divider adds variant styles (dotted, gradient,
|
|
4
|
+
// pinched) and a label slot for "OR" / "section break" usage.
|
|
5
|
+
import type * as React from "react";
|
|
6
|
+
import { cn } from "./cn.ts";
|
|
7
|
+
|
|
8
|
+
export interface DividerProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
9
|
+
variant?: "solid" | "dotted" | "dashed" | "gradient" | "pinched";
|
|
10
|
+
orientation?: "horizontal" | "vertical";
|
|
11
|
+
/** Optional centered label, like "OR" or "section break". */
|
|
12
|
+
label?: string;
|
|
13
|
+
/** Color source — semantic token name; defaults to border. */
|
|
14
|
+
color?: "border" | "muted" | "primary" | "accent";
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const COLOR_BORDER: Record<NonNullable<DividerProps["color"]>, string> = {
|
|
18
|
+
border: "border-border",
|
|
19
|
+
muted: "border-muted-foreground/30",
|
|
20
|
+
primary: "border-primary/40",
|
|
21
|
+
accent: "border-accent/60",
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const COLOR_BG: Record<NonNullable<DividerProps["color"]>, string> = {
|
|
25
|
+
border: "from-border via-border to-border",
|
|
26
|
+
muted: "from-transparent via-muted-foreground/40 to-transparent",
|
|
27
|
+
primary: "from-transparent via-primary to-transparent",
|
|
28
|
+
accent: "from-transparent via-accent to-transparent",
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const VARIANT_BORDER: Record<NonNullable<DividerProps["variant"]>, string> = {
|
|
32
|
+
solid: "border-solid",
|
|
33
|
+
dotted: "border-dotted",
|
|
34
|
+
dashed: "border-dashed",
|
|
35
|
+
gradient: "",
|
|
36
|
+
pinched: "border-solid",
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export function Divider({
|
|
40
|
+
variant = "solid",
|
|
41
|
+
orientation = "horizontal",
|
|
42
|
+
label,
|
|
43
|
+
color = "border",
|
|
44
|
+
className,
|
|
45
|
+
...rest
|
|
46
|
+
}: DividerProps) {
|
|
47
|
+
if (label) {
|
|
48
|
+
return (
|
|
49
|
+
<div
|
|
50
|
+
data-slot="divider"
|
|
51
|
+
data-variant={variant}
|
|
52
|
+
className={cn(
|
|
53
|
+
"flex items-center gap-3 text-xs uppercase tracking-wider text-muted-foreground",
|
|
54
|
+
className,
|
|
55
|
+
)}
|
|
56
|
+
{...rest}
|
|
57
|
+
>
|
|
58
|
+
<span
|
|
59
|
+
className={cn(
|
|
60
|
+
"flex-1",
|
|
61
|
+
variant === "gradient"
|
|
62
|
+
? cn("h-px bg-gradient-to-r", COLOR_BG[color])
|
|
63
|
+
: cn("border-t", VARIANT_BORDER[variant], COLOR_BORDER[color]),
|
|
64
|
+
)}
|
|
65
|
+
/>
|
|
66
|
+
<span className="shrink-0">{label}</span>
|
|
67
|
+
<span
|
|
68
|
+
className={cn(
|
|
69
|
+
"flex-1",
|
|
70
|
+
variant === "gradient"
|
|
71
|
+
? cn("h-px bg-gradient-to-r", COLOR_BG[color])
|
|
72
|
+
: cn("border-t", VARIANT_BORDER[variant], COLOR_BORDER[color]),
|
|
73
|
+
)}
|
|
74
|
+
/>
|
|
75
|
+
</div>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (variant === "gradient") {
|
|
80
|
+
return (
|
|
81
|
+
<div
|
|
82
|
+
data-slot="divider"
|
|
83
|
+
data-variant="gradient"
|
|
84
|
+
className={cn(
|
|
85
|
+
orientation === "horizontal" ? "h-px w-full" : "w-px self-stretch",
|
|
86
|
+
"bg-gradient-to-r",
|
|
87
|
+
COLOR_BG[color],
|
|
88
|
+
className,
|
|
89
|
+
)}
|
|
90
|
+
{...rest}
|
|
91
|
+
/>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (variant === "pinched") {
|
|
96
|
+
return (
|
|
97
|
+
<div
|
|
98
|
+
data-slot="divider"
|
|
99
|
+
data-variant="pinched"
|
|
100
|
+
className={cn("flex items-center justify-center w-full", className)}
|
|
101
|
+
{...rest}
|
|
102
|
+
>
|
|
103
|
+
<span className={cn("h-px w-16 border-t", COLOR_BORDER[color])} />
|
|
104
|
+
<span className={cn("mx-1 size-1.5 rounded-full", COLOR_BG[color].split(" ")[1] ?? "")} />
|
|
105
|
+
<span className={cn("h-px w-16 border-t", COLOR_BORDER[color])} />
|
|
106
|
+
</div>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<div
|
|
112
|
+
data-slot="divider"
|
|
113
|
+
data-variant={variant}
|
|
114
|
+
className={cn(
|
|
115
|
+
orientation === "horizontal"
|
|
116
|
+
? cn("w-full border-t", VARIANT_BORDER[variant], COLOR_BORDER[color])
|
|
117
|
+
: cn("self-stretch border-l", VARIANT_BORDER[variant], COLOR_BORDER[color]),
|
|
118
|
+
className,
|
|
119
|
+
)}
|
|
120
|
+
{...rest}
|
|
121
|
+
/>
|
|
122
|
+
);
|
|
123
|
+
}
|