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,176 @@
|
|
|
1
|
+
import type { MenuProps } from "antd";
|
|
2
|
+
import { Card as AntCard, Menu as AntMenu } from "antd";
|
|
3
|
+
import {
|
|
4
|
+
type CSSProperties,
|
|
5
|
+
createElement,
|
|
6
|
+
Fragment,
|
|
7
|
+
type ReactElement,
|
|
8
|
+
type ReactNode,
|
|
9
|
+
} from "react";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Canvas-safe antd overlays. antd's Modal/Drawer/Popover/Tooltip/Dropdown
|
|
13
|
+
* portal to `document.body` and, in SSR, render nothing at all (rc-util's
|
|
14
|
+
* Portal is client-only — verified: `open` overlays SSR to an empty string).
|
|
15
|
+
* In design mode we want them rendered **open + inline** (in normal flow, no
|
|
16
|
+
* escaping portal, no fixed backdrop) so a screenshot shows their surface.
|
|
17
|
+
* These shims render the overlay's *content* on an inline antd Card surface;
|
|
18
|
+
* the open/anchor/transition machinery is dropped. Trigger-wrapping overlays
|
|
19
|
+
* (Popover/Tooltip/Dropdown) render their child trigger inline, followed by
|
|
20
|
+
* the pinned-open surface.
|
|
21
|
+
*
|
|
22
|
+
* Mirrors the MUI adapter's `overlays.ts` and the shadcn snapshot's
|
|
23
|
+
* pinned-open overlay stance.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
type Props = Record<string, unknown> & { children?: ReactNode };
|
|
27
|
+
|
|
28
|
+
/** Pass-through props every node carries — className for styling, data-node-path for canvas selection. */
|
|
29
|
+
function chrome(props: Props): { className?: string; "data-node-path"?: string } {
|
|
30
|
+
// Only the keys that are actually present: the return type says these may be
|
|
31
|
+
// *absent*, and under `exactOptionalPropertyTypes` an explicit `undefined` is
|
|
32
|
+
// a different thing from an omitted key.
|
|
33
|
+
const className = typeof props.className === "string" ? props.className : undefined;
|
|
34
|
+
const nodePath = props["data-node-path"];
|
|
35
|
+
return {
|
|
36
|
+
...(className !== undefined ? { className } : {}),
|
|
37
|
+
...(typeof nodePath === "string" ? { "data-node-path": nodePath } : {}),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Merge the node's authored `style` (this provider's style channel) over the shim's base. */
|
|
42
|
+
function mergeStyle(baseStyle: CSSProperties, style: unknown): CSSProperties {
|
|
43
|
+
return style && typeof style === "object" && !Array.isArray(style)
|
|
44
|
+
? { ...baseStyle, ...(style as CSSProperties) }
|
|
45
|
+
: baseStyle;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const SURFACE_SHADOW = "0 6px 16px rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12)";
|
|
49
|
+
|
|
50
|
+
/** The modal surface, rendered inline (open, no portal/backdrop). `footer` renders as a right-aligned row. */
|
|
51
|
+
export function Modal(props: Props): ReactElement {
|
|
52
|
+
const width = typeof props.width === "number" ? props.width : 520;
|
|
53
|
+
const footer = props.footer as ReactNode | undefined;
|
|
54
|
+
return createElement(
|
|
55
|
+
AntCard,
|
|
56
|
+
{
|
|
57
|
+
...chrome(props),
|
|
58
|
+
title: props.title as ReactNode,
|
|
59
|
+
style: mergeStyle(
|
|
60
|
+
{ width: "100%", maxWidth: width, margin: "16px auto", boxShadow: SURFACE_SHADOW },
|
|
61
|
+
props.style,
|
|
62
|
+
),
|
|
63
|
+
},
|
|
64
|
+
props.children,
|
|
65
|
+
footer
|
|
66
|
+
? createElement(
|
|
67
|
+
"div",
|
|
68
|
+
{ style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 16 } },
|
|
69
|
+
footer,
|
|
70
|
+
)
|
|
71
|
+
: null,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** A side-drawer panel, rendered inline as a fixed-width column. */
|
|
76
|
+
export function Drawer(props: Props): ReactElement {
|
|
77
|
+
return createElement(
|
|
78
|
+
AntCard,
|
|
79
|
+
{
|
|
80
|
+
...chrome(props),
|
|
81
|
+
title: props.title as ReactNode,
|
|
82
|
+
style: mergeStyle(
|
|
83
|
+
{ width: 320, height: "100%", borderRadius: 0, boxShadow: SURFACE_SHADOW },
|
|
84
|
+
props.style,
|
|
85
|
+
),
|
|
86
|
+
},
|
|
87
|
+
props.children,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** The trigger child inline, followed by the popover surface (title + content), pinned open. */
|
|
92
|
+
export function Popover(props: Props): ReactElement {
|
|
93
|
+
return createElement(
|
|
94
|
+
Fragment,
|
|
95
|
+
null,
|
|
96
|
+
props.children,
|
|
97
|
+
createElement(
|
|
98
|
+
AntCard,
|
|
99
|
+
{
|
|
100
|
+
...chrome(props),
|
|
101
|
+
size: "small",
|
|
102
|
+
title: props.title as ReactNode,
|
|
103
|
+
style: mergeStyle(
|
|
104
|
+
{ display: "inline-block", maxWidth: 320, marginTop: 8, boxShadow: SURFACE_SHADOW },
|
|
105
|
+
props.style,
|
|
106
|
+
),
|
|
107
|
+
},
|
|
108
|
+
props.content as ReactNode,
|
|
109
|
+
),
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** The trigger child inline; `title` renders beside it as a dark tooltip pill. */
|
|
114
|
+
export function Tooltip(props: Props): ReactElement {
|
|
115
|
+
const tip = props.title as ReactNode | undefined;
|
|
116
|
+
return createElement(
|
|
117
|
+
Fragment,
|
|
118
|
+
null,
|
|
119
|
+
props.children,
|
|
120
|
+
tip == null
|
|
121
|
+
? null
|
|
122
|
+
: createElement(
|
|
123
|
+
"span",
|
|
124
|
+
{
|
|
125
|
+
...chrome(props),
|
|
126
|
+
style: mergeStyle(
|
|
127
|
+
{
|
|
128
|
+
display: "inline-block",
|
|
129
|
+
background: "rgba(0, 0, 0, 0.85)",
|
|
130
|
+
color: "#fff",
|
|
131
|
+
borderRadius: 6,
|
|
132
|
+
padding: "4px 8px",
|
|
133
|
+
fontSize: 12,
|
|
134
|
+
lineHeight: 1.4,
|
|
135
|
+
marginLeft: 8,
|
|
136
|
+
verticalAlign: "middle",
|
|
137
|
+
},
|
|
138
|
+
props.style,
|
|
139
|
+
),
|
|
140
|
+
},
|
|
141
|
+
tip,
|
|
142
|
+
),
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** The trigger child inline, followed by the dropdown's menu surface (from `menu.items`), pinned open. */
|
|
147
|
+
export function Dropdown(props: Props): ReactElement {
|
|
148
|
+
const menu = props.menu as { items?: MenuProps["items"] } | undefined;
|
|
149
|
+
return createElement(
|
|
150
|
+
Fragment,
|
|
151
|
+
null,
|
|
152
|
+
props.children,
|
|
153
|
+
createElement(
|
|
154
|
+
"div",
|
|
155
|
+
{
|
|
156
|
+
...chrome(props),
|
|
157
|
+
style: mergeStyle(
|
|
158
|
+
{
|
|
159
|
+
display: "inline-block",
|
|
160
|
+
minWidth: 160,
|
|
161
|
+
marginTop: 4,
|
|
162
|
+
borderRadius: 8,
|
|
163
|
+
boxShadow: SURFACE_SHADOW,
|
|
164
|
+
overflow: "hidden",
|
|
165
|
+
},
|
|
166
|
+
props.style,
|
|
167
|
+
),
|
|
168
|
+
},
|
|
169
|
+
createElement(AntMenu, {
|
|
170
|
+
items: menu?.items ?? [],
|
|
171
|
+
selectable: false,
|
|
172
|
+
style: { borderInlineEnd: "none" },
|
|
173
|
+
}),
|
|
174
|
+
),
|
|
175
|
+
);
|
|
176
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { helpersRegistry } from "@velloo/helpers";
|
|
2
|
+
import type { ComponentRegistry } from "@velloo/provider";
|
|
3
|
+
import {
|
|
4
|
+
Alert,
|
|
5
|
+
Avatar,
|
|
6
|
+
Badge,
|
|
7
|
+
Breadcrumb,
|
|
8
|
+
Button,
|
|
9
|
+
Card,
|
|
10
|
+
Checkbox,
|
|
11
|
+
Col,
|
|
12
|
+
Divider,
|
|
13
|
+
Empty,
|
|
14
|
+
Flex,
|
|
15
|
+
Input,
|
|
16
|
+
List,
|
|
17
|
+
Menu,
|
|
18
|
+
Pagination,
|
|
19
|
+
Progress,
|
|
20
|
+
Radio,
|
|
21
|
+
Rate,
|
|
22
|
+
Row,
|
|
23
|
+
Segmented,
|
|
24
|
+
Select,
|
|
25
|
+
Skeleton,
|
|
26
|
+
Slider,
|
|
27
|
+
Space,
|
|
28
|
+
Statistic,
|
|
29
|
+
Steps,
|
|
30
|
+
Switch,
|
|
31
|
+
Table,
|
|
32
|
+
Tabs,
|
|
33
|
+
Tag,
|
|
34
|
+
Typography,
|
|
35
|
+
} from "antd";
|
|
36
|
+
import { Drawer, Dropdown, Modal, Popover, Tooltip } from "./overlays.ts";
|
|
37
|
+
|
|
38
|
+
const REUSED_HELPER_IDS = [
|
|
39
|
+
"Icon",
|
|
40
|
+
"Image",
|
|
41
|
+
"Placeholder",
|
|
42
|
+
"SVG",
|
|
43
|
+
"Layer",
|
|
44
|
+
"Gradient",
|
|
45
|
+
"Prose",
|
|
46
|
+
] as const;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The runtime registry for antd-native folders: design `$ref` ids → real antd
|
|
50
|
+
* components, SSR'd in-process via the adapter's cssinjs render pass. Dotted
|
|
51
|
+
* antd subcomponents get manifest-friendly flat ids (`Typography.Title` ⇒
|
|
52
|
+
* `TypographyTitle`, `List.Item` ⇒ `ListItem`) — the MCP intro tells the agent
|
|
53
|
+
* how those destructure in emitted code. The overlay surface
|
|
54
|
+
* (Modal/Drawer/Popover/Tooltip/Dropdown) is canvas-safe-wrapped in
|
|
55
|
+
* `overlays.ts` — antd's own overlays portal and render NOTHING in SSR, so the
|
|
56
|
+
* shims render them open + inline instead.
|
|
57
|
+
*/
|
|
58
|
+
export const registry: ComponentRegistry = {
|
|
59
|
+
Alert,
|
|
60
|
+
Avatar,
|
|
61
|
+
Badge,
|
|
62
|
+
Breadcrumb,
|
|
63
|
+
Button,
|
|
64
|
+
Card,
|
|
65
|
+
Checkbox,
|
|
66
|
+
Col,
|
|
67
|
+
Divider,
|
|
68
|
+
Drawer,
|
|
69
|
+
Dropdown,
|
|
70
|
+
Empty,
|
|
71
|
+
Flex,
|
|
72
|
+
Input,
|
|
73
|
+
List,
|
|
74
|
+
ListItem: List.Item,
|
|
75
|
+
ListItemMeta: List.Item.Meta,
|
|
76
|
+
Menu,
|
|
77
|
+
Modal,
|
|
78
|
+
Pagination,
|
|
79
|
+
Popover,
|
|
80
|
+
Progress,
|
|
81
|
+
Radio,
|
|
82
|
+
Rate,
|
|
83
|
+
Row,
|
|
84
|
+
Segmented,
|
|
85
|
+
Select,
|
|
86
|
+
Skeleton,
|
|
87
|
+
Slider,
|
|
88
|
+
Space,
|
|
89
|
+
Statistic,
|
|
90
|
+
Steps,
|
|
91
|
+
Switch,
|
|
92
|
+
Table,
|
|
93
|
+
Tabs,
|
|
94
|
+
Tag,
|
|
95
|
+
Tooltip,
|
|
96
|
+
TypographyParagraph: Typography.Paragraph,
|
|
97
|
+
TypographyText: Typography.Text,
|
|
98
|
+
TypographyTitle: Typography.Title,
|
|
99
|
+
// Framework-neutral velloo helpers antd has no equivalent for — chiefly
|
|
100
|
+
// `Icon` (lucide; @ant-design/icons isn't surfaced) + imagery/composition
|
|
101
|
+
// helpers. Reused verbatim from `@velloo/helpers`, like provider-mui. They
|
|
102
|
+
// size via props (`Icon size`), not Tailwind — the JIT is off on an antd folder.
|
|
103
|
+
...helpersRegistry(REUSED_HELPER_IDS),
|
|
104
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { createCache, extractStyle, StyleProvider } from "@ant-design/cssinjs";
|
|
2
|
+
import type { RenderPass } from "@velloo/provider";
|
|
3
|
+
import type { Theme as VellooTheme } from "@velloo/schema";
|
|
4
|
+
import { ConfigProvider } from "antd";
|
|
5
|
+
import { createElement } from "react";
|
|
6
|
+
import { antdThemeConfig } from "./theme.ts";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A fresh cssinjs + antd render pass for one SSR. `wrap` nests the tree under
|
|
10
|
+
* a per-render cssinjs StyleProvider + an antd ConfigProvider carrying the
|
|
11
|
+
* projected velloo tokens (with `cssVar: true`, so `--ant-*` variables reach
|
|
12
|
+
* inline styles); `css()` extracts the style rules the render registered in
|
|
13
|
+
* the cache. The renderer injects that CSS into a `data-velloo-adapter`
|
|
14
|
+
* <style>. Unlike emotion, cssinjs extraction reads the cache directly — the
|
|
15
|
+
* rendered HTML isn't needed.
|
|
16
|
+
*
|
|
17
|
+
* SSR works in-process because antd is a velloo dependency, so it links the
|
|
18
|
+
* shared monorepo React — no dual-React hazard.
|
|
19
|
+
*/
|
|
20
|
+
export function makeRenderPass(theme: VellooTheme, dark = false): RenderPass {
|
|
21
|
+
const cache = createCache();
|
|
22
|
+
const config = antdThemeConfig(theme, dark);
|
|
23
|
+
return {
|
|
24
|
+
wrap: (element) =>
|
|
25
|
+
createElement(
|
|
26
|
+
StyleProvider,
|
|
27
|
+
{ cache },
|
|
28
|
+
createElement(ConfigProvider, { theme: config }, element),
|
|
29
|
+
),
|
|
30
|
+
// `plain: true` returns bare CSS text; strip <style> wrappers defensively
|
|
31
|
+
// anyway — the RenderPass contract returns CSS, not markup.
|
|
32
|
+
css: () => stripStyleTags(extractStyle(cache, { plain: true })),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function stripStyleTags(css: string): string {
|
|
37
|
+
let current = css;
|
|
38
|
+
for (;;) {
|
|
39
|
+
const next = current.replace(/<\/?style[^>]*>/gi, "");
|
|
40
|
+
if (next === current) return next;
|
|
41
|
+
current = next;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* antd styles components via cssinjs (the ConfigProvider theme + inline
|
|
3
|
+
* `style` objects), not Tailwind utility classes — so this entry mostly exists
|
|
4
|
+
* to satisfy the JIT contract. It still imports Tailwind + declares the token
|
|
5
|
+
* @theme so any stray utility class resolves, and the canvas base reads themed.
|
|
6
|
+
*/
|
|
7
|
+
@import "tailwindcss";
|
|
8
|
+
|
|
9
|
+
@theme {
|
|
10
|
+
--color-background: oklch(1 0 0);
|
|
11
|
+
--color-foreground: oklch(0.145 0 0);
|
|
12
|
+
--color-primary: oklch(0.205 0 0);
|
|
13
|
+
--color-primary-foreground: oklch(0.985 0 0);
|
|
14
|
+
--font-sans: system-ui, -apple-system, sans-serif;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
html, body {
|
|
18
|
+
background: var(--color-background);
|
|
19
|
+
color: var(--color-foreground);
|
|
20
|
+
font-family: var(--font-sans);
|
|
21
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { identifierRef } from "@velloo/provider";
|
|
2
|
+
import {
|
|
3
|
+
type ColorPair,
|
|
4
|
+
DEFAULT_TYPESET_NAME,
|
|
5
|
+
resolveColors,
|
|
6
|
+
typesetScale,
|
|
7
|
+
type Theme as VellooTheme,
|
|
8
|
+
} from "@velloo/schema";
|
|
9
|
+
import type { ThemeConfig } from "antd";
|
|
10
|
+
import { theme as antdTheme } from "antd";
|
|
11
|
+
import { formatRgb, parse } from "culori";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* antd's token engine derives its palette ramps with @ant-design/fast-color,
|
|
15
|
+
* which parses `#hex`, `rgb()/rgba()`, `hsl()/hsla()` — NOT `oklch()`, which is
|
|
16
|
+
* exactly what velloo themes store. Convert anything outside that set to
|
|
17
|
+
* `rgb(...)` via culori; pass antd-native formats through untouched so a hex
|
|
18
|
+
* theme stays hex (and round-trips identically in codegen).
|
|
19
|
+
*/
|
|
20
|
+
function antdColor(css: string): string {
|
|
21
|
+
const s = css.trim();
|
|
22
|
+
if (/^(#|rgb|hsl)/i.test(s)) return s;
|
|
23
|
+
return formatRgb(parse(s)) ?? s;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** A color slot is a CSS string or a { DEFAULT, foreground } pair — pull the base color (antd-safe). */
|
|
27
|
+
function base(slot: ColorPair | undefined, fallback: string): string {
|
|
28
|
+
if (typeof slot === "string") return antdColor(slot);
|
|
29
|
+
if (slot && typeof slot === "object" && typeof slot.DEFAULT === "string")
|
|
30
|
+
return antdColor(slot.DEFAULT);
|
|
31
|
+
return antdColor(fallback);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** antd's `borderRadius` token is a px number; coerce velloo's radius.md (number or CSS len). */
|
|
35
|
+
function radiusPx(theme: VellooTheme): number {
|
|
36
|
+
const md = (theme.radius as Record<string, unknown> | undefined)?.md;
|
|
37
|
+
if (typeof md === "number") return md;
|
|
38
|
+
if (typeof md === "string") {
|
|
39
|
+
const n = Number.parseFloat(md);
|
|
40
|
+
return Number.isFinite(n) ? (md.includes("rem") ? n * 16 : n) : 8;
|
|
41
|
+
}
|
|
42
|
+
return 8;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Project velloo's unified token tree onto antd's seed tokens — the SINGLE
|
|
47
|
+
* source of the velloo→antd mapping shared by the runtime render pass and
|
|
48
|
+
* codegen, so the preview and the emitted theme never diverge. In dark mode,
|
|
49
|
+
* overlay the theme's dark color slots — otherwise the dark algorithm would
|
|
50
|
+
* derive from the light color values.
|
|
51
|
+
*/
|
|
52
|
+
function antdTokens(theme: VellooTheme, dark: boolean): NonNullable<ThemeConfig["token"]> {
|
|
53
|
+
const c = resolveColors(theme, dark);
|
|
54
|
+
return {
|
|
55
|
+
colorPrimary: base(c.primary, "#4f46e5"),
|
|
56
|
+
colorBgBase: antdColor(c.background),
|
|
57
|
+
colorTextBase: antdColor(c.foreground),
|
|
58
|
+
colorError: base(c.destructive, "#dc2626"),
|
|
59
|
+
borderRadius: radiusPx(theme),
|
|
60
|
+
...antdTypography(theme),
|
|
61
|
+
...(c.card ? { colorBgContainer: base(c.card, c.background) } : {}),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Project the default typeset onto antd's typography seed tokens.
|
|
67
|
+
*
|
|
68
|
+
* antd derives its whole type scale from `fontSize` plus the five
|
|
69
|
+
* `fontSizeHeading*` tokens, which is close enough to velloo's ladder to map
|
|
70
|
+
* directly. Values come from `typesetScale` — the concrete-value form of the
|
|
71
|
+
* same ratio table `typesetCss` uses symbolically — because a seed token ends
|
|
72
|
+
* up in a serialized `ThemeConfig` where no CSS variables exist.
|
|
73
|
+
*
|
|
74
|
+
* antd has only five heading tokens (h1–h5), so the velloo `h6` rung has no
|
|
75
|
+
* antd equivalent and is intentionally dropped here; `Prose` regions still get
|
|
76
|
+
* it from the typeset CSS.
|
|
77
|
+
*/
|
|
78
|
+
function antdTypography(theme: VellooTheme): NonNullable<ThemeConfig["token"]> {
|
|
79
|
+
const typography = theme.typography;
|
|
80
|
+
const scale = typesetScale(typography.typesets?.[DEFAULT_TYPESET_NAME], {
|
|
81
|
+
...(typography.fontFamily ? { fontFamily: typography.fontFamily } : {}),
|
|
82
|
+
});
|
|
83
|
+
return {
|
|
84
|
+
fontFamily:
|
|
85
|
+
scale.body.fontFamily ??
|
|
86
|
+
typography.fontFamily?.sans ??
|
|
87
|
+
"system-ui, -apple-system, sans-serif",
|
|
88
|
+
fontSize: scale.body.fontSize,
|
|
89
|
+
fontSizeSM: scale.caption.fontSize,
|
|
90
|
+
fontSizeLG: scale.lead.fontSize,
|
|
91
|
+
fontSizeHeading1: scale.h1.fontSize,
|
|
92
|
+
fontSizeHeading2: scale.h2.fontSize,
|
|
93
|
+
fontSizeHeading3: scale.h3.fontSize,
|
|
94
|
+
fontSizeHeading4: scale.h4.fontSize,
|
|
95
|
+
fontSizeHeading5: scale.h5.fontSize,
|
|
96
|
+
lineHeight: scale.body.lineHeight,
|
|
97
|
+
lineHeightHeading1: scale.h1.lineHeight,
|
|
98
|
+
lineHeightHeading2: scale.h2.lineHeight,
|
|
99
|
+
lineHeightHeading3: scale.h3.lineHeight,
|
|
100
|
+
lineHeightHeading4: scale.h4.lineHeight,
|
|
101
|
+
lineHeightHeading5: scale.h5.lineHeight,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The runtime `ThemeConfig` for the render pass — carries the REAL algorithm
|
|
107
|
+
* function (antd derives its map tokens by calling it). `cssVar: true` also
|
|
108
|
+
* publishes every token as an `--ant-*` CSS variable, so inline `style`
|
|
109
|
+
* objects (this provider's style channel) can reference theme values.
|
|
110
|
+
*/
|
|
111
|
+
export function antdThemeConfig(theme: VellooTheme, dark = false): ThemeConfig {
|
|
112
|
+
return {
|
|
113
|
+
cssVar: true,
|
|
114
|
+
algorithm: dark ? antdTheme.darkAlgorithm : antdTheme.defaultAlgorithm,
|
|
115
|
+
token: antdTokens(theme, dark),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* The codegen projection (`themeToNative`): the same token mapping, but the
|
|
121
|
+
* algorithm emits as a bare identifier (`antdTheme.darkAlgorithm`) that the
|
|
122
|
+
* theme module's import line brings into scope — a function can't serialize.
|
|
123
|
+
* The light flavor references `defaultAlgorithm` explicitly (identical to
|
|
124
|
+
* antd's default) so the aliased import is always used in the emitted module.
|
|
125
|
+
*/
|
|
126
|
+
export function antdThemeOptions(theme: VellooTheme, dark = false): unknown {
|
|
127
|
+
return {
|
|
128
|
+
cssVar: true,
|
|
129
|
+
algorithm: identifierRef(dark ? "antdTheme.darkAlgorithm" : "antdTheme.defaultAlgorithm"),
|
|
130
|
+
token: antdTokens(theme, dark),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lives in its own module (exported as `@velloo/provider-antd/version`) so
|
|
3
|
+
* version-only consumers — the CLI init wizard — don't pull the provider's
|
|
4
|
+
* registry (and with it all of antd) into their import graph. The bundled
|
|
5
|
+
* CLI lazy-loads the full provider per folder config; see
|
|
6
|
+
* `packages/server/src/providers.ts`.
|
|
7
|
+
*/
|
|
8
|
+
export const ANTD_VERSION = "5" as const;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { dirname, join } from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import {
|
|
4
|
+
catalogFromManifest,
|
|
5
|
+
type FrameworkAdapter,
|
|
6
|
+
type Manifest,
|
|
7
|
+
SX_PROP,
|
|
8
|
+
} from "@velloo/provider";
|
|
9
|
+
import { resolveProviderSrcDir } from "@velloo/provider/src-dir";
|
|
10
|
+
import { CHAKRA_INTRO } from "./intro.ts";
|
|
11
|
+
import { CHAKRA_MANIFEST } from "./manifest.ts";
|
|
12
|
+
import { registry } from "./registry.ts";
|
|
13
|
+
import { makeRenderPass } from "./render-pass.ts";
|
|
14
|
+
import { chakraThemeOptions } from "./theme.ts";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Chakra UI v2 provider — a first-class FrameworkAdapter. Chakra ships as a
|
|
18
|
+
* velloo dependency (pre-bundled), so its components SSR in-process against
|
|
19
|
+
* the shared monorepo React; the adapter's emotion `renderPass` extracts the
|
|
20
|
+
* critical CSS (chakra rides the same emotion machinery as MUI). Styling is
|
|
21
|
+
* the native `sx` prop, and the theme projects velloo tokens onto an
|
|
22
|
+
* `extendTheme` POJO (brand scale, semantic body colors, radii, fonts).
|
|
23
|
+
* Canvas-safe overlays (Modal/Drawer/Popover/Menu/Tooltip compositions),
|
|
24
|
+
* `"@chakra-ui/react"` codegen, an `extendTheme` theme emit,
|
|
25
|
+
* `velloo init --library=chakra`, and the catalog are all wired.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
export { CHAKRA_VERSION } from "./version.ts";
|
|
29
|
+
|
|
30
|
+
import { CHAKRA_VERSION } from "./version.ts";
|
|
31
|
+
|
|
32
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
33
|
+
|
|
34
|
+
/** Resolve the provider src (Tailwind entry + sources), from dev + the bundled CLI. */
|
|
35
|
+
const srcDir = resolveProviderSrcDir(here, "provider-chakra", process.env.VELLOO_CHAKRA_SRC);
|
|
36
|
+
|
|
37
|
+
export function createProvider(): FrameworkAdapter {
|
|
38
|
+
return {
|
|
39
|
+
id: "chakra",
|
|
40
|
+
version: CHAKRA_VERSION,
|
|
41
|
+
label: "Chakra UI v2",
|
|
42
|
+
componentsDir: srcDir,
|
|
43
|
+
styleEntryPath: join(srcDir, "tailwind-entry.css"),
|
|
44
|
+
registry,
|
|
45
|
+
loadManifest: async (): Promise<Manifest> => CHAKRA_MANIFEST,
|
|
46
|
+
// The catalog is the chakra *library* surface — every curated chakra
|
|
47
|
+
// component, all installed (bundled). The reused velloo helpers (source
|
|
48
|
+
// "velloo", e.g. Icon→lucide) are always-available built-ins, not library
|
|
49
|
+
// components to install, so they're excluded.
|
|
50
|
+
catalog: async () =>
|
|
51
|
+
catalogFromManifest(
|
|
52
|
+
CHAKRA_MANIFEST.filter((c) => c.source === "chakra"),
|
|
53
|
+
{ importPath: "@chakra-ui/react" },
|
|
54
|
+
),
|
|
55
|
+
styleChannel: SX_PROP,
|
|
56
|
+
styleChannels: ["sx"],
|
|
57
|
+
mcpIntro: () => [...CHAKRA_INTRO],
|
|
58
|
+
renderPass: (theme, dark) => makeRenderPass(theme, dark ?? false),
|
|
59
|
+
codegenModule: "@chakra-ui/react",
|
|
60
|
+
themeToNative: (theme, dark) => chakraThemeOptions(theme, dark),
|
|
61
|
+
themeModule: {
|
|
62
|
+
importLines: ['import { extendTheme } from "@chakra-ui/react";'],
|
|
63
|
+
factory: "extendTheme",
|
|
64
|
+
defaultPath: "chakra-theme.ts",
|
|
65
|
+
},
|
|
66
|
+
// canvasBundleSpec is deliberately absent in v1: the server's bundle-entry
|
|
67
|
+
// builder implements only the MUI-shaped emotion style runtime (its entry
|
|
68
|
+
// template expects `ThemeProvider` + `createTheme` from `stylesModule`);
|
|
69
|
+
// chakra needs `ChakraProvider` + `extendTheme`, so chakra folders render
|
|
70
|
+
// via the in-process emotion SSR path. Extending it means teaching the
|
|
71
|
+
// emotion `CanvasStyleRuntime` a provider/factory shape (or a new union
|
|
72
|
+
// member) in packages/provider/src/adapter.ts plus a branch in
|
|
73
|
+
// packages/server/src/live/canvas-bundle.ts.
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** The id used in `Library.id` to select this provider. */
|
|
78
|
+
export const CHAKRA_PROVIDER_ID = "chakra" as const;
|
|
79
|
+
|
|
80
|
+
export { brandScale, chakraThemeOptions } from "./theme.ts";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP instruction framing for a chakra folder (`FrameworkAdapter.mcpIntro`).
|
|
3
|
+
*
|
|
4
|
+
* The server's base brief is framework-neutral, so this states the vocabulary
|
|
5
|
+
* and the style channel positively rather than correcting a shadcn claim.
|
|
6
|
+
*/
|
|
7
|
+
export const CHAKRA_INTRO: readonly string[] = [
|
|
8
|
+
"**This folder targets Chakra UI v2.** Components are real Chakra: `Box`/`Flex`/`Stack`/`HStack`/`VStack`/`Grid`+`GridItem`/`Container`/`Spacer` for layout, `Card`+`CardHeader`/`CardBody`/`CardFooter`, `Heading`/`Text` (ALL text — `size` picks the heading scale), `Button`/`IconButton`, `Input`/`Textarea`/`Select`/`Checkbox`/`Radio`/`Switch`/`Slider`+parts, `Badge`/`Tag`/`Avatar`/`Alert`+parts/`Stat`+parts/`Progress`/`Skeleton`, `TableContainer`+`Table`/`Thead`/`Tbody`/`Tr`/`Th`/`Td`, `Tabs`+parts, `List`/`ListItem`, `Breadcrumb`+parts, and the overlay surface `Modal`/`Drawer`/`Popover`/`Menu`/`Tooltip` (chakra's composition parts are registered and render open + inline in design mode). Call `list_components` for the full set and per-component `example` props.",
|
|
9
|
+
"",
|
|
10
|
+
'**Style through `sx`.** `update_props { style: { display: "flex", alignItems: "center", gap: 4, p: 6, color: "brand.600" } }` — an object (merges shallowly; an inner `null` drops a key, `style: null` clears). `sx` keys are Chakra style props; spacing is the chakra scale (`p: 4` = 16px); color values take theme tokens — `"brand.500"` is the theme\'s primary scale, `"chakra-body-bg"`/`"chakra-subtle-text"` are the semantic surfaces, and `"gray.600"` etc. work too. Prefer component props (`colorScheme`, `variant`, `size`, `spacing`) over sx where they exist — `colorScheme="brand"` is the primary-colored variant.',
|
|
11
|
+
"",
|
|
12
|
+
'`emit_code` emits idiomatic `<Component sx={{…}} />` importing from `"@chakra-ui/react"`; `emit_theme` emits an `extendTheme(...)` module (default `chakra-theme.ts`) — wire it with `<ChakraProvider theme={theme}>`. Overlays are design-mode shims rendered pinned open: the emitted composition (`Modal > ModalContent > …`) is real chakra, but add the `isOpen`/`onClose` disclosure wiring when implementing. Tailwind utility diagnostics do not apply here.',
|
|
13
|
+
"",
|
|
14
|
+
];
|