@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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { FieldProps as SurfaceFieldProps } from '@ankhorage/surface';
|
|
2
2
|
import type React from 'react';
|
|
3
|
-
import type { ZoraBaseProps } from '
|
|
4
|
-
import type { TextInputProps } from '
|
|
3
|
+
import type { ZoraBaseProps } from '../theme/ZoraBaseProps';
|
|
4
|
+
import type { TextInputProps } from './text-input';
|
|
5
5
|
export type ValidationRule = {
|
|
6
6
|
kind: 'required';
|
|
7
7
|
message?: string;
|
|
@@ -41,20 +41,19 @@ export interface FormFieldConfig<TName extends string = string> {
|
|
|
41
41
|
disabled?: boolean;
|
|
42
42
|
testID?: string;
|
|
43
43
|
}
|
|
44
|
-
interface
|
|
44
|
+
export interface FormProps extends ZoraBaseProps {
|
|
45
|
+
children?: React.ReactNode;
|
|
46
|
+
onSubmit?: () => void | Promise<void>;
|
|
47
|
+
loading?: boolean;
|
|
48
|
+
disabled?: boolean;
|
|
49
|
+
submitLabel?: React.ReactNode;
|
|
50
|
+
actions?: React.ReactNode;
|
|
51
|
+
}
|
|
52
|
+
export interface FormFieldProps extends ZoraBaseProps, Pick<Omit<SurfaceFieldProps, 'mode' | 'themeId'>, 'children' | 'disabled' | 'errorText' | 'invalid' | 'readOnly' | 'required'> {
|
|
45
53
|
label: React.ReactNode;
|
|
46
54
|
description?: React.ReactNode;
|
|
47
55
|
helperText?: React.ReactNode;
|
|
48
56
|
}
|
|
49
|
-
export interface FormFieldControlProps<TName extends string = string> extends ZoraBaseProps {
|
|
50
|
-
field: FormFieldConfig<TName>;
|
|
51
|
-
value: FormFieldValue;
|
|
52
|
-
onChange: (name: TName, value: FormFieldValue) => void;
|
|
53
|
-
error?: React.ReactNode;
|
|
54
|
-
disabled?: boolean;
|
|
55
|
-
loading?: boolean;
|
|
56
|
-
}
|
|
57
|
-
export type FormFieldProps<TName extends string = string> = FormFieldControlProps<TName> | FormFieldWrapperProps;
|
|
58
57
|
export interface FormActionsProps extends ZoraBaseProps {
|
|
59
58
|
submitLabel?: React.ReactNode;
|
|
60
59
|
loading?: boolean;
|
|
@@ -65,20 +64,6 @@ export interface FormActionsProps extends ZoraBaseProps {
|
|
|
65
64
|
export interface FormErrorProps extends ZoraBaseProps {
|
|
66
65
|
error?: React.ReactNode;
|
|
67
66
|
}
|
|
68
|
-
export interface FormProps<TName extends string = string> extends ZoraBaseProps {
|
|
69
|
-
fields: readonly FormFieldConfig<TName>[];
|
|
70
|
-
values: FormValues<TName>;
|
|
71
|
-
onChange: (values: FormValues<TName>) => void;
|
|
72
|
-
onSubmit: (values: FormValues<TName>) => void | Promise<void>;
|
|
73
|
-
errors?: FormErrors<TName>;
|
|
74
|
-
error?: React.ReactNode;
|
|
75
|
-
loading?: boolean;
|
|
76
|
-
disabled?: boolean;
|
|
77
|
-
submitLabel?: React.ReactNode;
|
|
78
|
-
actions?: React.ReactNode;
|
|
79
|
-
footer?: React.ReactNode;
|
|
80
|
-
validateOnChange?: boolean;
|
|
81
|
-
}
|
|
82
67
|
export interface FormValidationResult<TName extends string = string> {
|
|
83
68
|
errors: FormValidationErrors<TName>;
|
|
84
69
|
valid: boolean;
|
|
@@ -101,5 +86,4 @@ export interface UseFormControllerResult<TName extends string = string> {
|
|
|
101
86
|
handleSubmit: () => Promise<void>;
|
|
102
87
|
reset: () => void;
|
|
103
88
|
}
|
|
104
|
-
|
|
105
|
-
//# sourceMappingURL=types.d.ts.map
|
|
89
|
+
//# sourceMappingURL=form.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../../src/types/form.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form.js","sourceRoot":"","sources":["../../src/types/form.ts"],"names":[],"mappings":"","sourcesContent":["import type { FieldProps as SurfaceFieldProps } from '@ankhorage/surface';\nimport type React from 'react';\n\nimport type { ZoraBaseProps } from '../theme/ZoraBaseProps';\nimport type { TextInputProps } from './text-input';\n\nexport type ValidationRule =\n | { kind: 'required'; message?: string }\n | { kind: 'email'; message?: string }\n | { kind: 'minLength'; value: number; message?: string }\n | { kind: 'pattern'; value: string; message?: string };\nexport type FormFieldValue = string;\nexport type FormValues<TName extends string = string> = Record<TName, FormFieldValue>;\nexport type FormErrors<TName extends string = string> = Partial<Record<TName, React.ReactNode>>;\nexport type FormValidationErrors<TName extends string = string> = Partial<Record<TName, string>>;\nexport type FormFieldInputType = 'email' | 'number' | 'otp' | 'password' | 'tel' | 'text' | 'url';\n\nexport interface FormFieldConfig<TName extends string = string> {\n name: TName;\n label: React.ReactNode;\n description?: React.ReactNode;\n helperText?: React.ReactNode;\n type?: FormFieldInputType;\n placeholder?: string;\n rules?: readonly ValidationRule[];\n autoCapitalize?: TextInputProps['autoCapitalize'];\n autoComplete?: TextInputProps['autoComplete'];\n keyboardType?: TextInputProps['keyboardType'];\n maxLength?: TextInputProps['maxLength'];\n readOnly?: boolean;\n required?: boolean;\n secureTextEntry?: boolean;\n textContentType?: TextInputProps['textContentType'];\n disabled?: boolean;\n testID?: string;\n}\n\nexport interface FormProps extends ZoraBaseProps {\n children?: React.ReactNode;\n onSubmit?: () => void | Promise<void>;\n loading?: boolean;\n disabled?: boolean;\n submitLabel?: React.ReactNode;\n actions?: React.ReactNode;\n}\n\nexport interface FormFieldProps\n extends\n ZoraBaseProps,\n Pick<\n Omit<SurfaceFieldProps, 'mode' | 'themeId'>,\n 'children' | 'disabled' | 'errorText' | 'invalid' | 'readOnly' | 'required'\n > {\n label: React.ReactNode;\n description?: React.ReactNode;\n helperText?: React.ReactNode;\n}\n\nexport interface FormActionsProps extends ZoraBaseProps {\n submitLabel?: React.ReactNode;\n loading?: boolean;\n disabled?: boolean;\n onSubmit?: () => void;\n children?: React.ReactNode;\n}\nexport interface FormErrorProps extends ZoraBaseProps {\n error?: React.ReactNode;\n}\nexport interface FormValidationResult<TName extends string = string> {\n errors: FormValidationErrors<TName>;\n valid: boolean;\n}\nexport interface UseFormControllerOptions<TName extends string = string> {\n fields: readonly FormFieldConfig<TName>[];\n initialValues?: Partial<FormValues<TName>>;\n values?: FormValues<TName>;\n errors?: FormErrors<TName>;\n onChange?: (values: FormValues<TName>) => void;\n onSubmit?: (values: FormValues<TName>) => void | Promise<void>;\n validateOnChange?: boolean;\n}\nexport interface UseFormControllerResult<TName extends string = string> {\n values: FormValues<TName>;\n errors: FormErrors<TName>;\n setValues: (values: FormValues<TName>) => void;\n setFieldValue: (name: TName, value: FormFieldValue) => void;\n validate: () => FormValidationResult<TName>;\n handleSubmit: () => Promise<void>;\n reset: () => void;\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { KeyboardAvoidingViewProps as SurfaceKeyboardAvoidingViewProps } from '@ankhorage/surface';
|
|
2
|
+
import type { ZoraBaseProps } from '../theme/ZoraBaseProps';
|
|
3
|
+
export type KeyboardAvoidingViewBehavior = NonNullable<SurfaceKeyboardAvoidingViewProps['behavior']>;
|
|
4
|
+
export interface KeyboardAvoidingViewProps extends ZoraBaseProps, Omit<SurfaceKeyboardAvoidingViewProps, keyof ZoraBaseProps> {
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=keyboard-avoiding-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboard-avoiding-view.d.ts","sourceRoot":"","sources":["../../src/types/keyboard-avoiding-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,IAAI,gCAAgC,EAAE,MAAM,oBAAoB,CAAC;AAExG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,MAAM,4BAA4B,GAAG,WAAW,CACpD,gCAAgC,CAAC,UAAU,CAAC,CAC7C,CAAC;AAEF,MAAM,WAAW,yBACf,SAAQ,aAAa,EAAE,IAAI,CAAC,gCAAgC,EAAE,MAAM,aAAa,CAAC;CAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboard-avoiding-view.js","sourceRoot":"","sources":["../../src/types/keyboard-avoiding-view.ts"],"names":[],"mappings":"","sourcesContent":["import type { KeyboardAvoidingViewProps as SurfaceKeyboardAvoidingViewProps } from '@ankhorage/surface';\n\nimport type { ZoraBaseProps } from '../theme/ZoraBaseProps';\n\nexport type KeyboardAvoidingViewBehavior = NonNullable<\n SurfaceKeyboardAvoidingViewProps['behavior']\n>;\n\nexport interface KeyboardAvoidingViewProps\n extends ZoraBaseProps, Omit<SurfaceKeyboardAvoidingViewProps, keyof ZoraBaseProps> {}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/zora",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "11.0.0",
|
|
5
5
|
"description": "Opinionated React Native and React Native Web UI kit built on @ankhorage/surface.",
|
|
6
6
|
"homepage": "https://github.com/ankhorage/zora#readme",
|
|
7
7
|
"bugs": {
|
|
@@ -42,7 +42,8 @@
|
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@ankhorage/color-theory": "^0.3.0",
|
|
44
44
|
"@ankhorage/contracts": "^12.0.1",
|
|
45
|
-
"@ankhorage/surface": "^4.
|
|
45
|
+
"@ankhorage/surface": "^4.2.0",
|
|
46
|
+
"@ankhorage/utility": "^0.8.0",
|
|
46
47
|
"expo-document-picker": "~57.0.1",
|
|
47
48
|
"expo-image-picker": "~57.0.16"
|
|
48
49
|
},
|
package/src/audit.test.ts
CHANGED
|
@@ -141,17 +141,15 @@ describe('Plan 5 audit — product-facing src imports ZORA foundation, not Surfa
|
|
|
141
141
|
join(SRC_ROOT, 'components', 'modal', 'Modal.tsx'),
|
|
142
142
|
join(SRC_ROOT, 'features', 'form', 'text-input', 'adapters', 'inbound', 'TextInput.tsx'),
|
|
143
143
|
join(SRC_ROOT, 'features', 'typography', 'adapters', 'inbound', 'Text.tsx'),
|
|
144
|
-
join(SRC_ROOT, '
|
|
145
|
-
join(SRC_ROOT, 'patterns', 'form-field', 'FormField.tsx'),
|
|
144
|
+
join(SRC_ROOT, 'features', 'form', 'adapters', 'inbound', 'FormField.tsx'),
|
|
146
145
|
// Type-only imports that intentionally expose Surface-compatible prop specs.
|
|
147
146
|
join(SRC_ROOT, 'components', 'checkbox', 'types.ts'),
|
|
148
|
-
join(SRC_ROOT, '
|
|
147
|
+
join(SRC_ROOT, 'types', 'form.ts'),
|
|
149
148
|
join(SRC_ROOT, 'types', 'icon-button.ts'),
|
|
150
149
|
join(SRC_ROOT, 'components', 'tabs', 'types.ts'),
|
|
151
150
|
join(SRC_ROOT, 'types', 'text.ts'),
|
|
152
151
|
join(SRC_ROOT, 'components', 'textarea', 'types.ts'),
|
|
153
152
|
join(SRC_ROOT, 'components', 'toolbar', 'types.ts'),
|
|
154
|
-
join(SRC_ROOT, 'patterns', 'form-field', 'types.ts'),
|
|
155
153
|
join(SRC_ROOT, 'patterns', 'tile-grid', 'types.ts'),
|
|
156
154
|
]);
|
|
157
155
|
|
package/src/constants.ts
CHANGED
|
@@ -11,12 +11,13 @@ export const FEATURE_MANIFEST_ELEMENTS = {
|
|
|
11
11
|
card: ['Card', 'MediaCard', 'MetricCard', 'PostCard', 'ProductCard'],
|
|
12
12
|
chip: ['Chip', 'ChipGroup'],
|
|
13
13
|
'data-table': ['DataTable'],
|
|
14
|
+
form: ['Form', 'FormError', 'FormField'],
|
|
14
15
|
button: ['Button', 'IconButton', 'ButtonGroup'],
|
|
15
16
|
icon: ['Icon'],
|
|
16
17
|
image: ['Image'],
|
|
18
|
+
'keyboard-avoiding-view': ['KeyboardAvoidingView'],
|
|
17
19
|
layout: ['Box', 'Container', 'ContentRail', 'Divider', 'Grid', 'Stack'],
|
|
18
20
|
list: ['FlatList', 'SectionList'],
|
|
19
|
-
'splash-screen': ['SplashScreen'],
|
|
20
21
|
typography: ['Heading', 'Text'],
|
|
21
22
|
uploader: ['Uploader'],
|
|
22
23
|
'bottom-sheet': ['BottomSheet'],
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
|
|
1
3
|
import { expect, test } from 'bun:test';
|
|
2
4
|
|
|
3
5
|
import { FEATURE_MANIFEST_ELEMENTS } from './constants';
|
|
@@ -17,6 +19,11 @@ test('every selected feature element is directly authorable through its canonica
|
|
|
17
19
|
}
|
|
18
20
|
});
|
|
19
21
|
|
|
22
|
+
test('form composition has one canonical feature owner', () => {
|
|
23
|
+
expect(existsSync('src/components/form')).toBe(false);
|
|
24
|
+
expect(existsSync('src/patterns/form-field')).toBe(false);
|
|
25
|
+
});
|
|
26
|
+
|
|
20
27
|
test('interactive authoring retains state and event payload bindings after plugin composition', () => {
|
|
21
28
|
const meta = ZORA_CORE_PLUGIN_METADATA.componentMeta;
|
|
22
29
|
expect(meta.DataTable?.bindings?.props?.sort?.value.type).toBe('object');
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
|
|
4
|
+
import type { FormProps } from '../../../../types/form';
|
|
5
|
+
import { Stack } from '../../../layout/public';
|
|
6
|
+
import { FormActions } from './FormActions';
|
|
7
|
+
|
|
8
|
+
function FormInner({
|
|
9
|
+
themeId: _themeId,
|
|
10
|
+
mode: _mode,
|
|
11
|
+
children,
|
|
12
|
+
onSubmit,
|
|
13
|
+
loading = false,
|
|
14
|
+
disabled = false,
|
|
15
|
+
submitLabel = 'Submit',
|
|
16
|
+
actions,
|
|
17
|
+
testID,
|
|
18
|
+
interactionPolicy,
|
|
19
|
+
}: FormProps) {
|
|
20
|
+
return (
|
|
21
|
+
<Stack gap="m" testID={testID}>
|
|
22
|
+
{children}
|
|
23
|
+
<FormActions
|
|
24
|
+
disabled={disabled}
|
|
25
|
+
interactionPolicy={interactionPolicy}
|
|
26
|
+
loading={loading}
|
|
27
|
+
onSubmit={() => {
|
|
28
|
+
if (interactionPolicy !== 'passive') void onSubmit?.();
|
|
29
|
+
}}
|
|
30
|
+
submitLabel={submitLabel}
|
|
31
|
+
>
|
|
32
|
+
{actions}
|
|
33
|
+
</FormActions>
|
|
34
|
+
</Stack>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/*** Composes explicit form fields, form errors, and submit actions. */
|
|
39
|
+
export const Form = withZoraThemeScope(FormInner);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
3
|
+
import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
|
|
4
|
+
import type { FormActionsProps } from '../../../../types/form';
|
|
5
|
+
import { Button } from '../../../button/public';
|
|
6
|
+
import { Box, Stack } from '../../../layout/public';
|
|
7
7
|
|
|
8
8
|
function FormActionsInner({
|
|
9
9
|
themeId: _themeId,
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { useZoraTheme } from '../../../../theme/useZoraTheme';
|
|
4
|
+
import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
|
|
5
|
+
import type { FormErrorProps } from '../../../../types/form';
|
|
6
|
+
import { Box } from '../../../layout/public';
|
|
7
|
+
import { Text } from '../../../typography/public';
|
|
8
|
+
|
|
9
|
+
function FormErrorInner({ themeId: _themeId, mode: _mode, error, testID }: FormErrorProps) {
|
|
10
|
+
const { theme } = useZoraTheme();
|
|
11
|
+
if (!error) return null;
|
|
12
|
+
return (
|
|
13
|
+
<Box borderColor={theme.colors.error} borderWidth={1} p="s" radius="m" testID={testID}>
|
|
14
|
+
<Text color="error" variant="bodySmall">
|
|
15
|
+
{error}
|
|
16
|
+
</Text>
|
|
17
|
+
</Box>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/*** Displays a form-level validation or submission error. */
|
|
22
|
+
export const FormError = withZoraThemeScope(FormErrorInner);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Field } from '@ankhorage/surface';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
4
|
+
import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
|
|
5
|
+
import type { FormFieldProps } from '../../../../types/form';
|
|
6
|
+
import { Stack } from '../../../layout/public';
|
|
7
|
+
import { Text } from '../../../typography/public';
|
|
8
8
|
|
|
9
9
|
function FormFieldInner({
|
|
10
10
|
themeId: _themeId,
|
|
@@ -13,6 +13,7 @@ function FormFieldInner({
|
|
|
13
13
|
description,
|
|
14
14
|
helperText,
|
|
15
15
|
children,
|
|
16
|
+
interactionPolicy: _interactionPolicy,
|
|
16
17
|
...props
|
|
17
18
|
}: FormFieldProps) {
|
|
18
19
|
return (
|
|
@@ -37,4 +38,5 @@ function FormFieldInner({
|
|
|
37
38
|
);
|
|
38
39
|
}
|
|
39
40
|
|
|
41
|
+
/*** Groups one form control with its label, description, helper text, and field error. */
|
|
40
42
|
export const FormField = withZoraThemeScope(FormFieldInner);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ZoraComponentMeta } from '../../metadata';
|
|
2
|
+
export const formActionsMeta = {
|
|
3
|
+
name: 'FormActions',
|
|
4
|
+
category: 'component',
|
|
5
|
+
directManifestNode: false,
|
|
6
|
+
allowedChildren: [],
|
|
7
|
+
note: 'Internal form action helper.',
|
|
8
|
+
props: {},
|
|
9
|
+
} as const satisfies ZoraComponentMeta;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ZoraComponentMeta } from '../../metadata';
|
|
2
|
+
export const formErrorMeta = {
|
|
3
|
+
name: 'FormError',
|
|
4
|
+
category: 'component',
|
|
5
|
+
directManifestNode: true,
|
|
6
|
+
allowedChildren: [],
|
|
7
|
+
blueprint: { label: 'Form error', defaultProps: { error: 'Unable to submit the form.' } },
|
|
8
|
+
bindings: {
|
|
9
|
+
props: {
|
|
10
|
+
error: {
|
|
11
|
+
label: 'Error',
|
|
12
|
+
description: 'Global form or submission error.',
|
|
13
|
+
value: { type: 'unknown' },
|
|
14
|
+
acceptsFallback: true,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
props: { error: { type: 'string', category: 'Content', label: 'Error' } },
|
|
19
|
+
} as const satisfies ZoraComponentMeta;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ZoraComponentMeta } from '../../metadata';
|
|
2
|
+
export const formFieldMeta = {
|
|
3
|
+
name: 'FormField',
|
|
4
|
+
category: 'component',
|
|
5
|
+
directManifestNode: true,
|
|
6
|
+
allowedChildren: ['Checkbox', 'CheckboxGroup', 'RadioGroup', 'TextInput'],
|
|
7
|
+
blueprint: { label: 'Form field', defaultProps: { label: 'Label' } },
|
|
8
|
+
bindings: {
|
|
9
|
+
props: {
|
|
10
|
+
errorText: {
|
|
11
|
+
label: 'Error text',
|
|
12
|
+
description: 'Field-level validation error.',
|
|
13
|
+
value: { type: 'unknown' },
|
|
14
|
+
acceptsFallback: true,
|
|
15
|
+
},
|
|
16
|
+
disabled: {
|
|
17
|
+
label: 'Disabled',
|
|
18
|
+
description: 'Whether the field is disabled.',
|
|
19
|
+
value: { type: 'boolean' },
|
|
20
|
+
acceptsFallback: true,
|
|
21
|
+
acceptsTransforms: true,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
props: {
|
|
26
|
+
label: { type: 'string', category: 'Content', label: 'Label', default: 'Label' },
|
|
27
|
+
description: { type: 'string', category: 'Content', label: 'Description' },
|
|
28
|
+
helperText: { type: 'string', category: 'Content', label: 'Helper text' },
|
|
29
|
+
errorText: { type: 'string', category: 'Validation', label: 'Error text' },
|
|
30
|
+
required: { type: 'boolean', category: 'Validation', label: 'Required', default: false },
|
|
31
|
+
invalid: { type: 'boolean', category: 'Validation', label: 'Invalid', default: false },
|
|
32
|
+
disabled: { type: 'boolean', category: 'State', label: 'Disabled', default: false },
|
|
33
|
+
readOnly: { type: 'boolean', category: 'State', label: 'Read-only', default: false },
|
|
34
|
+
},
|
|
35
|
+
} as const satisfies ZoraComponentMeta;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ZoraComponentMeta } from '../../metadata';
|
|
2
|
+
export const formMeta = {
|
|
3
|
+
name: 'Form',
|
|
4
|
+
category: 'component',
|
|
5
|
+
directManifestNode: true,
|
|
6
|
+
allowedChildren: ['FormError', 'FormField'],
|
|
7
|
+
blueprint: {
|
|
8
|
+
label: 'Form',
|
|
9
|
+
defaultProps: { submitLabel: 'Submit', loading: false, disabled: false },
|
|
10
|
+
},
|
|
11
|
+
bindings: {
|
|
12
|
+
events: {
|
|
13
|
+
submit: {
|
|
14
|
+
label: 'Submit',
|
|
15
|
+
description: 'Runs when the form is submitted.',
|
|
16
|
+
payload: { eventType: 'form.submit', fields: [] },
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
events: {
|
|
21
|
+
submit: {
|
|
22
|
+
label: 'Submit',
|
|
23
|
+
eventType: 'form.submit',
|
|
24
|
+
description: 'Emitted when the form is submitted.',
|
|
25
|
+
payloadFields: [],
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
slots: { actions: { label: 'Actions', allowedChildren: ['Button', 'ButtonGroup'] } },
|
|
29
|
+
props: {
|
|
30
|
+
submitLabel: { type: 'string', category: 'Content', label: 'Submit label', default: 'Submit' },
|
|
31
|
+
loading: { type: 'boolean', category: 'State', label: 'Loading', default: false },
|
|
32
|
+
disabled: { type: 'boolean', category: 'State', label: 'Disabled', default: false },
|
|
33
|
+
},
|
|
34
|
+
} as const satisfies ZoraComponentMeta;
|
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
export { Form } from './Form';
|
|
2
|
-
export { FormActions } from './FormActions';
|
|
3
|
-
export { FormError } from './FormError';
|
|
4
|
-
export { FormField } from './FormField';
|
|
5
1
|
export type {
|
|
6
2
|
FormActionsProps,
|
|
7
3
|
FormErrorProps,
|
|
8
4
|
FormErrors,
|
|
9
5
|
FormFieldConfig,
|
|
10
|
-
FormFieldControlProps,
|
|
11
6
|
FormFieldInputType,
|
|
12
7
|
FormFieldProps,
|
|
13
8
|
FormProps,
|
|
@@ -17,6 +12,10 @@ export type {
|
|
|
17
12
|
UseFormControllerOptions,
|
|
18
13
|
UseFormControllerResult,
|
|
19
14
|
ValidationRule,
|
|
20
|
-
} from '
|
|
15
|
+
} from '../../types/form';
|
|
16
|
+
export { Form } from './adapters/inbound/Form';
|
|
17
|
+
export { FormActions } from './adapters/inbound/FormActions';
|
|
18
|
+
export { FormError } from './adapters/inbound/FormError';
|
|
19
|
+
export { FormField } from './adapters/inbound/FormField';
|
|
21
20
|
export { useFormController } from './useFormController';
|
|
22
|
-
export { hasRequiredRule, validateField, validateFields, validateValue } from './validation';
|
|
21
|
+
export { hasRequiredRule, validateField, validateFields, validateValue } from './utils/validation';
|
|
@@ -6,8 +6,8 @@ import type {
|
|
|
6
6
|
FormValues,
|
|
7
7
|
UseFormControllerOptions,
|
|
8
8
|
UseFormControllerResult,
|
|
9
|
-
} from '
|
|
10
|
-
import { validateFields } from './validation';
|
|
9
|
+
} from '../../types/form';
|
|
10
|
+
import { validateFields } from './utils/validation';
|
|
11
11
|
|
|
12
12
|
function createInitialValues<TName extends string>(
|
|
13
13
|
fields: readonly { name: TName }[],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test } from 'bun:test';
|
|
2
2
|
|
|
3
|
-
import type { FormFieldConfig, FormValues } from '
|
|
3
|
+
import type { FormFieldConfig, FormValues } from '../../../types/form';
|
|
4
4
|
import { validateFields, validateValue } from './validation';
|
|
5
5
|
|
|
6
6
|
describe('form validation', () => {
|
|
@@ -12,6 +12,9 @@ describe('form validation', () => {
|
|
|
12
12
|
|
|
13
13
|
test('validates email fields', () => {
|
|
14
14
|
expect(validateValue('not-email', [{ kind: 'email' }])).toBe('Enter a valid email address.');
|
|
15
|
+
expect(validateValue('person@exam_ple.com', [{ kind: 'email' }])).toBe(
|
|
16
|
+
'Enter a valid email address.',
|
|
17
|
+
);
|
|
15
18
|
expect(validateValue('person@example.com', [{ kind: 'email' }])).toBeUndefined();
|
|
16
19
|
});
|
|
17
20
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import { isEmail } from '@ankhorage/utility/regex';
|
|
2
|
+
|
|
1
3
|
import type {
|
|
2
4
|
FormFieldConfig,
|
|
3
5
|
FormValidationErrors,
|
|
4
6
|
FormValidationResult,
|
|
5
7
|
FormValues,
|
|
6
8
|
ValidationRule,
|
|
7
|
-
} from '
|
|
8
|
-
|
|
9
|
-
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
9
|
+
} from '../../../types/form';
|
|
10
10
|
|
|
11
11
|
export function hasRequiredRule(rules: readonly ValidationRule[] | undefined): boolean {
|
|
12
12
|
return rules?.some((rule) => rule.kind === 'required') ?? false;
|
|
@@ -27,11 +27,7 @@ export function validateValue(
|
|
|
27
27
|
return rule.message ?? 'This field is required.';
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
if (
|
|
31
|
-
rule.kind === 'email' &&
|
|
32
|
-
normalizedValue.length > 0 &&
|
|
33
|
-
!emailPattern.test(normalizedValue)
|
|
34
|
-
) {
|
|
30
|
+
if (rule.kind === 'email' && normalizedValue.length > 0 && !isEmail(normalizedValue)) {
|
|
35
31
|
return rule.message ?? 'Enter a valid email address.';
|
|
36
32
|
}
|
|
37
33
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { KeyboardAvoidingView as SurfaceKeyboardAvoidingView } from '@ankhorage/surface';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
|
|
5
|
+
import type { KeyboardAvoidingViewProps } from '../../../../types/keyboard-avoiding-view';
|
|
6
|
+
|
|
7
|
+
/*** Native keyboard-aware container exposed through the canonical ZORA feature boundary. */
|
|
8
|
+
export const KeyboardAvoidingView = withZoraThemeScope(KeyboardAvoidingViewInner);
|
|
9
|
+
|
|
10
|
+
/*** Forwards React Native keyboard avoidance and view props without adding platform behavior. */
|
|
11
|
+
function KeyboardAvoidingViewInner({
|
|
12
|
+
themeId: _themeId,
|
|
13
|
+
mode: _mode,
|
|
14
|
+
interactionPolicy: _interactionPolicy,
|
|
15
|
+
...props
|
|
16
|
+
}: KeyboardAvoidingViewProps) {
|
|
17
|
+
return <SurfaceKeyboardAvoidingView {...props} />;
|
|
18
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { CONTAINER_ALLOWED_CHILDREN } from '../../metadata/allowedChildren';
|
|
2
|
+
import type { ZoraComponentMeta } from '../../metadata/types';
|
|
3
|
+
|
|
4
|
+
export const keyboardAvoidingViewMeta = {
|
|
5
|
+
name: 'KeyboardAvoidingView',
|
|
6
|
+
category: 'layout',
|
|
7
|
+
directManifestNode: true,
|
|
8
|
+
allowedChildren: [...CONTAINER_ALLOWED_CHILDREN],
|
|
9
|
+
blueprint: {
|
|
10
|
+
label: 'Keyboard avoiding view',
|
|
11
|
+
defaultProps: {
|
|
12
|
+
behavior: 'padding',
|
|
13
|
+
enabled: true,
|
|
14
|
+
keyboardVerticalOffset: 0,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
props: {
|
|
18
|
+
behavior: {
|
|
19
|
+
type: 'enum',
|
|
20
|
+
category: 'Behavior',
|
|
21
|
+
label: 'Behavior',
|
|
22
|
+
enum: ['height', 'position', 'padding'],
|
|
23
|
+
default: 'padding',
|
|
24
|
+
},
|
|
25
|
+
enabled: {
|
|
26
|
+
type: 'boolean',
|
|
27
|
+
category: 'Behavior',
|
|
28
|
+
label: 'Enabled',
|
|
29
|
+
default: true,
|
|
30
|
+
},
|
|
31
|
+
keyboardVerticalOffset: {
|
|
32
|
+
type: 'number',
|
|
33
|
+
category: 'Layout',
|
|
34
|
+
label: 'Keyboard vertical offset',
|
|
35
|
+
default: 0,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
} as const satisfies ZoraComponentMeta;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
3
|
import { Modal } from '../../../../components/modal';
|
|
4
|
-
import { FormField } from '../../../../patterns/form-field';
|
|
5
4
|
import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
|
|
6
5
|
import type { UploadAsset, UploaderProps, UploadType } from '../../../../types/upload';
|
|
7
6
|
import { Button } from '../../../button/public';
|
|
7
|
+
import { FormField } from '../../../form/public';
|
|
8
8
|
import { Icon } from '../../../icon/public';
|
|
9
9
|
import { Image } from '../../../image/public';
|
|
10
10
|
import { Box, Stack } from '../../../layout/public';
|
package/src/index.ts
CHANGED
|
@@ -4,33 +4,6 @@ export type { BreadcrumbItem, BreadcrumbsProps } from './components/breadcrumbs'
|
|
|
4
4
|
export { Breadcrumbs } from './components/breadcrumbs';
|
|
5
5
|
export type { DatePickerProps, DatePickerValue } from './components/date-picker';
|
|
6
6
|
export { DatePicker } from './components/date-picker';
|
|
7
|
-
export type {
|
|
8
|
-
FormActionsProps,
|
|
9
|
-
FormErrorProps,
|
|
10
|
-
FormErrors,
|
|
11
|
-
FormFieldConfig,
|
|
12
|
-
FormFieldControlProps,
|
|
13
|
-
FormFieldInputType,
|
|
14
|
-
FormFieldProps,
|
|
15
|
-
FormProps,
|
|
16
|
-
FormValidationErrors,
|
|
17
|
-
FormValidationResult,
|
|
18
|
-
FormValues,
|
|
19
|
-
UseFormControllerOptions,
|
|
20
|
-
UseFormControllerResult,
|
|
21
|
-
ValidationRule,
|
|
22
|
-
} from './components/form';
|
|
23
|
-
export {
|
|
24
|
-
Form,
|
|
25
|
-
FormActions,
|
|
26
|
-
FormError,
|
|
27
|
-
FormField,
|
|
28
|
-
hasRequiredRule,
|
|
29
|
-
useFormController,
|
|
30
|
-
validateField,
|
|
31
|
-
validateFields,
|
|
32
|
-
validateValue,
|
|
33
|
-
} from './components/form';
|
|
34
7
|
export type {
|
|
35
8
|
GradientColor,
|
|
36
9
|
GradientColors,
|
|
@@ -139,6 +112,32 @@ export {
|
|
|
139
112
|
type CheckboxGroupProps,
|
|
140
113
|
type CheckboxProps,
|
|
141
114
|
} from './features/form/checkbox/public';
|
|
115
|
+
export type {
|
|
116
|
+
FormActionsProps,
|
|
117
|
+
FormErrorProps,
|
|
118
|
+
FormErrors,
|
|
119
|
+
FormFieldConfig,
|
|
120
|
+
FormFieldInputType,
|
|
121
|
+
FormFieldProps,
|
|
122
|
+
FormProps,
|
|
123
|
+
FormValidationErrors,
|
|
124
|
+
FormValidationResult,
|
|
125
|
+
FormValues,
|
|
126
|
+
UseFormControllerOptions,
|
|
127
|
+
UseFormControllerResult,
|
|
128
|
+
ValidationRule,
|
|
129
|
+
} from './features/form/public';
|
|
130
|
+
export {
|
|
131
|
+
Form,
|
|
132
|
+
FormActions,
|
|
133
|
+
FormError,
|
|
134
|
+
FormField,
|
|
135
|
+
hasRequiredRule,
|
|
136
|
+
useFormController,
|
|
137
|
+
validateField,
|
|
138
|
+
validateFields,
|
|
139
|
+
validateValue,
|
|
140
|
+
} from './features/form/public';
|
|
142
141
|
export {
|
|
143
142
|
Radio,
|
|
144
143
|
RadioGroup,
|
|
@@ -155,6 +154,11 @@ export type { IconProps } from './features/icon/public';
|
|
|
155
154
|
export { Icon } from './features/icon/public';
|
|
156
155
|
export type { ImageFit, ImageProps, SurfaceImageSource } from './features/image/public';
|
|
157
156
|
export { Image } from './features/image/public';
|
|
157
|
+
export {
|
|
158
|
+
KeyboardAvoidingView,
|
|
159
|
+
type KeyboardAvoidingViewBehavior,
|
|
160
|
+
type KeyboardAvoidingViewProps,
|
|
161
|
+
} from './features/keyboard-avoiding-view/public';
|
|
158
162
|
export type {
|
|
159
163
|
BoxProps,
|
|
160
164
|
ContainerProps,
|
|
@@ -185,8 +189,6 @@ export {
|
|
|
185
189
|
ProgressRing,
|
|
186
190
|
type ProgressRingProps,
|
|
187
191
|
} from './features/progress/public';
|
|
188
|
-
export type { SplashScreenLogoShape, SplashScreenProps } from './features/splash-screen/public';
|
|
189
|
-
export { SplashScreen } from './features/splash-screen/public';
|
|
190
192
|
export type { SurfaceProps, SurfaceVariant } from './features/surface/public';
|
|
191
193
|
export { Surface } from './features/surface/public';
|
|
192
194
|
export type {
|