@page-speed/forms 0.1.0 → 0.1.1

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.
Files changed (2) hide show
  1. package/README.md +51 -426
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,469 +1,94 @@
1
- # @page-speed/forms
1
+ # OpenSite Page Speed Forms
2
2
 
3
- Ultra-high-performance React form library with field-level reactivity and tree-shakable architecture.
3
+ Type-safe form state management and validation for React applications.
4
4
 
5
- ## Features
5
+ ## Overview
6
6
 
7
- - =� **Field-Level Reactivity**: Only re-render the specific field that changed (~1 re-render per change vs ~10 for traditional hooks)
8
- - =� **Tree-Shakable**: Import only what you need - Core module starts at 13 KB gzipped
9
- - � **Built on @legendapp/state**: Observable-based state management for optimal performance
10
- -  **Valibot Integration**: Lightweight validation (95% smaller than Zod)
11
- - <� **TypeScript-First**: Full type safety with comprehensive type definitions
12
- -  **Accessible**: ARIA attributes and semantic HTML out of the box
13
- - = **Progressive Enhancement**: Forms work without JavaScript
14
- - <� **Unstyled**: Bring your own styles - no CSS to override
7
+ OpenSite Page Speed Forms is a high-performance library designed to streamline form state management, validation, and submission handling in React applications. This library is part of OpenSite AI's open-source ecosystem, built for performance and open collaboration. By emphasizing type safety and modularity, it aligns with OpenSite's goal to create scalable, open, and developer-friendly performance tooling.
15
8
 
