@object-ui/react 3.1.5 → 3.3.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 (109) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +28 -3
  3. package/dist/SchemaRenderer.js +2 -2
  4. package/dist/components/form/FieldFactory.js +5 -2
  5. package/dist/context/AppShellContext.d.ts +26 -0
  6. package/dist/context/AppShellContext.js +67 -0
  7. package/dist/context/index.d.ts +1 -7
  8. package/dist/context/index.js +1 -7
  9. package/dist/hooks/index.d.ts +1 -0
  10. package/dist/hooks/index.js +1 -0
  11. package/dist/hooks/useDataRefresh.d.ts +36 -0
  12. package/dist/hooks/useDataRefresh.js +50 -0
  13. package/dist/hooks/useDiscovery.d.ts +12 -0
  14. package/dist/hooks/useDiscovery.js +6 -0
  15. package/dist/hooks/usePerformanceBudget.js +1 -1
  16. package/package.json +32 -9
  17. package/.turbo/turbo-build.log +0 -4
  18. package/src/LazyPluginLoader.tsx +0 -174
  19. package/src/SchemaRenderer.tsx +0 -266
  20. package/src/__tests__/LazyPluginLoader.test.tsx +0 -176
  21. package/src/__tests__/SchemaRenderer.aria.test.tsx +0 -118
  22. package/src/__tests__/SchemaRenderer.debug.test.tsx +0 -69
  23. package/src/__tests__/SchemaRenderer.errorBoundary.test.tsx +0 -114
  24. package/src/__tests__/SchemaRenderer.expressions.test.tsx +0 -131
  25. package/src/__tests__/SchemaRendererProvider.smoke.test.tsx +0 -132
  26. package/src/__tests__/ThemeProvider.test.tsx +0 -451
  27. package/src/__tests__/useNavigationOverlay.test.ts +0 -578
  28. package/src/__tests__/useOffline.test.ts +0 -198
  29. package/src/__tests__/usePageTransition.test.ts +0 -214
  30. package/src/__tests__/usePageVariables.test.tsx +0 -334
  31. package/src/__tests__/usePerformance.test.ts +0 -137
  32. package/src/__tests__/useViewData.test.tsx +0 -422
  33. package/src/__tests__/view-switching.test.tsx +0 -456
  34. package/src/components/form/FieldFactory.tsx +0 -509
  35. package/src/components/form/FormRenderer.test.tsx +0 -744
  36. package/src/components/form/FormRenderer.tsx +0 -258
  37. package/src/components/form/README.md +0 -352
  38. package/src/components/form/index.ts +0 -12
  39. package/src/context/ActionContext.tsx +0 -213
  40. package/src/context/DndContext.tsx +0 -260
  41. package/src/context/NotificationContext.tsx +0 -280
  42. package/src/context/SchemaRendererContext.tsx +0 -48
  43. package/src/context/ThemeContext.tsx +0 -325
  44. package/src/context/__tests__/ActionContext.test.tsx +0 -174
  45. package/src/context/__tests__/DndContext.test.tsx +0 -150
  46. package/src/context/__tests__/NotificationContext.test.tsx +0 -176
  47. package/src/context/__tests__/useDataScope.test.tsx +0 -91
  48. package/src/context/index.ts +0 -13
  49. package/src/hooks/__tests__/useActionEngine.test.ts +0 -170
  50. package/src/hooks/__tests__/useActionRunner.test.ts +0 -153
  51. package/src/hooks/__tests__/useAnimation.test.ts +0 -82
  52. package/src/hooks/__tests__/useColumnSummary.test.ts +0 -93
  53. package/src/hooks/__tests__/useCrudShortcuts.test.ts +0 -85
  54. package/src/hooks/__tests__/useDebugMode.test.ts +0 -83
  55. package/src/hooks/__tests__/useDensityMode.test.ts +0 -81
  56. package/src/hooks/__tests__/useDiscovery.test.tsx +0 -149
  57. package/src/hooks/__tests__/useDynamicApp.test.ts +0 -161
  58. package/src/hooks/__tests__/useETagCache.test.ts +0 -153
  59. package/src/hooks/__tests__/useExpression.test.ts +0 -86
  60. package/src/hooks/__tests__/useFocusTrap.test.ts +0 -294
  61. package/src/hooks/__tests__/useKeyboardShortcuts.test.ts +0 -144
  62. package/src/hooks/__tests__/usePageTransition.test.ts +0 -158
  63. package/src/hooks/__tests__/usePerformanceBudget.test.ts +0 -157
  64. package/src/hooks/__tests__/useReducedMotion.test.ts +0 -104
  65. package/src/hooks/__tests__/useSchemaPersistence.test.ts +0 -220
  66. package/src/hooks/__tests__/useViewSharing.test.ts +0 -121
  67. package/src/hooks/__tests__/useViewTransition.test.ts +0 -61
  68. package/src/hooks/index.ts +0 -35
  69. package/src/hooks/useActionEngine.ts +0 -84
  70. package/src/hooks/useActionRunner.ts +0 -119
  71. package/src/hooks/useAnimation.ts +0 -117
  72. package/src/hooks/useClientNotifications.ts +0 -251
  73. package/src/hooks/useColumnSummary.ts +0 -87
  74. package/src/hooks/useCrudShortcuts.ts +0 -126
  75. package/src/hooks/useDebugMode.ts +0 -95
  76. package/src/hooks/useDensityMode.ts +0 -102
  77. package/src/hooks/useDiscovery.ts +0 -154
  78. package/src/hooks/useDynamicApp.ts +0 -142
  79. package/src/hooks/useETagCache.ts +0 -404
  80. package/src/hooks/useExpression.ts +0 -56
  81. package/src/hooks/useFocusManagement.ts +0 -248
  82. package/src/hooks/useFocusTrap.ts +0 -138
  83. package/src/hooks/useGlobalUndo.ts +0 -98
  84. package/src/hooks/useKeyboardShortcuts.ts +0 -119
  85. package/src/hooks/useNavigationOverlay.ts +0 -190
  86. package/src/hooks/useOffline.ts +0 -301
  87. package/src/hooks/usePageTransition.ts +0 -187
  88. package/src/hooks/usePageVariables.tsx +0 -157
  89. package/src/hooks/usePerformance.ts +0 -246
  90. package/src/hooks/usePerformanceBudget.ts +0 -313
  91. package/src/hooks/useReducedMotion.ts +0 -53
  92. package/src/hooks/useSchemaPersistence.ts +0 -222
  93. package/src/hooks/useViewData.ts +0 -201
  94. package/src/hooks/useViewSharing.ts +0 -140
  95. package/src/hooks/useViewTransition.ts +0 -144
  96. package/src/index.ts +0 -41
  97. package/src/spec-bridge/SpecBridge.ts +0 -64
  98. package/src/spec-bridge/__tests__/P1SpecBridge.test.ts +0 -855
  99. package/src/spec-bridge/__tests__/SpecBridge.test.ts +0 -550
  100. package/src/spec-bridge/bridges/dashboard.ts +0 -180
  101. package/src/spec-bridge/bridges/form-view.ts +0 -109
  102. package/src/spec-bridge/bridges/list-view.ts +0 -187
  103. package/src/spec-bridge/bridges/page.ts +0 -136
  104. package/src/spec-bridge/index.ts +0 -14
  105. package/src/spec-bridge/types.ts +0 -38
  106. package/src/utils/i18n.ts +0 -10
  107. package/tsconfig.json +0 -17
  108. package/tsconfig.tsbuildinfo +0 -1
  109. package/vitest.config.ts +0 -2
