formix-ui 0.0.2 → 0.0.3
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/README.md +341 -341
- package/dist/bin/index.js +297 -297
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,341 +1,341 @@
|
|
|
1
|
-
# 🚀 Formix UI
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/formix-ui)
|
|
4
|
-
[](https://opensource.org/licenses/MIT)
|
|
5
|
-
[](https://www.typescriptlang.org/)
|
|
6
|
-
[](https://reactjs.org/)
|
|
7
|
-
|
|
8
|
-
**A powerful, schema-driven form engine for React with a visual builder, comprehensive validation, and enterprise-grade features.**
|
|
9
|
-
|
|
10
|
-
## ✨ Features
|
|
11
|
-
|
|
12
|
-
### 🎨 **Visual Form Builder**
|
|
13
|
-
|
|
14
|
-
- Drag-and-drop field arrangement
|
|
15
|
-
- 60+ configurable properties per field
|
|
16
|
-
- Real-time preview
|
|
17
|
-
- Schema import/export (JSON)
|
|
18
|
-
- Smart field defaults
|
|
19
|
-
- **Component Playground**: Interactive gallery for all UI components
|
|
20
|
-
|
|
21
|
-
### 📝 **17 Field Types**
|
|
22
|
-
|
|
23
|
-
- Text inputs (text, email, url, tel, password)
|
|
24
|
-
- Number input with constraints
|
|
25
|
-
- Textarea with auto-grow
|
|
26
|
-
- Autocomplete with async support
|
|
27
|
-
- Native select & multi-select
|
|
28
|
-
- Checkbox, Switch, Radio groups
|
|
29
|
-
- File upload with preview
|
|
30
|
-
- Date, Time, DateTime, DateRange pickers (Native components)
|
|
31
|
-
|
|
32
|
-
### ✅ **Advanced Validation**
|
|
33
|
-
|
|
34
|
-
- 20+ validation types
|
|
35
|
-
- Zod integration
|
|
36
|
-
- Custom validation functions
|
|
37
|
-
|
|
38
|
-
## ✨ Features (v3.2.0)
|
|
39
|
-
|
|
40
|
-
- **Framework Agnostic State**: Choose between Native `useForm`, **Formik**, or **React Hook Form**.
|
|
41
|
-
- **Multi-Validation Support**: First-class support for **Zod** and **Yup**.
|
|
42
|
-
- **Themed Variant System**: Default, Outlined, and Covered variants for all inputs.
|
|
43
|
-
- **Smart CLI 3.0**: Select your stack (`npx formix-ui init`) and we'll configure your validation and state management automatically.
|
|
44
|
-
- Dark mode support
|
|
45
|
-
- Fully responsive (12-column grid)
|
|
46
|
-
- Tailwind CSS 4.1
|
|
47
|
-
|
|
48
|
-
### 🛠️ **CLI 3.0 Power Tools**
|
|
49
|
-
|
|
50
|
-
Detailed instructions can be found in the [CLI Guide](CLI_GUIDE.md).
|
|
51
|
-
|
|
52
|
-
- **`init`**: Comprehensive setup with custom package name support
|
|
53
|
-
- **`add`**: Install specific components locally with dependency tracking
|
|
54
|
-
- **`update`**: Keep your local components up-to-date with a single command
|
|
55
|
-
- **`create`**: Scaffold a new project from scratch (`npx formix-ui create`)
|
|
56
|
-
|
|
57
|
-
### 🌐 **Accessibility**
|
|
58
|
-
|
|
59
|
-
- ARIA labels
|
|
60
|
-
- Keyboard navigation
|
|
61
|
-
- Screen reader support
|
|
62
|
-
- Semantic HTML
|
|
63
|
-
|
|
64
|
-
## 📦 Installation
|
|
65
|
-
|
|
66
|
-
```bash
|
|
67
|
-
npm install formix-ui
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### Peer Dependencies
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
npm install react react-dom tailwindcss zod formik yup
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## 🚀 Quick Start
|
|
77
|
-
|
|
78
|
-
### 1. Basic Form
|
|
79
|
-
|
|
80
|
-
```tsx
|
|
81
|
-
import { SchemaForm } from "formix-ui";
|
|
82
|
-
import type { FormSchema } from "formix-ui";
|
|
83
|
-
|
|
84
|
-
const schema: FormSchema = {
|
|
85
|
-
title: "Contact Form",
|
|
86
|
-
description: "Get in touch with us",
|
|
87
|
-
fields: [
|
|
88
|
-
{
|
|
89
|
-
id: "name",
|
|
90
|
-
name: "name",
|
|
91
|
-
label: "Full Name",
|
|
92
|
-
type: "text",
|
|
93
|
-
placeholder: "John Doe",
|
|
94
|
-
validation: [{ type: "required", message: "Name is required" }],
|
|
95
|
-
grid: { colSpan: 12, xs: 12, sm: 6 },
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
id: "email",
|
|
99
|
-
name: "email",
|
|
100
|
-
label: "Email",
|
|
101
|
-
type: "email",
|
|
102
|
-
placeholder: "john@example.com",
|
|
103
|
-
validation: [{ type: "required" }, { type: "email", message: "Invalid email" }],
|
|
104
|
-
grid: { colSpan: 12, xs: 12, sm: 6 },
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
id: "message",
|
|
108
|
-
name: "message",
|
|
109
|
-
label: "Message",
|
|
110
|
-
type: "textarea",
|
|
111
|
-
rows: 4,
|
|
112
|
-
grid: { colSpan: 12 },
|
|
113
|
-
},
|
|
114
|
-
],
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
function App() {
|
|
118
|
-
return (
|
|
119
|
-
<SchemaForm
|
|
120
|
-
schema={schema}
|
|
121
|
-
onSubmit={(values) => {
|
|
122
|
-
console.log("Form submitted:", values);
|
|
123
|
-
}}
|
|
124
|
-
/>
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
### 2. Form Builder
|
|
130
|
-
|
|
131
|
-
```tsx
|
|
132
|
-
import { FormBuilder } from "formix-ui";
|
|
133
|
-
|
|
134
|
-
function App() {
|
|
135
|
-
return <FormBuilder />;
|
|
136
|
-
}
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### 3. Advanced Features
|
|
140
|
-
|
|
141
|
-
```tsx
|
|
142
|
-
import { SchemaForm } from "formix-ui";
|
|
143
|
-
import { useRef } from "react";
|
|
144
|
-
import type { SchemaFormHandle } from "formix-ui";
|
|
145
|
-
|
|
146
|
-
function App() {
|
|
147
|
-
const formRef = useRef<SchemaFormHandle>(null);
|
|
148
|
-
|
|
149
|
-
return (
|
|
150
|
-
<>
|
|
151
|
-
<SchemaForm
|
|
152
|
-
ref={formRef}
|
|
153
|
-
schema={schema}
|
|
154
|
-
debug // Show debug panel
|
|
155
|
-
onValidate={(values) => {
|
|
156
|
-
// Custom cross-field validation
|
|
157
|
-
const errors: Record<string, string> = {};
|
|
158
|
-
if (values.password !== values.confirmPassword) {
|
|
159
|
-
errors.confirmPassword = "Passwords don't match";
|
|
160
|
-
}
|
|
161
|
-
return errors;
|
|
162
|
-
}}
|
|
163
|
-
onSubmit={(values) => {
|
|
164
|
-
console.log("Submitted:", values);
|
|
165
|
-
}}
|
|
166
|
-
/>
|
|
167
|
-
|
|
168
|
-
<button onClick={() => formRef.current?.submit()}>Submit Form</button>
|
|
169
|
-
<button onClick={() => formRef.current?.reset()}>Reset Form</button>
|
|
170
|
-
</>
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
## 📚 Documentation
|
|
176
|
-
|
|
177
|
-
### Field Types
|
|
178
|
-
|
|
179
|
-
| Type | Description | Special Props |
|
|
180
|
-
| -------------- | ----------------- | ---------------------------------------------- |
|
|
181
|
-
| `text` | Single-line text | `minLength`, `maxLength`, `pattern` |
|
|
182
|
-
| `email` | Email input | Auto email validation |
|
|
183
|
-
| `url` | URL input | Auto URL validation |
|
|
184
|
-
| `tel` | Phone number | `pattern` for format |
|
|
185
|
-
| `password` | Password input | Masked input |
|
|
186
|
-
| `number` | Numeric input | `min`, `max`, `step` |
|
|
187
|
-
| `textarea` | Multi-line text | `rows`, `autoGrow`, `showCharCount` |
|
|
188
|
-
| `autocomplete` | Searchable select | `options`, `multiple`, `asyncUrl`, `creatable` |
|
|
189
|
-
| `select` | Native select | `options`, `multiple` |
|
|
190
|
-
| `checkbox` | Checkbox | `checkboxLabel` |
|
|
191
|
-
| `switch` | Toggle switch | Boolean value |
|
|
192
|
-
| `radio` | Radio group | `options`, `direction` |
|
|
193
|
-
| `file` | File upload | `accept`, `maxSize`, `maxFiles` |
|
|
194
|
-
| `date` | Date picker | `minDate`, `maxDate`, `dateFormat` |
|
|
195
|
-
| `time` | Time picker | `timeFormat` |
|
|
196
|
-
| `datetime` | Date + Time | `dateFormat`, `timeFormat` |
|
|
197
|
-
| `daterange` | Date range | `minDate`, `maxDate` |
|
|
198
|
-
|
|
199
|
-
### Validation Types
|
|
200
|
-
|
|
201
|
-
```typescript
|
|
202
|
-
type ValidationRule =
|
|
203
|
-
| { type: "required"; message?: string }
|
|
204
|
-
| { type: "email"; message?: string }
|
|
205
|
-
| { type: "url"; message?: string }
|
|
206
|
-
| { type: "minLength"; value: number; message?: string }
|
|
207
|
-
| { type: "maxLength"; value: number; message?: string }
|
|
208
|
-
| { type: "min"; value: number; message?: string }
|
|
209
|
-
| { type: "max"; value: number; message?: string }
|
|
210
|
-
| { type: "pattern"; value: string; message?: string }
|
|
211
|
-
| { type: "regex"; value: RegExp; message?: string }
|
|
212
|
-
| { type: "fileSize"; value: number; message?: string }
|
|
213
|
-
| { type: "fileType"; value: string[]; message?: string }
|
|
214
|
-
| { type: "minDate"; value: Date; message?: string }
|
|
215
|
-
| { type: "maxDate"; value: Date; message?: string }
|
|
216
|
-
| { type: "integer"; message?: string }
|
|
217
|
-
| { type: "positive"; message?: string }
|
|
218
|
-
| { type: "negative"; message?: string }
|
|
219
|
-
| { type: "custom"; validate: (value: any) => boolean; message?: string };
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
### Conditional Visibility
|
|
223
|
-
|
|
224
|
-
```typescript
|
|
225
|
-
{
|
|
226
|
-
id: "other-role",
|
|
227
|
-
name: "otherRole",
|
|
228
|
-
label: "Specify Role",
|
|
229
|
-
type: "text",
|
|
230
|
-
visibilityRules: [
|
|
231
|
-
{ field: "role", operator: "eq", value: "other" }
|
|
232
|
-
],
|
|
233
|
-
reserveSpace: true // Keeps layout stable
|
|
234
|
-
}
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
### Grid Layout
|
|
238
|
-
|
|
239
|
-
```typescript
|
|
240
|
-
{
|
|
241
|
-
grid: {
|
|
242
|
-
colSpan: 6, // Desktop (default)
|
|
243
|
-
xs: 12, // Mobile (<640px)
|
|
244
|
-
sm: 6, // Tablet (640px+)
|
|
245
|
-
lg: 4 // Large desktop (1024px+)
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
## 🎨 Theming
|
|
251
|
-
|
|
252
|
-
Formix UI uses Tailwind CSS 4.1 with CSS variables for theming:
|
|
253
|
-
|
|
254
|
-
```css
|
|
255
|
-
@theme {
|
|
256
|
-
--color-primary: oklch(0.6 0.2 250);
|
|
257
|
-
--color-background: oklch(1 0 0);
|
|
258
|
-
--color-foreground: oklch(0.2 0 0);
|
|
259
|
-
/* ... more variables */
|
|
260
|
-
}
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
Toggle dark mode:
|
|
264
|
-
|
|
265
|
-
```tsx
|
|
266
|
-
import { ThemeProvider, ThemeSwitcher } from "formix-ui";
|
|
267
|
-
|
|
268
|
-
function App() {
|
|
269
|
-
return (
|
|
270
|
-
<ThemeProvider defaultTheme="system">
|
|
271
|
-
<ThemeSwitcher />
|
|
272
|
-
{/* Your forms */}
|
|
273
|
-
</ThemeProvider>
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
## 🔧 Configuration
|
|
279
|
-
|
|
280
|
-
### TypeScript
|
|
281
|
-
|
|
282
|
-
```json
|
|
283
|
-
{
|
|
284
|
-
"compilerOptions": {
|
|
285
|
-
"paths": {
|
|
286
|
-
"@/*": ["./src/*"]
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
### Tailwind CSS
|
|
293
|
-
|
|
294
|
-
```js
|
|
295
|
-
// tailwind.config.js
|
|
296
|
-
export default {
|
|
297
|
-
content: [
|
|
298
|
-
"./index.html",
|
|
299
|
-
"./src/**/*.{js,ts,jsx,tsx}",
|
|
300
|
-
"./node_modules/formix-ui/**/*.{js,ts,jsx,tsx}",
|
|
301
|
-
],
|
|
302
|
-
};
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
## 📖 Examples
|
|
306
|
-
|
|
307
|
-
Check out the `/examples` directory for:
|
|
308
|
-
|
|
309
|
-
- Basic form
|
|
310
|
-
- Multi-step wizard
|
|
311
|
-
- Dynamic fields
|
|
312
|
-
- File upload
|
|
313
|
-
- Async autocomplete
|
|
314
|
-
- Conditional logic
|
|
315
|
-
- Custom validation
|
|
316
|
-
|
|
317
|
-
## 🤝 Contributing
|
|
318
|
-
|
|
319
|
-
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
320
|
-
|
|
321
|
-
## 📄 License
|
|
322
|
-
|
|
323
|
-
MIT © Adarsh A
|
|
324
|
-
|
|
325
|
-
## 🙏 Acknowledgments
|
|
326
|
-
|
|
327
|
-
- Built with [React](https://reactjs.org/)
|
|
328
|
-
- Styled with [Tailwind CSS](https://tailwindcss.com/)
|
|
329
|
-
- Date pickers powered by Custom Native Components
|
|
330
|
-
- Validation with [Zod](https://zod.dev/)
|
|
331
|
-
|
|
332
|
-
## 🔗 Links
|
|
333
|
-
|
|
334
|
-
- [Documentation](https://adarshatl03.github.io/formix-ui/)
|
|
335
|
-
- [GitHub](https://github.com/adarshatl03/formix-ui)
|
|
336
|
-
- [NPM](https://www.npmjs.com/package/formix-ui)
|
|
337
|
-
- [Demo](https://adarshatl03.github.io/formix-ui/)
|
|
338
|
-
|
|
339
|
-
---
|
|
340
|
-
|
|
341
|
-
**Made with ❤️ by the Formix UI team**
|
|
1
|
+
# 🚀 Formix UI
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/formix-ui)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
6
|
+
[](https://reactjs.org/)
|
|
7
|
+
|
|
8
|
+
**A powerful, schema-driven form engine for React with a visual builder, comprehensive validation, and enterprise-grade features.**
|
|
9
|
+
|
|
10
|
+
## ✨ Features
|
|
11
|
+
|
|
12
|
+
### 🎨 **Visual Form Builder**
|
|
13
|
+
|
|
14
|
+
- Drag-and-drop field arrangement
|
|
15
|
+
- 60+ configurable properties per field
|
|
16
|
+
- Real-time preview
|
|
17
|
+
- Schema import/export (JSON)
|
|
18
|
+
- Smart field defaults
|
|
19
|
+
- **Component Playground**: Interactive gallery for all UI components
|
|
20
|
+
|
|
21
|
+
### 📝 **17 Field Types**
|
|
22
|
+
|
|
23
|
+
- Text inputs (text, email, url, tel, password)
|
|
24
|
+
- Number input with constraints
|
|
25
|
+
- Textarea with auto-grow
|
|
26
|
+
- Autocomplete with async support
|
|
27
|
+
- Native select & multi-select
|
|
28
|
+
- Checkbox, Switch, Radio groups
|
|
29
|
+
- File upload with preview
|
|
30
|
+
- Date, Time, DateTime, DateRange pickers (Native components)
|
|
31
|
+
|
|
32
|
+
### ✅ **Advanced Validation**
|
|
33
|
+
|
|
34
|
+
- 20+ validation types
|
|
35
|
+
- Zod integration
|
|
36
|
+
- Custom validation functions
|
|
37
|
+
|
|
38
|
+
## ✨ Features (v3.2.0)
|
|
39
|
+
|
|
40
|
+
- **Framework Agnostic State**: Choose between Native `useForm`, **Formik**, or **React Hook Form**.
|
|
41
|
+
- **Multi-Validation Support**: First-class support for **Zod** and **Yup**.
|
|
42
|
+
- **Themed Variant System**: Default, Outlined, and Covered variants for all inputs.
|
|
43
|
+
- **Smart CLI 3.0**: Select your stack (`npx formix-ui init`) and we'll configure your validation and state management automatically.
|
|
44
|
+
- Dark mode support
|
|
45
|
+
- Fully responsive (12-column grid)
|
|
46
|
+
- Tailwind CSS 4.1
|
|
47
|
+
|
|
48
|
+
### 🛠️ **CLI 3.0 Power Tools**
|
|
49
|
+
|
|
50
|
+
Detailed instructions can be found in the [CLI Guide](CLI_GUIDE.md).
|
|
51
|
+
|
|
52
|
+
- **`init`**: Comprehensive setup with custom package name support
|
|
53
|
+
- **`add`**: Install specific components locally with dependency tracking
|
|
54
|
+
- **`update`**: Keep your local components up-to-date with a single command
|
|
55
|
+
- **`create`**: Scaffold a new project from scratch (`npx formix-ui create`)
|
|
56
|
+
|
|
57
|
+
### 🌐 **Accessibility**
|
|
58
|
+
|
|
59
|
+
- ARIA labels
|
|
60
|
+
- Keyboard navigation
|
|
61
|
+
- Screen reader support
|
|
62
|
+
- Semantic HTML
|
|
63
|
+
|
|
64
|
+
## 📦 Installation
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npm install formix-ui
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Peer Dependencies
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm install react react-dom tailwindcss zod formik yup
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## 🚀 Quick Start
|
|
77
|
+
|
|
78
|
+
### 1. Basic Form
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
import { SchemaForm } from "formix-ui";
|
|
82
|
+
import type { FormSchema } from "formix-ui";
|
|
83
|
+
|
|
84
|
+
const schema: FormSchema = {
|
|
85
|
+
title: "Contact Form",
|
|
86
|
+
description: "Get in touch with us",
|
|
87
|
+
fields: [
|
|
88
|
+
{
|
|
89
|
+
id: "name",
|
|
90
|
+
name: "name",
|
|
91
|
+
label: "Full Name",
|
|
92
|
+
type: "text",
|
|
93
|
+
placeholder: "John Doe",
|
|
94
|
+
validation: [{ type: "required", message: "Name is required" }],
|
|
95
|
+
grid: { colSpan: 12, xs: 12, sm: 6 },
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
id: "email",
|
|
99
|
+
name: "email",
|
|
100
|
+
label: "Email",
|
|
101
|
+
type: "email",
|
|
102
|
+
placeholder: "john@example.com",
|
|
103
|
+
validation: [{ type: "required" }, { type: "email", message: "Invalid email" }],
|
|
104
|
+
grid: { colSpan: 12, xs: 12, sm: 6 },
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
id: "message",
|
|
108
|
+
name: "message",
|
|
109
|
+
label: "Message",
|
|
110
|
+
type: "textarea",
|
|
111
|
+
rows: 4,
|
|
112
|
+
grid: { colSpan: 12 },
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
function App() {
|
|
118
|
+
return (
|
|
119
|
+
<SchemaForm
|
|
120
|
+
schema={schema}
|
|
121
|
+
onSubmit={(values) => {
|
|
122
|
+
console.log("Form submitted:", values);
|
|
123
|
+
}}
|
|
124
|
+
/>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### 2. Form Builder
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
import { FormBuilder } from "formix-ui";
|
|
133
|
+
|
|
134
|
+
function App() {
|
|
135
|
+
return <FormBuilder />;
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### 3. Advanced Features
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
import { SchemaForm } from "formix-ui";
|
|
143
|
+
import { useRef } from "react";
|
|
144
|
+
import type { SchemaFormHandle } from "formix-ui";
|
|
145
|
+
|
|
146
|
+
function App() {
|
|
147
|
+
const formRef = useRef<SchemaFormHandle>(null);
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
<>
|
|
151
|
+
<SchemaForm
|
|
152
|
+
ref={formRef}
|
|
153
|
+
schema={schema}
|
|
154
|
+
debug // Show debug panel
|
|
155
|
+
onValidate={(values) => {
|
|
156
|
+
// Custom cross-field validation
|
|
157
|
+
const errors: Record<string, string> = {};
|
|
158
|
+
if (values.password !== values.confirmPassword) {
|
|
159
|
+
errors.confirmPassword = "Passwords don't match";
|
|
160
|
+
}
|
|
161
|
+
return errors;
|
|
162
|
+
}}
|
|
163
|
+
onSubmit={(values) => {
|
|
164
|
+
console.log("Submitted:", values);
|
|
165
|
+
}}
|
|
166
|
+
/>
|
|
167
|
+
|
|
168
|
+
<button onClick={() => formRef.current?.submit()}>Submit Form</button>
|
|
169
|
+
<button onClick={() => formRef.current?.reset()}>Reset Form</button>
|
|
170
|
+
</>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## 📚 Documentation
|
|
176
|
+
|
|
177
|
+
### Field Types
|
|
178
|
+
|
|
179
|
+
| Type | Description | Special Props |
|
|
180
|
+
| -------------- | ----------------- | ---------------------------------------------- |
|
|
181
|
+
| `text` | Single-line text | `minLength`, `maxLength`, `pattern` |
|
|
182
|
+
| `email` | Email input | Auto email validation |
|
|
183
|
+
| `url` | URL input | Auto URL validation |
|
|
184
|
+
| `tel` | Phone number | `pattern` for format |
|
|
185
|
+
| `password` | Password input | Masked input |
|
|
186
|
+
| `number` | Numeric input | `min`, `max`, `step` |
|
|
187
|
+
| `textarea` | Multi-line text | `rows`, `autoGrow`, `showCharCount` |
|
|
188
|
+
| `autocomplete` | Searchable select | `options`, `multiple`, `asyncUrl`, `creatable` |
|
|
189
|
+
| `select` | Native select | `options`, `multiple` |
|
|
190
|
+
| `checkbox` | Checkbox | `checkboxLabel` |
|
|
191
|
+
| `switch` | Toggle switch | Boolean value |
|
|
192
|
+
| `radio` | Radio group | `options`, `direction` |
|
|
193
|
+
| `file` | File upload | `accept`, `maxSize`, `maxFiles` |
|
|
194
|
+
| `date` | Date picker | `minDate`, `maxDate`, `dateFormat` |
|
|
195
|
+
| `time` | Time picker | `timeFormat` |
|
|
196
|
+
| `datetime` | Date + Time | `dateFormat`, `timeFormat` |
|
|
197
|
+
| `daterange` | Date range | `minDate`, `maxDate` |
|
|
198
|
+
|
|
199
|
+
### Validation Types
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
type ValidationRule =
|
|
203
|
+
| { type: "required"; message?: string }
|
|
204
|
+
| { type: "email"; message?: string }
|
|
205
|
+
| { type: "url"; message?: string }
|
|
206
|
+
| { type: "minLength"; value: number; message?: string }
|
|
207
|
+
| { type: "maxLength"; value: number; message?: string }
|
|
208
|
+
| { type: "min"; value: number; message?: string }
|
|
209
|
+
| { type: "max"; value: number; message?: string }
|
|
210
|
+
| { type: "pattern"; value: string; message?: string }
|
|
211
|
+
| { type: "regex"; value: RegExp; message?: string }
|
|
212
|
+
| { type: "fileSize"; value: number; message?: string }
|
|
213
|
+
| { type: "fileType"; value: string[]; message?: string }
|
|
214
|
+
| { type: "minDate"; value: Date; message?: string }
|
|
215
|
+
| { type: "maxDate"; value: Date; message?: string }
|
|
216
|
+
| { type: "integer"; message?: string }
|
|
217
|
+
| { type: "positive"; message?: string }
|
|
218
|
+
| { type: "negative"; message?: string }
|
|
219
|
+
| { type: "custom"; validate: (value: any) => boolean; message?: string };
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Conditional Visibility
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
{
|
|
226
|
+
id: "other-role",
|
|
227
|
+
name: "otherRole",
|
|
228
|
+
label: "Specify Role",
|
|
229
|
+
type: "text",
|
|
230
|
+
visibilityRules: [
|
|
231
|
+
{ field: "role", operator: "eq", value: "other" }
|
|
232
|
+
],
|
|
233
|
+
reserveSpace: true // Keeps layout stable
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Grid Layout
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
{
|
|
241
|
+
grid: {
|
|
242
|
+
colSpan: 6, // Desktop (default)
|
|
243
|
+
xs: 12, // Mobile (<640px)
|
|
244
|
+
sm: 6, // Tablet (640px+)
|
|
245
|
+
lg: 4 // Large desktop (1024px+)
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## 🎨 Theming
|
|
251
|
+
|
|
252
|
+
Formix UI uses Tailwind CSS 4.1 with CSS variables for theming:
|
|
253
|
+
|
|
254
|
+
```css
|
|
255
|
+
@theme {
|
|
256
|
+
--color-primary: oklch(0.6 0.2 250);
|
|
257
|
+
--color-background: oklch(1 0 0);
|
|
258
|
+
--color-foreground: oklch(0.2 0 0);
|
|
259
|
+
/* ... more variables */
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Toggle dark mode:
|
|
264
|
+
|
|
265
|
+
```tsx
|
|
266
|
+
import { ThemeProvider, ThemeSwitcher } from "formix-ui";
|
|
267
|
+
|
|
268
|
+
function App() {
|
|
269
|
+
return (
|
|
270
|
+
<ThemeProvider defaultTheme="system">
|
|
271
|
+
<ThemeSwitcher />
|
|
272
|
+
{/* Your forms */}
|
|
273
|
+
</ThemeProvider>
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## 🔧 Configuration
|
|
279
|
+
|
|
280
|
+
### TypeScript
|
|
281
|
+
|
|
282
|
+
```json
|
|
283
|
+
{
|
|
284
|
+
"compilerOptions": {
|
|
285
|
+
"paths": {
|
|
286
|
+
"@/*": ["./src/*"]
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Tailwind CSS
|
|
293
|
+
|
|
294
|
+
```js
|
|
295
|
+
// tailwind.config.js
|
|
296
|
+
export default {
|
|
297
|
+
content: [
|
|
298
|
+
"./index.html",
|
|
299
|
+
"./src/**/*.{js,ts,jsx,tsx}",
|
|
300
|
+
"./node_modules/formix-ui/**/*.{js,ts,jsx,tsx}",
|
|
301
|
+
],
|
|
302
|
+
};
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## 📖 Examples
|
|
306
|
+
|
|
307
|
+
Check out the `/examples` directory for:
|
|
308
|
+
|
|
309
|
+
- Basic form
|
|
310
|
+
- Multi-step wizard
|
|
311
|
+
- Dynamic fields
|
|
312
|
+
- File upload
|
|
313
|
+
- Async autocomplete
|
|
314
|
+
- Conditional logic
|
|
315
|
+
- Custom validation
|
|
316
|
+
|
|
317
|
+
## 🤝 Contributing
|
|
318
|
+
|
|
319
|
+
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
320
|
+
|
|
321
|
+
## 📄 License
|
|
322
|
+
|
|
323
|
+
MIT © Adarsh A
|
|
324
|
+
|
|
325
|
+
## 🙏 Acknowledgments
|
|
326
|
+
|
|
327
|
+
- Built with [React](https://reactjs.org/)
|
|
328
|
+
- Styled with [Tailwind CSS](https://tailwindcss.com/)
|
|
329
|
+
- Date pickers powered by Custom Native Components
|
|
330
|
+
- Validation with [Zod](https://zod.dev/)
|
|
331
|
+
|
|
332
|
+
## 🔗 Links
|
|
333
|
+
|
|
334
|
+
- [Documentation](https://adarshatl03.github.io/formix-ui/)
|
|
335
|
+
- [GitHub](https://github.com/adarshatl03/formix-ui)
|
|
336
|
+
- [NPM](https://www.npmjs.com/package/formix-ui)
|
|
337
|
+
- [Demo](https://adarshatl03.github.io/formix-ui/)
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
**Made with ❤️ by the Formix UI team**
|
package/dist/bin/index.js
CHANGED
|
@@ -9,186 +9,186 @@ import ora from "ora";
|
|
|
9
9
|
import { fileURLToPath } from "url";
|
|
10
10
|
import { registry, getComponent } from "./registry.js";
|
|
11
11
|
// Tailwind v4 CSS Template
|
|
12
|
-
const TAILWIND_V4_CSS = `@import "tailwindcss";
|
|
13
|
-
@source "../node_modules/r-form-engine/dist";
|
|
14
|
-
|
|
15
|
-
@variant dark (&:where(.dark, .dark *));
|
|
16
|
-
|
|
17
|
-
/* =========================================
|
|
18
|
-
BASE PALETTE (STATIC)
|
|
19
|
-
========================================= */
|
|
20
|
-
:root {
|
|
21
|
-
--color-primary:#003c71;
|
|
22
|
-
--color-secondary:#ff681d;
|
|
23
|
-
--brand-secondary-orange: #ff681d; /* New explicit brand variable */
|
|
24
|
-
--zinc-0: #ffffff;
|
|
25
|
-
--zinc-50: oklch(0.985 0.01 240);
|
|
26
|
-
--zinc-100: oklch(0.965 0.01 240);
|
|
27
|
-
--zinc-200: oklch(0.920 0.02 240);
|
|
28
|
-
--zinc-300: oklch(0.870 0.03 240);
|
|
29
|
-
--zinc-400: oklch(0.700 0.04 240);
|
|
30
|
-
--zinc-500: oklch(0.550 0.05 240);
|
|
31
|
-
--zinc-600: oklch(0.440 0.05 240);
|
|
32
|
-
--zinc-700: oklch(0.350 0.05 240);
|
|
33
|
-
--zinc-800: oklch(0.270 0.05 240);
|
|
34
|
-
--zinc-900: oklch(0.200 0.04 240);
|
|
35
|
-
--zinc-950: oklch(0.130 0.03 240);
|
|
36
|
-
|
|
37
|
-
--primary-400: oklch(0.65 0.18 260);
|
|
38
|
-
--primary-500: oklch(0.55 0.22 260);
|
|
39
|
-
--primary-600: oklch(0.45 0.22 260);
|
|
40
|
-
|
|
41
|
-
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/* =========================================
|
|
45
|
-
LIGHT THEME (VISIBLY LIGHT)
|
|
46
|
-
========================================= */
|
|
47
|
-
:root {
|
|
48
|
-
|
|
49
|
-
--color-background: var(--zinc-50);
|
|
50
|
-
--color-foreground: var(--zinc-900);
|
|
51
|
-
|
|
52
|
-
--color-card: var(--zinc-0);
|
|
53
|
-
--color-card-foreground: var(--zinc-900);
|
|
54
|
-
|
|
55
|
-
--color-popover: var(--zinc-0);
|
|
56
|
-
--color-popover-foreground: var(--zinc-900);
|
|
57
|
-
|
|
58
|
-
--color-primary: var(--primary-500);
|
|
59
|
-
--color-primary-foreground: #ffffff;
|
|
60
|
-
|
|
61
|
-
--color-secondary: var(--zinc-100);
|
|
62
|
-
--color-secondary-foreground: var(--zinc-800);
|
|
63
|
-
|
|
64
|
-
--color-muted: var(--zinc-100);
|
|
65
|
-
--color-muted-foreground: var(--zinc-500);
|
|
66
|
-
|
|
67
|
-
--color-accent: var(--zinc-100);
|
|
68
|
-
--color-accent-foreground: var(--zinc-800);
|
|
69
|
-
|
|
70
|
-
--color-destructive: oklch(0.63 0.26 29);
|
|
71
|
-
--color-destructive-foreground: #ffffff;
|
|
72
|
-
|
|
73
|
-
--color-border: var(--zinc-300);
|
|
74
|
-
--color-input: var(--zinc-0);
|
|
75
|
-
--color-ring: var(--primary-500);
|
|
76
|
-
|
|
77
|
-
--color-control-checked: var(--color-primary);
|
|
78
|
-
|
|
79
|
-
--color-tooltip-bg: var(--zinc-900);
|
|
80
|
-
--color-tooltip-text: #ffffff;
|
|
81
|
-
|
|
82
|
-
--color-surface-50: var(--zinc-50);
|
|
83
|
-
--color-surface-100: var(--zinc-100);
|
|
84
|
-
--color-surface-200: var(--zinc-200);
|
|
85
|
-
--color-surface-300: var(--zinc-300);
|
|
86
|
-
--color-surface-400: var(--zinc-400);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
/* =========================================
|
|
92
|
-
MANUAL DARK MODE
|
|
93
|
-
========================================= */
|
|
94
|
-
html.dark, .dark {
|
|
95
|
-
color-scheme: dark;
|
|
96
|
-
|
|
97
|
-
--color-background: var(--zinc-950);
|
|
98
|
-
--color-foreground: var(--zinc-50);
|
|
99
|
-
|
|
100
|
-
--color-card: var(--zinc-900);
|
|
101
|
-
--color-card-foreground: var(--zinc-50);
|
|
102
|
-
|
|
103
|
-
--color-popover: var(--zinc-900);
|
|
104
|
-
--color-popover-foreground: var(--zinc-50);
|
|
105
|
-
|
|
106
|
-
--color-primary: var(--primary-400);
|
|
107
|
-
--color-primary-foreground: #ffffff;
|
|
108
|
-
|
|
109
|
-
--color-secondary: var(--zinc-800);
|
|
110
|
-
--color-secondary-foreground: var(--zinc-50);
|
|
111
|
-
|
|
112
|
-
--color-muted: var(--zinc-800);
|
|
113
|
-
--color-muted-foreground: var(--zinc-400);
|
|
114
|
-
|
|
115
|
-
--color-accent: var(--zinc-800);
|
|
116
|
-
--color-accent-foreground: var(--zinc-50);
|
|
117
|
-
|
|
118
|
-
--color-destructive: oklch(0.4 0.2 29);
|
|
119
|
-
|
|
120
|
-
--color-border: var(--zinc-800);
|
|
121
|
-
--color-input: var(--zinc-900);
|
|
122
|
-
--color-ring: var(--primary-400);
|
|
123
|
-
|
|
124
|
-
--color-control-checked: var(--brand-secondary-orange);
|
|
125
|
-
|
|
126
|
-
--color-tooltip-bg: var(--zinc-800);
|
|
127
|
-
--color-tooltip-text: var(--zinc-50);
|
|
128
|
-
|
|
129
|
-
--color-surface-50: var(--zinc-950);
|
|
130
|
-
--color-surface-100: var(--zinc-900);
|
|
131
|
-
--color-surface-200: var(--zinc-800);
|
|
132
|
-
--color-surface-300: var(--zinc-700);
|
|
133
|
-
--color-surface-400: var(--zinc-600);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/* =========================================
|
|
137
|
-
TAILWIND v4 THEME MAP
|
|
138
|
-
========================================= */
|
|
139
|
-
@theme {
|
|
140
|
-
--color-background: var(--color-background);
|
|
141
|
-
--color-foreground: var(--color-foreground);
|
|
142
|
-
--color-card: var(--color-card);
|
|
143
|
-
--color-card-foreground: var(--color-card-foreground);
|
|
144
|
-
--color-popover: var(--color-popover);
|
|
145
|
-
--color-popover-foreground: var(--color-popover-foreground);
|
|
146
|
-
--color-primary: var(--color-primary);
|
|
147
|
-
--color-primary-foreground: var(--color-primary-foreground);
|
|
148
|
-
--color-secondary: var(--color-secondary);
|
|
149
|
-
--color-secondary-foreground: var(--color-secondary-foreground);
|
|
150
|
-
--color-muted: var(--color-muted);
|
|
151
|
-
--color-muted-foreground: var(--color-muted-foreground);
|
|
152
|
-
--color-accent: var(--color-accent);
|
|
153
|
-
--color-accent-foreground: var(--color-accent-foreground);
|
|
154
|
-
--color-destructive: var(--color-destructive);
|
|
155
|
-
--color-destructive-foreground: var(--color-destructive-foreground);
|
|
156
|
-
--color-border: var(--color-border);
|
|
157
|
-
--color-input: var(--color-input);
|
|
158
|
-
--color-ring: var(--color-ring);
|
|
159
|
-
--color-control-checked: var(--color-control-checked);
|
|
160
|
-
--color-tooltip-bg: var(--color-tooltip-bg);
|
|
161
|
-
--color-tooltip-text: var(--color-tooltip-text);
|
|
162
|
-
--color-surface-50: var(--color-surface-50);
|
|
163
|
-
--color-surface-100: var(--color-surface-100);
|
|
164
|
-
--color-surface-200: var(--color-surface-200);
|
|
165
|
-
--color-surface-300: var(--color-surface-300);
|
|
166
|
-
--color-surface-400: var(--color-surface-400);
|
|
167
|
-
--font-sans: var(--font-sans);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/* =========================================
|
|
171
|
-
GLOBALS
|
|
172
|
-
========================================= */
|
|
173
|
-
body {
|
|
174
|
-
background-color: var(--color-background);
|
|
175
|
-
color: var(--color-foreground);
|
|
176
|
-
font-family: var(--font-sans);
|
|
177
|
-
-webkit-font-smoothing: antialiased;
|
|
178
|
-
-moz-osx-font-smoothing: grayscale;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
@layer base {
|
|
182
|
-
input:focus,
|
|
183
|
-
textarea:focus,
|
|
184
|
-
select:focus,
|
|
185
|
-
.ring-2,
|
|
186
|
-
.focus\\:ring-2:focus,
|
|
187
|
-
.focus-within\\:ring-2:focus-within {
|
|
188
|
-
outline: none !important;
|
|
189
|
-
box-shadow: none !important;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
12
|
+
const TAILWIND_V4_CSS = `@import "tailwindcss";
|
|
13
|
+
@source "../node_modules/r-form-engine/dist";
|
|
14
|
+
|
|
15
|
+
@variant dark (&:where(.dark, .dark *));
|
|
16
|
+
|
|
17
|
+
/* =========================================
|
|
18
|
+
BASE PALETTE (STATIC)
|
|
19
|
+
========================================= */
|
|
20
|
+
:root {
|
|
21
|
+
--color-primary:#003c71;
|
|
22
|
+
--color-secondary:#ff681d;
|
|
23
|
+
--brand-secondary-orange: #ff681d; /* New explicit brand variable */
|
|
24
|
+
--zinc-0: #ffffff;
|
|
25
|
+
--zinc-50: oklch(0.985 0.01 240);
|
|
26
|
+
--zinc-100: oklch(0.965 0.01 240);
|
|
27
|
+
--zinc-200: oklch(0.920 0.02 240);
|
|
28
|
+
--zinc-300: oklch(0.870 0.03 240);
|
|
29
|
+
--zinc-400: oklch(0.700 0.04 240);
|
|
30
|
+
--zinc-500: oklch(0.550 0.05 240);
|
|
31
|
+
--zinc-600: oklch(0.440 0.05 240);
|
|
32
|
+
--zinc-700: oklch(0.350 0.05 240);
|
|
33
|
+
--zinc-800: oklch(0.270 0.05 240);
|
|
34
|
+
--zinc-900: oklch(0.200 0.04 240);
|
|
35
|
+
--zinc-950: oklch(0.130 0.03 240);
|
|
36
|
+
|
|
37
|
+
--primary-400: oklch(0.65 0.18 260);
|
|
38
|
+
--primary-500: oklch(0.55 0.22 260);
|
|
39
|
+
--primary-600: oklch(0.45 0.22 260);
|
|
40
|
+
|
|
41
|
+
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* =========================================
|
|
45
|
+
LIGHT THEME (VISIBLY LIGHT)
|
|
46
|
+
========================================= */
|
|
47
|
+
:root {
|
|
48
|
+
|
|
49
|
+
--color-background: var(--zinc-50);
|
|
50
|
+
--color-foreground: var(--zinc-900);
|
|
51
|
+
|
|
52
|
+
--color-card: var(--zinc-0);
|
|
53
|
+
--color-card-foreground: var(--zinc-900);
|
|
54
|
+
|
|
55
|
+
--color-popover: var(--zinc-0);
|
|
56
|
+
--color-popover-foreground: var(--zinc-900);
|
|
57
|
+
|
|
58
|
+
--color-primary: var(--primary-500);
|
|
59
|
+
--color-primary-foreground: #ffffff;
|
|
60
|
+
|
|
61
|
+
--color-secondary: var(--zinc-100);
|
|
62
|
+
--color-secondary-foreground: var(--zinc-800);
|
|
63
|
+
|
|
64
|
+
--color-muted: var(--zinc-100);
|
|
65
|
+
--color-muted-foreground: var(--zinc-500);
|
|
66
|
+
|
|
67
|
+
--color-accent: var(--zinc-100);
|
|
68
|
+
--color-accent-foreground: var(--zinc-800);
|
|
69
|
+
|
|
70
|
+
--color-destructive: oklch(0.63 0.26 29);
|
|
71
|
+
--color-destructive-foreground: #ffffff;
|
|
72
|
+
|
|
73
|
+
--color-border: var(--zinc-300);
|
|
74
|
+
--color-input: var(--zinc-0);
|
|
75
|
+
--color-ring: var(--primary-500);
|
|
76
|
+
|
|
77
|
+
--color-control-checked: var(--color-primary);
|
|
78
|
+
|
|
79
|
+
--color-tooltip-bg: var(--zinc-900);
|
|
80
|
+
--color-tooltip-text: #ffffff;
|
|
81
|
+
|
|
82
|
+
--color-surface-50: var(--zinc-50);
|
|
83
|
+
--color-surface-100: var(--zinc-100);
|
|
84
|
+
--color-surface-200: var(--zinc-200);
|
|
85
|
+
--color-surface-300: var(--zinc-300);
|
|
86
|
+
--color-surface-400: var(--zinc-400);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
/* =========================================
|
|
92
|
+
MANUAL DARK MODE
|
|
93
|
+
========================================= */
|
|
94
|
+
html.dark, .dark {
|
|
95
|
+
color-scheme: dark;
|
|
96
|
+
|
|
97
|
+
--color-background: var(--zinc-950);
|
|
98
|
+
--color-foreground: var(--zinc-50);
|
|
99
|
+
|
|
100
|
+
--color-card: var(--zinc-900);
|
|
101
|
+
--color-card-foreground: var(--zinc-50);
|
|
102
|
+
|
|
103
|
+
--color-popover: var(--zinc-900);
|
|
104
|
+
--color-popover-foreground: var(--zinc-50);
|
|
105
|
+
|
|
106
|
+
--color-primary: var(--primary-400);
|
|
107
|
+
--color-primary-foreground: #ffffff;
|
|
108
|
+
|
|
109
|
+
--color-secondary: var(--zinc-800);
|
|
110
|
+
--color-secondary-foreground: var(--zinc-50);
|
|
111
|
+
|
|
112
|
+
--color-muted: var(--zinc-800);
|
|
113
|
+
--color-muted-foreground: var(--zinc-400);
|
|
114
|
+
|
|
115
|
+
--color-accent: var(--zinc-800);
|
|
116
|
+
--color-accent-foreground: var(--zinc-50);
|
|
117
|
+
|
|
118
|
+
--color-destructive: oklch(0.4 0.2 29);
|
|
119
|
+
|
|
120
|
+
--color-border: var(--zinc-800);
|
|
121
|
+
--color-input: var(--zinc-900);
|
|
122
|
+
--color-ring: var(--primary-400);
|
|
123
|
+
|
|
124
|
+
--color-control-checked: var(--brand-secondary-orange);
|
|
125
|
+
|
|
126
|
+
--color-tooltip-bg: var(--zinc-800);
|
|
127
|
+
--color-tooltip-text: var(--zinc-50);
|
|
128
|
+
|
|
129
|
+
--color-surface-50: var(--zinc-950);
|
|
130
|
+
--color-surface-100: var(--zinc-900);
|
|
131
|
+
--color-surface-200: var(--zinc-800);
|
|
132
|
+
--color-surface-300: var(--zinc-700);
|
|
133
|
+
--color-surface-400: var(--zinc-600);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* =========================================
|
|
137
|
+
TAILWIND v4 THEME MAP
|
|
138
|
+
========================================= */
|
|
139
|
+
@theme {
|
|
140
|
+
--color-background: var(--color-background);
|
|
141
|
+
--color-foreground: var(--color-foreground);
|
|
142
|
+
--color-card: var(--color-card);
|
|
143
|
+
--color-card-foreground: var(--color-card-foreground);
|
|
144
|
+
--color-popover: var(--color-popover);
|
|
145
|
+
--color-popover-foreground: var(--color-popover-foreground);
|
|
146
|
+
--color-primary: var(--color-primary);
|
|
147
|
+
--color-primary-foreground: var(--color-primary-foreground);
|
|
148
|
+
--color-secondary: var(--color-secondary);
|
|
149
|
+
--color-secondary-foreground: var(--color-secondary-foreground);
|
|
150
|
+
--color-muted: var(--color-muted);
|
|
151
|
+
--color-muted-foreground: var(--color-muted-foreground);
|
|
152
|
+
--color-accent: var(--color-accent);
|
|
153
|
+
--color-accent-foreground: var(--color-accent-foreground);
|
|
154
|
+
--color-destructive: var(--color-destructive);
|
|
155
|
+
--color-destructive-foreground: var(--color-destructive-foreground);
|
|
156
|
+
--color-border: var(--color-border);
|
|
157
|
+
--color-input: var(--color-input);
|
|
158
|
+
--color-ring: var(--color-ring);
|
|
159
|
+
--color-control-checked: var(--color-control-checked);
|
|
160
|
+
--color-tooltip-bg: var(--color-tooltip-bg);
|
|
161
|
+
--color-tooltip-text: var(--color-tooltip-text);
|
|
162
|
+
--color-surface-50: var(--color-surface-50);
|
|
163
|
+
--color-surface-100: var(--color-surface-100);
|
|
164
|
+
--color-surface-200: var(--color-surface-200);
|
|
165
|
+
--color-surface-300: var(--color-surface-300);
|
|
166
|
+
--color-surface-400: var(--color-surface-400);
|
|
167
|
+
--font-sans: var(--font-sans);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* =========================================
|
|
171
|
+
GLOBALS
|
|
172
|
+
========================================= */
|
|
173
|
+
body {
|
|
174
|
+
background-color: var(--color-background);
|
|
175
|
+
color: var(--color-foreground);
|
|
176
|
+
font-family: var(--font-sans);
|
|
177
|
+
-webkit-font-smoothing: antialiased;
|
|
178
|
+
-moz-osx-font-smoothing: grayscale;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
@layer base {
|
|
182
|
+
input:focus,
|
|
183
|
+
textarea:focus,
|
|
184
|
+
select:focus,
|
|
185
|
+
.ring-2,
|
|
186
|
+
.focus\\:ring-2:focus,
|
|
187
|
+
.focus-within\\:ring-2:focus-within {
|
|
188
|
+
outline: none !important;
|
|
189
|
+
box-shadow: none !important;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
192
|
`;
|
|
193
193
|
// Get package version
|
|
194
194
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -214,117 +214,117 @@ const generateLandingPageContent = (config, version) => {
|
|
|
214
214
|
const componentToUse = formState === "formik" ? "FormikSchemaForm" : "SchemaForm";
|
|
215
215
|
// Note: We use Tailwind v4 classes assuming it's configured.
|
|
216
216
|
// We use standard React imports since the library handles the rest.
|
|
217
|
-
return `${isNext ? '"use client";\n' : ""}import { ${componentToUse}, ThemeProvider } from 'r-form-engine';
|
|
218
|
-
import type { FormSchema } from 'r-form-engine';
|
|
219
|
-
${isNext ? "import './globals.css';" : "import 'r-form-engine/styles';"}
|
|
220
|
-
|
|
221
|
-
const schema: FormSchema = {
|
|
222
|
-
title: "Welcome to FormEngine",
|
|
223
|
-
description: "Your project is pre-configured with ${validationLib} and ${formState}.",
|
|
224
|
-
fields: [
|
|
225
|
-
{
|
|
226
|
-
id: "name",
|
|
227
|
-
name: "name",
|
|
228
|
-
label: "What's your name?",
|
|
229
|
-
type: "text",
|
|
230
|
-
placeholder: "Enter your name",
|
|
231
|
-
validation: [{ type: "required", message: "Name is required" }],
|
|
232
|
-
grid: { colSpan: 12 }
|
|
233
|
-
},
|
|
234
|
-
{
|
|
235
|
-
id: "framework",
|
|
236
|
-
name: "framework",
|
|
237
|
-
label: "Framework",
|
|
238
|
-
type: "text",
|
|
239
|
-
defaultValue: "${framework}",
|
|
240
|
-
readOnly: true,
|
|
241
|
-
grid: { colSpan: 4 }
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
id: "validation",
|
|
245
|
-
name: "validation",
|
|
246
|
-
label: "Validation",
|
|
247
|
-
type: "text",
|
|
248
|
-
defaultValue: "${validationLib}",
|
|
249
|
-
readOnly: true,
|
|
250
|
-
grid: { colSpan: 4 }
|
|
251
|
-
},
|
|
252
|
-
{
|
|
253
|
-
id: "formState",
|
|
254
|
-
name: "formState",
|
|
255
|
-
label: "State Manager",
|
|
256
|
-
type: "text",
|
|
257
|
-
defaultValue: "${formState}",
|
|
258
|
-
readOnly: true,
|
|
259
|
-
grid: { colSpan: 4 }
|
|
260
|
-
}
|
|
261
|
-
]
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
export default function ${isNext ? "Page" : "App"}() {
|
|
265
|
-
return (
|
|
266
|
-
<ThemeProvider defaultTheme="system">
|
|
267
|
-
<div className="min-h-screen bg-background text-foreground p-8 flex flex-col items-center border-t-4 border-primary">
|
|
268
|
-
<header className="mb-16 text-center max-w-3xl">
|
|
269
|
-
<div className="inline-block px-4 py-1.5 mb-6 text-sm font-bold bg-primary/10 text-primary rounded-full border border-primary/20 uppercase tracking-widest">
|
|
270
|
-
v${version} Successfully Scaffolded
|
|
271
|
-
</div>
|
|
272
|
-
<h1 className="text-5xl md:text-7xl font-black tracking-tighter mb-6">
|
|
273
|
-
Build Forms <span className="text-primary italic">Faster.</span>
|
|
274
|
-
</h1>
|
|
275
|
-
<p className="text-muted-foreground text-xl leading-relaxed mx-auto max-w-xl">
|
|
276
|
-
Your <strong>${framework}</strong> project is ready with <strong>${validationLib}</strong> validation and <strong>${formState}</strong> state management.
|
|
277
|
-
</p>
|
|
278
|
-
<div className="mt-10 flex flex-wrap gap-4 justify-center">
|
|
279
|
-
<a
|
|
280
|
-
href="https://adarshatl03.github.io/form-engine/"
|
|
281
|
-
target="_blank"
|
|
282
|
-
className="px-10 py-4 bg-primary text-primary-foreground rounded-2xl font-black hover:scale-105 transition-all shadow-xl shadow-primary/25"
|
|
283
|
-
>
|
|
284
|
-
Documentation
|
|
285
|
-
</a>
|
|
286
|
-
<a
|
|
287
|
-
href="https://github.com/adarshatl03/form-engine"
|
|
288
|
-
target="_blank"
|
|
289
|
-
className="px-10 py-4 bg-card border-2 border-border rounded-2xl font-bold hover:bg-muted transition-colors"
|
|
290
|
-
>
|
|
291
|
-
GitHub
|
|
292
|
-
</a>
|
|
293
|
-
</div>
|
|
294
|
-
</header>
|
|
295
|
-
|
|
296
|
-
<main className="w-full max-w-2xl bg-card rounded-[2.5rem] shadow-2xl overflow-hidden border border-border">
|
|
297
|
-
<div className="p-12">
|
|
298
|
-
<h2 className="text-3xl font-black mb-10 tracking-tight">Quick Start</h2>
|
|
299
|
-
<${componentToUse}
|
|
300
|
-
schema={schema}
|
|
301
|
-
onSubmit={(v) => {
|
|
302
|
-
console.log("Form Values:", v);
|
|
303
|
-
alert("Submission successful! check console.");
|
|
304
|
-
}}
|
|
305
|
-
/>
|
|
306
|
-
</div>
|
|
307
|
-
<div className="bg-muted p-8 flex flex-col sm:flex-row justify-between items-center gap-6 border-t border-border">
|
|
308
|
-
<div className="text-center sm:text-left">
|
|
309
|
-
<p className="text-xs uppercase tracking-widest font-black text-muted-foreground mb-1">Project Stack</p>
|
|
310
|
-
<p className="text-sm font-bold opacity-80">${framework} • ${validationLib} • ${formState}</p>
|
|
311
|
-
</div>
|
|
312
|
-
<button
|
|
313
|
-
onClick={() => window.open('https://adarshatl03.github.io/form-engine/playground', '_blank')}
|
|
314
|
-
className="px-6 py-2 bg-foreground text-background rounded-full font-bold text-sm hover:opacity-90 transition-opacity"
|
|
315
|
-
>
|
|
316
|
-
Open Form Builder →
|
|
317
|
-
</button>
|
|
318
|
-
</div>
|
|
319
|
-
</main>
|
|
320
|
-
|
|
321
|
-
<footer className="mt-20 text-muted-foreground font-medium text-sm">
|
|
322
|
-
Built with r-form-engine • The modern form stack
|
|
323
|
-
</footer>
|
|
324
|
-
</div>
|
|
325
|
-
</ThemeProvider>
|
|
326
|
-
);
|
|
327
|
-
}
|
|
217
|
+
return `${isNext ? '"use client";\n' : ""}import { ${componentToUse}, ThemeProvider } from 'r-form-engine';
|
|
218
|
+
import type { FormSchema } from 'r-form-engine';
|
|
219
|
+
${isNext ? "import './globals.css';" : "import 'r-form-engine/styles';"}
|
|
220
|
+
|
|
221
|
+
const schema: FormSchema = {
|
|
222
|
+
title: "Welcome to FormEngine",
|
|
223
|
+
description: "Your project is pre-configured with ${validationLib} and ${formState}.",
|
|
224
|
+
fields: [
|
|
225
|
+
{
|
|
226
|
+
id: "name",
|
|
227
|
+
name: "name",
|
|
228
|
+
label: "What's your name?",
|
|
229
|
+
type: "text",
|
|
230
|
+
placeholder: "Enter your name",
|
|
231
|
+
validation: [{ type: "required", message: "Name is required" }],
|
|
232
|
+
grid: { colSpan: 12 }
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
id: "framework",
|
|
236
|
+
name: "framework",
|
|
237
|
+
label: "Framework",
|
|
238
|
+
type: "text",
|
|
239
|
+
defaultValue: "${framework}",
|
|
240
|
+
readOnly: true,
|
|
241
|
+
grid: { colSpan: 4 }
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
id: "validation",
|
|
245
|
+
name: "validation",
|
|
246
|
+
label: "Validation",
|
|
247
|
+
type: "text",
|
|
248
|
+
defaultValue: "${validationLib}",
|
|
249
|
+
readOnly: true,
|
|
250
|
+
grid: { colSpan: 4 }
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
id: "formState",
|
|
254
|
+
name: "formState",
|
|
255
|
+
label: "State Manager",
|
|
256
|
+
type: "text",
|
|
257
|
+
defaultValue: "${formState}",
|
|
258
|
+
readOnly: true,
|
|
259
|
+
grid: { colSpan: 4 }
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
export default function ${isNext ? "Page" : "App"}() {
|
|
265
|
+
return (
|
|
266
|
+
<ThemeProvider defaultTheme="system">
|
|
267
|
+
<div className="min-h-screen bg-background text-foreground p-8 flex flex-col items-center border-t-4 border-primary">
|
|
268
|
+
<header className="mb-16 text-center max-w-3xl">
|
|
269
|
+
<div className="inline-block px-4 py-1.5 mb-6 text-sm font-bold bg-primary/10 text-primary rounded-full border border-primary/20 uppercase tracking-widest">
|
|
270
|
+
v${version} Successfully Scaffolded
|
|
271
|
+
</div>
|
|
272
|
+
<h1 className="text-5xl md:text-7xl font-black tracking-tighter mb-6">
|
|
273
|
+
Build Forms <span className="text-primary italic">Faster.</span>
|
|
274
|
+
</h1>
|
|
275
|
+
<p className="text-muted-foreground text-xl leading-relaxed mx-auto max-w-xl">
|
|
276
|
+
Your <strong>${framework}</strong> project is ready with <strong>${validationLib}</strong> validation and <strong>${formState}</strong> state management.
|
|
277
|
+
</p>
|
|
278
|
+
<div className="mt-10 flex flex-wrap gap-4 justify-center">
|
|
279
|
+
<a
|
|
280
|
+
href="https://adarshatl03.github.io/form-engine/"
|
|
281
|
+
target="_blank"
|
|
282
|
+
className="px-10 py-4 bg-primary text-primary-foreground rounded-2xl font-black hover:scale-105 transition-all shadow-xl shadow-primary/25"
|
|
283
|
+
>
|
|
284
|
+
Documentation
|
|
285
|
+
</a>
|
|
286
|
+
<a
|
|
287
|
+
href="https://github.com/adarshatl03/form-engine"
|
|
288
|
+
target="_blank"
|
|
289
|
+
className="px-10 py-4 bg-card border-2 border-border rounded-2xl font-bold hover:bg-muted transition-colors"
|
|
290
|
+
>
|
|
291
|
+
GitHub
|
|
292
|
+
</a>
|
|
293
|
+
</div>
|
|
294
|
+
</header>
|
|
295
|
+
|
|
296
|
+
<main className="w-full max-w-2xl bg-card rounded-[2.5rem] shadow-2xl overflow-hidden border border-border">
|
|
297
|
+
<div className="p-12">
|
|
298
|
+
<h2 className="text-3xl font-black mb-10 tracking-tight">Quick Start</h2>
|
|
299
|
+
<${componentToUse}
|
|
300
|
+
schema={schema}
|
|
301
|
+
onSubmit={(v) => {
|
|
302
|
+
console.log("Form Values:", v);
|
|
303
|
+
alert("Submission successful! check console.");
|
|
304
|
+
}}
|
|
305
|
+
/>
|
|
306
|
+
</div>
|
|
307
|
+
<div className="bg-muted p-8 flex flex-col sm:flex-row justify-between items-center gap-6 border-t border-border">
|
|
308
|
+
<div className="text-center sm:text-left">
|
|
309
|
+
<p className="text-xs uppercase tracking-widest font-black text-muted-foreground mb-1">Project Stack</p>
|
|
310
|
+
<p className="text-sm font-bold opacity-80">${framework} • ${validationLib} • ${formState}</p>
|
|
311
|
+
</div>
|
|
312
|
+
<button
|
|
313
|
+
onClick={() => window.open('https://adarshatl03.github.io/form-engine/playground', '_blank')}
|
|
314
|
+
className="px-6 py-2 bg-foreground text-background rounded-full font-bold text-sm hover:opacity-90 transition-opacity"
|
|
315
|
+
>
|
|
316
|
+
Open Form Builder →
|
|
317
|
+
</button>
|
|
318
|
+
</div>
|
|
319
|
+
</main>
|
|
320
|
+
|
|
321
|
+
<footer className="mt-20 text-muted-foreground font-medium text-sm">
|
|
322
|
+
Built with r-form-engine • The modern form stack
|
|
323
|
+
</footer>
|
|
324
|
+
</div>
|
|
325
|
+
</ThemeProvider>
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
328
|
`;
|
|
329
329
|
};
|
|
330
330
|
// Utility: Resolve package root
|
|
@@ -751,12 +751,12 @@ program
|
|
|
751
751
|
const cssPath = "app/globals.css";
|
|
752
752
|
fs.ensureDirSync(path.dirname(cssPath));
|
|
753
753
|
fs.writeFileSync(cssPath, TAILWIND_V4_CSS);
|
|
754
|
-
const postcssContent = `const config = {
|
|
755
|
-
plugins: {
|
|
756
|
-
'@tailwindcss/postcss': {},
|
|
757
|
-
},
|
|
758
|
-
};
|
|
759
|
-
export default config;
|
|
754
|
+
const postcssContent = `const config = {
|
|
755
|
+
plugins: {
|
|
756
|
+
'@tailwindcss/postcss': {},
|
|
757
|
+
},
|
|
758
|
+
};
|
|
759
|
+
export default config;
|
|
760
760
|
`;
|
|
761
761
|
fs.writeFileSync("postcss.config.mjs", postcssContent);
|
|
762
762
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "formix-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -65,12 +65,12 @@
|
|
|
65
65
|
"license": "MIT",
|
|
66
66
|
"repository": {
|
|
67
67
|
"type": "git",
|
|
68
|
-
"url": "
|
|
68
|
+
"url": "https://github.com/adarshatl03/FormixUI.git"
|
|
69
69
|
},
|
|
70
70
|
"bugs": {
|
|
71
|
-
"url": "https://github.com/adarshatl03/
|
|
71
|
+
"url": "https://github.com/adarshatl03/FormixUI/issues"
|
|
72
72
|
},
|
|
73
|
-
"homepage": "https://adarshatl03.github.io/
|
|
73
|
+
"homepage": "https://adarshatl03.github.io/FormixUI/",
|
|
74
74
|
"peerDependencies": {
|
|
75
75
|
"formik": ">=2.4.0",
|
|
76
76
|
"lucide-react": ">=0.1.0",
|