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.
Files changed (267) hide show
  1. package/BUN-LICENSE.md +91 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +9 -0
  4. package/README.md +288 -2
  5. package/THIRD-PARTY-NOTICES.md +467 -0
  6. package/assets/elsewhere-alps-9fqhv029.jpg +0 -0
  7. package/assets/elsewhere-bali-vp60g115.jpg +0 -0
  8. package/assets/elsewhere-forest-xgn23zrj.jpg +0 -0
  9. package/assets/elsewhere-japan-qs7qkbr2.jpg +0 -0
  10. package/assets/elsewhere-kyoto-map-n2bvkrya.svg +1 -0
  11. package/assets/elsewhere-kyoto-qemtn6nk.jpg +0 -0
  12. package/assets/elsewhere-room-g1gaw7cs.jpg +0 -0
  13. package/canvas/apple-touch-icon.png +0 -0
  14. package/canvas/assets/index-BCvDZiBo.css +2 -0
  15. package/canvas/assets/index-ClaBqcaS.js +28 -0
  16. package/canvas/assets/lucide-all-iIF-pmzN.js +1 -0
  17. package/canvas/assets/radix-C3HaOB-d.js +41 -0
  18. package/canvas/assets/react-D0Ec-185.js +9 -0
  19. package/canvas/assets/rolldown-runtime-hePW80VL.js +1 -0
  20. package/canvas/assets/vendor-CKmQ-Zst.js +53 -0
  21. package/canvas/favicon.ico +0 -0
  22. package/canvas/favicon.svg +12 -0
  23. package/canvas/fonts/OFL-1.1.txt +93 -0
  24. package/canvas/fonts/poppins-700.woff2 +0 -0
  25. package/canvas/icon-192.png +0 -0
  26. package/canvas/icon-512.png +0 -0
  27. package/canvas/index.html +22 -0
  28. package/canvas/site.webmanifest +11 -0
  29. package/chunk-08sv3k41.js +4 -0
  30. package/chunk-0fe83yzt.js +2 -0
  31. package/chunk-0t68szgr.js +3 -0
  32. package/chunk-1h55s5he.js +2 -0
  33. package/chunk-2c7jbx46.js +2 -0
  34. package/chunk-2smsg2ct.js +7 -0
  35. package/chunk-308ynsxd.js +2 -0
  36. package/chunk-3e8vez4d.js +1229 -0
  37. package/chunk-40xgcth8.js +63 -0
  38. package/chunk-4dn75m6t.js +3 -0
  39. package/chunk-4fj5tahv.js +3 -0
  40. package/chunk-6nqghjda.js +3 -0
  41. package/chunk-6tx68d90.js +3 -0
  42. package/chunk-6w6ch4ce.js +2 -0
  43. package/chunk-735ezz23.js +86 -0
  44. package/chunk-7eq7nx37.js +7 -0
  45. package/chunk-7eyb8yrf.js +6 -0
  46. package/chunk-80fjfyha.js +86 -0
  47. package/chunk-80r93t2e.js +4 -0
  48. package/chunk-94vx1yb0.js +3 -0
  49. package/chunk-9vg3yafz.js +3 -0
  50. package/chunk-a84n72m2.js +4 -0
  51. package/chunk-ampmdzz4.js +10 -0
  52. package/chunk-avns4dbf.js +2 -0
  53. package/chunk-ayrb3qnm.js +3 -0
  54. package/chunk-bwnvcncx.js +3 -0
  55. package/chunk-ccszg02q.js +5 -0
  56. package/chunk-cvn689d5.js +3 -0
  57. package/chunk-cxe6jjwj.js +3 -0
  58. package/chunk-dg6z4vdd.js +3 -0
  59. package/chunk-dgwjpbp9.js +3 -0
  60. package/chunk-dy41n60j.js +52 -0
  61. package/chunk-ek71z2fv.js +226 -0
  62. package/chunk-er1fxb7d.js +2 -0
  63. package/chunk-eyr8hrzf.js +2 -0
  64. package/chunk-fjbzk4sw.js +3 -0
  65. package/chunk-fsbsksga.js +3 -0
  66. package/chunk-h6gchare.js +3 -0
  67. package/chunk-hcb68zt7.js +85 -0
  68. package/chunk-hggap8fq.js +3 -0
  69. package/chunk-j11fyeqh.js +2 -0
  70. package/chunk-jb21jkp1.js +8 -0
  71. package/chunk-jfx9xjmr.js +18 -0
  72. package/chunk-jr0ss0mm.js +303 -0
  73. package/chunk-jrsknzjt.js +3 -0
  74. package/chunk-jv0xggh0.js +2 -0
  75. package/chunk-k17gfwq3.js +2 -0
  76. package/chunk-mh2pr7cq.js +5 -0
  77. package/chunk-mnapdp1y.js +2 -0
  78. package/chunk-mzhdrawd.js +3 -0
  79. package/chunk-n9gs6yx9.js +2 -0
  80. package/chunk-ngnymg2q.js +3 -0
  81. package/chunk-nwx5700b.js +3 -0
  82. package/chunk-pjtg3wnm.js +4 -0
  83. package/chunk-pp86v6m6.js +3 -0
  84. package/chunk-r22epxz2.js +3 -0
  85. package/chunk-rgasy862.js +5 -0
  86. package/chunk-rpwpeph5.js +3 -0
  87. package/chunk-s23gtejf.js +3 -0
  88. package/chunk-sjgqnykd.js +6 -0
  89. package/chunk-sn3x2m0m.js +6 -0
  90. package/chunk-t448rrfr.js +2 -0
  91. package/chunk-tdsk5wxa.js +451 -0
  92. package/chunk-v40fn08f.js +442 -0
  93. package/chunk-vbk1qhdz.js +3 -0
  94. package/chunk-vdkrbzh1.js +2 -0
  95. package/chunk-vgmr98cv.js +40 -0
  96. package/chunk-vsv8z729.js +6 -0
  97. package/chunk-x4f4k9pp.js +26 -0
  98. package/chunk-xt5ayg7g.js +4 -0
  99. package/chunk-ydhwv29b.js +244 -0
  100. package/chunk-zb6hc1y0.js +2 -0
  101. package/cli.js +3 -0
  102. package/launcher.cjs +97 -0
  103. package/package.json +58 -5
  104. package/pkgs/helpers/src/box.tsx +21 -0
  105. package/pkgs/helpers/src/cn.ts +32 -0
  106. package/pkgs/helpers/src/descriptors.ts +270 -0
  107. package/pkgs/helpers/src/divider.tsx +123 -0
  108. package/pkgs/helpers/src/gradient.tsx +90 -0
  109. package/pkgs/helpers/src/heading.tsx +20 -0
  110. package/pkgs/helpers/src/icon-data.ts +8009 -0
  111. package/pkgs/helpers/src/icon.tsx +53 -0
  112. package/pkgs/helpers/src/image.tsx +111 -0
  113. package/pkgs/helpers/src/index.ts +29 -0
  114. package/pkgs/helpers/src/layer.tsx +61 -0
  115. package/pkgs/helpers/src/lowering.ts +53 -0
  116. package/pkgs/helpers/src/paths.ts +47 -0
  117. package/pkgs/helpers/src/placeholder.tsx +88 -0
  118. package/pkgs/helpers/src/prose.tsx +42 -0
  119. package/pkgs/helpers/src/registry.ts +41 -0
  120. package/pkgs/helpers/src/svg.tsx +62 -0
  121. package/pkgs/helpers/src/text.tsx +16 -0
  122. package/pkgs/provider-antd/src/index.ts +78 -0
  123. package/pkgs/provider-antd/src/intro.ts +14 -0
  124. package/pkgs/provider-antd/src/manifest.ts +439 -0
  125. package/pkgs/provider-antd/src/overlays.ts +176 -0
  126. package/pkgs/provider-antd/src/registry.ts +104 -0
  127. package/pkgs/provider-antd/src/render-pass.ts +43 -0
  128. package/pkgs/provider-antd/src/tailwind-entry.css +21 -0
  129. package/pkgs/provider-antd/src/theme.ts +132 -0
  130. package/pkgs/provider-antd/src/version.ts +8 -0
  131. package/pkgs/provider-chakra/src/index.ts +80 -0
  132. package/pkgs/provider-chakra/src/intro.ts +14 -0
  133. package/pkgs/provider-chakra/src/manifest.ts +421 -0
  134. package/pkgs/provider-chakra/src/overlays.ts +246 -0
  135. package/pkgs/provider-chakra/src/registry.ts +227 -0
  136. package/pkgs/provider-chakra/src/render-pass.ts +55 -0
  137. package/pkgs/provider-chakra/src/tailwind-entry.css +21 -0
  138. package/pkgs/provider-chakra/src/theme.ts +180 -0
  139. package/pkgs/provider-chakra/src/version.ts +8 -0
  140. package/pkgs/provider-mui/src/index.ts +117 -0
  141. package/pkgs/provider-mui/src/intro.ts +12 -0
  142. package/pkgs/provider-mui/src/manifest.ts +263 -0
  143. package/pkgs/provider-mui/src/overlays.ts +124 -0
  144. package/pkgs/provider-mui/src/registry.ts +120 -0
  145. package/pkgs/provider-mui/src/render-pass.ts +36 -0
  146. package/pkgs/provider-mui/src/tailwind-entry.css +21 -0
  147. package/pkgs/provider-mui/src/theme.ts +129 -0
  148. package/pkgs/provider-mui/src/version.ts +8 -0
  149. package/pkgs/provider-none/src/components-inline.tsx +204 -0
  150. package/pkgs/provider-none/src/components.tsx +155 -0
  151. package/pkgs/provider-none/src/index.ts +57 -0
  152. package/pkgs/provider-none/src/intro.ts +18 -0
  153. package/pkgs/provider-none/src/manifest.ts +163 -0
  154. package/pkgs/provider-none/src/registry-inline.ts +36 -0
  155. package/pkgs/provider-none/src/registry.ts +39 -0
  156. package/pkgs/provider-none/src/tailwind-entry.css +57 -0
  157. package/pkgs/provider-none/src/version.ts +10 -0
  158. package/pkgs/schema/src/annotation.ts +120 -0
  159. package/pkgs/schema/src/asset.ts +66 -0
  160. package/pkgs/schema/src/board.ts +71 -0
  161. package/pkgs/schema/src/comment.ts +107 -0
  162. package/pkgs/schema/src/config.ts +185 -0
  163. package/pkgs/schema/src/css-sanitize.ts +56 -0
  164. package/pkgs/schema/src/extension.ts +105 -0
  165. package/pkgs/schema/src/fonts.ts +690 -0
  166. package/pkgs/schema/src/frame.ts +40 -0
  167. package/pkgs/schema/src/icon-name.ts +21 -0
  168. package/pkgs/schema/src/ids.ts +14 -0
  169. package/pkgs/schema/src/index.ts +169 -0
  170. package/pkgs/schema/src/migrate.ts +297 -0
  171. package/pkgs/schema/src/node.ts +229 -0
  172. package/pkgs/schema/src/paths.ts +28 -0
  173. package/pkgs/schema/src/repo.ts +134 -0
  174. package/pkgs/schema/src/screen.ts +30 -0
  175. package/pkgs/schema/src/snippet-resolve.ts +193 -0
  176. package/pkgs/schema/src/snippet.ts +104 -0
  177. package/pkgs/schema/src/svg-sanitize.ts +487 -0
  178. package/pkgs/schema/src/theme.ts +218 -0
  179. package/pkgs/schema/src/typeset.ts +693 -0
  180. package/pkgs/schema/src/validate-ids.ts +46 -0
  181. package/pkgs/schema/src/viewport.ts +8 -0
  182. package/pkgs/shadcn-snapshot/dist/manifest.json +8109 -0
  183. package/pkgs/shadcn-snapshot/src/components/canvas-portal.tsx +55 -0
  184. package/pkgs/shadcn-snapshot/src/components/ui/accordion.tsx +122 -0
  185. package/pkgs/shadcn-snapshot/src/components/ui/alert-dialog.tsx +164 -0
  186. package/pkgs/shadcn-snapshot/src/components/ui/alert.tsx +74 -0
  187. package/pkgs/shadcn-snapshot/src/components/ui/aspect-ratio.tsx +13 -0
  188. package/pkgs/shadcn-snapshot/src/components/ui/attachment.tsx +197 -0
  189. package/pkgs/shadcn-snapshot/src/components/ui/avatar.tsx +100 -0
  190. package/pkgs/shadcn-snapshot/src/components/ui/badge.tsx +50 -0
  191. package/pkgs/shadcn-snapshot/src/components/ui/breadcrumb.tsx +109 -0
  192. package/pkgs/shadcn-snapshot/src/components/ui/bubble.tsx +130 -0
  193. package/pkgs/shadcn-snapshot/src/components/ui/button-group.tsx +82 -0
  194. package/pkgs/shadcn-snapshot/src/components/ui/button.tsx +72 -0
  195. package/pkgs/shadcn-snapshot/src/components/ui/calendar.tsx +229 -0
  196. package/pkgs/shadcn-snapshot/src/components/ui/card.tsx +92 -0
  197. package/pkgs/shadcn-snapshot/src/components/ui/carousel.tsx +235 -0
  198. package/pkgs/shadcn-snapshot/src/components/ui/chart-option.ts +250 -0
  199. package/pkgs/shadcn-snapshot/src/components/ui/chart.tsx +177 -0
  200. package/pkgs/shadcn-snapshot/src/components/ui/checkbox.tsx +41 -0
  201. package/pkgs/shadcn-snapshot/src/components/ui/collapsible.tsx +32 -0
  202. package/pkgs/shadcn-snapshot/src/components/ui/combobox.tsx +196 -0
  203. package/pkgs/shadcn-snapshot/src/components/ui/context-menu.tsx +227 -0
  204. package/pkgs/shadcn-snapshot/src/components/ui/dialog.tsx +131 -0
  205. package/pkgs/shadcn-snapshot/src/components/ui/direction.tsx +24 -0
  206. package/pkgs/shadcn-snapshot/src/components/ui/drawer.tsx +112 -0
  207. package/pkgs/shadcn-snapshot/src/components/ui/dropdown-menu.tsx +205 -0
  208. package/pkgs/shadcn-snapshot/src/components/ui/empty.tsx +98 -0
  209. package/pkgs/shadcn-snapshot/src/components/ui/field.tsx +228 -0
  210. package/pkgs/shadcn-snapshot/src/components/ui/hover-card.tsx +51 -0
  211. package/pkgs/shadcn-snapshot/src/components/ui/input-group.tsx +148 -0
  212. package/pkgs/shadcn-snapshot/src/components/ui/input.tsx +43 -0
  213. package/pkgs/shadcn-snapshot/src/components/ui/item.tsx +187 -0
  214. package/pkgs/shadcn-snapshot/src/components/ui/kbd.tsx +30 -0
  215. package/pkgs/shadcn-snapshot/src/components/ui/label.tsx +25 -0
  216. package/pkgs/shadcn-snapshot/src/components/ui/marker.tsx +71 -0
  217. package/pkgs/shadcn-snapshot/src/components/ui/menubar.tsx +243 -0
  218. package/pkgs/shadcn-snapshot/src/components/ui/message.tsx +89 -0
  219. package/pkgs/shadcn-snapshot/src/components/ui/native-select.tsx +60 -0
  220. package/pkgs/shadcn-snapshot/src/components/ui/navigation-menu.tsx +165 -0
  221. package/pkgs/shadcn-snapshot/src/components/ui/pagination.tsx +117 -0
  222. package/pkgs/shadcn-snapshot/src/components/ui/popover.tsx +66 -0
  223. package/pkgs/shadcn-snapshot/src/components/ui/progress.tsx +35 -0
  224. package/pkgs/shadcn-snapshot/src/components/ui/radio-group.tsx +48 -0
  225. package/pkgs/shadcn-snapshot/src/components/ui/scroll-area.tsx +59 -0
  226. package/pkgs/shadcn-snapshot/src/components/ui/select.tsx +180 -0
  227. package/pkgs/shadcn-snapshot/src/components/ui/separator.tsx +32 -0
  228. package/pkgs/shadcn-snapshot/src/components/ui/sheet.tsx +107 -0
  229. package/pkgs/shadcn-snapshot/src/components/ui/skeleton.tsx +17 -0
  230. package/pkgs/shadcn-snapshot/src/components/ui/slider.tsx +68 -0
  231. package/pkgs/shadcn-snapshot/src/components/ui/sonner.tsx +91 -0
  232. package/pkgs/shadcn-snapshot/src/components/ui/spinner.tsx +21 -0
  233. package/pkgs/shadcn-snapshot/src/components/ui/switch.tsx +41 -0
  234. package/pkgs/shadcn-snapshot/src/components/ui/table.tsx +93 -0
  235. package/pkgs/shadcn-snapshot/src/components/ui/tabs.tsx +84 -0
  236. package/pkgs/shadcn-snapshot/src/components/ui/textarea.tsx +24 -0
  237. package/pkgs/shadcn-snapshot/src/components/ui/toggle-group.tsx +94 -0
  238. package/pkgs/shadcn-snapshot/src/components/ui/toggle.tsx +50 -0
  239. package/pkgs/shadcn-snapshot/src/components/ui/tooltip.tsx +47 -0
  240. package/pkgs/shadcn-snapshot/src/examples.ts +36 -0
  241. package/pkgs/shadcn-snapshot/src/groups.ts +87 -0
  242. package/pkgs/shadcn-snapshot/src/index.ts +43 -0
  243. package/pkgs/shadcn-snapshot/src/lib/utils.ts +4 -0
  244. package/pkgs/shadcn-snapshot/src/manifest.ts +12 -0
  245. package/pkgs/shadcn-snapshot/src/notes.ts +97 -0
  246. package/pkgs/shadcn-snapshot/src/paths.ts +47 -0
  247. package/pkgs/shadcn-snapshot/src/registry-files.ts +293 -0
  248. package/pkgs/shadcn-snapshot/src/registry.ts +631 -0
  249. package/pkgs/shadcn-snapshot/src/shadcn-tailwind.css +632 -0
  250. package/pkgs/shadcn-snapshot/src/tailwind-entry.css +159 -0
  251. package/pkgs/shadcn-snapshot/src/version.ts +8 -0
  252. package/plugins/claude/velloo/.claude-plugin/plugin.json +6 -0
  253. package/plugins/claude/velloo/agents/velloo-design-reviewer.md +33 -0
  254. package/plugins/claude/velloo/agents/velloo-designer.md +39 -0
  255. package/plugins/claude/velloo/commands/design.md +11 -0
  256. package/plugins/claude/velloo/commands/implement.md +10 -0
  257. package/plugins/claude/velloo/commands/review.md +8 -0
  258. package/plugins/gemini/GEMINI.md +31 -0
  259. package/plugins/gemini/commands/velloo/design.toml +10 -0
  260. package/plugins/gemini/commands/velloo/implement.toml +9 -0
  261. package/plugins/gemini/gemini-extension.json +9 -0
  262. package/skills/velloo-brand/SKILL.md +124 -0
  263. package/skills/velloo-design/SKILL.md +144 -0
  264. package/skills/velloo-design-system/SKILL.md +90 -0
  265. package/skills/velloo-implement/SKILL.md +101 -0
  266. package/skills/velloo-logo/SKILL.md +93 -0
  267. package/skills/velloo-setup/SKILL.md +156 -0
