@tmorrow/cre8-wc 2.0.4 → 2.0.5
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/a2ui/build-knowledge-graph.py +297 -0
- package/a2ui/catalog +240 -0
- package/a2ui/catalog-kg.json +6704 -0
- package/a2ui/catalog.json +576 -84
- package/a2ui/catalog.svg +3295 -0
- package/a2ui/demo.html +5 -49
- package/a2ui/examples/card-gallery.json +786 -0
- package/a2ui/examples/dating-grid.json +456 -0
- package/a2ui/examples/llm-observability.json +1719 -0
- package/a2ui/examples/portfolio.json +341 -0
- package/a2ui/generate-catalog.mjs +3 -0
- package/cdn/cre8-wc.esm.js +3057 -2438
- package/cdn/cre8-wc.esm.js.map +1 -1
- package/cdn/cre8-wc.min.js +1801 -1204
- package/cdn/cre8-wc.min.js.map +1 -1
- package/lib/components/accordion/accordion.d.ts +1 -0
- package/lib/components/accordion/accordion.d.ts.map +1 -1
- package/lib/components/accordion/accordion.js +1 -0
- package/lib/components/accordion/accordion.js.map +1 -1
- package/lib/components/accordion-item/accordion-item.d.ts +1 -0
- package/lib/components/accordion-item/accordion-item.d.ts.map +1 -1
- package/lib/components/accordion-item/accordion-item.js +1 -0
- package/lib/components/accordion-item/accordion-item.js.map +1 -1
- package/lib/components/alert/alert.d.ts +6 -0
- package/lib/components/alert/alert.d.ts.map +1 -1
- package/lib/components/alert/alert.js +6 -0
- package/lib/components/alert/alert.js.map +1 -1
- package/lib/components/button/button.d.ts +2 -0
- package/lib/components/button/button.d.ts.map +1 -1
- package/lib/components/button/button.js +2 -0
- package/lib/components/button/button.js.map +1 -1
- package/lib/components/button/button.styles.d.ts.map +1 -1
- package/lib/components/button/button.styles.js +1120 -557
- package/lib/components/button/button.styles.js.map +1 -1
- package/lib/components/button-group/button-group.d.ts +9 -0
- package/lib/components/button-group/button-group.d.ts.map +1 -1
- package/lib/components/button-group/button-group.js +8 -0
- package/lib/components/button-group/button-group.js.map +1 -1
- package/lib/components/button-group/button-group.styles.d.ts.map +1 -1
- package/lib/components/button-group/button-group.styles.js +12 -0
- package/lib/components/button-group/button-group.styles.js.map +1 -1
- package/lib/components/card/card.d.ts +1 -1
- package/lib/components/card/card.d.ts.map +1 -1
- package/lib/components/card/card.js +1 -0
- package/lib/components/card/card.js.map +1 -1
- package/lib/components/card/card.styles.d.ts.map +1 -1
- package/lib/components/card/card.styles.js +8 -0
- package/lib/components/card/card.styles.js.map +1 -1
- package/lib/components/checkbox-field-item/checkbox-field-item.d.ts +6 -0
- package/lib/components/checkbox-field-item/checkbox-field-item.d.ts.map +1 -1
- package/lib/components/checkbox-field-item/checkbox-field-item.js +6 -0
- package/lib/components/checkbox-field-item/checkbox-field-item.js.map +1 -1
- package/lib/components/checkbox-field-item/checkbox-field-item.styles.js +1 -1
- package/lib/components/checkbox-field-item/checkbox-field-item.styles.js.map +1 -1
- package/lib/components/date-picker/date-picker.d.ts +5 -0
- package/lib/components/date-picker/date-picker.d.ts.map +1 -1
- package/lib/components/date-picker/date-picker.js +12 -10
- package/lib/components/date-picker/date-picker.js.map +1 -1
- package/lib/components/dropdown/dropdown.d.ts +2 -0
- package/lib/components/dropdown/dropdown.d.ts.map +1 -1
- package/lib/components/dropdown/dropdown.js +2 -0
- package/lib/components/dropdown/dropdown.js.map +1 -1
- package/lib/components/dropdown-item/dropdown-item.d.ts +8 -0
- package/lib/components/dropdown-item/dropdown-item.d.ts.map +1 -1
- package/lib/components/dropdown-item/dropdown-item.js +15 -2
- package/lib/components/dropdown-item/dropdown-item.js.map +1 -1
- package/lib/components/feature/feature.d.ts +4 -0
- package/lib/components/feature/feature.d.ts.map +1 -1
- package/lib/components/feature/feature.js +4 -1
- package/lib/components/feature/feature.js.map +1 -1
- package/lib/components/field/field.d.ts +2 -0
- package/lib/components/field/field.d.ts.map +1 -1
- package/lib/components/field/field.js +3 -0
- package/lib/components/field/field.js.map +1 -1
- package/lib/components/global-nav-item/global-nav-item.d.ts +2 -0
- package/lib/components/global-nav-item/global-nav-item.d.ts.map +1 -1
- package/lib/components/global-nav-item/global-nav-item.js +2 -0
- package/lib/components/global-nav-item/global-nav-item.js.map +1 -1
- package/lib/components/header/header.d.ts +2 -0
- package/lib/components/header/header.d.ts.map +1 -1
- package/lib/components/header/header.js +2 -0
- package/lib/components/header/header.js.map +1 -1
- package/lib/components/hero/hero.d.ts +4 -0
- package/lib/components/hero/hero.d.ts.map +1 -1
- package/lib/components/hero/hero.js +4 -0
- package/lib/components/hero/hero.js.map +1 -1
- package/lib/components/hero/hero.styles.d.ts.map +1 -1
- package/lib/components/hero/hero.styles.js +13 -0
- package/lib/components/hero/hero.styles.js.map +1 -1
- package/lib/components/icon/icon.d.ts +3 -0
- package/lib/components/icon/icon.d.ts.map +1 -1
- package/lib/components/icon/icon.js +7 -5
- package/lib/components/icon/icon.js.map +1 -1
- package/lib/components/link/link.d.ts +2 -0
- package/lib/components/link/link.d.ts.map +1 -1
- package/lib/components/link/link.js +2 -0
- package/lib/components/link/link.js.map +1 -1
- package/lib/components/link-list-item/link-list-item.d.ts +2 -0
- package/lib/components/link-list-item/link-list-item.d.ts.map +1 -1
- package/lib/components/link-list-item/link-list-item.js +2 -0
- package/lib/components/link-list-item/link-list-item.js.map +1 -1
- package/lib/components/modal/modal.d.ts +4 -0
- package/lib/components/modal/modal.d.ts.map +1 -1
- package/lib/components/modal/modal.js +4 -0
- package/lib/components/modal/modal.js.map +1 -1
- package/lib/components/multi-select/multi-select.d.ts +4 -0
- package/lib/components/multi-select/multi-select.d.ts.map +1 -1
- package/lib/components/multi-select/multi-select.js +5 -2
- package/lib/components/multi-select/multi-select.js.map +1 -1
- package/lib/components/page-header/page-header.d.ts +1 -0
- package/lib/components/page-header/page-header.d.ts.map +1 -1
- package/lib/components/page-header/page-header.js +3 -2
- package/lib/components/page-header/page-header.js.map +1 -1
- package/lib/components/pagination/pagination.d.ts +7 -0
- package/lib/components/pagination/pagination.d.ts.map +1 -1
- package/lib/components/pagination/pagination.js +7 -0
- package/lib/components/pagination/pagination.js.map +1 -1
- package/lib/components/percent-bar/percent-bar.d.ts.map +1 -1
- package/lib/components/percent-bar/percent-bar.js +1 -0
- package/lib/components/percent-bar/percent-bar.js.map +1 -1
- package/lib/components/popover/popover.d.ts +6 -0
- package/lib/components/popover/popover.d.ts.map +1 -1
- package/lib/components/popover/popover.js +7 -1
- package/lib/components/popover/popover.js.map +1 -1
- package/lib/components/primary-nav-item/primary-nav-item.d.ts +2 -0
- package/lib/components/primary-nav-item/primary-nav-item.d.ts.map +1 -1
- package/lib/components/primary-nav-item/primary-nav-item.js +2 -0
- package/lib/components/primary-nav-item/primary-nav-item.js.map +1 -1
- package/lib/components/remove-tag/remove-tag.d.ts +2 -0
- package/lib/components/remove-tag/remove-tag.d.ts.map +1 -1
- package/lib/components/remove-tag/remove-tag.js +3 -1
- package/lib/components/remove-tag/remove-tag.js.map +1 -1
- package/lib/components/section/section.d.ts +1 -0
- package/lib/components/section/section.d.ts.map +1 -1
- package/lib/components/section/section.js +1 -0
- package/lib/components/section/section.js.map +1 -1
- package/lib/components/select/select.d.ts +2 -0
- package/lib/components/select/select.d.ts.map +1 -1
- package/lib/components/select/select.js +5 -1
- package/lib/components/select/select.js.map +1 -1
- package/lib/components/split-button/split-button.d.ts +3 -0
- package/lib/components/split-button/split-button.d.ts.map +1 -1
- package/lib/components/split-button/split-button.js.map +1 -1
- package/lib/components/tab/tab.d.ts +2 -0
- package/lib/components/tab/tab.d.ts.map +1 -1
- package/lib/components/tab/tab.js +2 -0
- package/lib/components/tab/tab.js.map +1 -1
- package/lib/components/table-object/table-object.d.ts +2 -0
- package/lib/components/table-object/table-object.d.ts.map +1 -1
- package/lib/components/table-object/table-object.js +2 -0
- package/lib/components/table-object/table-object.js.map +1 -1
- package/lib/components/table-row/table-row.d.ts +1 -0
- package/lib/components/table-row/table-row.d.ts.map +1 -1
- package/lib/components/table-row/table-row.js +1 -0
- package/lib/components/table-row/table-row.js.map +1 -1
- package/lib/components/tag/tag.d.ts +5 -0
- package/lib/components/tag/tag.d.ts.map +1 -1
- package/lib/components/tag/tag.js +2 -0
- package/lib/components/tag/tag.js.map +1 -1
- package/lib/components/tag-list/tag-list.d.ts +2 -0
- package/lib/components/tag-list/tag-list.d.ts.map +1 -1
- package/lib/components/tag-list/tag-list.js +2 -0
- package/lib/components/tag-list/tag-list.js.map +1 -1
- package/lib/components/text-link/text-link.d.ts +1 -0
- package/lib/components/text-link/text-link.d.ts.map +1 -1
- package/lib/components/text-link/text-link.js +1 -0
- package/lib/components/text-link/text-link.js.map +1 -1
- package/lib/components/tooltip/tooltip.d.ts +6 -0
- package/lib/components/tooltip/tooltip.d.ts.map +1 -1
- package/lib/components/tooltip/tooltip.js +3 -0
- package/lib/components/tooltip/tooltip.js.map +1 -1
- package/lib/design-tokens/brands/claude-terracotta/css/tokens_brand.css +85 -0
- package/lib/design-tokens/brands/claude-terracotta/css/tokens_claude-terracotta.css +1 -0
- package/lib/design-tokens/brands/claude-terracotta/css/tokens_claude-terracotta.module.d.ts +3 -0
- package/lib/design-tokens/brands/claude-terracotta/css/tokens_claude-terracotta.module.d.ts.map +1 -0
- package/lib/design-tokens/brands/claude-terracotta/css/tokens_claude-terracotta.module.js +90 -0
- package/lib/design-tokens/brands/claude-terracotta/css/tokens_claude-terracotta.module.js.map +1 -0
- package/lib/design-tokens/brands/cre8-a2ui/css/tokens_brand.css +1 -0
- package/lib/design-tokens/brands/cre8-teal/css/tokens_brand.css +87 -0
- package/lib/design-tokens/brands/cre8-teal/css/tokens_cre8-teal.css +1 -0
- package/lib/design-tokens/brands/cre8-teal/css/tokens_cre8-teal.module.d.ts +3 -0
- package/lib/design-tokens/brands/cre8-teal/css/tokens_cre8-teal.module.d.ts.map +1 -0
- package/lib/design-tokens/brands/cre8-teal/css/tokens_cre8-teal.module.js +90 -0
- package/lib/design-tokens/brands/cre8-teal/css/tokens_cre8-teal.module.js.map +1 -0
- package/lib/scripts/generate-react-manifest.d.ts +20 -0
- package/lib/scripts/generate-react-manifest.d.ts.map +1 -0
- package/lib/scripts/generate-react-manifest.js +154 -0
- package/lib/scripts/generate-react-manifest.js.map +1 -0
- package/mcp-manifest.json +203 -38
- package/package.json +10 -4
- package/react-manifest.json +3594 -0
- package/dist/leaf.png +0 -0
- package/dist/leafDS.png +0 -0
- package/dist/leafLogo.svg +0 -1
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate React MCP Manifest from the Web Component MCP manifest.
|
|
3
|
+
*
|
|
4
|
+
* Reads mcp-manifest.json (generated by generate-mcp-manifest.ts) and
|
|
5
|
+
* transforms it into react-manifest.json, which the cre8-mcp server
|
|
6
|
+
* resolves via `@tmorrow/cre8-wc/react-manifest.json` when tools are
|
|
7
|
+
* called with `format: "react"`.
|
|
8
|
+
*
|
|
9
|
+
* Naming rules intentionally mirror scripts/generate-react-wrappers.ts
|
|
10
|
+
* and the cre8-mcp server's own web→react tag conversion:
|
|
11
|
+
* - cre8-button → Cre8Button
|
|
12
|
+
* - kebab-case attrs → camelCase props
|
|
13
|
+
* - events → on<EventName> callback props
|
|
14
|
+
* - slots → children?: React.ReactNode
|
|
15
|
+
*
|
|
16
|
+
* Run after build:mcp-manifest:
|
|
17
|
+
* npx tsx scripts/generate-react-manifest.ts
|
|
18
|
+
*/
|
|
19
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
20
|
+
import { join, dirname } from 'path';
|
|
21
|
+
import { fileURLToPath } from 'url';
|
|
22
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
23
|
+
const __dirname = dirname(__filename);
|
|
24
|
+
const ROOT = join(__dirname, '..');
|
|
25
|
+
// ─── Naming helpers ──────────────────────────────────────────────────
|
|
26
|
+
/** cre8-button → Cre8Button (same rule as generate-react-wrappers.ts) */
|
|
27
|
+
function toPascalCase(tagName) {
|
|
28
|
+
return tagName
|
|
29
|
+
.split('-')
|
|
30
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
31
|
+
.join('');
|
|
32
|
+
}
|
|
33
|
+
/** full-width → fullWidth; already-camel names pass through */
|
|
34
|
+
function toCamelCase(name) {
|
|
35
|
+
return name.includes('-')
|
|
36
|
+
? name.replace(/-([a-z])/g, (_, c) => c.toUpperCase())
|
|
37
|
+
: name;
|
|
38
|
+
}
|
|
39
|
+
/** cre8.dropdown-close → onCre8DropdownClose (same rule as wrappers) */
|
|
40
|
+
function toEventPropName(eventName) {
|
|
41
|
+
const valid = eventName
|
|
42
|
+
.split(/[.-]/)
|
|
43
|
+
.map((part, index) => index === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1))
|
|
44
|
+
.join('');
|
|
45
|
+
return 'on' + valid.charAt(0).toUpperCase() + valid.slice(1);
|
|
46
|
+
}
|
|
47
|
+
// ─── HTML example → JSX ──────────────────────────────────────────────
|
|
48
|
+
/**
|
|
49
|
+
* Best-effort conversion of a web-component HTML snippet to JSX:
|
|
50
|
+
* - cre8-* tags → Cre8* component names
|
|
51
|
+
* - kebab-case attributes → camelCase
|
|
52
|
+
* - class → className
|
|
53
|
+
* - HTML comments → JSX comments
|
|
54
|
+
* - empty elements collapsed to self-closing form
|
|
55
|
+
*/
|
|
56
|
+
function htmlToJsx(html) {
|
|
57
|
+
let jsx = html;
|
|
58
|
+
// Tag names: <cre8-button ...> / </cre8-button>
|
|
59
|
+
jsx = jsx.replace(/<(\/?)(cre8-[a-z0-9-]+)/g, (_m, slash, tag) => {
|
|
60
|
+
return `<${slash}${toPascalCase(tag)}`;
|
|
61
|
+
});
|
|
62
|
+
// Attributes inside tags: kebab-case → camelCase, class → className.
|
|
63
|
+
// `slot` is left as-is (passed through to the underlying element).
|
|
64
|
+
jsx = jsx.replace(/<[^/!][^>]*>/g, (tagStr) => tagStr.replace(/\s([a-z][a-z0-9-]*)(=)?/g, (m, attr, eq) => {
|
|
65
|
+
if (attr === 'class')
|
|
66
|
+
return ` className${eq || ''}`;
|
|
67
|
+
if (attr.includes('-'))
|
|
68
|
+
return ` ${toCamelCase(attr)}${eq || ''}`;
|
|
69
|
+
return m;
|
|
70
|
+
}));
|
|
71
|
+
// HTML comments → JSX comments
|
|
72
|
+
jsx = jsx.replace(/<!--([\s\S]*?)-->/g, '{/*$1*/}');
|
|
73
|
+
// Collapse empty elements: <Cre8Button ... ></Cre8Button> → <Cre8Button ... />
|
|
74
|
+
jsx = jsx.replace(/<(Cre8[A-Za-z0-9]+)([^>]*)><\/\1>/g, '<$1$2 />');
|
|
75
|
+
return jsx;
|
|
76
|
+
}
|
|
77
|
+
// ─── Transform ───────────────────────────────────────────────────────
|
|
78
|
+
function transformComponent(comp) {
|
|
79
|
+
const props = {};
|
|
80
|
+
// Attributes → camelCase props
|
|
81
|
+
for (const [attrName, attr] of Object.entries(comp.attributes || {})) {
|
|
82
|
+
props[toCamelCase(attrName)] = { ...attr };
|
|
83
|
+
}
|
|
84
|
+
// Properties are already camelCase; merge (attributes win on collision,
|
|
85
|
+
// since the wrapper exposes the attribute-backed prop)
|
|
86
|
+
for (const [propName, prop] of Object.entries(comp.properties || {})) {
|
|
87
|
+
if (!(propName in props)) {
|
|
88
|
+
props[propName] = { ...prop };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Slots → children
|
|
92
|
+
if (Object.keys(comp.slots || {}).length > 0) {
|
|
93
|
+
const named = Object.keys(comp.slots).filter((s) => s !== 'default');
|
|
94
|
+
props.children = {
|
|
95
|
+
type: 'React.ReactNode',
|
|
96
|
+
description: named.length > 0
|
|
97
|
+
? `Slotted content. Named slots (set slot="..." on the child): ${named.join(', ')}`
|
|
98
|
+
: 'Slotted content.',
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// Events → on<EventName> callback props
|
|
102
|
+
for (const [eventName, event] of Object.entries(comp.events || {})) {
|
|
103
|
+
props[toEventPropName(eventName)] = {
|
|
104
|
+
type: '(event: CustomEvent) => void',
|
|
105
|
+
...(event.description ? { description: event.description } : {}),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
name: toPascalCase(comp.name),
|
|
110
|
+
tagName: comp.name,
|
|
111
|
+
category: comp.category,
|
|
112
|
+
description: comp.description,
|
|
113
|
+
props,
|
|
114
|
+
examples: (comp.examples || []).map((ex) => ({
|
|
115
|
+
description: ex.description,
|
|
116
|
+
jsx: htmlToJsx(ex.html),
|
|
117
|
+
})),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
// ─── Main ────────────────────────────────────────────────────────────
|
|
121
|
+
function main() {
|
|
122
|
+
const inputPath = join(ROOT, 'mcp-manifest.json');
|
|
123
|
+
console.log(`Reading web manifest from: ${inputPath}`);
|
|
124
|
+
const webManifest = JSON.parse(readFileSync(inputPath, 'utf-8'));
|
|
125
|
+
const components = webManifest.components.map(transformComponent);
|
|
126
|
+
console.log(`Transformed ${components.length} components`);
|
|
127
|
+
const reactManifest = {
|
|
128
|
+
version: webManifest.version,
|
|
129
|
+
library: '@tmorrow/cre8-react',
|
|
130
|
+
componentPrefix: 'Cre8',
|
|
131
|
+
description: 'React wrappers for cre8 Web Components (@tmorrow/cre8-wc)',
|
|
132
|
+
framework: 'React 18+ via @lit/react',
|
|
133
|
+
components,
|
|
134
|
+
baseClasses: webManifest.baseClasses,
|
|
135
|
+
patterns: (webManifest.patterns || []).map((p) => ({
|
|
136
|
+
...p,
|
|
137
|
+
template: htmlToJsx(p.template),
|
|
138
|
+
})),
|
|
139
|
+
designTokens: webManifest.designTokens,
|
|
140
|
+
accessibility: webManifest.accessibility,
|
|
141
|
+
dependencies: {
|
|
142
|
+
'@lit/react': webManifest.dependencies?.['@lit/react'] || '^1.0.8',
|
|
143
|
+
'@tmorrow/cre8-wc': `^${webManifest.version}`,
|
|
144
|
+
react: '>=18',
|
|
145
|
+
'react-dom': '>=18',
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
const outputPath = join(ROOT, 'react-manifest.json');
|
|
149
|
+
writeFileSync(outputPath, JSON.stringify(reactManifest, null, 2) + '\n');
|
|
150
|
+
console.log(`Wrote react manifest to: ${outputPath}`);
|
|
151
|
+
console.log(`Total components: ${components.length}`);
|
|
152
|
+
}
|
|
153
|
+
main();
|
|
154
|
+
//# sourceMappingURL=generate-react-manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-react-manifest.js","sourceRoot":"","sources":["../../scripts/generate-react-manifest.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Generate React MCP Manifest from the Web Component MCP manifest.\n *\n * Reads mcp-manifest.json (generated by generate-mcp-manifest.ts) and\n * transforms it into react-manifest.json, which the cre8-mcp server\n * resolves via `@tmorrow/cre8-wc/react-manifest.json` when tools are\n * called with `format: \"react\"`.\n *\n * Naming rules intentionally mirror scripts/generate-react-wrappers.ts\n * and the cre8-mcp server's own web→react tag conversion:\n * - cre8-button → Cre8Button\n * - kebab-case attrs → camelCase props\n * - events → on<EventName> callback props\n * - slots → children?: React.ReactNode\n *\n * Run after build:mcp-manifest:\n * npx tsx scripts/generate-react-manifest.ts\n */\n\nimport { readFileSync, writeFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst ROOT = join(__dirname, '..');\n\n// ─── Types (input: mcp-manifest.json) ────────────────────────────────\ninterface McpAttribute {\n type: string;\n values?: string[];\n default?: string | boolean | number;\n description?: string;\n}\n\ninterface McpComponent {\n name: string;\n category: string;\n description: string;\n attributes: Record<string, McpAttribute>;\n properties: Record<string, McpAttribute>;\n slots: Record<string, { description?: string }>;\n events: Record<string, { detail?: Record<string, unknown>; description?: string }>;\n cssProperties: Record<string, { description?: string }>;\n examples: Array<{ description: string; html: string }>;\n}\n\ninterface McpManifest {\n version: string;\n library: string;\n tagPrefix: string;\n description: string;\n framework: string;\n components: McpComponent[];\n baseClasses: unknown;\n patterns: Array<{ name: string; description: string; template: string }>;\n designTokens: unknown;\n accessibility: unknown;\n dependencies: Record<string, string>;\n}\n\n// ─── Types (output: react-manifest.json) ─────────────────────────────\ninterface ReactProp {\n type: string;\n values?: string[];\n default?: string | boolean | number;\n description?: string;\n}\n\ninterface ReactComponent {\n name: string;\n tagName: string;\n category: string;\n description: string;\n props: Record<string, ReactProp>;\n examples: Array<{ description: string; jsx: string }>;\n}\n\n// ─── Naming helpers ──────────────────────────────────────────────────\n\n/** cre8-button → Cre8Button (same rule as generate-react-wrappers.ts) */\nfunction toPascalCase(tagName: string): string {\n return tagName\n .split('-')\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join('');\n}\n\n/** full-width → fullWidth; already-camel names pass through */\nfunction toCamelCase(name: string): string {\n return name.includes('-')\n ? name.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase())\n : name;\n}\n\n/** cre8.dropdown-close → onCre8DropdownClose (same rule as wrappers) */\nfunction toEventPropName(eventName: string): string {\n const valid = eventName\n .split(/[.-]/)\n .map((part, index) =>\n index === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1),\n )\n .join('');\n return 'on' + valid.charAt(0).toUpperCase() + valid.slice(1);\n}\n\n// ─── HTML example → JSX ──────────────────────────────────────────────\n\n/**\n * Best-effort conversion of a web-component HTML snippet to JSX:\n * - cre8-* tags → Cre8* component names\n * - kebab-case attributes → camelCase\n * - class → className\n * - HTML comments → JSX comments\n * - empty elements collapsed to self-closing form\n */\nfunction htmlToJsx(html: string): string {\n let jsx = html;\n\n // Tag names: <cre8-button ...> / </cre8-button>\n jsx = jsx.replace(/<(\\/?)(cre8-[a-z0-9-]+)/g, (_m, slash: string, tag: string) => {\n return `<${slash}${toPascalCase(tag)}`;\n });\n\n // Attributes inside tags: kebab-case → camelCase, class → className.\n // `slot` is left as-is (passed through to the underlying element).\n jsx = jsx.replace(/<[^/!][^>]*>/g, (tagStr) =>\n tagStr.replace(/\\s([a-z][a-z0-9-]*)(=)?/g, (m, attr: string, eq?: string) => {\n if (attr === 'class') return ` className${eq || ''}`;\n if (attr.includes('-')) return ` ${toCamelCase(attr)}${eq || ''}`;\n return m;\n }),\n );\n\n // HTML comments → JSX comments\n jsx = jsx.replace(/<!--([\\s\\S]*?)-->/g, '{/*$1*/}');\n\n // Collapse empty elements: <Cre8Button ... ></Cre8Button> → <Cre8Button ... />\n jsx = jsx.replace(/<(Cre8[A-Za-z0-9]+)([^>]*)><\\/\\1>/g, '<$1$2 />');\n\n return jsx;\n}\n\n// ─── Transform ───────────────────────────────────────────────────────\n\nfunction transformComponent(comp: McpComponent): ReactComponent {\n const props: Record<string, ReactProp> = {};\n\n // Attributes → camelCase props\n for (const [attrName, attr] of Object.entries(comp.attributes || {})) {\n props[toCamelCase(attrName)] = { ...attr };\n }\n\n // Properties are already camelCase; merge (attributes win on collision,\n // since the wrapper exposes the attribute-backed prop)\n for (const [propName, prop] of Object.entries(comp.properties || {})) {\n if (!(propName in props)) {\n props[propName] = { ...prop };\n }\n }\n\n // Slots → children\n if (Object.keys(comp.slots || {}).length > 0) {\n const named = Object.keys(comp.slots).filter((s) => s !== 'default');\n props.children = {\n type: 'React.ReactNode',\n description:\n named.length > 0\n ? `Slotted content. Named slots (set slot=\"...\" on the child): ${named.join(', ')}`\n : 'Slotted content.',\n };\n }\n\n // Events → on<EventName> callback props\n for (const [eventName, event] of Object.entries(comp.events || {})) {\n props[toEventPropName(eventName)] = {\n type: '(event: CustomEvent) => void',\n ...(event.description ? { description: event.description } : {}),\n };\n }\n\n return {\n name: toPascalCase(comp.name),\n tagName: comp.name,\n category: comp.category,\n description: comp.description,\n props,\n examples: (comp.examples || []).map((ex) => ({\n description: ex.description,\n jsx: htmlToJsx(ex.html),\n })),\n };\n}\n\n// ─── Main ────────────────────────────────────────────────────────────\n\nfunction main() {\n const inputPath = join(ROOT, 'mcp-manifest.json');\n console.log(`Reading web manifest from: ${inputPath}`);\n\n const webManifest: McpManifest = JSON.parse(readFileSync(inputPath, 'utf-8'));\n\n const components = webManifest.components.map(transformComponent);\n console.log(`Transformed ${components.length} components`);\n\n const reactManifest = {\n version: webManifest.version,\n library: '@tmorrow/cre8-react',\n componentPrefix: 'Cre8',\n description: 'React wrappers for cre8 Web Components (@tmorrow/cre8-wc)',\n framework: 'React 18+ via @lit/react',\n components,\n baseClasses: webManifest.baseClasses,\n patterns: (webManifest.patterns || []).map((p) => ({\n ...p,\n template: htmlToJsx(p.template),\n })),\n designTokens: webManifest.designTokens,\n accessibility: webManifest.accessibility,\n dependencies: {\n '@lit/react': webManifest.dependencies?.['@lit/react'] || '^1.0.8',\n '@tmorrow/cre8-wc': `^${webManifest.version}`,\n react: '>=18',\n 'react-dom': '>=18',\n },\n };\n\n const outputPath = join(ROOT, 'react-manifest.json');\n writeFileSync(outputPath, JSON.stringify(reactManifest, null, 2) + '\\n');\n console.log(`Wrote react manifest to: ${outputPath}`);\n console.log(`Total components: ${components.length}`);\n}\n\nmain();\n"]}
|