formik-form-components 0.2.18 → 0.2.19
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 +458 -261
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,22 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Formik Form Components
|
|
2
2
|
|
|
3
3
|
A comprehensive collection of reusable, accessible, and customizable form components built with React, Material-UI, Formik, and Tiptap. Streamline your form development with pre-built, production-ready form elements that follow Material Design principles.
|
|
4
4
|
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- 🚀 **30+** production-ready form components
|
|
10
|
+
- 🎨 Consistent Material Design styling
|
|
11
|
+
- 🔍 Built-in form validation with Yup
|
|
12
|
+
- 📱 Fully responsive components
|
|
13
|
+
- 🎯 TypeScript support
|
|
14
|
+
- 🛠️ Customizable theming
|
|
15
|
+
- 📅 Date/Time pickers with calendar icons
|
|
16
|
+
- ✨ Rich text editing with Tiptap
|
|
17
|
+
- 📱 Mobile-friendly file uploads
|
|
18
|
+
- 🌍 Internationalization (i18n) ready
|
|
19
|
+
|
|
5
20
|
## Table of Contents
|
|
6
21
|
|
|
7
22
|
- [Installation](#installation)
|
|
@@ -24,82 +39,34 @@ npm install formik-form-components --legacy-peer-deps
|
|
|
24
39
|
yarn add formik-form-components
|
|
25
40
|
```
|
|
26
41
|
|
|
27
|
-
##
|
|
28
|
-
|
|
29
|
-
This package has the following peer dependencies. You can install them all with a single command:
|
|
42
|
+
## Installation
|
|
30
43
|
|
|
31
44
|
### Prerequisites
|
|
32
45
|
|
|
33
|
-
- TypeScript 5.0.0 or higher
|
|
46
|
+
- TypeScript 5.0.0 or higher
|
|
34
47
|
- Node.js 16.0.0 or higher
|
|
48
|
+
- React 18.0.0 or higher
|
|
35
49
|
|
|
36
|
-
###
|
|
37
|
-
|
|
38
|
-
Using npm:
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
# First, ensure TypeScript 5+ is installed
|
|
42
|
-
npm install --save-dev typescript@latest
|
|
43
|
-
|
|
44
|
-
# Then install peer dependencies with --legacy-peer-deps to handle dependency conflicts
|
|
45
|
-
npm install formik @mui/material @mui/icons-material @emotion/react @emotion/styled @mui/x-date-pickers dayjs @iconify/react react-phone-input-2 framer-motion react-dropzone i18next react-i18next react-lazy-load-image-component @tiptap/react @tiptap/starter-kit @tiptap/extension-link @tiptap/extension-text-align --legacy-peer-deps
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Or with Yarn:
|
|
50
|
+
### Quick Start
|
|
49
51
|
|
|
50
52
|
```bash
|
|
51
|
-
#
|
|
52
|
-
|
|
53
|
+
# Using npm
|
|
54
|
+
npx create-react-app my-app --template typescript
|
|
55
|
+
cd my-app
|
|
56
|
+
npm install formik-form-components
|
|
53
57
|
|
|
54
|
-
#
|
|
55
|
-
yarn
|
|
58
|
+
# Or using Yarn
|
|
59
|
+
yarn create react-app my-app --template typescript
|
|
60
|
+
cd my-app
|
|
61
|
+
yarn add formik-form-components
|
|
56
62
|
```
|
|
57
63
|
|
|
58
|
-
### Optional Dependencies
|
|
59
|
-
|
|
60
|
-
Some dependencies are marked as optional and are only required if you use specific components:
|
|
61
|
-
|
|
62
|
-
- **Rich Text Editor**:
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
@tiptap/react @tiptap/starter-kit @tiptap/extension-link @tiptap/extension-text-align
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
- **Date Pickers**:
|
|
69
|
-
|
|
70
|
-
```bash
|
|
71
|
-
@mui/x-date-pickers dayjs
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
- **File Upload**:
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
react-dropzone
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
- **Internationalization**:
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
i18next react-i18next
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
- **Animations**:
|
|
87
|
-
|
|
88
|
-
```bash
|
|
89
|
-
framer-motion
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
- **Icons**:
|
|
93
|
-
```bash
|
|
94
|
-
@mui/icons-material @iconify/react
|
|
95
|
-
```
|
|
96
|
-
|
|
97
64
|
## Getting Started
|
|
98
65
|
|
|
99
66
|
1. **Install the package and dependencies**:
|
|
100
67
|
|
|
101
68
|
```bash
|
|
102
|
-
|
|
69
|
+
npm install formik-form-components
|
|
103
70
|
```
|
|
104
71
|
|
|
105
72
|
2. **Wrap your app with ThemeProvider (optional but recommended)**:
|
|
@@ -123,234 +90,339 @@ Some dependencies are marked as optional and are only required if you use specif
|
|
|
123
90
|
3. **Basic Form Example**:
|
|
124
91
|
|
|
125
92
|
```tsx
|
|
126
|
-
import { Formik, Form } from
|
|
127
|
-
import * as Yup from
|
|
93
|
+
import { Formik, Form } from "formik";
|
|
94
|
+
import * as Yup from "yup";
|
|
128
95
|
import {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
} from
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const validationSchema = Yup.object({
|
|
142
|
-
name: Yup.string().required('Name is required'),
|
|
143
|
-
email: Yup.string().email('Invalid email').required('Email is required'),
|
|
144
|
-
phone: Yup.string().required('Phone number is required'),
|
|
145
|
-
dob: Yup.date().required('Date of birth is required'),
|
|
146
|
-
bio: Yup.string().required('Bio is required'),
|
|
147
|
-
rating: Yup.number().required('Rating is required'),
|
|
148
|
-
gender: Yup.string().required('Gender is required'),
|
|
149
|
-
interests: Yup.array().min(1, 'Select at least one interest'),
|
|
150
|
-
terms: Yup.boolean().oneOf([true], 'You must accept the terms')
|
|
151
|
-
});
|
|
96
|
+
AppInputField,
|
|
97
|
+
AppCheckBox,
|
|
98
|
+
AppDatePicker,
|
|
99
|
+
AppRichTextEditor,
|
|
100
|
+
AppRating,
|
|
101
|
+
AppRadioGroup,
|
|
102
|
+
AppMultiSelector,
|
|
103
|
+
} from "formik-form-components";
|
|
104
|
+
import { FormikHelpers } from "formik";
|
|
105
|
+
import { Button, Box } from "@mui/material";
|
|
106
|
+
```
|
|
152
107
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
];
|
|
165
|
-
|
|
166
|
-
function MyForm() {
|
|
167
|
-
const initialValues = {
|
|
168
|
-
name: '',
|
|
169
|
-
email: '',
|
|
170
|
-
phone: '',
|
|
171
|
-
dob: null,
|
|
172
|
-
bio: '',
|
|
173
|
-
rating: 0,
|
|
174
|
-
gender: '',
|
|
175
|
-
interests: [],
|
|
176
|
-
terms: false
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
const handleSubmit = (values, { setSubmitting }) => {
|
|
180
|
-
console.log('Form submitted:', values);
|
|
181
|
-
setSubmitting(false);
|
|
182
|
-
};
|
|
108
|
+
const validationSchema = Yup.object({
|
|
109
|
+
name: Yup.string().required("Name is required"),
|
|
110
|
+
email: Yup.string().email("Invalid email").required("Email is required"),
|
|
111
|
+
phone: Yup.string().required("Phone number is required"),
|
|
112
|
+
dob: Yup.date().required("Date of birth is required"),
|
|
113
|
+
bio: Yup.string().required("Bio is required"),
|
|
114
|
+
rating: Yup.number().required("Rating is required"),
|
|
115
|
+
gender: Yup.string().required("Gender is required"),
|
|
116
|
+
interests: Yup.array().min(1, "Select at least one interest"),
|
|
117
|
+
terms: Yup.boolean().oneOf([true], "You must accept the terms"),
|
|
118
|
+
});
|
|
183
119
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
120
|
+
const interests = [
|
|
121
|
+
{ value: "sports", label: "Sports" },
|
|
122
|
+
{ value: "music", label: "Music" },
|
|
123
|
+
{ value: "reading", label: "Reading" },
|
|
124
|
+
{ value: "travel", label: "Travel" },
|
|
125
|
+
];
|
|
126
|
+
|
|
127
|
+
const genderOptions = [
|
|
128
|
+
{ value: "male", label: "Male" },
|
|
129
|
+
{ value: "female", label: "Female" },
|
|
130
|
+
{ value: "other", label: "Other" },
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
function App() {
|
|
134
|
+
const initialValues = {
|
|
135
|
+
name: "",
|
|
136
|
+
email: "",
|
|
137
|
+
phone: "",
|
|
138
|
+
dob: null,
|
|
139
|
+
bio: "",
|
|
140
|
+
rating: 0,
|
|
141
|
+
gender: "",
|
|
142
|
+
interests: [],
|
|
143
|
+
terms: false,
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const handleSubmit = (
|
|
147
|
+
values: {
|
|
148
|
+
[K in keyof typeof initialValues]: (typeof initialValues)[K];
|
|
149
|
+
},
|
|
150
|
+
{ setSubmitting }: FormikHelpers<typeof initialValues>
|
|
151
|
+
) => {
|
|
152
|
+
console.log("Form submitted:", values);
|
|
153
|
+
setSubmitting(false);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
return (
|
|
157
|
+
<Formik
|
|
158
|
+
initialValues={initialValues}
|
|
159
|
+
validationSchema={validationSchema}
|
|
160
|
+
onSubmit={handleSubmit}
|
|
161
|
+
>
|
|
162
|
+
{({ isSubmitting, setFieldValue, values }) => (
|
|
163
|
+
|
|
164
|
+
<Form>
|
|
165
|
+
<Box sx={{ maxWidth: 600, mx: "auto", p: 3 }}>
|
|
166
|
+
<AppInputField
|
|
167
|
+
name="name"
|
|
168
|
+
label="Full Name"
|
|
169
|
+
placeholder="Enter your full name"
|
|
170
|
+
fullWidth
|
|
171
|
+
margin="normal"
|
|
172
|
+
/>
|
|
173
|
+
|
|
174
|
+
<AppInputField
|
|
175
|
+
name="email"
|
|
176
|
+
label="Email Address"
|
|
177
|
+
type="email"
|
|
178
|
+
placeholder="your.email@example.com"
|
|
179
|
+
fullWidth
|
|
180
|
+
margin="normal"
|
|
181
|
+
/>
|
|
182
|
+
|
|
183
|
+
<AppDatePicker name="birthDate" label="Birth Date" sx={{ mb: 2 }} />
|
|
184
|
+
|
|
185
|
+
<AppRichTextEditor
|
|
186
|
+
name="content"
|
|
187
|
+
label="Content"
|
|
188
|
+
variant="outlined"
|
|
189
|
+
sx={{ mb: 2 }}
|
|
190
|
+
/>
|
|
191
|
+
|
|
192
|
+
<AppRating
|
|
193
|
+
name="rating"
|
|
194
|
+
label="How would you rate your experience?"
|
|
195
|
+
precision={0.5}
|
|
196
|
+
size="large"
|
|
197
|
+
/>
|
|
198
|
+
|
|
199
|
+
<AppRadioGroup
|
|
200
|
+
name="gender"
|
|
201
|
+
label="Gender"
|
|
202
|
+
options={genderOptions}
|
|
203
|
+
row
|
|
204
|
+
/>
|
|
205
|
+
|
|
206
|
+
<AppMultiSelector
|
|
207
|
+
name="interests"
|
|
208
|
+
label="Interests"
|
|
209
|
+
options={interests}
|
|
210
|
+
fullWidth
|
|
211
|
+
/>
|
|
212
|
+
|
|
213
|
+
<AppCheckBox
|
|
214
|
+
name="terms"
|
|
215
|
+
option={[
|
|
216
|
+
{
|
|
217
|
+
label: "I agree to terms and conditions",
|
|
218
|
+
name: "terms",
|
|
219
|
+
value: "agreed",
|
|
220
|
+
},
|
|
221
|
+
]}
|
|
222
|
+
sx={{ mb: 2 }}
|
|
223
|
+
/>
|
|
224
|
+
|
|
225
|
+
<Box sx={{ mt: 3, display: "flex", justifyContent: "flex-end" }}>
|
|
226
|
+
<Button
|
|
227
|
+
type="submit"
|
|
228
|
+
variant="contained"
|
|
229
|
+
color="primary"
|
|
230
|
+
disabled={isSubmitting}
|
|
231
|
+
>
|
|
232
|
+
{isSubmitting ? "Submitting..." : "Submit"}
|
|
233
|
+
</Button>
|
|
234
|
+
</Box>
|
|
235
|
+
</Box>
|
|
236
|
+
</Form>
|
|
237
|
+
)}
|
|
238
|
+
</Formik>
|
|
239
|
+
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export default App;
|
|
244
|
+
|
|
245
|
+
````
|
|
279
246
|
|
|
280
247
|
## Available Components
|
|
281
248
|
|
|
282
|
-
### Form
|
|
249
|
+
### Form Inputs
|
|
283
250
|
|
|
284
|
-
- `AppInputField` -
|
|
285
|
-
- `
|
|
286
|
-
- `
|
|
287
|
-
- `AppSwitch` - Toggle switch
|
|
251
|
+
- `AppInputField` - Versatile text input with validation and Material-UI styling
|
|
252
|
+
- `AppTextArea` - Multi-line text input with auto-resize
|
|
253
|
+
- `AppCheckBox` - Customizable checkbox with label and validation
|
|
254
|
+
- `AppSwitch` - Toggle switch with label and form integration
|
|
255
|
+
- `AppRadioGroup` - Group of radio buttons with form validation
|
|
256
|
+
- `AppRating` - Interactive star rating component
|
|
288
257
|
|
|
289
|
-
###
|
|
258
|
+
### Selection Components
|
|
290
259
|
|
|
291
|
-
- `AppSelect` -
|
|
292
|
-
- `AppSearchableSelect` - Searchable
|
|
293
|
-
- `AppMultiSelector` - Multi-select
|
|
294
|
-
- `AppSearchableMultiSelector` - Searchable multi-select
|
|
260
|
+
- `AppSelect` - Dropdown select with Material-UI styling
|
|
261
|
+
- `AppSearchableSelect` - Searchable dropdown with typeahead
|
|
262
|
+
- `AppMultiSelector` - Multi-select with chips and search
|
|
263
|
+
- `AppSearchableMultiSelector` - Searchable multi-select with chips
|
|
264
|
+
- `AppAutocomplete` - Autocomplete with suggestions
|
|
265
|
+
- `AppTagsCreator` - Tag input with creation and selection
|
|
295
266
|
|
|
296
|
-
### Date & Time
|
|
267
|
+
### Date & Time Pickers
|
|
297
268
|
|
|
298
|
-
- `AppDatePicker` - Date picker
|
|
299
|
-
- `AppTimePicker` - Time picker
|
|
300
|
-
- `
|
|
301
|
-
- `
|
|
269
|
+
- `AppDatePicker` - Date picker with calendar icon and validation
|
|
270
|
+
- `AppTimePicker` - Time picker with 12/24 hour support
|
|
271
|
+
- `AppDateAndTimePicker` - Combined date and time picker
|
|
272
|
+
- `AppDateTimePicker` - Alternative date/time picker implementation
|
|
302
273
|
|
|
303
|
-
###
|
|
274
|
+
### File Handling
|
|
304
275
|
|
|
305
|
-
- `
|
|
306
|
-
- `
|
|
276
|
+
- `AppUploadFile` - File upload with drag & drop and preview
|
|
277
|
+
- `AppSimpleUploadFile` - Basic file upload component
|
|
307
278
|
- `AppImageUpload` - Image upload with crop and preview
|
|
308
279
|
|
|
280
|
+
### Rich Content
|
|
281
|
+
|
|
282
|
+
- `AppRichTextEditor` - Feature-rich WYSIWYG editor with Tiptap
|
|
283
|
+
- `RichTextEditor` - Core rich text editor component
|
|
284
|
+
|
|
309
285
|
### Advanced
|
|
310
286
|
|
|
311
|
-
- `AppPhoneNoInput` -
|
|
312
|
-
- `
|
|
313
|
-
- `
|
|
314
|
-
- `AppSlider` - Range slider input
|
|
315
|
-
- `AppFormErrorMessage` - Displays form validation errors
|
|
287
|
+
- `AppPhoneNoInput` - International phone number input
|
|
288
|
+
- `AppFormErrorMessage` - Consistent error message display
|
|
289
|
+
- `SubmitButton` - Form submission button with loading state
|
|
316
290
|
|
|
317
291
|
## Component Documentation
|
|
318
292
|
|
|
293
|
+
## Component Examples
|
|
294
|
+
|
|
319
295
|
### AppInputField
|
|
320
296
|
|
|
321
297
|
A versatile text input field with built-in validation and Material-UI styling.
|
|
322
298
|
|
|
323
299
|
```tsx
|
|
324
300
|
import { AppInputField } from 'formik-form-components';
|
|
301
|
+
import { InputAdornment } from '@mui/material';
|
|
302
|
+
import { Email as EmailIcon } from '@mui/icons-material';
|
|
325
303
|
|
|
304
|
+
// Basic usage
|
|
326
305
|
<AppInputField
|
|
327
|
-
name="
|
|
328
|
-
label="
|
|
329
|
-
placeholder="Enter your
|
|
306
|
+
name="email"
|
|
307
|
+
label="Email Address"
|
|
308
|
+
placeholder="Enter your email"
|
|
330
309
|
fullWidth
|
|
331
|
-
margin="normal"
|
|
332
310
|
required
|
|
333
|
-
helperText="
|
|
311
|
+
helperText="We'll never share your email"
|
|
334
312
|
InputProps={{
|
|
335
|
-
startAdornment:
|
|
313
|
+
startAdornment: (
|
|
314
|
+
<InputAdornment position="start">
|
|
315
|
+
<EmailIcon color="action" />
|
|
316
|
+
</InputAdornment>
|
|
317
|
+
),
|
|
318
|
+
}}
|
|
319
|
+
/>
|
|
320
|
+
````
|
|
321
|
+
|
|
322
|
+
### AppDatePicker
|
|
323
|
+
|
|
324
|
+
Date picker with calendar icon and validation.
|
|
325
|
+
|
|
326
|
+
```tsx
|
|
327
|
+
import { AppDatePicker } from 'formik-form-components';
|
|
328
|
+
|
|
329
|
+
<AppDatePicker
|
|
330
|
+
name="birthDate"
|
|
331
|
+
label="Date of Birth"
|
|
332
|
+
required
|
|
333
|
+
sx={{ mb: 2 }}
|
|
334
|
+
textFieldSx={{
|
|
335
|
+
'& .MuiOutlinedInput-root': {
|
|
336
|
+
'&:hover fieldset': {
|
|
337
|
+
borderColor: 'primary.main',
|
|
338
|
+
},
|
|
339
|
+
},
|
|
336
340
|
}}
|
|
337
341
|
/>
|
|
338
342
|
```
|
|
339
343
|
|
|
340
|
-
|
|
344
|
+
### AppRating
|
|
345
|
+
|
|
346
|
+
Interactive star rating component with customizable colors.
|
|
347
|
+
|
|
348
|
+
```tsx
|
|
349
|
+
import { AppRating } from 'formik-form-components';
|
|
350
|
+
|
|
351
|
+
<AppRating
|
|
352
|
+
name="rating"
|
|
353
|
+
label="Rating"
|
|
354
|
+
required
|
|
355
|
+
ratingSx={{
|
|
356
|
+
'& .MuiRating-iconFilled': {
|
|
357
|
+
color: '#ff6d75',
|
|
358
|
+
},
|
|
359
|
+
'& .MuiRating-iconHover': {
|
|
360
|
+
color: '#ff3d47',
|
|
361
|
+
},
|
|
362
|
+
}}
|
|
363
|
+
/>
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### AppUploadFile
|
|
367
|
+
|
|
368
|
+
File upload component with drag & drop support.
|
|
369
|
+
|
|
370
|
+
```tsx
|
|
371
|
+
import { AppUploadFile } from 'formik-form-components';
|
|
372
|
+
|
|
373
|
+
<AppUploadFile
|
|
374
|
+
name="document"
|
|
375
|
+
label="Upload Document"
|
|
376
|
+
accept="application/pdf"
|
|
377
|
+
maxSize={5 * 1024 * 1024} // 5MB
|
|
378
|
+
onDelete={() => setFieldValue("document", null)}
|
|
379
|
+
helperText="PDF files up to 5MB"
|
|
380
|
+
/>
|
|
381
|
+
```
|
|
341
382
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
383
|
+
### AppRichTextEditor
|
|
384
|
+
|
|
385
|
+
Feature-rich WYSIWYG editor based on Tiptap.
|
|
386
|
+
|
|
387
|
+
```tsx
|
|
388
|
+
import { AppRichTextEditor } from 'formik-form-components';
|
|
389
|
+
|
|
390
|
+
<AppRichTextEditor
|
|
391
|
+
name="content"
|
|
392
|
+
label="Article Content"
|
|
393
|
+
placeholder="Start writing your article here..."
|
|
394
|
+
toolbarItems={[
|
|
395
|
+
'heading',
|
|
396
|
+
'bold', 'italic', 'underline', 'strike',
|
|
397
|
+
'|',
|
|
398
|
+
'bulletList', 'orderedList', 'blockquote',
|
|
399
|
+
'|',
|
|
400
|
+
'link', 'image', 'video',
|
|
401
|
+
'|',
|
|
402
|
+
'alignLeft', 'alignCenter', 'alignRight',
|
|
403
|
+
'|',
|
|
404
|
+
'undo', 'redo'
|
|
405
|
+
]}
|
|
406
|
+
sx={{ minHeight: 300 }}
|
|
407
|
+
/>
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
## Component Props
|
|
411
|
+
|
|
412
|
+
### Common Props
|
|
413
|
+
|
|
414
|
+
Most form components accept these common props:
|
|
415
|
+
|
|
416
|
+
| Prop | Type | Default | Description |
|
|
417
|
+
| ---------- | ------- | -------- | --------------------------------------------------- |
|
|
418
|
+
| name | string | required | Field name for Formik |
|
|
419
|
+
| label | string | '' | Field label |
|
|
420
|
+
| required | boolean | false | Show required indicator |
|
|
421
|
+
| disabled | boolean | false | Disable the input |
|
|
422
|
+
| helperText | string | '' | Helper text below the field |
|
|
423
|
+
| fullWidth | boolean | false | Take full width of container |
|
|
424
|
+
| sx | SxProps | {} | Custom styles |
|
|
425
|
+
| ...other | any | - | Additional props passed to the underlying component |
|
|
354
426
|
|
|
355
427
|
### AppRichTextEditor
|
|
356
428
|
|
|
@@ -383,19 +455,48 @@ import { AppRichTextEditor } from '@tkturners/form-components';
|
|
|
383
455
|
|
|
384
456
|
All components can be customized using Material-UI's theming system. You can override styles, default props, and more.
|
|
385
457
|
|
|
458
|
+
### Basic Theme Customization
|
|
459
|
+
|
|
386
460
|
```tsx
|
|
387
461
|
import { createTheme } from '@mui/material/styles';
|
|
388
462
|
|
|
389
|
-
const theme = createTheme({
|
|
463
|
+
export const theme = createTheme({
|
|
464
|
+
palette: {
|
|
465
|
+
primary: {
|
|
466
|
+
main: '#3f51b5',
|
|
467
|
+
light: '#6573c3',
|
|
468
|
+
dark: '#2c387e',
|
|
469
|
+
contrastText: '#fff',
|
|
470
|
+
},
|
|
471
|
+
secondary: {
|
|
472
|
+
main: '#f50057',
|
|
473
|
+
light: '#f73378',
|
|
474
|
+
dark: '#ab003c',
|
|
475
|
+
contrastText: '#fff',
|
|
476
|
+
},
|
|
477
|
+
},
|
|
478
|
+
typography: {
|
|
479
|
+
fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
|
|
480
|
+
h1: { fontSize: '2.5rem', fontWeight: 500 },
|
|
481
|
+
h2: { fontSize: '2rem', fontWeight: 500 },
|
|
482
|
+
// ... other typography settings
|
|
483
|
+
},
|
|
390
484
|
components: {
|
|
485
|
+
MuiButton: {
|
|
486
|
+
styleOverrides: {
|
|
487
|
+
root: {
|
|
488
|
+
textTransform: 'none',
|
|
489
|
+
borderRadius: 8,
|
|
490
|
+
},
|
|
491
|
+
},
|
|
492
|
+
},
|
|
391
493
|
MuiTextField: {
|
|
392
494
|
defaultProps: {
|
|
393
495
|
variant: 'outlined',
|
|
394
496
|
fullWidth: true,
|
|
395
|
-
|
|
497
|
+
size: 'small',
|
|
396
498
|
},
|
|
397
499
|
},
|
|
398
|
-
// Override specific component styles
|
|
399
500
|
MuiFormControl: {
|
|
400
501
|
styleOverrides: {
|
|
401
502
|
root: {
|
|
@@ -403,19 +504,115 @@ const theme = createTheme({
|
|
|
403
504
|
},
|
|
404
505
|
},
|
|
405
506
|
},
|
|
507
|
+
// Add more component overrides as needed
|
|
508
|
+
},
|
|
509
|
+
});
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Customizing Specific Components
|
|
513
|
+
|
|
514
|
+
You can customize specific components by targeting their class names:
|
|
515
|
+
|
|
516
|
+
```tsx
|
|
517
|
+
const theme = createTheme({
|
|
518
|
+
components: {
|
|
519
|
+
// Customize DatePicker
|
|
520
|
+
MuiPickersDay: {
|
|
521
|
+
styleOverrides: {
|
|
522
|
+
root: {
|
|
523
|
+
'&.Mui-selected': {
|
|
524
|
+
backgroundColor: theme.palette.primary.main,
|
|
525
|
+
'&:hover': {
|
|
526
|
+
backgroundColor: theme.palette.primary.dark,
|
|
527
|
+
},
|
|
528
|
+
},
|
|
529
|
+
},
|
|
530
|
+
},
|
|
531
|
+
},
|
|
532
|
+
|
|
533
|
+
// Customize Rating
|
|
534
|
+
MuiRating: {
|
|
535
|
+
styleOverrides: {
|
|
536
|
+
iconFilled: {
|
|
537
|
+
color: '#ff6d75',
|
|
538
|
+
},
|
|
539
|
+
iconHover: {
|
|
540
|
+
color: '#ff3d47',
|
|
541
|
+
},
|
|
542
|
+
},
|
|
543
|
+
},
|
|
544
|
+
|
|
545
|
+
// Customize Select
|
|
546
|
+
MuiOutlinedInput: {
|
|
547
|
+
styleOverrides: {
|
|
548
|
+
root: {
|
|
549
|
+
'&:hover .MuiOutlinedInput-notchedOutline': {
|
|
550
|
+
borderColor: 'rgba(0, 0, 0, 0.23)',
|
|
551
|
+
},
|
|
552
|
+
'&.Mui-focused .MuiOutlinedInput-notchedOutline': {
|
|
553
|
+
borderWidth: '1px',
|
|
554
|
+
},
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
},
|
|
406
558
|
},
|
|
407
|
-
|
|
559
|
+
});
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### Dark Mode
|
|
563
|
+
|
|
564
|
+
Easily implement dark mode with Material-UI's theme system:
|
|
565
|
+
|
|
566
|
+
```tsx
|
|
567
|
+
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
|
568
|
+
import CssBaseline from '@mui/material/CssBaseline';
|
|
569
|
+
|
|
570
|
+
const darkTheme = createTheme({
|
|
408
571
|
palette: {
|
|
572
|
+
mode: 'dark',
|
|
409
573
|
primary: {
|
|
410
|
-
main: '#
|
|
574
|
+
main: '#90caf9',
|
|
411
575
|
},
|
|
412
576
|
secondary: {
|
|
413
|
-
main: '#
|
|
577
|
+
main: '#f48fb1',
|
|
578
|
+
},
|
|
579
|
+
background: {
|
|
580
|
+
default: '#121212',
|
|
581
|
+
paper: '#1e1e1e',
|
|
414
582
|
},
|
|
415
583
|
},
|
|
416
584
|
});
|
|
585
|
+
|
|
586
|
+
function App() {
|
|
587
|
+
return (
|
|
588
|
+
<ThemeProvider theme={darkTheme}>
|
|
589
|
+
<CssBaseline />
|
|
590
|
+
{/* Your app components */}
|
|
591
|
+
</ThemeProvider>
|
|
592
|
+
);
|
|
593
|
+
}
|
|
417
594
|
```
|
|
418
595
|
|
|
596
|
+
root: {
|
|
597
|
+
marginBottom: '1rem',
|
|
598
|
+
},
|
|
599
|
+
},
|
|
600
|
+
},
|
|
601
|
+
|
|
602
|
+
},
|
|
603
|
+
// Custom palette
|
|
604
|
+
palette: {
|
|
605
|
+
primary: {
|
|
606
|
+
main: '#1976d2',
|
|
607
|
+
},
|
|
608
|
+
secondary: {
|
|
609
|
+
main: '#dc004e',
|
|
610
|
+
},
|
|
611
|
+
},
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
````
|
|
615
|
+
|
|
419
616
|
## TypeScript Support
|
|
420
617
|
|
|
421
618
|
All components are written in TypeScript and include type definitions. The form values should be properly typed when using with Formik:
|
|
@@ -448,7 +645,7 @@ const validationSchema = Yup.object<FormValues>({
|
|
|
448
645
|
>
|
|
449
646
|
{/* ... */}
|
|
450
647
|
</Formik>
|
|
451
|
-
|
|
648
|
+
````
|
|
452
649
|
|
|
453
650
|
## Contributing
|
|
454
651
|
|