@@ -0,0 +1,180 @@
1
+ // Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/select).
2
+ // Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
3
+ // Canvas-safe: see ../canvas-portal.tsx. Select is the most divergent shim.
4
+ // Radix drives the trigger label and the item check mark through a context
5
+ // that Portal/Content set up, so once the popup renders inline that channel is
6
+ // dead — the label is authored on `SelectValue` and the check on `SelectItem`'s
7
+ // `selected`, which also puts both under inspector control. Classes track
8
+ // upstream minus the ones keyed to Radix's runtime vars
9
+ // (`--radix-select-*`) or to the open animation, which would fire on every
10
+ // render and leave screenshots catching a mid-transition frame.
11
+ "use client";
12
+
13
+ import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
14
+ import { Select as SelectPrimitive } from "radix-ui";
15
+ import type * as React from "react";
16
+ import { cn } from "../../lib/utils.ts";
17
+ import { inlineOpenAttrs, pinOpenInDesignMode } from "../canvas-portal.tsx";
18
+
19
+ const SCROLL_BUTTON =
20
+ "z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4";
21
+
22
+ export function Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>) {
23
+ return <SelectPrimitive.Root data-slot="select" {...pinOpenInDesignMode(props)} />;
24
+ }
25
+
26
+ /**
27
+ * A plain button, not `SelectPrimitive.Trigger`: the rest of this file already
28
+ * bypasses Radix (Content, Item and Value are inline elements), so the root's
29
+ * context has nothing left to give a trigger — while Radix's own trigger
30
+ * *throws* when it can't find that context. Designs compose nodes freely, so a
31
+ * trigger sitting on its own under a Box is a shape the canvas has to render,
32
+ * not a crash that takes the whole screen down with it.
33
+ */
34
+ export function SelectTrigger({
35
+ className,
36
+ size = "default",
37
+ children,
38
+ ...props
39
+ }: React.ComponentProps<"button"> & {
40
+ size?: "sm" | "default";
41
+ }) {
42
+ return (
43
+ <button
44
+ type="button"
45
+ data-slot="select-trigger"
46
+ data-size={size}
47
+ className={cn(
48
+ "flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
49
+ className,
50
+ )}
51
+ {...props}
52
+ >
53
+ {children}
54
+ <ChevronDownIcon className="pointer-events-none size-4 text-muted-foreground" />
55
+ </button>
56
+ );
57
+ }
58
+
59
+ /**
60
+ * Static value display. Radix reads the label off the selected item, which
61
+ * only exists inside the portal it owns; design mode renders whatever the
62
+ * user typed so the trigger reads "Pro plan" next to the chevron. Pass
63
+ * `placeholder` alone for the empty state — it takes upstream's muted styling
64
+ * here rather than through the trigger's `data-placeholder`.
65
+ */
66
+ export function SelectValue({
67
+ className,
68
+ placeholder,
69
+ children,
70
+ ...props
71
+ }: React.ComponentProps<"span"> & { placeholder?: string }) {
72
+ return (
73
+ <span
74
+ data-slot="select-value"
75
+ className={children === undefined ? cn("text-muted-foreground", className) : className}
76
+ {...props}
77
+ >
78
+ {children ?? placeholder ?? ""}
79
+ </span>
80
+ );
81
+ }
82
+
83
+ export function SelectContent({
84
+ className,
85
+ position: _position,
86
+ align: _align,
87
+ side: _side,
88
+ sideOffset: _sideOffset,
89
+ collisionPadding: _collisionPadding,
90
+ ...props
91
+ }: React.ComponentProps<"div"> & {
92
+ position?: "popper" | "item-aligned";
93
+ align?: string;
94
+ side?: string;
95
+ sideOffset?: number;
96
+ collisionPadding?: number;
97
+ }) {
98
+ return (
99
+ <div
100
+ data-slot="select-content"
101
+ {...inlineOpenAttrs()}
102
+ className={cn(
103
+ "cn-menu-target cn-menu-translucent relative z-50 min-w-36 overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10",
104
+ className,
105
+ )}
106
+ {...props}
107
+ />
108
+ );
109
+ }
110
+
111
+ export function SelectGroup({ className, ...props }: React.ComponentProps<"div">) {
112
+ return <div data-slot="select-group" className={cn("scroll-my-1 p-1", className)} {...props} />;
113
+ }
114
+
115
+ export function SelectLabel({ className, ...props }: React.ComponentProps<"div">) {
116
+ return (
117
+ <div
118
+ data-slot="select-label"
119
+ className={cn("px-1.5 py-1 text-xs text-muted-foreground", className)}
120
+ {...props}
121
+ />
122
+ );
123
+ }
124
+
125
+ export function SelectItem({
126
+ className,
127
+ children,
128
+ value,
129
+ selected,
130
+ ...props
131
+ }: React.ComponentProps<"div"> & { value?: string; selected?: boolean }) {
132
+ return (
133
+ <div
134
+ data-slot="select-item"
135
+ data-value={value}
136
+ data-state={selected ? "checked" : "unchecked"}
137
+ className={cn(
138
+ "relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
139
+ className,
140
+ )}
141
+ {...props}
142
+ >
143
+ <span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center">
144
+ {selected ? <CheckIcon className="pointer-events-none" /> : null}
145
+ </span>
146
+ <span>{children}</span>
147
+ </div>
148
+ );
149
+ }
150
+
151
+ export function SelectSeparator({ className, ...props }: React.ComponentProps<"div">) {
152
+ return (
153
+ <div
154
+ data-slot="select-separator"
155
+ className={cn("pointer-events-none -mx-1 my-1 h-px bg-border", className)}
156
+ {...props}
157
+ />
158
+ );
159
+ }
160
+
161
+ /**
162
+ * Upstream renders both scroll buttons inside Content and lets Radix hide them
163
+ * until the list actually overflows. A static render can't measure that, so
164
+ * they stay opt-in children rather than always-on chrome.
165
+ */
166
+ export function SelectScrollUpButton({ className, ...props }: React.ComponentProps<"div">) {
167
+ return (
168
+ <div data-slot="select-scroll-up-button" className={cn(SCROLL_BUTTON, className)} {...props}>
169
+ <ChevronUpIcon />
170
+ </div>
171
+ );
172
+ }
173
+
174
+ export function SelectScrollDownButton({ className, ...props }: React.ComponentProps<"div">) {
175
+ return (
176
+ <div data-slot="select-scroll-down-button" className={cn(SCROLL_BUTTON, className)} {...props}>
177
+ <ChevronDownIcon />
178
+ </div>
179
+ );
180
+ }
@@ -0,0 +1,32 @@
1
+ // Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/separator).
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 { Separator as SeparatorPrimitive } from "radix-ui";
8
+ import type * as React from "react";
9
+
10
+ import { cn } from "../../lib/utils.ts";
11
+
12
+ function Separator({
13
+ className,
14
+ orientation = "horizontal",
15
+ decorative = true,
16
+ ...props
17
+ }: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
18
+ return (
19
+ <SeparatorPrimitive.Root
20
+ data-slot="separator"
21
+ decorative={decorative}
22
+ orientation={orientation}
23
+ className={cn(
24
+ "shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
25
+ className,
26
+ )}
27
+ {...props}
28
+ />
29
+ );
30
+ }
31
+
32
+ export { Separator };
@@ -0,0 +1,107 @@
1
+ // Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/sheet).
2
+ // Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
3
+ // Canvas-safe: see ../canvas-portal.tsx. Content is a plain panel in the page
4
+ // flow, so upstream's viewport-edge anchoring goes away while `data-side` keeps
5
+ // driving the per-side size and border — a fixed panel would pin itself to the
6
+ // canvas viewport instead of the frame it belongs to. The close button is a
7
+ // plain Button rather than Radix Close, so a Content placed on the canvas
8
+ // without its Root still renders. Classes track upstream minus the slide/fade
9
+ // transitions: we pin `data-state="open"`, so those would replay on every
10
+ // render and screenshots would catch a mid-transition frame.
11
+ "use client";
12
+
13
+ import { XIcon } from "lucide-react";
14
+ import { Dialog as SheetPrimitive } from "radix-ui";
15
+ import type * as React from "react";
16
+ import { cn } from "../../lib/utils.ts";
17
+ import { inlineOpenAttrs, pinOpenInDesignMode } from "../canvas-portal.tsx";
18
+ import { Button } from "./button.tsx";
19
+
20
+ export function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
21
+ return <SheetPrimitive.Root data-slot="sheet" {...pinOpenInDesignMode(props)} />;
22
+ }
23
+
24
+ export function SheetTrigger({ ...props }: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
25
+ return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />;
26
+ }
27
+
28
+ export function SheetClose({ ...props }: React.ComponentProps<typeof SheetPrimitive.Close>) {
29
+ return <SheetPrimitive.Close data-slot="sheet-close" {...props} />;
30
+ }
31
+
32
+ export function SheetContent({
33
+ className,
34
+ children,
35
+ side = "right",
36
+ showCloseButton = true,
37
+ ...props
38
+ }: React.ComponentProps<"div"> & {
39
+ side?: "top" | "right" | "bottom" | "left";
40
+ showCloseButton?: boolean;
41
+ }) {
42
+ return (
43
+ <div
44
+ data-slot="sheet-content"
45
+ data-side={side}
46
+ {...inlineOpenAttrs()}
47
+ className={cn(
48
+ "relative z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",
49
+ className,
50
+ )}
51
+ {...props}
52
+ >
53
+ {children}
54
+ {showCloseButton && (
55
+ <Button
56
+ data-slot="sheet-close"
57
+ variant="ghost"
58
+ className="absolute top-3 right-3"
59
+ size="icon-sm"
60
+ >
61
+ <XIcon />
62
+ <span className="sr-only">Close</span>
63
+ </Button>
64
+ )}
65
+ </div>
66
+ );
67
+ }
68
+
69
+ export function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
70
+ return (
71
+ <div
72
+ data-slot="sheet-header"
73
+ className={cn("flex flex-col gap-0.5 p-4", className)}
74
+ {...props}
75
+ />
76
+ );
77
+ }
78
+
79
+ export function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
80
+ return (
81
+ <div
82
+ data-slot="sheet-footer"
83
+ className={cn("mt-auto flex flex-col gap-2 p-4", className)}
84
+ {...props}
85
+ />
86
+ );
87
+ }
88
+
89
+ export function SheetTitle({ className, ...props }: React.ComponentProps<"h2">) {
90
+ return (
91
+ <h2
92
+ data-slot="sheet-title"
93
+ className={cn("cn-font-heading text-base font-medium text-foreground", className)}
94
+ {...props}
95
+ />
96
+ );
97
+ }
98
+
99
+ export function SheetDescription({ className, ...props }: React.ComponentProps<"p">) {
100
+ return (
101
+ <p
102
+ data-slot="sheet-description"
103
+ className={cn("text-sm text-muted-foreground", className)}
104
+ {...props}
105
+ />
106
+ );
107
+ }
@@ -0,0 +1,17 @@
1
+ // Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/skeleton).
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
+ import { cn } from "../../lib/utils.ts";
6
+
7
+ function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
8
+ return (
9
+ <div
10
+ data-slot="skeleton"
11
+ className={cn("animate-pulse rounded-md bg-muted", className)}
12
+ {...props}
13
+ />
14
+ );
15
+ }
16
+
17
+ export { Skeleton };
@@ -0,0 +1,68 @@
1
+ // Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/slider).
2
+ // Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
3
+ // Canvas-safe: a design ships `value` to position the thumb, with no handler
4
+ // because nothing on the canvas is interactive. Radix would pin the thumb and
5
+ // React would warn about the missing handler, so a handlerless `value` becomes
6
+ // `defaultValue`.
7
+ "use client";
8
+
9
+ import { Slider as SliderPrimitive } from "radix-ui";
10
+ import * as React from "react";
11
+
12
+ import { cn } from "../../lib/utils.ts";
13
+
14
+ export function Slider({
15
+ className,
16
+ defaultValue,
17
+ value,
18
+ min = 0,
19
+ max = 100,
20
+ ...props
21
+ }: React.ComponentProps<typeof SliderPrimitive.Root>) {
22
+ const isStaticControlled = value !== undefined && props.onValueChange === undefined;
23
+ // Only the keys that are actually set — an explicit `value: undefined` reads
24
+ // to Radix as a controlled slider with no value, which is not what "unset"
25
+ // means.
26
+ const resolved: { value?: typeof value; defaultValue?: typeof defaultValue } = isStaticControlled
27
+ ? { defaultValue: value }
28
+ : {
29
+ ...(value === undefined ? {} : { value }),
30
+ ...(defaultValue === undefined ? {} : { defaultValue }),
31
+ };
32
+
33
+ const _values = React.useMemo(
34
+ () => (Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max]),
35
+ [value, defaultValue, min, max],
36
+ );
37
+
38
+ return (
39
+ <SliderPrimitive.Root
40
+ data-slot="slider"
41
+ {...resolved}
42
+ min={min}
43
+ max={max}
44
+ className={cn(
45
+ "relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:min-h-40 data-vertical:w-auto data-vertical:flex-col",
46
+ className,
47
+ )}
48
+ {...props}
49
+ >
50
+ <SliderPrimitive.Track
51
+ data-slot="slider-track"
52
+ className="relative grow overflow-hidden rounded-full bg-muted data-horizontal:h-1 data-horizontal:w-full data-vertical:h-full data-vertical:w-1"
53
+ >
54
+ <SliderPrimitive.Range
55
+ data-slot="slider-range"
56
+ className="absolute bg-primary select-none data-horizontal:h-full data-vertical:w-full"
57
+ />
58
+ </SliderPrimitive.Track>
59
+ {Array.from({ length: _values.length }, (_, index) => (
60
+ <SliderPrimitive.Thumb
61
+ data-slot="slider-thumb"
62
+ key={index}
63
+ className="relative block size-3 shrink-0 rounded-full border border-ring bg-white ring-ring/50 transition-[color,box-shadow] select-none after:absolute after:-inset-2 hover:ring-3 focus-visible:ring-3 focus-visible:outline-hidden active:ring-3 disabled:pointer-events-none disabled:opacity-50"
64
+ />
65
+ ))}
66
+ </SliderPrimitive.Root>
67
+ );
68
+ }
@@ -0,0 +1,91 @@
1
+ // Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/sonner).
2
+ // Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
3
+ //
4
+ // Canvas-safe: real apps render sonner's <Toaster />, which mounts an
5
+ // imperative queue plus a portal at the document root. Nothing calls toast()
6
+ // in design mode, so that queue only ever paints an empty region — we render a
7
+ // single sample toast pinned to the configured corner instead, so a user who
8
+ // drops a <Toaster /> onto a screen sees what it will look like at runtime.
9
+ // Upstream reads next-themes to hand sonner a theme; the canvas is already
10
+ // themed by the design folder's tokens, so the sample is painted from the same
11
+ // CSS vars upstream passes down rather than taking that dependency.
12
+ "use client";
13
+
14
+ import { CircleCheckIcon } from "lucide-react";
15
+ import type * as React from "react";
16
+ import { cn } from "../../lib/utils.ts";
17
+
18
+ export interface ToasterProps extends React.ComponentProps<"div"> {
19
+ position?:
20
+ | "top-left"
21
+ | "top-center"
22
+ | "top-right"
23
+ | "bottom-left"
24
+ | "bottom-center"
25
+ | "bottom-right";
26
+ richColors?: boolean;
27
+ expand?: boolean;
28
+ closeButton?: boolean;
29
+ theme?: "light" | "dark" | "system";
30
+ }
31
+
32
+ const POSITION_CLASS: Record<NonNullable<ToasterProps["position"]>, string> = {
33
+ "top-left": "top-4 left-4 items-start",
34
+ "top-center": "top-4 left-1/2 -translate-x-1/2 items-center",
35
+ "top-right": "top-4 right-4 items-end",
36
+ "bottom-left": "bottom-4 left-4 items-start",
37
+ "bottom-center": "bottom-4 left-1/2 -translate-x-1/2 items-center",
38
+ "bottom-right": "bottom-4 right-4 items-end",
39
+ };
40
+
41
+ const TOAST_VARS = {
42
+ "--normal-bg": "var(--popover)",
43
+ "--normal-text": "var(--popover-foreground)",
44
+ "--normal-border": "var(--border)",
45
+ "--border-radius": "var(--radius)",
46
+ } as React.CSSProperties;
47
+
48
+ const TOAST_STYLE = {
49
+ background: "var(--normal-bg)",
50
+ color: "var(--normal-text)",
51
+ borderColor: "var(--normal-border)",
52
+ borderRadius: "var(--border-radius)",
53
+ } as React.CSSProperties;
54
+
55
+ export function Toaster({
56
+ className,
57
+ style,
58
+ position = "bottom-right",
59
+ richColors: _richColors,
60
+ expand: _expand,
61
+ closeButton: _closeButton,
62
+ theme: _theme,
63
+ ...props
64
+ }: ToasterProps) {
65
+ return (
66
+ <div
67
+ data-slot="sonner-toaster"
68
+ data-velloo-inline="true"
69
+ className={cn(
70
+ "pointer-events-none fixed z-50 flex flex-col gap-2",
71
+ POSITION_CLASS[position],
72
+ className,
73
+ )}
74
+ style={{ ...TOAST_VARS, ...style }}
75
+ {...props}
76
+ >
77
+ <div
78
+ data-slot="sonner-toast"
79
+ data-state="open"
80
+ className="pointer-events-auto flex w-80 max-w-[calc(100vw-2rem)] items-start gap-2 border p-4 text-sm shadow-lg"
81
+ style={TOAST_STYLE}
82
+ >
83
+ <CircleCheckIcon className="mt-0.5 size-4 shrink-0" aria-hidden="true" />
84
+ <div className="flex-1">
85
+ <div className="font-medium">Toast</div>
86
+ <div className="text-muted-foreground">Sample toast preview.</div>
87
+ </div>
88
+ </div>
89
+ </div>
90
+ );
91
+ }
@@ -0,0 +1,21 @@
1
+ // Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/spinner).
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
+
6
+ import { Loader2Icon } from "lucide-react";
7
+ import { cn } from "../../lib/utils.ts";
8
+
9
+ function Spinner({ className, ...props }: React.ComponentProps<"svg">) {
10
+ return (
11
+ <Loader2Icon
12
+ data-slot="spinner"
13
+ role="status"
14
+ aria-label="Loading"
15
+ className={cn("size-4 animate-spin", className)}
16
+ {...props}
17
+ />
18
+ );
19
+ }
20
+
21
+ export { Spinner };
@@ -0,0 +1,41 @@
1
+ // Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/switch).
2
+ // Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
3
+ // Canvas-safe: same contract as Checkbox — a design ships `checked` to show an
4
+ // on state with no handler to change it, so it becomes `defaultChecked` rather
5
+ // than a controlled switch React warns about.
6
+ "use client";
7
+
8
+ import { Switch as SwitchPrimitive } from "radix-ui";
9
+ import type * as React from "react";
10
+
11
+ import { cn } from "../../lib/utils.ts";
12
+
13
+ export function Switch({
14
+ className,
15
+ size = "default",
16
+ ...props
17
+ }: React.ComponentProps<typeof SwitchPrimitive.Root> & {
18
+ size?: "sm" | "default";
19
+ }) {
20
+ const { checked, ...rest } = props;
21
+ const isStaticControlled = checked !== undefined && props.onCheckedChange === undefined;
22
+ // Drop `checked` by omitting it, not by setting it to undefined: Radix reads
23
+ // "present but undefined" as a controlled component with no value.
24
+ const finalProps = isStaticControlled ? { ...rest, defaultChecked: checked } : props;
25
+ return (
26
+ <SwitchPrimitive.Root
27
+ data-slot="switch"
28
+ data-size={size}
29
+ className={cn(
30
+ "peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none group-has-[:focus-visible]/field-label:border-transparent group-has-[:focus-visible]/field-label:ring-0 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50",
31
+ className,
32
+ )}
33
+ {...finalProps}
34
+ >
35
+ <SwitchPrimitive.Thumb
36
+ data-slot="switch-thumb"
37
+ className="pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-unchecked:bg-foreground"
38
+ />
39
+ </SwitchPrimitive.Root>
40
+ );
41
+ }
@@ -0,0 +1,93 @@
1
+ // Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/table).
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 type * as React from "react";
8
+
9
+ import { cn } from "../../lib/utils.ts";
10
+
11
+ function Table({ className, ...props }: React.ComponentProps<"table">) {
12
+ return (
13
+ <div data-slot="table-container" className="relative w-full overflow-x-auto">
14
+ <table
15
+ data-slot="table"
16
+ className={cn("w-full caption-bottom text-sm", className)}
17
+ {...props}
18
+ />
19
+ </div>
20
+ );
21
+ }
22
+
23
+ function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
24
+ return <thead data-slot="table-header" className={cn("[&_tr]:border-b", className)} {...props} />;
25
+ }
26
+
27
+ function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
28
+ return (
29
+ <tbody
30
+ data-slot="table-body"
31
+ className={cn("[&_tr:last-child]:border-0", className)}
32
+ {...props}
33
+ />
34
+ );
35
+ }
36
+
37
+ function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
38
+ return (
39
+ <tfoot
40
+ data-slot="table-footer"
41
+ className={cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className)}
42
+ {...props}
43
+ />
44
+ );
45
+ }
46
+
47
+ function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
48
+ return (
49
+ <tr
50
+ data-slot="table-row"
51
+ className={cn(
52
+ "border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",
53
+ className,
54
+ )}
55
+ {...props}
56
+ />
57
+ );
58
+ }
59
+
60
+ function TableHead({ className, ...props }: React.ComponentProps<"th">) {
61
+ return (
62
+ <th
63
+ data-slot="table-head"
64
+ className={cn(
65
+ "h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
66
+ className,
67
+ )}
68
+ {...props}
69
+ />
70
+ );
71
+ }
72
+
73
+ function TableCell({ className, ...props }: React.ComponentProps<"td">) {
74
+ return (
75
+ <td
76
+ data-slot="table-cell"
77
+ className={cn("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0", className)}
78
+ {...props}
79
+ />
80
+ );
81
+ }
82
+
83
+ function TableCaption({ className, ...props }: React.ComponentProps<"caption">) {
84
+ return (
85
+ <caption
86
+ data-slot="table-caption"
87
+ className={cn("mt-4 text-sm text-muted-foreground", className)}
88
+ {...props}
89
+ />
90
+ );
91
+ }
92
+
93
+ export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };