config-driven-form 1.0.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/README.md +46 -0
- package/dist/index.css +176 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.mts +36 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +250 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +243 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +78 -0
package/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Config-Driven Form
|
|
2
|
+
|
|
3
|
+
A highly scalable, config-driven React form library that dynamically generates beautiful, fully validated forms directly from JSON Schema.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Performant**: Built on top of `react-hook-form` and `ajv` to minimize re-renders and handle complex schemas efficiently.
|
|
8
|
+
- **Extensible**: Easily add custom field types (like rich-text editors, maps, or file uploaders) using our custom `FieldRenderer` engine.
|
|
9
|
+
- **Rich Text Support**: Built-in integration with `Tiptap` for rich text editing.
|
|
10
|
+
- **Beautiful by Default**: Features a modern, glassmorphic design system out of the box using pure CSS.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install config-driven-form react-hook-form
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
import React from 'react';
|
|
22
|
+
import { SchemaForm, JSONSchema } from 'config-driven-form';
|
|
23
|
+
import 'config-driven-form/dist/index.css';
|
|
24
|
+
|
|
25
|
+
const mySchema: JSONSchema = {
|
|
26
|
+
type: 'object',
|
|
27
|
+
title: 'Contact Us',
|
|
28
|
+
properties: {
|
|
29
|
+
email: { type: 'string', format: 'email', title: 'Email Address' },
|
|
30
|
+
message: { type: 'string', format: 'rich-text', title: 'Your Message' },
|
|
31
|
+
},
|
|
32
|
+
required: ['email'],
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default function App() {
|
|
36
|
+
return (
|
|
37
|
+
<div style={{ padding: '2rem' }}>
|
|
38
|
+
<SchemaForm schema={mySchema} onSubmit={(data) => console.log(data)} />
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Contributing
|
|
45
|
+
|
|
46
|
+
We welcome contributions! If you want to fix a bug, add a new field type, or improve the documentation, please read our [Developer's Guide (CONTRIBUTING.md)](./CONTRIBUTING.md) to get started with your local development environment.
|
package/dist/index.css
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/* src/styles/form.css */
|
|
2
|
+
:root {
|
|
3
|
+
--cdf-primary: #6366f1;
|
|
4
|
+
--cdf-primary-hover: #4f46e5;
|
|
5
|
+
--cdf-primary-light: rgba(99, 102, 241, 0.1);
|
|
6
|
+
--cdf-error: #ef4444;
|
|
7
|
+
--cdf-error-light: rgba(239, 68, 68, 0.1);
|
|
8
|
+
--cdf-bg: #ffffff;
|
|
9
|
+
--cdf-surface: #f8fafc;
|
|
10
|
+
--cdf-border: #e2e8f0;
|
|
11
|
+
--cdf-border-focus: #94a3b8;
|
|
12
|
+
--cdf-text: #0f172a;
|
|
13
|
+
--cdf-text-muted: #64748b;
|
|
14
|
+
--cdf-radius: 12px;
|
|
15
|
+
--cdf-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
|
16
|
+
--cdf-shadow-focus: 0 0 0 4px rgba(99, 102, 241, 0.15);
|
|
17
|
+
--cdf-font:
|
|
18
|
+
"Inter",
|
|
19
|
+
-apple-system,
|
|
20
|
+
BlinkMacSystemFont,
|
|
21
|
+
"Segoe UI",
|
|
22
|
+
Roboto,
|
|
23
|
+
sans-serif;
|
|
24
|
+
--cdf-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
25
|
+
}
|
|
26
|
+
.cdf-form-container {
|
|
27
|
+
font-family: var(--cdf-font);
|
|
28
|
+
color: var(--cdf-text);
|
|
29
|
+
background: var(--cdf-bg);
|
|
30
|
+
border-radius: var(--cdf-radius);
|
|
31
|
+
padding: 2rem;
|
|
32
|
+
box-shadow: var(--cdf-shadow);
|
|
33
|
+
max-width: 600px;
|
|
34
|
+
margin: 0 auto;
|
|
35
|
+
border: 1px solid var(--cdf-border);
|
|
36
|
+
}
|
|
37
|
+
.cdf-form-title {
|
|
38
|
+
font-size: 1.5rem;
|
|
39
|
+
font-weight: 600;
|
|
40
|
+
margin-bottom: 1.5rem;
|
|
41
|
+
color: var(--cdf-text);
|
|
42
|
+
}
|
|
43
|
+
.cdf-field-group {
|
|
44
|
+
margin-bottom: 1.25rem;
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-direction: column;
|
|
47
|
+
}
|
|
48
|
+
.cdf-label {
|
|
49
|
+
font-size: 0.875rem;
|
|
50
|
+
font-weight: 500;
|
|
51
|
+
margin-bottom: 0.5rem;
|
|
52
|
+
color: var(--cdf-text);
|
|
53
|
+
display: flex;
|
|
54
|
+
align-items: center;
|
|
55
|
+
gap: 0.25rem;
|
|
56
|
+
}
|
|
57
|
+
.cdf-required-mark {
|
|
58
|
+
color: var(--cdf-error);
|
|
59
|
+
}
|
|
60
|
+
.cdf-input-wrapper {
|
|
61
|
+
position: relative;
|
|
62
|
+
display: flex;
|
|
63
|
+
align-items: center;
|
|
64
|
+
}
|
|
65
|
+
.cdf-input {
|
|
66
|
+
width: 100%;
|
|
67
|
+
padding: 0.75rem 1rem;
|
|
68
|
+
font-size: 0.9375rem;
|
|
69
|
+
font-family: var(--cdf-font);
|
|
70
|
+
color: var(--cdf-text);
|
|
71
|
+
background-color: var(--cdf-surface);
|
|
72
|
+
border: 1px solid var(--cdf-border);
|
|
73
|
+
border-radius: var(--cdf-radius);
|
|
74
|
+
transition: var(--cdf-transition);
|
|
75
|
+
outline: none;
|
|
76
|
+
box-sizing: border-box;
|
|
77
|
+
}
|
|
78
|
+
.cdf-input:hover {
|
|
79
|
+
border-color: var(--cdf-border-focus);
|
|
80
|
+
}
|
|
81
|
+
.cdf-input:focus {
|
|
82
|
+
border-color: var(--cdf-primary);
|
|
83
|
+
background-color: var(--cdf-bg);
|
|
84
|
+
box-shadow: var(--cdf-shadow-focus);
|
|
85
|
+
}
|
|
86
|
+
.cdf-input--error {
|
|
87
|
+
border-color: var(--cdf-error);
|
|
88
|
+
background-color: var(--cdf-error-light);
|
|
89
|
+
}
|
|
90
|
+
.cdf-input--error:focus {
|
|
91
|
+
border-color: var(--cdf-error);
|
|
92
|
+
box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.15);
|
|
93
|
+
}
|
|
94
|
+
.cdf-error-message {
|
|
95
|
+
font-size: 0.75rem;
|
|
96
|
+
color: var(--cdf-error);
|
|
97
|
+
margin-top: 0.375rem;
|
|
98
|
+
display: flex;
|
|
99
|
+
align-items: center;
|
|
100
|
+
gap: 0.25rem;
|
|
101
|
+
}
|
|
102
|
+
.cdf-submit-btn {
|
|
103
|
+
width: 100%;
|
|
104
|
+
padding: 0.875rem 1.5rem;
|
|
105
|
+
font-size: 1rem;
|
|
106
|
+
font-weight: 600;
|
|
107
|
+
font-family: var(--cdf-font);
|
|
108
|
+
color: #ffffff;
|
|
109
|
+
background-color: var(--cdf-primary);
|
|
110
|
+
border: none;
|
|
111
|
+
border-radius: var(--cdf-radius);
|
|
112
|
+
cursor: pointer;
|
|
113
|
+
transition: var(--cdf-transition);
|
|
114
|
+
margin-top: 1rem;
|
|
115
|
+
box-shadow: 0 4px 14px 0 rgba(99, 102, 241, 0.39);
|
|
116
|
+
}
|
|
117
|
+
.cdf-submit-btn:hover {
|
|
118
|
+
background-color: var(--cdf-primary-hover);
|
|
119
|
+
transform: translateY(-1px);
|
|
120
|
+
box-shadow: 0 6px 20px rgba(99, 102, 241, 0.4);
|
|
121
|
+
}
|
|
122
|
+
.cdf-submit-btn:active {
|
|
123
|
+
transform: translateY(1px);
|
|
124
|
+
box-shadow: 0 2px 10px rgba(99, 102, 241, 0.3);
|
|
125
|
+
}
|
|
126
|
+
.cdf-rich-text-wrapper {
|
|
127
|
+
border: 1px solid var(--cdf-border);
|
|
128
|
+
border-radius: var(--cdf-radius);
|
|
129
|
+
overflow: hidden;
|
|
130
|
+
transition: var(--cdf-transition);
|
|
131
|
+
}
|
|
132
|
+
.cdf-rich-text-wrapper:focus-within {
|
|
133
|
+
border-color: var(--cdf-primary);
|
|
134
|
+
box-shadow: var(--cdf-shadow-focus);
|
|
135
|
+
}
|
|
136
|
+
.cdf-rich-text-toolbar {
|
|
137
|
+
display: flex;
|
|
138
|
+
gap: 0.25rem;
|
|
139
|
+
padding: 0.5rem;
|
|
140
|
+
background: var(--cdf-surface);
|
|
141
|
+
border-bottom: 1px solid var(--cdf-border);
|
|
142
|
+
}
|
|
143
|
+
.cdf-toolbar-btn {
|
|
144
|
+
padding: 0.375rem;
|
|
145
|
+
background: transparent;
|
|
146
|
+
border: none;
|
|
147
|
+
border-radius: 4px;
|
|
148
|
+
cursor: pointer;
|
|
149
|
+
color: var(--cdf-text-muted);
|
|
150
|
+
transition: var(--cdf-transition);
|
|
151
|
+
}
|
|
152
|
+
.cdf-toolbar-btn:hover {
|
|
153
|
+
background: rgba(0, 0, 0, 0.05);
|
|
154
|
+
color: var(--cdf-text);
|
|
155
|
+
}
|
|
156
|
+
.cdf-toolbar-btn.is-active {
|
|
157
|
+
background: var(--cdf-primary-light);
|
|
158
|
+
color: var(--cdf-primary);
|
|
159
|
+
}
|
|
160
|
+
.cdf-rich-text-content {
|
|
161
|
+
padding: 1rem;
|
|
162
|
+
min-height: 120px;
|
|
163
|
+
background: var(--cdf-bg);
|
|
164
|
+
outline: none;
|
|
165
|
+
}
|
|
166
|
+
.cdf-rich-text-content .ProseMirror {
|
|
167
|
+
outline: none;
|
|
168
|
+
}
|
|
169
|
+
.cdf-rich-text-content .ProseMirror p.is-editor-empty:first-child::before {
|
|
170
|
+
color: var(--cdf-text-muted);
|
|
171
|
+
content: attr(data-placeholder);
|
|
172
|
+
float: left;
|
|
173
|
+
height: 0;
|
|
174
|
+
pointer-events: none;
|
|
175
|
+
}
|
|
176
|
+
/*# sourceMappingURL=index.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/styles/form.css"],"sourcesContent":[":root {\n --cdf-primary: #6366f1;\n --cdf-primary-hover: #4f46e5;\n --cdf-primary-light: rgba(99, 102, 241, 0.1);\n --cdf-error: #ef4444;\n --cdf-error-light: rgba(239, 68, 68, 0.1);\n --cdf-bg: #ffffff;\n --cdf-surface: #f8fafc;\n --cdf-border: #e2e8f0;\n --cdf-border-focus: #94a3b8;\n --cdf-text: #0f172a;\n --cdf-text-muted: #64748b;\n --cdf-radius: 12px;\n --cdf-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05);\n --cdf-shadow-focus: 0 0 0 4px rgba(99, 102, 241, 0.15);\n --cdf-font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n --cdf-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.cdf-form-container {\n font-family: var(--cdf-font);\n color: var(--cdf-text);\n background: var(--cdf-bg);\n border-radius: var(--cdf-radius);\n padding: 2rem;\n box-shadow: var(--cdf-shadow);\n max-width: 600px;\n margin: 0 auto;\n border: 1px solid var(--cdf-border);\n}\n\n.cdf-form-title {\n font-size: 1.5rem;\n font-weight: 600;\n margin-bottom: 1.5rem;\n color: var(--cdf-text);\n}\n\n.cdf-field-group {\n margin-bottom: 1.25rem;\n display: flex;\n flex-direction: column;\n}\n\n.cdf-label {\n font-size: 0.875rem;\n font-weight: 500;\n margin-bottom: 0.5rem;\n color: var(--cdf-text);\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.cdf-required-mark {\n color: var(--cdf-error);\n}\n\n.cdf-input-wrapper {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.cdf-input {\n width: 100%;\n padding: 0.75rem 1rem;\n font-size: 0.9375rem;\n font-family: var(--cdf-font);\n color: var(--cdf-text);\n background-color: var(--cdf-surface);\n border: 1px solid var(--cdf-border);\n border-radius: var(--cdf-radius);\n transition: var(--cdf-transition);\n outline: none;\n box-sizing: border-box;\n}\n\n.cdf-input:hover {\n border-color: var(--cdf-border-focus);\n}\n\n.cdf-input:focus {\n border-color: var(--cdf-primary);\n background-color: var(--cdf-bg);\n box-shadow: var(--cdf-shadow-focus);\n}\n\n.cdf-input--error {\n border-color: var(--cdf-error);\n background-color: var(--cdf-error-light);\n}\n\n.cdf-input--error:focus {\n border-color: var(--cdf-error);\n box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.15);\n}\n\n.cdf-error-message {\n font-size: 0.75rem;\n color: var(--cdf-error);\n margin-top: 0.375rem;\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.cdf-submit-btn {\n width: 100%;\n padding: 0.875rem 1.5rem;\n font-size: 1rem;\n font-weight: 600;\n font-family: var(--cdf-font);\n color: #ffffff;\n background-color: var(--cdf-primary);\n border: none;\n border-radius: var(--cdf-radius);\n cursor: pointer;\n transition: var(--cdf-transition);\n margin-top: 1rem;\n box-shadow: 0 4px 14px 0 rgba(99, 102, 241, 0.39);\n}\n\n.cdf-submit-btn:hover {\n background-color: var(--cdf-primary-hover);\n transform: translateY(-1px);\n box-shadow: 0 6px 20px rgba(99, 102, 241, 0.4);\n}\n\n.cdf-submit-btn:active {\n transform: translateY(1px);\n box-shadow: 0 2px 10px rgba(99, 102, 241, 0.3);\n}\n\n/* Rich Text Editor Overrides */\n.cdf-rich-text-wrapper {\n border: 1px solid var(--cdf-border);\n border-radius: var(--cdf-radius);\n overflow: hidden;\n transition: var(--cdf-transition);\n}\n\n.cdf-rich-text-wrapper:focus-within {\n border-color: var(--cdf-primary);\n box-shadow: var(--cdf-shadow-focus);\n}\n\n.cdf-rich-text-toolbar {\n display: flex;\n gap: 0.25rem;\n padding: 0.5rem;\n background: var(--cdf-surface);\n border-bottom: 1px solid var(--cdf-border);\n}\n\n.cdf-toolbar-btn {\n padding: 0.375rem;\n background: transparent;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n color: var(--cdf-text-muted);\n transition: var(--cdf-transition);\n}\n\n.cdf-toolbar-btn:hover {\n background: rgba(0, 0, 0, 0.05);\n color: var(--cdf-text);\n}\n\n.cdf-toolbar-btn.is-active {\n background: var(--cdf-primary-light);\n color: var(--cdf-primary);\n}\n\n.cdf-rich-text-content {\n padding: 1rem;\n min-height: 120px;\n background: var(--cdf-bg);\n outline: none;\n}\n\n.cdf-rich-text-content .ProseMirror {\n outline: none;\n}\n\n.cdf-rich-text-content .ProseMirror p.is-editor-empty:first-child::before {\n color: var(--cdf-text-muted);\n content: attr(data-placeholder);\n float: left;\n height: 0;\n pointer-events: none;\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
type FieldType = 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array';
|
|
4
|
+
type FieldFormat = 'email' | 'password' | 'date' | 'time' | 'uri' | 'rich-text' | string;
|
|
5
|
+
interface JSONSchema {
|
|
6
|
+
type: FieldType;
|
|
7
|
+
title?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
format?: FieldFormat;
|
|
10
|
+
properties?: Record<string, JSONSchema>;
|
|
11
|
+
required?: string[];
|
|
12
|
+
minLength?: number;
|
|
13
|
+
maxLength?: number;
|
|
14
|
+
minimum?: number;
|
|
15
|
+
maximum?: number;
|
|
16
|
+
pattern?: string;
|
|
17
|
+
enum?: any[];
|
|
18
|
+
items?: JSONSchema | JSONSchema[];
|
|
19
|
+
default?: any;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface SchemaFormProps {
|
|
23
|
+
schema: JSONSchema;
|
|
24
|
+
onSubmit: (data: any) => void;
|
|
25
|
+
defaultValues?: any;
|
|
26
|
+
}
|
|
27
|
+
declare const SchemaForm: React.FC<SchemaFormProps>;
|
|
28
|
+
|
|
29
|
+
interface FieldRendererProps {
|
|
30
|
+
name: string;
|
|
31
|
+
schema: JSONSchema;
|
|
32
|
+
isRequired?: boolean;
|
|
33
|
+
}
|
|
34
|
+
declare const FieldRenderer: React.FC<FieldRendererProps>;
|
|
35
|
+
|
|
36
|
+
export { type FieldFormat, FieldRenderer, type FieldType, type JSONSchema, SchemaForm };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
type FieldType = 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array';
|
|
4
|
+
type FieldFormat = 'email' | 'password' | 'date' | 'time' | 'uri' | 'rich-text' | string;
|
|
5
|
+
interface JSONSchema {
|
|
6
|
+
type: FieldType;
|
|
7
|
+
title?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
format?: FieldFormat;
|
|
10
|
+
properties?: Record<string, JSONSchema>;
|
|
11
|
+
required?: string[];
|
|
12
|
+
minLength?: number;
|
|
13
|
+
maxLength?: number;
|
|
14
|
+
minimum?: number;
|
|
15
|
+
maximum?: number;
|
|
16
|
+
pattern?: string;
|
|
17
|
+
enum?: any[];
|
|
18
|
+
items?: JSONSchema | JSONSchema[];
|
|
19
|
+
default?: any;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface SchemaFormProps {
|
|
23
|
+
schema: JSONSchema;
|
|
24
|
+
onSubmit: (data: any) => void;
|
|
25
|
+
defaultValues?: any;
|
|
26
|
+
}
|
|
27
|
+
declare const SchemaForm: React.FC<SchemaFormProps>;
|
|
28
|
+
|
|
29
|
+
interface FieldRendererProps {
|
|
30
|
+
name: string;
|
|
31
|
+
schema: JSONSchema;
|
|
32
|
+
isRequired?: boolean;
|
|
33
|
+
}
|
|
34
|
+
declare const FieldRenderer: React.FC<FieldRendererProps>;
|
|
35
|
+
|
|
36
|
+
export { type FieldFormat, FieldRenderer, type FieldType, type JSONSchema, SchemaForm };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var reactHookForm = require('react-hook-form');
|
|
4
|
+
var ajv = require('@hookform/resolvers/ajv');
|
|
5
|
+
var lucideReact = require('lucide-react');
|
|
6
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
+
var react = require('react');
|
|
8
|
+
var react$1 = require('@tiptap/react');
|
|
9
|
+
var StarterKit = require('@tiptap/starter-kit');
|
|
10
|
+
|
|
11
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
+
|
|
13
|
+
var StarterKit__default = /*#__PURE__*/_interopDefault(StarterKit);
|
|
14
|
+
|
|
15
|
+
// src/components/SchemaForm.tsx
|
|
16
|
+
var TextField = ({ name, schema, isRequired }) => {
|
|
17
|
+
const {
|
|
18
|
+
register,
|
|
19
|
+
formState: { errors }
|
|
20
|
+
} = reactHookForm.useFormContext();
|
|
21
|
+
const error = errors[name];
|
|
22
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cdf-field-group", children: [
|
|
23
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "cdf-label", htmlFor: name, children: [
|
|
24
|
+
schema.title || name,
|
|
25
|
+
isRequired && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cdf-required-mark", children: "*" })
|
|
26
|
+
] }),
|
|
27
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "cdf-input-wrapper", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
28
|
+
"input",
|
|
29
|
+
{
|
|
30
|
+
id: name,
|
|
31
|
+
type: schema.format === "email" ? "email" : "text",
|
|
32
|
+
className: `cdf-input ${error ? "cdf-input--error" : ""}`,
|
|
33
|
+
placeholder: `Enter ${schema.title || name}`,
|
|
34
|
+
...register(name)
|
|
35
|
+
}
|
|
36
|
+
) }),
|
|
37
|
+
error && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "cdf-error-message", children: [
|
|
38
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { size: 14 }),
|
|
39
|
+
error.message
|
|
40
|
+
] })
|
|
41
|
+
] });
|
|
42
|
+
};
|
|
43
|
+
var PasswordField = ({ name, schema, isRequired }) => {
|
|
44
|
+
const {
|
|
45
|
+
register,
|
|
46
|
+
formState: { errors }
|
|
47
|
+
} = reactHookForm.useFormContext();
|
|
48
|
+
const [showPassword, setShowPassword] = react.useState(false);
|
|
49
|
+
const error = errors[name];
|
|
50
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cdf-field-group", children: [
|
|
51
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "cdf-label", htmlFor: name, children: [
|
|
52
|
+
schema.title || name,
|
|
53
|
+
isRequired && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cdf-required-mark", children: "*" })
|
|
54
|
+
] }),
|
|
55
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cdf-input-wrapper", children: [
|
|
56
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
57
|
+
"input",
|
|
58
|
+
{
|
|
59
|
+
id: name,
|
|
60
|
+
type: showPassword ? "text" : "password",
|
|
61
|
+
className: `cdf-input ${error ? "cdf-input--error" : ""}`,
|
|
62
|
+
style: { paddingRight: "2.5rem" },
|
|
63
|
+
placeholder: `Enter ${schema.title || name}`,
|
|
64
|
+
...register(name)
|
|
65
|
+
}
|
|
66
|
+
),
|
|
67
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
68
|
+
"button",
|
|
69
|
+
{
|
|
70
|
+
type: "button",
|
|
71
|
+
className: "cdf-toolbar-btn",
|
|
72
|
+
style: { position: "absolute", right: "0.5rem" },
|
|
73
|
+
onClick: () => setShowPassword(!showPassword),
|
|
74
|
+
children: showPassword ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.EyeOff, { size: 16 }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { size: 16 })
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
] }),
|
|
78
|
+
error && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "cdf-error-message", children: [
|
|
79
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { size: 14 }),
|
|
80
|
+
error.message
|
|
81
|
+
] })
|
|
82
|
+
] });
|
|
83
|
+
};
|
|
84
|
+
var NumberField = ({ name, schema, isRequired }) => {
|
|
85
|
+
const {
|
|
86
|
+
register,
|
|
87
|
+
formState: { errors }
|
|
88
|
+
} = reactHookForm.useFormContext();
|
|
89
|
+
const error = errors[name];
|
|
90
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cdf-field-group", children: [
|
|
91
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "cdf-label", htmlFor: name, children: [
|
|
92
|
+
schema.title || name,
|
|
93
|
+
isRequired && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cdf-required-mark", children: "*" })
|
|
94
|
+
] }),
|
|
95
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "cdf-input-wrapper", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
96
|
+
"input",
|
|
97
|
+
{
|
|
98
|
+
id: name,
|
|
99
|
+
type: "number",
|
|
100
|
+
className: `cdf-input ${error ? "cdf-input--error" : ""}`,
|
|
101
|
+
placeholder: `Enter ${schema.title || name}`,
|
|
102
|
+
...register(name, {
|
|
103
|
+
valueAsNumber: true
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
) }),
|
|
107
|
+
error && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "cdf-error-message", children: [
|
|
108
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { size: 14 }),
|
|
109
|
+
error.message
|
|
110
|
+
] })
|
|
111
|
+
] });
|
|
112
|
+
};
|
|
113
|
+
var RichTextField = ({ name, schema, isRequired }) => {
|
|
114
|
+
const {
|
|
115
|
+
setValue,
|
|
116
|
+
watch,
|
|
117
|
+
formState: { errors }
|
|
118
|
+
} = reactHookForm.useFormContext();
|
|
119
|
+
const error = errors[name];
|
|
120
|
+
const value = watch(name);
|
|
121
|
+
const editor = react$1.useEditor({
|
|
122
|
+
extensions: [StarterKit__default.default],
|
|
123
|
+
content: value || "",
|
|
124
|
+
onUpdate: ({ editor: editor2 }) => {
|
|
125
|
+
setValue(name, editor2.getHTML(), { shouldValidate: true, shouldDirty: true });
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
react.useEffect(() => {
|
|
129
|
+
if (editor && value !== editor.getHTML()) {
|
|
130
|
+
editor.commands.setContent(value || "");
|
|
131
|
+
}
|
|
132
|
+
}, [value, editor]);
|
|
133
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cdf-field-group", children: [
|
|
134
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "cdf-label", htmlFor: name, children: [
|
|
135
|
+
schema.title || name,
|
|
136
|
+
isRequired && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cdf-required-mark", children: "*" })
|
|
137
|
+
] }),
|
|
138
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `cdf-rich-text-wrapper ${error ? "cdf-input--error" : ""}`, children: [
|
|
139
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cdf-rich-text-toolbar", children: [
|
|
140
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
141
|
+
"button",
|
|
142
|
+
{
|
|
143
|
+
type: "button",
|
|
144
|
+
onClick: () => editor == null ? void 0 : editor.chain().focus().toggleBold().run(),
|
|
145
|
+
className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("bold")) ? "is-active" : ""}`,
|
|
146
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bold, { size: 16 })
|
|
147
|
+
}
|
|
148
|
+
),
|
|
149
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
150
|
+
"button",
|
|
151
|
+
{
|
|
152
|
+
type: "button",
|
|
153
|
+
onClick: () => editor == null ? void 0 : editor.chain().focus().toggleItalic().run(),
|
|
154
|
+
className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("italic")) ? "is-active" : ""}`,
|
|
155
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Italic, { size: 16 })
|
|
156
|
+
}
|
|
157
|
+
),
|
|
158
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
159
|
+
"button",
|
|
160
|
+
{
|
|
161
|
+
type: "button",
|
|
162
|
+
onClick: () => editor == null ? void 0 : editor.chain().focus().toggleHeading({ level: 2 }).run(),
|
|
163
|
+
className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("heading", { level: 2 })) ? "is-active" : ""}`,
|
|
164
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heading2, { size: 16 })
|
|
165
|
+
}
|
|
166
|
+
),
|
|
167
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
168
|
+
"button",
|
|
169
|
+
{
|
|
170
|
+
type: "button",
|
|
171
|
+
onClick: () => editor == null ? void 0 : editor.chain().focus().toggleBulletList().run(),
|
|
172
|
+
className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("bulletList")) ? "is-active" : ""}`,
|
|
173
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.List, { size: 16 })
|
|
174
|
+
}
|
|
175
|
+
),
|
|
176
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
177
|
+
"button",
|
|
178
|
+
{
|
|
179
|
+
type: "button",
|
|
180
|
+
onClick: () => editor == null ? void 0 : editor.chain().focus().toggleOrderedList().run(),
|
|
181
|
+
className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("orderedList")) ? "is-active" : ""}`,
|
|
182
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListOrdered, { size: 16 })
|
|
183
|
+
}
|
|
184
|
+
)
|
|
185
|
+
] }),
|
|
186
|
+
/* @__PURE__ */ jsxRuntime.jsx(react$1.EditorContent, { editor, className: "cdf-rich-text-content" })
|
|
187
|
+
] }),
|
|
188
|
+
error && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "cdf-error-message", children: [
|
|
189
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { size: 14 }),
|
|
190
|
+
error.message
|
|
191
|
+
] })
|
|
192
|
+
] });
|
|
193
|
+
};
|
|
194
|
+
var FieldRenderer = ({ name, schema, isRequired }) => {
|
|
195
|
+
if (schema.type === "string") {
|
|
196
|
+
if (schema.format === "password") {
|
|
197
|
+
return /* @__PURE__ */ jsxRuntime.jsx(PasswordField, { name, schema, isRequired });
|
|
198
|
+
}
|
|
199
|
+
if (schema.format === "rich-text") {
|
|
200
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RichTextField, { name, schema, isRequired });
|
|
201
|
+
}
|
|
202
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TextField, { name, schema, isRequired });
|
|
203
|
+
}
|
|
204
|
+
if (schema.type === "number" || schema.type === "integer") {
|
|
205
|
+
return /* @__PURE__ */ jsxRuntime.jsx(NumberField, { name, schema, isRequired });
|
|
206
|
+
}
|
|
207
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cdf-field-group", children: /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "cdf-error-message", children: [
|
|
208
|
+
"Unsupported field type: ",
|
|
209
|
+
schema.type
|
|
210
|
+
] }) });
|
|
211
|
+
};
|
|
212
|
+
var SchemaForm = ({ schema, onSubmit, defaultValues }) => {
|
|
213
|
+
const methods = reactHookForm.useForm({
|
|
214
|
+
resolver: ajv.ajvResolver(schema, {
|
|
215
|
+
formats: {
|
|
216
|
+
"rich-text": true,
|
|
217
|
+
password: true,
|
|
218
|
+
email: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
|
|
219
|
+
}
|
|
220
|
+
}),
|
|
221
|
+
defaultValues
|
|
222
|
+
});
|
|
223
|
+
if (schema.type !== "object" || !schema.properties) {
|
|
224
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cdf-error-message", children: "Root schema must be an object with properties." });
|
|
225
|
+
}
|
|
226
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cdf-form-container", children: [
|
|
227
|
+
schema.title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "cdf-form-title", children: schema.title }),
|
|
228
|
+
schema.description && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "var(--cdf-text-muted)", marginBottom: "1.5rem" }, children: schema.description }),
|
|
229
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactHookForm.FormProvider, { ...methods, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: methods.handleSubmit(onSubmit), noValidate: true, children: [
|
|
230
|
+
Object.entries(schema.properties).map(([key, propSchema]) => {
|
|
231
|
+
var _a;
|
|
232
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
233
|
+
FieldRenderer,
|
|
234
|
+
{
|
|
235
|
+
name: key,
|
|
236
|
+
schema: propSchema,
|
|
237
|
+
isRequired: (_a = schema.required) == null ? void 0 : _a.includes(key)
|
|
238
|
+
},
|
|
239
|
+
key
|
|
240
|
+
);
|
|
241
|
+
}),
|
|
242
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "submit", className: "cdf-submit-btn", children: "Submit" })
|
|
243
|
+
] }) })
|
|
244
|
+
] });
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
exports.FieldRenderer = FieldRenderer;
|
|
248
|
+
exports.SchemaForm = SchemaForm;
|
|
249
|
+
//# sourceMappingURL=index.js.map
|
|
250
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/fields/TextField.tsx","../src/components/fields/PasswordField.tsx","../src/components/fields/NumberField.tsx","../src/components/fields/RichTextField.tsx","../src/components/FieldRenderer.tsx","../src/components/SchemaForm.tsx"],"names":["useFormContext","jsxs","jsx","AlertCircle","useState","EyeOff","Eye","useEditor","StarterKit","editor","useEffect","Bold","Italic","Heading2","List","ListOrdered","EditorContent","useForm","ajvResolver","FormProvider"],"mappings":"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","file":"index.js","sourcesContent":["import React from 'react';\nimport { useFormContext } from 'react-hook-form';\nimport { JSONSchema } from '../../types/schema';\nimport { AlertCircle } from 'lucide-react';\n\ninterface TextFieldProps {\n name: string;\n schema: JSONSchema;\n isRequired?: boolean;\n}\n\nexport const TextField: React.FC<TextFieldProps> = ({ name, schema, isRequired }) => {\n const {\n register,\n formState: { errors },\n } = useFormContext();\n const error = errors[name];\n\n return (\n <div className=\"cdf-field-group\">\n <label className=\"cdf-label\" htmlFor={name}>\n {schema.title || name}\n {isRequired && <span className=\"cdf-required-mark\">*</span>}\n </label>\n <div className=\"cdf-input-wrapper\">\n <input\n id={name}\n type={schema.format === 'email' ? 'email' : 'text'}\n className={`cdf-input ${error ? 'cdf-input--error' : ''}`}\n placeholder={`Enter ${schema.title || name}`}\n {...register(name)}\n />\n </div>\n {error && (\n <span className=\"cdf-error-message\">\n <AlertCircle size={14} />\n {error.message as string}\n </span>\n )}\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport { useFormContext } from 'react-hook-form';\nimport { JSONSchema } from '../../types/schema';\nimport { AlertCircle, Eye, EyeOff } from 'lucide-react';\n\ninterface PasswordFieldProps {\n name: string;\n schema: JSONSchema;\n isRequired?: boolean;\n}\n\nexport const PasswordField: React.FC<PasswordFieldProps> = ({ name, schema, isRequired }) => {\n const {\n register,\n formState: { errors },\n } = useFormContext();\n const [showPassword, setShowPassword] = useState(false);\n const error = errors[name];\n\n return (\n <div className=\"cdf-field-group\">\n <label className=\"cdf-label\" htmlFor={name}>\n {schema.title || name}\n {isRequired && <span className=\"cdf-required-mark\">*</span>}\n </label>\n <div className=\"cdf-input-wrapper\">\n <input\n id={name}\n type={showPassword ? 'text' : 'password'}\n className={`cdf-input ${error ? 'cdf-input--error' : ''}`}\n style={{ paddingRight: '2.5rem' }}\n placeholder={`Enter ${schema.title || name}`}\n {...register(name)}\n />\n <button\n type=\"button\"\n className=\"cdf-toolbar-btn\"\n style={{ position: 'absolute', right: '0.5rem' }}\n onClick={() => setShowPassword(!showPassword)}\n >\n {showPassword ? <EyeOff size={16} /> : <Eye size={16} />}\n </button>\n </div>\n {error && (\n <span className=\"cdf-error-message\">\n <AlertCircle size={14} />\n {error.message as string}\n </span>\n )}\n </div>\n );\n};\n","import React from 'react';\nimport { useFormContext } from 'react-hook-form';\nimport { JSONSchema } from '../../types/schema';\nimport { AlertCircle } from 'lucide-react';\n\ninterface NumberFieldProps {\n name: string;\n schema: JSONSchema;\n isRequired?: boolean;\n}\n\nexport const NumberField: React.FC<NumberFieldProps> = ({ name, schema, isRequired }) => {\n const {\n register,\n formState: { errors },\n } = useFormContext();\n const error = errors[name];\n\n return (\n <div className=\"cdf-field-group\">\n <label className=\"cdf-label\" htmlFor={name}>\n {schema.title || name}\n {isRequired && <span className=\"cdf-required-mark\">*</span>}\n </label>\n <div className=\"cdf-input-wrapper\">\n <input\n id={name}\n type=\"number\"\n className={`cdf-input ${error ? 'cdf-input--error' : ''}`}\n placeholder={`Enter ${schema.title || name}`}\n {...register(name, {\n valueAsNumber: true,\n })}\n />\n </div>\n {error && (\n <span className=\"cdf-error-message\">\n <AlertCircle size={14} />\n {error.message as string}\n </span>\n )}\n </div>\n );\n};\n","import React, { useEffect } from 'react';\nimport { useFormContext } from 'react-hook-form';\nimport { useEditor, EditorContent } from '@tiptap/react';\nimport StarterKit from '@tiptap/starter-kit';\nimport { JSONSchema } from '../../types/schema';\nimport { AlertCircle, Bold, Italic, List, ListOrdered, Heading2 } from 'lucide-react';\n\ninterface RichTextFieldProps {\n name: string;\n schema: JSONSchema;\n isRequired?: boolean;\n}\n\nexport const RichTextField: React.FC<RichTextFieldProps> = ({ name, schema, isRequired }) => {\n const {\n setValue,\n watch,\n formState: { errors },\n } = useFormContext();\n const error = errors[name];\n const value = watch(name);\n\n const editor = useEditor({\n extensions: [StarterKit],\n content: value || '',\n onUpdate: ({ editor }) => {\n setValue(name, editor.getHTML(), { shouldValidate: true, shouldDirty: true });\n },\n });\n\n // Keep editor in sync with external form changes (if any)\n useEffect(() => {\n if (editor && value !== editor.getHTML()) {\n editor.commands.setContent(value || '');\n }\n }, [value, editor]);\n\n return (\n <div className=\"cdf-field-group\">\n <label className=\"cdf-label\" htmlFor={name}>\n {schema.title || name}\n {isRequired && <span className=\"cdf-required-mark\">*</span>}\n </label>\n\n <div className={`cdf-rich-text-wrapper ${error ? 'cdf-input--error' : ''}`}>\n <div className=\"cdf-rich-text-toolbar\">\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleBold().run()}\n className={`cdf-toolbar-btn ${editor?.isActive('bold') ? 'is-active' : ''}`}\n >\n <Bold size={16} />\n </button>\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleItalic().run()}\n className={`cdf-toolbar-btn ${editor?.isActive('italic') ? 'is-active' : ''}`}\n >\n <Italic size={16} />\n </button>\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleHeading({ level: 2 }).run()}\n className={`cdf-toolbar-btn ${editor?.isActive('heading', { level: 2 }) ? 'is-active' : ''}`}\n >\n <Heading2 size={16} />\n </button>\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleBulletList().run()}\n className={`cdf-toolbar-btn ${editor?.isActive('bulletList') ? 'is-active' : ''}`}\n >\n <List size={16} />\n </button>\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleOrderedList().run()}\n className={`cdf-toolbar-btn ${editor?.isActive('orderedList') ? 'is-active' : ''}`}\n >\n <ListOrdered size={16} />\n </button>\n </div>\n\n <EditorContent editor={editor} className=\"cdf-rich-text-content\" />\n </div>\n\n {error && (\n <span className=\"cdf-error-message\">\n <AlertCircle size={14} />\n {error.message as string}\n </span>\n )}\n </div>\n );\n};\n","import React from 'react';\nimport { JSONSchema } from '../types/schema';\nimport { TextField } from './fields/TextField';\nimport { PasswordField } from './fields/PasswordField';\nimport { NumberField } from './fields/NumberField';\nimport { RichTextField } from './fields/RichTextField';\n\ninterface FieldRendererProps {\n name: string;\n schema: JSONSchema;\n isRequired?: boolean;\n}\n\nexport const FieldRenderer: React.FC<FieldRendererProps> = ({ name, schema, isRequired }) => {\n if (schema.type === 'string') {\n if (schema.format === 'password') {\n return <PasswordField name={name} schema={schema} isRequired={isRequired} />;\n }\n if (schema.format === 'rich-text') {\n return <RichTextField name={name} schema={schema} isRequired={isRequired} />;\n }\n return <TextField name={name} schema={schema} isRequired={isRequired} />;\n }\n\n if (schema.type === 'number' || schema.type === 'integer') {\n return <NumberField name={name} schema={schema} isRequired={isRequired} />;\n }\n\n // Fallback for unsupported types\n return (\n <div className=\"cdf-field-group\">\n <p className=\"cdf-error-message\">Unsupported field type: {schema.type}</p>\n </div>\n );\n};\n","import React from 'react';\nimport { useForm, FormProvider } from 'react-hook-form';\nimport { ajvResolver } from '@hookform/resolvers/ajv';\nimport { JSONSchema } from '../types/schema';\nimport { FieldRenderer } from './FieldRenderer';\nimport '../styles/form.css';\n\ninterface SchemaFormProps {\n schema: JSONSchema;\n onSubmit: (data: any) => void;\n defaultValues?: any;\n}\n\nexport const SchemaForm: React.FC<SchemaFormProps> = ({ schema, onSubmit, defaultValues }) => {\n const methods = useForm({\n resolver: ajvResolver(schema as any, {\n formats: {\n 'rich-text': true,\n password: true,\n email: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/,\n },\n }),\n defaultValues,\n });\n\n if (schema.type !== 'object' || !schema.properties) {\n return <div className=\"cdf-error-message\">Root schema must be an object with properties.</div>;\n }\n\n return (\n <div className=\"cdf-form-container\">\n {schema.title && <h2 className=\"cdf-form-title\">{schema.title}</h2>}\n {schema.description && (\n <p style={{ color: 'var(--cdf-text-muted)', marginBottom: '1.5rem' }}>\n {schema.description}\n </p>\n )}\n\n <FormProvider {...methods}>\n <form onSubmit={methods.handleSubmit(onSubmit)} noValidate>\n {Object.entries(schema.properties).map(([key, propSchema]) => (\n <FieldRenderer\n key={key}\n name={key}\n schema={propSchema}\n isRequired={schema.required?.includes(key)}\n />\n ))}\n <button type=\"submit\" className=\"cdf-submit-btn\">\n Submit\n </button>\n </form>\n </FormProvider>\n </div>\n );\n};\n"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { useForm, FormProvider, useFormContext } from 'react-hook-form';
|
|
2
|
+
import { ajvResolver } from '@hookform/resolvers/ajv';
|
|
3
|
+
import { EyeOff, Eye, AlertCircle, Bold, Italic, Heading2, List, ListOrdered } from 'lucide-react';
|
|
4
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
|
+
import { useState, useEffect } from 'react';
|
|
6
|
+
import { useEditor, EditorContent } from '@tiptap/react';
|
|
7
|
+
import StarterKit from '@tiptap/starter-kit';
|
|
8
|
+
|
|
9
|
+
// src/components/SchemaForm.tsx
|
|
10
|
+
var TextField = ({ name, schema, isRequired }) => {
|
|
11
|
+
const {
|
|
12
|
+
register,
|
|
13
|
+
formState: { errors }
|
|
14
|
+
} = useFormContext();
|
|
15
|
+
const error = errors[name];
|
|
16
|
+
return /* @__PURE__ */ jsxs("div", { className: "cdf-field-group", children: [
|
|
17
|
+
/* @__PURE__ */ jsxs("label", { className: "cdf-label", htmlFor: name, children: [
|
|
18
|
+
schema.title || name,
|
|
19
|
+
isRequired && /* @__PURE__ */ jsx("span", { className: "cdf-required-mark", children: "*" })
|
|
20
|
+
] }),
|
|
21
|
+
/* @__PURE__ */ jsx("div", { className: "cdf-input-wrapper", children: /* @__PURE__ */ jsx(
|
|
22
|
+
"input",
|
|
23
|
+
{
|
|
24
|
+
id: name,
|
|
25
|
+
type: schema.format === "email" ? "email" : "text",
|
|
26
|
+
className: `cdf-input ${error ? "cdf-input--error" : ""}`,
|
|
27
|
+
placeholder: `Enter ${schema.title || name}`,
|
|
28
|
+
...register(name)
|
|
29
|
+
}
|
|
30
|
+
) }),
|
|
31
|
+
error && /* @__PURE__ */ jsxs("span", { className: "cdf-error-message", children: [
|
|
32
|
+
/* @__PURE__ */ jsx(AlertCircle, { size: 14 }),
|
|
33
|
+
error.message
|
|
34
|
+
] })
|
|
35
|
+
] });
|
|
36
|
+
};
|
|
37
|
+
var PasswordField = ({ name, schema, isRequired }) => {
|
|
38
|
+
const {
|
|
39
|
+
register,
|
|
40
|
+
formState: { errors }
|
|
41
|
+
} = useFormContext();
|
|
42
|
+
const [showPassword, setShowPassword] = useState(false);
|
|
43
|
+
const error = errors[name];
|
|
44
|
+
return /* @__PURE__ */ jsxs("div", { className: "cdf-field-group", children: [
|
|
45
|
+
/* @__PURE__ */ jsxs("label", { className: "cdf-label", htmlFor: name, children: [
|
|
46
|
+
schema.title || name,
|
|
47
|
+
isRequired && /* @__PURE__ */ jsx("span", { className: "cdf-required-mark", children: "*" })
|
|
48
|
+
] }),
|
|
49
|
+
/* @__PURE__ */ jsxs("div", { className: "cdf-input-wrapper", children: [
|
|
50
|
+
/* @__PURE__ */ jsx(
|
|
51
|
+
"input",
|
|
52
|
+
{
|
|
53
|
+
id: name,
|
|
54
|
+
type: showPassword ? "text" : "password",
|
|
55
|
+
className: `cdf-input ${error ? "cdf-input--error" : ""}`,
|
|
56
|
+
style: { paddingRight: "2.5rem" },
|
|
57
|
+
placeholder: `Enter ${schema.title || name}`,
|
|
58
|
+
...register(name)
|
|
59
|
+
}
|
|
60
|
+
),
|
|
61
|
+
/* @__PURE__ */ jsx(
|
|
62
|
+
"button",
|
|
63
|
+
{
|
|
64
|
+
type: "button",
|
|
65
|
+
className: "cdf-toolbar-btn",
|
|
66
|
+
style: { position: "absolute", right: "0.5rem" },
|
|
67
|
+
onClick: () => setShowPassword(!showPassword),
|
|
68
|
+
children: showPassword ? /* @__PURE__ */ jsx(EyeOff, { size: 16 }) : /* @__PURE__ */ jsx(Eye, { size: 16 })
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
] }),
|
|
72
|
+
error && /* @__PURE__ */ jsxs("span", { className: "cdf-error-message", children: [
|
|
73
|
+
/* @__PURE__ */ jsx(AlertCircle, { size: 14 }),
|
|
74
|
+
error.message
|
|
75
|
+
] })
|
|
76
|
+
] });
|
|
77
|
+
};
|
|
78
|
+
var NumberField = ({ name, schema, isRequired }) => {
|
|
79
|
+
const {
|
|
80
|
+
register,
|
|
81
|
+
formState: { errors }
|
|
82
|
+
} = useFormContext();
|
|
83
|
+
const error = errors[name];
|
|
84
|
+
return /* @__PURE__ */ jsxs("div", { className: "cdf-field-group", children: [
|
|
85
|
+
/* @__PURE__ */ jsxs("label", { className: "cdf-label", htmlFor: name, children: [
|
|
86
|
+
schema.title || name,
|
|
87
|
+
isRequired && /* @__PURE__ */ jsx("span", { className: "cdf-required-mark", children: "*" })
|
|
88
|
+
] }),
|
|
89
|
+
/* @__PURE__ */ jsx("div", { className: "cdf-input-wrapper", children: /* @__PURE__ */ jsx(
|
|
90
|
+
"input",
|
|
91
|
+
{
|
|
92
|
+
id: name,
|
|
93
|
+
type: "number",
|
|
94
|
+
className: `cdf-input ${error ? "cdf-input--error" : ""}`,
|
|
95
|
+
placeholder: `Enter ${schema.title || name}`,
|
|
96
|
+
...register(name, {
|
|
97
|
+
valueAsNumber: true
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
) }),
|
|
101
|
+
error && /* @__PURE__ */ jsxs("span", { className: "cdf-error-message", children: [
|
|
102
|
+
/* @__PURE__ */ jsx(AlertCircle, { size: 14 }),
|
|
103
|
+
error.message
|
|
104
|
+
] })
|
|
105
|
+
] });
|
|
106
|
+
};
|
|
107
|
+
var RichTextField = ({ name, schema, isRequired }) => {
|
|
108
|
+
const {
|
|
109
|
+
setValue,
|
|
110
|
+
watch,
|
|
111
|
+
formState: { errors }
|
|
112
|
+
} = useFormContext();
|
|
113
|
+
const error = errors[name];
|
|
114
|
+
const value = watch(name);
|
|
115
|
+
const editor = useEditor({
|
|
116
|
+
extensions: [StarterKit],
|
|
117
|
+
content: value || "",
|
|
118
|
+
onUpdate: ({ editor: editor2 }) => {
|
|
119
|
+
setValue(name, editor2.getHTML(), { shouldValidate: true, shouldDirty: true });
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
useEffect(() => {
|
|
123
|
+
if (editor && value !== editor.getHTML()) {
|
|
124
|
+
editor.commands.setContent(value || "");
|
|
125
|
+
}
|
|
126
|
+
}, [value, editor]);
|
|
127
|
+
return /* @__PURE__ */ jsxs("div", { className: "cdf-field-group", children: [
|
|
128
|
+
/* @__PURE__ */ jsxs("label", { className: "cdf-label", htmlFor: name, children: [
|
|
129
|
+
schema.title || name,
|
|
130
|
+
isRequired && /* @__PURE__ */ jsx("span", { className: "cdf-required-mark", children: "*" })
|
|
131
|
+
] }),
|
|
132
|
+
/* @__PURE__ */ jsxs("div", { className: `cdf-rich-text-wrapper ${error ? "cdf-input--error" : ""}`, children: [
|
|
133
|
+
/* @__PURE__ */ jsxs("div", { className: "cdf-rich-text-toolbar", children: [
|
|
134
|
+
/* @__PURE__ */ jsx(
|
|
135
|
+
"button",
|
|
136
|
+
{
|
|
137
|
+
type: "button",
|
|
138
|
+
onClick: () => editor == null ? void 0 : editor.chain().focus().toggleBold().run(),
|
|
139
|
+
className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("bold")) ? "is-active" : ""}`,
|
|
140
|
+
children: /* @__PURE__ */ jsx(Bold, { size: 16 })
|
|
141
|
+
}
|
|
142
|
+
),
|
|
143
|
+
/* @__PURE__ */ jsx(
|
|
144
|
+
"button",
|
|
145
|
+
{
|
|
146
|
+
type: "button",
|
|
147
|
+
onClick: () => editor == null ? void 0 : editor.chain().focus().toggleItalic().run(),
|
|
148
|
+
className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("italic")) ? "is-active" : ""}`,
|
|
149
|
+
children: /* @__PURE__ */ jsx(Italic, { size: 16 })
|
|
150
|
+
}
|
|
151
|
+
),
|
|
152
|
+
/* @__PURE__ */ jsx(
|
|
153
|
+
"button",
|
|
154
|
+
{
|
|
155
|
+
type: "button",
|
|
156
|
+
onClick: () => editor == null ? void 0 : editor.chain().focus().toggleHeading({ level: 2 }).run(),
|
|
157
|
+
className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("heading", { level: 2 })) ? "is-active" : ""}`,
|
|
158
|
+
children: /* @__PURE__ */ jsx(Heading2, { size: 16 })
|
|
159
|
+
}
|
|
160
|
+
),
|
|
161
|
+
/* @__PURE__ */ jsx(
|
|
162
|
+
"button",
|
|
163
|
+
{
|
|
164
|
+
type: "button",
|
|
165
|
+
onClick: () => editor == null ? void 0 : editor.chain().focus().toggleBulletList().run(),
|
|
166
|
+
className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("bulletList")) ? "is-active" : ""}`,
|
|
167
|
+
children: /* @__PURE__ */ jsx(List, { size: 16 })
|
|
168
|
+
}
|
|
169
|
+
),
|
|
170
|
+
/* @__PURE__ */ jsx(
|
|
171
|
+
"button",
|
|
172
|
+
{
|
|
173
|
+
type: "button",
|
|
174
|
+
onClick: () => editor == null ? void 0 : editor.chain().focus().toggleOrderedList().run(),
|
|
175
|
+
className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("orderedList")) ? "is-active" : ""}`,
|
|
176
|
+
children: /* @__PURE__ */ jsx(ListOrdered, { size: 16 })
|
|
177
|
+
}
|
|
178
|
+
)
|
|
179
|
+
] }),
|
|
180
|
+
/* @__PURE__ */ jsx(EditorContent, { editor, className: "cdf-rich-text-content" })
|
|
181
|
+
] }),
|
|
182
|
+
error && /* @__PURE__ */ jsxs("span", { className: "cdf-error-message", children: [
|
|
183
|
+
/* @__PURE__ */ jsx(AlertCircle, { size: 14 }),
|
|
184
|
+
error.message
|
|
185
|
+
] })
|
|
186
|
+
] });
|
|
187
|
+
};
|
|
188
|
+
var FieldRenderer = ({ name, schema, isRequired }) => {
|
|
189
|
+
if (schema.type === "string") {
|
|
190
|
+
if (schema.format === "password") {
|
|
191
|
+
return /* @__PURE__ */ jsx(PasswordField, { name, schema, isRequired });
|
|
192
|
+
}
|
|
193
|
+
if (schema.format === "rich-text") {
|
|
194
|
+
return /* @__PURE__ */ jsx(RichTextField, { name, schema, isRequired });
|
|
195
|
+
}
|
|
196
|
+
return /* @__PURE__ */ jsx(TextField, { name, schema, isRequired });
|
|
197
|
+
}
|
|
198
|
+
if (schema.type === "number" || schema.type === "integer") {
|
|
199
|
+
return /* @__PURE__ */ jsx(NumberField, { name, schema, isRequired });
|
|
200
|
+
}
|
|
201
|
+
return /* @__PURE__ */ jsx("div", { className: "cdf-field-group", children: /* @__PURE__ */ jsxs("p", { className: "cdf-error-message", children: [
|
|
202
|
+
"Unsupported field type: ",
|
|
203
|
+
schema.type
|
|
204
|
+
] }) });
|
|
205
|
+
};
|
|
206
|
+
var SchemaForm = ({ schema, onSubmit, defaultValues }) => {
|
|
207
|
+
const methods = useForm({
|
|
208
|
+
resolver: ajvResolver(schema, {
|
|
209
|
+
formats: {
|
|
210
|
+
"rich-text": true,
|
|
211
|
+
password: true,
|
|
212
|
+
email: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
|
|
213
|
+
}
|
|
214
|
+
}),
|
|
215
|
+
defaultValues
|
|
216
|
+
});
|
|
217
|
+
if (schema.type !== "object" || !schema.properties) {
|
|
218
|
+
return /* @__PURE__ */ jsx("div", { className: "cdf-error-message", children: "Root schema must be an object with properties." });
|
|
219
|
+
}
|
|
220
|
+
return /* @__PURE__ */ jsxs("div", { className: "cdf-form-container", children: [
|
|
221
|
+
schema.title && /* @__PURE__ */ jsx("h2", { className: "cdf-form-title", children: schema.title }),
|
|
222
|
+
schema.description && /* @__PURE__ */ jsx("p", { style: { color: "var(--cdf-text-muted)", marginBottom: "1.5rem" }, children: schema.description }),
|
|
223
|
+
/* @__PURE__ */ jsx(FormProvider, { ...methods, children: /* @__PURE__ */ jsxs("form", { onSubmit: methods.handleSubmit(onSubmit), noValidate: true, children: [
|
|
224
|
+
Object.entries(schema.properties).map(([key, propSchema]) => {
|
|
225
|
+
var _a;
|
|
226
|
+
return /* @__PURE__ */ jsx(
|
|
227
|
+
FieldRenderer,
|
|
228
|
+
{
|
|
229
|
+
name: key,
|
|
230
|
+
schema: propSchema,
|
|
231
|
+
isRequired: (_a = schema.required) == null ? void 0 : _a.includes(key)
|
|
232
|
+
},
|
|
233
|
+
key
|
|
234
|
+
);
|
|
235
|
+
}),
|
|
236
|
+
/* @__PURE__ */ jsx("button", { type: "submit", className: "cdf-submit-btn", children: "Submit" })
|
|
237
|
+
] }) })
|
|
238
|
+
] });
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
export { FieldRenderer, SchemaForm };
|
|
242
|
+
//# sourceMappingURL=index.mjs.map
|
|
243
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/fields/TextField.tsx","../src/components/fields/PasswordField.tsx","../src/components/fields/NumberField.tsx","../src/components/fields/RichTextField.tsx","../src/components/FieldRenderer.tsx","../src/components/SchemaForm.tsx"],"names":["useFormContext","jsxs","jsx","AlertCircle","editor"],"mappings":";;;;;;;;;AAWO,IAAM,YAAsC,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,YAAW,KAAM;AACnF,EAAA,MAAM;AAAA,IACJ,QAAA;AAAA,IACA,SAAA,EAAW,EAAE,MAAA;AAAO,MAClB,cAAA,EAAe;AACnB,EAAA,MAAM,KAAA,GAAQ,OAAO,IAAI,CAAA;AAEzB,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iBAAA,EACb,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAU,WAAA,EAAY,OAAA,EAAS,IAAA,EACnC,QAAA,EAAA;AAAA,MAAA,MAAA,CAAO,KAAA,IAAS,IAAA;AAAA,MAChB,UAAA,oBAAc,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qBAAoB,QAAA,EAAA,GAAA,EAAC;AAAA,KAAA,EACtD,CAAA;AAAA,oBACA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mBAAA,EACb,QAAA,kBAAA,GAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,EAAA,EAAI,IAAA;AAAA,QACJ,IAAA,EAAM,MAAA,CAAO,MAAA,KAAW,OAAA,GAAU,OAAA,GAAU,MAAA;AAAA,QAC5C,SAAA,EAAW,CAAA,UAAA,EAAa,KAAA,GAAQ,kBAAA,GAAqB,EAAE,CAAA,CAAA;AAAA,QACvD,WAAA,EAAa,CAAA,MAAA,EAAS,MAAA,CAAO,KAAA,IAAS,IAAI,CAAA,CAAA;AAAA,QACzC,GAAG,SAAS,IAAI;AAAA;AAAA,KACnB,EACF,CAAA;AAAA,IACC,KAAA,oBACC,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mBAAA,EACd,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,WAAA,EAAA,EAAY,MAAM,EAAA,EAAI,CAAA;AAAA,MACtB,KAAA,CAAM;AAAA,KAAA,EACT;AAAA,GAAA,EAEJ,CAAA;AAEJ,CAAA;AC9BO,IAAM,gBAA8C,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,YAAW,KAAM;AAC3F,EAAA,MAAM;AAAA,IACJ,QAAA;AAAA,IACA,SAAA,EAAW,EAAE,MAAA;AAAO,MAClBA,cAAAA,EAAe;AACnB,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAS,KAAK,CAAA;AACtD,EAAA,MAAM,KAAA,GAAQ,OAAO,IAAI,CAAA;AAEzB,EAAA,uBACEC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iBAAA,EACb,QAAA,EAAA;AAAA,oBAAAA,IAAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAU,WAAA,EAAY,SAAS,IAAA,EACnC,QAAA,EAAA;AAAA,MAAA,MAAA,CAAO,KAAA,IAAS,IAAA;AAAA,MAChB,8BAAcC,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qBAAoB,QAAA,EAAA,GAAA,EAAC;AAAA,KAAA,EACtD,CAAA;AAAA,oBACAD,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mBAAA,EACb,QAAA,EAAA;AAAA,sBAAAC,GAAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,EAAA,EAAI,IAAA;AAAA,UACJ,IAAA,EAAM,eAAe,MAAA,GAAS,UAAA;AAAA,UAC9B,SAAA,EAAW,CAAA,UAAA,EAAa,KAAA,GAAQ,kBAAA,GAAqB,EAAE,CAAA,CAAA;AAAA,UACvD,KAAA,EAAO,EAAE,YAAA,EAAc,QAAA,EAAS;AAAA,UAChC,WAAA,EAAa,CAAA,MAAA,EAAS,MAAA,CAAO,KAAA,IAAS,IAAI,CAAA,CAAA;AAAA,UACzC,GAAG,SAAS,IAAI;AAAA;AAAA,OACnB;AAAA,sBACAA,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,SAAA,EAAU,iBAAA;AAAA,UACV,KAAA,EAAO,EAAE,QAAA,EAAU,UAAA,EAAY,OAAO,QAAA,EAAS;AAAA,UAC/C,OAAA,EAAS,MAAM,eAAA,CAAgB,CAAC,YAAY,CAAA;AAAA,UAE3C,QAAA,EAAA,YAAA,mBAAeA,GAAAA,CAAC,MAAA,EAAA,EAAO,IAAA,EAAM,EAAA,EAAI,CAAA,mBAAKA,GAAAA,CAAC,GAAA,EAAA,EAAI,IAAA,EAAM,EAAA,EAAI;AAAA;AAAA;AACxD,KAAA,EACF,CAAA;AAAA,IACC,KAAA,oBACCD,IAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,mBAAA,EACd,QAAA,EAAA;AAAA,sBAAAC,GAAAA,CAACC,WAAAA,EAAA,EAAY,IAAA,EAAM,EAAA,EAAI,CAAA;AAAA,MACtB,KAAA,CAAM;AAAA,KAAA,EACT;AAAA,GAAA,EAEJ,CAAA;AAEJ,CAAA;ACxCO,IAAM,cAA0C,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,YAAW,KAAM;AACvF,EAAA,MAAM;AAAA,IACJ,QAAA;AAAA,IACA,SAAA,EAAW,EAAE,MAAA;AAAO,MAClBH,cAAAA,EAAe;AACnB,EAAA,MAAM,KAAA,GAAQ,OAAO,IAAI,CAAA;AAEzB,EAAA,uBACEC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iBAAA,EACb,QAAA,EAAA;AAAA,oBAAAA,IAAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAU,WAAA,EAAY,SAAS,IAAA,EACnC,QAAA,EAAA;AAAA,MAAA,MAAA,CAAO,KAAA,IAAS,IAAA;AAAA,MAChB,8BAAcC,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qBAAoB,QAAA,EAAA,GAAA,EAAC;AAAA,KAAA,EACtD,CAAA;AAAA,oBACAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBACb,QAAA,kBAAAA,GAAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,EAAA,EAAI,IAAA;AAAA,QACJ,IAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAW,CAAA,UAAA,EAAa,KAAA,GAAQ,kBAAA,GAAqB,EAAE,CAAA,CAAA;AAAA,QACvD,WAAA,EAAa,CAAA,MAAA,EAAS,MAAA,CAAO,KAAA,IAAS,IAAI,CAAA,CAAA;AAAA,QACzC,GAAG,SAAS,IAAA,EAAM;AAAA,UACjB,aAAA,EAAe;AAAA,SAChB;AAAA;AAAA,KACH,EACF,CAAA;AAAA,IACC,KAAA,oBACCD,IAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,mBAAA,EACd,QAAA,EAAA;AAAA,sBAAAC,GAAAA,CAACC,WAAAA,EAAA,EAAY,IAAA,EAAM,EAAA,EAAI,CAAA;AAAA,MACtB,KAAA,CAAM;AAAA,KAAA,EACT;AAAA,GAAA,EAEJ,CAAA;AAEJ,CAAA;AC9BO,IAAM,gBAA8C,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,YAAW,KAAM;AAC3F,EAAA,MAAM;AAAA,IACJ,QAAA;AAAA,IACA,KAAA;AAAA,IACA,SAAA,EAAW,EAAE,MAAA;AAAO,MAClBH,cAAAA,EAAe;AACnB,EAAA,MAAM,KAAA,GAAQ,OAAO,IAAI,CAAA;AACzB,EAAA,MAAM,KAAA,GAAQ,MAAM,IAAI,CAAA;AAExB,EAAA,MAAM,SAAS,SAAA,CAAU;AAAA,IACvB,UAAA,EAAY,CAAC,UAAU,CAAA;AAAA,IACvB,SAAS,KAAA,IAAS,EAAA;AAAA,IAClB,QAAA,EAAU,CAAC,EAAE,MAAA,EAAAI,SAAO,KAAM;AACxB,MAAA,QAAA,CAAS,IAAA,EAAMA,QAAO,OAAA,EAAQ,EAAG,EAAE,cAAA,EAAgB,IAAA,EAAM,WAAA,EAAa,IAAA,EAAM,CAAA;AAAA,IAC9E;AAAA,GACD,CAAA;AAGD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,MAAA,IAAU,KAAA,KAAU,MAAA,CAAO,OAAA,EAAQ,EAAG;AACxC,MAAA,MAAA,CAAO,QAAA,CAAS,UAAA,CAAW,KAAA,IAAS,EAAE,CAAA;AAAA,IACxC;AAAA,EACF,CAAA,EAAG,CAAC,KAAA,EAAO,MAAM,CAAC,CAAA;AAElB,EAAA,uBACEH,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iBAAA,EACb,QAAA,EAAA;AAAA,oBAAAA,IAAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAU,WAAA,EAAY,SAAS,IAAA,EACnC,QAAA,EAAA;AAAA,MAAA,MAAA,CAAO,KAAA,IAAS,IAAA;AAAA,MAChB,8BAAcC,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qBAAoB,QAAA,EAAA,GAAA,EAAC;AAAA,KAAA,EACtD,CAAA;AAAA,oBAEAD,KAAC,KAAA,EAAA,EAAI,SAAA,EAAW,yBAAyB,KAAA,GAAQ,kBAAA,GAAqB,EAAE,CAAA,CAAA,EACtE,QAAA,EAAA;AAAA,sBAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uBAAA,EACb,QAAA,EAAA;AAAA,wBAAAC,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,KAAA,EAAA,CAAQ,QAAQ,UAAA,EAAA,CAAa,GAAA,EAAA;AAAA,YACpD,WAAW,CAAA,gBAAA,EAAA,CAAmB,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,QAAA,CAAS,MAAA,CAAA,IAAU,cAAc,EAAE,CAAA,CAAA;AAAA,YAEzE,QAAA,kBAAAA,GAAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAM,EAAA,EAAI;AAAA;AAAA,SAClB;AAAA,wBACAA,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,KAAA,EAAA,CAAQ,QAAQ,YAAA,EAAA,CAAe,GAAA,EAAA;AAAA,YACtD,WAAW,CAAA,gBAAA,EAAA,CAAmB,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,QAAA,CAAS,QAAA,CAAA,IAAY,cAAc,EAAE,CAAA,CAAA;AAAA,YAE3E,QAAA,kBAAAA,GAAAA,CAAC,MAAA,EAAA,EAAO,IAAA,EAAM,EAAA,EAAI;AAAA;AAAA,SACpB;AAAA,wBACAA,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,KAAA,EAAA,CAAQ,QAAQ,aAAA,CAAc,EAAE,KAAA,EAAO,CAAA,EAAE,CAAA,CAAG,GAAA,EAAA;AAAA,YACnE,SAAA,EAAW,CAAA,gBAAA,EAAA,CAAmB,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,QAAA,CAAS,SAAA,EAAW,EAAE,KAAA,EAAO,CAAA,EAAE,CAAA,IAAK,WAAA,GAAc,EAAE,CAAA,CAAA;AAAA,YAE1F,QAAA,kBAAAA,GAAAA,CAAC,QAAA,EAAA,EAAS,IAAA,EAAM,EAAA,EAAI;AAAA;AAAA,SACtB;AAAA,wBACAA,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,KAAA,EAAA,CAAQ,QAAQ,gBAAA,EAAA,CAAmB,GAAA,EAAA;AAAA,YAC1D,WAAW,CAAA,gBAAA,EAAA,CAAmB,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,QAAA,CAAS,YAAA,CAAA,IAAgB,cAAc,EAAE,CAAA,CAAA;AAAA,YAE/E,QAAA,kBAAAA,GAAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAM,EAAA,EAAI;AAAA;AAAA,SAClB;AAAA,wBACAA,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,KAAA,EAAA,CAAQ,QAAQ,iBAAA,EAAA,CAAoB,GAAA,EAAA;AAAA,YAC3D,WAAW,CAAA,gBAAA,EAAA,CAAmB,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,QAAA,CAAS,aAAA,CAAA,IAAiB,cAAc,EAAE,CAAA,CAAA;AAAA,YAEhF,QAAA,kBAAAA,GAAAA,CAAC,WAAA,EAAA,EAAY,IAAA,EAAM,EAAA,EAAI;AAAA;AAAA;AACzB,OAAA,EACF,CAAA;AAAA,sBAEAA,GAAAA,CAAC,aAAA,EAAA,EAAc,MAAA,EAAgB,WAAU,uBAAA,EAAwB;AAAA,KAAA,EACnE,CAAA;AAAA,IAEC,KAAA,oBACCD,IAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,mBAAA,EACd,QAAA,EAAA;AAAA,sBAAAC,GAAAA,CAACC,WAAAA,EAAA,EAAY,IAAA,EAAM,EAAA,EAAI,CAAA;AAAA,MACtB,KAAA,CAAM;AAAA,KAAA,EACT;AAAA,GAAA,EAEJ,CAAA;AAEJ,CAAA;ACjFO,IAAM,gBAA8C,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,YAAW,KAAM;AAC3F,EAAA,IAAI,MAAA,CAAO,SAAS,QAAA,EAAU;AAC5B,IAAA,IAAI,MAAA,CAAO,WAAW,UAAA,EAAY;AAChC,MAAA,uBAAOD,GAAAA,CAAC,aAAA,EAAA,EAAc,IAAA,EAAY,QAAgB,UAAA,EAAwB,CAAA;AAAA,IAC5E;AACA,IAAA,IAAI,MAAA,CAAO,WAAW,WAAA,EAAa;AACjC,MAAA,uBAAOA,GAAAA,CAAC,aAAA,EAAA,EAAc,IAAA,EAAY,QAAgB,UAAA,EAAwB,CAAA;AAAA,IAC5E;AACA,IAAA,uBAAOA,GAAAA,CAAC,SAAA,EAAA,EAAU,IAAA,EAAY,QAAgB,UAAA,EAAwB,CAAA;AAAA,EACxE;AAEA,EAAA,IAAI,MAAA,CAAO,IAAA,KAAS,QAAA,IAAY,MAAA,CAAO,SAAS,SAAA,EAAW;AACzD,IAAA,uBAAOA,GAAAA,CAAC,WAAA,EAAA,EAAY,IAAA,EAAY,QAAgB,UAAA,EAAwB,CAAA;AAAA,EAC1E;AAGA,EAAA,uBACEA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mBACb,QAAA,kBAAAD,IAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,mBAAA,EAAoB,QAAA,EAAA;AAAA,IAAA,0BAAA;AAAA,IAAyB,MAAA,CAAO;AAAA,GAAA,EAAK,CAAA,EACxE,CAAA;AAEJ;ACrBO,IAAM,aAAwC,CAAC,EAAE,MAAA,EAAQ,QAAA,EAAU,eAAc,KAAM;AAC5F,EAAA,MAAM,UAAU,OAAA,CAAQ;AAAA,IACtB,QAAA,EAAU,YAAY,MAAA,EAAe;AAAA,MACnC,OAAA,EAAS;AAAA,QACP,WAAA,EAAa,IAAA;AAAA,QACb,QAAA,EAAU,IAAA;AAAA,QACV,KAAA,EAAO;AAAA;AACT,KACD,CAAA;AAAA,IACD;AAAA,GACD,CAAA;AAED,EAAA,IAAI,MAAA,CAAO,IAAA,KAAS,QAAA,IAAY,CAAC,OAAO,UAAA,EAAY;AAClD,IAAA,uBAAOC,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAoB,QAAA,EAAA,gDAAA,EAA8C,CAAA;AAAA,EAC1F;AAEA,EAAA,uBACED,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oBAAA,EACZ,QAAA,EAAA;AAAA,IAAA,MAAA,CAAO,yBAASC,GAAAA,CAAC,QAAG,SAAA,EAAU,gBAAA,EAAkB,iBAAO,KAAA,EAAM,CAAA;AAAA,IAC7D,MAAA,CAAO,WAAA,oBACNA,GAAAA,CAAC,GAAA,EAAA,EAAE,KAAA,EAAO,EAAE,KAAA,EAAO,uBAAA,EAAyB,YAAA,EAAc,QAAA,EAAS,EAChE,iBAAO,WAAA,EACV,CAAA;AAAA,oBAGFA,GAAAA,CAAC,YAAA,EAAA,EAAc,GAAG,SAChB,QAAA,kBAAAD,IAAAA,CAAC,MAAA,EAAA,EAAK,QAAA,EAAU,OAAA,CAAQ,YAAA,CAAa,QAAQ,CAAA,EAAG,YAAU,IAAA,EACvD,QAAA,EAAA;AAAA,MAAA,MAAA,CAAO,OAAA,CAAQ,OAAO,UAAU,CAAA,CAAE,IAAI,CAAC,CAAC,GAAA,EAAK,UAAU,CAAA,KAAG;AAxCrE,QAAA,IAAA,EAAA;AAyCY,QAAA,uBAAAC,GAAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YAEC,IAAA,EAAM,GAAA;AAAA,YACN,MAAA,EAAQ,UAAA;AAAA,YACR,UAAA,EAAA,CAAY,EAAA,GAAA,MAAA,CAAO,QAAA,KAAP,IAAA,GAAA,MAAA,GAAA,EAAA,CAAiB,QAAA,CAAS,GAAA;AAAA,WAAA;AAAA,UAHjC;AAAA,SAIP;AAAA,MAAA,CACD,CAAA;AAAA,sBACDA,GAAAA,CAAC,QAAA,EAAA,EAAO,MAAK,QAAA,EAAS,SAAA,EAAU,kBAAiB,QAAA,EAAA,QAAA,EAEjD;AAAA,KAAA,EACF,CAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ","file":"index.mjs","sourcesContent":["import React from 'react';\nimport { useFormContext } from 'react-hook-form';\nimport { JSONSchema } from '../../types/schema';\nimport { AlertCircle } from 'lucide-react';\n\ninterface TextFieldProps {\n name: string;\n schema: JSONSchema;\n isRequired?: boolean;\n}\n\nexport const TextField: React.FC<TextFieldProps> = ({ name, schema, isRequired }) => {\n const {\n register,\n formState: { errors },\n } = useFormContext();\n const error = errors[name];\n\n return (\n <div className=\"cdf-field-group\">\n <label className=\"cdf-label\" htmlFor={name}>\n {schema.title || name}\n {isRequired && <span className=\"cdf-required-mark\">*</span>}\n </label>\n <div className=\"cdf-input-wrapper\">\n <input\n id={name}\n type={schema.format === 'email' ? 'email' : 'text'}\n className={`cdf-input ${error ? 'cdf-input--error' : ''}`}\n placeholder={`Enter ${schema.title || name}`}\n {...register(name)}\n />\n </div>\n {error && (\n <span className=\"cdf-error-message\">\n <AlertCircle size={14} />\n {error.message as string}\n </span>\n )}\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport { useFormContext } from 'react-hook-form';\nimport { JSONSchema } from '../../types/schema';\nimport { AlertCircle, Eye, EyeOff } from 'lucide-react';\n\ninterface PasswordFieldProps {\n name: string;\n schema: JSONSchema;\n isRequired?: boolean;\n}\n\nexport const PasswordField: React.FC<PasswordFieldProps> = ({ name, schema, isRequired }) => {\n const {\n register,\n formState: { errors },\n } = useFormContext();\n const [showPassword, setShowPassword] = useState(false);\n const error = errors[name];\n\n return (\n <div className=\"cdf-field-group\">\n <label className=\"cdf-label\" htmlFor={name}>\n {schema.title || name}\n {isRequired && <span className=\"cdf-required-mark\">*</span>}\n </label>\n <div className=\"cdf-input-wrapper\">\n <input\n id={name}\n type={showPassword ? 'text' : 'password'}\n className={`cdf-input ${error ? 'cdf-input--error' : ''}`}\n style={{ paddingRight: '2.5rem' }}\n placeholder={`Enter ${schema.title || name}`}\n {...register(name)}\n />\n <button\n type=\"button\"\n className=\"cdf-toolbar-btn\"\n style={{ position: 'absolute', right: '0.5rem' }}\n onClick={() => setShowPassword(!showPassword)}\n >\n {showPassword ? <EyeOff size={16} /> : <Eye size={16} />}\n </button>\n </div>\n {error && (\n <span className=\"cdf-error-message\">\n <AlertCircle size={14} />\n {error.message as string}\n </span>\n )}\n </div>\n );\n};\n","import React from 'react';\nimport { useFormContext } from 'react-hook-form';\nimport { JSONSchema } from '../../types/schema';\nimport { AlertCircle } from 'lucide-react';\n\ninterface NumberFieldProps {\n name: string;\n schema: JSONSchema;\n isRequired?: boolean;\n}\n\nexport const NumberField: React.FC<NumberFieldProps> = ({ name, schema, isRequired }) => {\n const {\n register,\n formState: { errors },\n } = useFormContext();\n const error = errors[name];\n\n return (\n <div className=\"cdf-field-group\">\n <label className=\"cdf-label\" htmlFor={name}>\n {schema.title || name}\n {isRequired && <span className=\"cdf-required-mark\">*</span>}\n </label>\n <div className=\"cdf-input-wrapper\">\n <input\n id={name}\n type=\"number\"\n className={`cdf-input ${error ? 'cdf-input--error' : ''}`}\n placeholder={`Enter ${schema.title || name}`}\n {...register(name, {\n valueAsNumber: true,\n })}\n />\n </div>\n {error && (\n <span className=\"cdf-error-message\">\n <AlertCircle size={14} />\n {error.message as string}\n </span>\n )}\n </div>\n );\n};\n","import React, { useEffect } from 'react';\nimport { useFormContext } from 'react-hook-form';\nimport { useEditor, EditorContent } from '@tiptap/react';\nimport StarterKit from '@tiptap/starter-kit';\nimport { JSONSchema } from '../../types/schema';\nimport { AlertCircle, Bold, Italic, List, ListOrdered, Heading2 } from 'lucide-react';\n\ninterface RichTextFieldProps {\n name: string;\n schema: JSONSchema;\n isRequired?: boolean;\n}\n\nexport const RichTextField: React.FC<RichTextFieldProps> = ({ name, schema, isRequired }) => {\n const {\n setValue,\n watch,\n formState: { errors },\n } = useFormContext();\n const error = errors[name];\n const value = watch(name);\n\n const editor = useEditor({\n extensions: [StarterKit],\n content: value || '',\n onUpdate: ({ editor }) => {\n setValue(name, editor.getHTML(), { shouldValidate: true, shouldDirty: true });\n },\n });\n\n // Keep editor in sync with external form changes (if any)\n useEffect(() => {\n if (editor && value !== editor.getHTML()) {\n editor.commands.setContent(value || '');\n }\n }, [value, editor]);\n\n return (\n <div className=\"cdf-field-group\">\n <label className=\"cdf-label\" htmlFor={name}>\n {schema.title || name}\n {isRequired && <span className=\"cdf-required-mark\">*</span>}\n </label>\n\n <div className={`cdf-rich-text-wrapper ${error ? 'cdf-input--error' : ''}`}>\n <div className=\"cdf-rich-text-toolbar\">\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleBold().run()}\n className={`cdf-toolbar-btn ${editor?.isActive('bold') ? 'is-active' : ''}`}\n >\n <Bold size={16} />\n </button>\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleItalic().run()}\n className={`cdf-toolbar-btn ${editor?.isActive('italic') ? 'is-active' : ''}`}\n >\n <Italic size={16} />\n </button>\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleHeading({ level: 2 }).run()}\n className={`cdf-toolbar-btn ${editor?.isActive('heading', { level: 2 }) ? 'is-active' : ''}`}\n >\n <Heading2 size={16} />\n </button>\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleBulletList().run()}\n className={`cdf-toolbar-btn ${editor?.isActive('bulletList') ? 'is-active' : ''}`}\n >\n <List size={16} />\n </button>\n <button\n type=\"button\"\n onClick={() => editor?.chain().focus().toggleOrderedList().run()}\n className={`cdf-toolbar-btn ${editor?.isActive('orderedList') ? 'is-active' : ''}`}\n >\n <ListOrdered size={16} />\n </button>\n </div>\n\n <EditorContent editor={editor} className=\"cdf-rich-text-content\" />\n </div>\n\n {error && (\n <span className=\"cdf-error-message\">\n <AlertCircle size={14} />\n {error.message as string}\n </span>\n )}\n </div>\n );\n};\n","import React from 'react';\nimport { JSONSchema } from '../types/schema';\nimport { TextField } from './fields/TextField';\nimport { PasswordField } from './fields/PasswordField';\nimport { NumberField } from './fields/NumberField';\nimport { RichTextField } from './fields/RichTextField';\n\ninterface FieldRendererProps {\n name: string;\n schema: JSONSchema;\n isRequired?: boolean;\n}\n\nexport const FieldRenderer: React.FC<FieldRendererProps> = ({ name, schema, isRequired }) => {\n if (schema.type === 'string') {\n if (schema.format === 'password') {\n return <PasswordField name={name} schema={schema} isRequired={isRequired} />;\n }\n if (schema.format === 'rich-text') {\n return <RichTextField name={name} schema={schema} isRequired={isRequired} />;\n }\n return <TextField name={name} schema={schema} isRequired={isRequired} />;\n }\n\n if (schema.type === 'number' || schema.type === 'integer') {\n return <NumberField name={name} schema={schema} isRequired={isRequired} />;\n }\n\n // Fallback for unsupported types\n return (\n <div className=\"cdf-field-group\">\n <p className=\"cdf-error-message\">Unsupported field type: {schema.type}</p>\n </div>\n );\n};\n","import React from 'react';\nimport { useForm, FormProvider } from 'react-hook-form';\nimport { ajvResolver } from '@hookform/resolvers/ajv';\nimport { JSONSchema } from '../types/schema';\nimport { FieldRenderer } from './FieldRenderer';\nimport '../styles/form.css';\n\ninterface SchemaFormProps {\n schema: JSONSchema;\n onSubmit: (data: any) => void;\n defaultValues?: any;\n}\n\nexport const SchemaForm: React.FC<SchemaFormProps> = ({ schema, onSubmit, defaultValues }) => {\n const methods = useForm({\n resolver: ajvResolver(schema as any, {\n formats: {\n 'rich-text': true,\n password: true,\n email: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/,\n },\n }),\n defaultValues,\n });\n\n if (schema.type !== 'object' || !schema.properties) {\n return <div className=\"cdf-error-message\">Root schema must be an object with properties.</div>;\n }\n\n return (\n <div className=\"cdf-form-container\">\n {schema.title && <h2 className=\"cdf-form-title\">{schema.title}</h2>}\n {schema.description && (\n <p style={{ color: 'var(--cdf-text-muted)', marginBottom: '1.5rem' }}>\n {schema.description}\n </p>\n )}\n\n <FormProvider {...methods}>\n <form onSubmit={methods.handleSubmit(onSubmit)} noValidate>\n {Object.entries(schema.properties).map(([key, propSchema]) => (\n <FieldRenderer\n key={key}\n name={key}\n schema={propSchema}\n isRequired={schema.required?.includes(key)}\n />\n ))}\n <button type=\"submit\" className=\"cdf-submit-btn\">\n Submit\n </button>\n </form>\n </FormProvider>\n </div>\n );\n};\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "config-driven-form",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup",
|
|
20
|
+
"dev": "tsup --watch",
|
|
21
|
+
"lint": "eslint 'src/**/*.{ts,tsx}'",
|
|
22
|
+
"format": "prettier --write 'src/**/*.{ts,tsx,css}'",
|
|
23
|
+
"prepare": "husky",
|
|
24
|
+
"storybook": "storybook dev -p 6006",
|
|
25
|
+
"build-storybook": "storybook build"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [],
|
|
28
|
+
"author": "",
|
|
29
|
+
"license": "ISC",
|
|
30
|
+
"type": "commonjs",
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=20.0.0"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@hookform/resolvers": "^5.4.0",
|
|
36
|
+
"@tiptap/pm": "^3.26.1",
|
|
37
|
+
"@tiptap/react": "^3.26.1",
|
|
38
|
+
"@tiptap/starter-kit": "^3.26.1",
|
|
39
|
+
"ajv": "^8.20.0",
|
|
40
|
+
"ajv-errors": "^3.0.0",
|
|
41
|
+
"ajv-formats": "^3.0.1",
|
|
42
|
+
"lucide-react": "^1.18.0",
|
|
43
|
+
"react-hook-form": "^7.79.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@changesets/cli": "^2.31.0",
|
|
47
|
+
"@chromatic-com/storybook": "^5.2.1",
|
|
48
|
+
"@commitlint/cli": "^21.0.2",
|
|
49
|
+
"@commitlint/config-conventional": "^21.0.2",
|
|
50
|
+
"@storybook/addon-a11y": "^10.4.5",
|
|
51
|
+
"@storybook/addon-docs": "^10.4.5",
|
|
52
|
+
"@storybook/addon-mcp": "^0.6.0",
|
|
53
|
+
"@storybook/addon-vitest": "^10.4.5",
|
|
54
|
+
"@storybook/react-vite": "^10.4.5",
|
|
55
|
+
"@types/react": "^19.2.17",
|
|
56
|
+
"@types/react-dom": "^19.2.3",
|
|
57
|
+
"@typescript-eslint/eslint-plugin": "^8.61.1",
|
|
58
|
+
"@typescript-eslint/parser": "^8.61.1",
|
|
59
|
+
"@vitest/browser-playwright": "^4.1.9",
|
|
60
|
+
"@vitest/coverage-v8": "^4.1.9",
|
|
61
|
+
"eslint": "^8.57.1",
|
|
62
|
+
"eslint-config-prettier": "^10.1.8",
|
|
63
|
+
"eslint-plugin-react": "^7.37.5",
|
|
64
|
+
"eslint-plugin-react-hooks": "^7.1.1",
|
|
65
|
+
"eslint-plugin-storybook": "^10.4.5",
|
|
66
|
+
"husky": "^9.1.7",
|
|
67
|
+
"lint-staged": "^17.0.7",
|
|
68
|
+
"playwright": "^1.61.0",
|
|
69
|
+
"prettier": "^3.8.4",
|
|
70
|
+
"react": "^19.2.7",
|
|
71
|
+
"react-dom": "^19.2.7",
|
|
72
|
+
"storybook": "^10.4.5",
|
|
73
|
+
"tsup": "^8.5.1",
|
|
74
|
+
"typescript": "^6.0.3",
|
|
75
|
+
"vite": "^8.0.16",
|
|
76
|
+
"vitest": "^4.1.9"
|
|
77
|
+
}
|
|
78
|
+
}
|