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,84 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/tabs).
|
|
2
|
+
// Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
|
|
3
|
+
// Regenerate with `bun run vendor` — do not hand-edit unless you are adding a
|
|
4
|
+
// canvas adaptation, in which case add the id to vendor.ts's ADAPTED set.
|
|
5
|
+
"use client";
|
|
6
|
+
|
|
7
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
8
|
+
import { Tabs as TabsPrimitive } from "radix-ui";
|
|
9
|
+
import type * as React from "react";
|
|
10
|
+
|
|
11
|
+
import { cn } from "../../lib/utils.ts";
|
|
12
|
+
|
|
13
|
+
function Tabs({
|
|
14
|
+
className,
|
|
15
|
+
orientation = "horizontal",
|
|
16
|
+
...props
|
|
17
|
+
}: React.ComponentProps<typeof TabsPrimitive.Root>) {
|
|
18
|
+
return (
|
|
19
|
+
<TabsPrimitive.Root
|
|
20
|
+
data-slot="tabs"
|
|
21
|
+
data-orientation={orientation}
|
|
22
|
+
className={cn("group/tabs flex gap-2 data-horizontal:flex-col", className)}
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const tabsListVariants = cva(
|
|
29
|
+
"group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none",
|
|
30
|
+
{
|
|
31
|
+
variants: {
|
|
32
|
+
variant: {
|
|
33
|
+
default: "bg-muted",
|
|
34
|
+
line: "gap-1 bg-transparent",
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
defaultVariants: {
|
|
38
|
+
variant: "default",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
function TabsList({
|
|
44
|
+
className,
|
|
45
|
+
variant = "default",
|
|
46
|
+
...props
|
|
47
|
+
}: React.ComponentProps<typeof TabsPrimitive.List> & VariantProps<typeof tabsListVariants>) {
|
|
48
|
+
return (
|
|
49
|
+
<TabsPrimitive.List
|
|
50
|
+
data-slot="tabs-list"
|
|
51
|
+
data-variant={variant}
|
|
52
|
+
className={cn(tabsListVariants({ variant }), className)}
|
|
53
|
+
{...props}
|
|
54
|
+
/>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function TabsTrigger({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
|
|
59
|
+
return (
|
|
60
|
+
<TabsPrimitive.Trigger
|
|
61
|
+
data-slot="tabs-trigger"
|
|
62
|
+
className={cn(
|
|
63
|
+
"relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
64
|
+
"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent",
|
|
65
|
+
"data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground",
|
|
66
|
+
"after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100",
|
|
67
|
+
className,
|
|
68
|
+
)}
|
|
69
|
+
{...props}
|
|
70
|
+
/>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function TabsContent({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Content>) {
|
|
75
|
+
return (
|
|
76
|
+
<TabsPrimitive.Content
|
|
77
|
+
data-slot="tabs-content"
|
|
78
|
+
className={cn("flex-1 text-sm outline-none", className)}
|
|
79
|
+
{...props}
|
|
80
|
+
/>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export { Tabs, TabsContent, TabsList, TabsTrigger, tabsListVariants };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/textarea).
|
|
2
|
+
// Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
|
|
3
|
+
// Canvas-safe: same contract as Input — designs ship a `value` with no handler
|
|
4
|
+
// to show populated copy, and React warns about a controlled field it can never
|
|
5
|
+
// update, so `value` without `onChange` opts into `readOnly`.
|
|
6
|
+
import type * as React from "react";
|
|
7
|
+
|
|
8
|
+
import { cn } from "../../lib/utils.ts";
|
|
9
|
+
|
|
10
|
+
export function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
|
|
11
|
+
const isStaticControlled =
|
|
12
|
+
props.value !== undefined && props.onChange === undefined && props.readOnly === undefined;
|
|
13
|
+
return (
|
|
14
|
+
<textarea
|
|
15
|
+
data-slot="textarea"
|
|
16
|
+
className={cn(
|
|
17
|
+
"flex field-sizing-content min-h-16 w-full rounded-lg border border-input bg-transparent px-2.5 py-2 text-base transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
|
|
18
|
+
className,
|
|
19
|
+
)}
|
|
20
|
+
{...props}
|
|
21
|
+
readOnly={isStaticControlled ? true : props.readOnly}
|
|
22
|
+
/>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/toggle-group).
|
|
2
|
+
// Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
|
|
3
|
+
// Canvas-safe: the group's props are relaxed off Radix's `type`-discriminated
|
|
4
|
+
// union, and `type` defaults, so a design that only names the items still
|
|
5
|
+
// renders.
|
|
6
|
+
"use client";
|
|
7
|
+
|
|
8
|
+
import type { VariantProps } from "class-variance-authority";
|
|
9
|
+
import { ToggleGroup as ToggleGroupPrimitive } from "radix-ui";
|
|
10
|
+
import * as React from "react";
|
|
11
|
+
|
|
12
|
+
import { cn } from "../../lib/utils.ts";
|
|
13
|
+
import { toggleVariants } from "./toggle.tsx";
|
|
14
|
+
|
|
15
|
+
const ToggleGroupContext = React.createContext<
|
|
16
|
+
VariantProps<typeof toggleVariants> & {
|
|
17
|
+
spacing?: number;
|
|
18
|
+
orientation?: "horizontal" | "vertical";
|
|
19
|
+
}
|
|
20
|
+
>({
|
|
21
|
+
size: "default",
|
|
22
|
+
variant: "default",
|
|
23
|
+
spacing: 2,
|
|
24
|
+
orientation: "horizontal",
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Radix discriminates the Root's props on `type` — `value` is a string for
|
|
29
|
+
* `"single"` and an array for `"multiple"` — which is user-hostile to thread
|
|
30
|
+
* through MCP. The wrapper takes a permissive passthrough instead: a
|
|
31
|
+
* design-mode group only has to render.
|
|
32
|
+
*/
|
|
33
|
+
export function ToggleGroup({
|
|
34
|
+
className,
|
|
35
|
+
variant,
|
|
36
|
+
size,
|
|
37
|
+
spacing = 2,
|
|
38
|
+
orientation = "horizontal",
|
|
39
|
+
type = "single",
|
|
40
|
+
children,
|
|
41
|
+
...props
|
|
42
|
+
// biome-ignore lint/suspicious/noExplicitAny: discriminated radix props are user-hostile in design mode
|
|
43
|
+
}: any) {
|
|
44
|
+
return (
|
|
45
|
+
<ToggleGroupPrimitive.Root
|
|
46
|
+
data-slot="toggle-group"
|
|
47
|
+
data-variant={variant}
|
|
48
|
+
data-size={size}
|
|
49
|
+
data-spacing={spacing}
|
|
50
|
+
data-orientation={orientation}
|
|
51
|
+
type={type as "single"}
|
|
52
|
+
style={{ "--gap": spacing } as React.CSSProperties}
|
|
53
|
+
className={cn(
|
|
54
|
+
"group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] rounded-lg data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-vertical:flex-col data-vertical:items-stretch",
|
|
55
|
+
className,
|
|
56
|
+
)}
|
|
57
|
+
{...props}
|
|
58
|
+
>
|
|
59
|
+
<ToggleGroupContext.Provider value={{ variant, size, spacing, orientation }}>
|
|
60
|
+
{children}
|
|
61
|
+
</ToggleGroupContext.Provider>
|
|
62
|
+
</ToggleGroupPrimitive.Root>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function ToggleGroupItem({
|
|
67
|
+
className,
|
|
68
|
+
children,
|
|
69
|
+
variant = "default",
|
|
70
|
+
size = "default",
|
|
71
|
+
...props
|
|
72
|
+
}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> & VariantProps<typeof toggleVariants>) {
|
|
73
|
+
const context = React.useContext(ToggleGroupContext);
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<ToggleGroupPrimitive.Item
|
|
77
|
+
data-slot="toggle-group-item"
|
|
78
|
+
data-variant={context.variant || variant}
|
|
79
|
+
data-size={context.size || size}
|
|
80
|
+
data-spacing={context.spacing}
|
|
81
|
+
className={cn(
|
|
82
|
+
"shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 focus:z-10 focus-visible:z-10 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-end]:pr-1.5 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-start]:pl-1.5 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-lg group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-lg group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-lg group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-lg group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t",
|
|
83
|
+
toggleVariants({
|
|
84
|
+
variant: context.variant || variant,
|
|
85
|
+
size: context.size || size,
|
|
86
|
+
}),
|
|
87
|
+
className,
|
|
88
|
+
)}
|
|
89
|
+
{...props}
|
|
90
|
+
>
|
|
91
|
+
{children}
|
|
92
|
+
</ToggleGroupPrimitive.Item>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/toggle).
|
|
2
|
+
// Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
|
|
3
|
+
// Regenerate with `bun run vendor` — do not hand-edit unless you are adding a
|
|
4
|
+
// canvas adaptation, in which case add the id to vendor.ts's ADAPTED set.
|
|
5
|
+
"use client";
|
|
6
|
+
|
|
7
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
8
|
+
import { Toggle as TogglePrimitive } from "radix-ui";
|
|
9
|
+
import type * as React from "react";
|
|
10
|
+
|
|
11
|
+
import { cn } from "../../lib/utils.ts";
|
|
12
|
+
|
|
13
|
+
const toggleVariants = cva(
|
|
14
|
+
"group/toggle inline-flex items-center justify-center gap-1 rounded-lg text-sm font-medium whitespace-nowrap transition-all outline-none hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 aria-pressed:bg-muted data-[state=on]:bg-muted dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
15
|
+
{
|
|
16
|
+
variants: {
|
|
17
|
+
variant: {
|
|
18
|
+
default: "bg-transparent",
|
|
19
|
+
outline: "border border-input bg-transparent hover:bg-muted",
|
|
20
|
+
},
|
|
21
|
+
size: {
|
|
22
|
+
default:
|
|
23
|
+
"h-8 min-w-8 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
24
|
+
sm: "h-7 min-w-7 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
|
|
25
|
+
lg: "h-9 min-w-9 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
defaultVariants: {
|
|
29
|
+
variant: "default",
|
|
30
|
+
size: "default",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
function Toggle({
|
|
36
|
+
className,
|
|
37
|
+
variant = "default",
|
|
38
|
+
size = "default",
|
|
39
|
+
...props
|
|
40
|
+
}: React.ComponentProps<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>) {
|
|
41
|
+
return (
|
|
42
|
+
<TogglePrimitive.Root
|
|
43
|
+
data-slot="toggle"
|
|
44
|
+
className={cn(toggleVariants({ variant, size, className }))}
|
|
45
|
+
{...props}
|
|
46
|
+
/>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export { Toggle, toggleVariants };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/tooltip).
|
|
2
|
+
// Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
|
|
3
|
+
// Canvas-safe: see ../canvas-portal.tsx.
|
|
4
|
+
"use client";
|
|
5
|
+
|
|
6
|
+
import { Tooltip as TooltipPrimitive } from "radix-ui";
|
|
7
|
+
import type * as React from "react";
|
|
8
|
+
import { cn } from "../../lib/utils.ts";
|
|
9
|
+
import { inlineOpenAttrs, pinOpenInDesignMode } from "../canvas-portal.tsx";
|
|
10
|
+
|
|
11
|
+
export function TooltipProvider({
|
|
12
|
+
...props
|
|
13
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
|
|
14
|
+
return <TooltipPrimitive.Provider data-slot="tooltip-provider" {...props} />;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>) {
|
|
18
|
+
return (
|
|
19
|
+
<TooltipPrimitive.Provider>
|
|
20
|
+
<TooltipPrimitive.Root data-slot="tooltip" {...pinOpenInDesignMode(props)} />
|
|
21
|
+
</TooltipPrimitive.Provider>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function TooltipTrigger({
|
|
26
|
+
...props
|
|
27
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
|
|
28
|
+
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function TooltipContent({
|
|
32
|
+
className,
|
|
33
|
+
sideOffset: _sideOffset,
|
|
34
|
+
...props
|
|
35
|
+
}: React.ComponentProps<"div"> & { sideOffset?: number }) {
|
|
36
|
+
return (
|
|
37
|
+
<div
|
|
38
|
+
data-slot="tooltip-content"
|
|
39
|
+
{...inlineOpenAttrs()}
|
|
40
|
+
className={cn(
|
|
41
|
+
"z-50 inline-flex w-fit max-w-xs items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pr-1.5 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm",
|
|
42
|
+
className,
|
|
43
|
+
)}
|
|
44
|
+
{...props}
|
|
45
|
+
/>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical usage examples merged into the generated manifest by
|
|
3
|
+
* build.ts. Only components whose prop *shapes* aren't obvious from
|
|
4
|
+
* names need one — the goal is that an agent can copy the example,
|
|
5
|
+
* swap values, and get a correct render on the first try.
|
|
6
|
+
*
|
|
7
|
+
* Covers the shadcn-sourced components only; the velloo helpers carry
|
|
8
|
+
* their examples inside `@velloo/helpers`' canonical descriptors.
|
|
9
|
+
*/
|
|
10
|
+
export const COMPONENT_EXAMPLES: Record<string, Record<string, unknown>> = {
|
|
11
|
+
Chart: {
|
|
12
|
+
// Single series: `data: [{ x, y }]`. Multi-series: `categories` +
|
|
13
|
+
// `series: [{ name, data: number[] }]` (legend auto-on). `kind`:
|
|
14
|
+
// bar | line | area | pie | scatter. `tickFormat`: number | compact |
|
|
15
|
+
// currency | percent. `xLabel`/`yLabel` add axis titles. `color`
|
|
16
|
+
// (single-series): primary | accent | muted — theme tokens, so charts
|
|
17
|
+
// flip under dark mode.
|
|
18
|
+
kind: "bar",
|
|
19
|
+
categories: ["Mon", "Tue", "Wed", "Thu", "Fri"],
|
|
20
|
+
series: [
|
|
21
|
+
{ name: "Revenue", data: [4200, 5800, 5100, 7300, 6400] },
|
|
22
|
+
{ name: "Refunds", data: [400, 600, 350, 720, 500] },
|
|
23
|
+
],
|
|
24
|
+
yLabel: "USD",
|
|
25
|
+
tickFormat: "compact",
|
|
26
|
+
className: "h-64 w-full",
|
|
27
|
+
},
|
|
28
|
+
Button: { variant: "outline", size: "sm", children: "Action" },
|
|
29
|
+
Badge: { variant: "secondary", children: "Label" },
|
|
30
|
+
Progress: { value: 64, className: "h-2" },
|
|
31
|
+
Avatar: { className: "size-9" },
|
|
32
|
+
// `ratio` is width/height as a number, not the "16:9" string it reads as.
|
|
33
|
+
AspectRatio: { ratio: 16 / 9 },
|
|
34
|
+
// Renders a list, so it takes objects rather than the string it looks like.
|
|
35
|
+
FieldError: { errors: [{ message: "Enter a valid email address." }] },
|
|
36
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which shelf each shadcn family sits on, keyed by its source file — the same
|
|
3
|
+
* key `build.ts` already resolves per component, so a newly vendored family
|
|
4
|
+
* gets grouped by adding one line here rather than by being re-listed
|
|
5
|
+
* somewhere downstream.
|
|
6
|
+
*
|
|
7
|
+
* A family with no entry falls into the catch-all bucket, which is why the
|
|
8
|
+
* manifest test asserts this table covers every vendored file: the previous
|
|
9
|
+
* arrangement kept the grouping in the canvas sidebar, where 20 new families
|
|
10
|
+
* were silently unbrowsable because nothing failed when the list went stale.
|
|
11
|
+
*/
|
|
12
|
+
import type { ComponentGroup } from "@velloo/provider";
|
|
13
|
+
|
|
14
|
+
export const FAMILY_GROUPS: Record<string, ComponentGroup> = {
|
|
15
|
+
button: "actions",
|
|
16
|
+
"button-group": "actions",
|
|
17
|
+
toggle: "actions",
|
|
18
|
+
"toggle-group": "actions",
|
|
19
|
+
|
|
20
|
+
input: "forms",
|
|
21
|
+
textarea: "forms",
|
|
22
|
+
label: "forms",
|
|
23
|
+
checkbox: "forms",
|
|
24
|
+
"radio-group": "forms",
|
|
25
|
+
switch: "forms",
|
|
26
|
+
slider: "forms",
|
|
27
|
+
select: "forms",
|
|
28
|
+
"native-select": "forms",
|
|
29
|
+
combobox: "forms",
|
|
30
|
+
calendar: "forms",
|
|
31
|
+
field: "forms",
|
|
32
|
+
"input-group": "forms",
|
|
33
|
+
|
|
34
|
+
avatar: "display",
|
|
35
|
+
badge: "display",
|
|
36
|
+
card: "display",
|
|
37
|
+
skeleton: "display",
|
|
38
|
+
table: "display",
|
|
39
|
+
item: "display",
|
|
40
|
+
kbd: "display",
|
|
41
|
+
|
|
42
|
+
alert: "feedback",
|
|
43
|
+
progress: "feedback",
|
|
44
|
+
sonner: "feedback",
|
|
45
|
+
spinner: "feedback",
|
|
46
|
+
empty: "feedback",
|
|
47
|
+
|
|
48
|
+
tabs: "navigation",
|
|
49
|
+
breadcrumb: "navigation",
|
|
50
|
+
pagination: "navigation",
|
|
51
|
+
accordion: "navigation",
|
|
52
|
+
"navigation-menu": "navigation",
|
|
53
|
+
menubar: "navigation",
|
|
54
|
+
|
|
55
|
+
dialog: "overlays",
|
|
56
|
+
"alert-dialog": "overlays",
|
|
57
|
+
sheet: "overlays",
|
|
58
|
+
drawer: "overlays",
|
|
59
|
+
popover: "overlays",
|
|
60
|
+
"dropdown-menu": "overlays",
|
|
61
|
+
"context-menu": "overlays",
|
|
62
|
+
"hover-card": "overlays",
|
|
63
|
+
tooltip: "overlays",
|
|
64
|
+
collapsible: "overlays",
|
|
65
|
+
|
|
66
|
+
"scroll-area": "layout",
|
|
67
|
+
separator: "layout",
|
|
68
|
+
carousel: "layout",
|
|
69
|
+
"aspect-ratio": "layout",
|
|
70
|
+
|
|
71
|
+
chart: "visuals",
|
|
72
|
+
|
|
73
|
+
attachment: "chat",
|
|
74
|
+
bubble: "chat",
|
|
75
|
+
message: "chat",
|
|
76
|
+
marker: "chat",
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Families that are intentionally ungrouped: real exports an agent can name,
|
|
81
|
+
* but not components anyone browses for. Listed rather than omitted so the
|
|
82
|
+
* coverage test can tell "decided" from "forgotten".
|
|
83
|
+
*/
|
|
84
|
+
export const UNGROUPED_FAMILIES: ReadonlySet<string> = new Set([
|
|
85
|
+
// Context provider for RTL — wraps a tree, renders no UI of its own.
|
|
86
|
+
"direction",
|
|
87
|
+
]);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type FrameworkAdapter, type Manifest, TAILWIND_CLASSNAME } from "@velloo/provider";
|
|
2
|
+
import { componentsDir, entryCssPath, manifestPath, snapshotVersion } from "./paths.ts";
|
|
3
|
+
import { registry } from "./registry.ts";
|
|
4
|
+
|
|
5
|
+
export type { ComponentDescriptor, Manifest, PropDescriptor } from "./manifest.ts";
|
|
6
|
+
export { componentsDir, entryCssPath, snapshotVersion } from "./paths.ts";
|
|
7
|
+
export { registry } from "./registry.ts";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Prop manifest extracted from the vendored sources via ts-morph at build time.
|
|
11
|
+
*/
|
|
12
|
+
export async function loadManifest(): Promise<Manifest> {
|
|
13
|
+
const file = Bun.file(manifestPath);
|
|
14
|
+
if (!(await file.exists())) {
|
|
15
|
+
throw new Error(
|
|
16
|
+
`@velloo/shadcn-snapshot: dist/manifest.json missing. Run \`bun run build\` in packages/shadcn-snapshot.`,
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
return (await file.json()) as Manifest;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Build a `ComponentProvider` instance for this snapshot. Optionally
|
|
24
|
+
* overrides the on-disk `componentsDir` when the user installed the
|
|
25
|
+
* snapshot files outside the binary (in-repo or cache mode) — the
|
|
26
|
+
* runtime registry stays bundled with velloo (so what the canvas
|
|
27
|
+
* renders is byte-identical across folders), but the JIT scan target
|
|
28
|
+
* follows the install location so user customizations contribute to
|
|
29
|
+
* the compiled CSS.
|
|
30
|
+
*/
|
|
31
|
+
export function createProvider(opts: { componentsDir?: string } = {}): FrameworkAdapter {
|
|
32
|
+
return {
|
|
33
|
+
id: "shadcn-react",
|
|
34
|
+
version: snapshotVersion,
|
|
35
|
+
componentsDir: opts.componentsDir ?? componentsDir,
|
|
36
|
+
styleEntryPath: entryCssPath,
|
|
37
|
+
registry,
|
|
38
|
+
loadManifest,
|
|
39
|
+
label: `shadcn-react ${snapshotVersion}`,
|
|
40
|
+
styleChannel: TAILWIND_CLASSNAME,
|
|
41
|
+
styleChannels: ["tailwind-classname"],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest types moved to `@velloo/provider`. This module re-exports them
|
|
3
|
+
* so existing imports (`from "@velloo/shadcn-snapshot"`) keep working
|
|
4
|
+
* through the migration; consumers should prefer importing from
|
|
5
|
+
* `@velloo/provider` going forward.
|
|
6
|
+
*/
|
|
7
|
+
export type {
|
|
8
|
+
ComponentDescriptor,
|
|
9
|
+
ControlType,
|
|
10
|
+
Manifest,
|
|
11
|
+
PropDescriptor,
|
|
12
|
+
} from "@velloo/provider";
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-component `designModeNotes`, merged into the generated manifest by
|
|
3
|
+
* build.ts.
|
|
4
|
+
*
|
|
5
|
+
* Scoped to one job: telling an agent *when to reach for a component instead
|
|
6
|
+
* of building the same thing out of `Box` and `Text`*. Prop names already say
|
|
7
|
+
* what a component accepts and `example` shows the shapes; neither says that
|
|
8
|
+
* a label/control/help-text stack is what `Field` is for. That gap matters
|
|
9
|
+
* most for the families that postdate most models' training data (Field,
|
|
10
|
+
* InputGroup, Item, Empty, ButtonGroup, Spinner, Kbd, the chat set), which
|
|
11
|
+
* otherwise get hand-rolled — so notes go on family roots, and on the handful
|
|
12
|
+
* of sub-pieces whose own role isn't obvious from the name.
|
|
13
|
+
*
|
|
14
|
+
* Keep them to a couple of sentences. The composition shape belongs here as a
|
|
15
|
+
* JSX sketch because `compose` takes exactly that syntax.
|
|
16
|
+
*/
|
|
17
|
+
export const COMPONENT_NOTES: Record<string, string> = {
|
|
18
|
+
// ---- Forms -------------------------------------------------------------
|
|
19
|
+
Field:
|
|
20
|
+
"The form-field scaffold — reach for this instead of stacking Label + Input + help text by hand. " +
|
|
21
|
+
"`<Field><FieldLabel htmlFor='email'>Email</FieldLabel><Input id='email'/>" +
|
|
22
|
+
"<FieldDescription>We never share it.</FieldDescription></Field>`. " +
|
|
23
|
+
'Set `orientation="horizontal"` to put the label beside the control (checkbox/switch rows), ' +
|
|
24
|
+
"`FieldGroup` to stack several fields with consistent spacing, and `FieldSet` + `FieldLegend` for a titled section.",
|
|
25
|
+
FieldError:
|
|
26
|
+
"Renders a list, so `errors` takes objects: `[{ message: 'Enter a valid email.' }]` — not a string. " +
|
|
27
|
+
"Place it last inside a `Field`.",
|
|
28
|
+
FieldSeparator: "An 'or' divider between fields; put the label in `children`.",
|
|
29
|
+
InputGroup:
|
|
30
|
+
"An input with something attached inside its border — a leading icon, a trailing unit, a submit button. " +
|
|
31
|
+
"`<InputGroup><InputGroupAddon><Icon name='search'/></InputGroupAddon><InputGroupInput placeholder='Search'/></InputGroup>`. " +
|
|
32
|
+
"Use `InputGroupInput`/`InputGroupTextarea` rather than a bare `Input` inside it, and " +
|
|
33
|
+
'`InputGroupAddon align="inline-end"` for the trailing slot. This is the component for search bars and prefixed URL fields.',
|
|
34
|
+
NativeSelect:
|
|
35
|
+
"A real `<select>` — one tap-to-open list on mobile, and it renders faithfully in design mode. " +
|
|
36
|
+
"Prefer it over `Select` for plain option lists; `Select` is the Radix listbox, needed only for rich/custom option rows. " +
|
|
37
|
+
"Children are `NativeSelectOption` (and `NativeSelectOptGroup`).",
|
|
38
|
+
Combobox:
|
|
39
|
+
"Type-to-filter selection: `ComboboxInput` + `ComboboxList`/`ComboboxItem`, with `ComboboxChips` for multi-select. " +
|
|
40
|
+
"In design mode the list renders open and inline so you can see it; filtering does not run.",
|
|
41
|
+
|
|
42
|
+
// ---- Actions -----------------------------------------------------------
|
|
43
|
+
ButtonGroup:
|
|
44
|
+
"Joins adjacent buttons into one segmented control — shared borders, rounded only on the ends. " +
|
|
45
|
+
"Use it instead of a flex `Box` with `gap`, which leaves them as separate buttons. " +
|
|
46
|
+
"`ButtonGroupText` adds a static label segment; `ButtonGroupSeparator` divides groups.",
|
|
47
|
+
|
|
48
|
+
// ---- Display -----------------------------------------------------------
|
|
49
|
+
Item:
|
|
50
|
+
"One row of a list — the generic list-row surface, and the right building block for settings rows, " +
|
|
51
|
+
"notification lists and file lists that would otherwise be a hand-built flex `Box`. " +
|
|
52
|
+
"`<Item><ItemMedia><Icon name='file'/></ItemMedia><ItemContent><ItemTitle>Report.pdf</ItemTitle>" +
|
|
53
|
+
"<ItemDescription>2.4 MB</ItemDescription></ItemContent><ItemActions><Button/></ItemActions></Item>`. " +
|
|
54
|
+
"`ItemGroup` wraps a list; use `Card` only for actual card surfaces.",
|
|
55
|
+
Kbd: "A keyboard key cap (`⌘`, `K`). `KbdGroup` sets a chord — reach for it in shortcut hints and command-menu rows.",
|
|
56
|
+
|
|
57
|
+
// ---- Feedback ----------------------------------------------------------
|
|
58
|
+
Empty:
|
|
59
|
+
"The empty-state surface: centred icon, heading, explanation, action. " +
|
|
60
|
+
"`<Empty><EmptyHeader><EmptyMedia><Icon name='inbox'/></EmptyMedia><EmptyTitle>No invoices</EmptyTitle>" +
|
|
61
|
+
"<EmptyDescription>Create one to get started.</EmptyDescription></EmptyHeader><EmptyContent><Button/></EmptyContent></Empty>`. " +
|
|
62
|
+
"Use it for any 'nothing here yet' panel rather than centring text in a `Box`.",
|
|
63
|
+
Spinner:
|
|
64
|
+
"An inline loading indicator. Size it with a class (`size-4`) and pair it with `Skeleton` for block-level placeholders.",
|
|
65
|
+
|
|
66
|
+
// ---- Overlays ----------------------------------------------------------
|
|
67
|
+
Drawer:
|
|
68
|
+
"A sheet that slides from an edge with a drag handle — the mobile-idiomatic bottom sheet. " +
|
|
69
|
+
"For a desktop side panel prefer `Sheet`; the two are otherwise the same shape. " +
|
|
70
|
+
"Rendered open and inline in design mode.",
|
|
71
|
+
HoverCard:
|
|
72
|
+
"A rich preview shown on hover (user cards, link previews) — not a `Tooltip`, which is for a short text hint. " +
|
|
73
|
+
"Rendered open and inline in design mode.",
|
|
74
|
+
ContextMenu:
|
|
75
|
+
"The right-click menu. Same item vocabulary as `DropdownMenu`, which is the one to use for a button-triggered menu. " +
|
|
76
|
+
"Rendered open and inline in design mode.",
|
|
77
|
+
|
|
78
|
+
// ---- Navigation --------------------------------------------------------
|
|
79
|
+
Menubar:
|
|
80
|
+
"A persistent application menu bar (File / Edit / View). For a single button-triggered menu use `DropdownMenu`. " +
|
|
81
|
+
"Rendered open and inline in design mode.",
|
|
82
|
+
NavigationMenu:
|
|
83
|
+
"Site-level navigation with rich dropdown panels — marketing headers. " +
|
|
84
|
+
"For in-page section switching use `Tabs`.",
|
|
85
|
+
|
|
86
|
+
// ---- Chat & AI ---------------------------------------------------------
|
|
87
|
+
Bubble:
|
|
88
|
+
"One chat turn's speech bubble; `BubbleGroup` stacks consecutive turns from the same author " +
|
|
89
|
+
"and `BubbleReactions` adds the reaction row. For a full turn with avatar and header, use `Message`.",
|
|
90
|
+
Message:
|
|
91
|
+
"A full chat turn: `MessageAvatar` + `MessageHeader` + `MessageContent` (+ `MessageFooter`). " +
|
|
92
|
+
"`MessageGroup` wraps a transcript. Use `Bubble` when you only need the bubble itself.",
|
|
93
|
+
Attachment:
|
|
94
|
+
"A file chip attached to a chat message — `AttachmentMedia` + `AttachmentTitle`/`AttachmentDescription`, " +
|
|
95
|
+
"with `AttachmentGroup` for several and `AttachmentActions` for remove/download.",
|
|
96
|
+
Marker: "Inline annotation highlighting a span of chat text (citations, references).",
|
|
97
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import pkg from "../package.json" with { type: "json" };
|
|
5
|
+
|
|
6
|
+
/** Date stamp recording which upstream shadcn pull this snapshot mirrors. */
|
|
7
|
+
export const snapshotVersion: string = (pkg as { snapshotVersion: string }).snapshotVersion;
|
|
8
|
+
|
|
9
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Package root holding `src/` (the component sources + Tailwind entry CSS) and
|
|
13
|
+
* `dist/manifest.json`. Resolves from source (`here` = this `src/` dir) and
|
|
14
|
+
* from the bundled CLI, where `build.ts` copies these assets to
|
|
15
|
+
* `<dist>/pkgs/shadcn-snapshot` next to `cli.js`.
|
|
16
|
+
*/
|
|
17
|
+
function resolveRoot(): string {
|
|
18
|
+
const dev = join(here, "..");
|
|
19
|
+
const candidates = [
|
|
20
|
+
process.env.VELLOO_SNAPSHOT_ROOT,
|
|
21
|
+
join(here, "pkgs", "shadcn-snapshot"),
|
|
22
|
+
dev,
|
|
23
|
+
].filter((p): p is string => Boolean(p));
|
|
24
|
+
return candidates.find((r) => existsSync(join(r, "src", "tailwind-entry.css"))) ?? dev;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const root = resolveRoot();
|
|
28
|
+
const srcDir = join(root, "src");
|
|
29
|
+
const distDir = join(root, "dist");
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Absolute path to the Tailwind entry CSS shipped with the snapshot. The
|
|
33
|
+
* server's JIT compiler reads this and runs Tailwind v4 against the live
|
|
34
|
+
* page folder so any class — including ones we haven't thought of yet —
|
|
35
|
+
* renders without a hand-rolled safelist.
|
|
36
|
+
*/
|
|
37
|
+
export const entryCssPath: string = join(srcDir, "tailwind-entry.css");
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Absolute path to the snapshot's component sources. The JIT scanner reads
|
|
41
|
+
* these so the canvas picks up classes used by shipped components even if
|
|
42
|
+
* no page references them directly.
|
|
43
|
+
*/
|
|
44
|
+
export const componentsDir: string = join(srcDir, "components");
|
|
45
|
+
|
|
46
|
+
/** Absolute path to the prebuilt manifest JSON (filled at `bun run build`). */
|
|
47
|
+
export const manifestPath: string = join(distDir, "manifest.json");
|