16
- ## Installation
9
+ Learn more at [opensite.ai](https://opensite.ai).
17
10
 
18
- ```bash
19
- # Using pnpm (recommended)
20
- pnpm add @page-speed/forms
11
+ ## Key Features
21
12
 
22
- # Optional: Add validation library
23
- pnpm add valibot
13
+ - Type-safe form state management with TypeScript.
14
+ - Flexible validation schemas supporting both synchronous and asynchronous validation.
15
+ - Modular useForm and useField hooks for complete form and field control.
16
+ - Built-in support for form submission and error handling.
17
+ - Configurable validation modes: `onChange`, `onBlur`, and `onSubmit`.
24
18
 
25
- # Optional: Add state management (peer dependency)
26
- pnpm add @legendapp/state
27
- ```
19
+ ## Installation
28
20
 
29
- ## Bundle Sizes
21
+ To install OpenSite Page Speed Forms, ensure you have Node.js and npm installed, then run:
30
22
 
31
- All sizes shown are **minified + gzipped** with dependencies:
23
+ ```
24
+ npm install @page-speed/forms
25
+ ```
32
26
 
33
- - **Core** (useForm, Form, Field, useField): 13.11 KB
34
- - **TextInput**: 502 B
35
- - **Valibot Adapter**: 392 B
36
- - **Full Bundle**: 13.25 KB
27
+ Dependencies:
28
+ - React
37
29
 
38
30
  ## Quick Start
39
31
 
40
- ### Basic Form
32
+ Here is a basic example to get started with OpenSite Page Speed Forms in your React application:
41
33
 
42
- ```tsx
43
- import { useForm, Form, Field } from '@page-speed/forms';
44
- import { TextInput } from '@page-speed/forms/inputs';
34
+ ```typescript
35
+ import React from 'react';
36
+ import { useForm, Form } from '@page-speed/forms';
45
37
 
46
- function LoginForm() {
38
+ function MyForm() {
47
39
  const form = useForm({
48
- initialValues: {
49
- email: '',
50
- password: '',
51
- },
52
- validationSchema: {
53
- email: (value) => !value ? 'Required' : undefined,
54
- password: (value) => value.length < 8 ? 'Too short' : undefined,
55
- },
56
- onSubmit: async (values) => {
57
- await login(values);
58
- },
40
+ initialValues: { email: '' },
41
+ onSubmit: (values) => {
42
+ console.log('Form Submitted:', values);
43
+ }
59
44
  });
60
45
 
61
46
  return (
62
47
  <Form form={form}>
63
- <Field name="email" label="Email">
64
- {({ field, meta }) => (
65
- <>
66
- <TextInput {...field} type="email" error={!!meta.error} />
67
- {meta.error && <span>{meta.error}</span>}
68
- </>
69
- )}
70
- </Field>
71
-
72
- <Field name="password" label="Password">
73
- {({ field, meta }) => (
74
- <>
75
- <TextInput {...field} type="password" error={!!meta.error} />
76
- {meta.error && <span>{meta.error}</span>}
77
- </>
78
- )}
79
- </Field>
80
-
81
- <button type="submit" disabled={form.isSubmitting}>
82
- Submit
83
- </button>
48
+ <input
49
+ name="email"
50
+ value={form.values.email}
51
+ onChange={(e) => form.setFieldValue('email', e.target.value)}
52
+ onBlur={() => form.setFieldTouched('email', true)}
53
+ />
54
+ <button type="submit">Submit</button>
84
55
  </Form>
85
56
  );
86
57
  }
87
58
  ```
88
59
 
89
- ### With Valibot Validation
90
-
91
- ```tsx
92
- import { useForm } from '@page-speed/forms';
93
- import { createValibotSchema } from '@page-speed/forms/validation/valibot';
94
- import * as v from 'valibot';
95
-
96
- const LoginSchema = v.object({
97
- email: v.pipe(v.string(), v.email('Invalid email')),
98
- password: v.pipe(v.string(), v.minLength(8, 'Too short')),
99
- });
100
-
101
- function LoginForm() {
102
- const form = useForm({
103
- initialValues: { email: '', password: '' },
104
- validationSchema: createValibotSchema(LoginSchema),
105
- onSubmit: async (values) => {
106
- await login(values);
107
- },
108
- });
109
-
110
- // ... rest of form
111
- }
112
- ```
113
-
114
- ## API Reference
115
-
116
- ### `useForm(options)`
117
-
118
- Main hook for creating form state.
119
-
120
- **Options:**
121
-
122
- - `initialValues` (required): Initial form values
123
- - `validationSchema`: Schema mapping field names to validators
124
- - `validateOn`: When to validate - `"onBlur"` (default) | `"onChange"` | `"onSubmit"`
125
- - `revalidateOn`: When to revalidate after first validation - `"onChange"` (default) | `"onBlur"`
126
- - `onSubmit` (required): Submit handler function
127
- - `onError`: Error handler for validation failures
128
- - `debug`: Enable debug logging
60
+ ## Configuration or Advanced Usage
129
61
 
130
- **Returns:**
62
+ OpenSite Page Speed Forms can be customized with various options:
131
63
 
132
64
  ```typescript
133
- {
134
- // State
135
- values: T;
136
- errors: FormErrors<T>;
137
- touched: TouchedFields<T>;
138
- isSubmitting: boolean;
139
- isValid: boolean;
140
- isDirty: boolean;
141
- status: 'idle' | 'submitting' | 'success' | 'error';
142
-
143
- // Actions
144
- handleSubmit: (e?: React.FormEvent) => Promise<void>;
145
- setFieldValue: (field: keyof T, value: T[field]) => void;
146
- setFieldError: (field: keyof T, error: string) => void;
147
- setFieldTouched: (field: keyof T, touched: boolean) => void;
148
- validateForm: () => Promise<FormErrors<T>>;
149
- validateField: (field: keyof T) => Promise<string | undefined>;
150
- resetForm: () => void;
151
- getFieldProps: (field: keyof T) => FieldInputProps;
152
- getFieldMeta: (field: keyof T) => FieldMeta;
153
- }
154
- ```
155
-
156
- ### `<Form>`
157
-
158
- Progressive enhancement wrapper component.
159
-
160
- ```tsx
161
- <Form
162
- form={form}
163
- action="/api/endpoint" // Fallback for no-JS
164
- method="post" // Fallback for no-JS
165
- className="my-form"
166
- >
167
- {/* fields */}
168
- </Form>
169
- ```
170
-
171
- ### `<Field>`
172
-
173
- Field wrapper with label, description, and error display.
174
-
175
- ```tsx
176
- <Field
177
- name="email"
178
- label="Email Address"
179
- description="We'll never share your email"
180
- validate={(value) => !value ? 'Required' : undefined}
181
- >
182
- {({ field, meta, helpers }) => (
183
- <TextInput {...field} error={!!meta.error} />
184
- )}
185
- </Field>
186
- ```
187
-
188
- ### `useField(options)`
189
-
190
- Field-level hook for accessing field state.
191
-
192
- ```tsx
193
- const { field, meta, helpers } = useField({
194
- name: 'email',
195
- validate: (value) => !value ? 'Required' : undefined,
196
- transform: (value) => value.toLowerCase(),
197
- });
198
- ```
199
-
200
- ### `<TextInput>`
201
-
202
- Lightweight, accessible text input component.
203
-
204
- ```tsx
205
- <TextInput
206
- name="email"
207
- value={value}
208
- onChange={onChange}
209
- onBlur={onBlur}
210
- type="email"
211
- placeholder="you@example.com"
212
- error={hasError}
213
- disabled={false}
214
- required={true}
215
- />
216
- ```
217
-
218
- ## Validation
219
-
220
- ### Inline Validators
221
-
222
- ```tsx
223
65
  const form = useForm({
224
66
  initialValues: { email: '' },
225
67
  validationSchema: {
226
- email: (value) => {
227
- if (!value) return 'Required';
228
- if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
229
- return 'Invalid email';
230
- }
231
- return undefined;
232
- },
233
- },
234
- onSubmit: async (values) => { /* ... */ },
235
- });
236
- ```
237
-
238
- ### Async Validation
239
-
240
- ```tsx
241
- const form = useForm({
242
- initialValues: { username: '' },
243
- validationSchema: {
244
- username: async (value) => {
245
- const exists = await checkUsernameExists(value);
246
- return exists ? 'Username taken' : undefined;
247
- },
248
- },
249
- onSubmit: async (values) => { /* ... */ },
250
- });
251
- ```
252
-
253
- ### Multiple Validators per Field
254
-
255
- ```tsx
256
- const form = useForm({
257
- initialValues: { password: '' },
258
- validationSchema: {
259
- password: [
260
- (value) => !value ? 'Required' : undefined,
261
- (value) => value.length < 8 ? 'Too short' : undefined,
262
- (value) => !/[A-Z]/.test(value) ? 'Needs uppercase' : undefined,
263
- ],
68
+ email: (value) => value.includes('@') ? undefined : 'Invalid email'
264
69
  },
265
- onSubmit: async (values) => { /* ... */ },
70
+ validateOn: 'onBlur',
71
+ revalidateOn: 'onChange',
72
+ onSubmit: (values) => console.log(values),
73
+ onError: (errors) => console.error(errors),
74
+ debug: true
266
75
  });
267
76
  ```
268
77
 
269
- ### Valibot Integration
78
+ ## Performance Notes
270
79
 
271
- ```tsx
272
- import { createValibotSchema } from '@page-speed/forms/validation/valibot';
273
- import * as v from 'valibot';
80
+ Performance is a core facet of everything we build at OpenSite AI. The library is optimized for minimal re-renders and efficient form state updates, ensuring your applications remain responsive and fast.
274
81
 
275
- const schema = v.object({
276
- email: v.pipe(
277
- v.string(),
278
- v.email('Invalid email'),
279
- v.endsWith('@company.com', 'Must be company email')
280
- ),
281
- age: v.pipe(
282
- v.number(),
283
- v.minValue(18, 'Must be 18+')
284
- ),
285
- });
286
-
287
- const form = useForm({
288
- initialValues: { email: '', age: 0 },
289
- validationSchema: createValibotSchema(schema),
290
- onSubmit: async (values) => { /* ... */ },
291
- });
292
- ```
293
-
294
- ## Advanced Usage
295
-
296
- ### Conditional Validation
297
-
298
- ```tsx
299
- const form = useForm({
300
- initialValues: {
301
- contactMethod: 'email',
302
- email: '',
303
- phone: '',
304
- },
305
- validationSchema: {
306
- email: (value, allValues) => {
307
- if (allValues.contactMethod === 'email' && !value) {
308
- return 'Email required when email is selected';
309
- }
310
- return undefined;
311
- },
312
- phone: (value, allValues) => {
313
- if (allValues.contactMethod === 'phone' && !value) {
314
- return 'Phone required when phone is selected';
315
- }
316
- return undefined;
317
- },
318
- },
319
- onSubmit: async (values) => { /* ... */ },
320
- });
321
- ```
322
-
323
- ### Dynamic Forms
324
-
325
- ```tsx
326
- function DynamicForm() {
327
- const form = useForm({
328
- initialValues: {
329
- contacts: [{ name: '', email: '' }],
330
- },
331
- onSubmit: async (values) => { /* ... */ },
332
- });
333
-
334
- return (
335
- <Form form={form}>
336
- {form.values.contacts.map((contact, index) => (
337
- <div key={index}>
338
- <Field name={`contacts.${index}.name`}>
339
- {({ field }) => <TextInput {...field} />}
340
- </Field>
341
- <Field name={`contacts.${index}.email`}>
342
- {({ field }) => <TextInput {...field} type="email" />}
343
- </Field>
344
- </div>
345
- ))}
346
- <button
347
- type="button"
348
- onClick={() => {
349
- form.setFieldValue('contacts', [
350
- ...form.values.contacts,
351
- { name: '', email: '' },
352
- ]);
353
- }}
354
- >
355
- Add Contact
356
- </button>
357
- </Form>
358
- );
359
- }
360
- ```
361
-
362
- ### Form Helpers in onSubmit
363
-
364
- ```tsx
365
- const form = useForm({
366
- initialValues: { email: '' },
367
- onSubmit: async (values, helpers) => {
368
- try {
369
- await api.submit(values);
370
- helpers.resetForm();
371
- } catch (error) {
372
- if (error.code === 'EMAIL_EXISTS') {
373
- helpers.setFieldError('email', 'Email already exists');
374
- } else {
375
- helpers.setErrors({ email: 'Unexpected error' });
376
- }
377
- }
378
- },
379
- });
380
- ```
381
-
382
- ## Tree-Shaking
383
-
384
- The library is designed for optimal tree-shaking. Import only what you need:
385
-
386
- ```tsx
387
- // Import core functionality (13.11 KB)
388
- import { useForm, Form, Field } from '@page-speed/forms/core';
389
-
390
- // Import input components separately (502 B)
391
- import { TextInput } from '@page-speed/forms/inputs';
392
-
393
- // Import validation adapters separately (392 B)
394
- import { createValibotSchema } from '@page-speed/forms/validation/valibot';
395
-
396
- // Or import from main entry point
397
- import { useForm } from '@page-speed/forms';
398
- ```
399
-
400
- ## Performance
401
-
402
- The library uses @legendapp/state for optimal performance:
403
-
404
- - **~1 re-render per change** vs ~10 for traditional hooks
405
- - **Observable-based state**: Fine-grained reactivity at the field level
406
- - **No unnecessary re-renders**: Parent form doesn't re-render when child field changes
407
- - **Efficient validation**: Debounced and memoized by default
408
-
409
- ## Progressive Enhancement
410
-
411
- Forms work without JavaScript by using native HTML form submission:
412
-
413
- ```tsx
414
- <Form
415
- form={form}
416
- action="/api/endpoint" // Used when JS disabled
417
- method="post"
418
- >
419
- {/* fields */}
420
- </Form>
421
- ```
422
-
423
- When JavaScript is available, `onSubmit` handles the submission. When JavaScript is disabled, the native HTML form submission takes over.
424
-
425
- ## Browser Support
426
-
427
- - Modern browsers (Chrome, Firefox, Safari, Edge)
428
- - Requires ES2020 support
429
- - No IE11 support
430
-
431
- ## TypeScript
432
-
433
- Fully typed with comprehensive type definitions:
434
-
435
- ```tsx
436
- import type {
437
- FormValues,
438
- FormErrors,
439
- TouchedFields,
440
- ValidationSchema,
441
- FieldValidator,
442
- UseFormOptions,
443
- UseFormReturn,
444
- } from '@page-speed/forms/core';
445
- ```
446
-
447
- ## Examples
82
+ ## Contributing
448
83
 
449
- See the [`examples/`](./examples) directory for more complete examples including:
450
- - Basic forms with inline validation
451
- - Valibot schema integration
452
- - Dynamic forms with conditional fields
453
- - Progressive enhancement
454
- - Async validation
84
+ We welcome contributions from the community to enhance OpenSite Page Speed Forms. Please refer to our [GitHub repository](https://github.com/opensite-ai) for guidelines and more information on how to get involved.
455
85
 
456
86
  ## License
457
87
 
458
- MIT
459
-
460
- ## Contributing
461
-
462
- Contributions welcome! Please read our contributing guidelines first.
88
+ Licensed under the BSD 3-Clause License. See the [LICENSE](./LICENSE) file for details.
463
89
 
464
- ## Credits
90
+ ## Related Projects
465
91
 
466
- Built with:
467
- - [@legendapp/state](https://legendapp.com/open-source/state/) - Observable state management
468
- - [Valibot](https://valibot.dev/) - Lightweight validation library
469
- - [tsup](https://tsup.egoist.dev/) - TypeScript bundler
92
+ - [Domain Extractor](https://github.com/opensite-ai/domain_extractor)
93
+ - [Page Speed Hooks](https://github.com/opensite-ai/page-speed-hooks)
94
+ - Visit [opensite.ai](https://opensite.ai) for more tools and information.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@page-speed/forms",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Ultra-high-performance React form library with field-level reactivity and tree-shakable architecture",
5
5
  "keywords": [
6
6
  "react",