create-flexireact 1.1.0 → 1.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/index.js +759 -4
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -76,6 +76,10 @@ const TEMPLATES = {
|
|
|
76
76
|
name: 'Default',
|
|
77
77
|
description: 'Premium template with modern UI, animations & dark mode',
|
|
78
78
|
},
|
|
79
|
+
'flexi-ui': {
|
|
80
|
+
name: 'Flexi UI',
|
|
81
|
+
description: 'Showcase template with @flexireact/flexi-ui components',
|
|
82
|
+
},
|
|
79
83
|
minimal: {
|
|
80
84
|
name: 'Minimal',
|
|
81
85
|
description: 'Bare minimum FlexiReact setup',
|
|
@@ -867,6 +871,745 @@ export default function HomePage() {
|
|
|
867
871
|
'public/.gitkeep': () => '',
|
|
868
872
|
};
|
|
869
873
|
|
|
874
|
+
// ============================================================================
|
|
875
|
+
// Flexi UI Template Files
|
|
876
|
+
// ============================================================================
|
|
877
|
+
|
|
878
|
+
const FLEXI_UI_FILES = {
|
|
879
|
+
'package.json': (name) => JSON.stringify({
|
|
880
|
+
name: name,
|
|
881
|
+
version: "1.0.0",
|
|
882
|
+
private: true,
|
|
883
|
+
type: "module",
|
|
884
|
+
scripts: {
|
|
885
|
+
dev: "npm run css && flexireact dev",
|
|
886
|
+
build: "npm run css && flexireact build",
|
|
887
|
+
start: "flexireact start",
|
|
888
|
+
css: "npx tailwindcss -i ./app/styles/globals.css -o ./public/styles.css --minify"
|
|
889
|
+
},
|
|
890
|
+
dependencies: {
|
|
891
|
+
"react": "^18.2.0",
|
|
892
|
+
"react-dom": "^18.2.0",
|
|
893
|
+
"@flexireact/core": "^1.0.0",
|
|
894
|
+
"@flexireact/flexi-ui": "^1.0.0",
|
|
895
|
+
"lucide-react": "^0.400.0"
|
|
896
|
+
},
|
|
897
|
+
devDependencies: {
|
|
898
|
+
"@types/react": "^18.2.0",
|
|
899
|
+
"@types/react-dom": "^18.2.0",
|
|
900
|
+
"typescript": "^5.3.0",
|
|
901
|
+
"tailwindcss": "^3.4.0",
|
|
902
|
+
"postcss": "^8.4.32",
|
|
903
|
+
"autoprefixer": "^10.4.16"
|
|
904
|
+
}
|
|
905
|
+
}, null, 2),
|
|
906
|
+
|
|
907
|
+
'tsconfig.json': TEMPLATE_FILES['tsconfig.json'],
|
|
908
|
+
|
|
909
|
+
'tailwind.config.js': () => `/** @type {import('tailwindcss').Config} */
|
|
910
|
+
const { flexiUIPlugin } = require('@flexireact/flexi-ui/tailwind');
|
|
911
|
+
|
|
912
|
+
module.exports = {
|
|
913
|
+
darkMode: 'class',
|
|
914
|
+
content: [
|
|
915
|
+
'./app/**/*.{js,ts,jsx,tsx}',
|
|
916
|
+
'./pages/**/*.{js,ts,jsx,tsx}',
|
|
917
|
+
'./components/**/*.{js,ts,jsx,tsx}',
|
|
918
|
+
'./layouts/**/*.{js,ts,jsx,tsx}',
|
|
919
|
+
'./node_modules/@flexireact/flexi-ui/dist/**/*.js',
|
|
920
|
+
],
|
|
921
|
+
theme: {
|
|
922
|
+
extend: {
|
|
923
|
+
fontFamily: {
|
|
924
|
+
sans: ['Inter', 'system-ui', 'sans-serif'],
|
|
925
|
+
},
|
|
926
|
+
animation: {
|
|
927
|
+
'fade-in': 'fadeIn 0.6s ease-out forwards',
|
|
928
|
+
'fade-up': 'fadeUp 0.6s ease-out forwards',
|
|
929
|
+
'scale-in': 'scaleIn 0.4s ease-out forwards',
|
|
930
|
+
'glow-pulse': 'glowPulse 3s ease-in-out infinite',
|
|
931
|
+
},
|
|
932
|
+
keyframes: {
|
|
933
|
+
fadeIn: {
|
|
934
|
+
'0%': { opacity: '0' },
|
|
935
|
+
'100%': { opacity: '1' },
|
|
936
|
+
},
|
|
937
|
+
fadeUp: {
|
|
938
|
+
'0%': { opacity: '0', transform: 'translateY(30px)' },
|
|
939
|
+
'100%': { opacity: '1', transform: 'translateY(0)' },
|
|
940
|
+
},
|
|
941
|
+
scaleIn: {
|
|
942
|
+
'0%': { opacity: '0', transform: 'scale(0.9)' },
|
|
943
|
+
'100%': { opacity: '1', transform: 'scale(1)' },
|
|
944
|
+
},
|
|
945
|
+
glowPulse: {
|
|
946
|
+
'0%, 100%': { boxShadow: '0 0 20px rgba(0, 255, 156, 0.15)' },
|
|
947
|
+
'50%': { boxShadow: '0 0 40px rgba(0, 255, 156, 0.3)' },
|
|
948
|
+
},
|
|
949
|
+
},
|
|
950
|
+
},
|
|
951
|
+
},
|
|
952
|
+
plugins: [flexiUIPlugin],
|
|
953
|
+
};
|
|
954
|
+
`,
|
|
955
|
+
|
|
956
|
+
'postcss.config.js': () => `module.exports = {
|
|
957
|
+
plugins: {
|
|
958
|
+
tailwindcss: {},
|
|
959
|
+
autoprefixer: {},
|
|
960
|
+
},
|
|
961
|
+
};
|
|
962
|
+
`,
|
|
963
|
+
|
|
964
|
+
'flexireact.config.js': () => `/** @type {import('@flexireact/core').Config} */
|
|
965
|
+
export default {
|
|
966
|
+
styles: [
|
|
967
|
+
'/styles.css',
|
|
968
|
+
'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap'
|
|
969
|
+
],
|
|
970
|
+
favicon: '/favicon.svg',
|
|
971
|
+
server: {
|
|
972
|
+
port: 3000
|
|
973
|
+
},
|
|
974
|
+
islands: {
|
|
975
|
+
enabled: true
|
|
976
|
+
}
|
|
977
|
+
};
|
|
978
|
+
`,
|
|
979
|
+
|
|
980
|
+
// ============================================================================
|
|
981
|
+
// Components
|
|
982
|
+
// ============================================================================
|
|
983
|
+
|
|
984
|
+
'components/Hero.tsx': () => `import React from 'react';
|
|
985
|
+
import { Button, Badge, Card } from '@flexireact/flexi-ui';
|
|
986
|
+
import { Zap, Github, ArrowRight, Sparkles } from 'lucide-react';
|
|
987
|
+
|
|
988
|
+
export function Hero() {
|
|
989
|
+
return (
|
|
990
|
+
<section className="relative min-h-screen flex items-center justify-center overflow-hidden">
|
|
991
|
+
{/* Radial Gradient Background */}
|
|
992
|
+
<div className="absolute inset-0 -z-10">
|
|
993
|
+
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[800px] h-[800px] rounded-full bg-gradient-radial from-[#00FF9C]/20 via-[#00FF9C]/5 to-transparent blur-3xl" />
|
|
994
|
+
<div className="absolute top-0 right-0 w-[600px] h-[600px] rounded-full bg-gradient-radial from-cyan-500/10 to-transparent blur-3xl" />
|
|
995
|
+
<div className="absolute bottom-0 left-0 w-[400px] h-[400px] rounded-full bg-gradient-radial from-emerald-500/10 to-transparent blur-3xl" />
|
|
996
|
+
</div>
|
|
997
|
+
|
|
998
|
+
{/* Grid Pattern Overlay */}
|
|
999
|
+
<div className="absolute inset-0 -z-10 bg-[linear-gradient(rgba(255,255,255,0.02)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.02)_1px,transparent_1px)] bg-[size:64px_64px]" />
|
|
1000
|
+
|
|
1001
|
+
<div className="container mx-auto px-6 py-32 max-w-6xl">
|
|
1002
|
+
<div className="flex flex-col items-center text-center">
|
|
1003
|
+
{/* Badge */}
|
|
1004
|
+
<div className="animate-fade-in" style={{ animationDelay: '0.1s' }}>
|
|
1005
|
+
<Badge variant="success" className="mb-8 px-4 py-2 text-sm">
|
|
1006
|
+
<Sparkles className="w-4 h-4 mr-2" />
|
|
1007
|
+
The Modern React Framework
|
|
1008
|
+
</Badge>
|
|
1009
|
+
</div>
|
|
1010
|
+
|
|
1011
|
+
{/* Title */}
|
|
1012
|
+
<h1 className="text-5xl sm:text-6xl md:text-7xl lg:text-8xl font-black tracking-tight mb-8 animate-fade-up" style={{ animationDelay: '0.2s' }}>
|
|
1013
|
+
Build{' '}
|
|
1014
|
+
<span className="text-transparent bg-clip-text bg-gradient-to-r from-[#00FF9C] via-emerald-400 to-cyan-400">
|
|
1015
|
+
beautiful
|
|
1016
|
+
</span>
|
|
1017
|
+
<br />
|
|
1018
|
+
apps faster
|
|
1019
|
+
</h1>
|
|
1020
|
+
|
|
1021
|
+
{/* Subtitle */}
|
|
1022
|
+
<p className="text-xl md:text-2xl text-[#94a3b8] max-w-2xl mb-12 leading-relaxed animate-fade-up" style={{ animationDelay: '0.3s' }}>
|
|
1023
|
+
Flexi UI is a stunning component library with neon emerald accents,
|
|
1024
|
+
dark-first design, and seamless React integration.
|
|
1025
|
+
</p>
|
|
1026
|
+
|
|
1027
|
+
{/* CTA Buttons */}
|
|
1028
|
+
<div className="flex flex-wrap items-center justify-center gap-4 mb-20 animate-fade-up" style={{ animationDelay: '0.4s' }}>
|
|
1029
|
+
<Button size="lg" className="gap-2 text-base px-8 py-4 h-auto">
|
|
1030
|
+
Get Started
|
|
1031
|
+
<ArrowRight className="w-5 h-5" />
|
|
1032
|
+
</Button>
|
|
1033
|
+
<Button variant="outline" size="lg" className="gap-2 text-base px-8 py-4 h-auto">
|
|
1034
|
+
<Github className="w-5 h-5" />
|
|
1035
|
+
GitHub
|
|
1036
|
+
</Button>
|
|
1037
|
+
</div>
|
|
1038
|
+
|
|
1039
|
+
{/* Terminal Preview */}
|
|
1040
|
+
<Card className="w-full max-w-2xl animate-scale-in animate-glow-pulse" style={{ animationDelay: '0.5s' }}>
|
|
1041
|
+
<div className="p-6">
|
|
1042
|
+
<div className="flex items-center gap-2 mb-4">
|
|
1043
|
+
<div className="w-3 h-3 rounded-full bg-red-500/80" />
|
|
1044
|
+
<div className="w-3 h-3 rounded-full bg-yellow-500/80" />
|
|
1045
|
+
<div className="w-3 h-3 rounded-full bg-green-500/80" />
|
|
1046
|
+
<span className="ml-3 text-xs text-[#64748b]">terminal</span>
|
|
1047
|
+
</div>
|
|
1048
|
+
<pre className="text-left text-sm md:text-base font-mono">
|
|
1049
|
+
<code>
|
|
1050
|
+
<span className="text-[#64748b]">$</span>{' '}
|
|
1051
|
+
<span className="text-[#00FF9C]">npm</span> install @flexireact/flexi-ui{'\n'}
|
|
1052
|
+
<span className="text-[#64748b]">$</span>{' '}
|
|
1053
|
+
<span className="text-[#00FF9C]">npx</span> create-flexireact my-app{'\n'}
|
|
1054
|
+
{'\n'}
|
|
1055
|
+
<span className="text-[#00FF9C]">✓</span> <span className="text-[#f8fafc]">Ready in</span> <span className="text-[#00FF9C]">38ms</span>
|
|
1056
|
+
</code>
|
|
1057
|
+
</pre>
|
|
1058
|
+
</div>
|
|
1059
|
+
</Card>
|
|
1060
|
+
</div>
|
|
1061
|
+
</div>
|
|
1062
|
+
</section>
|
|
1063
|
+
);
|
|
1064
|
+
}
|
|
1065
|
+
`,
|
|
1066
|
+
|
|
1067
|
+
'components/Features.tsx': () => `import React from 'react';
|
|
1068
|
+
import { Card, Badge } from '@flexireact/flexi-ui';
|
|
1069
|
+
import { Zap, Folder, Sparkles, Server, Palette, Shield } from 'lucide-react';
|
|
1070
|
+
|
|
1071
|
+
const features = [
|
|
1072
|
+
{
|
|
1073
|
+
icon: Zap,
|
|
1074
|
+
title: 'Lightning Fast',
|
|
1075
|
+
description: 'Powered by esbuild for instant builds and sub-second hot module replacement.',
|
|
1076
|
+
badge: 'Performance',
|
|
1077
|
+
},
|
|
1078
|
+
{
|
|
1079
|
+
icon: Folder,
|
|
1080
|
+
title: 'File-based Routing',
|
|
1081
|
+
description: 'Create a file in pages/, get a route automatically. Simple and intuitive.',
|
|
1082
|
+
badge: 'DX',
|
|
1083
|
+
},
|
|
1084
|
+
{
|
|
1085
|
+
icon: Sparkles,
|
|
1086
|
+
title: 'Islands Architecture',
|
|
1087
|
+
description: 'Partial hydration for minimal JavaScript. Only hydrate what needs interactivity.',
|
|
1088
|
+
badge: 'Modern',
|
|
1089
|
+
},
|
|
1090
|
+
{
|
|
1091
|
+
icon: Server,
|
|
1092
|
+
title: 'SSR & SSG',
|
|
1093
|
+
description: 'Server-side rendering and static generation out of the box. SEO friendly.',
|
|
1094
|
+
badge: 'SEO',
|
|
1095
|
+
},
|
|
1096
|
+
{
|
|
1097
|
+
icon: Palette,
|
|
1098
|
+
title: 'Beautiful Design',
|
|
1099
|
+
description: 'Neon emerald accents with dark-first design. Stunning out of the box.',
|
|
1100
|
+
badge: 'UI',
|
|
1101
|
+
},
|
|
1102
|
+
{
|
|
1103
|
+
icon: Shield,
|
|
1104
|
+
title: 'Type Safe',
|
|
1105
|
+
description: 'Full TypeScript support with strict type checking and excellent DX.',
|
|
1106
|
+
badge: 'TypeScript',
|
|
1107
|
+
},
|
|
1108
|
+
];
|
|
1109
|
+
|
|
1110
|
+
export function Features() {
|
|
1111
|
+
return (
|
|
1112
|
+
<section className="py-32 px-6">
|
|
1113
|
+
<div className="container mx-auto max-w-6xl">
|
|
1114
|
+
{/* Section Header */}
|
|
1115
|
+
<div className="text-center mb-20">
|
|
1116
|
+
<Badge variant="outline" className="mb-6">Features</Badge>
|
|
1117
|
+
<h2 className="text-4xl md:text-5xl font-bold tracking-tight mb-6">
|
|
1118
|
+
Everything you need
|
|
1119
|
+
</h2>
|
|
1120
|
+
<p className="text-xl text-[#94a3b8] max-w-2xl mx-auto">
|
|
1121
|
+
A complete toolkit for building modern web applications with React and Flexi UI.
|
|
1122
|
+
</p>
|
|
1123
|
+
</div>
|
|
1124
|
+
|
|
1125
|
+
{/* Feature Grid */}
|
|
1126
|
+
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
1127
|
+
{features.map((feature, index) => (
|
|
1128
|
+
<Card
|
|
1129
|
+
key={index}
|
|
1130
|
+
className="group p-8 transition-all duration-300 hover:border-[#00FF9C]/50 hover:shadow-[0_0_30px_rgba(0,255,156,0.1)] cursor-default animate-fade-up"
|
|
1131
|
+
style={{ animationDelay: \`\${index * 0.1}s\` }}
|
|
1132
|
+
>
|
|
1133
|
+
<div className="flex items-start gap-4">
|
|
1134
|
+
<div className="p-3 rounded-xl bg-[#00FF9C]/10 text-[#00FF9C] group-hover:bg-[#00FF9C] group-hover:text-black transition-all duration-300">
|
|
1135
|
+
<feature.icon className="w-6 h-6" />
|
|
1136
|
+
</div>
|
|
1137
|
+
<div className="flex-1">
|
|
1138
|
+
<div className="flex items-center gap-2 mb-2">
|
|
1139
|
+
<h3 className="text-lg font-semibold">{feature.title}</h3>
|
|
1140
|
+
</div>
|
|
1141
|
+
<p className="text-[#94a3b8] text-sm leading-relaxed">
|
|
1142
|
+
{feature.description}
|
|
1143
|
+
</p>
|
|
1144
|
+
</div>
|
|
1145
|
+
</div>
|
|
1146
|
+
</Card>
|
|
1147
|
+
))}
|
|
1148
|
+
</div>
|
|
1149
|
+
</div>
|
|
1150
|
+
</section>
|
|
1151
|
+
);
|
|
1152
|
+
}
|
|
1153
|
+
`,
|
|
1154
|
+
|
|
1155
|
+
'components/Showcase.tsx': () => `import React from 'react';
|
|
1156
|
+
import {
|
|
1157
|
+
Button,
|
|
1158
|
+
Card,
|
|
1159
|
+
Badge,
|
|
1160
|
+
Input,
|
|
1161
|
+
Checkbox,
|
|
1162
|
+
Switch,
|
|
1163
|
+
Progress,
|
|
1164
|
+
Spinner,
|
|
1165
|
+
Avatar,
|
|
1166
|
+
Separator
|
|
1167
|
+
} from '@flexireact/flexi-ui';
|
|
1168
|
+
import { Mail, Lock, User, Search, Heart, Star, Check } from 'lucide-react';
|
|
1169
|
+
|
|
1170
|
+
export function Showcase() {
|
|
1171
|
+
return (
|
|
1172
|
+
<section className="py-32 px-6 relative">
|
|
1173
|
+
{/* Background Gradient */}
|
|
1174
|
+
<div className="absolute inset-0 -z-10">
|
|
1175
|
+
<div className="absolute top-1/2 left-1/4 w-[500px] h-[500px] rounded-full bg-gradient-radial from-[#00FF9C]/10 to-transparent blur-3xl" />
|
|
1176
|
+
</div>
|
|
1177
|
+
|
|
1178
|
+
<div className="container mx-auto max-w-6xl">
|
|
1179
|
+
{/* Section Header */}
|
|
1180
|
+
<div className="text-center mb-20">
|
|
1181
|
+
<Badge variant="success" className="mb-6">Components</Badge>
|
|
1182
|
+
<h2 className="text-4xl md:text-5xl font-bold tracking-tight mb-6">
|
|
1183
|
+
Beautiful by default
|
|
1184
|
+
</h2>
|
|
1185
|
+
<p className="text-xl text-[#94a3b8] max-w-2xl mx-auto">
|
|
1186
|
+
23+ components designed with attention to detail. Dark mode first, accessible, and customizable.
|
|
1187
|
+
</p>
|
|
1188
|
+
</div>
|
|
1189
|
+
|
|
1190
|
+
{/* Component Showcase Grid */}
|
|
1191
|
+
<div className="grid lg:grid-cols-2 gap-8">
|
|
1192
|
+
{/* Buttons Card */}
|
|
1193
|
+
<Card className="p-8">
|
|
1194
|
+
<h3 className="text-lg font-semibold mb-6 flex items-center gap-2">
|
|
1195
|
+
<span className="w-2 h-2 rounded-full bg-[#00FF9C]" />
|
|
1196
|
+
Buttons
|
|
1197
|
+
</h3>
|
|
1198
|
+
<div className="flex flex-wrap gap-3">
|
|
1199
|
+
<Button>Primary</Button>
|
|
1200
|
+
<Button variant="secondary">Secondary</Button>
|
|
1201
|
+
<Button variant="outline">Outline</Button>
|
|
1202
|
+
<Button variant="ghost">Ghost</Button>
|
|
1203
|
+
<Button variant="danger">Danger</Button>
|
|
1204
|
+
<Button variant="link">Link</Button>
|
|
1205
|
+
</div>
|
|
1206
|
+
<Separator className="my-6" />
|
|
1207
|
+
<div className="flex flex-wrap gap-3">
|
|
1208
|
+
<Button size="sm">Small</Button>
|
|
1209
|
+
<Button size="md">Medium</Button>
|
|
1210
|
+
<Button size="lg">Large</Button>
|
|
1211
|
+
</div>
|
|
1212
|
+
<Separator className="my-6" />
|
|
1213
|
+
<div className="flex flex-wrap gap-3">
|
|
1214
|
+
<Button loading>Loading</Button>
|
|
1215
|
+
<Button disabled>Disabled</Button>
|
|
1216
|
+
<Button className="gap-2">
|
|
1217
|
+
<Heart className="w-4 h-4" /> With Icon
|
|
1218
|
+
</Button>
|
|
1219
|
+
</div>
|
|
1220
|
+
</Card>
|
|
1221
|
+
|
|
1222
|
+
{/* Inputs Card */}
|
|
1223
|
+
<Card className="p-8">
|
|
1224
|
+
<h3 className="text-lg font-semibold mb-6 flex items-center gap-2">
|
|
1225
|
+
<span className="w-2 h-2 rounded-full bg-[#00FF9C]" />
|
|
1226
|
+
Inputs
|
|
1227
|
+
</h3>
|
|
1228
|
+
<div className="space-y-4">
|
|
1229
|
+
<Input
|
|
1230
|
+
label="Email"
|
|
1231
|
+
placeholder="you@example.com"
|
|
1232
|
+
type="email"
|
|
1233
|
+
/>
|
|
1234
|
+
<Input
|
|
1235
|
+
label="Password"
|
|
1236
|
+
placeholder="Enter password"
|
|
1237
|
+
type="password"
|
|
1238
|
+
/>
|
|
1239
|
+
<Input
|
|
1240
|
+
label="Search"
|
|
1241
|
+
placeholder="Search..."
|
|
1242
|
+
/>
|
|
1243
|
+
<Input
|
|
1244
|
+
label="With Error"
|
|
1245
|
+
placeholder="Invalid input"
|
|
1246
|
+
error
|
|
1247
|
+
helperText="This field is required"
|
|
1248
|
+
/>
|
|
1249
|
+
</div>
|
|
1250
|
+
</Card>
|
|
1251
|
+
|
|
1252
|
+
{/* Badges Card */}
|
|
1253
|
+
<Card className="p-8">
|
|
1254
|
+
<h3 className="text-lg font-semibold mb-6 flex items-center gap-2">
|
|
1255
|
+
<span className="w-2 h-2 rounded-full bg-[#00FF9C]" />
|
|
1256
|
+
Badges & Status
|
|
1257
|
+
</h3>
|
|
1258
|
+
<div className="flex flex-wrap gap-3 mb-6">
|
|
1259
|
+
<Badge>Default</Badge>
|
|
1260
|
+
<Badge variant="success">Success</Badge>
|
|
1261
|
+
<Badge variant="warning">Warning</Badge>
|
|
1262
|
+
<Badge variant="danger">Danger</Badge>
|
|
1263
|
+
<Badge variant="outline">Outline</Badge>
|
|
1264
|
+
</div>
|
|
1265
|
+
<Separator className="my-6" />
|
|
1266
|
+
<h4 className="text-sm font-medium mb-4 text-[#94a3b8]">Progress</h4>
|
|
1267
|
+
<div className="space-y-4">
|
|
1268
|
+
<Progress value={25} />
|
|
1269
|
+
<Progress value={50} />
|
|
1270
|
+
<Progress value={75} />
|
|
1271
|
+
<Progress value={100} />
|
|
1272
|
+
</div>
|
|
1273
|
+
</Card>
|
|
1274
|
+
|
|
1275
|
+
{/* Form Controls Card */}
|
|
1276
|
+
<Card className="p-8">
|
|
1277
|
+
<h3 className="text-lg font-semibold mb-6 flex items-center gap-2">
|
|
1278
|
+
<span className="w-2 h-2 rounded-full bg-[#00FF9C]" />
|
|
1279
|
+
Form Controls
|
|
1280
|
+
</h3>
|
|
1281
|
+
<div className="space-y-6">
|
|
1282
|
+
<div className="flex items-center gap-4">
|
|
1283
|
+
<Checkbox id="terms" />
|
|
1284
|
+
<label htmlFor="terms" className="text-sm">Accept terms and conditions</label>
|
|
1285
|
+
</div>
|
|
1286
|
+
<div className="flex items-center gap-4">
|
|
1287
|
+
<Checkbox id="newsletter" defaultChecked />
|
|
1288
|
+
<label htmlFor="newsletter" className="text-sm">Subscribe to newsletter</label>
|
|
1289
|
+
</div>
|
|
1290
|
+
<Separator />
|
|
1291
|
+
<div className="flex items-center justify-between">
|
|
1292
|
+
<span className="text-sm">Dark Mode</span>
|
|
1293
|
+
<Switch defaultChecked />
|
|
1294
|
+
</div>
|
|
1295
|
+
<div className="flex items-center justify-between">
|
|
1296
|
+
<span className="text-sm">Notifications</span>
|
|
1297
|
+
<Switch />
|
|
1298
|
+
</div>
|
|
1299
|
+
<Separator />
|
|
1300
|
+
<div className="flex items-center gap-4">
|
|
1301
|
+
<Spinner size="sm" />
|
|
1302
|
+
<Spinner />
|
|
1303
|
+
<Spinner size="lg" />
|
|
1304
|
+
</div>
|
|
1305
|
+
</div>
|
|
1306
|
+
</Card>
|
|
1307
|
+
</div>
|
|
1308
|
+
|
|
1309
|
+
{/* Avatars Row */}
|
|
1310
|
+
<Card className="p-8 mt-8">
|
|
1311
|
+
<h3 className="text-lg font-semibold mb-6 flex items-center gap-2">
|
|
1312
|
+
<span className="w-2 h-2 rounded-full bg-[#00FF9C]" />
|
|
1313
|
+
Avatars
|
|
1314
|
+
</h3>
|
|
1315
|
+
<div className="flex items-center gap-4 flex-wrap">
|
|
1316
|
+
<Avatar size="sm" fallback="JD" />
|
|
1317
|
+
<Avatar fallback="AB" />
|
|
1318
|
+
<Avatar size="lg" fallback="CD" />
|
|
1319
|
+
<Avatar size="xl" fallback="EF" />
|
|
1320
|
+
<Separator orientation="vertical" className="h-12 mx-4" />
|
|
1321
|
+
<div className="flex -space-x-3">
|
|
1322
|
+
<Avatar fallback="A" className="ring-2 ring-[#0a0a0a]" />
|
|
1323
|
+
<Avatar fallback="B" className="ring-2 ring-[#0a0a0a]" />
|
|
1324
|
+
<Avatar fallback="C" className="ring-2 ring-[#0a0a0a]" />
|
|
1325
|
+
<Avatar fallback="+5" className="ring-2 ring-[#0a0a0a]" />
|
|
1326
|
+
</div>
|
|
1327
|
+
</div>
|
|
1328
|
+
</Card>
|
|
1329
|
+
</div>
|
|
1330
|
+
</section>
|
|
1331
|
+
);
|
|
1332
|
+
}
|
|
1333
|
+
`,
|
|
1334
|
+
|
|
1335
|
+
'components/Footer.tsx': () => `import React from 'react';
|
|
1336
|
+
import { Separator } from '@flexireact/flexi-ui';
|
|
1337
|
+
import { Github, Twitter, Heart } from 'lucide-react';
|
|
1338
|
+
|
|
1339
|
+
export function Footer() {
|
|
1340
|
+
return (
|
|
1341
|
+
<footer className="border-t border-[#1e293b]">
|
|
1342
|
+
<div className="container mx-auto max-w-6xl px-6 py-12">
|
|
1343
|
+
<div className="flex flex-col md:flex-row items-center justify-between gap-6">
|
|
1344
|
+
{/* Logo & Copyright */}
|
|
1345
|
+
<div className="flex items-center gap-3">
|
|
1346
|
+
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-[#00FF9C] to-emerald-400 flex items-center justify-center">
|
|
1347
|
+
<span className="text-black font-bold text-sm">F</span>
|
|
1348
|
+
</div>
|
|
1349
|
+
<span className="text-[#94a3b8] text-sm">
|
|
1350
|
+
Built with <Heart className="w-4 h-4 inline text-red-500 mx-1" /> using{' '}
|
|
1351
|
+
<a href="https://github.com/flexireact/flexi-ui" className="text-[#00FF9C] hover:underline">
|
|
1352
|
+
Flexi UI
|
|
1353
|
+
</a>
|
|
1354
|
+
</span>
|
|
1355
|
+
</div>
|
|
1356
|
+
|
|
1357
|
+
{/* Links */}
|
|
1358
|
+
<div className="flex items-center gap-6">
|
|
1359
|
+
<a
|
|
1360
|
+
href="https://github.com/flexireact/flexi-ui"
|
|
1361
|
+
className="text-[#94a3b8] hover:text-white transition-colors flex items-center gap-2 text-sm"
|
|
1362
|
+
>
|
|
1363
|
+
<Github className="w-4 h-4" />
|
|
1364
|
+
GitHub
|
|
1365
|
+
</a>
|
|
1366
|
+
<a
|
|
1367
|
+
href="https://github.com/flexireact/flexireact"
|
|
1368
|
+
className="text-[#94a3b8] hover:text-white transition-colors text-sm"
|
|
1369
|
+
>
|
|
1370
|
+
Documentation
|
|
1371
|
+
</a>
|
|
1372
|
+
<a
|
|
1373
|
+
href="https://github.com/flexireact/flexi-ui"
|
|
1374
|
+
className="text-[#94a3b8] hover:text-white transition-colors text-sm"
|
|
1375
|
+
>
|
|
1376
|
+
Components
|
|
1377
|
+
</a>
|
|
1378
|
+
</div>
|
|
1379
|
+
</div>
|
|
1380
|
+
</div>
|
|
1381
|
+
</footer>
|
|
1382
|
+
);
|
|
1383
|
+
}
|
|
1384
|
+
`,
|
|
1385
|
+
|
|
1386
|
+
'components/Navbar.tsx': () => `import React from 'react';
|
|
1387
|
+
import { Button, Badge } from '@flexireact/flexi-ui';
|
|
1388
|
+
import { Github, Menu } from 'lucide-react';
|
|
1389
|
+
|
|
1390
|
+
export function Navbar() {
|
|
1391
|
+
return (
|
|
1392
|
+
<header className="fixed top-0 left-0 right-0 z-50 border-b border-[#1e293b]/50 bg-[#0a0a0a]/80 backdrop-blur-xl">
|
|
1393
|
+
<nav className="container mx-auto max-w-6xl px-6 h-16 flex items-center justify-between">
|
|
1394
|
+
{/* Logo */}
|
|
1395
|
+
<a href="/" className="flex items-center gap-3 group">
|
|
1396
|
+
<div className="w-9 h-9 rounded-xl bg-gradient-to-br from-[#00FF9C] to-emerald-400 flex items-center justify-center shadow-lg shadow-[#00FF9C]/20 group-hover:shadow-[#00FF9C]/40 transition-shadow">
|
|
1397
|
+
<span className="text-black font-black text-lg">F</span>
|
|
1398
|
+
</div>
|
|
1399
|
+
<span className="text-lg font-bold">Flexi UI</span>
|
|
1400
|
+
<Badge variant="outline" className="hidden sm:flex text-xs">v1.0</Badge>
|
|
1401
|
+
</a>
|
|
1402
|
+
|
|
1403
|
+
{/* Desktop Nav */}
|
|
1404
|
+
<div className="hidden md:flex items-center gap-2">
|
|
1405
|
+
<Button variant="ghost" size="sm">
|
|
1406
|
+
<a href="https://github.com/flexireact/flexi-ui">Docs</a>
|
|
1407
|
+
</Button>
|
|
1408
|
+
<Button variant="ghost" size="sm">
|
|
1409
|
+
<a href="https://github.com/flexireact/flexi-ui">Components</a>
|
|
1410
|
+
</Button>
|
|
1411
|
+
<Button variant="ghost" size="sm">
|
|
1412
|
+
<a href="https://github.com/flexireact/flexireact">FlexiReact</a>
|
|
1413
|
+
</Button>
|
|
1414
|
+
<div className="w-px h-6 bg-[#1e293b] mx-2" />
|
|
1415
|
+
<Button variant="outline" size="sm" className="gap-2">
|
|
1416
|
+
<Github className="w-4 h-4" />
|
|
1417
|
+
<a href="https://github.com/flexireact/flexi-ui">GitHub</a>
|
|
1418
|
+
</Button>
|
|
1419
|
+
</div>
|
|
1420
|
+
|
|
1421
|
+
{/* Mobile Menu Button */}
|
|
1422
|
+
<Button variant="ghost" size="sm" className="md:hidden">
|
|
1423
|
+
<Menu className="w-5 h-5" />
|
|
1424
|
+
</Button>
|
|
1425
|
+
</nav>
|
|
1426
|
+
</header>
|
|
1427
|
+
);
|
|
1428
|
+
}
|
|
1429
|
+
`,
|
|
1430
|
+
|
|
1431
|
+
'components/index.ts': () => `export { Hero } from './Hero';
|
|
1432
|
+
export { Features } from './Features';
|
|
1433
|
+
export { Showcase } from './Showcase';
|
|
1434
|
+
export { Footer } from './Footer';
|
|
1435
|
+
export { Navbar } from './Navbar';
|
|
1436
|
+
`,
|
|
1437
|
+
|
|
1438
|
+
// ============================================================================
|
|
1439
|
+
// Pages & Layouts
|
|
1440
|
+
// ============================================================================
|
|
1441
|
+
|
|
1442
|
+
'layouts/root.tsx': () => `import React from 'react';
|
|
1443
|
+
import { ThemeProvider } from '@flexireact/flexi-ui';
|
|
1444
|
+
import { Navbar } from '../components/Navbar';
|
|
1445
|
+
import { Footer } from '../components/Footer';
|
|
1446
|
+
|
|
1447
|
+
interface LayoutProps {
|
|
1448
|
+
children: React.ReactNode;
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
export default function RootLayout({ children }: LayoutProps) {
|
|
1452
|
+
return (
|
|
1453
|
+
<ThemeProvider defaultTheme="dark">
|
|
1454
|
+
<div className="min-h-screen bg-[#0a0a0a] text-white antialiased">
|
|
1455
|
+
<Navbar />
|
|
1456
|
+
<main className="pt-16">{children}</main>
|
|
1457
|
+
<Footer />
|
|
1458
|
+
</div>
|
|
1459
|
+
</ThemeProvider>
|
|
1460
|
+
);
|
|
1461
|
+
}
|
|
1462
|
+
`,
|
|
1463
|
+
|
|
1464
|
+
'pages/index.tsx': () => `import React from 'react';
|
|
1465
|
+
import { Hero } from '../components/Hero';
|
|
1466
|
+
import { Features } from '../components/Features';
|
|
1467
|
+
import { Showcase } from '../components/Showcase';
|
|
1468
|
+
|
|
1469
|
+
export default function HomePage() {
|
|
1470
|
+
return (
|
|
1471
|
+
<>
|
|
1472
|
+
<Hero />
|
|
1473
|
+
<Features />
|
|
1474
|
+
<Showcase />
|
|
1475
|
+
</>
|
|
1476
|
+
);
|
|
1477
|
+
}
|
|
1478
|
+
`,
|
|
1479
|
+
|
|
1480
|
+
// ============================================================================
|
|
1481
|
+
// Styles
|
|
1482
|
+
// ============================================================================
|
|
1483
|
+
|
|
1484
|
+
'app/styles/globals.css': () => `@tailwind base;
|
|
1485
|
+
@tailwind components;
|
|
1486
|
+
@tailwind utilities;
|
|
1487
|
+
|
|
1488
|
+
@layer base {
|
|
1489
|
+
:root {
|
|
1490
|
+
--flexi-bg: #0a0a0a;
|
|
1491
|
+
--flexi-fg: #fafafa;
|
|
1492
|
+
--flexi-primary: #00FF9C;
|
|
1493
|
+
--flexi-primary-fg: #000000;
|
|
1494
|
+
--flexi-muted: #94a3b8;
|
|
1495
|
+
--flexi-border: #1e293b;
|
|
1496
|
+
--flexi-card: #0f0f0f;
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
* {
|
|
1500
|
+
border-color: var(--flexi-border);
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
html {
|
|
1504
|
+
scroll-behavior: smooth;
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
body {
|
|
1508
|
+
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
|
1509
|
+
background-color: var(--flexi-bg);
|
|
1510
|
+
color: var(--flexi-fg);
|
|
1511
|
+
min-height: 100vh;
|
|
1512
|
+
-webkit-font-smoothing: antialiased;
|
|
1513
|
+
-moz-osx-font-smoothing: grayscale;
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
::selection {
|
|
1517
|
+
background-color: rgba(0, 255, 156, 0.3);
|
|
1518
|
+
color: white;
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
@layer utilities {
|
|
1523
|
+
.bg-gradient-radial {
|
|
1524
|
+
background: radial-gradient(circle, var(--tw-gradient-stops));
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
.text-balance {
|
|
1528
|
+
text-wrap: balance;
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
/* Custom scrollbar */
|
|
1532
|
+
::-webkit-scrollbar {
|
|
1533
|
+
width: 8px;
|
|
1534
|
+
height: 8px;
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
::-webkit-scrollbar-track {
|
|
1538
|
+
background: #0a0a0a;
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1541
|
+
::-webkit-scrollbar-thumb {
|
|
1542
|
+
background: #1e293b;
|
|
1543
|
+
border-radius: 4px;
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
::-webkit-scrollbar-thumb:hover {
|
|
1547
|
+
background: #334155;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
/* Animation utilities */
|
|
1552
|
+
.animate-fade-in {
|
|
1553
|
+
animation: fadeIn 0.6s ease-out forwards;
|
|
1554
|
+
opacity: 0;
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
.animate-fade-up {
|
|
1558
|
+
animation: fadeUp 0.6s ease-out forwards;
|
|
1559
|
+
opacity: 0;
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
.animate-scale-in {
|
|
1563
|
+
animation: scaleIn 0.4s ease-out forwards;
|
|
1564
|
+
opacity: 0;
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
@keyframes fadeIn {
|
|
1568
|
+
from { opacity: 0; }
|
|
1569
|
+
to { opacity: 1; }
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
@keyframes fadeUp {
|
|
1573
|
+
from {
|
|
1574
|
+
opacity: 0;
|
|
1575
|
+
transform: translateY(30px);
|
|
1576
|
+
}
|
|
1577
|
+
to {
|
|
1578
|
+
opacity: 1;
|
|
1579
|
+
transform: translateY(0);
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
@keyframes scaleIn {
|
|
1584
|
+
from {
|
|
1585
|
+
opacity: 0;
|
|
1586
|
+
transform: scale(0.9);
|
|
1587
|
+
}
|
|
1588
|
+
to {
|
|
1589
|
+
opacity: 1;
|
|
1590
|
+
transform: scale(1);
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
`,
|
|
1594
|
+
|
|
1595
|
+
// ============================================================================
|
|
1596
|
+
// Public Assets
|
|
1597
|
+
// ============================================================================
|
|
1598
|
+
|
|
1599
|
+
'public/.gitkeep': () => '',
|
|
1600
|
+
|
|
1601
|
+
'public/favicon.svg': () => `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
|
1602
|
+
<defs>
|
|
1603
|
+
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
1604
|
+
<stop offset="0%" style="stop-color:#00FF9C"/>
|
|
1605
|
+
<stop offset="100%" style="stop-color:#10b981"/>
|
|
1606
|
+
</linearGradient>
|
|
1607
|
+
</defs>
|
|
1608
|
+
<rect width="100" height="100" rx="20" fill="#0a0a0a"/>
|
|
1609
|
+
<text x="50" y="68" font-family="system-ui" font-size="50" font-weight="900" fill="url(#grad)" text-anchor="middle">F</text>
|
|
1610
|
+
</svg>`,
|
|
1611
|
+
};
|
|
1612
|
+
|
|
870
1613
|
// ============================================================================
|
|
871
1614
|
// Main
|
|
872
1615
|
// ============================================================================
|
|
@@ -918,9 +1661,14 @@ async function main() {
|
|
|
918
1661
|
fs.mkdirSync(projectPath, { recursive: true });
|
|
919
1662
|
|
|
920
1663
|
// Create subdirectories
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
1664
|
+
let dirs;
|
|
1665
|
+
if (templateKey === 'minimal') {
|
|
1666
|
+
dirs = ['pages', 'public'];
|
|
1667
|
+
} else if (templateKey === 'flexi-ui') {
|
|
1668
|
+
dirs = ['pages', 'public', 'components', 'layouts', 'app/styles'];
|
|
1669
|
+
} else {
|
|
1670
|
+
dirs = ['pages', 'public', 'components', 'components/ui', 'layouts', 'app/styles', 'lib'];
|
|
1671
|
+
}
|
|
924
1672
|
|
|
925
1673
|
for (const dir of dirs) {
|
|
926
1674
|
fs.mkdirSync(path.join(projectPath, dir), { recursive: true });
|
|
@@ -938,7 +1686,14 @@ async function main() {
|
|
|
938
1686
|
spinner2.start();
|
|
939
1687
|
|
|
940
1688
|
try {
|
|
941
|
-
|
|
1689
|
+
let files;
|
|
1690
|
+
if (templateKey === 'minimal') {
|
|
1691
|
+
files = MINIMAL_FILES;
|
|
1692
|
+
} else if (templateKey === 'flexi-ui') {
|
|
1693
|
+
files = FLEXI_UI_FILES;
|
|
1694
|
+
} else {
|
|
1695
|
+
files = TEMPLATE_FILES;
|
|
1696
|
+
}
|
|
942
1697
|
|
|
943
1698
|
for (const [filePath, contentFn] of Object.entries(files)) {
|
|
944
1699
|
const fullPath = path.join(projectPath, filePath);
|