@@ -1,258 +0,0 @@
1
- /**
2
- * ObjectUI
3
- * Copyright (c) 2024-present ObjectStack Inc.
4
- *
5
- * This source code is licensed under the MIT license found in the
6
- * LICENSE file in the root directory of this source tree.
7
- */
8
-
9
- import React from 'react';
10
- import { useForm, FormProvider, UseFormReturn } from 'react-hook-form';
11
- import type { FormView, FormSection } from '@objectstack/spec/ui';
12
- import { FieldFactory } from './FieldFactory';
13
- import { ExpressionEvaluator } from '@object-ui/core';
14
- import { resolveI18nLabel } from '../../utils/i18n';
15
-
16
- export interface FormRendererProps {
17
- /**
18
- * The FormView schema from @objectstack/spec
19
- */
20
- schema: FormView;
21
- /**
22
- * Initial form data
23
- */
24
- data?: Record<string, any>;
25
- /**
26
- * Form submission handler
27
- */
28
- onSubmit?: (data: Record<string, any>) => void | Promise<void>;
29
- /**
30
- * Form change handler
31
- */
32
- onChange?: (data: Record<string, any>) => void;
33
- /**
34
- * Custom class name for the form
35
- */
36
- className?: string;
37
- /**
38
- * Whether the form is disabled
39
- */
40
- disabled?: boolean;
41
- }
42
-
43
- /**
44
- * FormRenderer component that renders forms based on FormViewSchema
45
- * from @objectstack/spec
46
- */
47
- export const FormRenderer: React.FC<FormRendererProps> = ({
48
- schema,
49
- data = {},
50
- onSubmit,
51
- onChange,
52
- className = '',
53
- disabled = false,
54
- }) => {
55
- // Create form methods with react-hook-form
56
- const methods = useForm({
57
- defaultValues: data,
58
- mode: 'onChange',
59
- });
60
-
61
- const { handleSubmit, watch } = methods;
62
-
63
- // Watch for form changes
64
- React.useEffect(() => {
65
- if (onChange) {
66
- const subscription = watch((value) => {
67
- onChange(value as Record<string, any>);
68
- });
69
- return () => subscription.unsubscribe();
70
- }
71
- }, [watch, onChange]);
72
-
73
- // Handle form submission
74
- const onSubmitForm = handleSubmit(async (formData) => {
75
- if (onSubmit) {
76
- await onSubmit(formData);
77
- }
78
- });
79
-
80
- // Render sections or fields
81
- const renderContent = () => {
82
- if (!schema.sections || schema.sections.length === 0) {
83
- return null;
84
- }
85
-
86
- return (
87
- <div className="space-y-6">
88
- {schema.sections.map((section, index) => (
89
- <FormSectionRenderer
90
- key={index}
91
- section={section}
92
- methods={methods}
93
- disabled={disabled}
94
- />
95
- ))}
96
- </div>
97
- );
98
- };
99
-
100
- return (
101
- <FormProvider {...methods}>
102
- <form onSubmit={onSubmitForm} className={`space-y-6 ${className}`}>
103
- {renderContent()}
104
-
105
- {/* Submit button - optional, can be customized */}
106
- <div className="flex justify-end gap-2">
107
- <button
108
- type="submit"
109
- disabled={disabled}
110
- className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed"
111
- >
112
- Submit
113
- </button>
114
- </div>
115
- </form>
116
- </FormProvider>
117
- );
118
- };
119
-
120
- interface FormSectionRendererProps {
121
- section: FormSection;
122
- methods: UseFormReturn<any>;
123
- disabled?: boolean;
124
- }
125
-
126
- // Grid column classes for different column counts
127
- const GRID_COLS = {
128
- 1: 'grid-cols-1',
129
- 2: 'grid-cols-1 md:grid-cols-2',
130
- 3: 'grid-cols-1 md:grid-cols-3',
131
- 4: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-4',
132
- } as const;
133
-
134
- // Column span classes
135
- const COL_SPAN = {
136
- 1: 'col-span-1',
137
- 2: 'col-span-2',
138
- 3: 'col-span-3',
139
- 4: 'col-span-4',
140
- } as const;
141
-
142
- /**
143
- * Evaluate whether a field should be visible based on visibleOn expression
144
- * and dependsOn parent field value.
145
- */
146
- function evaluateFieldVisibility(
147
- fieldConfig: any,
148
- formValues: Record<string, any>,
149
- ): boolean {
150
- // If explicitly hidden, skip
151
- if (fieldConfig.hidden) {
152
- return false;
153
- }
154
-
155
- // Evaluate visibleOn expression
156
- if (fieldConfig.visibleOn) {
157
- try {
158
- const evaluator = new ExpressionEvaluator({ data: formValues, form: formValues });
159
- return evaluator.evaluateCondition(fieldConfig.visibleOn);
160
- } catch {
161
- // On error, default to visible
162
- return true;
163
- }
164
- }
165
-
166
- // Evaluate dependsOn: field is hidden if parent field has no value
167
- if (fieldConfig.dependsOn) {
168
- const parentValue = formValues[fieldConfig.dependsOn];
169
- return parentValue !== undefined && parentValue !== null && parentValue !== '';
170
- }
171
-
172
- return true;
173
- }
174
-
175
- /**
176
- * Renders a form section with grid layout
177
- */
178
- const FormSectionRenderer: React.FC<FormSectionRendererProps> = ({
179
- section,
180
- methods,
181
- disabled = false,
182
- }) => {
183
- const [isCollapsed, setIsCollapsed] = React.useState(section.collapsed || false);
184
-
185
- // Determine grid columns based on section.columns
186
- const gridCols = GRID_COLS[section.columns || 1];
187
-
188
- // Collect whether there are any conditional fields
189
- const hasConditionalFields = React.useMemo(() => {
190
- return section.fields.some((field) => {
191
- if (typeof field === 'string') return false;
192
- return !!field.dependsOn || !!field.visibleOn;
193
- });
194
- }, [section.fields]);
195
-
196
- // Watch form values for conditional field evaluation
197
- // Only watch when there are fields with dependsOn or visibleOn to avoid
198
- // unnecessary re-renders in forms without conditional fields.
199
- const allFormValues = methods.watch();
200
- const formValues = hasConditionalFields ? allFormValues : undefined;
201
-
202
- const handleToggleCollapse = () => {
203
- if (section.collapsible) {
204
- setIsCollapsed(!isCollapsed);
205
- }
206
- };
207
-
208
- return (
209
- <div className="border rounded-lg p-4">
210
- {section.label && (
211
- <div
212
- className={`flex items-center justify-between mb-4 ${
213
- section.collapsible ? 'cursor-pointer' : ''
214
- }`}
215
- onClick={handleToggleCollapse}
216
- >
217
- <h3 className="text-lg font-semibold">{resolveI18nLabel(section.label)}</h3>
218
- {section.collapsible && (
219
- <span className="text-sm text-gray-500">
220
- {isCollapsed ? '▶' : '▼'}
221
- </span>
222
- )}
223
- </div>
224
- )}
225
-
226
- {!isCollapsed && (
227
- <div className={`grid ${gridCols} gap-4`}>
228
- {section.fields.map((field, index) => {
229
- // Handle both string fields (legacy) and FormFieldSchema objects
230
- const fieldName = typeof field === 'string' ? field : field.field;
231
- const fieldConfig = typeof field === 'string' ? { field: fieldName } : field;
232
-
233
- // Evaluate visibility: static hidden, visibleOn expression, dependsOn parent
234
- if (!evaluateFieldVisibility(fieldConfig, formValues || {})) {
235
- return null;
236
- }
237
-
238
- // Calculate colSpan for grid
239
- const colSpan = fieldConfig.colSpan || 1;
240
- const colSpanClass = COL_SPAN[Math.min(colSpan, section.columns || 1) as keyof typeof COL_SPAN];
241
-
242
- return (
243
- <div key={`${fieldName}-${index}`} className={colSpanClass}>
244
- <FieldFactory
245
- field={fieldConfig}
246
- methods={methods}
247
- disabled={disabled || fieldConfig.readonly}
248
- />
249
- </div>
250
- );
251
- })}
252
- </div>
253
- )}
254
- </div>
255
- );
256
- };
257
-
258
- FormRenderer.displayName = 'FormRenderer';
@@ -1,352 +0,0 @@
1
- # FormRenderer Component
2
-
3
- The `FormRenderer` component is a React component that renders forms based on the `FormView` schema from `@objectstack/spec`. It provides a flexible and powerful way to create forms with minimal code.
4
-
5
- ## Features
6
-
7
- - ✅ **Schema-driven**: Define forms using JSON schema from `@objectstack/spec`
8
- - ✅ **Multi-column layouts**: Support for 1-4 column grid layouts
9
- - ✅ **Collapsible sections**: Organize forms with collapsible sections
10
- - ✅ **Form state management**: Built-in state management using `react-hook-form`
11
- - ✅ **Multiple field types**: Text, Number, Checkbox, Textarea, Select, Date, DateTime, Time
12
- - ⏳ **Conditional fields**: Show/hide fields based on conditions (planned)
13
- - ⏳ **Schema validation**: Zod validation support (planned)
14
- - ✅ **Column spanning**: Fields can span multiple columns
15
- - ✅ **Help text**: Display helpful descriptions for fields
16
- - ✅ **Required fields**: Mark fields as required with validation
17
-
18
- ## Installation
19
-
20
- The FormRenderer component is part of the `@object-ui/react` package:
21
-
22
- ```bash
23
- npm install @object-ui/react @objectstack/spec react-hook-form
24
- ```
25
-
26
- Or with pnpm:
27
-
28
- ```bash
29
- pnpm add @object-ui/react @objectstack/spec react-hook-form
30
- ```
31
-
32
- ## Basic Usage
33
-
34
- ```tsx
35
- import { FormRenderer } from '@object-ui/react';
36
- import type { FormView } from '@objectstack/spec/ui';
37
-
38
- const schema: FormView = {
39
- type: 'simple',
40
- sections: [
41
- {
42
- label: 'Contact Information',
43
- collapsible: false,
44
- collapsed: false,
45
- columns: 2,
46
- fields: [
47
- {
48
- field: 'firstName',
49
- label: 'First Name',
50
- required: true,
51
- widget: 'text',
52
- },
53
- {
54
- field: 'lastName',
55
- label: 'Last Name',
56
- required: true,
57
- widget: 'text',
58
- },
59
- {
60
- field: 'email',
61
- label: 'Email',
62
- required: true,
63
- widget: 'email',
64
- helpText: 'We will never share your email',
65
- },
66
- ],
67
- },
68
- ],
69
- };
70
-
71
- function MyForm() {
72
- const handleSubmit = (data: Record<string, any>) => {
73
- console.log('Form submitted:', data);
74
- };
75
-
76
- return (
77
- <FormRenderer
78
- schema={schema}
79
- onSubmit={handleSubmit}
80
- />
81
- );
82
- }
83
- ```
84
-
85
- ## Props
86
-
87
- ### FormRendererProps
88
-
89
- | Prop | Type | Required | Description |
90
- |------|------|----------|-------------|
91
- | `schema` | `FormView` | Yes | The FormView schema from @objectstack/spec |
92
- | `data` | `Record<string, any>` | No | Initial form data |
93
- | `onSubmit` | `(data: Record<string, any>) => void \| Promise<void>` | No | Form submission handler |
94
- | `onChange` | `(data: Record<string, any>) => void` | No | Form change handler |
95
- | `className` | `string` | No | Custom CSS class for the form |
96
- | `disabled` | `boolean` | No | Whether the form is disabled |
97
-
98
- ## Schema Structure
99
-
100
- ### FormView
101
-
102
- The main schema that defines the entire form.
103
-
104
- ```typescript
105
- interface FormView {
106
- type: 'simple' | 'tabbed' | 'wizard';
107
- sections?: FormSection[];
108
- data?: DataSource; // Optional data source configuration
109
- }
110
- ```
111
-
112
- ### FormSection
113
-
114
- Defines a section of the form with its own layout.
115
-
116
- ```typescript
117
- interface FormSection {
118
- label?: string;
119
- collapsible?: boolean;
120
- collapsed?: boolean;
121
- columns: 1 | 2 | 3 | 4;
122
- fields: (string | FormField)[];
123
- }
124
- ```
125
-
126
- ### FormField
127
-
128
- Defines individual form fields.
129
-
130
- ```typescript
131
- interface FormField {
132
- field: string; // Field name
133
- label?: string;
134
- placeholder?: string;
135
- helpText?: string;
136
- readonly?: boolean;
137
- required?: boolean;
138
- hidden?: boolean;
139
- colSpan?: number; // Number of columns to span (1-4)
140
- widget?: string; // Widget type (text, number, checkbox, etc.)
141
- dependsOn?: string; // Field dependency
142
- visibleOn?: string; // Visibility condition
143
- }
144
- ```
145
-
146
- ## Supported Widget Types
147
-
148
- The `FieldFactory` component supports the following widget types:
149
-
150
- ### Text Input Types
151
- - `text`, `string` - Basic text input
152
- - `email` - Email input with validation
153
- - `password` - Password input (masked)
154
- - `url` - URL input
155
- - `tel`, `phone` - Telephone/phone number input
156
- - `textarea` - Multi-line text input
157
- - `markdown` - Markdown text editor (textarea with monospace font)
158
- - `html` - HTML/Rich text editor (textarea with monospace font)
159
-
160
- ### Numeric Input Types
161
- - `number`, `integer`, `float` - Number input
162
- - `currency` - Currency input with $ prefix
163
- - `percent` - Percentage input with % suffix
164
-
165
- ### Boolean & Selection Types
166
- - `checkbox`, `boolean` - Checkbox input
167
- - `select`, `dropdown` - Select dropdown
168
-
169
- ### Date & Time Types
170
- - `date` - Date picker
171
- - `datetime`, `datetime-local` - DateTime picker
172
- - `time` - Time picker
173
-
174
- ### File Upload Types
175
- - `file` - File upload input
176
- - `image` - Image upload input (defaults to image/* mime types)
177
-
178
- ### Relationship Types
179
- - `lookup` - Lookup/reference field (select with options)
180
- - `master_detail` - Master-detail relationship (select with options)
181
- - `user`, `owner` - User selection field (select with options)
182
-
183
- ### Complex & Special Types
184
- - `location` - Geographic location (latitude/longitude inputs)
185
- - `object` - JSON object editor (textarea with JSON validation)
186
- - `formula` - Read-only computed field
187
- - `summary` - Read-only aggregation/rollup field
188
- - `auto_number` - Read-only auto-generated number
189
- - `vector` - Vector/embedding display (read-only)
190
- - `grid` - Sub-table/grid editor (placeholder)
191
-
192
- ## Extended Field Properties
193
-
194
- Some field types support additional properties beyond the base FormField schema:
195
-
196
- ```typescript
197
- interface ExtendedFormField extends FormField {
198
- // For file/image uploads
199
- multiple?: boolean;
200
- accept?: string[];
201
-
202
- // For select/lookup/user fields
203
- options?: Array<{
204
- label: string;
205
- value: string;
206
- disabled?: boolean;
207
- }>;
208
- }
209
- ```
210
-
211
- Example usage with extended properties:
212
-
213
- ```tsx
214
- {
215
- field: 'avatar',
216
- label: 'Profile Picture',
217
- widget: 'image',
218
- accept: ['image/png', 'image/jpeg'],
219
- multiple: false
220
- }
221
-
222
- {
223
- field: 'account',
224
- label: 'Account',
225
- widget: 'lookup',
226
- options: [
227
- { label: 'Account 1', value: '1' },
228
- { label: 'Account 2', value: '2' }
229
- ]
230
- }
231
- ```
232
-
233
- ## Known Limitations
234
-
235
- ### Version 0.3.0
236
-
237
- - **Conditional Visibility**: The `visibleOn` and `dependsOn` properties are not yet implemented. Fields are visible by default unless explicitly marked as `hidden`.
238
- - **Advanced Select Options**: While select/lookup/user fields support options via the `ExtendedFormField` interface, they don't yet support advanced features like search, async loading, or custom rendering.
239
- - **Rich Text Editors**: The `markdown` and `html` widgets currently use plain textareas with monospace fonts. Full WYSIWYG editors are planned for future releases.
240
- - **File Upload Preview**: File and image widgets support uploads but don't yet show previews or provide upload progress indicators.
241
- - **Location Maps**: The location widget provides lat/lng inputs but doesn't include map visualization or geocoding.
242
- - **Grid Editor**: The grid widget is a placeholder and doesn't yet provide spreadsheet-like editing capabilities.
243
- - **Validation**: Currently only basic required field validation is supported via react-hook-form. Advanced Zod schema validation is planned for future releases.
244
-
245
- These features are planned for future releases.
246
-
247
- ## Examples
248
-
249
- ### Multi-Section Form
250
-
251
- ```tsx
252
- const schema: FormView = {
253
- type: 'simple',
254
- sections: [
255
- {
256
- label: 'Personal Information',
257
- collapsible: true,
258
- collapsed: false,
259
- columns: 2,
260
- fields: [
261
- { field: 'firstName', label: 'First Name', required: true, widget: 'text' },
262
- { field: 'lastName', label: 'Last Name', required: true, widget: 'text' },
263
- { field: 'email', label: 'Email', required: true, widget: 'email' },
264
- { field: 'phone', label: 'Phone', widget: 'tel' },
265
- ],
266
- },
267
- {
268
- label: 'Preferences',
269
- collapsible: true,
270
- collapsed: true,
271
- columns: 1,
272
- fields: [
273
- {
274
- field: 'newsletter',
275
- label: 'Subscribe to newsletter',
276
- widget: 'checkbox',
277
- helpText: 'Receive updates about our products',
278
- },
279
- ],
280
- },
281
- ],
282
- };
283
- ```
284
-
285
- ### Form with Initial Data
286
-
287
- ```tsx
288
- const initialData = {
289
- firstName: 'John',
290
- lastName: 'Doe',
291
- email: 'john@example.com',
292
- newsletter: true,
293
- };
294
-
295
- <FormRenderer
296
- schema={schema}
297
- data={initialData}
298
- onSubmit={handleSubmit}
299
- />
300
- ```
301
-
302
- ### Form with Column Spanning
303
-
304
- ```tsx
305
- const schema: FormView = {
306
- type: 'simple',
307
- sections: [
308
- {
309
- label: 'Contact',
310
- columns: 2,
311
- fields: [
312
- { field: 'name', label: 'Name', widget: 'text' },
313
- { field: 'email', label: 'Email', widget: 'email' },
314
- {
315
- field: 'message',
316
- label: 'Message',
317
- widget: 'textarea',
318
- colSpan: 2, // Spans both columns
319
- },
320
- ],
321
- },
322
- ],
323
- };
324
- ```
325
-
326
- ## Architecture
327
-
328
- The FormRenderer is built on top of:
329
-
330
- - **react-hook-form**: For form state management and validation
331
- - **@objectstack/spec**: For schema definitions
332
-
333
- ## Customization
334
-
335
- You can customize the appearance of the form by:
336
-
337
- 1. Using the `className` prop on the FormRenderer
338
- 2. Using Tailwind CSS classes in your application
339
- 3. Extending the FieldFactory component for custom widgets
340
-
341
- ## Related Components
342
-
343
- - `FieldFactory`: Renders individual form fields based on widget type
344
- - `SchemaRenderer`: General-purpose schema renderer for ObjectUI
345
-
346
- ## License
347
-
348
- MIT
349
-
350
- ## Contributing
351
-
352
- Contributions are welcome! Please read the [CONTRIBUTING.md](../../CONTRIBUTING.md) for details.
@@ -1,12 +0,0 @@
1
- /**
2
- * ObjectUI
3
- * Copyright (c) 2024-present ObjectStack Inc.
4
- *
5
- * This source code is licensed under the MIT license found in the
6
- * LICENSE file in the root directory of this source tree.
7
- */
8
-
9
- export { FormRenderer } from './FormRenderer';
10
- export type { FormRendererProps } from './FormRenderer';
11
- export { FieldFactory } from './FieldFactory';
12
- export type { FieldFactoryProps, ExtendedFormField } from './FieldFactory';