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,55 @@
1
+ /**
2
+ * Canvas-safe portal contract — the heart of the adapter pattern.
3
+ *
4
+ * Radix primitives portal their "open" content to `document.body` so it
5
+ * stacks above page chrome. Inside Velloo's canvas iframes, a portal to
6
+ * the body is invisible (the iframe's body has nothing for the design
7
+ * to attach to), and any styling pinned to a transformed ancestor breaks
8
+ * the math.
9
+ *
10
+ * The Velloo contract: render the content **inline** under the
11
+ * component itself, never through a portal. We don't actually want users
12
+ * clicking the dropdown shut in design mode — they want to see the
13
+ * styled state at all times. So:
14
+ *
15
+ * <Dialog>
16
+ * <DialogTrigger>Open</DialogTrigger>
17
+ * <DialogContent>...</DialogContent> ← rendered inline, always visible
18
+ * </Dialog>
19
+ *
20
+ * Implementation:
21
+ *
22
+ * 1. The Velloo Root for each Radix-shaped component forces
23
+ * `open={true}` / `defaultOpen={true}` in design mode so Radix
24
+ * mounts Content (otherwise Content is conditional on open state).
25
+ * 2. The Velloo `Content` ditches Radix's `Portal` wrapper — it
26
+ * renders the styled card with the same data-slot attribute that
27
+ * shadcn ships, so user-app CSS still targets it normally.
28
+ *
29
+ * The user's real app imports unmodified shadcn from their own
30
+ * `components/ui/<name>.tsx` (fetched at `velloo init` from upstream)
31
+ * and gets the actual modal behavior. The canvas-only adapter is what
32
+ * lets the *canvas* render those modals inline.
33
+ *
34
+ * The snapshot stays design-mode only; the upstream provider + adapter
35
+ * layer drive real app behavior.
36
+ */
37
+ /**
38
+ * Decide whether a Radix root should pin `open=true` in design mode.
39
+ * If the consumer explicitly set `open` or `defaultOpen`, respect it.
40
+ * Otherwise pin open so Content renders.
41
+ */
42
+ export function pinOpenInDesignMode<Props extends { open?: boolean; defaultOpen?: boolean }>(
43
+ props: Props,
44
+ ): Props {
45
+ if (props.open !== undefined || props.defaultOpen !== undefined) return props;
46
+ return { ...props, open: true };
47
+ }
48
+
49
+ /**
50
+ * Helper: spread the relevant `data-state` / aria attributes onto an
51
+ * inline-rendered Content so user-app shadcn CSS still styles it.
52
+ */
53
+ export function inlineOpenAttrs(): { "data-state": "open"; "data-velloo-inline": "true" } {
54
+ return { "data-state": "open", "data-velloo-inline": "true" };
55
+ }
@@ -0,0 +1,122 @@
1
+ // Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/accordion).
2
+ // Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
3
+ // Canvas-safe: an accordion with no `value`/`defaultValue` opens itself, so a
4
+ // design that never receives a click still shows its content styling. Designs
5
+ // that set either prop keep their explicit state.
6
+ "use client";
7
+
8
+ import { ChevronDownIcon, ChevronUpIcon } from "lucide-react";
9
+ import { Accordion as AccordionPrimitive } from "radix-ui";
10
+ import type * as React from "react";
11
+ import { Children, isValidElement, type ReactNode } from "react";
12
+
13
+ import { cn } from "../../lib/utils.ts";
14
+
15
+ function itemValues(children: ReactNode): string[] {
16
+ const values: string[] = [];
17
+ for (const child of Children.toArray(children)) {
18
+ if (!isValidElement<{ value?: unknown }>(child)) continue;
19
+ const { value } = child.props;
20
+ if (typeof value === "string") values.push(value);
21
+ }
22
+ return values;
23
+ }
24
+
25
+ /**
26
+ * Radix's `type: "single" | "multiple"` discriminates the whole props union —
27
+ * `value` changes shape with it — which is user-hostile to thread through MCP.
28
+ * The wrapper takes a permissive passthrough instead: a design-mode accordion
29
+ * only has to render.
30
+ */
31
+ // biome-ignore lint/suspicious/noExplicitAny: discriminated radix props are user-hostile in design mode
32
+ export function Accordion({ className, type, ...props }: any) {
33
+ const classes = cn("flex w-full flex-col", className);
34
+ const resolvedType = type === "multiple" ? "multiple" : "single";
35
+
36
+ // Nothing on the canvas is clickable, so an accordion left in its initial
37
+ // state would show every item collapsed and none of the content styling. Open
38
+ // what the type allows — every item when multiple, the first when single.
39
+ const values = props.value || props.defaultValue ? undefined : itemValues(props.children);
40
+ const defaultValue =
41
+ values === undefined || values.length === 0
42
+ ? undefined
43
+ : resolvedType === "multiple"
44
+ ? values
45
+ : values[0];
46
+
47
+ return (
48
+ <AccordionPrimitive.Root
49
+ type={resolvedType}
50
+ {...(resolvedType === "single" ? { collapsible: true } : {})}
51
+ data-slot="accordion"
52
+ className={classes}
53
+ {...props}
54
+ {...(defaultValue === undefined ? {} : { defaultValue })}
55
+ />
56
+ );
57
+ }
58
+
59
+ export function AccordionItem({
60
+ className,
61
+ ...props
62
+ }: React.ComponentProps<typeof AccordionPrimitive.Item>) {
63
+ return (
64
+ <AccordionPrimitive.Item
65
+ data-slot="accordion-item"
66
+ className={cn("not-last:border-b", className)}
67
+ {...props}
68
+ />
69
+ );
70
+ }
71
+
72
+ export function AccordionTrigger({
73
+ className,
74
+ children,
75
+ ...props
76
+ }: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {
77
+ return (
78
+ <AccordionPrimitive.Header className="flex">
79
+ <AccordionPrimitive.Trigger
80
+ data-slot="accordion-trigger"
81
+ className={cn(
82
+ "group/accordion-trigger relative flex flex-1 items-start justify-between rounded-lg border border-transparent py-2.5 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:after:border-ring disabled:pointer-events-none disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground",
83
+ className,
84
+ )}
85
+ {...props}
86
+ >
87
+ {children}
88
+ <ChevronDownIcon
89
+ data-slot="accordion-trigger-icon"
90
+ className="pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden"
91
+ />
92
+ <ChevronUpIcon
93
+ data-slot="accordion-trigger-icon"
94
+ className="pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline"
95
+ />
96
+ </AccordionPrimitive.Trigger>
97
+ </AccordionPrimitive.Header>
98
+ );
99
+ }
100
+
101
+ export function AccordionContent({
102
+ className,
103
+ children,
104
+ ...props
105
+ }: React.ComponentProps<typeof AccordionPrimitive.Content>) {
106
+ return (
107
+ <AccordionPrimitive.Content
108
+ data-slot="accordion-content"
109
+ className="overflow-hidden text-sm data-open:animate-accordion-down data-closed:animate-accordion-up"
110
+ {...props}
111
+ >
112
+ <div
113
+ className={cn(
114
+ "h-(--radix-accordion-content-height) pt-0 pb-2.5 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4",
115
+ className,
116
+ )}
117
+ >
118
+ {children}
119
+ </div>
120
+ </AccordionPrimitive.Content>
121
+ );
122
+ }
@@ -0,0 +1,164 @@
1
+ // Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/alert-dialog).
2
+ // Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
3
+ // Canvas-safe: see ../canvas-portal.tsx. Content is a plain card in the page
4
+ // flow — not a portaled, viewport-centered layer — and it doesn't pull the
5
+ // Overlay in with it, because a full-bleed backdrop would dim the whole design
6
+ // surface. Action/Cancel render the Button directly instead of wrapping a Radix
7
+ // primitive, so a Content placed on the canvas without its Root still renders.
8
+ // Classes track upstream minus the open/close animations: we pin
9
+ // `data-state="open"`, so those would replay on every render and screenshots
10
+ // would catch a mid-transition frame.
11
+ "use client";
12
+
13
+ import { AlertDialog as AlertDialogPrimitive } from "radix-ui";
14
+ import type * as React from "react";
15
+ import { cn } from "../../lib/utils.ts";
16
+ import { inlineOpenAttrs, pinOpenInDesignMode } from "../canvas-portal.tsx";
17
+ import { Button } from "./button.tsx";
18
+
19
+ export function AlertDialog({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {
20
+ return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...pinOpenInDesignMode(props)} />;
21
+ }
22
+
23
+ export function AlertDialogTrigger({
24
+ ...props
25
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {
26
+ return <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />;
27
+ }
28
+
29
+ /** Upstream's Portal, neutralized: children render where they sit. */
30
+ export function AlertDialogPortal({ children }: React.ComponentProps<"div">) {
31
+ return <>{children}</>;
32
+ }
33
+
34
+ export function AlertDialogOverlay({ className, ...props }: React.ComponentProps<"div">) {
35
+ return (
36
+ <div
37
+ data-slot="alert-dialog-overlay"
38
+ {...inlineOpenAttrs()}
39
+ className={cn(
40
+ "fixed inset-0 z-50 bg-black/10 supports-backdrop-filter:backdrop-blur-xs",
41
+ className,
42
+ )}
43
+ {...props}
44
+ />
45
+ );
46
+ }
47
+
48
+ export function AlertDialogContent({
49
+ className,
50
+ size = "default",
51
+ ...props
52
+ }: React.ComponentProps<"div"> & { size?: "default" | "sm" }) {
53
+ return (
54
+ <div
55
+ data-slot="alert-dialog-content"
56
+ data-size={size}
57
+ {...inlineOpenAttrs()}
58
+ className={cn(
59
+ "group/alert-dialog-content z-50 grid w-full gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm",
60
+ className,
61
+ )}
62
+ {...props}
63
+ />
64
+ );
65
+ }
66
+
67
+ export function AlertDialogHeader({ className, ...props }: React.ComponentProps<"div">) {
68
+ return (
69
+ <div
70
+ data-slot="alert-dialog-header"
71
+ className={cn(
72
+ "grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]",
73
+ className,
74
+ )}
75
+ {...props}
76
+ />
77
+ );
78
+ }
79
+
80
+ export function AlertDialogFooter({ className, ...props }: React.ComponentProps<"div">) {
81
+ return (
82
+ <div
83
+ data-slot="alert-dialog-footer"
84
+ className={cn(
85
+ "-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end",
86
+ className,
87
+ )}
88
+ {...props}
89
+ />
90
+ );
91
+ }
92
+
93
+ export function AlertDialogMedia({ className, ...props }: React.ComponentProps<"div">) {
94
+ return (
95
+ <div
96
+ data-slot="alert-dialog-media"
97
+ className={cn(
98
+ "mb-2 inline-flex size-10 items-center justify-center rounded-md bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-6",
99
+ className,
100
+ )}
101
+ {...props}
102
+ />
103
+ );
104
+ }
105
+
106
+ export function AlertDialogTitle({ className, ...props }: React.ComponentProps<"h2">) {
107
+ return (
108
+ <h2
109
+ data-slot="alert-dialog-title"
110
+ className={cn(
111
+ "cn-font-heading text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",
112
+ className,
113
+ )}
114
+ {...props}
115
+ />
116
+ );
117
+ }
118
+
119
+ export function AlertDialogDescription({ className, ...props }: React.ComponentProps<"p">) {
120
+ return (
121
+ <p
122
+ data-slot="alert-dialog-description"
123
+ className={cn(
124
+ "text-sm text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
125
+ className,
126
+ )}
127
+ {...props}
128
+ />
129
+ );
130
+ }
131
+
132
+ export function AlertDialogAction({
133
+ className,
134
+ variant = "default",
135
+ size = "default",
136
+ ...props
137
+ }: React.ComponentProps<"button"> & Pick<React.ComponentProps<typeof Button>, "variant" | "size">) {
138
+ return (
139
+ <Button
140
+ data-slot="alert-dialog-action"
141
+ variant={variant}
142
+ size={size}
143
+ className={cn(className)}
144
+ {...props}
145
+ />
146
+ );
147
+ }
148
+
149
+ export function AlertDialogCancel({
150
+ className,
151
+ variant = "outline",
152
+ size = "default",
153
+ ...props
154
+ }: React.ComponentProps<"button"> & Pick<React.ComponentProps<typeof Button>, "variant" | "size">) {
155
+ return (
156
+ <Button
157
+ data-slot="alert-dialog-cancel"
158
+ variant={variant}
159
+ size={size}
160
+ className={cn(className)}
161
+ {...props}
162
+ />
163
+ );
164
+ }
@@ -0,0 +1,74 @@
1
+ // Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/alert).
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 { cva, type VariantProps } from "class-variance-authority";
7
+ import type * as React from "react";
8
+
9
+ import { cn } from "../../lib/utils.ts";
10
+
11
+ const alertVariants = cva(
12
+ "group/alert relative grid w-full gap-0.5 rounded-lg border px-2.5 py-2 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4",
13
+ {
14
+ variants: {
15
+ variant: {
16
+ default: "bg-card text-card-foreground",
17
+ destructive:
18
+ "bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current",
19
+ },
20
+ },
21
+ defaultVariants: {
22
+ variant: "default",
23
+ },
24
+ },
25
+ );
26
+
27
+ function Alert({
28
+ className,
29
+ variant,
30
+ ...props
31
+ }: React.ComponentProps<"div"> & VariantProps<typeof alertVariants>) {
32
+ return (
33
+ <div
34
+ data-slot="alert"
35
+ role="alert"
36
+ className={cn(alertVariants({ variant }), className)}
37
+ {...props}
38
+ />
39
+ );
40
+ }
41
+
42
+ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
43
+ return (
44
+ <div
45
+ data-slot="alert-title"
46
+ className={cn(
47
+ "font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground",
48
+ className,
49
+ )}
50
+ {...props}
51
+ />
52
+ );
53
+ }
54
+
55
+ function AlertDescription({ className, ...props }: React.ComponentProps<"div">) {
56
+ return (
57
+ <div
58
+ data-slot="alert-description"
59
+ className={cn(
60
+ "text-sm text-balance text-muted-foreground md:text-pretty [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4",
61
+ className,
62
+ )}
63
+ {...props}
64
+ />
65
+ );
66
+ }
67
+
68
+ function AlertAction({ className, ...props }: React.ComponentProps<"div">) {
69
+ return (
70
+ <div data-slot="alert-action" className={cn("absolute top-2 right-2", className)} {...props} />
71
+ );
72
+ }
73
+
74
+ export { Alert, AlertAction, AlertDescription, AlertTitle };
@@ -0,0 +1,13 @@
1
+ // Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/aspect-ratio).
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 { AspectRatio as AspectRatioPrimitive } from "radix-ui";
8
+
9
+ function AspectRatio({ ...props }: React.ComponentProps<typeof AspectRatioPrimitive.Root>) {
10
+ return <AspectRatioPrimitive.Root data-slot="aspect-ratio" {...props} />;
11
+ }
12
+
13
+ export { AspectRatio };
@@ -0,0 +1,197 @@
1
+ // Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/attachment).
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 { cva, type VariantProps } from "class-variance-authority";
7
+ import { Slot } from "radix-ui";
8
+ import type * as React from "react";
9
+
10
+ import { cn } from "../../lib/utils.ts";
11
+ import { Button } from "./button.tsx";
12
+
13
+ const attachmentVariants = cva(
14
+ "group/attachment relative flex w-fit max-w-full min-w-0 shrink-0 flex-wrap rounded-xl border bg-card text-card-foreground transition-colors focus-within:ring-1 focus-within:ring-ring/50 has-[>a,>button]:hover:bg-muted/50 data-[state=error]:border-destructive/30 data-[state=idle]:border-dashed",
15
+ {
16
+ variants: {
17
+ size: {
18
+ default:
19
+ "gap-2 text-sm has-data-[slot=attachment-content]:px-2.5 has-data-[slot=attachment-content]:py-2 has-data-[slot=attachment-media]:p-2",
20
+ sm: "gap-2.5 text-xs has-data-[slot=attachment-content]:px-2 has-data-[slot=attachment-content]:py-1.5 has-data-[slot=attachment-media]:p-1.5",
21
+ xs: "gap-1.5 rounded-lg text-xs has-data-[slot=attachment-content]:px-1.5 has-data-[slot=attachment-content]:py-1 has-data-[slot=attachment-media]:p-1",
22
+ },
23
+ orientation: {
24
+ horizontal: "min-w-40 items-center",
25
+ vertical: "w-24 flex-col has-data-[slot=attachment-content]:w-30",
26
+ },
27
+ },
28
+ },
29
+ );
30
+
31
+ function Attachment({
32
+ className,
33
+ state = "done",
34
+ size = "default",
35
+ orientation = "horizontal",
36
+ ...props
37
+ }: React.ComponentProps<"div"> &
38
+ VariantProps<typeof attachmentVariants> & {
39
+ state?: "idle" | "uploading" | "processing" | "error" | "done";
40
+ }) {
41
+ return (
42
+ <div
43
+ data-slot="attachment"
44
+ data-state={state}
45
+ data-size={size}
46
+ data-orientation={orientation}
47
+ className={cn(attachmentVariants({ size, orientation }), className)}
48
+ {...props}
49
+ />
50
+ );
51
+ }
52
+
53
+ const attachmentMediaVariants = cva(
54
+ "relative flex aspect-square w-10 shrink-0 items-center justify-center overflow-hidden rounded-lg bg-muted text-foreground group-data-[orientation=vertical]/attachment:w-full group-data-[size=sm]/attachment:w-8 group-data-[size=xs]/attachment:w-7 group-data-[size=xs]/attachment:rounded-md group-data-[state=error]/attachment:bg-destructive/10 group-data-[state=error]/attachment:text-destructive group-data-[orientation=vertical]/attachment:*:data-[slot=spinner]:size-6! [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 group-data-[orientation=vertical]/attachment:[&_svg:not([class*='size-'])]:size-6 group-data-[size=xs]/attachment:[&_svg:not([class*='size-'])]:size-3.5",
55
+ {
56
+ variants: {
57
+ variant: {
58
+ icon: "",
59
+ image:
60
+ "opacity-60 group-data-[state=done]/attachment:opacity-100 group-data-[state=idle]/attachment:opacity-100 *:[img]:aspect-square *:[img]:w-full *:[img]:object-cover",
61
+ },
62
+ },
63
+ defaultVariants: {
64
+ variant: "icon",
65
+ },
66
+ },
67
+ );
68
+
69
+ function AttachmentMedia({
70
+ className,
71
+ variant = "icon",
72
+ ...props
73
+ }: React.ComponentProps<"div"> & VariantProps<typeof attachmentMediaVariants>) {
74
+ return (
75
+ <div
76
+ data-slot="attachment-media"
77
+ data-variant={variant}
78
+ className={cn(attachmentMediaVariants({ variant }), className)}
79
+ {...props}
80
+ />
81
+ );
82
+ }
83
+
84
+ function AttachmentContent({ className, ...props }: React.ComponentProps<"div">) {
85
+ return (
86
+ <div
87
+ data-slot="attachment-content"
88
+ className={cn(
89
+ "max-w-full min-w-0 flex-1 leading-tight group-data-[orientation=vertical]/attachment:px-1",
90
+ className,
91
+ )}
92
+ {...props}
93
+ />
94
+ );
95
+ }
96
+
97
+ function AttachmentTitle({ className, ...props }: React.ComponentProps<"span">) {
98
+ return (
99
+ <span
100
+ data-slot="attachment-title"
101
+ className={cn(
102
+ "block max-w-full min-w-0 truncate font-medium group-data-[state=processing]/attachment:shimmer group-data-[state=uploading]/attachment:shimmer",
103
+ className,
104
+ )}
105
+ {...props}
106
+ />
107
+ );
108
+ }
109
+
110
+ function AttachmentDescription({ className, ...props }: React.ComponentProps<"span">) {
111
+ return (
112
+ <span
113
+ data-slot="attachment-description"
114
+ className={cn(
115
+ "mt-0.5 block min-w-0 truncate text-xs text-muted-foreground group-data-[state=error]/attachment:text-destructive/80",
116
+ "max-w-full",
117
+ className,
118
+ )}
119
+ {...props}
120
+ />
121
+ );
122
+ }
123
+
124
+ function AttachmentActions({ className, ...props }: React.ComponentProps<"div">) {
125
+ return (
126
+ <div
127
+ data-slot="attachment-actions"
128
+ className={cn(
129
+ "relative z-20 flex shrink-0 items-center group-data-[orientation=vertical]/attachment:absolute group-data-[orientation=vertical]/attachment:top-3 group-data-[orientation=vertical]/attachment:right-3 group-data-[orientation=vertical]/attachment:gap-1",
130
+ className,
131
+ )}
132
+ {...props}
133
+ />
134
+ );
135
+ }
136
+
137
+ function AttachmentAction({
138
+ className,
139
+ variant,
140
+ size = "icon-xs",
141
+ ...props
142
+ }: React.ComponentProps<typeof Button>) {
143
+ return (
144
+ <Button
145
+ data-slot="attachment-action"
146
+ variant={variant ?? "ghost"}
147
+ size={size}
148
+ className={cn(className)}
149
+ {...props}
150
+ />
151
+ );
152
+ }
153
+
154
+ function AttachmentTrigger({
155
+ className,
156
+ asChild = false,
157
+ type,
158
+ ...props
159
+ }: React.ComponentProps<"button"> & {
160
+ asChild?: boolean;
161
+ }) {
162
+ const Comp = asChild ? Slot.Root : "button";
163
+
164
+ return (
165
+ <Comp
166
+ data-slot="attachment-trigger"
167
+ type={asChild ? undefined : (type ?? "button")}
168
+ className={cn("absolute inset-0 z-10 outline-none", className)}
169
+ {...props}
170
+ />
171
+ );
172
+ }
173
+
174
+ function AttachmentGroup({ className, ...props }: React.ComponentProps<"div">) {
175
+ return (
176
+ <div
177
+ data-slot="attachment-group"
178
+ className={cn(
179
+ "flex min-w-0 scroll-fade-x snap-x snap-mandatory scroll-px-1 scrollbar-none gap-3 overflow-x-auto overscroll-x-contain py-1 *:data-[slot=attachment]:flex-none *:data-[slot=attachment]:snap-start",
180
+ className,
181
+ )}
182
+ {...props}
183
+ />
184
+ );
185
+ }
186
+
187
+ export {
188
+ Attachment,
189
+ AttachmentAction,
190
+ AttachmentActions,
191
+ AttachmentContent,
192
+ AttachmentDescription,
193
+ AttachmentGroup,
194
+ AttachmentMedia,
195
+ AttachmentTitle,
196
+ AttachmentTrigger,
197
+ };