@static-ui/core 0.1.0-beta.1

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.
@@ -0,0 +1,47 @@
1
+ type FrameworkId = "react" | "nextjs" | "vue" | "nuxt" | "solid" | "svelte" | "astro" | "remix";
2
+ interface ComponentSchema {
3
+ name: string;
4
+ description: string;
5
+ category: string;
6
+ frameworks: FrameworkId[];
7
+ props: ComponentProp[];
8
+ dependencies: Record<FrameworkId, string[]>;
9
+ tailwindClasses: string;
10
+ slots: ComponentSlot[];
11
+ variants: Record<string, ComponentVariantDefinition>;
12
+ }
13
+ interface ComponentProp {
14
+ name: string;
15
+ type: string;
16
+ default?: string;
17
+ description?: string;
18
+ required?: boolean;
19
+ }
20
+ interface ComponentSlot {
21
+ name: string;
22
+ description?: string;
23
+ required?: boolean;
24
+ }
25
+ interface ComponentVariantDefinition {
26
+ values: Record<string, string>;
27
+ default: string;
28
+ }
29
+ interface GeneratedComponent {
30
+ framework: FrameworkId;
31
+ name: string;
32
+ content: string;
33
+ extension: string;
34
+ dependencies: string[];
35
+ }
36
+
37
+ declare const buttonSchema: ComponentSchema;
38
+
39
+ declare function generateReactComponent(schema: ComponentSchema): GeneratedComponent;
40
+
41
+ declare function generateVueComponent(schema: ComponentSchema): GeneratedComponent;
42
+
43
+ declare function generateSolidComponent(schema: ComponentSchema): GeneratedComponent;
44
+
45
+ declare function generateSvelteComponent(schema: ComponentSchema): GeneratedComponent;
46
+
47
+ export { type ComponentProp, type ComponentSchema, type ComponentSlot, type ComponentVariantDefinition, type FrameworkId, type GeneratedComponent, buttonSchema, generateReactComponent, generateSolidComponent, generateSvelteComponent, generateVueComponent };
package/dist/index.js ADDED
@@ -0,0 +1,255 @@
1
+ // src/schemas/button.ts
2
+ var buttonSchema = {
3
+ name: "button",
4
+ description: "A clickable element that triggers an action",
5
+ category: "actions",
6
+ frameworks: ["react", "nextjs", "vue", "nuxt", "solid", "svelte"],
7
+ props: [
8
+ { name: "variant", type: "'default' | 'outline' | 'destructive'", default: "default", description: "Button visual style" },
9
+ { name: "size", type: "'default' | 'sm' | 'lg'", default: "default", description: "Button size" },
10
+ { name: "disabled", type: "boolean", default: "false", description: "Whether the button is disabled" },
11
+ { name: "children", type: "React.ReactNode", description: "Button content", required: true }
12
+ ],
13
+ dependencies: {
14
+ react: ["@base-ui/react", "class-variance-authority", "clsx", "tailwind-merge"],
15
+ nextjs: ["@base-ui/react", "class-variance-authority", "clsx", "tailwind-merge"],
16
+ vue: ["class-variance-authority", "clsx", "tailwind-merge"],
17
+ nuxt: ["class-variance-authority", "clsx", "tailwind-merge"],
18
+ solid: ["clsx", "tailwind-merge"],
19
+ svelte: ["clsx", "tailwind-merge"],
20
+ astro: [],
21
+ remix: ["@base-ui/react", "class-variance-authority", "clsx", "tailwind-merge"]
22
+ },
23
+ tailwindClasses: "inline-flex items-center justify-center font-medium rounded-md text-sm transition-colors focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 data-[focus-visible]:ring-2 data-[focus-visible]:ring-ring data-[focus-visible]:ring-offset-2",
24
+ slots: [
25
+ { name: "root", description: "The button element itself" }
26
+ ],
27
+ variants: {
28
+ variant: {
29
+ values: {
30
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
31
+ outline: "border border-border bg-background text-foreground hover:bg-muted",
32
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90"
33
+ },
34
+ default: "default"
35
+ },
36
+ size: {
37
+ values: {
38
+ default: "h-10 px-4 py-2",
39
+ sm: "h-9 px-3",
40
+ lg: "h-11 px-8"
41
+ },
42
+ default: "default"
43
+ }
44
+ }
45
+ };
46
+
47
+ // src/generators/react.ts
48
+ function generateReactComponent(schema) {
49
+ const variantsCode = schema.variants ? Object.entries(schema.variants).reduce((acc, [name, variant]) => {
50
+ const entries = Object.entries(variant.values).map(([k, v]) => ` ${k}: "${v}",`).join("\n");
51
+ return `${acc}
52
+ ${name}: {
53
+ ${entries}
54
+ },
55
+ defaultVariants: {
56
+ ${name}: "${variant.default}",
57
+ },`;
58
+ }, `const ${schema.name}Variants = cva("${schema.tailwindClasses}", {`) + "\n });" : "";
59
+ const content = `import * as React from "react"
60
+ import { Button as BaseButton } from "@base-ui/react/button"
61
+ import { cva, type VariantProps } from "class-variance-authority"
62
+ import { cn } from "@/lib/utils"
63
+
64
+ ${variantsCode}
65
+
66
+ export interface ${capitalize(schema.name)}Props
67
+ extends React.ComponentPropsWithoutRef<typeof BaseButton>,
68
+ VariantProps<typeof ${schema.name}Variants> {}
69
+
70
+ const ${capitalize(schema.name)} = React.forwardRef<HTMLButtonElement, ${capitalize(schema.name)}Props>(
71
+ ({ className, variant, size, ...props }, ref) => {
72
+ return (
73
+ <BaseButton
74
+ ref={ref}
75
+ className={cn(${schema.name}Variants({ variant, size, className }))}
76
+ {...props}
77
+ />
78
+ )
79
+ }
80
+ )
81
+
82
+ ${capitalize(schema.name)}.displayName = "${capitalize(schema.name)}"
83
+
84
+ export { ${capitalize(schema.name)}, ${schema.name}Variants }
85
+ `;
86
+ return {
87
+ framework: "react",
88
+ name: schema.name,
89
+ content,
90
+ extension: ".tsx",
91
+ dependencies: schema.dependencies.react
92
+ };
93
+ }
94
+ function capitalize(s) {
95
+ return s.charAt(0).toUpperCase() + s.slice(1);
96
+ }
97
+
98
+ // src/generators/vue.ts
99
+ function generateVueComponent(schema) {
100
+ const variantProps = schema.variants ? Object.entries(schema.variants).map(([name, v]) => ` ${name}: {
101
+ type: String,
102
+ default: "${v.default}",
103
+ validator: (value: string) => ["${Object.keys(v.values).join('", "')}"].includes(value),
104
+ },`).join("\n") : "";
105
+ const variantClasses = schema.variants ? Object.entries(schema.variants).map(([name, v]) => {
106
+ const entries = Object.entries(v.values).map(([k, cls]) => ` case "${k}": classes.push("${cls}"); break;`).join("\n");
107
+ return ` const ${name}Classes = computed(() => {
108
+ const classes: string[] = [];
109
+ switch (props.${name}) {
110
+ ${entries}
111
+ }
112
+ return classes;
113
+ });`;
114
+ }).join("\n\n") : "";
115
+ const mergedClasses = schema.variants ? `const mergedClasses = computed(() => {
116
+ return cn("${schema.tailwindClasses}", ...${Object.keys(schema.variants).map((v) => `${v}Classes.value`).join(", ")});
117
+ });` : `const mergedClasses = "${schema.tailwindClasses}";`;
118
+ const content = `<template>
119
+ <button
120
+ :class="mergedClasses"
121
+ :disabled="disabled"
122
+ v-bind="$attrs"
123
+ >
124
+ <slot />
125
+ </button>
126
+ </template>
127
+
128
+ <script setup lang="ts">
129
+ import { computed } from "vue"
130
+ import { cn } from "@/lib/utils"
131
+
132
+ interface Props {
133
+ variant?: "${Object.keys(schema.variants?.variant?.values || {}).join('" | "')}"
134
+ size?: "${Object.keys(schema.variants?.size?.values || {}).join('" | "')}"
135
+ disabled?: boolean
136
+ }
137
+
138
+ const props = withDefaults(defineProps<Props>(), {
139
+ variant: "${schema.variants?.variant?.default || "default"}",
140
+ size: "${schema.variants?.size?.default || "default"}",
141
+ disabled: false,
142
+ })
143
+
144
+ ${variantClasses}
145
+
146
+ ${mergedClasses}
147
+ </script>
148
+ `;
149
+ return {
150
+ framework: "vue",
151
+ name: schema.name,
152
+ content,
153
+ extension: ".vue",
154
+ dependencies: schema.dependencies.vue
155
+ };
156
+ }
157
+
158
+ // src/generators/solid.ts
159
+ function generateSolidComponent(schema) {
160
+ const variantEntries = schema.variants ? Object.entries(schema.variants).map(([name, v]) => {
161
+ const entries = Object.entries(v.values).map(([k, cls]) => ` ${k}: "${cls}"`).join(",\n");
162
+ return `const ${schema.name}${capitalize2(name)} = {
163
+ ${entries},
164
+ } as const;`;
165
+ }).join("\n\n") : "";
166
+ const variantFn = schema.variants ? `function get${capitalize2(schema.name)}Classes(props: ${capitalize2(schema.name)}Props) {
167
+ const classes = ["${schema.tailwindClasses}"];
168
+ ${Object.entries(schema.variants).map(([name, v]) => {
169
+ return `if (props.${name}) classes.push(${schema.name}${capitalize2(name)}[props.${name}]);`;
170
+ }).join("\n ")}
171
+ return cn(...classes);
172
+ }` : "";
173
+ const content = `import type { ComponentProps } from "solid-js"
174
+ import { cn } from "@/lib/utils"
175
+
176
+ ${variantEntries}
177
+
178
+ export interface ${capitalize2(schema.name)}Props {
179
+ variant?: "${Object.keys(schema.variants?.variant?.values || {}).join('" | "')}"
180
+ size?: "${Object.keys(schema.variants?.size?.values || {}).join('" | "')}"
181
+ disabled?: boolean
182
+ class?: string
183
+ children?: any
184
+ }
185
+
186
+ ${variantFn}
187
+
188
+ export function ${capitalize2(schema.name)}(props: ${capitalize2(schema.name)}Props) {
189
+ return (
190
+ <button
191
+ class={get${capitalize2(schema.name)}Classes(props)}
192
+ disabled={props.disabled}
193
+ >
194
+ {props.children}
195
+ </button>
196
+ )
197
+ }
198
+ `;
199
+ return {
200
+ framework: "solid",
201
+ name: schema.name,
202
+ content,
203
+ extension: ".tsx",
204
+ dependencies: schema.dependencies.solid
205
+ };
206
+ }
207
+ function capitalize2(s) {
208
+ return s.charAt(0).toUpperCase() + s.slice(1);
209
+ }
210
+
211
+ // src/generators/svelte.ts
212
+ function generateSvelteComponent(schema) {
213
+ const variantProps = schema.variants ? Object.entries(schema.variants).map(([name, v]) => {
214
+ return ` let ${name}: "${Object.keys(v.values).join('" | "')}" = "${v.default}";`;
215
+ }).join("\n") : "";
216
+ const variantClassMap = schema.variants ? Object.entries(schema.variants).map(([name, v]) => {
217
+ const mapEntries = Object.entries(v.values).map(([k, cls]) => ` "${k}": "${cls}"`).join(",\n");
218
+ return ` const ${name}Classes: Record<string, string> = {
219
+ ${mapEntries},
220
+ };`;
221
+ }).join("\n\n") : "";
222
+ const scriptContent = `<script lang="ts">
223
+ import { cn } from "$lib/utils"
224
+
225
+ export let disabled = false;
226
+ ${variantProps ? "\n" + variantProps : ""}
227
+ ${variantClassMap ? "\n" + variantClassMap : ""}
228
+
229
+ $: classes = cn(
230
+ "${schema.tailwindClasses}",
231
+ ${schema.variants ? Object.entries(schema.variants).map(([name]) => `${name}Classes[${name}]`).join(",\n ") : ""}
232
+ );
233
+ </script>
234
+ `;
235
+ const templateContent = `
236
+ <button class={classes} {disabled} on:click>
237
+ <slot />
238
+ </button>
239
+ `;
240
+ const content = scriptContent + templateContent;
241
+ return {
242
+ framework: "svelte",
243
+ name: schema.name,
244
+ content,
245
+ extension: ".svelte",
246
+ dependencies: schema.dependencies.svelte
247
+ };
248
+ }
249
+ export {
250
+ buttonSchema,
251
+ generateReactComponent,
252
+ generateSolidComponent,
253
+ generateSvelteComponent,
254
+ generateVueComponent
255
+ };
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@static-ui/core",
3
+ "version": "0.1.0-beta.1",
4
+ "private": false,
5
+ "type": "module",
6
+ "description": "Static UI core - component schemas and multi-framework code generators. Source of truth for component definitions.",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "module": "./dist/index.js",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "default": "./dist/index.js"
15
+ }
16
+ },
17
+ "sideEffects": false,
18
+ "files": [
19
+ "dist",
20
+ "src"
21
+ ],
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "scripts": {
26
+ "build": "tsup src/index.ts --format esm --dts",
27
+ "dev": "tsup src/index.ts --format esm --watch",
28
+ "typecheck": "tsc --noEmit"
29
+ },
30
+ "keywords": [
31
+ "static-ui",
32
+ "core",
33
+ "schemas",
34
+ "codegen",
35
+ "components",
36
+ "multi-framework"
37
+ ],
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "git+https://github.com/Anshul563/static-ui.git",
41
+ "directory": "packages/core"
42
+ },
43
+ "homepage": "https://get-staticui.vercel.app",
44
+ "bugs": {
45
+ "url": "https://github.com/Anshul563/static-ui/issues"
46
+ },
47
+ "author": {
48
+ "name": "Anshul Shakya",
49
+ "url": "https://github.com/Anshul563"
50
+ },
51
+ "license": "MIT",
52
+ "dependencies": {
53
+ "typescript": "^5.3.3"
54
+ },
55
+ "devDependencies": {
56
+ "@types/node": "^20.11.0",
57
+ "tsup": "^8.0.1"
58
+ }
59
+ }
@@ -0,0 +1,4 @@
1
+ export { generateReactComponent } from "./react.js";
2
+ export { generateVueComponent } from "./vue.js";
3
+ export { generateSolidComponent } from "./solid.js";
4
+ export { generateSvelteComponent } from "./svelte.js";
@@ -0,0 +1,54 @@
1
+ import type { ComponentSchema, GeneratedComponent } from "../types.js";
2
+
3
+ export function generateReactComponent(schema: ComponentSchema): GeneratedComponent {
4
+ const variantsCode = schema.variants ? Object.entries(schema.variants).reduce((acc, [name, variant]) => {
5
+ const entries = Object.entries(variant.values).map(([k, v]) => ` ${k}: "${v}",`).join("\n");
6
+ return `${acc}
7
+ ${name}: {
8
+ ${entries}
9
+ },
10
+ defaultVariants: {
11
+ ${name}: "${variant.default}",
12
+ },`;
13
+ }, `const ${schema.name}Variants = cva("${schema.tailwindClasses}", {`) + "\n });" : "";
14
+
15
+ const content = `import * as React from "react"
16
+ import { Button as BaseButton } from "@base-ui/react/button"
17
+ import { cva, type VariantProps } from "class-variance-authority"
18
+ import { cn } from "@/lib/utils"
19
+
20
+ ${variantsCode}
21
+
22
+ export interface ${capitalize(schema.name)}Props
23
+ extends React.ComponentPropsWithoutRef<typeof BaseButton>,
24
+ VariantProps<typeof ${schema.name}Variants> {}
25
+
26
+ const ${capitalize(schema.name)} = React.forwardRef<HTMLButtonElement, ${capitalize(schema.name)}Props>(
27
+ ({ className, variant, size, ...props }, ref) => {
28
+ return (
29
+ <BaseButton
30
+ ref={ref}
31
+ className={cn(${schema.name}Variants({ variant, size, className }))}
32
+ {...props}
33
+ />
34
+ )
35
+ }
36
+ )
37
+
38
+ ${capitalize(schema.name)}.displayName = "${capitalize(schema.name)}"
39
+
40
+ export { ${capitalize(schema.name)}, ${schema.name}Variants }
41
+ `;
42
+
43
+ return {
44
+ framework: "react",
45
+ name: schema.name,
46
+ content,
47
+ extension: ".tsx",
48
+ dependencies: schema.dependencies.react,
49
+ };
50
+ }
51
+
52
+ function capitalize(s: string): string {
53
+ return s.charAt(0).toUpperCase() + s.slice(1);
54
+ }
@@ -0,0 +1,59 @@
1
+ import type { ComponentSchema, GeneratedComponent } from "../types.js";
2
+
3
+ export function generateSolidComponent(schema: ComponentSchema): GeneratedComponent {
4
+ const variantEntries = schema.variants
5
+ ? Object.entries(schema.variants).map(([name, v]) => {
6
+ const entries = Object.entries(v.values).map(([k, cls]) => ` ${k}: "${cls}"`).join(",\n");
7
+ return `const ${schema.name}${capitalize(name)} = {\n${entries},\n } as const;`;
8
+ }).join("\n\n")
9
+ : "";
10
+
11
+ const variantFn = schema.variants
12
+ ? `function get${capitalize(schema.name)}Classes(props: ${capitalize(schema.name)}Props) {
13
+ const classes = ["${schema.tailwindClasses}"];
14
+ ${Object.entries(schema.variants).map(([name, v]) => {
15
+ return `if (props.${name}) classes.push(${schema.name}${capitalize(name)}[props.${name}]);`;
16
+ }).join("\n ")}
17
+ return cn(...classes);
18
+ }`
19
+ : "";
20
+
21
+ const content = `import type { ComponentProps } from "solid-js"
22
+ import { cn } from "@/lib/utils"
23
+
24
+ ${variantEntries}
25
+
26
+ export interface ${capitalize(schema.name)}Props {
27
+ variant?: "${Object.keys(schema.variants?.variant?.values || {}).join('" | "')}"
28
+ size?: "${Object.keys(schema.variants?.size?.values || {}).join('" | "')}"
29
+ disabled?: boolean
30
+ class?: string
31
+ children?: any
32
+ }
33
+
34
+ ${variantFn}
35
+
36
+ export function ${capitalize(schema.name)}(props: ${capitalize(schema.name)}Props) {
37
+ return (
38
+ <button
39
+ class={get${capitalize(schema.name)}Classes(props)}
40
+ disabled={props.disabled}
41
+ >
42
+ {props.children}
43
+ </button>
44
+ )
45
+ }
46
+ `;
47
+
48
+ return {
49
+ framework: "solid",
50
+ name: schema.name,
51
+ content,
52
+ extension: ".tsx",
53
+ dependencies: schema.dependencies.solid,
54
+ };
55
+ }
56
+
57
+ function capitalize(s: string): string {
58
+ return s.charAt(0).toUpperCase() + s.slice(1);
59
+ }
@@ -0,0 +1,48 @@
1
+ import type { ComponentSchema, GeneratedComponent } from "../types.js";
2
+
3
+ export function generateSvelteComponent(schema: ComponentSchema): GeneratedComponent {
4
+ const variantProps = schema.variants
5
+ ? Object.entries(schema.variants).map(([name, v]) => {
6
+ return ` let ${name}: "${Object.keys(v.values).join('" | "')}" = "${v.default}";`;
7
+ }).join("\n")
8
+ : "";
9
+
10
+ const variantClassMap = schema.variants
11
+ ? Object.entries(schema.variants).map(([name, v]) => {
12
+ const mapEntries = Object.entries(v.values).map(([k, cls]) => ` "${k}": "${cls}"`).join(",\n");
13
+ return ` const ${name}Classes: Record<string, string> = {\n${mapEntries},\n };`;
14
+ }).join("\n\n")
15
+ : "";
16
+
17
+ const scriptContent = `<script lang="ts">
18
+ import { cn } from "$lib/utils"
19
+
20
+ export let disabled = false;
21
+ ${variantProps ? "\n" + variantProps : ""}
22
+ ${variantClassMap ? "\n" + variantClassMap : ""}
23
+
24
+ $: classes = cn(
25
+ "${schema.tailwindClasses}",
26
+ ${schema.variants
27
+ ? Object.entries(schema.variants).map(([name]) => `${name}Classes[${name}]`).join(",\n ")
28
+ : ""}
29
+ );
30
+ </script>
31
+ `;
32
+
33
+ const templateContent = `
34
+ <button class={classes} {disabled} on:click>
35
+ <slot />
36
+ </button>
37
+ `;
38
+
39
+ const content = scriptContent + templateContent;
40
+
41
+ return {
42
+ framework: "svelte",
43
+ name: schema.name,
44
+ content,
45
+ extension: ".svelte",
46
+ dependencies: schema.dependencies.svelte,
47
+ };
48
+ }
@@ -0,0 +1,70 @@
1
+ import type { ComponentSchema, GeneratedComponent } from "../types.js";
2
+
3
+ export function generateVueComponent(schema: ComponentSchema): GeneratedComponent {
4
+ const variantProps = schema.variants
5
+ ? Object.entries(schema.variants).map(([name, v]) => ` ${name}: {
6
+ type: String,
7
+ default: "${v.default}",
8
+ validator: (value: string) => ["${Object.keys(v.values).join('", "')}"].includes(value),
9
+ },`).join("\n")
10
+ : "";
11
+
12
+ const variantClasses = schema.variants
13
+ ? Object.entries(schema.variants).map(([name, v]) => {
14
+ const entries = Object.entries(v.values).map(([k, cls]) => ` case "${k}": classes.push("${cls}"); break;`).join("\n");
15
+ return ` const ${name}Classes = computed(() => {
16
+ const classes: string[] = [];
17
+ switch (props.${name}) {
18
+ ${entries}
19
+ }
20
+ return classes;
21
+ });`;
22
+ }).join("\n\n")
23
+ : "";
24
+
25
+ const mergedClasses = schema.variants
26
+ ? `const mergedClasses = computed(() => {
27
+ return cn("${schema.tailwindClasses}", ...${Object.keys(schema.variants).map(v => `${v}Classes.value`).join(", ")});
28
+ });`
29
+ : `const mergedClasses = "${schema.tailwindClasses}";`;
30
+
31
+ const content = `<template>
32
+ <button
33
+ :class="mergedClasses"
34
+ :disabled="disabled"
35
+ v-bind="$attrs"
36
+ >
37
+ <slot />
38
+ </button>
39
+ </template>
40
+
41
+ <script setup lang="ts">
42
+ import { computed } from "vue"
43
+ import { cn } from "@/lib/utils"
44
+
45
+ interface Props {
46
+ variant?: "${Object.keys(schema.variants?.variant?.values || {}).join('" | "')}"
47
+ size?: "${Object.keys(schema.variants?.size?.values || {}).join('" | "')}"
48
+ disabled?: boolean
49
+ }
50
+
51
+ const props = withDefaults(defineProps<Props>(), {
52
+ variant: "${schema.variants?.variant?.default || "default"}",
53
+ size: "${schema.variants?.size?.default || "default"}",
54
+ disabled: false,
55
+ })
56
+
57
+ ${variantClasses}
58
+
59
+ ${mergedClasses}
60
+ </script>
61
+ `;
62
+
63
+ return {
64
+ framework: "vue",
65
+ name: schema.name,
66
+ content,
67
+ extension: ".vue",
68
+ dependencies: schema.dependencies.vue,
69
+ };
70
+ }
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export type { ComponentSchema, GeneratedComponent, ComponentProp, ComponentSlot, ComponentVariantDefinition, FrameworkId } from "./types.js";
2
+ export { buttonSchema } from "./schemas/button.js";
3
+ export { generateReactComponent, generateVueComponent, generateSolidComponent, generateSvelteComponent } from "./generators/index.js";
@@ -0,0 +1,46 @@
1
+ import type { ComponentSchema } from "../types.js";
2
+
3
+ export const buttonSchema: ComponentSchema = {
4
+ name: "button",
5
+ description: "A clickable element that triggers an action",
6
+ category: "actions",
7
+ frameworks: ["react", "nextjs", "vue", "nuxt", "solid", "svelte"],
8
+ props: [
9
+ { name: "variant", type: "'default' | 'outline' | 'destructive'", default: "default", description: "Button visual style" },
10
+ { name: "size", type: "'default' | 'sm' | 'lg'", default: "default", description: "Button size" },
11
+ { name: "disabled", type: "boolean", default: "false", description: "Whether the button is disabled" },
12
+ { name: "children", type: "React.ReactNode", description: "Button content", required: true },
13
+ ],
14
+ dependencies: {
15
+ react: ["@base-ui/react", "class-variance-authority", "clsx", "tailwind-merge"],
16
+ nextjs: ["@base-ui/react", "class-variance-authority", "clsx", "tailwind-merge"],
17
+ vue: ["class-variance-authority", "clsx", "tailwind-merge"],
18
+ nuxt: ["class-variance-authority", "clsx", "tailwind-merge"],
19
+ solid: ["clsx", "tailwind-merge"],
20
+ svelte: ["clsx", "tailwind-merge"],
21
+ astro: [],
22
+ remix: ["@base-ui/react", "class-variance-authority", "clsx", "tailwind-merge"],
23
+ },
24
+ tailwindClasses: "inline-flex items-center justify-center font-medium rounded-md text-sm transition-colors focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 data-[focus-visible]:ring-2 data-[focus-visible]:ring-ring data-[focus-visible]:ring-offset-2",
25
+ slots: [
26
+ { name: "root", description: "The button element itself" },
27
+ ],
28
+ variants: {
29
+ variant: {
30
+ values: {
31
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
32
+ outline: "border border-border bg-background text-foreground hover:bg-muted",
33
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
34
+ },
35
+ default: "default",
36
+ },
37
+ size: {
38
+ values: {
39
+ default: "h-10 px-4 py-2",
40
+ sm: "h-9 px-3",
41
+ lg: "h-11 px-8",
42
+ },
43
+ default: "default",
44
+ },
45
+ },
46
+ };
package/src/types.ts ADDED
@@ -0,0 +1,48 @@
1
+ export type FrameworkId =
2
+ | "react"
3
+ | "nextjs"
4
+ | "vue"
5
+ | "nuxt"
6
+ | "solid"
7
+ | "svelte"
8
+ | "astro"
9
+ | "remix";
10
+
11
+ export interface ComponentSchema {
12
+ name: string;
13
+ description: string;
14
+ category: string;
15
+ frameworks: FrameworkId[];
16
+ props: ComponentProp[];
17
+ dependencies: Record<FrameworkId, string[]>;
18
+ tailwindClasses: string;
19
+ slots: ComponentSlot[];
20
+ variants: Record<string, ComponentVariantDefinition>;
21
+ }
22
+
23
+ export interface ComponentProp {
24
+ name: string;
25
+ type: string;
26
+ default?: string;
27
+ description?: string;
28
+ required?: boolean;
29
+ }
30
+
31
+ export interface ComponentSlot {
32
+ name: string;
33
+ description?: string;
34
+ required?: boolean;
35
+ }
36
+
37
+ export interface ComponentVariantDefinition {
38
+ values: Record<string, string>;
39
+ default: string;
40
+ }
41
+
42
+ export interface GeneratedComponent {
43
+ framework: FrameworkId;
44
+ name: string;
45
+ content: string;
46
+ extension: string;
47
+ dependencies: string[];
48
+ }