@ankhorage/zora 9.0.1 → 11.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/CHANGELOG.md +17 -0
- package/README.md +2 -2
- package/dist/constants.d.ts +2 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/features/bottom-sheet/bottomSheetMeta.d.ts +1 -1
- package/dist/features/card/cardMeta.d.ts +1 -1
- package/dist/features/card/mediaCardMeta.d.ts +1 -1
- package/dist/features/card/postCardMeta.d.ts +1 -1
- package/dist/features/form/adapters/inbound/Form.d.ts +5 -0
- package/dist/features/form/adapters/inbound/Form.d.ts.map +1 -0
- package/dist/features/form/adapters/inbound/Form.js +18 -0
- package/dist/features/form/adapters/inbound/Form.js.map +1 -0
- package/dist/{components/form → features/form/adapters/inbound}/FormActions.d.ts +1 -1
- package/dist/features/form/adapters/inbound/FormActions.d.ts.map +1 -0
- package/dist/{components/form → features/form/adapters/inbound}/FormActions.js +3 -3
- package/dist/features/form/adapters/inbound/FormActions.js.map +1 -0
- package/dist/features/form/adapters/inbound/FormError.d.ts +5 -0
- package/dist/features/form/adapters/inbound/FormError.d.ts.map +1 -0
- package/dist/features/form/adapters/inbound/FormError.js +18 -0
- package/dist/features/form/adapters/inbound/FormError.js.map +1 -0
- package/dist/features/form/adapters/inbound/FormField.d.ts +5 -0
- package/dist/features/form/adapters/inbound/FormField.d.ts.map +1 -0
- package/dist/{patterns/form-field → features/form/adapters/inbound}/FormField.js +5 -4
- package/dist/features/form/adapters/inbound/FormField.js.map +1 -0
- package/dist/features/form/formActionsMeta.d.ts +9 -0
- package/dist/features/form/formActionsMeta.d.ts.map +1 -0
- package/dist/features/form/formActionsMeta.js +9 -0
- package/dist/features/form/formActionsMeta.js.map +1 -0
- package/dist/features/form/formErrorMeta.d.ts +32 -0
- package/dist/features/form/formErrorMeta.d.ts.map +1 -0
- package/dist/features/form/formErrorMeta.js +19 -0
- package/dist/features/form/formErrorMeta.js.map +1 -0
- package/dist/{components/form/meta.d.ts → features/form/formFieldMeta.d.ts} +28 -39
- package/dist/features/form/formFieldMeta.d.ts.map +1 -0
- package/dist/features/form/formFieldMeta.js +35 -0
- package/dist/features/form/formFieldMeta.js.map +1 -0
- package/dist/features/form/formMeta.d.ts +61 -0
- package/dist/features/form/formMeta.d.ts.map +1 -0
- package/dist/features/form/formMeta.js +34 -0
- package/dist/features/form/formMeta.js.map +1 -0
- package/dist/features/form/public.d.ts +8 -0
- package/dist/features/form/public.d.ts.map +1 -0
- package/dist/features/form/public.js +7 -0
- package/dist/features/form/public.js.map +1 -0
- package/dist/{components → features}/form/useFormController.d.ts +1 -1
- package/dist/features/form/useFormController.d.ts.map +1 -0
- package/dist/{components → features}/form/useFormController.js +1 -1
- package/dist/features/form/useFormController.js.map +1 -0
- package/dist/{components/form → features/form/utils}/validation.d.ts +1 -1
- package/dist/features/form/utils/validation.d.ts.map +1 -0
- package/dist/{components/form → features/form/utils}/validation.js +2 -4
- package/dist/features/form/utils/validation.js.map +1 -0
- package/dist/features/keyboard-avoiding-view/adapters/inbound/KeyboardAvoidingView.d.ts +5 -0
- package/dist/features/keyboard-avoiding-view/adapters/inbound/KeyboardAvoidingView.d.ts.map +1 -0
- package/dist/features/keyboard-avoiding-view/adapters/inbound/KeyboardAvoidingView.js +10 -0
- package/dist/features/keyboard-avoiding-view/adapters/inbound/KeyboardAvoidingView.js.map +1 -0
- package/dist/features/keyboard-avoiding-view/keyboardAvoidingViewMeta.d.ts +36 -0
- package/dist/features/keyboard-avoiding-view/keyboardAvoidingViewMeta.d.ts.map +1 -0
- package/dist/features/keyboard-avoiding-view/keyboardAvoidingViewMeta.js +37 -0
- package/dist/features/keyboard-avoiding-view/keyboardAvoidingViewMeta.js.map +1 -0
- package/dist/features/keyboard-avoiding-view/public.d.ts +3 -0
- package/dist/features/keyboard-avoiding-view/public.d.ts.map +1 -0
- package/dist/features/keyboard-avoiding-view/public.js +3 -0
- package/dist/features/keyboard-avoiding-view/public.js.map +1 -0
- package/dist/features/layout/boxMeta.d.ts +1 -1
- package/dist/features/layout/containerMeta.d.ts +1 -1
- package/dist/features/layout/gridMeta.d.ts +1 -1
- package/dist/features/layout/stackMeta.d.ts +1 -1
- package/dist/features/list/flatListMeta.d.ts +1 -1
- package/dist/features/list/sectionListMeta.d.ts +1 -1
- package/dist/features/surface/surfaceMeta.d.ts +1 -1
- package/dist/features/uploader/adapters/inbound/Uploader.d.ts.map +1 -1
- package/dist/features/uploader/adapters/inbound/Uploader.js +1 -1
- package/dist/features/uploader/adapters/inbound/Uploader.js.map +1 -1
- package/dist/index.d.ts +3 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/layout/screen/meta.d.ts +1 -1
- package/dist/layout/screen-section/meta.d.ts +1 -1
- package/dist/metadata/allowedChildren.d.ts +3 -3
- package/dist/metadata/allowedChildren.d.ts.map +1 -1
- package/dist/metadata/allowedChildren.js +2 -2
- package/dist/metadata/allowedChildren.js.map +1 -1
- package/dist/metadata/bindableComponentMeta.d.ts +2 -2
- package/dist/metadata/componentMeta.d.ts.map +1 -1
- package/dist/metadata/componentMeta.js +6 -3
- package/dist/metadata/componentMeta.js.map +1 -1
- package/dist/patterns/auth/AuthForm.d.ts +21 -0
- package/dist/patterns/auth/AuthForm.d.ts.map +1 -0
- package/dist/patterns/auth/AuthForm.js +19 -0
- package/dist/patterns/auth/AuthForm.js.map +1 -0
- package/dist/patterns/auth/AuthFormField.d.ts +16 -0
- package/dist/patterns/auth/AuthFormField.d.ts.map +1 -0
- package/dist/patterns/auth/AuthFormField.js +38 -0
- package/dist/patterns/auth/AuthFormField.js.map +1 -0
- package/dist/patterns/auth/ForgotPasswordForm.d.ts.map +1 -1
- package/dist/patterns/auth/ForgotPasswordForm.js +2 -2
- package/dist/patterns/auth/ForgotPasswordForm.js.map +1 -1
- package/dist/patterns/auth/OtpForm.d.ts.map +1 -1
- package/dist/patterns/auth/OtpForm.js +2 -2
- package/dist/patterns/auth/OtpForm.js.map +1 -1
- package/dist/patterns/auth/SignInForm.d.ts.map +1 -1
- package/dist/patterns/auth/SignInForm.js +2 -2
- package/dist/patterns/auth/SignInForm.js.map +1 -1
- package/dist/patterns/auth/SignUpForm.d.ts.map +1 -1
- package/dist/patterns/auth/SignUpForm.js +2 -2
- package/dist/patterns/auth/SignUpForm.js.map +1 -1
- package/dist/patterns/auth/types.d.ts +1 -1
- package/dist/patterns/auth/types.d.ts.map +1 -1
- package/dist/patterns/auth/types.js.map +1 -1
- package/dist/patterns/auth/utils.d.ts +1 -1
- package/dist/patterns/auth/utils.d.ts.map +1 -1
- package/dist/patterns/auth/utils.js.map +1 -1
- package/dist/patterns/inspector-field/InspectorField.js +1 -1
- package/dist/patterns/inspector-field/InspectorField.js.map +1 -1
- package/dist/patterns/message-bubble/meta.d.ts +1 -1
- package/dist/patterns/notice/meta.d.ts +1 -1
- package/dist/patterns/panel/meta.d.ts +1 -1
- package/dist/patterns/reader/meta.d.ts +2 -2
- package/dist/patterns/scanner/meta.d.ts +2 -2
- package/dist/registry.js +3 -3
- package/dist/registry.js.map +1 -1
- package/dist/{components/form/types.d.ts → types/form.d.ts} +12 -28
- package/dist/types/form.d.ts.map +1 -0
- package/dist/types/form.js +2 -0
- package/dist/types/form.js.map +1 -0
- package/dist/types/keyboard-avoiding-view.d.ts +6 -0
- package/dist/types/keyboard-avoiding-view.d.ts.map +1 -0
- package/dist/types/keyboard-avoiding-view.js +2 -0
- package/dist/types/keyboard-avoiding-view.js.map +1 -0
- package/package.json +3 -2
- package/src/audit.test.ts +2 -4
- package/src/constants.ts +2 -1
- package/src/featureManifest.test.ts +7 -0
- package/src/features/form/adapters/inbound/Form.tsx +39 -0
- package/src/{components/form → features/form/adapters/inbound}/FormActions.tsx +4 -4
- package/src/features/form/adapters/inbound/FormError.tsx +22 -0
- package/src/{patterns/form-field → features/form/adapters/inbound}/FormField.tsx +6 -4
- package/src/features/form/formActionsMeta.ts +9 -0
- package/src/features/form/formErrorMeta.ts +19 -0
- package/src/features/form/formFieldMeta.ts +35 -0
- package/src/features/form/formMeta.ts +34 -0
- package/src/{components/form/index.ts → features/form/public.ts} +6 -7
- package/src/{components → features}/form/useFormController.ts +2 -2
- package/src/{components/form → features/form/utils}/validation.test.ts +4 -1
- package/src/{components/form → features/form/utils}/validation.ts +4 -8
- package/src/features/keyboard-avoiding-view/adapters/inbound/KeyboardAvoidingView.tsx +18 -0
- package/src/features/keyboard-avoiding-view/keyboardAvoidingViewMeta.ts +38 -0
- package/src/features/keyboard-avoiding-view/public.ts +5 -0
- package/src/features/uploader/adapters/inbound/Uploader.tsx +1 -1
- package/src/index.ts +31 -29
- package/src/metadata/allowedChildren.ts +2 -2
- package/src/metadata/componentMeta.test.ts +32 -2
- package/src/metadata/componentMeta.ts +6 -3
- package/src/patterns/auth/AuthForm.tsx +68 -0
- package/src/patterns/auth/AuthFormField.tsx +81 -0
- package/src/patterns/auth/ForgotPasswordForm.tsx +3 -2
- package/src/patterns/auth/OtpForm.tsx +3 -2
- package/src/patterns/auth/SignInForm.tsx +3 -2
- package/src/patterns/auth/SignUpForm.tsx +3 -2
- package/src/patterns/auth/types.ts +1 -1
- package/src/patterns/auth/utils.ts +1 -1
- package/src/patterns/inspector-field/InspectorField.tsx +1 -1
- package/src/platformAcceptance.test.ts +1 -1
- package/src/registry.ts +3 -3
- package/src/showcaseCoverage.test.ts +1 -0
- package/src/theme/themeScopeStructure.test.ts +5 -7
- package/src/{components/form/types.ts → types/form.ts} +12 -36
- package/src/types/keyboard-avoiding-view.ts +10 -0
- package/dist/components/form/Form.d.ts +0 -7
- package/dist/components/form/Form.d.ts.map +0 -1
- package/dist/components/form/Form.js +0 -34
- package/dist/components/form/Form.js.map +0 -1
- package/dist/components/form/FormActions.d.ts.map +0 -1
- package/dist/components/form/FormActions.js.map +0 -1
- package/dist/components/form/FormError.d.ts +0 -7
- package/dist/components/form/FormError.d.ts.map +0 -1
- package/dist/components/form/FormError.js +0 -21
- package/dist/components/form/FormError.js.map +0 -1
- package/dist/components/form/FormField.d.ts +0 -7
- package/dist/components/form/FormField.d.ts.map +0 -1
- package/dist/components/form/FormField.js +0 -81
- package/dist/components/form/FormField.js.map +0 -1
- package/dist/components/form/index.d.ts +0 -8
- package/dist/components/form/index.d.ts.map +0 -1
- package/dist/components/form/index.js +0 -7
- package/dist/components/form/index.js.map +0 -1
- package/dist/components/form/meta.d.ts.map +0 -1
- package/dist/components/form/meta.js +0 -94
- package/dist/components/form/meta.js.map +0 -1
- package/dist/components/form/types.d.ts.map +0 -1
- package/dist/components/form/types.js +0 -2
- package/dist/components/form/types.js.map +0 -1
- package/dist/components/form/useFormController.d.ts.map +0 -1
- package/dist/components/form/useFormController.js.map +0 -1
- package/dist/components/form/validation.d.ts.map +0 -1
- package/dist/components/form/validation.js.map +0 -1
- package/dist/features/splash-screen/adapters/inbound/SplashScreen.d.ts +0 -11
- package/dist/features/splash-screen/adapters/inbound/SplashScreen.d.ts.map +0 -1
- package/dist/features/splash-screen/adapters/inbound/SplashScreen.js +0 -55
- package/dist/features/splash-screen/adapters/inbound/SplashScreen.js.map +0 -1
- package/dist/features/splash-screen/public.d.ts +0 -3
- package/dist/features/splash-screen/public.d.ts.map +0 -1
- package/dist/features/splash-screen/public.js +0 -2
- package/dist/features/splash-screen/public.js.map +0 -1
- package/dist/features/splash-screen/splashScreenMeta.d.ts +0 -39
- package/dist/features/splash-screen/splashScreenMeta.d.ts.map +0 -1
- package/dist/features/splash-screen/splashScreenMeta.js +0 -40
- package/dist/features/splash-screen/splashScreenMeta.js.map +0 -1
- package/dist/patterns/form-field/FormField.d.ts +0 -4
- package/dist/patterns/form-field/FormField.d.ts.map +0 -1
- package/dist/patterns/form-field/FormField.js.map +0 -1
- package/dist/patterns/form-field/index.d.ts +0 -2
- package/dist/patterns/form-field/index.d.ts.map +0 -1
- package/dist/patterns/form-field/index.js +0 -2
- package/dist/patterns/form-field/index.js.map +0 -1
- package/dist/patterns/form-field/types.d.ts +0 -9
- package/dist/patterns/form-field/types.d.ts.map +0 -1
- package/dist/patterns/form-field/types.js +0 -2
- package/dist/patterns/form-field/types.js.map +0 -1
- package/dist/types/splash-screen.d.ts +0 -16
- package/dist/types/splash-screen.d.ts.map +0 -1
- package/dist/types/splash-screen.js +0 -2
- package/dist/types/splash-screen.js.map +0 -1
- package/src/components/form/Form.tsx +0 -74
- package/src/components/form/FormError.tsx +0 -34
- package/src/components/form/FormField.tsx +0 -157
- package/src/components/form/meta.ts +0 -98
- package/src/features/splash-screen/adapters/inbound/SplashScreen.tsx +0 -98
- package/src/features/splash-screen/public.ts +0 -2
- package/src/features/splash-screen/splashScreenMeta.ts +0 -41
- package/src/patterns/form-field/index.ts +0 -1
- package/src/patterns/form-field/types.ts +0 -16
- package/src/types/splash-screen.ts +0 -18
|
@@ -10,7 +10,6 @@ export const CONTAINER_ALLOWED_CHILDREN = [
|
|
|
10
10
|
'ChipGroup',
|
|
11
11
|
'DataTable',
|
|
12
12
|
'IconButton',
|
|
13
|
-
'SplashScreen',
|
|
14
13
|
'Uploader',
|
|
15
14
|
'FlatList',
|
|
16
15
|
'SectionList',
|
|
@@ -25,12 +24,13 @@ export const CONTAINER_ALLOWED_CHILDREN = [
|
|
|
25
24
|
'Heading',
|
|
26
25
|
'Icon',
|
|
27
26
|
'Image',
|
|
27
|
+
'KeyboardAvoidingView',
|
|
28
28
|
'Button',
|
|
29
29
|
'ButtonGroup',
|
|
30
30
|
'RadioGroup',
|
|
31
31
|
'ThemeModeToggle',
|
|
32
32
|
'TextInput',
|
|
33
|
-
'
|
|
33
|
+
'Form',
|
|
34
34
|
'Card',
|
|
35
35
|
'Panel',
|
|
36
36
|
'Notice',
|
|
@@ -51,7 +51,7 @@ describe('ZORA_COMPONENT_META event metadata', () => {
|
|
|
51
51
|
const eventType: ZoraComponentEventPayloadKind = event?.eventType ?? 'form.submit';
|
|
52
52
|
|
|
53
53
|
expect(eventType).toBe('form.submit');
|
|
54
|
-
expect(event?.payloadFields
|
|
54
|
+
expect(event?.payloadFields).toEqual([]);
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
test('declares button event metadata', () => {
|
|
@@ -100,6 +100,21 @@ describe('ZORA_COMPONENT_META requirement metadata', () => {
|
|
|
100
100
|
});
|
|
101
101
|
|
|
102
102
|
describe('ZORA_COMPONENT_META invariants', () => {
|
|
103
|
+
test('keeps form nodes in their canonical hierarchy', () => {
|
|
104
|
+
expect(ZORA_COMPONENT_META.Form.allowedChildren).toEqual(['FormError', 'FormField']);
|
|
105
|
+
expect(ZORA_COMPONENT_META.FormField.allowedChildren).toEqual([
|
|
106
|
+
'Checkbox',
|
|
107
|
+
'CheckboxGroup',
|
|
108
|
+
'RadioGroup',
|
|
109
|
+
'TextInput',
|
|
110
|
+
]);
|
|
111
|
+
for (const [name, meta] of Object.entries(ZORA_COMPONENT_META)) {
|
|
112
|
+
if (name === 'Form') continue;
|
|
113
|
+
expect(meta.allowedChildren).not.toContain('FormError');
|
|
114
|
+
expect(meta.allowedChildren).not.toContain('FormField');
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
103
118
|
test('every key matches meta.name', () => {
|
|
104
119
|
for (const [key, meta] of Object.entries(ZORA_COMPONENT_META)) {
|
|
105
120
|
expect(meta.name).toBe(key);
|
|
@@ -136,6 +151,7 @@ describe('ZORA_COMPONENT_META invariants', () => {
|
|
|
136
151
|
'EmptyState',
|
|
137
152
|
'Hero',
|
|
138
153
|
'Button',
|
|
154
|
+
'FormError',
|
|
139
155
|
'Checkbox',
|
|
140
156
|
'CheckboxGroup',
|
|
141
157
|
'Radio',
|
|
@@ -158,12 +174,13 @@ describe('ZORA_COMPONENT_META invariants', () => {
|
|
|
158
174
|
]);
|
|
159
175
|
|
|
160
176
|
const expectedContainerNodes = new Set([
|
|
177
|
+
'Form',
|
|
161
178
|
'Surface',
|
|
162
179
|
'MediaCard',
|
|
163
|
-
'SplashScreen',
|
|
164
180
|
'FlatList',
|
|
165
181
|
'SectionList',
|
|
166
182
|
'BottomSheet',
|
|
183
|
+
'KeyboardAvoidingView',
|
|
167
184
|
'FormField',
|
|
168
185
|
'ButtonGroup',
|
|
169
186
|
'Screen',
|
|
@@ -244,6 +261,19 @@ describe('ZORA_COMPONENT_META invariants', () => {
|
|
|
244
261
|
expect(ZORA_COMPONENT_META.ThemeModeToggle.blueprint?.defaultProps).toEqual({ size: 'm' });
|
|
245
262
|
});
|
|
246
263
|
|
|
264
|
+
test('KeyboardAvoidingView is a direct manifest container with native behavior props', () => {
|
|
265
|
+
const keyboardAvoidingView = ZORA_COMPONENT_META.KeyboardAvoidingView;
|
|
266
|
+
|
|
267
|
+
expect(keyboardAvoidingView.directManifestNode).toBe(true);
|
|
268
|
+
expect(keyboardAvoidingView.allowedChildren.length).toBeGreaterThan(0);
|
|
269
|
+
expect(keyboardAvoidingView.blueprint?.defaultProps).toEqual({
|
|
270
|
+
behavior: 'padding',
|
|
271
|
+
enabled: true,
|
|
272
|
+
keyboardVerticalOffset: 0,
|
|
273
|
+
});
|
|
274
|
+
expect(keyboardAvoidingView.props.behavior?.enum).toEqual(['height', 'position', 'padding']);
|
|
275
|
+
});
|
|
276
|
+
|
|
247
277
|
test('Progress is a direct manifest leaf with serializable defaults', () => {
|
|
248
278
|
expect(ZORA_COMPONENT_META.Progress.directManifestNode).toBe(true);
|
|
249
279
|
expect(ZORA_COMPONENT_META.Progress.allowedChildren).toEqual([]);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { appBarMeta } from '../components/app-bar/meta';
|
|
2
2
|
import { breadcrumbsMeta } from '../components/breadcrumbs/meta';
|
|
3
3
|
import { datePickerMeta } from '../components/date-picker/meta';
|
|
4
|
-
import { formActionsMeta, formErrorMeta, formFieldMeta, formMeta } from '../components/form/meta';
|
|
5
4
|
import { gradientMeta } from '../components/gradient/meta';
|
|
6
5
|
import { dropdownMenuMeta, menuMeta } from '../components/menu/meta';
|
|
7
6
|
import { modalMeta } from '../components/modal/meta';
|
|
@@ -37,10 +36,15 @@ import { chipMeta } from '../features/chip/chipMeta';
|
|
|
37
36
|
import { dataTableMeta } from '../features/data-table/dataTableMeta';
|
|
38
37
|
import { emptyStateMeta } from '../features/empty-state/emptyStateMeta';
|
|
39
38
|
import { checkboxGroupMeta, checkboxMeta } from '../features/form/checkbox/checkboxMeta';
|
|
39
|
+
import { formActionsMeta } from '../features/form/formActionsMeta';
|
|
40
|
+
import { formErrorMeta } from '../features/form/formErrorMeta';
|
|
41
|
+
import { formFieldMeta } from '../features/form/formFieldMeta';
|
|
42
|
+
import { formMeta } from '../features/form/formMeta';
|
|
40
43
|
import { radioGroupMeta, radioMeta } from '../features/form/radio/radioMeta';
|
|
41
44
|
import { textInputMeta } from '../features/form/text-input/textInputMeta';
|
|
42
45
|
import { iconMeta } from '../features/icon/iconMeta';
|
|
43
46
|
import { imageMeta } from '../features/image/imageMeta';
|
|
47
|
+
import { keyboardAvoidingViewMeta } from '../features/keyboard-avoiding-view/keyboardAvoidingViewMeta';
|
|
44
48
|
import { boxMeta } from '../features/layout/boxMeta';
|
|
45
49
|
import { containerMeta } from '../features/layout/containerMeta';
|
|
46
50
|
import { contentRailMeta } from '../features/layout/contentRailMeta';
|
|
@@ -50,7 +54,6 @@ import { stackMeta } from '../features/layout/stackMeta';
|
|
|
50
54
|
import { flatListMeta } from '../features/list/flatListMeta';
|
|
51
55
|
import { sectionListMeta } from '../features/list/sectionListMeta';
|
|
52
56
|
import { progressMeta, progressRingMeta } from '../features/progress/progressMeta';
|
|
53
|
-
import { splashScreenMeta } from '../features/splash-screen/splashScreenMeta';
|
|
54
57
|
import { surfaceMeta } from '../features/surface/surfaceMeta';
|
|
55
58
|
import { headingMeta } from '../features/typography/headingMeta';
|
|
56
59
|
import { textMeta } from '../features/typography/textMeta';
|
|
@@ -133,6 +136,7 @@ export const ZORA_COMPONENT_META: ZoraComponentMetaRegistry = finalizeFeatureMet
|
|
|
133
136
|
Icon: iconMeta,
|
|
134
137
|
IconButton: iconButtonMeta,
|
|
135
138
|
Image: imageMeta,
|
|
139
|
+
KeyboardAvoidingView: keyboardAvoidingViewMeta,
|
|
136
140
|
TextInput: textInputMeta,
|
|
137
141
|
MediaCard: mediaCardMeta,
|
|
138
142
|
Menu: menuMeta,
|
|
@@ -150,7 +154,6 @@ export const ZORA_COMPONENT_META: ZoraComponentMetaRegistry = finalizeFeatureMet
|
|
|
150
154
|
SkeletonCard: skeletonCardMeta,
|
|
151
155
|
SkeletonList: skeletonListMeta,
|
|
152
156
|
SkeletonText: skeletonTextMeta,
|
|
153
|
-
SplashScreen: splashScreenMeta,
|
|
154
157
|
Tabs: tabsMeta,
|
|
155
158
|
Text: textMeta,
|
|
156
159
|
TimePicker: timePickerMeta,
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { FormActions, FormError, useFormController } from '../../features/form/public';
|
|
4
|
+
import { Stack } from '../../features/layout/public';
|
|
5
|
+
import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
|
|
6
|
+
import type { FormErrors, FormFieldConfig, FormValues } from '../../types/form';
|
|
7
|
+
import { AuthFormField } from './AuthFormField';
|
|
8
|
+
|
|
9
|
+
interface AuthFormProps<TName extends string> {
|
|
10
|
+
fields: readonly FormFieldConfig<TName>[];
|
|
11
|
+
values: FormValues<TName>;
|
|
12
|
+
onChange: (values: FormValues<TName>) => void;
|
|
13
|
+
onSubmit: (values: FormValues<TName>) => void | Promise<void>;
|
|
14
|
+
errors?: FormErrors<TName>;
|
|
15
|
+
error?: React.ReactNode;
|
|
16
|
+
loading?: boolean;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
submitLabel?: React.ReactNode;
|
|
19
|
+
actions?: React.ReactNode;
|
|
20
|
+
testID?: string;
|
|
21
|
+
interactionPolicy?: ZoraBaseProps['interactionPolicy'];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/*** Keeps config-driven field orchestration private to the auth patterns that own it. */
|
|
25
|
+
export function AuthForm<TName extends string>({
|
|
26
|
+
fields,
|
|
27
|
+
values,
|
|
28
|
+
onChange,
|
|
29
|
+
onSubmit,
|
|
30
|
+
errors,
|
|
31
|
+
error,
|
|
32
|
+
loading = false,
|
|
33
|
+
disabled = false,
|
|
34
|
+
submitLabel = 'Submit',
|
|
35
|
+
actions,
|
|
36
|
+
testID,
|
|
37
|
+
interactionPolicy,
|
|
38
|
+
}: AuthFormProps<TName>) {
|
|
39
|
+
const controller = useFormController({ fields, values, errors, onChange, onSubmit });
|
|
40
|
+
return (
|
|
41
|
+
<Stack gap="m" testID={testID}>
|
|
42
|
+
<FormError error={error} />
|
|
43
|
+
{fields.map((field) => (
|
|
44
|
+
<AuthFormField
|
|
45
|
+
key={field.name}
|
|
46
|
+
disabled={disabled}
|
|
47
|
+
error={controller.errors[field.name]}
|
|
48
|
+
field={field}
|
|
49
|
+
interactionPolicy={interactionPolicy}
|
|
50
|
+
loading={loading}
|
|
51
|
+
onChange={controller.setFieldValue}
|
|
52
|
+
value={values[field.name]}
|
|
53
|
+
/>
|
|
54
|
+
))}
|
|
55
|
+
<FormActions
|
|
56
|
+
disabled={disabled}
|
|
57
|
+
interactionPolicy={interactionPolicy}
|
|
58
|
+
loading={loading}
|
|
59
|
+
onSubmit={() => {
|
|
60
|
+
if (interactionPolicy !== 'passive') void controller.handleSubmit();
|
|
61
|
+
}}
|
|
62
|
+
submitLabel={submitLabel}
|
|
63
|
+
>
|
|
64
|
+
{actions}
|
|
65
|
+
</FormActions>
|
|
66
|
+
</Stack>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { FormField, hasRequiredRule } from '../../features/form/public';
|
|
4
|
+
import { TextInput } from '../../features/form/text-input/public';
|
|
5
|
+
import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
|
|
6
|
+
import type { FormFieldConfig, FormFieldValue } from '../../types/form';
|
|
7
|
+
|
|
8
|
+
interface AuthFormFieldProps<TName extends string> {
|
|
9
|
+
field: FormFieldConfig<TName>;
|
|
10
|
+
value: FormFieldValue;
|
|
11
|
+
onChange: (name: TName, value: FormFieldValue) => void;
|
|
12
|
+
error?: React.ReactNode;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
loading?: boolean;
|
|
15
|
+
interactionPolicy?: ZoraBaseProps['interactionPolicy'];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/*** Adapts an auth field configuration to the public compositional form primitives. */
|
|
19
|
+
export function AuthFormField<TName extends string>({
|
|
20
|
+
field,
|
|
21
|
+
value,
|
|
22
|
+
onChange,
|
|
23
|
+
error,
|
|
24
|
+
disabled = false,
|
|
25
|
+
loading = false,
|
|
26
|
+
interactionPolicy,
|
|
27
|
+
}: AuthFormFieldProps<TName>) {
|
|
28
|
+
const fieldDisabled = disabled || loading || field.disabled;
|
|
29
|
+
return (
|
|
30
|
+
<FormField
|
|
31
|
+
description={field.description}
|
|
32
|
+
disabled={fieldDisabled}
|
|
33
|
+
errorText={error}
|
|
34
|
+
helperText={field.helperText}
|
|
35
|
+
invalid={Boolean(error)}
|
|
36
|
+
label={field.label}
|
|
37
|
+
readOnly={field.readOnly}
|
|
38
|
+
required={field.required ?? hasRequiredRule(field.rules)}
|
|
39
|
+
testID={field.testID}
|
|
40
|
+
>
|
|
41
|
+
<TextInput
|
|
42
|
+
accessibilityLabel={typeof field.label === 'string' ? field.label : undefined}
|
|
43
|
+
autoCapitalize={
|
|
44
|
+
field.autoCapitalize ??
|
|
45
|
+
(['email', 'password', 'url'].includes(field.type ?? 'text') ? 'none' : undefined)
|
|
46
|
+
}
|
|
47
|
+
autoComplete={field.autoComplete}
|
|
48
|
+
disabled={fieldDisabled}
|
|
49
|
+
interactionPolicy={interactionPolicy}
|
|
50
|
+
invalid={Boolean(error)}
|
|
51
|
+
keyboardType={resolveKeyboardType(field)}
|
|
52
|
+
maxLength={field.maxLength}
|
|
53
|
+
onChangeText={(nextValue) => onChange(field.name, nextValue)}
|
|
54
|
+
placeholder={field.placeholder}
|
|
55
|
+
readOnly={field.readOnly}
|
|
56
|
+
secureTextEntry={field.secureTextEntry ?? field.type === 'password'}
|
|
57
|
+
textContentType={resolveTextContentType(field)}
|
|
58
|
+
value={value}
|
|
59
|
+
/>
|
|
60
|
+
</FormField>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/*** Resolves the native keyboard for an auth field configuration. */
|
|
65
|
+
function resolveKeyboardType(field: FormFieldConfig) {
|
|
66
|
+
if (field.keyboardType) return field.keyboardType;
|
|
67
|
+
if (field.type === 'email') return 'email-address';
|
|
68
|
+
if (field.type === 'number' || field.type === 'otp') return 'number-pad';
|
|
69
|
+
if (field.type === 'tel') return 'phone-pad';
|
|
70
|
+
if (field.type === 'url') return 'url';
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/*** Resolves platform text-content hints for an auth field configuration. */
|
|
75
|
+
function resolveTextContentType(field: FormFieldConfig) {
|
|
76
|
+
if (field.textContentType) return field.textContentType;
|
|
77
|
+
if (field.type === 'email') return 'emailAddress';
|
|
78
|
+
if (field.type === 'password') return 'password';
|
|
79
|
+
if (field.type === 'otp') return 'oneTimeCode';
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import { Form, type FormFieldConfig, type FormValues } from '../../components/form';
|
|
4
3
|
import { Button } from '../../features/button/public';
|
|
5
4
|
import { Stack } from '../../features/layout/public';
|
|
6
5
|
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
6
|
+
import type { FormFieldConfig, FormValues } from '../../types/form';
|
|
7
|
+
import { AuthForm } from './AuthForm';
|
|
7
8
|
import type { ForgotPasswordFormProps } from './types';
|
|
8
9
|
import {
|
|
9
10
|
defaultIdentifiers,
|
|
@@ -56,7 +57,7 @@ function ForgotPasswordFormInner({
|
|
|
56
57
|
);
|
|
57
58
|
|
|
58
59
|
return (
|
|
59
|
-
<
|
|
60
|
+
<AuthForm
|
|
60
61
|
actions={
|
|
61
62
|
onSignIn ? (
|
|
62
63
|
<Stack direction="row" gap="s" wrap="wrap">
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import { Form, type FormFieldConfig, type FormValues } from '../../components/form';
|
|
4
3
|
import { Button } from '../../features/button/public';
|
|
5
4
|
import { Stack } from '../../features/layout/public';
|
|
6
5
|
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
6
|
+
import type { FormFieldConfig, FormValues } from '../../types/form';
|
|
7
|
+
import { AuthForm } from './AuthForm';
|
|
7
8
|
import type { OtpFormProps } from './types';
|
|
8
9
|
|
|
9
10
|
type OtpFieldName = 'otp';
|
|
@@ -51,7 +52,7 @@ function OtpFormInner({
|
|
|
51
52
|
);
|
|
52
53
|
|
|
53
54
|
return (
|
|
54
|
-
<
|
|
55
|
+
<AuthForm
|
|
55
56
|
actions={
|
|
56
57
|
onResend ? (
|
|
57
58
|
<Stack direction="row" gap="s" wrap="wrap">
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import { Form, type FormFieldConfig, type FormValues } from '../../components/form';
|
|
4
3
|
import { Button } from '../../features/button/public';
|
|
5
4
|
import { Stack } from '../../features/layout/public';
|
|
6
5
|
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
6
|
+
import type { FormFieldConfig, FormValues } from '../../types/form';
|
|
7
|
+
import { AuthForm } from './AuthForm';
|
|
7
8
|
import type { SignInFormProps } from './types';
|
|
8
9
|
import {
|
|
9
10
|
defaultIdentifiers,
|
|
@@ -68,7 +69,7 @@ function SignInFormInner({
|
|
|
68
69
|
);
|
|
69
70
|
|
|
70
71
|
return (
|
|
71
|
-
<
|
|
72
|
+
<AuthForm
|
|
72
73
|
actions={
|
|
73
74
|
hasActions ? (
|
|
74
75
|
<Stack direction="row" gap="s" wrap="wrap">
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import { Form, type FormFieldConfig, type FormValues } from '../../components/form';
|
|
4
3
|
import { Button } from '../../features/button/public';
|
|
5
4
|
import { Stack } from '../../features/layout/public';
|
|
6
5
|
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
6
|
+
import type { FormFieldConfig, FormValues } from '../../types/form';
|
|
7
|
+
import { AuthForm } from './AuthForm';
|
|
7
8
|
import type { SignUpFormProps } from './types';
|
|
8
9
|
|
|
9
10
|
const defaultSignUpFields = [
|
|
@@ -48,7 +49,7 @@ function SignUpFormInner({
|
|
|
48
49
|
const [values, setValues] = React.useState<FormValues>(() => createValues(fields));
|
|
49
50
|
|
|
50
51
|
return (
|
|
51
|
-
<
|
|
52
|
+
<AuthForm
|
|
52
53
|
actions={
|
|
53
54
|
onSignIn ? (
|
|
54
55
|
<Stack direction="row" gap="s" wrap="wrap">
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { ButtonIconSpec } from '@ankhorage/surface';
|
|
2
2
|
import type React from 'react';
|
|
3
3
|
|
|
4
|
-
import type { FormFieldConfig, FormValues } from '../../components/form';
|
|
5
4
|
import type { ButtonProps } from '../../features/button/public';
|
|
6
5
|
import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
|
|
6
|
+
import type { FormFieldConfig, FormValues } from '../../types/form';
|
|
7
7
|
|
|
8
8
|
export type AuthIdentifierKind = 'email' | 'phone' | 'username';
|
|
9
9
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FormFieldConfig, ValidationRule } from '../../
|
|
1
|
+
import type { FormFieldConfig, ValidationRule } from '../../types/form';
|
|
2
2
|
import type { AuthIdentifierKind } from './types';
|
|
3
3
|
|
|
4
4
|
export const defaultIdentifiers = ['email'] as const satisfies readonly AuthIdentifierKind[];
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
+
import { FormField } from '../../features/form/public';
|
|
3
4
|
import { Box, Stack } from '../../features/layout/public';
|
|
4
5
|
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
5
|
-
import { FormField } from '../form-field';
|
|
6
6
|
import type { InspectorFieldProps } from './types';
|
|
7
7
|
|
|
8
8
|
function InspectorFieldInner({
|
|
@@ -9,6 +9,6 @@ test('passes the isolated Surface 4 and RN Web 0.21 acceptance suite', () => {
|
|
|
9
9
|
const output = `${subprocess.stdout.toString()}\n${subprocess.stderr.toString()}`;
|
|
10
10
|
|
|
11
11
|
expect(subprocess.exitCode, output).toBe(0);
|
|
12
|
-
expect(output).toContain('
|
|
12
|
+
expect(output).toContain('10 pass');
|
|
13
13
|
expect(output).toContain('0 fail');
|
|
14
14
|
});
|
package/src/registry.ts
CHANGED
|
@@ -4,7 +4,6 @@ import type React from 'react';
|
|
|
4
4
|
import { AppBar } from './components/app-bar';
|
|
5
5
|
import { Breadcrumbs } from './components/breadcrumbs';
|
|
6
6
|
import { DatePicker } from './components/date-picker';
|
|
7
|
-
import { Form, FormActions, FormError, FormField } from './components/form';
|
|
8
7
|
import { Gradient } from './components/gradient';
|
|
9
8
|
import { DropdownMenu, Menu } from './components/menu';
|
|
10
9
|
import { Modal } from './components/modal';
|
|
@@ -35,15 +34,16 @@ import { ChipGroup } from './features/chip/public';
|
|
|
35
34
|
import { DataTable } from './features/data-table/public';
|
|
36
35
|
import { EmptyState } from './features/empty-state/public';
|
|
37
36
|
import { Checkbox, CheckboxGroup } from './features/form/checkbox/public';
|
|
37
|
+
import { Form, FormActions, FormError, FormField } from './features/form/public';
|
|
38
38
|
import { Radio, RadioGroup } from './features/form/radio/public';
|
|
39
39
|
import { TextInput } from './features/form/text-input/public';
|
|
40
40
|
import { Icon } from './features/icon/public';
|
|
41
41
|
import { Image } from './features/image/public';
|
|
42
|
+
import { KeyboardAvoidingView } from './features/keyboard-avoiding-view/public';
|
|
42
43
|
import { Box, Container, Divider, Grid, Stack } from './features/layout/public';
|
|
43
44
|
import { ContentRail } from './features/layout/public';
|
|
44
45
|
import { FlatList, SectionList } from './features/list/public';
|
|
45
46
|
import { Progress, ProgressRing } from './features/progress/public';
|
|
46
|
-
import { SplashScreen } from './features/splash-screen/public';
|
|
47
47
|
import { Surface } from './features/surface/public';
|
|
48
48
|
import { Heading } from './features/typography/public';
|
|
49
49
|
import { Text } from './features/typography/public';
|
|
@@ -138,6 +138,7 @@ const _ZORA_COMPONENT_REGISTRY = {
|
|
|
138
138
|
Icon,
|
|
139
139
|
IconButton,
|
|
140
140
|
Image,
|
|
141
|
+
KeyboardAvoidingView,
|
|
141
142
|
TextInput,
|
|
142
143
|
MediaCard,
|
|
143
144
|
Menu,
|
|
@@ -155,7 +156,6 @@ const _ZORA_COMPONENT_REGISTRY = {
|
|
|
155
156
|
SkeletonCard,
|
|
156
157
|
SkeletonList,
|
|
157
158
|
SkeletonText,
|
|
158
|
-
SplashScreen,
|
|
159
159
|
Tabs,
|
|
160
160
|
Text,
|
|
161
161
|
TimePicker,
|
|
@@ -65,10 +65,10 @@ const scopedComponentFiles = [
|
|
|
65
65
|
join(srcDir, 'features', 'card', 'adapters', 'inbound', 'MetricCard.tsx'),
|
|
66
66
|
join(srcDir, 'features', 'form', 'checkbox', 'adapters', 'inbound', 'Checkbox.tsx'),
|
|
67
67
|
join(srcDir, 'features', 'form', 'checkbox', 'adapters', 'inbound', 'CheckboxGroup.tsx'),
|
|
68
|
-
join(srcDir, '
|
|
69
|
-
join(srcDir, '
|
|
70
|
-
join(srcDir, '
|
|
71
|
-
join(srcDir, '
|
|
68
|
+
join(srcDir, 'features', 'form', 'adapters', 'inbound', 'Form.tsx'),
|
|
69
|
+
join(srcDir, 'features', 'form', 'adapters', 'inbound', 'FormActions.tsx'),
|
|
70
|
+
join(srcDir, 'features', 'form', 'adapters', 'inbound', 'FormError.tsx'),
|
|
71
|
+
join(srcDir, 'features', 'form', 'adapters', 'inbound', 'FormField.tsx'),
|
|
72
72
|
join(srcDir, 'features', 'typography', 'adapters', 'inbound', 'Heading.tsx'),
|
|
73
73
|
join(srcDir, 'features', 'icon', 'adapters', 'inbound', 'Icon.tsx'),
|
|
74
74
|
join(srcDir, 'features', 'button', 'adapters', 'inbound', 'IconButton.tsx'),
|
|
@@ -99,7 +99,6 @@ const scopedComponentFiles = [
|
|
|
99
99
|
join(srcDir, 'patterns', 'confirm-dialog', 'ConfirmDialog.tsx'),
|
|
100
100
|
join(srcDir, 'patterns', 'disclosure-section', 'DisclosureSection.tsx'),
|
|
101
101
|
join(srcDir, 'features', 'empty-state', 'adapters', 'inbound', 'EmptyState.tsx'),
|
|
102
|
-
join(srcDir, 'patterns', 'form-field', 'FormField.tsx'),
|
|
103
102
|
join(srcDir, 'patterns', 'inspector-field', 'InspectorField.tsx'),
|
|
104
103
|
join(srcDir, 'patterns', 'list', 'List.tsx'),
|
|
105
104
|
join(srcDir, 'patterns', 'list', 'ListRow.tsx'),
|
|
@@ -136,7 +135,7 @@ const scopedPropTypeFiles = [
|
|
|
136
135
|
join(srcDir, 'types', 'media-card.ts'),
|
|
137
136
|
join(srcDir, 'types', 'metric-card.ts'),
|
|
138
137
|
join(srcDir, 'types', 'checkbox.ts'),
|
|
139
|
-
join(srcDir, '
|
|
138
|
+
join(srcDir, 'types', 'form.ts'),
|
|
140
139
|
join(srcDir, 'types', 'heading.ts'),
|
|
141
140
|
join(srcDir, 'types', 'icon.ts'),
|
|
142
141
|
join(srcDir, 'types', 'icon-button.ts'),
|
|
@@ -162,7 +161,6 @@ const scopedPropTypeFiles = [
|
|
|
162
161
|
join(srcDir, 'patterns', 'confirm-dialog', 'types.ts'),
|
|
163
162
|
join(srcDir, 'patterns', 'disclosure-section', 'types.ts'),
|
|
164
163
|
join(srcDir, 'types', 'empty-state.ts'),
|
|
165
|
-
join(srcDir, 'patterns', 'form-field', 'types.ts'),
|
|
166
164
|
join(srcDir, 'patterns', 'inspector-field', 'types.ts'),
|
|
167
165
|
join(srcDir, 'patterns', 'list', 'types.ts'),
|
|
168
166
|
join(srcDir, 'patterns', 'notice', 'types.ts'),
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import type { FieldProps as SurfaceFieldProps } from '@ankhorage/surface';
|
|
2
2
|
import type React from 'react';
|
|
3
3
|
|
|
4
|
-
import type { ZoraBaseProps } from '
|
|
5
|
-
import type { TextInputProps } from '
|
|
4
|
+
import type { ZoraBaseProps } from '../theme/ZoraBaseProps';
|
|
5
|
+
import type { TextInputProps } from './text-input';
|
|
6
6
|
|
|
7
7
|
export type ValidationRule =
|
|
8
8
|
| { kind: 'required'; message?: string }
|
|
9
9
|
| { kind: 'email'; message?: string }
|
|
10
10
|
| { kind: 'minLength'; value: number; message?: string }
|
|
11
11
|
| { kind: 'pattern'; value: string; message?: string };
|
|
12
|
-
|
|
13
12
|
export type FormFieldValue = string;
|
|
14
13
|
export type FormValues<TName extends string = string> = Record<TName, FormFieldValue>;
|
|
15
14
|
export type FormErrors<TName extends string = string> = Partial<Record<TName, React.ReactNode>>;
|
|
16
15
|
export type FormValidationErrors<TName extends string = string> = Partial<Record<TName, string>>;
|
|
17
|
-
|
|
18
16
|
export type FormFieldInputType = 'email' | 'number' | 'otp' | 'password' | 'tel' | 'text' | 'url';
|
|
19
17
|
|
|
20
18
|
export interface FormFieldConfig<TName extends string = string> {
|
|
@@ -37,7 +35,16 @@ export interface FormFieldConfig<TName extends string = string> {
|
|
|
37
35
|
testID?: string;
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
interface
|
|
38
|
+
export interface FormProps extends ZoraBaseProps {
|
|
39
|
+
children?: React.ReactNode;
|
|
40
|
+
onSubmit?: () => void | Promise<void>;
|
|
41
|
+
loading?: boolean;
|
|
42
|
+
disabled?: boolean;
|
|
43
|
+
submitLabel?: React.ReactNode;
|
|
44
|
+
actions?: React.ReactNode;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface FormFieldProps
|
|
41
48
|
extends
|
|
42
49
|
ZoraBaseProps,
|
|
43
50
|
Pick<
|
|
@@ -49,18 +56,6 @@ interface FormFieldWrapperProps
|
|
|
49
56
|
helperText?: React.ReactNode;
|
|
50
57
|
}
|
|
51
58
|
|
|
52
|
-
export interface FormFieldControlProps<TName extends string = string> extends ZoraBaseProps {
|
|
53
|
-
field: FormFieldConfig<TName>;
|
|
54
|
-
value: FormFieldValue;
|
|
55
|
-
onChange: (name: TName, value: FormFieldValue) => void;
|
|
56
|
-
error?: React.ReactNode;
|
|
57
|
-
disabled?: boolean;
|
|
58
|
-
loading?: boolean;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export type FormFieldProps<TName extends string = string> =
|
|
62
|
-
FormFieldControlProps<TName> | FormFieldWrapperProps;
|
|
63
|
-
|
|
64
59
|
export interface FormActionsProps extends ZoraBaseProps {
|
|
65
60
|
submitLabel?: React.ReactNode;
|
|
66
61
|
loading?: boolean;
|
|
@@ -68,31 +63,13 @@ export interface FormActionsProps extends ZoraBaseProps {
|
|
|
68
63
|
onSubmit?: () => void;
|
|
69
64
|
children?: React.ReactNode;
|
|
70
65
|
}
|
|
71
|
-
|
|
72
66
|
export interface FormErrorProps extends ZoraBaseProps {
|
|
73
67
|
error?: React.ReactNode;
|
|
74
68
|
}
|
|
75
|
-
|
|
76
|
-
export interface FormProps<TName extends string = string> extends ZoraBaseProps {
|
|
77
|
-
fields: readonly FormFieldConfig<TName>[];
|
|
78
|
-
values: FormValues<TName>;
|
|
79
|
-
onChange: (values: FormValues<TName>) => void;
|
|
80
|
-
onSubmit: (values: FormValues<TName>) => void | Promise<void>;
|
|
81
|
-
errors?: FormErrors<TName>;
|
|
82
|
-
error?: React.ReactNode;
|
|
83
|
-
loading?: boolean;
|
|
84
|
-
disabled?: boolean;
|
|
85
|
-
submitLabel?: React.ReactNode;
|
|
86
|
-
actions?: React.ReactNode;
|
|
87
|
-
footer?: React.ReactNode;
|
|
88
|
-
validateOnChange?: boolean;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
69
|
export interface FormValidationResult<TName extends string = string> {
|
|
92
70
|
errors: FormValidationErrors<TName>;
|
|
93
71
|
valid: boolean;
|
|
94
72
|
}
|
|
95
|
-
|
|
96
73
|
export interface UseFormControllerOptions<TName extends string = string> {
|
|
97
74
|
fields: readonly FormFieldConfig<TName>[];
|
|
98
75
|
initialValues?: Partial<FormValues<TName>>;
|
|
@@ -102,7 +79,6 @@ export interface UseFormControllerOptions<TName extends string = string> {
|
|
|
102
79
|
onSubmit?: (values: FormValues<TName>) => void | Promise<void>;
|
|
103
80
|
validateOnChange?: boolean;
|
|
104
81
|
}
|
|
105
|
-
|
|
106
82
|
export interface UseFormControllerResult<TName extends string = string> {
|
|
107
83
|
values: FormValues<TName>;
|
|
108
84
|
errors: FormErrors<TName>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { KeyboardAvoidingViewProps as SurfaceKeyboardAvoidingViewProps } from '@ankhorage/surface';
|
|
2
|
+
|
|
3
|
+
import type { ZoraBaseProps } from '../theme/ZoraBaseProps';
|
|
4
|
+
|
|
5
|
+
export type KeyboardAvoidingViewBehavior = NonNullable<
|
|
6
|
+
SurfaceKeyboardAvoidingViewProps['behavior']
|
|
7
|
+
>;
|
|
8
|
+
|
|
9
|
+
export interface KeyboardAvoidingViewProps
|
|
10
|
+
extends ZoraBaseProps, Omit<SurfaceKeyboardAvoidingViewProps, keyof ZoraBaseProps> {}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { FormProps } from './types';
|
|
3
|
-
/***
|
|
4
|
-
* Composes fields and actions into a validated form layout.
|
|
5
|
-
*/
|
|
6
|
-
export declare const Form: <TName extends string = string>(props: FormProps<TName>) => React.ReactElement | null;
|
|
7
|
-
//# sourceMappingURL=Form.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Form.d.ts","sourceRoot":"","sources":["../../../src/components/form/Form.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AA+DzC;;GAEG;AACH,eAAO,MAAM,IAAI,GA/DE,KAAK,SAAS,MAAM,gEA+DU,CAAC"}
|