@ankhorage/zora 10.0.0 → 12.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 +20 -0
- package/README.md +2 -1
- package/dist/constants.d.ts +4 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +4 -0
- 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/data-table/adapters/inbound/DataTable.d.ts.map +1 -1
- package/dist/features/data-table/adapters/inbound/DataTable.js +1 -1
- package/dist/features/data-table/adapters/inbound/DataTable.js.map +1 -1
- package/dist/{components/date-picker → features/date-picker/adapters/inbound}/DatePicker.d.ts +1 -1
- package/dist/features/date-picker/adapters/inbound/DatePicker.d.ts.map +1 -0
- package/dist/{components/date-picker → features/date-picker/adapters/inbound}/DatePicker.js +23 -26
- package/dist/features/date-picker/adapters/inbound/DatePicker.js.map +1 -0
- package/dist/features/date-picker/datePickerMeta.d.ts +83 -0
- package/dist/features/date-picker/datePickerMeta.d.ts.map +1 -0
- package/dist/features/date-picker/datePickerMeta.js +57 -0
- package/dist/features/date-picker/datePickerMeta.js.map +1 -0
- package/dist/features/date-picker/public.d.ts +3 -0
- package/dist/features/date-picker/public.d.ts.map +1 -0
- package/dist/features/date-picker/public.js +2 -0
- package/dist/features/date-picker/public.js.map +1 -0
- package/dist/features/date-picker/utils/localDate.d.ts +5 -0
- package/dist/features/date-picker/utils/localDate.d.ts.map +1 -0
- package/dist/features/date-picker/utils/localDate.js +27 -0
- package/dist/features/date-picker/utils/localDate.js.map +1 -0
- 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/{patterns/hero → features/hero/adapters/inbound}/Hero.d.ts +1 -1
- package/dist/features/hero/adapters/inbound/Hero.d.ts.map +1 -0
- package/dist/{patterns/hero → features/hero/adapters/inbound}/Hero.js +5 -6
- package/dist/features/hero/adapters/inbound/Hero.js.map +1 -0
- package/dist/{patterns/hero/meta.d.ts → features/hero/heroMeta.d.ts} +1 -1
- package/dist/features/hero/heroMeta.d.ts.map +1 -0
- package/dist/{patterns/hero/meta.js → features/hero/heroMeta.js} +1 -1
- package/dist/features/hero/heroMeta.js.map +1 -0
- package/dist/features/hero/public.d.ts +3 -0
- package/dist/features/hero/public.d.ts.map +1 -0
- package/dist/features/hero/public.js +2 -0
- package/dist/features/hero/public.js.map +1 -0
- package/dist/features/keyboard-avoiding-view/keyboardAvoidingViewMeta.d.ts +1 -1
- 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/{patterns/missing-element → features/missing-element/adapters/inbound}/MissingElement.d.ts +1 -1
- package/dist/features/missing-element/adapters/inbound/MissingElement.d.ts.map +1 -0
- package/dist/{patterns/missing-element → features/missing-element/adapters/inbound}/MissingElement.js +5 -5
- package/dist/features/missing-element/adapters/inbound/MissingElement.js.map +1 -0
- package/dist/{patterns/missing-element/meta.d.ts → features/missing-element/missingElementMeta.d.ts} +1 -1
- package/dist/features/missing-element/missingElementMeta.d.ts.map +1 -0
- package/dist/{patterns/missing-element/meta.js → features/missing-element/missingElementMeta.js} +1 -1
- package/dist/features/missing-element/missingElementMeta.js.map +1 -0
- package/dist/features/missing-element/public.d.ts +3 -0
- package/dist/features/missing-element/public.d.ts.map +1 -0
- package/dist/features/missing-element/public.js +2 -0
- package/dist/features/missing-element/public.js.map +1 -0
- package/dist/{components/skeleton → features/skeleton/adapters/inbound}/Skeleton.d.ts +1 -1
- package/dist/features/skeleton/adapters/inbound/Skeleton.d.ts.map +1 -0
- package/dist/{components/skeleton → features/skeleton/adapters/inbound}/Skeleton.js +3 -3
- package/dist/features/skeleton/adapters/inbound/Skeleton.js.map +1 -0
- package/dist/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonCard.d.ts +1 -1
- package/dist/features/skeleton/adapters/inbound/SkeletonCard.d.ts.map +1 -0
- package/dist/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonCard.js +4 -4
- package/dist/features/skeleton/adapters/inbound/SkeletonCard.js.map +1 -0
- package/dist/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonList.d.ts +1 -1
- package/dist/features/skeleton/adapters/inbound/SkeletonList.d.ts.map +1 -0
- package/dist/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonList.js +2 -2
- package/dist/features/skeleton/adapters/inbound/SkeletonList.js.map +1 -0
- package/dist/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonText.d.ts +1 -1
- package/dist/features/skeleton/adapters/inbound/SkeletonText.d.ts.map +1 -0
- package/dist/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonText.js +2 -2
- package/dist/features/skeleton/adapters/inbound/SkeletonText.js.map +1 -0
- package/dist/features/skeleton/public.d.ts +6 -0
- package/dist/features/skeleton/public.d.ts.map +1 -0
- package/dist/features/skeleton/public.js +5 -0
- package/dist/features/skeleton/public.js.map +1 -0
- package/dist/features/skeleton/skeletonMeta.d.ts +178 -0
- package/dist/features/skeleton/skeletonMeta.d.ts.map +1 -0
- package/dist/features/skeleton/skeletonMeta.js +84 -0
- package/dist/features/skeleton/skeletonMeta.js.map +1 -0
- package/dist/features/surface/surfaceMeta.d.ts +1 -1
- package/dist/{components/time-picker → features/time-picker/adapters/inbound}/TimePicker.d.ts +1 -1
- package/dist/features/time-picker/adapters/inbound/TimePicker.d.ts.map +1 -0
- package/dist/{components/time-picker → features/time-picker/adapters/inbound}/TimePicker.js +8 -11
- package/dist/features/time-picker/adapters/inbound/TimePicker.js.map +1 -0
- package/dist/features/time-picker/public.d.ts +3 -0
- package/dist/features/time-picker/public.d.ts.map +1 -0
- package/dist/features/time-picker/public.js +2 -0
- package/dist/features/time-picker/public.js.map +1 -0
- package/dist/features/time-picker/timePickerMeta.d.ts +90 -0
- package/dist/features/time-picker/timePickerMeta.d.ts.map +1 -0
- package/dist/features/time-picker/timePickerMeta.js +64 -0
- package/dist/features/time-picker/timePickerMeta.js.map +1 -0
- 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 +7 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -6
- 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 +8 -1
- 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 +9 -6
- 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 +6 -6
- package/dist/registry.js.map +1 -1
- package/dist/{components/date-picker/types.d.ts → types/date-picker.d.ts} +6 -6
- package/dist/types/date-picker.d.ts.map +1 -0
- package/dist/types/date-picker.js +2 -0
- package/dist/types/date-picker.js.map +1 -0
- 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/{patterns/hero/types.d.ts → types/hero.d.ts} +3 -3
- package/dist/types/hero.d.ts.map +1 -0
- package/dist/types/hero.js +2 -0
- package/dist/types/hero.js.map +1 -0
- package/dist/{patterns/missing-element/types.d.ts → types/missing-element.d.ts} +2 -2
- package/dist/types/missing-element.d.ts.map +1 -0
- package/dist/types/missing-element.js +2 -0
- package/dist/types/missing-element.js.map +1 -0
- package/dist/{components/skeleton/types.d.ts → types/skeleton.d.ts} +3 -3
- package/dist/types/skeleton.d.ts.map +1 -0
- package/dist/types/skeleton.js +2 -0
- package/dist/types/skeleton.js.map +1 -0
- package/dist/{components/time-picker/types.d.ts → types/time-picker.d.ts} +2 -2
- package/dist/types/time-picker.d.ts.map +1 -0
- package/dist/types/time-picker.js +2 -0
- package/dist/types/time-picker.js.map +1 -0
- package/package.json +2 -1
- package/src/audit.test.ts +2 -4
- package/src/constants.ts +4 -0
- package/src/featureManifest.test.ts +19 -0
- package/src/features/bottom-sheet/public.test.ts +2 -2
- package/src/features/data-table/adapters/inbound/DataTable.tsx +1 -1
- package/src/{components/date-picker → features/date-picker/adapters/inbound}/DatePicker.tsx +41 -32
- package/src/features/date-picker/datePickerMeta.ts +58 -0
- package/src/features/date-picker/public.test.ts +15 -0
- package/src/features/date-picker/public.ts +2 -0
- package/src/features/date-picker/utils/localDate.test.ts +18 -0
- package/src/features/date-picker/utils/localDate.ts +29 -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/{components/date-picker/meta.ts → features/form/formActionsMeta.ts} +3 -4
- 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/{patterns/hero → features/hero/adapters/inbound}/Hero.tsx +6 -7
- package/src/features/hero/public.ts +2 -0
- package/src/{patterns → features}/missing-element/MissingElement.test.ts +6 -4
- package/src/{patterns/missing-element → features/missing-element/adapters/inbound}/MissingElement.tsx +6 -6
- package/src/features/missing-element/public.ts +2 -0
- package/src/{components/skeleton → features/skeleton/adapters/inbound}/Skeleton.tsx +4 -4
- package/src/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonCard.tsx +5 -5
- package/src/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonList.tsx +3 -3
- package/src/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonText.tsx +3 -3
- package/src/features/skeleton/public.test.ts +24 -0
- package/src/features/skeleton/public.ts +13 -0
- package/src/features/skeleton/skeletonMeta.ts +88 -0
- package/src/{components/time-picker → features/time-picker/adapters/inbound}/TimePicker.tsx +9 -12
- package/src/features/time-picker/public.test.ts +14 -0
- package/src/features/time-picker/public.ts +2 -0
- package/src/features/time-picker/timePickerMeta.ts +65 -0
- package/src/features/uploader/adapters/inbound/Uploader.tsx +1 -1
- package/src/index.ts +58 -45
- package/src/interactionPolicy.test.ts +3 -3
- package/src/metadata/allowedChildren.ts +8 -1
- package/src/metadata/componentMeta.test.ts +24 -1
- package/src/metadata/componentMeta.ts +14 -11
- 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/registry.ts +6 -6
- package/src/theme/themeScopeStructure.test.ts +5 -7
- package/src/{components/date-picker/types.ts → types/date-picker.ts} +5 -5
- package/src/{components/form/types.ts → types/form.ts} +12 -36
- package/src/{patterns/hero/types.ts → types/hero.ts} +2 -2
- package/src/{patterns/missing-element/types.ts → types/missing-element.ts} +1 -1
- package/src/{components/skeleton/types.ts → types/skeleton.ts} +2 -2
- package/src/{components/time-picker/types.ts → types/time-picker.ts} +1 -1
- package/dist/components/date-picker/DatePicker.d.ts.map +0 -1
- package/dist/components/date-picker/DatePicker.js.map +0 -1
- package/dist/components/date-picker/index.d.ts +0 -3
- package/dist/components/date-picker/index.d.ts.map +0 -1
- package/dist/components/date-picker/index.js +0 -2
- package/dist/components/date-picker/index.js.map +0 -1
- package/dist/components/date-picker/meta.d.ts +0 -9
- package/dist/components/date-picker/meta.d.ts.map +0 -1
- package/dist/components/date-picker/meta.js +0 -9
- package/dist/components/date-picker/meta.js.map +0 -1
- package/dist/components/date-picker/types.d.ts.map +0 -1
- package/dist/components/date-picker/types.js +0 -2
- package/dist/components/date-picker/types.js.map +0 -1
- 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/components/skeleton/Skeleton.d.ts.map +0 -1
- package/dist/components/skeleton/Skeleton.js.map +0 -1
- package/dist/components/skeleton/SkeletonCard.d.ts.map +0 -1
- package/dist/components/skeleton/SkeletonCard.js.map +0 -1
- package/dist/components/skeleton/SkeletonList.d.ts.map +0 -1
- package/dist/components/skeleton/SkeletonList.js.map +0 -1
- package/dist/components/skeleton/SkeletonText.d.ts.map +0 -1
- package/dist/components/skeleton/SkeletonText.js.map +0 -1
- package/dist/components/skeleton/index.d.ts +0 -6
- package/dist/components/skeleton/index.d.ts.map +0 -1
- package/dist/components/skeleton/index.js +0 -5
- package/dist/components/skeleton/index.js.map +0 -1
- package/dist/components/skeleton/meta.d.ts +0 -33
- package/dist/components/skeleton/meta.d.ts.map +0 -1
- package/dist/components/skeleton/meta.js +0 -33
- package/dist/components/skeleton/meta.js.map +0 -1
- package/dist/components/skeleton/types.d.ts.map +0 -1
- package/dist/components/skeleton/types.js +0 -2
- package/dist/components/skeleton/types.js.map +0 -1
- package/dist/components/time-picker/TimePicker.d.ts.map +0 -1
- package/dist/components/time-picker/TimePicker.js.map +0 -1
- package/dist/components/time-picker/index.d.ts +0 -3
- package/dist/components/time-picker/index.d.ts.map +0 -1
- package/dist/components/time-picker/index.js +0 -2
- package/dist/components/time-picker/index.js.map +0 -1
- package/dist/components/time-picker/meta.d.ts +0 -9
- package/dist/components/time-picker/meta.d.ts.map +0 -1
- package/dist/components/time-picker/meta.js +0 -9
- package/dist/components/time-picker/meta.js.map +0 -1
- package/dist/components/time-picker/types.d.ts.map +0 -1
- package/dist/components/time-picker/types.js +0 -2
- package/dist/components/time-picker/types.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/patterns/hero/Hero.d.ts.map +0 -1
- package/dist/patterns/hero/Hero.js.map +0 -1
- package/dist/patterns/hero/index.d.ts +0 -3
- package/dist/patterns/hero/index.d.ts.map +0 -1
- package/dist/patterns/hero/index.js +0 -2
- package/dist/patterns/hero/index.js.map +0 -1
- package/dist/patterns/hero/meta.d.ts.map +0 -1
- package/dist/patterns/hero/meta.js.map +0 -1
- package/dist/patterns/hero/types.d.ts.map +0 -1
- package/dist/patterns/hero/types.js +0 -2
- package/dist/patterns/hero/types.js.map +0 -1
- package/dist/patterns/missing-element/MissingElement.d.ts.map +0 -1
- package/dist/patterns/missing-element/MissingElement.js.map +0 -1
- package/dist/patterns/missing-element/index.d.ts +0 -3
- package/dist/patterns/missing-element/index.d.ts.map +0 -1
- package/dist/patterns/missing-element/index.js +0 -2
- package/dist/patterns/missing-element/index.js.map +0 -1
- package/dist/patterns/missing-element/meta.d.ts.map +0 -1
- package/dist/patterns/missing-element/meta.js.map +0 -1
- package/dist/patterns/missing-element/types.d.ts.map +0 -1
- package/dist/patterns/missing-element/types.js +0 -2
- package/dist/patterns/missing-element/types.js.map +0 -1
- package/src/components/date-picker/index.ts +0 -2
- 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/components/skeleton/index.ts +0 -13
- package/src/components/skeleton/meta.ts +0 -37
- package/src/components/time-picker/index.ts +0 -2
- package/src/components/time-picker/meta.ts +0 -10
- package/src/patterns/form-field/index.ts +0 -1
- package/src/patterns/form-field/types.ts +0 -16
- package/src/patterns/hero/index.ts +0 -2
- package/src/patterns/missing-element/index.ts +0 -2
- /package/src/{patterns/hero/meta.ts → features/hero/heroMeta.ts} +0 -0
- /package/src/{patterns/missing-element/meta.ts → features/missing-element/missingElementMeta.ts} +0 -0
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { Field } from '@ankhorage/surface';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
4
|
+
import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
|
|
5
|
+
import type { DatePickerProps } from '../../../../types/date-picker';
|
|
6
|
+
import { useBottomSheet } from '../../../bottom-sheet/public';
|
|
7
|
+
import { Button } from '../../../button/public';
|
|
8
|
+
import { Box, Stack } from '../../../layout/public';
|
|
9
|
+
import { Text } from '../../../typography/public';
|
|
10
|
+
import { formatLocalDate, parseLocalDate } from '../../utils/localDate';
|
|
10
11
|
|
|
11
12
|
const WEEKDAY_LABELS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] as const;
|
|
12
13
|
const DAY_CELL_WIDTH = 42;
|
|
@@ -27,15 +28,14 @@ function renderLabel(label: React.ReactNode, description: React.ReactNode | unde
|
|
|
27
28
|
);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
/***
|
|
31
|
-
function
|
|
32
|
-
return
|
|
31
|
+
/*** Compare two values by local calendar day. */
|
|
32
|
+
function isSameLocalDay(left: string | null, right: Date): boolean {
|
|
33
|
+
return left === formatLocalDate(right);
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
/***
|
|
36
|
-
function
|
|
37
|
-
|
|
38
|
-
return startOfLocalDay(left).getTime() === startOfLocalDay(right).getTime();
|
|
36
|
+
/*** Normalize a Date to the start of its local calendar day for range comparisons. */
|
|
37
|
+
function startOfLocalDay(value: Date): Date {
|
|
38
|
+
return new Date(value.getFullYear(), value.getMonth(), value.getDate());
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/*** Report whether one local calendar day precedes another. */
|
|
@@ -65,28 +65,27 @@ function formatMonthLabel(value: Date): string {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
/*** Format a selected date with the platform locale defaults. */
|
|
68
|
-
function formatDefaultDate(value:
|
|
69
|
-
return value
|
|
68
|
+
function formatDefaultDate(value: string): string {
|
|
69
|
+
return parseLocalDate(value)?.toLocaleDateString() ?? value;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
/*** Build the padded calendar grid for one month. */
|
|
73
73
|
function createMonthDays(month: Date): (Date | null)[] {
|
|
74
74
|
const firstDay = new Date(month.getFullYear(), month.getMonth(), 1);
|
|
75
75
|
const dayCount = new Date(month.getFullYear(), month.getMonth() + 1, 0).getDate();
|
|
76
|
-
const
|
|
76
|
+
const populatedLength = firstDay.getDay() + dayCount;
|
|
77
|
+
const paddedLength = Math.ceil(populatedLength / 7) * 7;
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return days;
|
|
79
|
+
return Array.from({ length: paddedLength }, (_, index) =>
|
|
80
|
+
index < firstDay.getDay()
|
|
81
|
+
? null
|
|
82
|
+
: new Date(month.getFullYear(), month.getMonth(), index - firstDay.getDay() + 1),
|
|
83
|
+
);
|
|
85
84
|
}
|
|
86
85
|
|
|
87
86
|
/*** Resolve the month initially shown by the calendar sheet. */
|
|
88
|
-
function resolveInitialMonth(value:
|
|
89
|
-
const base = value ?? minDate ?? new Date();
|
|
87
|
+
function resolveInitialMonth(value: string | null, minDate: string | undefined): Date {
|
|
88
|
+
const base = parseLocalDate(value) ?? parseLocalDate(minDate) ?? new Date();
|
|
90
89
|
return new Date(base.getFullYear(), base.getMonth(), 1);
|
|
91
90
|
}
|
|
92
91
|
|
|
@@ -142,7 +141,7 @@ function DatePickerInner({
|
|
|
142
141
|
minDate={minDate}
|
|
143
142
|
onDismiss={dismiss}
|
|
144
143
|
onSelect={(date) => {
|
|
145
|
-
onValueChange?.(
|
|
144
|
+
onValueChange?.(formatLocalDate(date));
|
|
146
145
|
dismiss();
|
|
147
146
|
}}
|
|
148
147
|
testID={testID}
|
|
@@ -197,6 +196,8 @@ function DatePickerSheet({
|
|
|
197
196
|
}: DatePickerSheetProps) {
|
|
198
197
|
const [displayMonth, setDisplayMonth] = React.useState(() => resolveInitialMonth(value, minDate));
|
|
199
198
|
const monthDays = React.useMemo(() => createMonthDays(displayMonth), [displayMonth]);
|
|
199
|
+
const resolvedMaxDate = React.useMemo(() => parseLocalDate(maxDate), [maxDate]);
|
|
200
|
+
const resolvedMinDate = React.useMemo(() => parseLocalDate(minDate), [minDate]);
|
|
200
201
|
|
|
201
202
|
return (
|
|
202
203
|
<Stack gap="m" p="m" testID={testID ? `${testID}-sheet` : undefined}>
|
|
@@ -204,15 +205,15 @@ function DatePickerSheet({
|
|
|
204
205
|
<DatePickerMonthNavigation
|
|
205
206
|
displayMonth={displayMonth}
|
|
206
207
|
interactionPolicy={interactionPolicy}
|
|
207
|
-
maxDate={
|
|
208
|
-
minDate={
|
|
208
|
+
maxDate={resolvedMaxDate}
|
|
209
|
+
minDate={resolvedMinDate}
|
|
209
210
|
onMonthChange={setDisplayMonth}
|
|
210
211
|
/>
|
|
211
212
|
<DatePickerWeekdays />
|
|
212
213
|
<DatePickerCalendar
|
|
213
214
|
interactionPolicy={interactionPolicy}
|
|
214
|
-
maxDate={
|
|
215
|
-
minDate={
|
|
215
|
+
maxDate={resolvedMaxDate}
|
|
216
|
+
minDate={resolvedMinDate}
|
|
216
217
|
monthDays={monthDays}
|
|
217
218
|
onSelect={onSelect}
|
|
218
219
|
testID={testID}
|
|
@@ -254,8 +255,11 @@ function DatePickerMonthNavigation({
|
|
|
254
255
|
maxDate,
|
|
255
256
|
minDate,
|
|
256
257
|
onMonthChange,
|
|
257
|
-
}:
|
|
258
|
+
}: {
|
|
258
259
|
displayMonth: Date;
|
|
260
|
+
interactionPolicy: DatePickerProps['interactionPolicy'];
|
|
261
|
+
maxDate: Date | undefined;
|
|
262
|
+
minDate: Date | undefined;
|
|
259
263
|
onMonthChange: (month: Date) => void;
|
|
260
264
|
}) {
|
|
261
265
|
const previousMonth = new Date(displayMonth.getFullYear(), displayMonth.getMonth() - 1, 1);
|
|
@@ -312,9 +316,14 @@ function DatePickerCalendar({
|
|
|
312
316
|
onSelect,
|
|
313
317
|
testID,
|
|
314
318
|
value,
|
|
315
|
-
}:
|
|
319
|
+
}: {
|
|
320
|
+
interactionPolicy: DatePickerProps['interactionPolicy'];
|
|
321
|
+
maxDate: Date | undefined;
|
|
322
|
+
minDate: Date | undefined;
|
|
316
323
|
monthDays: readonly (Date | null)[];
|
|
317
324
|
onSelect: (value: Date) => void;
|
|
325
|
+
testID: string | undefined;
|
|
326
|
+
value: DatePickerProps['value'];
|
|
318
327
|
}) {
|
|
319
328
|
return (
|
|
320
329
|
<Stack direction="row" gap="xs" wrap="wrap">
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ZoraComponentMeta } from '../../metadata';
|
|
2
|
+
|
|
3
|
+
export const datePickerMeta = {
|
|
4
|
+
name: 'DatePicker',
|
|
5
|
+
category: 'component',
|
|
6
|
+
description: 'Captures a local calendar date through the shared BottomSheet picker host.',
|
|
7
|
+
directManifestNode: true,
|
|
8
|
+
allowedChildren: [],
|
|
9
|
+
blueprint: {
|
|
10
|
+
label: 'Date picker',
|
|
11
|
+
defaultProps: {
|
|
12
|
+
value: null,
|
|
13
|
+
placeholder: 'Choose date',
|
|
14
|
+
disabled: false,
|
|
15
|
+
required: false,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
events: {
|
|
19
|
+
valueChange: {
|
|
20
|
+
label: 'Value change',
|
|
21
|
+
eventType: 'datePicker.valueChange',
|
|
22
|
+
description: 'Emitted when a local calendar date is selected.',
|
|
23
|
+
payloadFields: [{ path: 'value', type: 'string', label: 'Value' }],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
props: {
|
|
27
|
+
value: {
|
|
28
|
+
type: 'string',
|
|
29
|
+
category: 'State',
|
|
30
|
+
label: 'Value',
|
|
31
|
+
default: null,
|
|
32
|
+
authoring: { authority: 'instance' },
|
|
33
|
+
},
|
|
34
|
+
label: { type: 'string', category: 'Content', label: 'Label' },
|
|
35
|
+
description: { type: 'string', category: 'Content', label: 'Description' },
|
|
36
|
+
error: { type: 'string', category: 'Validation', label: 'Error' },
|
|
37
|
+
placeholder: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
category: 'Content',
|
|
40
|
+
label: 'Placeholder',
|
|
41
|
+
default: 'Choose date',
|
|
42
|
+
},
|
|
43
|
+
minDate: { type: 'string', category: 'Validation', label: 'Minimum date' },
|
|
44
|
+
maxDate: { type: 'string', category: 'Validation', label: 'Maximum date' },
|
|
45
|
+
disabled: {
|
|
46
|
+
type: 'boolean',
|
|
47
|
+
category: 'State',
|
|
48
|
+
label: 'Disabled',
|
|
49
|
+
default: false,
|
|
50
|
+
},
|
|
51
|
+
required: {
|
|
52
|
+
type: 'boolean',
|
|
53
|
+
category: 'Validation',
|
|
54
|
+
label: 'Required',
|
|
55
|
+
default: false,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
} as const satisfies ZoraComponentMeta;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { expect, test } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
import { ZORA_COMPONENT_META } from '../../metadata/componentMeta';
|
|
4
|
+
|
|
5
|
+
test('DatePicker exposes a serializable manifest contract through the shared BottomSheet', async () => {
|
|
6
|
+
const source = await Bun.file('src/features/date-picker/adapters/inbound/DatePicker.tsx').text();
|
|
7
|
+
const meta = ZORA_COMPONENT_META.DatePicker;
|
|
8
|
+
|
|
9
|
+
expect(meta.directManifestNode).toBe(true);
|
|
10
|
+
expect(meta.props.value?.type).toBe('string');
|
|
11
|
+
expect(meta.events?.valueChange?.eventType).toBe('datePicker.valueChange');
|
|
12
|
+
expect(meta.bindings?.props?.value?.value.type).toBe('string');
|
|
13
|
+
expect(source).toContain('useBottomSheet()');
|
|
14
|
+
expect(source).toContain('formatLocalDate(date)');
|
|
15
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
import { formatLocalDate, parseLocalDate } from './localDate';
|
|
4
|
+
|
|
5
|
+
describe('local date serialization', () => {
|
|
6
|
+
test('round-trips a valid YYYY-MM-DD value without a UTC conversion', () => {
|
|
7
|
+
const parsed = parseLocalDate('2026-09-13');
|
|
8
|
+
|
|
9
|
+
expect(parsed).toBeDefined();
|
|
10
|
+
expect(parsed ? formatLocalDate(parsed) : undefined).toBe('2026-09-13');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('rejects malformed and impossible calendar dates', () => {
|
|
14
|
+
expect(parseLocalDate('2026-2-03')).toBeUndefined();
|
|
15
|
+
expect(parseLocalDate('2026-02-30')).toBeUndefined();
|
|
16
|
+
expect(parseLocalDate(null)).toBeUndefined();
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const LOCAL_DATE_PATTERN = /^(\d{4})-(\d{2})-(\d{2})$/u;
|
|
2
|
+
|
|
3
|
+
/*** Parse a calendar date without applying a UTC offset. */
|
|
4
|
+
export function parseLocalDate(value: string | null | undefined): Date | undefined {
|
|
5
|
+
if (!value) return undefined;
|
|
6
|
+
|
|
7
|
+
const match = LOCAL_DATE_PATTERN.exec(value);
|
|
8
|
+
if (!match) return undefined;
|
|
9
|
+
|
|
10
|
+
const year = Number(match[1]);
|
|
11
|
+
const month = Number(match[2]);
|
|
12
|
+
const day = Number(match[3]);
|
|
13
|
+
const parsed = new Date(year, month - 1, day);
|
|
14
|
+
parsed.setFullYear(year);
|
|
15
|
+
|
|
16
|
+
return parsed.getFullYear() === year &&
|
|
17
|
+
parsed.getMonth() === month - 1 &&
|
|
18
|
+
parsed.getDate() === day
|
|
19
|
+
? parsed
|
|
20
|
+
: undefined;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/*** Serialize a Date as a local calendar date suitable for manifest state. */
|
|
24
|
+
export function formatLocalDate(value: Date): string {
|
|
25
|
+
const year = String(value.getFullYear()).padStart(4, '0');
|
|
26
|
+
const month = String(value.getMonth() + 1).padStart(2, '0');
|
|
27
|
+
const day = String(value.getDate()).padStart(2, '0');
|
|
28
|
+
return `${year}-${month}-${day}`;
|
|
29
|
+
}
|
|
@@ -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);
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { ZoraComponentMeta } from '../../metadata';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
name: 'DatePicker',
|
|
2
|
+
export const formActionsMeta = {
|
|
3
|
+
name: 'FormActions',
|
|
5
4
|
category: 'component',
|
|
6
5
|
directManifestNode: false,
|
|
7
6
|
allowedChildren: [],
|
|
8
|
-
note: '
|
|
7
|
+
note: 'Internal form action helper.',
|
|
9
8
|
props: {},
|
|
10
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
|
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import type { HeroAction, HeroAlign, HeroProps } from './types';
|
|
3
|
+
import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
|
|
4
|
+
import type { HeroAction, HeroAlign, HeroProps } from '../../../../types/hero';
|
|
5
|
+
import { Button } from '../../../button/public';
|
|
6
|
+
import { Card } from '../../../card/public';
|
|
7
|
+
import { Box, Grid, Stack } from '../../../layout/public';
|
|
8
|
+
import { Heading, Text } from '../../../typography/public';
|
|
10
9
|
|
|
11
10
|
function HeroInner({
|
|
12
11
|
themeId: _themeId,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, expect, test } from 'bun:test';
|
|
2
2
|
|
|
3
3
|
import { ZORA_BINDABLE_COMPONENT_META, ZORA_COMPONENT_META } from '../../metadata';
|
|
4
|
-
import { missingElementMeta } from './
|
|
4
|
+
import { missingElementMeta } from './missingElementMeta';
|
|
5
5
|
|
|
6
6
|
describe('MissingElement draft contract', () => {
|
|
7
7
|
test('is a release-blocking manifest leaf distinct from completed states', () => {
|
|
@@ -41,7 +41,9 @@ describe('MissingElement draft contract', () => {
|
|
|
41
41
|
});
|
|
42
42
|
|
|
43
43
|
test('visibly and accessibly identifies the gap while preserving its minimum dimensions', async () => {
|
|
44
|
-
const source = await Bun.file(
|
|
44
|
+
const source = await Bun.file(
|
|
45
|
+
'src/features/missing-element/adapters/inbound/MissingElement.tsx',
|
|
46
|
+
).text();
|
|
45
47
|
|
|
46
48
|
expect(source).toContain('accessibilityLabel={accessibilityLabel}');
|
|
47
49
|
expect(source).toContain('accessibilityRole="text"');
|
|
@@ -54,8 +56,8 @@ describe('MissingElement draft contract', () => {
|
|
|
54
56
|
|
|
55
57
|
test('accepts the canonical interaction policy without owning interactive behavior', async () => {
|
|
56
58
|
const [source, types] = await Promise.all([
|
|
57
|
-
Bun.file('src/
|
|
58
|
-
Bun.file('src/
|
|
59
|
+
Bun.file('src/features/missing-element/adapters/inbound/MissingElement.tsx').text(),
|
|
60
|
+
Bun.file('src/types/missing-element.ts').text(),
|
|
59
61
|
]);
|
|
60
62
|
|
|
61
63
|
expect(types).toContain('MissingElementProps extends ZoraBaseProps');
|