@algodomain/smart-forms 0.1.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 ADDED
@@ -0,0 +1,313 @@
1
+ # @algodomain/smart-forms
2
+
3
+ A powerful, flexible React form framework with smart fields, multi-tab support, built-in validation, and seamless API integration. Built with TypeScript, Tailwind CSS, and shadcn/ui components.
4
+
5
+ 📚 **[Complete User Guide](./USER_GUIDE.md)** | 🚀 **[Quick Reference](./QUICK_REFERENCE.md)** | 📖 **[API Reference](./API_REFERENCE.md)**
6
+
7
+ ## Features
8
+
9
+ - 🎯 **Smart Fields**: Pre-built, validated form fields with consistent UX
10
+ - 📑 **Multi-Tab Forms**: Create complex forms with tabbed navigation and progress tracking
11
+ - ✅ **Built-in Validation**: Powered by Zod for type-safe validation
12
+ - 🔄 **API Integration**: Automatic form submission with authentication support
13
+ - 💾 **Auto-Save**: LocalStorage support for draft saving
14
+ - 🎨 **Customizable**: Full theme control via CSS variables
15
+ - 🌙 **Dark Mode**: Built-in support for light and dark themes
16
+ - ♿ **Accessible**: Built on Radix UI primitives
17
+ - 📦 **Tree-Shakeable**: Import only what you need
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install @algodomain/smart-forms
23
+ # or
24
+ pnpm add @algodomain/smart-forms
25
+ # or
26
+ yarn add @algodomain/smart-forms
27
+ ```
28
+
29
+ ### Peer Dependencies
30
+
31
+ Make sure you have these installed:
32
+
33
+ ```bash
34
+ npm install react react-dom tailwindcss zod react-toastify date-fns lucide-react
35
+ ```
36
+
37
+ ## Quick Start
38
+
39
+ ### 1. Import the CSS
40
+
41
+ Add this to your main entry file (e.g., `main.tsx` or `index.tsx`):
42
+
43
+ ```tsx
44
+ import '@algodomain/smart-forms/style.css'
45
+ import './index.css' // Your Tailwind CSS
46
+ ```
47
+
48
+ ### 2. Create Your First Form
49
+
50
+ ```tsx
51
+ import { SmartForm } from '@algodomain/smart-forms'
52
+ import { SmartInput } from '@algodomain/smart-forms/fields'
53
+ import { FieldEmail, FieldPassword } from '@algodomain/smart-forms/opinionated'
54
+
55
+ function RegistrationForm() {
56
+ return (
57
+ <SmartForm
58
+ api="/api/register"
59
+ method="POST"
60
+ submitButtonText="Sign Up"
61
+ onSuccess={(data) => console.log('User created:', data)}
62
+ onError={(error) => console.error('Error:', error)}
63
+ authentication={{ enable: true }}
64
+ >
65
+ <SmartInput field="name" label="Full Name" required />
66
+ <FieldEmail field="email" required />
67
+ <FieldPassword field="password" required />
68
+ <SmartSelect
69
+ field="role"
70
+ label="Role"
71
+ options={[
72
+ { value: 'user', label: 'User' },
73
+ { value: 'admin', label: 'Admin' }
74
+ ]}
75
+ />
76
+ </SmartForm>
77
+ )
78
+ }
79
+ ```
80
+
81
+ ### 3. Multi-Tab Form Example
82
+
83
+ ```tsx
84
+ import { MultiTabSmartForm, Tab } from '@algodomain/smart-forms'
85
+ import { SmartInput, SmartRadioGroup, SmartTags } from '@algodomain/smart-forms/fields'
86
+ import { z } from 'zod'
87
+
88
+ function CreateJobForm() {
89
+ return (
90
+ <MultiTabSmartForm
91
+ api="/api/jobs"
92
+ method="POST"
93
+ showProgressBar={true}
94
+ showTabNumbers={true}
95
+ authentication={{ enable: true }}
96
+ onSuccess={(data) => console.log('Job created:', data)}
97
+ >
98
+ <Tab title="Basic Info">
99
+ <SmartInput
100
+ field="jobTitle"
101
+ label="Job Title"
102
+ validation={z.string().min(3)}
103
+ required
104
+ />
105
+ <SmartRadioGroup
106
+ field="jobType"
107
+ label="Job Type"
108
+ options={[
109
+ { value: 'FULL_TIME', label: 'Full Time' },
110
+ { value: 'PART_TIME', label: 'Part Time' }
111
+ ]}
112
+ required
113
+ />
114
+ </Tab>
115
+
116
+ <Tab title="Requirements">
117
+ <SmartTags
118
+ field="skills"
119
+ label="Required Skills"
120
+ validation={z.array(z.string()).min(1)}
121
+ required
122
+ />
123
+ <SmartInput
124
+ field="experience"
125
+ label="Years of Experience"
126
+ type="number"
127
+ />
128
+ </Tab>
129
+ </MultiTabSmartForm>
130
+ )
131
+ }
132
+ ```
133
+
134
+ ## Available Components
135
+
136
+ ### Core Forms
137
+
138
+ - **SmartForm**: Single-page form with API integration
139
+ - **MultiTabSmartForm**: Multi-step tabbed form with progress tracking
140
+ - **BaseSmartForm**: Low-level form component for custom layouts
141
+
142
+ ### Smart Fields
143
+
144
+ Import from `@algodomain/smart-forms/fields`:
145
+
146
+ - `SmartInput` - Text, email, password, number, textarea inputs
147
+ - `SmartSelect` - Dropdown select
148
+ - `SmartCheckbox` - Checkbox with label
149
+ - `SmartRadioGroup` - Radio button group
150
+ - `SmartCombobox` - Searchable select
151
+ - `SmartDatePicker` - Date picker with calendar
152
+ - `SmartFileUpload` - File upload with preview
153
+ - `SmartSlider` - Single value slider
154
+ - `SmartDualRangeSlider` - Min/max range slider
155
+ - `SmartTags` - Tag input field
156
+ - `SmartAutoSuggestTags` - Tags with autocomplete
157
+ - `SmartBasicRichTextbox` - Basic rich text editor
158
+
159
+ ### Opinionated Fields
160
+
161
+ Import from `@algodomain/smart-forms/opinionated`:
162
+
163
+ Pre-configured fields with built-in validation:
164
+
165
+ - `FieldEmail` - Email field with validation
166
+ - `FieldPassword` / `FieldConfirmPassword` - Password fields
167
+ - `FieldPhone` - Phone number field
168
+ - `FieldFirstName` / `FieldLastName` / `FieldFullName` - Name fields
169
+ - `FieldAge` - Age field with validation
170
+ - `FieldStreetAddress` / `FieldCity` / `FieldZipCode` / `FieldState` - Address fields
171
+ - `FieldMessage` / `FieldComments` - Message/comment fields
172
+
173
+ ## Configuration
174
+
175
+ ### Form Props
176
+
177
+ ```tsx
178
+ <SmartForm
179
+ api="/api/endpoint" // API endpoint
180
+ method="POST" // HTTP method (POST, PUT, PATCH)
181
+ submitButtonText="Submit" // Custom button text
182
+ onSuccess={(data) => {}} // Success callback
183
+ onError={(error) => {}} // Error callback
184
+ authentication={{ enable: true }} // Add Bearer token
185
+ enableLocalStorage={true} // Enable draft saving
186
+ storageKey="my-form-draft" // LocalStorage key
187
+ initialData={{ name: "John" }} // Pre-fill data
188
+ transformData={(data) => data} // Transform before submit
189
+ />
190
+ ```
191
+
192
+ ### Field Props
193
+
194
+ All smart fields support these common props:
195
+
196
+ - `field` (required): Field name
197
+ - `label`: Display label
198
+ - `required`: Make field required
199
+ - `validation`: Zod schema for validation
200
+ - `defaultValue`: Initial value
201
+ - `placeholder`: Placeholder text
202
+ - `className`: Custom CSS class
203
+ - `info`: Info tooltip text
204
+ - `subLabel`: Additional label text
205
+
206
+ ## Theme Customization
207
+
208
+ ### Override CSS Variables
209
+
210
+ Add this to your CSS file:
211
+
212
+ ```css
213
+ :root {
214
+ --primary: oklch(0.5 0.2 250); /* Custom primary color */
215
+ --radius: 1rem; /* Border radius */
216
+ --background: oklch(1 0 0); /* Background color */
217
+ --foreground: oklch(0.145 0 0); /* Text color */
218
+ }
219
+
220
+ /* Dark mode */
221
+ .dark {
222
+ --background: oklch(0.145 0 0);
223
+ --foreground: oklch(0.985 0 0);
224
+ }
225
+ ```
226
+
227
+ ### Full Tailwind Support (Optional)
228
+
229
+ For complete Tailwind utility support, add to your `index.css`:
230
+
231
+ ```css
232
+ @source "../node_modules/@algodomain/smart-forms/dist/index.js";
233
+ @source "../node_modules/@algodomain/smart-forms/dist/index.cjs";
234
+ ```
235
+
236
+ This ensures Tailwind generates utilities used inside the library.
237
+
238
+ ## Authentication
239
+
240
+ Enable authentication to automatically include Bearer tokens:
241
+
242
+ ```tsx
243
+ <SmartForm
244
+ authentication={{
245
+ enable: true,
246
+ refreshTokenEndpoint: "/api/auth/refresh", // Optional
247
+ accessTokenKey: "accessToken", // Default
248
+ refreshTokenKey: "refreshToken" // Default
249
+ }}
250
+ />
251
+ ```
252
+
253
+ The library will:
254
+ 1. Get the access token from localStorage
255
+ 2. Include it as `Authorization: Bearer <token>`
256
+ 3. Automatically refresh if refresh endpoint is provided
257
+ 4. Retry the request with the new token
258
+
259
+ ## Validation
260
+
261
+ Use Zod schemas for validation:
262
+
263
+ ```tsx
264
+ import { z } from 'zod'
265
+
266
+ <SmartInput
267
+ field="email"
268
+ label="Email"
269
+ validation={z
270
+ .string()
271
+ .email("Invalid email")
272
+ .min(5, "Too short")
273
+ }
274
+ required
275
+ />
276
+ ```
277
+
278
+ ## TypeScript Support
279
+
280
+ Fully typed with TypeScript. Import types:
281
+
282
+ ```tsx
283
+ import type {
284
+ SmartFormProps,
285
+ FormConfig,
286
+ SmartInputProps
287
+ } from '@algodomain/smart-forms'
288
+ ```
289
+
290
+ ## Examples
291
+
292
+ Check out the examples directory for more use cases:
293
+
294
+ - Simple contact form
295
+ - Multi-step registration
296
+ - Job posting form
297
+ - User profile form
298
+ - Complex validation scenarios
299
+
300
+ ## License
301
+
302
+ MIT
303
+
304
+ ## Contributing
305
+
306
+ Contributions welcome! Please open an issue or PR on GitHub.
307
+
308
+ ## Support
309
+
310
+ For issues and questions:
311
+ - GitHub Issues: [github.com/algodomain/smart-forms](https://github.com/algodomain/smart-forms)
312
+ - Documentation: [docs.algodomain.com](https://docs.algodomain.com)
313
+
@@ -0,0 +1,94 @@
1
+ import React__default, { ReactNode } from 'react';
2
+
3
+ /**
4
+ * Authentication configuration for SmartForm
5
+ *
6
+ * @interface AuthenticationConfig
7
+ * @property {boolean} enable - Enable authentication (sends Bearer token in Authorization header)
8
+ * @property {string} [refreshTokenEndpoint] - Optional endpoint for token refresh when accessToken expires
9
+ * @property {string} [accessTokenKey] - localStorage key for access token (default: 'accessToken')
10
+ * @property {string} [refreshTokenKey] - localStorage key for refresh token (default: 'refreshToken')
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * // Basic authentication without token refresh
15
+ * authentication={{ enable: true }}
16
+ *
17
+ * // Authentication with token refresh
18
+ * authentication={{
19
+ * enable: true,
20
+ * refreshTokenEndpoint: "/api/auth/refresh"
21
+ * }}
22
+ *
23
+ * // Custom token keys
24
+ * authentication={{
25
+ * enable: true,
26
+ * refreshTokenEndpoint: "/api/auth/refresh",
27
+ * accessTokenKey: "myAccessToken",
28
+ * refreshTokenKey: "myRefreshToken"
29
+ * }}
30
+ * ```
31
+ */
32
+ interface AuthenticationConfig {
33
+ enable: boolean;
34
+ refreshTokenEndpoint?: string;
35
+ accessTokenKey?: string;
36
+ refreshTokenKey?: string;
37
+ }
38
+ interface FormConfig {
39
+ showProgressBar?: any;
40
+ api?: string;
41
+ method?: 'POST' | 'PUT' | 'PATCH';
42
+ submitButtonText?: string;
43
+ submitButtonIcon?: ReactNode;
44
+ allowSaveDraft?: boolean;
45
+ saveDraftApi?: string;
46
+ onSuccess?: (data: any) => void;
47
+ onError?: (error: any) => void;
48
+ transformData?: (data: any) => any;
49
+ className?: string;
50
+ title?: string;
51
+ subTitle?: string;
52
+ storageKey?: string;
53
+ enableLocalStorage?: boolean;
54
+ logFormData?: boolean;
55
+ showReset?: boolean;
56
+ showTabNumbers?: boolean;
57
+ authentication?: AuthenticationConfig;
58
+ }
59
+ interface FormContextType {
60
+ formData: any;
61
+ errors: any;
62
+ isLoading: boolean;
63
+ isDraftSaving: boolean;
64
+ updateField: (field: string, value: any) => void;
65
+ validateField: (field: string, value: any) => boolean;
66
+ validateFields: (fields: string[]) => boolean;
67
+ submitForm: () => Promise<void>;
68
+ validateFormAndGetResult: () => boolean;
69
+ saveDraft: () => Promise<void>;
70
+ resetForm: () => void;
71
+ fieldRefs: React__default.MutableRefObject<any>;
72
+ registerValidation: (field: string, validation: any) => void;
73
+ validationRegistry: any;
74
+ config: FormConfig;
75
+ setErrors: (errors: any) => void;
76
+ registerSubmitHook: (key: string, hook: () => Promise<void>) => void;
77
+ unregisterSubmitHook: (key: string) => void;
78
+ }
79
+ interface SmartFormProviderProps {
80
+ children: ReactNode;
81
+ config: FormConfig;
82
+ initialData?: any;
83
+ }
84
+ declare const SmartFormProvider: React__default.FC<SmartFormProviderProps>;
85
+ declare const useSmartForm: () => FormContextType;
86
+ declare const useFormField: (field: string) => {
87
+ value: any;
88
+ error: any;
89
+ onChange: (value: any) => void;
90
+ fieldRef: (el: any) => any;
91
+ registerValidation: (field: string, validation: any) => void;
92
+ };
93
+
94
+ export { type AuthenticationConfig as A, type FormContextType as F, SmartFormProvider as S, useFormField as a, type FormConfig as b, useSmartForm as u };
@@ -0,0 +1,94 @@
1
+ import React__default, { ReactNode } from 'react';
2
+
3
+ /**
4
+ * Authentication configuration for SmartForm
5
+ *
6
+ * @interface AuthenticationConfig
7
+ * @property {boolean} enable - Enable authentication (sends Bearer token in Authorization header)
8
+ * @property {string} [refreshTokenEndpoint] - Optional endpoint for token refresh when accessToken expires
9
+ * @property {string} [accessTokenKey] - localStorage key for access token (default: 'accessToken')
10
+ * @property {string} [refreshTokenKey] - localStorage key for refresh token (default: 'refreshToken')
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * // Basic authentication without token refresh
15
+ * authentication={{ enable: true }}
16
+ *
17
+ * // Authentication with token refresh
18
+ * authentication={{
19
+ * enable: true,
20
+ * refreshTokenEndpoint: "/api/auth/refresh"
21
+ * }}
22
+ *
23
+ * // Custom token keys
24
+ * authentication={{
25
+ * enable: true,
26
+ * refreshTokenEndpoint: "/api/auth/refresh",
27
+ * accessTokenKey: "myAccessToken",
28
+ * refreshTokenKey: "myRefreshToken"
29
+ * }}
30
+ * ```
31
+ */
32
+ interface AuthenticationConfig {
33
+ enable: boolean;
34
+ refreshTokenEndpoint?: string;
35
+ accessTokenKey?: string;
36
+ refreshTokenKey?: string;
37
+ }
38
+ interface FormConfig {
39
+ showProgressBar?: any;
40
+ api?: string;
41
+ method?: 'POST' | 'PUT' | 'PATCH';
42
+ submitButtonText?: string;
43
+ submitButtonIcon?: ReactNode;
44
+ allowSaveDraft?: boolean;
45
+ saveDraftApi?: string;
46
+ onSuccess?: (data: any) => void;
47
+ onError?: (error: any) => void;
48
+ transformData?: (data: any) => any;
49
+ className?: string;
50
+ title?: string;
51
+ subTitle?: string;
52
+ storageKey?: string;
53
+ enableLocalStorage?: boolean;
54
+ logFormData?: boolean;
55
+ showReset?: boolean;
56
+ showTabNumbers?: boolean;
57
+ authentication?: AuthenticationConfig;
58
+ }
59
+ interface FormContextType {
60
+ formData: any;
61
+ errors: any;
62
+ isLoading: boolean;
63
+ isDraftSaving: boolean;
64
+ updateField: (field: string, value: any) => void;
65
+ validateField: (field: string, value: any) => boolean;
66
+ validateFields: (fields: string[]) => boolean;
67
+ submitForm: () => Promise<void>;
68
+ validateFormAndGetResult: () => boolean;
69
+ saveDraft: () => Promise<void>;
70
+ resetForm: () => void;
71
+ fieldRefs: React__default.MutableRefObject<any>;
72
+ registerValidation: (field: string, validation: any) => void;
73
+ validationRegistry: any;
74
+ config: FormConfig;
75
+ setErrors: (errors: any) => void;
76
+ registerSubmitHook: (key: string, hook: () => Promise<void>) => void;
77
+ unregisterSubmitHook: (key: string) => void;
78
+ }
79
+ interface SmartFormProviderProps {
80
+ children: ReactNode;
81
+ config: FormConfig;
82
+ initialData?: any;
83
+ }
84
+ declare const SmartFormProvider: React__default.FC<SmartFormProviderProps>;
85
+ declare const useSmartForm: () => FormContextType;
86
+ declare const useFormField: (field: string) => {
87
+ value: any;
88
+ error: any;
89
+ onChange: (value: any) => void;
90
+ fieldRef: (el: any) => any;
91
+ registerValidation: (field: string, validation: any) => void;
92
+ };
93
+
94
+ export { type AuthenticationConfig as A, type FormContextType as F, SmartFormProvider as S, useFormField as a, type FormConfig as b, useSmartForm as u };
@@ -0,0 +1,111 @@
1
+ import React__default from 'react';
2
+
3
+ interface SmartInputProps {
4
+ field: string;
5
+ label?: string;
6
+ type?: 'text' | 'email' | 'password' | 'tel' | 'number' | 'textarea';
7
+ placeholder?: string;
8
+ validation?: any;
9
+ className?: string;
10
+ required?: boolean;
11
+ defaultValue?: any;
12
+ info?: string;
13
+ subLabel?: string;
14
+ }
15
+ declare const SmartInput: React__default.FC<SmartInputProps>;
16
+
17
+ interface SmartCheckboxProps {
18
+ field: string;
19
+ label?: string;
20
+ className?: string;
21
+ validation?: any;
22
+ required?: boolean;
23
+ defaultValue?: boolean;
24
+ info?: string;
25
+ subLabel?: string;
26
+ }
27
+ declare const SmartCheckbox: React__default.FC<SmartCheckboxProps>;
28
+
29
+ interface SmartRadioGroupOption {
30
+ value: string;
31
+ label: string;
32
+ }
33
+ interface SmartRadioGroupProps {
34
+ field: string;
35
+ label?: string;
36
+ options: SmartRadioGroupOption[];
37
+ name?: string;
38
+ alignment?: 'vertical' | 'horizontal';
39
+ className?: string;
40
+ validation?: any;
41
+ required?: boolean;
42
+ defaultValue?: string;
43
+ info?: string;
44
+ subLabel?: string;
45
+ }
46
+ declare const SmartRadioGroup: React__default.FC<SmartRadioGroupProps>;
47
+
48
+ interface SmartSelectOption {
49
+ value: string;
50
+ label: string;
51
+ }
52
+ interface SmartSelectProps {
53
+ field: string;
54
+ label?: string;
55
+ options: SmartSelectOption[];
56
+ className?: string;
57
+ placeholder?: string;
58
+ validation?: any;
59
+ required?: boolean;
60
+ defaultValue?: string;
61
+ info?: string;
62
+ subLabel?: string;
63
+ }
64
+ declare const SmartSelect: React__default.FC<SmartSelectProps>;
65
+
66
+ interface SmartDatePickerProps {
67
+ field: string;
68
+ label?: string;
69
+ className?: string;
70
+ placeholder?: string;
71
+ validation?: any;
72
+ required?: boolean;
73
+ allowPast?: boolean;
74
+ allowFuture?: boolean;
75
+ /**
76
+ * When true, value will be stored/returned as ISO string (yyyy-MM-dd).
77
+ * Otherwise the underlying form value will be a Date instance.
78
+ */
79
+ valueAsString?: boolean;
80
+ /** Optional minimum selectable date */
81
+ minDate?: Date;
82
+ /** Optional maximum selectable date */
83
+ maxDate?: Date;
84
+ /** Default value for the date picker (can be Date or string depending on valueAsString) */
85
+ defaultValue?: Date | string;
86
+ info?: string;
87
+ subLabel?: string;
88
+ }
89
+ declare const SmartDatePicker: React__default.FC<SmartDatePickerProps>;
90
+
91
+ interface SmartTagsProps {
92
+ field: string;
93
+ label?: string;
94
+ className?: string;
95
+ placeholder?: string;
96
+ validation?: any;
97
+ required?: boolean;
98
+ maxTags?: number;
99
+ defaultValue?: string[];
100
+ maxLength?: number;
101
+ minLength?: number;
102
+ allowDuplicates?: boolean;
103
+ disabled?: boolean;
104
+ onTagAdd?: (tagText: string) => void;
105
+ onTagRemove?: (tagText: string) => void;
106
+ info?: string;
107
+ subLabel?: string;
108
+ }
109
+ declare const SmartTags: React__default.FC<SmartTagsProps>;
110
+
111
+ export { SmartInput as S, SmartCheckbox as a, SmartRadioGroup as b, SmartSelect as c, SmartDatePicker as d, SmartTags as e, type SmartInputProps as f, type SmartTagsProps as g };