rn-inputforge 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +959 -39
- package/lib/commonjs/a11y/audit.js +72 -0
- package/lib/commonjs/a11y/audit.js.map +1 -0
- package/lib/commonjs/a11y/index.js +13 -0
- package/lib/commonjs/a11y/index.js.map +1 -0
- package/lib/commonjs/adapters/index.js +25 -0
- package/lib/commonjs/adapters/index.js.map +1 -0
- package/lib/commonjs/adapters/reactHookForm.js +107 -0
- package/lib/commonjs/adapters/reactHookForm.js.map +1 -0
- package/lib/commonjs/autofill/index.js +25 -0
- package/lib/commonjs/autofill/index.js.map +1 -0
- package/lib/commonjs/autofill/profiles.js +199 -0
- package/lib/commonjs/autofill/profiles.js.map +1 -0
- package/lib/commonjs/components/FieldFlowA11yAudit/FieldFlowA11yAudit.js +99 -0
- package/lib/commonjs/components/FieldFlowA11yAudit/FieldFlowA11yAudit.js.map +1 -0
- package/lib/commonjs/components/FieldFlowA11yAudit/index.js +13 -0
- package/lib/commonjs/components/FieldFlowA11yAudit/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowAffordance/FieldFlowAffordance.js +104 -0
- package/lib/commonjs/components/FieldFlowAffordance/FieldFlowAffordance.js.map +1 -0
- package/lib/commonjs/components/FieldFlowAffordance/index.js +13 -0
- package/lib/commonjs/components/FieldFlowAffordance/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowAuthActions/FieldFlowAuthActions.js +130 -0
- package/lib/commonjs/components/FieldFlowAuthActions/FieldFlowAuthActions.js.map +1 -0
- package/lib/commonjs/components/FieldFlowAuthActions/index.js +13 -0
- package/lib/commonjs/components/FieldFlowAuthActions/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowCompleteness/FieldFlowCompleteness.js +100 -0
- package/lib/commonjs/components/FieldFlowCompleteness/FieldFlowCompleteness.js.map +1 -0
- package/lib/commonjs/components/FieldFlowCompleteness/index.js +13 -0
- package/lib/commonjs/components/FieldFlowCompleteness/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowCreditCard/FieldFlowCreditCard.js +146 -0
- package/lib/commonjs/components/FieldFlowCreditCard/FieldFlowCreditCard.js.map +1 -0
- package/lib/commonjs/components/FieldFlowCreditCard/index.js +13 -0
- package/lib/commonjs/components/FieldFlowCreditCard/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowDraftBanner/FieldFlowDraftBanner.js +156 -0
- package/lib/commonjs/components/FieldFlowDraftBanner/FieldFlowDraftBanner.js.map +1 -0
- package/lib/commonjs/components/FieldFlowDraftBanner/index.js +13 -0
- package/lib/commonjs/components/FieldFlowDraftBanner/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowFormHeader/FieldFlowFormHeader.js +102 -0
- package/lib/commonjs/components/FieldFlowFormHeader/FieldFlowFormHeader.js.map +1 -0
- package/lib/commonjs/components/FieldFlowFormHeader/index.js +13 -0
- package/lib/commonjs/components/FieldFlowFormHeader/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowInfoTip/FieldFlowInfoTip.js +121 -0
- package/lib/commonjs/components/FieldFlowInfoTip/FieldFlowInfoTip.js.map +1 -0
- package/lib/commonjs/components/FieldFlowInfoTip/index.js +13 -0
- package/lib/commonjs/components/FieldFlowInfoTip/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowInlineAlert/FieldFlowInlineAlert.js +142 -0
- package/lib/commonjs/components/FieldFlowInlineAlert/FieldFlowInlineAlert.js.map +1 -0
- package/lib/commonjs/components/FieldFlowInlineAlert/index.js +13 -0
- package/lib/commonjs/components/FieldFlowInlineAlert/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowInput/FieldFlowInput.js +179 -53
- package/lib/commonjs/components/FieldFlowInput/FieldFlowInput.js.map +1 -1
- package/lib/commonjs/components/FieldFlowInput/styles.js +60 -8
- package/lib/commonjs/components/FieldFlowInput/styles.js.map +1 -1
- package/lib/commonjs/components/FieldFlowKeyboardToolbar/FieldFlowKeyboardToolbar.js +137 -0
- package/lib/commonjs/components/FieldFlowKeyboardToolbar/FieldFlowKeyboardToolbar.js.map +1 -0
- package/lib/commonjs/components/FieldFlowKeyboardToolbar/index.js +19 -0
- package/lib/commonjs/components/FieldFlowKeyboardToolbar/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowNumberStepper/FieldFlowNumberStepper.js +136 -0
- package/lib/commonjs/components/FieldFlowNumberStepper/FieldFlowNumberStepper.js.map +1 -0
- package/lib/commonjs/components/FieldFlowNumberStepper/index.js +13 -0
- package/lib/commonjs/components/FieldFlowNumberStepper/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowPasswordStrength/FieldFlowPasswordStrength.js +122 -0
- package/lib/commonjs/components/FieldFlowPasswordStrength/FieldFlowPasswordStrength.js.map +1 -0
- package/lib/commonjs/components/FieldFlowPasswordStrength/index.js +13 -0
- package/lib/commonjs/components/FieldFlowPasswordStrength/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowPhone/FieldFlowPhone.js +263 -0
- package/lib/commonjs/components/FieldFlowPhone/FieldFlowPhone.js.map +1 -0
- package/lib/commonjs/components/FieldFlowPhone/index.js +13 -0
- package/lib/commonjs/components/FieldFlowPhone/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowRating/FieldFlowRating.js +106 -0
- package/lib/commonjs/components/FieldFlowRating/FieldFlowRating.js.map +1 -0
- package/lib/commonjs/components/FieldFlowRating/index.js +13 -0
- package/lib/commonjs/components/FieldFlowRating/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowSection/FieldFlowSection.js +141 -0
- package/lib/commonjs/components/FieldFlowSection/FieldFlowSection.js.map +1 -0
- package/lib/commonjs/components/FieldFlowSection/index.js +13 -0
- package/lib/commonjs/components/FieldFlowSection/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowSegmented/FieldFlowSegmented.js +195 -0
- package/lib/commonjs/components/FieldFlowSegmented/FieldFlowSegmented.js.map +1 -0
- package/lib/commonjs/components/FieldFlowSegmented/index.js +13 -0
- package/lib/commonjs/components/FieldFlowSegmented/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowSignature/FieldFlowSignature.js +200 -0
- package/lib/commonjs/components/FieldFlowSignature/FieldFlowSignature.js.map +1 -0
- package/lib/commonjs/components/FieldFlowSignature/index.js +13 -0
- package/lib/commonjs/components/FieldFlowSignature/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowSkeleton/FieldFlowSkeleton.js +101 -0
- package/lib/commonjs/components/FieldFlowSkeleton/FieldFlowSkeleton.js.map +1 -0
- package/lib/commonjs/components/FieldFlowSkeleton/index.js +13 -0
- package/lib/commonjs/components/FieldFlowSkeleton/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowSlider/FieldFlowSlider.js +178 -0
- package/lib/commonjs/components/FieldFlowSlider/FieldFlowSlider.js.map +1 -0
- package/lib/commonjs/components/FieldFlowSlider/index.js +13 -0
- package/lib/commonjs/components/FieldFlowSlider/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowStepper/FieldFlowStepper.js +166 -0
- package/lib/commonjs/components/FieldFlowStepper/FieldFlowStepper.js.map +1 -0
- package/lib/commonjs/components/FieldFlowStepper/index.js +13 -0
- package/lib/commonjs/components/FieldFlowStepper/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowTags/FieldFlowTags.js +240 -0
- package/lib/commonjs/components/FieldFlowTags/FieldFlowTags.js.map +1 -0
- package/lib/commonjs/components/FieldFlowTags/index.js +13 -0
- package/lib/commonjs/components/FieldFlowTags/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowTypeahead/FieldFlowTypeahead.js +227 -0
- package/lib/commonjs/components/FieldFlowTypeahead/FieldFlowTypeahead.js.map +1 -0
- package/lib/commonjs/components/FieldFlowTypeahead/index.js +13 -0
- package/lib/commonjs/components/FieldFlowTypeahead/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowUpload/FieldFlowUpload.js +191 -0
- package/lib/commonjs/components/FieldFlowUpload/FieldFlowUpload.js.map +1 -0
- package/lib/commonjs/components/FieldFlowUpload/index.js +13 -0
- package/lib/commonjs/components/FieldFlowUpload/index.js.map +1 -0
- package/lib/commonjs/components/KeyboardAwareFormWrapper/KeyboardAwareFormWrapper.js +6 -4
- package/lib/commonjs/components/KeyboardAwareFormWrapper/KeyboardAwareFormWrapper.js.map +1 -1
- package/lib/commonjs/hooks/index.js +56 -0
- package/lib/commonjs/hooks/index.js.map +1 -1
- package/lib/commonjs/hooks/useFieldFlowArray.js +110 -0
- package/lib/commonjs/hooks/useFieldFlowArray.js.map +1 -0
- package/lib/commonjs/hooks/useFieldFlowCompleteness.js +46 -0
- package/lib/commonjs/hooks/useFieldFlowCompleteness.js.map +1 -0
- package/lib/commonjs/hooks/useFieldFlowDirtyGuard.js +53 -0
- package/lib/commonjs/hooks/useFieldFlowDirtyGuard.js.map +1 -0
- package/lib/commonjs/hooks/useFieldFlowDraft.js +168 -0
- package/lib/commonjs/hooks/useFieldFlowDraft.js.map +1 -0
- package/lib/commonjs/hooks/useFieldFlowForm.js +224 -30
- package/lib/commonjs/hooks/useFieldFlowForm.js.map +1 -1
- package/lib/commonjs/hooks/useFieldFlowSteps.js +77 -0
- package/lib/commonjs/hooks/useFieldFlowSteps.js.map +1 -0
- package/lib/commonjs/hooks/useFieldFlowSubmitQueue.js +145 -0
- package/lib/commonjs/hooks/useFieldFlowSubmitQueue.js.map +1 -0
- package/lib/commonjs/hooks/useFormIntelligence.js +130 -0
- package/lib/commonjs/hooks/useFormIntelligence.js.map +1 -0
- package/lib/commonjs/hooks/useKeyboardManager.js +15 -0
- package/lib/commonjs/hooks/useKeyboardManager.js.map +1 -1
- package/lib/commonjs/hooks/useSmartPaste.js +27 -0
- package/lib/commonjs/hooks/useSmartPaste.js.map +1 -0
- package/lib/commonjs/i18n/index.js +25 -0
- package/lib/commonjs/i18n/index.js.map +1 -0
- package/lib/commonjs/i18n/messages.js +88 -0
- package/lib/commonjs/i18n/messages.js.map +1 -0
- package/lib/commonjs/index.js +466 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/intelligence/formAccessibility.js +79 -0
- package/lib/commonjs/intelligence/formAccessibility.js.map +1 -0
- package/lib/commonjs/intelligence/index.js +31 -0
- package/lib/commonjs/intelligence/index.js.map +1 -0
- package/lib/commonjs/intelligence/types.js +2 -0
- package/lib/commonjs/intelligence/types.js.map +1 -0
- package/lib/commonjs/motion/index.js +20 -0
- package/lib/commonjs/motion/index.js.map +1 -0
- package/lib/commonjs/motion/useFieldMotion.js +111 -0
- package/lib/commonjs/motion/useFieldMotion.js.map +1 -0
- package/lib/commonjs/motion/useReducedMotion.js +32 -0
- package/lib/commonjs/motion/useReducedMotion.js.map +1 -0
- package/lib/commonjs/paste/index.js +19 -0
- package/lib/commonjs/paste/index.js.map +1 -0
- package/lib/commonjs/paste/smartPaste.js +113 -0
- package/lib/commonjs/paste/smartPaste.js.map +1 -0
- package/lib/commonjs/schema/FieldFlowSchemaForm.js +219 -0
- package/lib/commonjs/schema/FieldFlowSchemaForm.js.map +1 -0
- package/lib/commonjs/schema/index.js +13 -0
- package/lib/commonjs/schema/index.js.map +1 -0
- package/lib/commonjs/schema/types.js +6 -0
- package/lib/commonjs/schema/types.js.map +1 -0
- package/lib/commonjs/theme/ThemeProvider.js +65 -4
- package/lib/commonjs/theme/ThemeProvider.js.map +1 -1
- package/lib/commonjs/theme/appearance.js +93 -0
- package/lib/commonjs/theme/appearance.js.map +1 -0
- package/lib/commonjs/theme/defaultTheme.js +17 -2
- package/lib/commonjs/theme/defaultTheme.js.map +1 -1
- package/lib/commonjs/theme/index.js +32 -0
- package/lib/commonjs/theme/index.js.map +1 -1
- package/lib/commonjs/theme/presets.js +142 -0
- package/lib/commonjs/theme/presets.js.map +1 -0
- package/lib/commonjs/types/globals.d.js +2 -0
- package/lib/commonjs/types/globals.d.js.map +1 -0
- package/lib/commonjs/utils/affordance.js +151 -0
- package/lib/commonjs/utils/affordance.js.map +1 -0
- package/lib/commonjs/utils/passwordStrength.js +79 -0
- package/lib/commonjs/utils/passwordStrength.js.map +1 -0
- package/lib/commonjs/utils/phoneCountries.js +119 -0
- package/lib/commonjs/utils/phoneCountries.js.map +1 -0
- package/lib/commonjs/validation/validators.js +10 -7
- package/lib/commonjs/validation/validators.js.map +1 -1
- package/lib/module/a11y/audit.js +68 -0
- package/lib/module/a11y/audit.js.map +1 -0
- package/lib/module/a11y/index.js +4 -0
- package/lib/module/a11y/index.js.map +1 -0
- package/lib/module/adapters/index.js +4 -0
- package/lib/module/adapters/index.js.map +1 -0
- package/lib/module/adapters/reactHookForm.js +100 -0
- package/lib/module/adapters/reactHookForm.js.map +1 -0
- package/lib/module/autofill/index.js +4 -0
- package/lib/module/autofill/index.js.map +1 -0
- package/lib/module/autofill/profiles.js +193 -0
- package/lib/module/autofill/profiles.js.map +1 -0
- package/lib/module/components/FieldFlowA11yAudit/FieldFlowA11yAudit.js +94 -0
- package/lib/module/components/FieldFlowA11yAudit/FieldFlowA11yAudit.js.map +1 -0
- package/lib/module/components/FieldFlowA11yAudit/index.js +4 -0
- package/lib/module/components/FieldFlowA11yAudit/index.js.map +1 -0
- package/lib/module/components/FieldFlowAffordance/FieldFlowAffordance.js +99 -0
- package/lib/module/components/FieldFlowAffordance/FieldFlowAffordance.js.map +1 -0
- package/lib/module/components/FieldFlowAffordance/index.js +4 -0
- package/lib/module/components/FieldFlowAffordance/index.js.map +1 -0
- package/lib/module/components/FieldFlowAuthActions/FieldFlowAuthActions.js +125 -0
- package/lib/module/components/FieldFlowAuthActions/FieldFlowAuthActions.js.map +1 -0
- package/lib/module/components/FieldFlowAuthActions/index.js +4 -0
- package/lib/module/components/FieldFlowAuthActions/index.js.map +1 -0
- package/lib/module/components/FieldFlowCompleteness/FieldFlowCompleteness.js +95 -0
- package/lib/module/components/FieldFlowCompleteness/FieldFlowCompleteness.js.map +1 -0
- package/lib/module/components/FieldFlowCompleteness/index.js +4 -0
- package/lib/module/components/FieldFlowCompleteness/index.js.map +1 -0
- package/lib/module/components/FieldFlowCreditCard/FieldFlowCreditCard.js +141 -0
- package/lib/module/components/FieldFlowCreditCard/FieldFlowCreditCard.js.map +1 -0
- package/lib/module/components/FieldFlowCreditCard/index.js +4 -0
- package/lib/module/components/FieldFlowCreditCard/index.js.map +1 -0
- package/lib/module/components/FieldFlowDraftBanner/FieldFlowDraftBanner.js +151 -0
- package/lib/module/components/FieldFlowDraftBanner/FieldFlowDraftBanner.js.map +1 -0
- package/lib/module/components/FieldFlowDraftBanner/index.js +4 -0
- package/lib/module/components/FieldFlowDraftBanner/index.js.map +1 -0
- package/lib/module/components/FieldFlowFormHeader/FieldFlowFormHeader.js +97 -0
- package/lib/module/components/FieldFlowFormHeader/FieldFlowFormHeader.js.map +1 -0
- package/lib/module/components/FieldFlowFormHeader/index.js +4 -0
- package/lib/module/components/FieldFlowFormHeader/index.js.map +1 -0
- package/lib/module/components/FieldFlowInfoTip/FieldFlowInfoTip.js +116 -0
- package/lib/module/components/FieldFlowInfoTip/FieldFlowInfoTip.js.map +1 -0
- package/lib/module/components/FieldFlowInfoTip/index.js +4 -0
- package/lib/module/components/FieldFlowInfoTip/index.js.map +1 -0
- package/lib/module/components/FieldFlowInlineAlert/FieldFlowInlineAlert.js +137 -0
- package/lib/module/components/FieldFlowInlineAlert/FieldFlowInlineAlert.js.map +1 -0
- package/lib/module/components/FieldFlowInlineAlert/index.js +4 -0
- package/lib/module/components/FieldFlowInlineAlert/index.js.map +1 -0
- package/lib/module/components/FieldFlowInput/FieldFlowInput.js +180 -54
- package/lib/module/components/FieldFlowInput/FieldFlowInput.js.map +1 -1
- package/lib/module/components/FieldFlowInput/styles.js +60 -8
- package/lib/module/components/FieldFlowInput/styles.js.map +1 -1
- package/lib/module/components/FieldFlowKeyboardToolbar/FieldFlowKeyboardToolbar.js +131 -0
- package/lib/module/components/FieldFlowKeyboardToolbar/FieldFlowKeyboardToolbar.js.map +1 -0
- package/lib/module/components/FieldFlowKeyboardToolbar/index.js +4 -0
- package/lib/module/components/FieldFlowKeyboardToolbar/index.js.map +1 -0
- package/lib/module/components/FieldFlowNumberStepper/FieldFlowNumberStepper.js +131 -0
- package/lib/module/components/FieldFlowNumberStepper/FieldFlowNumberStepper.js.map +1 -0
- package/lib/module/components/FieldFlowNumberStepper/index.js +4 -0
- package/lib/module/components/FieldFlowNumberStepper/index.js.map +1 -0
- package/lib/module/components/FieldFlowPasswordStrength/FieldFlowPasswordStrength.js +117 -0
- package/lib/module/components/FieldFlowPasswordStrength/FieldFlowPasswordStrength.js.map +1 -0
- package/lib/module/components/FieldFlowPasswordStrength/index.js +4 -0
- package/lib/module/components/FieldFlowPasswordStrength/index.js.map +1 -0
- package/lib/module/components/FieldFlowPhone/FieldFlowPhone.js +258 -0
- package/lib/module/components/FieldFlowPhone/FieldFlowPhone.js.map +1 -0
- package/lib/module/components/FieldFlowPhone/index.js +4 -0
- package/lib/module/components/FieldFlowPhone/index.js.map +1 -0
- package/lib/module/components/FieldFlowRating/FieldFlowRating.js +101 -0
- package/lib/module/components/FieldFlowRating/FieldFlowRating.js.map +1 -0
- package/lib/module/components/FieldFlowRating/index.js +4 -0
- package/lib/module/components/FieldFlowRating/index.js.map +1 -0
- package/lib/module/components/FieldFlowSection/FieldFlowSection.js +136 -0
- package/lib/module/components/FieldFlowSection/FieldFlowSection.js.map +1 -0
- package/lib/module/components/FieldFlowSection/index.js +4 -0
- package/lib/module/components/FieldFlowSection/index.js.map +1 -0
- package/lib/module/components/FieldFlowSegmented/FieldFlowSegmented.js +190 -0
- package/lib/module/components/FieldFlowSegmented/FieldFlowSegmented.js.map +1 -0
- package/lib/module/components/FieldFlowSegmented/index.js +4 -0
- package/lib/module/components/FieldFlowSegmented/index.js.map +1 -0
- package/lib/module/components/FieldFlowSignature/FieldFlowSignature.js +195 -0
- package/lib/module/components/FieldFlowSignature/FieldFlowSignature.js.map +1 -0
- package/lib/module/components/FieldFlowSignature/index.js +4 -0
- package/lib/module/components/FieldFlowSignature/index.js.map +1 -0
- package/lib/module/components/FieldFlowSkeleton/FieldFlowSkeleton.js +96 -0
- package/lib/module/components/FieldFlowSkeleton/FieldFlowSkeleton.js.map +1 -0
- package/lib/module/components/FieldFlowSkeleton/index.js +4 -0
- package/lib/module/components/FieldFlowSkeleton/index.js.map +1 -0
- package/lib/module/components/FieldFlowSlider/FieldFlowSlider.js +173 -0
- package/lib/module/components/FieldFlowSlider/FieldFlowSlider.js.map +1 -0
- package/lib/module/components/FieldFlowSlider/index.js +4 -0
- package/lib/module/components/FieldFlowSlider/index.js.map +1 -0
- package/lib/module/components/FieldFlowStepper/FieldFlowStepper.js +161 -0
- package/lib/module/components/FieldFlowStepper/FieldFlowStepper.js.map +1 -0
- package/lib/module/components/FieldFlowStepper/index.js +4 -0
- package/lib/module/components/FieldFlowStepper/index.js.map +1 -0
- package/lib/module/components/FieldFlowTags/FieldFlowTags.js +235 -0
- package/lib/module/components/FieldFlowTags/FieldFlowTags.js.map +1 -0
- package/lib/module/components/FieldFlowTags/index.js +4 -0
- package/lib/module/components/FieldFlowTags/index.js.map +1 -0
- package/lib/module/components/FieldFlowTypeahead/FieldFlowTypeahead.js +222 -0
- package/lib/module/components/FieldFlowTypeahead/FieldFlowTypeahead.js.map +1 -0
- package/lib/module/components/FieldFlowTypeahead/index.js +4 -0
- package/lib/module/components/FieldFlowTypeahead/index.js.map +1 -0
- package/lib/module/components/FieldFlowUpload/FieldFlowUpload.js +186 -0
- package/lib/module/components/FieldFlowUpload/FieldFlowUpload.js.map +1 -0
- package/lib/module/components/FieldFlowUpload/index.js +4 -0
- package/lib/module/components/FieldFlowUpload/index.js.map +1 -0
- package/lib/module/components/KeyboardAwareFormWrapper/KeyboardAwareFormWrapper.js +5 -3
- package/lib/module/components/KeyboardAwareFormWrapper/KeyboardAwareFormWrapper.js.map +1 -1
- package/lib/module/hooks/index.js +8 -0
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/useFieldFlowArray.js +106 -0
- package/lib/module/hooks/useFieldFlowArray.js.map +1 -0
- package/lib/module/hooks/useFieldFlowCompleteness.js +42 -0
- package/lib/module/hooks/useFieldFlowCompleteness.js.map +1 -0
- package/lib/module/hooks/useFieldFlowDirtyGuard.js +49 -0
- package/lib/module/hooks/useFieldFlowDirtyGuard.js.map +1 -0
- package/lib/module/hooks/useFieldFlowDraft.js +165 -0
- package/lib/module/hooks/useFieldFlowDraft.js.map +1 -0
- package/lib/module/hooks/useFieldFlowForm.js +224 -30
- package/lib/module/hooks/useFieldFlowForm.js.map +1 -1
- package/lib/module/hooks/useFieldFlowSteps.js +73 -0
- package/lib/module/hooks/useFieldFlowSteps.js.map +1 -0
- package/lib/module/hooks/useFieldFlowSubmitQueue.js +141 -0
- package/lib/module/hooks/useFieldFlowSubmitQueue.js.map +1 -0
- package/lib/module/hooks/useFormIntelligence.js +126 -0
- package/lib/module/hooks/useFormIntelligence.js.map +1 -0
- package/lib/module/hooks/useKeyboardManager.js +15 -0
- package/lib/module/hooks/useKeyboardManager.js.map +1 -1
- package/lib/module/hooks/useSmartPaste.js +23 -0
- package/lib/module/hooks/useSmartPaste.js.map +1 -0
- package/lib/module/i18n/index.js +4 -0
- package/lib/module/i18n/index.js.map +1 -0
- package/lib/module/i18n/messages.js +82 -0
- package/lib/module/i18n/messages.js.map +1 -0
- package/lib/module/index.js +46 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/intelligence/formAccessibility.js +72 -0
- package/lib/module/intelligence/formAccessibility.js.map +1 -0
- package/lib/module/intelligence/index.js +4 -0
- package/lib/module/intelligence/index.js.map +1 -0
- package/lib/module/intelligence/types.js +2 -0
- package/lib/module/intelligence/types.js.map +1 -0
- package/lib/module/motion/index.js +5 -0
- package/lib/module/motion/index.js.map +1 -0
- package/lib/module/motion/useFieldMotion.js +107 -0
- package/lib/module/motion/useFieldMotion.js.map +1 -0
- package/lib/module/motion/useReducedMotion.js +29 -0
- package/lib/module/motion/useReducedMotion.js.map +1 -0
- package/lib/module/paste/index.js +4 -0
- package/lib/module/paste/index.js.map +1 -0
- package/lib/module/paste/smartPaste.js +108 -0
- package/lib/module/paste/smartPaste.js.map +1 -0
- package/lib/module/schema/FieldFlowSchemaForm.js +214 -0
- package/lib/module/schema/FieldFlowSchemaForm.js.map +1 -0
- package/lib/module/schema/index.js +4 -0
- package/lib/module/schema/index.js.map +1 -0
- package/lib/module/schema/types.js +4 -0
- package/lib/module/schema/types.js.map +1 -0
- package/lib/module/theme/ThemeProvider.js +66 -5
- package/lib/module/theme/ThemeProvider.js.map +1 -1
- package/lib/module/theme/appearance.js +87 -0
- package/lib/module/theme/appearance.js.map +1 -0
- package/lib/module/theme/defaultTheme.js +17 -2
- package/lib/module/theme/defaultTheme.js.map +1 -1
- package/lib/module/theme/index.js +2 -0
- package/lib/module/theme/index.js.map +1 -1
- package/lib/module/theme/presets.js +138 -0
- package/lib/module/theme/presets.js.map +1 -0
- package/lib/module/types/globals.d.js +2 -0
- package/lib/module/types/globals.d.js.map +1 -0
- package/lib/module/utils/affordance.js +140 -0
- package/lib/module/utils/affordance.js.map +1 -0
- package/lib/module/utils/passwordStrength.js +74 -0
- package/lib/module/utils/passwordStrength.js.map +1 -0
- package/lib/module/utils/phoneCountries.js +113 -0
- package/lib/module/utils/phoneCountries.js.map +1 -0
- package/lib/module/validation/validators.js +10 -7
- package/lib/module/validation/validators.js.map +1 -1
- package/lib/typescript/a11y/audit.d.ts +32 -0
- package/lib/typescript/a11y/audit.d.ts.map +1 -0
- package/lib/typescript/a11y/index.d.ts +3 -0
- package/lib/typescript/a11y/index.d.ts.map +1 -0
- package/lib/typescript/adapters/index.d.ts +3 -0
- package/lib/typescript/adapters/index.d.ts.map +1 -0
- package/lib/typescript/adapters/reactHookForm.d.ts +56 -0
- package/lib/typescript/adapters/reactHookForm.d.ts.map +1 -0
- package/lib/typescript/autofill/index.d.ts +3 -0
- package/lib/typescript/autofill/index.d.ts.map +1 -0
- package/lib/typescript/autofill/profiles.d.ts +48 -0
- package/lib/typescript/autofill/profiles.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowA11yAudit/FieldFlowA11yAudit.d.ts +21 -0
- package/lib/typescript/components/FieldFlowA11yAudit/FieldFlowA11yAudit.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowA11yAudit/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowA11yAudit/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowAffordance/FieldFlowAffordance.d.ts +29 -0
- package/lib/typescript/components/FieldFlowAffordance/FieldFlowAffordance.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowAffordance/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowAffordance/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowAuthActions/FieldFlowAuthActions.d.ts +29 -0
- package/lib/typescript/components/FieldFlowAuthActions/FieldFlowAuthActions.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowAuthActions/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowAuthActions/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowCompleteness/FieldFlowCompleteness.d.ts +25 -0
- package/lib/typescript/components/FieldFlowCompleteness/FieldFlowCompleteness.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowCompleteness/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowCompleteness/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowCreditCard/FieldFlowCreditCard.d.ts +27 -0
- package/lib/typescript/components/FieldFlowCreditCard/FieldFlowCreditCard.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowCreditCard/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowCreditCard/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowDraftBanner/FieldFlowDraftBanner.d.ts +24 -0
- package/lib/typescript/components/FieldFlowDraftBanner/FieldFlowDraftBanner.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowDraftBanner/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowDraftBanner/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowFormHeader/FieldFlowFormHeader.d.ts +23 -0
- package/lib/typescript/components/FieldFlowFormHeader/FieldFlowFormHeader.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowFormHeader/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowFormHeader/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowInfoTip/FieldFlowInfoTip.d.ts +19 -0
- package/lib/typescript/components/FieldFlowInfoTip/FieldFlowInfoTip.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowInfoTip/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowInfoTip/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowInlineAlert/FieldFlowInlineAlert.d.ts +22 -0
- package/lib/typescript/components/FieldFlowInlineAlert/FieldFlowInlineAlert.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowInlineAlert/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowInlineAlert/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowInput/FieldFlowInput.d.ts.map +1 -1
- package/lib/typescript/components/FieldFlowInput/styles.d.ts +52 -1
- package/lib/typescript/components/FieldFlowInput/styles.d.ts.map +1 -1
- package/lib/typescript/components/FieldFlowInput/types.d.ts +50 -0
- package/lib/typescript/components/FieldFlowInput/types.d.ts.map +1 -1
- package/lib/typescript/components/FieldFlowKeyboardToolbar/FieldFlowKeyboardToolbar.d.ts +30 -0
- package/lib/typescript/components/FieldFlowKeyboardToolbar/FieldFlowKeyboardToolbar.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowKeyboardToolbar/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowKeyboardToolbar/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowNumberStepper/FieldFlowNumberStepper.d.ts +34 -0
- package/lib/typescript/components/FieldFlowNumberStepper/FieldFlowNumberStepper.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowNumberStepper/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowNumberStepper/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowPasswordStrength/FieldFlowPasswordStrength.d.ts +26 -0
- package/lib/typescript/components/FieldFlowPasswordStrength/FieldFlowPasswordStrength.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowPasswordStrength/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowPasswordStrength/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowPhone/FieldFlowPhone.d.ts +40 -0
- package/lib/typescript/components/FieldFlowPhone/FieldFlowPhone.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowPhone/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowPhone/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowRating/FieldFlowRating.d.ts +30 -0
- package/lib/typescript/components/FieldFlowRating/FieldFlowRating.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowRating/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowRating/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowSection/FieldFlowSection.d.ts +35 -0
- package/lib/typescript/components/FieldFlowSection/FieldFlowSection.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowSection/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowSection/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowSegmented/FieldFlowSegmented.d.ts +28 -0
- package/lib/typescript/components/FieldFlowSegmented/FieldFlowSegmented.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowSegmented/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowSegmented/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowSignature/FieldFlowSignature.d.ts +41 -0
- package/lib/typescript/components/FieldFlowSignature/FieldFlowSignature.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowSignature/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowSignature/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowSkeleton/FieldFlowSkeleton.d.ts +21 -0
- package/lib/typescript/components/FieldFlowSkeleton/FieldFlowSkeleton.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowSkeleton/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowSkeleton/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowSlider/FieldFlowSlider.d.ts +30 -0
- package/lib/typescript/components/FieldFlowSlider/FieldFlowSlider.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowSlider/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowSlider/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowStepper/FieldFlowStepper.d.ts +31 -0
- package/lib/typescript/components/FieldFlowStepper/FieldFlowStepper.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowStepper/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowStepper/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowTags/FieldFlowTags.d.ts +41 -0
- package/lib/typescript/components/FieldFlowTags/FieldFlowTags.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowTags/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowTags/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowTypeahead/FieldFlowTypeahead.d.ts +43 -0
- package/lib/typescript/components/FieldFlowTypeahead/FieldFlowTypeahead.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowTypeahead/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowTypeahead/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowUpload/FieldFlowUpload.d.ts +52 -0
- package/lib/typescript/components/FieldFlowUpload/FieldFlowUpload.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowUpload/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowUpload/index.d.ts.map +1 -0
- package/lib/typescript/components/KeyboardAwareFormWrapper/KeyboardAwareFormWrapper.d.ts +3 -2
- package/lib/typescript/components/KeyboardAwareFormWrapper/KeyboardAwareFormWrapper.d.ts.map +1 -1
- package/lib/typescript/hooks/index.d.ts +17 -1
- package/lib/typescript/hooks/index.d.ts.map +1 -1
- package/lib/typescript/hooks/useFieldFlowArray.d.ts +54 -0
- package/lib/typescript/hooks/useFieldFlowArray.d.ts.map +1 -0
- package/lib/typescript/hooks/useFieldFlowCompleteness.d.ts +28 -0
- package/lib/typescript/hooks/useFieldFlowCompleteness.d.ts.map +1 -0
- package/lib/typescript/hooks/useFieldFlowDirtyGuard.d.ts +26 -0
- package/lib/typescript/hooks/useFieldFlowDirtyGuard.d.ts.map +1 -0
- package/lib/typescript/hooks/useFieldFlowDraft.d.ts +64 -0
- package/lib/typescript/hooks/useFieldFlowDraft.d.ts.map +1 -0
- package/lib/typescript/hooks/useFieldFlowForm.d.ts +80 -2
- package/lib/typescript/hooks/useFieldFlowForm.d.ts.map +1 -1
- package/lib/typescript/hooks/useFieldFlowSteps.d.ts +42 -0
- package/lib/typescript/hooks/useFieldFlowSteps.d.ts.map +1 -0
- package/lib/typescript/hooks/useFieldFlowSubmitQueue.d.ts +45 -0
- package/lib/typescript/hooks/useFieldFlowSubmitQueue.d.ts.map +1 -0
- package/lib/typescript/hooks/useFormIntelligence.d.ts +23 -0
- package/lib/typescript/hooks/useFormIntelligence.d.ts.map +1 -0
- package/lib/typescript/hooks/useKeyboardManager.d.ts +6 -0
- package/lib/typescript/hooks/useKeyboardManager.d.ts.map +1 -1
- package/lib/typescript/hooks/useSmartPaste.d.ts +14 -0
- package/lib/typescript/hooks/useSmartPaste.d.ts.map +1 -0
- package/lib/typescript/i18n/index.d.ts +3 -0
- package/lib/typescript/i18n/index.d.ts.map +1 -0
- package/lib/typescript/i18n/messages.d.ts +16 -0
- package/lib/typescript/i18n/messages.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +73 -5
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/intelligence/formAccessibility.d.ts +21 -0
- package/lib/typescript/intelligence/formAccessibility.d.ts.map +1 -0
- package/lib/typescript/intelligence/index.d.ts +4 -0
- package/lib/typescript/intelligence/index.d.ts.map +1 -0
- package/lib/typescript/intelligence/types.d.ts +36 -0
- package/lib/typescript/intelligence/types.d.ts.map +1 -0
- package/lib/typescript/motion/index.d.ts +4 -0
- package/lib/typescript/motion/index.d.ts.map +1 -0
- package/lib/typescript/motion/useFieldMotion.d.ts +31 -0
- package/lib/typescript/motion/useFieldMotion.d.ts.map +1 -0
- package/lib/typescript/motion/useReducedMotion.d.ts +5 -0
- package/lib/typescript/motion/useReducedMotion.d.ts.map +1 -0
- package/lib/typescript/paste/index.d.ts +3 -0
- package/lib/typescript/paste/index.d.ts.map +1 -0
- package/lib/typescript/paste/smartPaste.d.ts +32 -0
- package/lib/typescript/paste/smartPaste.d.ts.map +1 -0
- package/lib/typescript/schema/FieldFlowSchemaForm.d.ts +28 -0
- package/lib/typescript/schema/FieldFlowSchemaForm.d.ts.map +1 -0
- package/lib/typescript/schema/index.d.ts +4 -0
- package/lib/typescript/schema/index.d.ts.map +1 -0
- package/lib/typescript/schema/types.d.ts +43 -0
- package/lib/typescript/schema/types.d.ts.map +1 -0
- package/lib/typescript/theme/ThemeProvider.d.ts +18 -4
- package/lib/typescript/theme/ThemeProvider.d.ts.map +1 -1
- package/lib/typescript/theme/appearance.d.ts +19 -0
- package/lib/typescript/theme/appearance.d.ts.map +1 -0
- package/lib/typescript/theme/defaultTheme.d.ts.map +1 -1
- package/lib/typescript/theme/index.d.ts +3 -0
- package/lib/typescript/theme/index.d.ts.map +1 -1
- package/lib/typescript/theme/presets.d.ts +134 -0
- package/lib/typescript/theme/presets.d.ts.map +1 -0
- package/lib/typescript/types/index.d.ts +26 -0
- package/lib/typescript/types/index.d.ts.map +1 -1
- package/lib/typescript/utils/affordance.d.ts +36 -0
- package/lib/typescript/utils/affordance.d.ts.map +1 -0
- package/lib/typescript/utils/passwordStrength.d.ts +26 -0
- package/lib/typescript/utils/passwordStrength.d.ts.map +1 -0
- package/lib/typescript/utils/phoneCountries.d.ts +12 -0
- package/lib/typescript/utils/phoneCountries.d.ts.map +1 -0
- package/lib/typescript/validation/validators.d.ts +3 -1
- package/lib/typescript/validation/validators.d.ts.map +1 -1
- package/package.json +19 -2
- package/src/a11y/audit.ts +99 -0
- package/src/a11y/index.ts +7 -0
- package/src/adapters/index.ts +9 -0
- package/src/adapters/reactHookForm.tsx +152 -0
- package/src/autofill/index.ts +10 -0
- package/src/autofill/profiles.ts +224 -0
- package/src/components/FieldFlowA11yAudit/FieldFlowA11yAudit.tsx +112 -0
- package/src/components/FieldFlowA11yAudit/index.ts +2 -0
- package/src/components/FieldFlowAffordance/FieldFlowAffordance.tsx +143 -0
- package/src/components/FieldFlowAffordance/index.ts +2 -0
- package/src/components/FieldFlowAuthActions/FieldFlowAuthActions.tsx +146 -0
- package/src/components/FieldFlowAuthActions/index.ts +6 -0
- package/src/components/FieldFlowCompleteness/FieldFlowCompleteness.tsx +109 -0
- package/src/components/FieldFlowCompleteness/index.ts +2 -0
- package/src/components/FieldFlowCreditCard/FieldFlowCreditCard.tsx +152 -0
- package/src/components/FieldFlowCreditCard/index.ts +2 -0
- package/src/components/FieldFlowDraftBanner/FieldFlowDraftBanner.tsx +169 -0
- package/src/components/FieldFlowDraftBanner/index.ts +2 -0
- package/src/components/FieldFlowFormHeader/FieldFlowFormHeader.tsx +106 -0
- package/src/components/FieldFlowFormHeader/index.ts +2 -0
- package/src/components/FieldFlowInfoTip/FieldFlowInfoTip.tsx +120 -0
- package/src/components/FieldFlowInfoTip/index.ts +2 -0
- package/src/components/FieldFlowInlineAlert/FieldFlowInlineAlert.tsx +134 -0
- package/src/components/FieldFlowInlineAlert/index.ts +2 -0
- package/src/components/FieldFlowInput/FieldFlowInput.tsx +240 -61
- package/src/components/FieldFlowInput/styles.ts +69 -11
- package/src/components/FieldFlowInput/types.ts +54 -0
- package/src/components/FieldFlowKeyboardToolbar/FieldFlowKeyboardToolbar.tsx +150 -0
- package/src/components/FieldFlowKeyboardToolbar/index.ts +5 -0
- package/src/components/FieldFlowNumberStepper/FieldFlowNumberStepper.tsx +156 -0
- package/src/components/FieldFlowNumberStepper/index.ts +2 -0
- package/src/components/FieldFlowPasswordStrength/FieldFlowPasswordStrength.tsx +148 -0
- package/src/components/FieldFlowPasswordStrength/index.ts +2 -0
- package/src/components/FieldFlowPhone/FieldFlowPhone.tsx +298 -0
- package/src/components/FieldFlowPhone/index.ts +2 -0
- package/src/components/FieldFlowRating/FieldFlowRating.tsx +121 -0
- package/src/components/FieldFlowRating/index.ts +2 -0
- package/src/components/FieldFlowSection/FieldFlowSection.tsx +176 -0
- package/src/components/FieldFlowSection/index.ts +2 -0
- package/src/components/FieldFlowSegmented/FieldFlowSegmented.tsx +248 -0
- package/src/components/FieldFlowSegmented/index.ts +2 -0
- package/src/components/FieldFlowSignature/FieldFlowSignature.tsx +241 -0
- package/src/components/FieldFlowSignature/index.ts +7 -0
- package/src/components/FieldFlowSkeleton/FieldFlowSkeleton.tsx +105 -0
- package/src/components/FieldFlowSkeleton/index.ts +2 -0
- package/src/components/FieldFlowSlider/FieldFlowSlider.tsx +190 -0
- package/src/components/FieldFlowSlider/index.ts +2 -0
- package/src/components/FieldFlowStepper/FieldFlowStepper.tsx +190 -0
- package/src/components/FieldFlowStepper/index.ts +2 -0
- package/src/components/FieldFlowTags/FieldFlowTags.tsx +319 -0
- package/src/components/FieldFlowTags/index.ts +2 -0
- package/src/components/FieldFlowTypeahead/FieldFlowTypeahead.tsx +261 -0
- package/src/components/FieldFlowTypeahead/index.ts +2 -0
- package/src/components/FieldFlowUpload/FieldFlowUpload.tsx +226 -0
- package/src/components/FieldFlowUpload/index.ts +6 -0
- package/src/components/KeyboardAwareFormWrapper/KeyboardAwareFormWrapper.tsx +8 -4
- package/src/hooks/index.ts +48 -0
- package/src/hooks/useFieldFlowArray.ts +153 -0
- package/src/hooks/useFieldFlowCompleteness.ts +69 -0
- package/src/hooks/useFieldFlowDirtyGuard.ts +70 -0
- package/src/hooks/useFieldFlowDraft.ts +221 -0
- package/src/hooks/useFieldFlowForm.ts +357 -28
- package/src/hooks/useFieldFlowSteps.ts +130 -0
- package/src/hooks/useFieldFlowSubmitQueue.ts +206 -0
- package/src/hooks/useFormIntelligence.ts +207 -0
- package/src/hooks/useKeyboardManager.ts +26 -0
- package/src/hooks/useSmartPaste.ts +33 -0
- package/src/i18n/index.ts +6 -0
- package/src/i18n/messages.ts +101 -0
- package/src/index.ts +251 -3
- package/src/intelligence/formAccessibility.ts +87 -0
- package/src/intelligence/index.ts +12 -0
- package/src/intelligence/types.ts +34 -0
- package/src/motion/index.ts +3 -0
- package/src/motion/useFieldMotion.ts +120 -0
- package/src/motion/useReducedMotion.ts +31 -0
- package/src/paste/index.ts +7 -0
- package/src/paste/smartPaste.ts +132 -0
- package/src/schema/FieldFlowSchemaForm.tsx +274 -0
- package/src/schema/index.ts +8 -0
- package/src/schema/types.ts +63 -0
- package/src/theme/ThemeProvider.tsx +96 -7
- package/src/theme/appearance.ts +105 -0
- package/src/theme/defaultTheme.ts +11 -0
- package/src/theme/index.ts +3 -0
- package/src/theme/presets.ts +120 -0
- package/src/types/globals.d.ts +2 -0
- package/src/types/index.ts +28 -0
- package/src/utils/affordance.ts +138 -0
- package/src/utils/passwordStrength.ts +109 -0
- package/src/utils/phoneCountries.ts +44 -0
- package/src/validation/validators.ts +17 -7
package/README.md
CHANGED
|
@@ -1,33 +1,131 @@
|
|
|
1
1
|
# rn-inputforge
|
|
2
2
|
|
|
3
|
-
A production-ready
|
|
3
|
+
A production-ready input & form system for **React Native** (bare CLI **and Expo**). Pure JS/TS — no native modules, works with **npm** or **yarn**.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
One package for fields, validation, theming, motion, drafts, and form UX — so you don’t bolt together five libraries for a signup screen.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
## What's
|
|
9
|
+
## What's included
|
|
10
|
+
|
|
11
|
+
Everything ships from `rn-inputforge`. Use this map to find the right export.
|
|
12
|
+
|
|
13
|
+
### Fields & controls
|
|
14
|
+
|
|
15
|
+
| You need… | Use |
|
|
16
|
+
| --------- | --- |
|
|
17
|
+
| Text / email / phone / password / search / number | [`FieldFlowInput`](#field-types) |
|
|
18
|
+
| Phone + country dial code | [`FieldFlowPhone`](#phone-with-country-code) |
|
|
19
|
+
| OTP / PIN digits | [`FieldFlowOTP`](#otp--pin) |
|
|
20
|
+
| Card / phone / currency / date mask | [`FieldFlowMaskedInput`](#masked-inputs) |
|
|
21
|
+
| Card number + expiry + CVC | [`FieldFlowCreditCard`](#credit-card-group) |
|
|
22
|
+
| Date / time / datetime | [`FieldFlowDateTimePicker`](#date--time-picker) |
|
|
23
|
+
| Checkbox / radio / switch | [`Checkbox, radio & switch`](#checkbox-radio--switch) |
|
|
24
|
+
| Multi-value chips (skills, tags) | [`FieldFlowTags`](#tags--chip-input) |
|
|
25
|
+
| Single or multi select | [`FieldFlowDropdown`](#dropdown--select-single--multiple) |
|
|
26
|
+
| Async search / typeahead | [`FieldFlowTypeahead`](#async-typeahead) |
|
|
27
|
+
| File / image upload (pluggable picker) | [`FieldFlowUpload`](#file--image-upload) |
|
|
28
|
+
| Star rating | [`FieldFlowRating`](#rating--slider--number-stepper) |
|
|
29
|
+
| Range slider | [`FieldFlowSlider`](#rating--slider--number-stepper) |
|
|
30
|
+
| +/- quantity stepper | [`FieldFlowNumberStepper`](#rating--slider--number-stepper) |
|
|
31
|
+
| Signature pad | [`FieldFlowSignature`](#signature-pad) |
|
|
32
|
+
| Plan / filter pill tabs | [`FieldFlowSegmented`](#motion--ui) |
|
|
33
|
+
| Long bio / notes | [`DescriptionField`](#description-fields) |
|
|
34
|
+
| Chat composer + attachments | [`ChatInput`](#chat-input) |
|
|
35
|
+
|
|
36
|
+
### Form engine
|
|
37
|
+
|
|
38
|
+
| You need… | Use |
|
|
39
|
+
| --------- | --- |
|
|
40
|
+
| Full form state + submit | [`useFieldFlowForm`](#validation) |
|
|
41
|
+
| Sync / async / cross-field rules | [Validation](#validation) · [Zod](#zod-optional) |
|
|
42
|
+
| Server / API field errors (422) | [`setErrors` / `setFieldError`](#server-errors) |
|
|
43
|
+
| Localized validation messages | [`locale` / `messages`](#localized-validation) |
|
|
44
|
+
| Multi-step wizard | [`useFieldFlowSteps`](#multi-step-wizard) + [`FieldFlowStepper`](#multi-step-wizard) |
|
|
45
|
+
| Warn before leaving dirty form | [`useFieldFlowDirtyGuard`](#dirty-leave-guard) |
|
|
46
|
+
| Show / hide / require fields by values | [Conditional fields](#conditional-fields--field-arrays) |
|
|
47
|
+
| Repeatable rows (guests, line items) | [`useFieldFlowArray`](#conditional-fields--field-arrays) |
|
|
48
|
+
| Resume unfinished forms | [`useFieldFlowDraft`](#draft-resume) + [`FieldFlowDraftBanner`](#draft-resume) |
|
|
49
|
+
| Keyboard next / done across fields | [`useKeyboardManager`](#keyboard--form-navigation) + [`KeyboardAwareFormWrapper`](#keyboard--form-navigation) |
|
|
50
|
+
| Friction analytics + a11y on failed submit | [Form intelligence](#form-intelligence) |
|
|
51
|
+
| Autofill / password manager hints | [`autofill` / `autofillProfiles`](#autofill-profiles) |
|
|
52
|
+
| Keyboard Prev/Next/Done bar | [`FieldFlowKeyboardToolbar`](#keyboard-toolbar) |
|
|
53
|
+
| Smart paste (OTP / card / address) | [`routeSmartPaste`](#smart-paste) |
|
|
54
|
+
| “N fields left” progress coach | [`FieldFlowCompleteness`](#completeness-coach) |
|
|
55
|
+
| Passkey / SSO / biometric strip | [`FieldFlowAuthActions`](#auth-actions) |
|
|
56
|
+
| JSON schema → form UI | [`FieldFlowSchemaForm`](#schema-form-renderer) |
|
|
57
|
+
| Dev accessibility audit | [`FieldFlowA11yAudit`](#a11y-auditor) |
|
|
58
|
+
| Offline submit retry queue | [`useFieldFlowSubmitQueue`](#offline-submit-queue) |
|
|
59
|
+
| Already on React Hook Form | [`FieldFlowController`](#react-hook-form-adapter) |
|
|
60
|
+
|
|
61
|
+
### UI polish & branding
|
|
62
|
+
|
|
63
|
+
| You need… | Use |
|
|
64
|
+
| --------- | --- |
|
|
65
|
+
| Group fields in a card / collapse | [`FieldFlowSection`](#motion--ui) |
|
|
66
|
+
| Focus glow, error shake, success pop | [`motion` on inputs](#motion--ui) · `useFieldMotion` |
|
|
67
|
+
| `+92` / `$` / `kg` inside the field | [`prefix` / `suffix`](#motion--ui) |
|
|
68
|
+
| Email domain / dial-code chips | [`suggestions`](#smart-suggestion-chips) · [`FieldFlowAffordance`](#smart-suggestion-chips) |
|
|
69
|
+
| Password meter | [`showStrength`](#password-strength) |
|
|
70
|
+
| Look: outlined / filled / underline / floating | [Variants](#variants) |
|
|
71
|
+
| Built-in icons (no icon pack) | [Icons](#icons) |
|
|
72
|
+
| Brand colors in one line | [`themePresets`](#theming) · [`FieldFlowThemeProvider`](#theming) |
|
|
73
|
+
| Density / size / shape / surface | [`density` `size` `shape` `surface` `focusRing`](#visual-system) |
|
|
74
|
+
| Calm tips & alerts | [`FieldFlowInlineAlert`](#visual-system) · [`FieldFlowInfoTip`](#visual-system) |
|
|
75
|
+
| Loading skeletons | [`FieldFlowSkeleton`](#visual-system) |
|
|
76
|
+
| Form intro header | [`FieldFlowFormHeader`](#visual-system) |
|
|
77
|
+
|
|
78
|
+
### Helpers (also exported)
|
|
79
|
+
|
|
80
|
+
Masks (`applyMask`, `unmask`, …) · password strength (`evaluatePasswordStrength`) · affordance helpers · a11y (`focusFirstError`, `announceForAccessibility`) · validators · Zod adapters · `FieldFlowIcon` / `renderFieldFlowIcon`
|
|
81
|
+
|
|
82
|
+
**Full walkthrough:** [Quick start](#quick-start) · [Try it](#try-it-expo--snack) · [Public API](#public-api-at-a-glance)
|
|
10
83
|
|
|
11
|
-
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## What's new in 0.5.0
|
|
12
87
|
|
|
13
88
|
| Addition | What you get |
|
|
14
89
|
| -------- | ------------ |
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
| **
|
|
22
|
-
| **
|
|
23
|
-
| **
|
|
24
|
-
| **
|
|
25
|
-
| **
|
|
26
|
-
| **
|
|
27
|
-
|
|
28
|
-
**
|
|
29
|
-
|
|
30
|
-
|
|
90
|
+
| **Smart Affordance** | Email / phone / currency suggestion chips |
|
|
91
|
+
| **Form Intelligence** | Friction report + autofocus / announce on failed submit |
|
|
92
|
+
| **Conditional fields** | `showWhen` / `requiredWhen` / `disabledWhen` |
|
|
93
|
+
| **Field arrays** | `useFieldFlowArray` |
|
|
94
|
+
| **Draft resume** | `useFieldFlowDraft` + `FieldFlowDraftBanner` |
|
|
95
|
+
| **Password strength** | `showStrength` / `FieldFlowPasswordStrength` |
|
|
96
|
+
| **Tags** | `FieldFlowTags` |
|
|
97
|
+
| **React Hook Form** | `FieldFlowController` / `FieldFlowTagsController` |
|
|
98
|
+
| **Motion UI** | Glow, shake, fade, success pop (`motion` prop) |
|
|
99
|
+
| **Sections** | `FieldFlowSection` |
|
|
100
|
+
| **Theme presets** | `themePresets.soft` / `warm` / `teal` / `midnight` / `contrast` |
|
|
101
|
+
| **Prefix / suffix** | Inline affixes on inputs |
|
|
102
|
+
| **Segmented** | `FieldFlowSegmented` |
|
|
103
|
+
| **Multi-step wizard** | `useFieldFlowSteps` + `FieldFlowStepper` |
|
|
104
|
+
| **Phone + country** | `FieldFlowPhone` |
|
|
105
|
+
| **File upload** | `FieldFlowUpload` (inject your picker) |
|
|
106
|
+
| **Typeahead** | `FieldFlowTypeahead` (async `fetchOptions`) |
|
|
107
|
+
| **Server errors** | `setErrors` / `setFieldError` / `clearErrors` |
|
|
108
|
+
| **Rating / slider / +/-** | `FieldFlowRating`, `FieldFlowSlider`, `FieldFlowNumberStepper` |
|
|
109
|
+
| **Dirty leave guard** | `useFieldFlowDirtyGuard` + `isDirty` |
|
|
110
|
+
| **i18n messages** | `locale` / `messages` (`en` `es` `fr` `de` `pt` `ar`) |
|
|
111
|
+
| **Credit card group** | `FieldFlowCreditCard` |
|
|
112
|
+
| **Signature pad** | `FieldFlowSignature` |
|
|
113
|
+
| **Autofill profiles** | `autofill` prop + `autofillProfiles.login/signup/…` |
|
|
114
|
+
| **Keyboard toolbar** | `FieldFlowKeyboardToolbar` Prev/Next/Done |
|
|
115
|
+
| **Smart paste** | `routeSmartPaste` / `useSmartPaste` |
|
|
116
|
+
| **Completeness coach** | `useFieldFlowCompleteness` + `FieldFlowCompleteness` |
|
|
117
|
+
| **Auth actions** | `FieldFlowAuthActions` (passkey / SSO / biometric slots) |
|
|
118
|
+
| **Schema form** | `FieldFlowSchemaForm` JSON → UI |
|
|
119
|
+
| **A11y auditor** | `runA11yAudit` + `FieldFlowA11yAudit` (dev) |
|
|
120
|
+
| **Submit queue** | `useFieldFlowSubmitQueue` offline / retry |
|
|
121
|
+
| **Visual system** | Density, size, shape, surface, focus rings |
|
|
122
|
+
| **Inline alert / skeleton / header** | `FieldFlowInlineAlert`, `FieldFlowSkeleton`, `FieldFlowFormHeader` |
|
|
123
|
+
| **Info tips + helper status** | `infoTip`, `helperStatus`, `FieldFlowInfoTip` |
|
|
124
|
+
| **Theme crossfade** | Soft fade when switching presets (`animateTheme`) |
|
|
125
|
+
|
|
126
|
+
Still from **0.4.0:** OTP, masks, date/time, checkbox/radio/switch, variants, icons, async + cross-field validation, Zod, Expo.
|
|
127
|
+
|
|
128
|
+
> **Note:** since 0.4.0, `validateField` / `validateAll` return `Promise<boolean>`.
|
|
31
129
|
|
|
32
130
|
---
|
|
33
131
|
|
|
@@ -52,6 +150,7 @@ That's it — this is a pure JavaScript/TypeScript package (no native code), so
|
|
|
52
150
|
- Works with Expo SDK that ships RN ≥ 0.73
|
|
53
151
|
- TypeScript is optional but recommended (type defs are bundled)
|
|
54
152
|
- `zod` is an **optional** peer dependency (only if you use the Zod helpers)
|
|
153
|
+
- `react-hook-form` is an **optional** peer dependency (only if you use `FieldFlowController`)
|
|
55
154
|
|
|
56
155
|
---
|
|
57
156
|
|
|
@@ -95,6 +194,24 @@ Setting `type="email"` automatically wires up the email keyboard, disables autoc
|
|
|
95
194
|
| `description` | default, multi-line | used internally by `DescriptionField` |
|
|
96
195
|
| `chat` | default | used internally by `ChatInput` |
|
|
97
196
|
|
|
197
|
+
### Core `FieldFlowInput` props (cheat sheet)
|
|
198
|
+
|
|
199
|
+
| Prop | Purpose |
|
|
200
|
+
| ---- | ------- |
|
|
201
|
+
| `type` | Keyboard + defaults (`email`, `password`, `phone`, …) |
|
|
202
|
+
| `variant` | `outlined` \| `filled` \| `underline` \| `floating` |
|
|
203
|
+
| `label` / `helperText` / `errorText` / `successText` | Copy + states |
|
|
204
|
+
| `rules` / `validateOnChange` | Built-in validation |
|
|
205
|
+
| `leftIcon` / `rightIcon` / `iconSize` / `clearable` | Icons (built-in name or custom node) |
|
|
206
|
+
| `prefix` / `suffix` | Inline affix text or node |
|
|
207
|
+
| `suggestions` | Smart chips (`true`, `'email'`, custom list) |
|
|
208
|
+
| `showStrength` | Password strength meter |
|
|
209
|
+
| `motion` | Micro-interactions (default `true`) |
|
|
210
|
+
| `maxLength` / `showCharacterCount` | Limits + counter |
|
|
211
|
+
| `theme` / style props | Per-field override |
|
|
212
|
+
|
|
213
|
+
All standard `TextInput` props still pass through (placeholder, `returnKeyType`, etc.).
|
|
214
|
+
|
|
98
215
|
---
|
|
99
216
|
|
|
100
217
|
## Validation
|
|
@@ -203,6 +320,429 @@ Also exported: `zodToFormErrors`, `createZodSubmitGuard`, `fieldRulesFromZodStri
|
|
|
203
320
|
|
|
204
321
|
---
|
|
205
322
|
|
|
323
|
+
## Try it (Expo / Snack)
|
|
324
|
+
|
|
325
|
+
1. Create a blank Snack at [snack.expo.dev](https://snack.expo.dev).
|
|
326
|
+
2. Add dependency `rn-inputforge` (and `react-hook-form` if you try the RHF adapter).
|
|
327
|
+
3. Paste any snippet from this README or copy `example/App.tsx` from the repo.
|
|
328
|
+
|
|
329
|
+
Same install works in a local Expo app:
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
npx create-expo-app MyFormDemo
|
|
333
|
+
cd MyFormDemo
|
|
334
|
+
npx expo install rn-inputforge
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## Password strength
|
|
340
|
+
|
|
341
|
+
```tsx
|
|
342
|
+
<FieldFlowInput
|
|
343
|
+
type="password"
|
|
344
|
+
label="Password"
|
|
345
|
+
value={password}
|
|
346
|
+
onChangeText={setPassword}
|
|
347
|
+
showStrength
|
|
348
|
+
// or: showStrength={{ showRules: true, rules: customRules }}
|
|
349
|
+
/>
|
|
350
|
+
|
|
351
|
+
// Standalone meter
|
|
352
|
+
<FieldFlowPasswordStrength password={password} />
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Pure helper: `evaluatePasswordStrength(password)` → `{ level, progress, passed, failed }`.
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## Tags / chip input
|
|
360
|
+
|
|
361
|
+
```tsx
|
|
362
|
+
const [skills, setSkills] = useState<string[]>([]);
|
|
363
|
+
|
|
364
|
+
<FieldFlowTags
|
|
365
|
+
label="Skills"
|
|
366
|
+
value={skills}
|
|
367
|
+
onChange={setSkills}
|
|
368
|
+
maxTags={8}
|
|
369
|
+
placeholder="Type a skill and press Enter"
|
|
370
|
+
helperText="Comma or Enter to add"
|
|
371
|
+
/>
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## React Hook Form adapter
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
npm install react-hook-form
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
```tsx
|
|
383
|
+
import { useForm } from 'react-hook-form';
|
|
384
|
+
import { FieldFlowController, FieldFlowTagsController } from 'rn-inputforge';
|
|
385
|
+
|
|
386
|
+
const { control, handleSubmit } = useForm({
|
|
387
|
+
defaultValues: { email: '', skills: [] as string[] },
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
<FieldFlowController
|
|
391
|
+
control={control}
|
|
392
|
+
name="email"
|
|
393
|
+
type="email"
|
|
394
|
+
label="Email"
|
|
395
|
+
suggestions
|
|
396
|
+
rules={{ required: 'Email is required' }}
|
|
397
|
+
/>
|
|
398
|
+
|
|
399
|
+
<FieldFlowTagsController
|
|
400
|
+
control={control}
|
|
401
|
+
name="skills"
|
|
402
|
+
label="Skills"
|
|
403
|
+
rules={{ validate: v => (v?.length ? true : 'Add at least one skill') }}
|
|
404
|
+
/>
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
Also exported: `mapRhfToFieldFlowProps` for custom `Controller` renders.
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
## Smart suggestion chips
|
|
412
|
+
|
|
413
|
+
Show quick-complete chips while a field is focused — a UX gap most RN input kits skip:
|
|
414
|
+
|
|
415
|
+
```tsx
|
|
416
|
+
// Infer from type: email → @gmail.com…, phone → +1/+44…, number/decimal → $/€/£
|
|
417
|
+
<FieldFlowInput type="email" label="Email" value={email} onChangeText={setEmail} suggestions />
|
|
418
|
+
|
|
419
|
+
// Force a preset or pass a custom list
|
|
420
|
+
<FieldFlowInput type="phone" suggestions="phone" value={phone} onChangeText={setPhone} />
|
|
421
|
+
<FieldFlowInput suggestions={['@company.com', '@partner.io']} value={work} onChangeText={setWork} />
|
|
422
|
+
|
|
423
|
+
// Standalone bar (e.g. above the keyboard area)
|
|
424
|
+
<FieldFlowAffordance
|
|
425
|
+
kind="email"
|
|
426
|
+
value={email}
|
|
427
|
+
onSelect={setEmail}
|
|
428
|
+
/>
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
Helpers exported: `applyEmailDomainSuggestion`, `DEFAULT_EMAIL_DOMAINS`, `DEFAULT_PHONE_DIAL_CODES`, `DEFAULT_CURRENCY_SYMBOLS`.
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
## Form intelligence
|
|
436
|
+
|
|
437
|
+
Enable friction tracking and accessibility autopilot on the form hook:
|
|
438
|
+
|
|
439
|
+
```tsx
|
|
440
|
+
const form = useFieldFlowForm({
|
|
441
|
+
initialValues: { email: '', password: '' },
|
|
442
|
+
rules: { email: { required: true, email: true }, password: { required: true, minLength: 8 } },
|
|
443
|
+
fieldOrder: ['email', 'password'],
|
|
444
|
+
intelligence: {
|
|
445
|
+
onReport: report => console.log(report.mostFriction),
|
|
446
|
+
// focusFirstError: true (default)
|
|
447
|
+
// announceErrors: true (default) — VoiceOver / TalkBack
|
|
448
|
+
},
|
|
449
|
+
onSubmit: async values => api.login(values),
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
<FieldFlowInput
|
|
453
|
+
ref={r => form.registerFieldRef('email', { current: r })}
|
|
454
|
+
label="Email"
|
|
455
|
+
{...form.getInputProps('email')}
|
|
456
|
+
suggestions
|
|
457
|
+
/>;
|
|
458
|
+
|
|
459
|
+
// After interactions:
|
|
460
|
+
form.intelligence?.getReport();
|
|
461
|
+
// → { sessionMs, submitAttempts, fields: { email: { focusCount, errorCount, totalFocusMs, … } }, mostFriction }
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
Standalone helpers: `useFormIntelligence`, `focusFirstError`, `announceForAccessibility`.
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
|
|
468
|
+
## Conditional fields & field arrays
|
|
469
|
+
|
|
470
|
+
```tsx
|
|
471
|
+
const form = useFieldFlowForm({
|
|
472
|
+
initialValues: { accountType: 'personal', company: '', taxId: '' },
|
|
473
|
+
conditions: {
|
|
474
|
+
company: {
|
|
475
|
+
showWhen: v => v.accountType === 'business',
|
|
476
|
+
requiredWhen: v => v.accountType === 'business',
|
|
477
|
+
},
|
|
478
|
+
taxId: {
|
|
479
|
+
showWhen: v => v.accountType === 'business',
|
|
480
|
+
disabledWhen: v => v.accountType !== 'business',
|
|
481
|
+
},
|
|
482
|
+
},
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
{form.isVisible('company') && (
|
|
486
|
+
<FieldFlowInput label="Company" {...form.getInputProps('company')!} />
|
|
487
|
+
)}
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
Repeatable groups:
|
|
491
|
+
|
|
492
|
+
```tsx
|
|
493
|
+
import { useFieldFlowArray, FieldFlowInput } from 'rn-inputforge';
|
|
494
|
+
|
|
495
|
+
const guests = useFieldFlowArray({
|
|
496
|
+
createItem: () => ({ name: '', email: '' }),
|
|
497
|
+
min: 1,
|
|
498
|
+
max: 5,
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
{guests.items.map((guest, i) => (
|
|
502
|
+
<FieldFlowInput
|
|
503
|
+
key={i}
|
|
504
|
+
label={`Guest ${i + 1}`}
|
|
505
|
+
value={guest.name}
|
|
506
|
+
onChangeText={name => guests.update(i, g => ({ ...g, name }))}
|
|
507
|
+
/>
|
|
508
|
+
))}
|
|
509
|
+
<Button title="Add guest" disabled={guests.isMax} onPress={() => guests.append()} />
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
---
|
|
513
|
+
|
|
514
|
+
## Draft resume
|
|
515
|
+
|
|
516
|
+
Persist form values with any storage backend (AsyncStorage, MMKV, custom). No hard dependency:
|
|
517
|
+
|
|
518
|
+
```tsx
|
|
519
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
520
|
+
import { useFieldFlowDraft, FieldFlowDraftBanner, useFieldFlowForm } from 'rn-inputforge';
|
|
521
|
+
|
|
522
|
+
const form = useFieldFlowForm({ initialValues: { name: '', email: '' }, /* … */ });
|
|
523
|
+
|
|
524
|
+
const draft = useFieldFlowDraft({
|
|
525
|
+
key: 'signup-v1',
|
|
526
|
+
storage: {
|
|
527
|
+
getItem: k => AsyncStorage.getItem(k),
|
|
528
|
+
setItem: (k, v) => AsyncStorage.setItem(k, v),
|
|
529
|
+
removeItem: k => AsyncStorage.removeItem(k),
|
|
530
|
+
},
|
|
531
|
+
values: form.values,
|
|
532
|
+
onRestore: form.setValues,
|
|
533
|
+
exclude: ['password'], // never persist secrets
|
|
534
|
+
ttlMs: 7 * 24 * 60 * 60 * 1000,
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
<FieldFlowDraftBanner
|
|
538
|
+
visible={draft.hasDraft}
|
|
539
|
+
savedAt={draft.draftSavedAt}
|
|
540
|
+
onResume={draft.resume}
|
|
541
|
+
onDiscard={draft.discard}
|
|
542
|
+
/>;
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
On successful submit, call `await draft.clear()` so the banner doesn't reappear.
|
|
546
|
+
|
|
547
|
+
---
|
|
548
|
+
|
|
549
|
+
## Multi-step wizard
|
|
550
|
+
|
|
551
|
+
```tsx
|
|
552
|
+
import { useFieldFlowForm, useFieldFlowSteps, FieldFlowStepper, FieldFlowInput } from 'rn-inputforge';
|
|
553
|
+
|
|
554
|
+
const form = useFieldFlowForm({
|
|
555
|
+
initialValues: { name: '', email: '', bio: '' },
|
|
556
|
+
rules: {
|
|
557
|
+
name: { required: true },
|
|
558
|
+
email: { required: true, email: true },
|
|
559
|
+
},
|
|
560
|
+
onSubmit: async values => api.signup(values),
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
const wizard = useFieldFlowSteps({
|
|
564
|
+
values: form.values,
|
|
565
|
+
validateFields: form.validateFields,
|
|
566
|
+
onComplete: form.submit,
|
|
567
|
+
steps: [
|
|
568
|
+
{ id: 'profile', title: 'Profile', fields: ['name'] },
|
|
569
|
+
{ id: 'contact', title: 'Contact', fields: ['email'] },
|
|
570
|
+
{ id: 'about', title: 'About', fields: ['bio'] },
|
|
571
|
+
],
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
<>
|
|
575
|
+
<FieldFlowStepper steps={wizard.steps} stepIndex={wizard.stepIndex} onStepPress={wizard.goTo} />
|
|
576
|
+
{wizard.step.id === 'profile' && <FieldFlowInput label="Name" {...form.getInputProps('name')!} />}
|
|
577
|
+
{wizard.step.id === 'contact' && <FieldFlowInput type="email" label="Email" {...form.getInputProps('email')!} />}
|
|
578
|
+
{wizard.step.id === 'about' && <FieldFlowInput label="Bio" {...form.getInputProps('bio')!} />}
|
|
579
|
+
<Button title={wizard.isLast ? 'Submit' : 'Next'} onPress={() => wizard.next()} />
|
|
580
|
+
{!wizard.isFirst && <Button title="Back" onPress={wizard.back} />}
|
|
581
|
+
</>;
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
---
|
|
585
|
+
|
|
586
|
+
## Server errors
|
|
587
|
+
|
|
588
|
+
Map API 422 responses straight into the form:
|
|
589
|
+
|
|
590
|
+
```tsx
|
|
591
|
+
try {
|
|
592
|
+
await api.signup(form.values);
|
|
593
|
+
} catch (err) {
|
|
594
|
+
// { email: 'Already taken', password: 'Too weak' }
|
|
595
|
+
form.setErrors(err.fieldErrors);
|
|
596
|
+
// or: form.setFieldError('email', 'Already taken');
|
|
597
|
+
// form.clearErrors('email') / form.clearErrors()
|
|
598
|
+
}
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
Also available: `form.isDirty`, `form.dirtyFields`, `form.validateFields(['email', 'password'])`.
|
|
602
|
+
|
|
603
|
+
---
|
|
604
|
+
|
|
605
|
+
## Localized validation
|
|
606
|
+
|
|
607
|
+
```tsx
|
|
608
|
+
const form = useFieldFlowForm({
|
|
609
|
+
initialValues: { email: '' },
|
|
610
|
+
rules: { email: { required: true, email: true } },
|
|
611
|
+
locale: 'es', // en | es | fr | de | pt | ar
|
|
612
|
+
// or: messages: createValidationMessages({ required: 'Custom…' }, 'en'),
|
|
613
|
+
});
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
Helpers: `getValidationMessages('fr')`, `validationMessageCatalogs`, `createValidationMessages`.
|
|
617
|
+
|
|
618
|
+
---
|
|
619
|
+
|
|
620
|
+
## Dirty leave guard
|
|
621
|
+
|
|
622
|
+
```tsx
|
|
623
|
+
import { useFieldFlowDirtyGuard } from 'rn-inputforge';
|
|
624
|
+
|
|
625
|
+
const { confirmIfDirty } = useFieldFlowDirtyGuard({
|
|
626
|
+
isDirty: form.isDirty,
|
|
627
|
+
onDiscard: form.reset,
|
|
628
|
+
});
|
|
629
|
+
|
|
630
|
+
// React Navigation:
|
|
631
|
+
navigation.addListener('beforeRemove', async e => {
|
|
632
|
+
if (!form.isDirty) return;
|
|
633
|
+
e.preventDefault();
|
|
634
|
+
if (await confirmIfDirty()) navigation.dispatch(e.data.action);
|
|
635
|
+
});
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
Android hardware back is intercepted automatically when dirty.
|
|
639
|
+
|
|
640
|
+
---
|
|
641
|
+
|
|
642
|
+
## Phone with country code
|
|
643
|
+
|
|
644
|
+
```tsx
|
|
645
|
+
import { FieldFlowPhone } from 'rn-inputforge';
|
|
646
|
+
|
|
647
|
+
const [phone, setPhone] = useState(null);
|
|
648
|
+
|
|
649
|
+
<FieldFlowPhone
|
|
650
|
+
label="Mobile"
|
|
651
|
+
value={phone}
|
|
652
|
+
onChange={setPhone}
|
|
653
|
+
defaultCountryCode="PK"
|
|
654
|
+
required
|
|
655
|
+
/>;
|
|
656
|
+
// phone.e164 → "+923001234567"
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
---
|
|
660
|
+
|
|
661
|
+
## File / image upload
|
|
662
|
+
|
|
663
|
+
Pure JS — you inject the picker (Expo or RN):
|
|
664
|
+
|
|
665
|
+
```tsx
|
|
666
|
+
import * as ImagePicker from 'expo-image-picker';
|
|
667
|
+
import { FieldFlowUpload } from 'rn-inputforge';
|
|
668
|
+
|
|
669
|
+
<FieldFlowUpload
|
|
670
|
+
label="ID photo"
|
|
671
|
+
maxFiles={2}
|
|
672
|
+
value={files}
|
|
673
|
+
onChange={setFiles}
|
|
674
|
+
pick={async () => {
|
|
675
|
+
const res = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ['images'] });
|
|
676
|
+
if (res.canceled || !res.assets[0]) return null;
|
|
677
|
+
const a = res.assets[0];
|
|
678
|
+
return { uri: a.uri, name: a.fileName ?? 'photo.jpg', mimeType: a.mimeType, size: a.fileSize };
|
|
679
|
+
}}
|
|
680
|
+
/>;
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
---
|
|
684
|
+
|
|
685
|
+
## Async typeahead
|
|
686
|
+
|
|
687
|
+
```tsx
|
|
688
|
+
import { FieldFlowTypeahead } from 'rn-inputforge';
|
|
689
|
+
|
|
690
|
+
<FieldFlowTypeahead
|
|
691
|
+
label="City"
|
|
692
|
+
value={city}
|
|
693
|
+
displayValue={cityLabel}
|
|
694
|
+
onChange={(value, option) => {
|
|
695
|
+
setCity(value);
|
|
696
|
+
setCityLabel(option?.label ?? '');
|
|
697
|
+
}}
|
|
698
|
+
fetchOptions={async query => {
|
|
699
|
+
const rows = await api.searchCities(query);
|
|
700
|
+
return rows.map(r => ({ label: r.name, value: r.id }));
|
|
701
|
+
}}
|
|
702
|
+
minChars={2}
|
|
703
|
+
/>;
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
---
|
|
707
|
+
|
|
708
|
+
## Rating / slider / number stepper
|
|
709
|
+
|
|
710
|
+
```tsx
|
|
711
|
+
<FieldFlowRating label="Experience" value={rating} onChange={setRating} />
|
|
712
|
+
<FieldFlowSlider label="Budget" value={budget} onChange={setBudget} min={0} max={1000} step={50} />
|
|
713
|
+
<FieldFlowNumberStepper label="Guests" value={guests} onChange={setGuests} min={1} max={12} />
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
---
|
|
717
|
+
|
|
718
|
+
## Credit card group
|
|
719
|
+
|
|
720
|
+
```tsx
|
|
721
|
+
import { FieldFlowCreditCard } from 'rn-inputforge';
|
|
722
|
+
|
|
723
|
+
const [card, setCard] = useState({ number: '', expiry: '', cvc: '', name: '' });
|
|
724
|
+
|
|
725
|
+
<FieldFlowCreditCard value={card} onChange={setCard} showName required />;
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
---
|
|
729
|
+
|
|
730
|
+
## Signature pad
|
|
731
|
+
|
|
732
|
+
```tsx
|
|
733
|
+
import { FieldFlowSignature } from 'rn-inputforge';
|
|
734
|
+
|
|
735
|
+
<FieldFlowSignature
|
|
736
|
+
label="Sign to confirm"
|
|
737
|
+
value={signature}
|
|
738
|
+
onChange={setSignature}
|
|
739
|
+
required
|
|
740
|
+
/>;
|
|
741
|
+
// signature.isEmpty / signature.strokes
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
---
|
|
745
|
+
|
|
206
746
|
## Variants
|
|
207
747
|
|
|
208
748
|
Every text-like field (`FieldFlowInput`, `FieldFlowMaskedInput`, date picker trigger) supports:
|
|
@@ -435,13 +975,343 @@ Handles expandable height, keyboard-avoiding behavior, and a send button that's
|
|
|
435
975
|
|
|
436
976
|
---
|
|
437
977
|
|
|
978
|
+
## Autofill profiles
|
|
979
|
+
|
|
980
|
+
```tsx
|
|
981
|
+
import { FieldFlowInput, autofillProfiles } from 'rn-inputforge';
|
|
982
|
+
|
|
983
|
+
<FieldFlowInput type="email" label="Email" autofill={autofillProfiles.signup.email} ... />
|
|
984
|
+
<FieldFlowInput type="password" label="Password" autofill="newPassword" ... />
|
|
985
|
+
<FieldFlowOTP autofill="oneTimeCode" ... /> // or pass through TextInput props
|
|
986
|
+
```
|
|
987
|
+
|
|
988
|
+
Roles: `email`, `password`, `newPassword`, `oneTimeCode`, `tel`, `name`, `streetAddress`, `ccNumber`, … — see `getAutofillProps` / `autofillProfiles`.
|
|
989
|
+
|
|
990
|
+
---
|
|
991
|
+
|
|
992
|
+
## Keyboard toolbar
|
|
993
|
+
|
|
994
|
+
```tsx
|
|
995
|
+
import {
|
|
996
|
+
FieldFlowKeyboardToolbar,
|
|
997
|
+
FIELD_FLOW_KEYBOARD_TOOLBAR_ID,
|
|
998
|
+
useKeyboardManager,
|
|
999
|
+
} from 'rn-inputforge';
|
|
1000
|
+
|
|
1001
|
+
const kb = useKeyboardManager({ order: ['email', 'password'], onSubmit: form.submit });
|
|
1002
|
+
|
|
1003
|
+
<>
|
|
1004
|
+
<FieldFlowInput
|
|
1005
|
+
inputAccessoryViewID={FIELD_FLOW_KEYBOARD_TOOLBAR_ID}
|
|
1006
|
+
...
|
|
1007
|
+
/>
|
|
1008
|
+
<FieldFlowKeyboardToolbar
|
|
1009
|
+
nativeID={FIELD_FLOW_KEYBOARD_TOOLBAR_ID}
|
|
1010
|
+
onPrevious={() => kb.focusPrevious(activeId)}
|
|
1011
|
+
onNext={() => kb.focusNext(activeId)}
|
|
1012
|
+
onDone={form.submit}
|
|
1013
|
+
canPrevious={kb.canGoPrevious(activeId)}
|
|
1014
|
+
canNext={kb.canGoNext(activeId)}
|
|
1015
|
+
/>
|
|
1016
|
+
</>
|
|
1017
|
+
```
|
|
1018
|
+
|
|
1019
|
+
---
|
|
1020
|
+
|
|
1021
|
+
## Smart paste
|
|
1022
|
+
|
|
1023
|
+
```tsx
|
|
1024
|
+
import { routeSmartPaste, useSmartPaste } from 'rn-inputforge';
|
|
1025
|
+
|
|
1026
|
+
const { handlePaste } = useSmartPaste({
|
|
1027
|
+
targets: {
|
|
1028
|
+
otp: r => setCode(r.value),
|
|
1029
|
+
card: r => setCardNumber(r.raw ?? r.value),
|
|
1030
|
+
email: r => form.handleChange('email')(r.value),
|
|
1031
|
+
addressFields: addr => {
|
|
1032
|
+
form.handleChange('street')(addr.street ?? '');
|
|
1033
|
+
form.handleChange('city')(addr.city ?? '');
|
|
1034
|
+
},
|
|
1035
|
+
},
|
|
1036
|
+
});
|
|
1037
|
+
|
|
1038
|
+
// After Clipboard.getString():
|
|
1039
|
+
handlePaste(pastedText);
|
|
1040
|
+
```
|
|
1041
|
+
|
|
1042
|
+
---
|
|
1043
|
+
|
|
1044
|
+
## Completeness coach
|
|
1045
|
+
|
|
1046
|
+
```tsx
|
|
1047
|
+
import { useFieldFlowCompleteness, FieldFlowCompleteness } from 'rn-inputforge';
|
|
1048
|
+
|
|
1049
|
+
const completeness = useFieldFlowCompleteness({
|
|
1050
|
+
values: form.values,
|
|
1051
|
+
requiredFields: ['name', 'email', 'password'],
|
|
1052
|
+
});
|
|
1053
|
+
|
|
1054
|
+
<FieldFlowCompleteness completeness={completeness} />;
|
|
1055
|
+
```
|
|
1056
|
+
|
|
1057
|
+
---
|
|
1058
|
+
|
|
1059
|
+
## Auth actions
|
|
1060
|
+
|
|
1061
|
+
```tsx
|
|
1062
|
+
import { FieldFlowAuthActions } from 'rn-inputforge';
|
|
1063
|
+
|
|
1064
|
+
<FieldFlowAuthActions
|
|
1065
|
+
actions={[
|
|
1066
|
+
{ id: 'passkey', label: 'Passkey', icon: 'key', onPress: signInWithPasskey },
|
|
1067
|
+
{ id: 'apple', label: 'Apple', icon: 'user', onPress: signInWithApple },
|
|
1068
|
+
{ id: 'google', label: 'Google', icon: 'globe', onPress: signInWithGoogle },
|
|
1069
|
+
]}
|
|
1070
|
+
/>
|
|
1071
|
+
```
|
|
1072
|
+
|
|
1073
|
+
---
|
|
1074
|
+
|
|
1075
|
+
## Schema form renderer
|
|
1076
|
+
|
|
1077
|
+
```tsx
|
|
1078
|
+
import { FieldFlowSchemaForm, type FieldFlowFormSchema } from 'rn-inputforge';
|
|
1079
|
+
|
|
1080
|
+
const schema: FieldFlowFormSchema = {
|
|
1081
|
+
fields: [
|
|
1082
|
+
{ name: 'name', type: 'text', label: 'Name', required: true, section: 'profile', autofill: 'name' },
|
|
1083
|
+
{ name: 'email', type: 'email', label: 'Email', required: true, section: 'profile' },
|
|
1084
|
+
{ name: 'plan', type: 'segmented', label: 'Plan', options: [
|
|
1085
|
+
{ label: 'Free', value: 'free' },
|
|
1086
|
+
{ label: 'Pro', value: 'pro' },
|
|
1087
|
+
]},
|
|
1088
|
+
],
|
|
1089
|
+
sections: [{ id: 'profile', title: 'Profile', icon: 'user' }],
|
|
1090
|
+
};
|
|
1091
|
+
|
|
1092
|
+
<FieldFlowSchemaForm
|
|
1093
|
+
schema={schema}
|
|
1094
|
+
onSubmit={async values => api.save(values)}
|
|
1095
|
+
renderFooter={({ submit, isSubmitting }) => (
|
|
1096
|
+
<Button title={isSubmitting ? '…' : 'Save'} onPress={() => void submit()} />
|
|
1097
|
+
)}
|
|
1098
|
+
/>;
|
|
1099
|
+
```
|
|
1100
|
+
|
|
1101
|
+
---
|
|
1102
|
+
|
|
1103
|
+
## A11y auditor
|
|
1104
|
+
|
|
1105
|
+
```tsx
|
|
1106
|
+
import { FieldFlowA11yAudit, runA11yAudit } from 'rn-inputforge';
|
|
1107
|
+
|
|
1108
|
+
<FieldFlowA11yAudit
|
|
1109
|
+
audit={{
|
|
1110
|
+
fields: [
|
|
1111
|
+
{ name: 'email', label: 'Email', required: true, hasAccessibilityLabel: true },
|
|
1112
|
+
{ name: 'bio', placeholderOnly: true, hitHeight: 36 },
|
|
1113
|
+
],
|
|
1114
|
+
respectsReducedMotion: true,
|
|
1115
|
+
}}
|
|
1116
|
+
/>;
|
|
1117
|
+
```
|
|
1118
|
+
|
|
1119
|
+
Dev-only by default (`devOnly`).
|
|
1120
|
+
|
|
1121
|
+
---
|
|
1122
|
+
|
|
1123
|
+
## Offline submit queue
|
|
1124
|
+
|
|
1125
|
+
```tsx
|
|
1126
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
1127
|
+
import { useFieldFlowSubmitQueue } from 'rn-inputforge';
|
|
1128
|
+
|
|
1129
|
+
const queue = useFieldFlowSubmitQueue({
|
|
1130
|
+
key: 'signup-queue',
|
|
1131
|
+
storage: AsyncStorage,
|
|
1132
|
+
submit: async payload => {
|
|
1133
|
+
await api.signup(payload);
|
|
1134
|
+
},
|
|
1135
|
+
});
|
|
1136
|
+
|
|
1137
|
+
// Instead of failing hard when offline:
|
|
1138
|
+
await queue.enqueue(form.values);
|
|
1139
|
+
// queue.pendingCount / queue.flush() / queue.clear()
|
|
1140
|
+
```
|
|
1141
|
+
|
|
1142
|
+
---
|
|
1143
|
+
|
|
1144
|
+
## Custom render slots
|
|
1145
|
+
|
|
1146
|
+
Most controls accept optional render props so apps can keep FieldFlow behavior and swap chrome:
|
|
1147
|
+
|
|
1148
|
+
| Component | Slots |
|
|
1149
|
+
| --------- | ----- |
|
|
1150
|
+
| `FieldFlowUpload` | `renderDropzone`, `renderFile` |
|
|
1151
|
+
| `FieldFlowTypeahead` | `renderOption`, `renderEmpty` |
|
|
1152
|
+
| `FieldFlowRating` | `renderStar` |
|
|
1153
|
+
| `FieldFlowSlider` | `renderThumb` |
|
|
1154
|
+
| `FieldFlowNumberStepper` | `renderDecrease`, `renderIncrease`, `renderValue` |
|
|
1155
|
+
| `FieldFlowPhone` | `renderDialButton`, `renderCountryOption` |
|
|
1156
|
+
| `FieldFlowStepper` | `renderStep`, `headerRight` |
|
|
1157
|
+
| `FieldFlowSignature` | `renderClear`, `renderPlaceholder` |
|
|
1158
|
+
|
|
1159
|
+
```tsx
|
|
1160
|
+
<FieldFlowRating
|
|
1161
|
+
value={rating}
|
|
1162
|
+
onChange={setRating}
|
|
1163
|
+
renderStar={({ filled, size }) => (
|
|
1164
|
+
<Text style={{ fontSize: size }}>{filled ? '🟢' : '⚪'}</Text>
|
|
1165
|
+
)}
|
|
1166
|
+
/>
|
|
1167
|
+
|
|
1168
|
+
<FieldFlowUpload
|
|
1169
|
+
pick={myPicker}
|
|
1170
|
+
value={files}
|
|
1171
|
+
onChange={setFiles}
|
|
1172
|
+
renderFile={({ file, remove }) => (
|
|
1173
|
+
<Pressable onPress={remove}>
|
|
1174
|
+
<Text>{file.name} ✕</Text>
|
|
1175
|
+
</Pressable>
|
|
1176
|
+
)}
|
|
1177
|
+
/>
|
|
1178
|
+
```
|
|
1179
|
+
|
|
1180
|
+
Defaults stay unchanged when you omit these props.
|
|
1181
|
+
|
|
1182
|
+
---
|
|
1183
|
+
|
|
1184
|
+
## Visual system
|
|
1185
|
+
|
|
1186
|
+
One-liner knobs on `FieldFlowThemeProvider` — easy on the eyes, fully customizable:
|
|
1187
|
+
|
|
1188
|
+
```tsx
|
|
1189
|
+
<FieldFlowThemeProvider
|
|
1190
|
+
theme={themePresets.soft}
|
|
1191
|
+
density="comfortable" // compact | comfortable | spacious
|
|
1192
|
+
size="md" // sm | md | lg
|
|
1193
|
+
shape="rounded" // square | rounded | pill
|
|
1194
|
+
surface="soft" // flat | elevated | soft | inset
|
|
1195
|
+
focusRing="softGlow" // solid | softGlow | underlinePulse
|
|
1196
|
+
animateTheme // soft crossfade when theme changes
|
|
1197
|
+
>
|
|
1198
|
+
<App />
|
|
1199
|
+
</FieldFlowThemeProvider>
|
|
1200
|
+
```
|
|
1201
|
+
|
|
1202
|
+
### Inline alert / skeleton / form header
|
|
1203
|
+
|
|
1204
|
+
```tsx
|
|
1205
|
+
<FieldFlowFormHeader
|
|
1206
|
+
title="Create account"
|
|
1207
|
+
subtitle="A calm start — we’ll guide you through a few short steps."
|
|
1208
|
+
progress={0.35}
|
|
1209
|
+
/>
|
|
1210
|
+
|
|
1211
|
+
<FieldFlowInlineAlert tone="info" title="Privacy" message="We’ll never share your email." />
|
|
1212
|
+
|
|
1213
|
+
{loading ? <FieldFlowSkeleton count={4} lastMultiline /> : <FormFields />}
|
|
1214
|
+
```
|
|
1215
|
+
|
|
1216
|
+
### Info tip + helper status
|
|
1217
|
+
|
|
1218
|
+
```tsx
|
|
1219
|
+
<FieldFlowInput
|
|
1220
|
+
label="Tax ID"
|
|
1221
|
+
infoTip="Used only for invoices. Never shown publicly."
|
|
1222
|
+
helperText="Optional for personal accounts"
|
|
1223
|
+
helperStatus="info"
|
|
1224
|
+
...
|
|
1225
|
+
/>
|
|
1226
|
+
```
|
|
1227
|
+
|
|
1228
|
+
---
|
|
1229
|
+
|
|
1230
|
+
## Motion & UI
|
|
1231
|
+
|
|
1232
|
+
### Field motion
|
|
1233
|
+
|
|
1234
|
+
`FieldFlowInput` ships with micro-interactions on by default (`motion={true}`):
|
|
1235
|
+
|
|
1236
|
+
- **Focus glow** — soft ring around the field chrome
|
|
1237
|
+
- **Error shake** — brief horizontal shake when validation fails
|
|
1238
|
+
- **Message fade** — helper / error text cross-fades in
|
|
1239
|
+
- **Success pop** — right-side success icon scales in
|
|
1240
|
+
|
|
1241
|
+
All of this uses React Native `Animated` (no Reanimated) and **respects OS Reduce Motion**. Pass `motion={false}` to disable per field, or use `useReducedMotion` / `useFieldMotion` if you build custom chrome.
|
|
1242
|
+
|
|
1243
|
+
```tsx
|
|
1244
|
+
<FieldFlowInput label="Email" type="email" value={email} onChangeText={setEmail} motion />
|
|
1245
|
+
```
|
|
1246
|
+
|
|
1247
|
+
### Prefix & suffix
|
|
1248
|
+
|
|
1249
|
+
Inline affixes sit inside the field before / after the value (alongside icons):
|
|
1250
|
+
|
|
1251
|
+
```tsx
|
|
1252
|
+
<FieldFlowInput
|
|
1253
|
+
type="phone"
|
|
1254
|
+
label="Phone"
|
|
1255
|
+
prefix="+92"
|
|
1256
|
+
value={phone}
|
|
1257
|
+
onChangeText={setPhone}
|
|
1258
|
+
/>
|
|
1259
|
+
|
|
1260
|
+
<FieldFlowInput
|
|
1261
|
+
type="decimal"
|
|
1262
|
+
label="Weight"
|
|
1263
|
+
suffix="kg"
|
|
1264
|
+
value={weight}
|
|
1265
|
+
onChangeText={setWeight}
|
|
1266
|
+
/>
|
|
1267
|
+
```
|
|
1268
|
+
|
|
1269
|
+
### Form sections
|
|
1270
|
+
|
|
1271
|
+
Group related fields into a themed card with optional collapse:
|
|
1272
|
+
|
|
1273
|
+
```tsx
|
|
1274
|
+
import { FieldFlowSection, FieldFlowInput } from 'rn-inputforge';
|
|
1275
|
+
|
|
1276
|
+
<FieldFlowSection title="Account" description="How we’ll reach you" icon="mail" collapsible>
|
|
1277
|
+
<FieldFlowInput type="email" label="Email" value={email} onChangeText={setEmail} />
|
|
1278
|
+
<FieldFlowInput type="phone" label="Phone" prefix="+1" value={phone} onChangeText={setPhone} />
|
|
1279
|
+
</FieldFlowSection>;
|
|
1280
|
+
```
|
|
1281
|
+
|
|
1282
|
+
### Segmented control
|
|
1283
|
+
|
|
1284
|
+
Animated pill control for plan pickers, account type, filters:
|
|
1285
|
+
|
|
1286
|
+
```tsx
|
|
1287
|
+
import { FieldFlowSegmented } from 'rn-inputforge';
|
|
1288
|
+
|
|
1289
|
+
<FieldFlowSegmented
|
|
1290
|
+
label="Account type"
|
|
1291
|
+
value={accountType}
|
|
1292
|
+
onChange={setAccountType}
|
|
1293
|
+
options={[
|
|
1294
|
+
{ label: 'Personal', value: 'personal', icon: 'user' },
|
|
1295
|
+
{ label: 'Business', value: 'business', icon: 'globe' },
|
|
1296
|
+
]}
|
|
1297
|
+
/>;
|
|
1298
|
+
```
|
|
1299
|
+
|
|
1300
|
+
---
|
|
1301
|
+
|
|
438
1302
|
## Theming
|
|
439
1303
|
|
|
440
1304
|
Wrap your app (or just a screen) in `FieldFlowThemeProvider` and override only what you need — everything else falls back to the default theme:
|
|
441
1305
|
|
|
442
1306
|
```tsx
|
|
443
|
-
import { FieldFlowThemeProvider } from 'rn-inputforge';
|
|
1307
|
+
import { FieldFlowThemeProvider, themePresets } from 'rn-inputforge';
|
|
1308
|
+
|
|
1309
|
+
// One-liner brand start
|
|
1310
|
+
<FieldFlowThemeProvider theme={themePresets.soft}>
|
|
1311
|
+
<App />
|
|
1312
|
+
</FieldFlowThemeProvider>
|
|
444
1313
|
|
|
1314
|
+
// Or merge your own tokens
|
|
445
1315
|
<FieldFlowThemeProvider
|
|
446
1316
|
theme={{
|
|
447
1317
|
colors: { borderFocused: '#7C3AED', labelFocused: '#7C3AED' },
|
|
@@ -452,8 +1322,49 @@ import { FieldFlowThemeProvider } from 'rn-inputforge';
|
|
|
452
1322
|
</FieldFlowThemeProvider>;
|
|
453
1323
|
```
|
|
454
1324
|
|
|
1325
|
+
**Bundled presets:** `default`, `dark`, `soft`, `warm`, `teal`, `midnight`, `contrast`. Use `getThemePreset('teal')` if you prefer a function call.
|
|
1326
|
+
|
|
455
1327
|
You can also pass a one-off `theme` prop directly to any single field to override it locally, or use the bundled `darkTheme` as a starting point for dark mode.
|
|
456
1328
|
|
|
1329
|
+
Theme tokens you can override: `colors.*`, `spacing.*`, `typography.*`, `animation.*` (see `FieldFlowTheme` in the package types).
|
|
1330
|
+
|
|
1331
|
+
---
|
|
1332
|
+
|
|
1333
|
+
## Public API at a glance
|
|
1334
|
+
|
|
1335
|
+
Import anything below from `'rn-inputforge'`:
|
|
1336
|
+
|
|
1337
|
+
```ts
|
|
1338
|
+
// Components
|
|
1339
|
+
FieldFlowInput, FieldFlowOTP, FieldFlowMaskedInput, FieldFlowDateTimePicker,
|
|
1340
|
+
FieldFlowCheckbox, FieldFlowRadio, FieldFlowSwitch, FieldFlowDropdown,
|
|
1341
|
+
FieldFlowTags, FieldFlowSegmented, FieldFlowSection, FieldFlowAffordance,
|
|
1342
|
+
FieldFlowDraftBanner, FieldFlowPasswordStrength, FieldFlowStepper,
|
|
1343
|
+
FieldFlowPhone, FieldFlowUpload, FieldFlowTypeahead, FieldFlowRating,
|
|
1344
|
+
FieldFlowSlider, FieldFlowNumberStepper, FieldFlowCreditCard, FieldFlowSignature,
|
|
1345
|
+
DescriptionField, ChatInput, KeyboardAwareFormWrapper
|
|
1346
|
+
|
|
1347
|
+
// Form hooks
|
|
1348
|
+
useFieldFlowForm, useFieldFlowArray, useFieldFlowDraft,
|
|
1349
|
+
useFieldFlowSteps, useFieldFlowDirtyGuard,
|
|
1350
|
+
useKeyboardManager, useFieldState, useFormIntelligence
|
|
1351
|
+
|
|
1352
|
+
// Motion / Theming / i18n
|
|
1353
|
+
useFieldMotion, useReducedMotion
|
|
1354
|
+
FieldFlowThemeProvider, themePresets, getThemePreset, defaultTheme, darkTheme
|
|
1355
|
+
getValidationMessages, createValidationMessages, validationMessageCatalogs
|
|
1356
|
+
|
|
1357
|
+
// Adapters / Icons
|
|
1358
|
+
FieldFlowController, FieldFlowTagsController, mapRhfToFieldFlowProps
|
|
1359
|
+
FieldFlowIcon, renderFieldFlowIcon
|
|
1360
|
+
|
|
1361
|
+
// Validation, masks, phone, a11y
|
|
1362
|
+
runRules, zod helpers, applyMask, unmask, DEFAULT_COUNTRY_DIALS,
|
|
1363
|
+
evaluatePasswordStrength, focusFirstError, announceForAccessibility, …
|
|
1364
|
+
```
|
|
1365
|
+
|
|
1366
|
+
Types for props, themes, rules, and draft storage are exported alongside the values. See `example/App.tsx` for a full usage reference screen.
|
|
1367
|
+
|
|
457
1368
|
---
|
|
458
1369
|
|
|
459
1370
|
## Project structure
|
|
@@ -462,25 +1373,34 @@ You can also pass a one-off `theme` prop directly to any single field to overrid
|
|
|
462
1373
|
rn-inputforge/
|
|
463
1374
|
├── src/
|
|
464
1375
|
│ ├── components/
|
|
465
|
-
│ │ ├── FieldFlowInput/
|
|
466
|
-
│ │ ├──
|
|
467
|
-
│ │ ├──
|
|
468
|
-
│ │ ├──
|
|
469
|
-
│ │ ├──
|
|
470
|
-
│ │ ├──
|
|
471
|
-
│ │ ├──
|
|
472
|
-
│ │ ├──
|
|
473
|
-
│ │ ├──
|
|
474
|
-
│ │ ├──
|
|
475
|
-
│ │ ├──
|
|
1376
|
+
│ │ ├── FieldFlowInput/ core input + variants + motion + affixes
|
|
1377
|
+
│ │ ├── FieldFlowSection/ themed form card / collapse
|
|
1378
|
+
│ │ ├── FieldFlowSegmented/ animated pill control
|
|
1379
|
+
│ │ ├── FieldFlowAffordance/ standalone suggestion chip bar
|
|
1380
|
+
│ │ ├── FieldFlowOTP/ OTP / PIN digit cells
|
|
1381
|
+
│ │ ├── FieldFlowMaskedInput/ phone, card, currency, date, custom masks
|
|
1382
|
+
│ │ ├── FieldFlowDateTimePicker/ date / time / datetime (pure JS)
|
|
1383
|
+
│ │ ├── FieldFlowCheckbox/ themed checkbox
|
|
1384
|
+
│ │ ├── FieldFlowRadio/ radio group
|
|
1385
|
+
│ │ ├── FieldFlowSwitch/ animated switch
|
|
1386
|
+
│ │ ├── FieldFlowDraftBanner/ resume-draft UI
|
|
1387
|
+
│ │ ├── FieldFlowTags/ multi-value chip input
|
|
1388
|
+
│ │ ├── FieldFlowPasswordStrength/ strength meter + rules
|
|
1389
|
+
│ │ ├── DescriptionField/ auto-growing multiline field
|
|
1390
|
+
│ │ ├── ChatInput/ chat composer + attachment toolbar
|
|
1391
|
+
│ │ ├── FieldFlowDropdown/ single/multi select
|
|
476
1392
|
│ │ └── KeyboardAwareFormWrapper/
|
|
477
|
-
│ ├──
|
|
478
|
-
│ ├──
|
|
479
|
-
│ ├──
|
|
480
|
-
│ ├──
|
|
481
|
-
│ ├──
|
|
482
|
-
│
|
|
483
|
-
├──
|
|
1393
|
+
│ ├── adapters/ react-hook-form Controllers
|
|
1394
|
+
│ ├── hooks/ form, array, draft, intelligence, keyboard
|
|
1395
|
+
│ ├── intelligence/ a11y helpers + friction report types
|
|
1396
|
+
│ ├── motion/ field motion + reduce-motion hooks
|
|
1397
|
+
│ ├── theme/ ThemeProvider + presets + default/dark
|
|
1398
|
+
│ ├── validation/ validators, Zod adapter
|
|
1399
|
+
│ ├── icons/ dependency-free icon set
|
|
1400
|
+
│ ├── utils/ masks, affordance, password strength, …
|
|
1401
|
+
│ ├── __tests__/ Jest unit tests
|
|
1402
|
+
│ └── index.ts public API
|
|
1403
|
+
├── example/App.tsx full usage reference
|
|
484
1404
|
├── package.json
|
|
485
1405
|
└── tsconfig*.json
|
|
486
1406
|
```
|