rn-inputforge 0.4.0 → 0.5.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/README.md +723 -39
- 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/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/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/FieldFlowInput/FieldFlowInput.js +143 -43
- package/lib/commonjs/components/FieldFlowInput/FieldFlowInput.js.map +1 -1
- package/lib/commonjs/components/FieldFlowInput/styles.js +16 -0
- package/lib/commonjs/components/FieldFlowInput/styles.js.map +1 -1
- 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/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/hooks/index.js +35 -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/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/useFormIntelligence.js +130 -0
- package/lib/commonjs/hooks/useFormIntelligence.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 +322 -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/theme/index.js +13 -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/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/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/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/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/FieldFlowInput/FieldFlowInput.js +144 -44
- package/lib/module/components/FieldFlowInput/FieldFlowInput.js.map +1 -1
- package/lib/module/components/FieldFlowInput/styles.js +16 -0
- package/lib/module/components/FieldFlowInput/styles.js.map +1 -1
- 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/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/hooks/index.js +5 -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/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/useFormIntelligence.js +126 -0
- package/lib/module/hooks/useFormIntelligence.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 +31 -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/theme/index.js +1 -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/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/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/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/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/FieldFlowInput/FieldFlowInput.d.ts.map +1 -1
- package/lib/typescript/components/FieldFlowInput/styles.d.ts +16 -0
- package/lib/typescript/components/FieldFlowInput/styles.d.ts.map +1 -1
- package/lib/typescript/components/FieldFlowInput/types.d.ts +32 -0
- package/lib/typescript/components/FieldFlowInput/types.d.ts.map +1 -1
- 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/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/hooks/index.d.ts +11 -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/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/useFormIntelligence.d.ts +23 -0
- package/lib/typescript/hooks/useFormIntelligence.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 +48 -4
- 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/theme/index.d.ts +2 -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/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/adapters/index.ts +9 -0
- package/src/adapters/reactHookForm.tsx +152 -0
- package/src/components/FieldFlowAffordance/FieldFlowAffordance.tsx +143 -0
- package/src/components/FieldFlowAffordance/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/FieldFlowInput/FieldFlowInput.tsx +174 -53
- package/src/components/FieldFlowInput/styles.ts +16 -0
- package/src/components/FieldFlowInput/types.ts +33 -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/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/hooks/index.ts +31 -0
- package/src/hooks/useFieldFlowArray.ts +153 -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/useFormIntelligence.ts +207 -0
- package/src/i18n/index.ts +6 -0
- package/src/i18n/messages.ts +101 -0
- package/src/index.ts +161 -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/theme/index.ts +2 -0
- package/src/theme/presets.ts +120 -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,107 @@
|
|
|
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
|
+
| Already on React Hook Form | [`FieldFlowController`](#react-hook-form-adapter) |
|
|
52
|
+
|
|
53
|
+
### UI polish & branding
|
|
54
|
+
|
|
55
|
+
| You need… | Use |
|
|
56
|
+
| --------- | --- |
|
|
57
|
+
| Group fields in a card / collapse | [`FieldFlowSection`](#motion--ui) |
|
|
58
|
+
| Focus glow, error shake, success pop | [`motion` on inputs](#motion--ui) · `useFieldMotion` |
|
|
59
|
+
| `+92` / `$` / `kg` inside the field | [`prefix` / `suffix`](#motion--ui) |
|
|
60
|
+
| Email domain / dial-code chips | [`suggestions`](#smart-suggestion-chips) · [`FieldFlowAffordance`](#smart-suggestion-chips) |
|
|
61
|
+
| Password meter | [`showStrength`](#password-strength) |
|
|
62
|
+
| Look: outlined / filled / underline / floating | [Variants](#variants) |
|
|
63
|
+
| Built-in icons (no icon pack) | [Icons](#icons) |
|
|
64
|
+
| Brand colors in one line | [`themePresets`](#theming) · [`FieldFlowThemeProvider`](#theming) |
|
|
65
|
+
|
|
66
|
+
### Helpers (also exported)
|
|
67
|
+
|
|
68
|
+
Masks (`applyMask`, `unmask`, …) · password strength (`evaluatePasswordStrength`) · affordance helpers · a11y (`focusFirstError`, `announceForAccessibility`) · validators · Zod adapters · `FieldFlowIcon` / `renderFieldFlowIcon`
|
|
69
|
+
|
|
70
|
+
**Full walkthrough:** [Quick start](#quick-start) · [Try it](#try-it-expo--snack) · [Public API](#public-api-at-a-glance)
|
|
10
71
|
|
|
11
|
-
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## What's new in 0.5.0
|
|
12
75
|
|
|
13
76
|
| Addition | What you get |
|
|
14
77
|
| -------- | ------------ |
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
| **
|
|
22
|
-
| **
|
|
23
|
-
| **
|
|
24
|
-
| **
|
|
25
|
-
| **
|
|
26
|
-
| **
|
|
27
|
-
|
|
28
|
-
**
|
|
29
|
-
|
|
30
|
-
|
|
78
|
+
| **Smart Affordance** | Email / phone / currency suggestion chips |
|
|
79
|
+
| **Form Intelligence** | Friction report + autofocus / announce on failed submit |
|
|
80
|
+
| **Conditional fields** | `showWhen` / `requiredWhen` / `disabledWhen` |
|
|
81
|
+
| **Field arrays** | `useFieldFlowArray` |
|
|
82
|
+
| **Draft resume** | `useFieldFlowDraft` + `FieldFlowDraftBanner` |
|
|
83
|
+
| **Password strength** | `showStrength` / `FieldFlowPasswordStrength` |
|
|
84
|
+
| **Tags** | `FieldFlowTags` |
|
|
85
|
+
| **React Hook Form** | `FieldFlowController` / `FieldFlowTagsController` |
|
|
86
|
+
| **Motion UI** | Glow, shake, fade, success pop (`motion` prop) |
|
|
87
|
+
| **Sections** | `FieldFlowSection` |
|
|
88
|
+
| **Theme presets** | `themePresets.soft` / `warm` / `teal` / `midnight` / `contrast` |
|
|
89
|
+
| **Prefix / suffix** | Inline affixes on inputs |
|
|
90
|
+
| **Segmented** | `FieldFlowSegmented` |
|
|
91
|
+
| **Multi-step wizard** | `useFieldFlowSteps` + `FieldFlowStepper` |
|
|
92
|
+
| **Phone + country** | `FieldFlowPhone` |
|
|
93
|
+
| **File upload** | `FieldFlowUpload` (inject your picker) |
|
|
94
|
+
| **Typeahead** | `FieldFlowTypeahead` (async `fetchOptions`) |
|
|
95
|
+
| **Server errors** | `setErrors` / `setFieldError` / `clearErrors` |
|
|
96
|
+
| **Rating / slider / +/-** | `FieldFlowRating`, `FieldFlowSlider`, `FieldFlowNumberStepper` |
|
|
97
|
+
| **Dirty leave guard** | `useFieldFlowDirtyGuard` + `isDirty` |
|
|
98
|
+
| **i18n messages** | `locale` / `messages` (`en` `es` `fr` `de` `pt` `ar`) |
|
|
99
|
+
| **Credit card group** | `FieldFlowCreditCard` |
|
|
100
|
+
| **Signature pad** | `FieldFlowSignature` |
|
|
101
|
+
|
|
102
|
+
Still from **0.4.0:** OTP, masks, date/time, checkbox/radio/switch, variants, icons, async + cross-field validation, Zod, Expo.
|
|
103
|
+
|
|
104
|
+
> **Note:** since 0.4.0, `validateField` / `validateAll` return `Promise<boolean>`.
|
|
31
105
|
|
|
32
106
|
---
|
|
33
107
|
|
|
@@ -52,6 +126,7 @@ That's it — this is a pure JavaScript/TypeScript package (no native code), so
|
|
|
52
126
|
- Works with Expo SDK that ships RN ≥ 0.73
|
|
53
127
|
- TypeScript is optional but recommended (type defs are bundled)
|
|
54
128
|
- `zod` is an **optional** peer dependency (only if you use the Zod helpers)
|
|
129
|
+
- `react-hook-form` is an **optional** peer dependency (only if you use `FieldFlowController`)
|
|
55
130
|
|
|
56
131
|
---
|
|
57
132
|
|
|
@@ -95,6 +170,24 @@ Setting `type="email"` automatically wires up the email keyboard, disables autoc
|
|
|
95
170
|
| `description` | default, multi-line | used internally by `DescriptionField` |
|
|
96
171
|
| `chat` | default | used internally by `ChatInput` |
|
|
97
172
|
|
|
173
|
+
### Core `FieldFlowInput` props (cheat sheet)
|
|
174
|
+
|
|
175
|
+
| Prop | Purpose |
|
|
176
|
+
| ---- | ------- |
|
|
177
|
+
| `type` | Keyboard + defaults (`email`, `password`, `phone`, …) |
|
|
178
|
+
| `variant` | `outlined` \| `filled` \| `underline` \| `floating` |
|
|
179
|
+
| `label` / `helperText` / `errorText` / `successText` | Copy + states |
|
|
180
|
+
| `rules` / `validateOnChange` | Built-in validation |
|
|
181
|
+
| `leftIcon` / `rightIcon` / `iconSize` / `clearable` | Icons (built-in name or custom node) |
|
|
182
|
+
| `prefix` / `suffix` | Inline affix text or node |
|
|
183
|
+
| `suggestions` | Smart chips (`true`, `'email'`, custom list) |
|
|
184
|
+
| `showStrength` | Password strength meter |
|
|
185
|
+
| `motion` | Micro-interactions (default `true`) |
|
|
186
|
+
| `maxLength` / `showCharacterCount` | Limits + counter |
|
|
187
|
+
| `theme` / style props | Per-field override |
|
|
188
|
+
|
|
189
|
+
All standard `TextInput` props still pass through (placeholder, `returnKeyType`, etc.).
|
|
190
|
+
|
|
98
191
|
---
|
|
99
192
|
|
|
100
193
|
## Validation
|
|
@@ -203,6 +296,429 @@ Also exported: `zodToFormErrors`, `createZodSubmitGuard`, `fieldRulesFromZodStri
|
|
|
203
296
|
|
|
204
297
|
---
|
|
205
298
|
|
|
299
|
+
## Try it (Expo / Snack)
|
|
300
|
+
|
|
301
|
+
1. Create a blank Snack at [snack.expo.dev](https://snack.expo.dev).
|
|
302
|
+
2. Add dependency `rn-inputforge` (and `react-hook-form` if you try the RHF adapter).
|
|
303
|
+
3. Paste any snippet from this README or copy `example/App.tsx` from the repo.
|
|
304
|
+
|
|
305
|
+
Same install works in a local Expo app:
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
npx create-expo-app MyFormDemo
|
|
309
|
+
cd MyFormDemo
|
|
310
|
+
npx expo install rn-inputforge
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Password strength
|
|
316
|
+
|
|
317
|
+
```tsx
|
|
318
|
+
<FieldFlowInput
|
|
319
|
+
type="password"
|
|
320
|
+
label="Password"
|
|
321
|
+
value={password}
|
|
322
|
+
onChangeText={setPassword}
|
|
323
|
+
showStrength
|
|
324
|
+
// or: showStrength={{ showRules: true, rules: customRules }}
|
|
325
|
+
/>
|
|
326
|
+
|
|
327
|
+
// Standalone meter
|
|
328
|
+
<FieldFlowPasswordStrength password={password} />
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Pure helper: `evaluatePasswordStrength(password)` → `{ level, progress, passed, failed }`.
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## Tags / chip input
|
|
336
|
+
|
|
337
|
+
```tsx
|
|
338
|
+
const [skills, setSkills] = useState<string[]>([]);
|
|
339
|
+
|
|
340
|
+
<FieldFlowTags
|
|
341
|
+
label="Skills"
|
|
342
|
+
value={skills}
|
|
343
|
+
onChange={setSkills}
|
|
344
|
+
maxTags={8}
|
|
345
|
+
placeholder="Type a skill and press Enter"
|
|
346
|
+
helperText="Comma or Enter to add"
|
|
347
|
+
/>
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## React Hook Form adapter
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
npm install react-hook-form
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
```tsx
|
|
359
|
+
import { useForm } from 'react-hook-form';
|
|
360
|
+
import { FieldFlowController, FieldFlowTagsController } from 'rn-inputforge';
|
|
361
|
+
|
|
362
|
+
const { control, handleSubmit } = useForm({
|
|
363
|
+
defaultValues: { email: '', skills: [] as string[] },
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
<FieldFlowController
|
|
367
|
+
control={control}
|
|
368
|
+
name="email"
|
|
369
|
+
type="email"
|
|
370
|
+
label="Email"
|
|
371
|
+
suggestions
|
|
372
|
+
rules={{ required: 'Email is required' }}
|
|
373
|
+
/>
|
|
374
|
+
|
|
375
|
+
<FieldFlowTagsController
|
|
376
|
+
control={control}
|
|
377
|
+
name="skills"
|
|
378
|
+
label="Skills"
|
|
379
|
+
rules={{ validate: v => (v?.length ? true : 'Add at least one skill') }}
|
|
380
|
+
/>
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
Also exported: `mapRhfToFieldFlowProps` for custom `Controller` renders.
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## Smart suggestion chips
|
|
388
|
+
|
|
389
|
+
Show quick-complete chips while a field is focused — a UX gap most RN input kits skip:
|
|
390
|
+
|
|
391
|
+
```tsx
|
|
392
|
+
// Infer from type: email → @gmail.com…, phone → +1/+44…, number/decimal → $/€/£
|
|
393
|
+
<FieldFlowInput type="email" label="Email" value={email} onChangeText={setEmail} suggestions />
|
|
394
|
+
|
|
395
|
+
// Force a preset or pass a custom list
|
|
396
|
+
<FieldFlowInput type="phone" suggestions="phone" value={phone} onChangeText={setPhone} />
|
|
397
|
+
<FieldFlowInput suggestions={['@company.com', '@partner.io']} value={work} onChangeText={setWork} />
|
|
398
|
+
|
|
399
|
+
// Standalone bar (e.g. above the keyboard area)
|
|
400
|
+
<FieldFlowAffordance
|
|
401
|
+
kind="email"
|
|
402
|
+
value={email}
|
|
403
|
+
onSelect={setEmail}
|
|
404
|
+
/>
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
Helpers exported: `applyEmailDomainSuggestion`, `DEFAULT_EMAIL_DOMAINS`, `DEFAULT_PHONE_DIAL_CODES`, `DEFAULT_CURRENCY_SYMBOLS`.
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
## Form intelligence
|
|
412
|
+
|
|
413
|
+
Enable friction tracking and accessibility autopilot on the form hook:
|
|
414
|
+
|
|
415
|
+
```tsx
|
|
416
|
+
const form = useFieldFlowForm({
|
|
417
|
+
initialValues: { email: '', password: '' },
|
|
418
|
+
rules: { email: { required: true, email: true }, password: { required: true, minLength: 8 } },
|
|
419
|
+
fieldOrder: ['email', 'password'],
|
|
420
|
+
intelligence: {
|
|
421
|
+
onReport: report => console.log(report.mostFriction),
|
|
422
|
+
// focusFirstError: true (default)
|
|
423
|
+
// announceErrors: true (default) — VoiceOver / TalkBack
|
|
424
|
+
},
|
|
425
|
+
onSubmit: async values => api.login(values),
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
<FieldFlowInput
|
|
429
|
+
ref={r => form.registerFieldRef('email', { current: r })}
|
|
430
|
+
label="Email"
|
|
431
|
+
{...form.getInputProps('email')}
|
|
432
|
+
suggestions
|
|
433
|
+
/>;
|
|
434
|
+
|
|
435
|
+
// After interactions:
|
|
436
|
+
form.intelligence?.getReport();
|
|
437
|
+
// → { sessionMs, submitAttempts, fields: { email: { focusCount, errorCount, totalFocusMs, … } }, mostFriction }
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
Standalone helpers: `useFormIntelligence`, `focusFirstError`, `announceForAccessibility`.
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## Conditional fields & field arrays
|
|
445
|
+
|
|
446
|
+
```tsx
|
|
447
|
+
const form = useFieldFlowForm({
|
|
448
|
+
initialValues: { accountType: 'personal', company: '', taxId: '' },
|
|
449
|
+
conditions: {
|
|
450
|
+
company: {
|
|
451
|
+
showWhen: v => v.accountType === 'business',
|
|
452
|
+
requiredWhen: v => v.accountType === 'business',
|
|
453
|
+
},
|
|
454
|
+
taxId: {
|
|
455
|
+
showWhen: v => v.accountType === 'business',
|
|
456
|
+
disabledWhen: v => v.accountType !== 'business',
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
{form.isVisible('company') && (
|
|
462
|
+
<FieldFlowInput label="Company" {...form.getInputProps('company')!} />
|
|
463
|
+
)}
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
Repeatable groups:
|
|
467
|
+
|
|
468
|
+
```tsx
|
|
469
|
+
import { useFieldFlowArray, FieldFlowInput } from 'rn-inputforge';
|
|
470
|
+
|
|
471
|
+
const guests = useFieldFlowArray({
|
|
472
|
+
createItem: () => ({ name: '', email: '' }),
|
|
473
|
+
min: 1,
|
|
474
|
+
max: 5,
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
{guests.items.map((guest, i) => (
|
|
478
|
+
<FieldFlowInput
|
|
479
|
+
key={i}
|
|
480
|
+
label={`Guest ${i + 1}`}
|
|
481
|
+
value={guest.name}
|
|
482
|
+
onChangeText={name => guests.update(i, g => ({ ...g, name }))}
|
|
483
|
+
/>
|
|
484
|
+
))}
|
|
485
|
+
<Button title="Add guest" disabled={guests.isMax} onPress={() => guests.append()} />
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
---
|
|
489
|
+
|
|
490
|
+
## Draft resume
|
|
491
|
+
|
|
492
|
+
Persist form values with any storage backend (AsyncStorage, MMKV, custom). No hard dependency:
|
|
493
|
+
|
|
494
|
+
```tsx
|
|
495
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
496
|
+
import { useFieldFlowDraft, FieldFlowDraftBanner, useFieldFlowForm } from 'rn-inputforge';
|
|
497
|
+
|
|
498
|
+
const form = useFieldFlowForm({ initialValues: { name: '', email: '' }, /* … */ });
|
|
499
|
+
|
|
500
|
+
const draft = useFieldFlowDraft({
|
|
501
|
+
key: 'signup-v1',
|
|
502
|
+
storage: {
|
|
503
|
+
getItem: k => AsyncStorage.getItem(k),
|
|
504
|
+
setItem: (k, v) => AsyncStorage.setItem(k, v),
|
|
505
|
+
removeItem: k => AsyncStorage.removeItem(k),
|
|
506
|
+
},
|
|
507
|
+
values: form.values,
|
|
508
|
+
onRestore: form.setValues,
|
|
509
|
+
exclude: ['password'], // never persist secrets
|
|
510
|
+
ttlMs: 7 * 24 * 60 * 60 * 1000,
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
<FieldFlowDraftBanner
|
|
514
|
+
visible={draft.hasDraft}
|
|
515
|
+
savedAt={draft.draftSavedAt}
|
|
516
|
+
onResume={draft.resume}
|
|
517
|
+
onDiscard={draft.discard}
|
|
518
|
+
/>;
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
On successful submit, call `await draft.clear()` so the banner doesn't reappear.
|
|
522
|
+
|
|
523
|
+
---
|
|
524
|
+
|
|
525
|
+
## Multi-step wizard
|
|
526
|
+
|
|
527
|
+
```tsx
|
|
528
|
+
import { useFieldFlowForm, useFieldFlowSteps, FieldFlowStepper, FieldFlowInput } from 'rn-inputforge';
|
|
529
|
+
|
|
530
|
+
const form = useFieldFlowForm({
|
|
531
|
+
initialValues: { name: '', email: '', bio: '' },
|
|
532
|
+
rules: {
|
|
533
|
+
name: { required: true },
|
|
534
|
+
email: { required: true, email: true },
|
|
535
|
+
},
|
|
536
|
+
onSubmit: async values => api.signup(values),
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
const wizard = useFieldFlowSteps({
|
|
540
|
+
values: form.values,
|
|
541
|
+
validateFields: form.validateFields,
|
|
542
|
+
onComplete: form.submit,
|
|
543
|
+
steps: [
|
|
544
|
+
{ id: 'profile', title: 'Profile', fields: ['name'] },
|
|
545
|
+
{ id: 'contact', title: 'Contact', fields: ['email'] },
|
|
546
|
+
{ id: 'about', title: 'About', fields: ['bio'] },
|
|
547
|
+
],
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
<>
|
|
551
|
+
<FieldFlowStepper steps={wizard.steps} stepIndex={wizard.stepIndex} onStepPress={wizard.goTo} />
|
|
552
|
+
{wizard.step.id === 'profile' && <FieldFlowInput label="Name" {...form.getInputProps('name')!} />}
|
|
553
|
+
{wizard.step.id === 'contact' && <FieldFlowInput type="email" label="Email" {...form.getInputProps('email')!} />}
|
|
554
|
+
{wizard.step.id === 'about' && <FieldFlowInput label="Bio" {...form.getInputProps('bio')!} />}
|
|
555
|
+
<Button title={wizard.isLast ? 'Submit' : 'Next'} onPress={() => wizard.next()} />
|
|
556
|
+
{!wizard.isFirst && <Button title="Back" onPress={wizard.back} />}
|
|
557
|
+
</>;
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
---
|
|
561
|
+
|
|
562
|
+
## Server errors
|
|
563
|
+
|
|
564
|
+
Map API 422 responses straight into the form:
|
|
565
|
+
|
|
566
|
+
```tsx
|
|
567
|
+
try {
|
|
568
|
+
await api.signup(form.values);
|
|
569
|
+
} catch (err) {
|
|
570
|
+
// { email: 'Already taken', password: 'Too weak' }
|
|
571
|
+
form.setErrors(err.fieldErrors);
|
|
572
|
+
// or: form.setFieldError('email', 'Already taken');
|
|
573
|
+
// form.clearErrors('email') / form.clearErrors()
|
|
574
|
+
}
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
Also available: `form.isDirty`, `form.dirtyFields`, `form.validateFields(['email', 'password'])`.
|
|
578
|
+
|
|
579
|
+
---
|
|
580
|
+
|
|
581
|
+
## Localized validation
|
|
582
|
+
|
|
583
|
+
```tsx
|
|
584
|
+
const form = useFieldFlowForm({
|
|
585
|
+
initialValues: { email: '' },
|
|
586
|
+
rules: { email: { required: true, email: true } },
|
|
587
|
+
locale: 'es', // en | es | fr | de | pt | ar
|
|
588
|
+
// or: messages: createValidationMessages({ required: 'Custom…' }, 'en'),
|
|
589
|
+
});
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
Helpers: `getValidationMessages('fr')`, `validationMessageCatalogs`, `createValidationMessages`.
|
|
593
|
+
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
## Dirty leave guard
|
|
597
|
+
|
|
598
|
+
```tsx
|
|
599
|
+
import { useFieldFlowDirtyGuard } from 'rn-inputforge';
|
|
600
|
+
|
|
601
|
+
const { confirmIfDirty } = useFieldFlowDirtyGuard({
|
|
602
|
+
isDirty: form.isDirty,
|
|
603
|
+
onDiscard: form.reset,
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
// React Navigation:
|
|
607
|
+
navigation.addListener('beforeRemove', async e => {
|
|
608
|
+
if (!form.isDirty) return;
|
|
609
|
+
e.preventDefault();
|
|
610
|
+
if (await confirmIfDirty()) navigation.dispatch(e.data.action);
|
|
611
|
+
});
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
Android hardware back is intercepted automatically when dirty.
|
|
615
|
+
|
|
616
|
+
---
|
|
617
|
+
|
|
618
|
+
## Phone with country code
|
|
619
|
+
|
|
620
|
+
```tsx
|
|
621
|
+
import { FieldFlowPhone } from 'rn-inputforge';
|
|
622
|
+
|
|
623
|
+
const [phone, setPhone] = useState(null);
|
|
624
|
+
|
|
625
|
+
<FieldFlowPhone
|
|
626
|
+
label="Mobile"
|
|
627
|
+
value={phone}
|
|
628
|
+
onChange={setPhone}
|
|
629
|
+
defaultCountryCode="PK"
|
|
630
|
+
required
|
|
631
|
+
/>;
|
|
632
|
+
// phone.e164 → "+923001234567"
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
---
|
|
636
|
+
|
|
637
|
+
## File / image upload
|
|
638
|
+
|
|
639
|
+
Pure JS — you inject the picker (Expo or RN):
|
|
640
|
+
|
|
641
|
+
```tsx
|
|
642
|
+
import * as ImagePicker from 'expo-image-picker';
|
|
643
|
+
import { FieldFlowUpload } from 'rn-inputforge';
|
|
644
|
+
|
|
645
|
+
<FieldFlowUpload
|
|
646
|
+
label="ID photo"
|
|
647
|
+
maxFiles={2}
|
|
648
|
+
value={files}
|
|
649
|
+
onChange={setFiles}
|
|
650
|
+
pick={async () => {
|
|
651
|
+
const res = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ['images'] });
|
|
652
|
+
if (res.canceled || !res.assets[0]) return null;
|
|
653
|
+
const a = res.assets[0];
|
|
654
|
+
return { uri: a.uri, name: a.fileName ?? 'photo.jpg', mimeType: a.mimeType, size: a.fileSize };
|
|
655
|
+
}}
|
|
656
|
+
/>;
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
---
|
|
660
|
+
|
|
661
|
+
## Async typeahead
|
|
662
|
+
|
|
663
|
+
```tsx
|
|
664
|
+
import { FieldFlowTypeahead } from 'rn-inputforge';
|
|
665
|
+
|
|
666
|
+
<FieldFlowTypeahead
|
|
667
|
+
label="City"
|
|
668
|
+
value={city}
|
|
669
|
+
displayValue={cityLabel}
|
|
670
|
+
onChange={(value, option) => {
|
|
671
|
+
setCity(value);
|
|
672
|
+
setCityLabel(option?.label ?? '');
|
|
673
|
+
}}
|
|
674
|
+
fetchOptions={async query => {
|
|
675
|
+
const rows = await api.searchCities(query);
|
|
676
|
+
return rows.map(r => ({ label: r.name, value: r.id }));
|
|
677
|
+
}}
|
|
678
|
+
minChars={2}
|
|
679
|
+
/>;
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
---
|
|
683
|
+
|
|
684
|
+
## Rating / slider / number stepper
|
|
685
|
+
|
|
686
|
+
```tsx
|
|
687
|
+
<FieldFlowRating label="Experience" value={rating} onChange={setRating} />
|
|
688
|
+
<FieldFlowSlider label="Budget" value={budget} onChange={setBudget} min={0} max={1000} step={50} />
|
|
689
|
+
<FieldFlowNumberStepper label="Guests" value={guests} onChange={setGuests} min={1} max={12} />
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
---
|
|
693
|
+
|
|
694
|
+
## Credit card group
|
|
695
|
+
|
|
696
|
+
```tsx
|
|
697
|
+
import { FieldFlowCreditCard } from 'rn-inputforge';
|
|
698
|
+
|
|
699
|
+
const [card, setCard] = useState({ number: '', expiry: '', cvc: '', name: '' });
|
|
700
|
+
|
|
701
|
+
<FieldFlowCreditCard value={card} onChange={setCard} showName required />;
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
---
|
|
705
|
+
|
|
706
|
+
## Signature pad
|
|
707
|
+
|
|
708
|
+
```tsx
|
|
709
|
+
import { FieldFlowSignature } from 'rn-inputforge';
|
|
710
|
+
|
|
711
|
+
<FieldFlowSignature
|
|
712
|
+
label="Sign to confirm"
|
|
713
|
+
value={signature}
|
|
714
|
+
onChange={setSignature}
|
|
715
|
+
required
|
|
716
|
+
/>;
|
|
717
|
+
// signature.isEmpty / signature.strokes
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
---
|
|
721
|
+
|
|
206
722
|
## Variants
|
|
207
723
|
|
|
208
724
|
Every text-like field (`FieldFlowInput`, `FieldFlowMaskedInput`, date picker trigger) supports:
|
|
@@ -435,13 +951,131 @@ Handles expandable height, keyboard-avoiding behavior, and a send button that's
|
|
|
435
951
|
|
|
436
952
|
---
|
|
437
953
|
|
|
954
|
+
## Custom render slots
|
|
955
|
+
|
|
956
|
+
Most controls accept optional render props so apps can keep FieldFlow behavior and swap chrome:
|
|
957
|
+
|
|
958
|
+
| Component | Slots |
|
|
959
|
+
| --------- | ----- |
|
|
960
|
+
| `FieldFlowUpload` | `renderDropzone`, `renderFile` |
|
|
961
|
+
| `FieldFlowTypeahead` | `renderOption`, `renderEmpty` |
|
|
962
|
+
| `FieldFlowRating` | `renderStar` |
|
|
963
|
+
| `FieldFlowSlider` | `renderThumb` |
|
|
964
|
+
| `FieldFlowNumberStepper` | `renderDecrease`, `renderIncrease`, `renderValue` |
|
|
965
|
+
| `FieldFlowPhone` | `renderDialButton`, `renderCountryOption` |
|
|
966
|
+
| `FieldFlowStepper` | `renderStep`, `headerRight` |
|
|
967
|
+
| `FieldFlowSignature` | `renderClear`, `renderPlaceholder` |
|
|
968
|
+
|
|
969
|
+
```tsx
|
|
970
|
+
<FieldFlowRating
|
|
971
|
+
value={rating}
|
|
972
|
+
onChange={setRating}
|
|
973
|
+
renderStar={({ filled, size }) => (
|
|
974
|
+
<Text style={{ fontSize: size }}>{filled ? '🟢' : '⚪'}</Text>
|
|
975
|
+
)}
|
|
976
|
+
/>
|
|
977
|
+
|
|
978
|
+
<FieldFlowUpload
|
|
979
|
+
pick={myPicker}
|
|
980
|
+
value={files}
|
|
981
|
+
onChange={setFiles}
|
|
982
|
+
renderFile={({ file, remove }) => (
|
|
983
|
+
<Pressable onPress={remove}>
|
|
984
|
+
<Text>{file.name} ✕</Text>
|
|
985
|
+
</Pressable>
|
|
986
|
+
)}
|
|
987
|
+
/>
|
|
988
|
+
```
|
|
989
|
+
|
|
990
|
+
Defaults stay unchanged when you omit these props.
|
|
991
|
+
|
|
992
|
+
---
|
|
993
|
+
|
|
994
|
+
## Motion & UI
|
|
995
|
+
|
|
996
|
+
### Field motion
|
|
997
|
+
|
|
998
|
+
`FieldFlowInput` ships with micro-interactions on by default (`motion={true}`):
|
|
999
|
+
|
|
1000
|
+
- **Focus glow** — soft ring around the field chrome
|
|
1001
|
+
- **Error shake** — brief horizontal shake when validation fails
|
|
1002
|
+
- **Message fade** — helper / error text cross-fades in
|
|
1003
|
+
- **Success pop** — right-side success icon scales in
|
|
1004
|
+
|
|
1005
|
+
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.
|
|
1006
|
+
|
|
1007
|
+
```tsx
|
|
1008
|
+
<FieldFlowInput label="Email" type="email" value={email} onChangeText={setEmail} motion />
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
### Prefix & suffix
|
|
1012
|
+
|
|
1013
|
+
Inline affixes sit inside the field before / after the value (alongside icons):
|
|
1014
|
+
|
|
1015
|
+
```tsx
|
|
1016
|
+
<FieldFlowInput
|
|
1017
|
+
type="phone"
|
|
1018
|
+
label="Phone"
|
|
1019
|
+
prefix="+92"
|
|
1020
|
+
value={phone}
|
|
1021
|
+
onChangeText={setPhone}
|
|
1022
|
+
/>
|
|
1023
|
+
|
|
1024
|
+
<FieldFlowInput
|
|
1025
|
+
type="decimal"
|
|
1026
|
+
label="Weight"
|
|
1027
|
+
suffix="kg"
|
|
1028
|
+
value={weight}
|
|
1029
|
+
onChangeText={setWeight}
|
|
1030
|
+
/>
|
|
1031
|
+
```
|
|
1032
|
+
|
|
1033
|
+
### Form sections
|
|
1034
|
+
|
|
1035
|
+
Group related fields into a themed card with optional collapse:
|
|
1036
|
+
|
|
1037
|
+
```tsx
|
|
1038
|
+
import { FieldFlowSection, FieldFlowInput } from 'rn-inputforge';
|
|
1039
|
+
|
|
1040
|
+
<FieldFlowSection title="Account" description="How we’ll reach you" icon="mail" collapsible>
|
|
1041
|
+
<FieldFlowInput type="email" label="Email" value={email} onChangeText={setEmail} />
|
|
1042
|
+
<FieldFlowInput type="phone" label="Phone" prefix="+1" value={phone} onChangeText={setPhone} />
|
|
1043
|
+
</FieldFlowSection>;
|
|
1044
|
+
```
|
|
1045
|
+
|
|
1046
|
+
### Segmented control
|
|
1047
|
+
|
|
1048
|
+
Animated pill control for plan pickers, account type, filters:
|
|
1049
|
+
|
|
1050
|
+
```tsx
|
|
1051
|
+
import { FieldFlowSegmented } from 'rn-inputforge';
|
|
1052
|
+
|
|
1053
|
+
<FieldFlowSegmented
|
|
1054
|
+
label="Account type"
|
|
1055
|
+
value={accountType}
|
|
1056
|
+
onChange={setAccountType}
|
|
1057
|
+
options={[
|
|
1058
|
+
{ label: 'Personal', value: 'personal', icon: 'user' },
|
|
1059
|
+
{ label: 'Business', value: 'business', icon: 'globe' },
|
|
1060
|
+
]}
|
|
1061
|
+
/>;
|
|
1062
|
+
```
|
|
1063
|
+
|
|
1064
|
+
---
|
|
1065
|
+
|
|
438
1066
|
## Theming
|
|
439
1067
|
|
|
440
1068
|
Wrap your app (or just a screen) in `FieldFlowThemeProvider` and override only what you need — everything else falls back to the default theme:
|
|
441
1069
|
|
|
442
1070
|
```tsx
|
|
443
|
-
import { FieldFlowThemeProvider } from 'rn-inputforge';
|
|
1071
|
+
import { FieldFlowThemeProvider, themePresets } from 'rn-inputforge';
|
|
1072
|
+
|
|
1073
|
+
// One-liner brand start
|
|
1074
|
+
<FieldFlowThemeProvider theme={themePresets.soft}>
|
|
1075
|
+
<App />
|
|
1076
|
+
</FieldFlowThemeProvider>
|
|
444
1077
|
|
|
1078
|
+
// Or merge your own tokens
|
|
445
1079
|
<FieldFlowThemeProvider
|
|
446
1080
|
theme={{
|
|
447
1081
|
colors: { borderFocused: '#7C3AED', labelFocused: '#7C3AED' },
|
|
@@ -452,8 +1086,49 @@ import { FieldFlowThemeProvider } from 'rn-inputforge';
|
|
|
452
1086
|
</FieldFlowThemeProvider>;
|
|
453
1087
|
```
|
|
454
1088
|
|
|
1089
|
+
**Bundled presets:** `default`, `dark`, `soft`, `warm`, `teal`, `midnight`, `contrast`. Use `getThemePreset('teal')` if you prefer a function call.
|
|
1090
|
+
|
|
455
1091
|
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
1092
|
|
|
1093
|
+
Theme tokens you can override: `colors.*`, `spacing.*`, `typography.*`, `animation.*` (see `FieldFlowTheme` in the package types).
|
|
1094
|
+
|
|
1095
|
+
---
|
|
1096
|
+
|
|
1097
|
+
## Public API at a glance
|
|
1098
|
+
|
|
1099
|
+
Import anything below from `'rn-inputforge'`:
|
|
1100
|
+
|
|
1101
|
+
```ts
|
|
1102
|
+
// Components
|
|
1103
|
+
FieldFlowInput, FieldFlowOTP, FieldFlowMaskedInput, FieldFlowDateTimePicker,
|
|
1104
|
+
FieldFlowCheckbox, FieldFlowRadio, FieldFlowSwitch, FieldFlowDropdown,
|
|
1105
|
+
FieldFlowTags, FieldFlowSegmented, FieldFlowSection, FieldFlowAffordance,
|
|
1106
|
+
FieldFlowDraftBanner, FieldFlowPasswordStrength, FieldFlowStepper,
|
|
1107
|
+
FieldFlowPhone, FieldFlowUpload, FieldFlowTypeahead, FieldFlowRating,
|
|
1108
|
+
FieldFlowSlider, FieldFlowNumberStepper, FieldFlowCreditCard, FieldFlowSignature,
|
|
1109
|
+
DescriptionField, ChatInput, KeyboardAwareFormWrapper
|
|
1110
|
+
|
|
1111
|
+
// Form hooks
|
|
1112
|
+
useFieldFlowForm, useFieldFlowArray, useFieldFlowDraft,
|
|
1113
|
+
useFieldFlowSteps, useFieldFlowDirtyGuard,
|
|
1114
|
+
useKeyboardManager, useFieldState, useFormIntelligence
|
|
1115
|
+
|
|
1116
|
+
// Motion / Theming / i18n
|
|
1117
|
+
useFieldMotion, useReducedMotion
|
|
1118
|
+
FieldFlowThemeProvider, themePresets, getThemePreset, defaultTheme, darkTheme
|
|
1119
|
+
getValidationMessages, createValidationMessages, validationMessageCatalogs
|
|
1120
|
+
|
|
1121
|
+
// Adapters / Icons
|
|
1122
|
+
FieldFlowController, FieldFlowTagsController, mapRhfToFieldFlowProps
|
|
1123
|
+
FieldFlowIcon, renderFieldFlowIcon
|
|
1124
|
+
|
|
1125
|
+
// Validation, masks, phone, a11y
|
|
1126
|
+
runRules, zod helpers, applyMask, unmask, DEFAULT_COUNTRY_DIALS,
|
|
1127
|
+
evaluatePasswordStrength, focusFirstError, announceForAccessibility, …
|
|
1128
|
+
```
|
|
1129
|
+
|
|
1130
|
+
Types for props, themes, rules, and draft storage are exported alongside the values. See `example/App.tsx` for a full usage reference screen.
|
|
1131
|
+
|
|
457
1132
|
---
|
|
458
1133
|
|
|
459
1134
|
## Project structure
|
|
@@ -462,25 +1137,34 @@ You can also pass a one-off `theme` prop directly to any single field to overrid
|
|
|
462
1137
|
rn-inputforge/
|
|
463
1138
|
├── src/
|
|
464
1139
|
│ ├── components/
|
|
465
|
-
│ │ ├── FieldFlowInput/
|
|
466
|
-
│ │ ├──
|
|
467
|
-
│ │ ├──
|
|
468
|
-
│ │ ├──
|
|
469
|
-
│ │ ├──
|
|
470
|
-
│ │ ├──
|
|
471
|
-
│ │ ├──
|
|
472
|
-
│ │ ├──
|
|
473
|
-
│ │ ├──
|
|
474
|
-
│ │ ├──
|
|
475
|
-
│ │ ├──
|
|
1140
|
+
│ │ ├── FieldFlowInput/ core input + variants + motion + affixes
|
|
1141
|
+
│ │ ├── FieldFlowSection/ themed form card / collapse
|
|
1142
|
+
│ │ ├── FieldFlowSegmented/ animated pill control
|
|
1143
|
+
│ │ ├── FieldFlowAffordance/ standalone suggestion chip bar
|
|
1144
|
+
│ │ ├── FieldFlowOTP/ OTP / PIN digit cells
|
|
1145
|
+
│ │ ├── FieldFlowMaskedInput/ phone, card, currency, date, custom masks
|
|
1146
|
+
│ │ ├── FieldFlowDateTimePicker/ date / time / datetime (pure JS)
|
|
1147
|
+
│ │ ├── FieldFlowCheckbox/ themed checkbox
|
|
1148
|
+
│ │ ├── FieldFlowRadio/ radio group
|
|
1149
|
+
│ │ ├── FieldFlowSwitch/ animated switch
|
|
1150
|
+
│ │ ├── FieldFlowDraftBanner/ resume-draft UI
|
|
1151
|
+
│ │ ├── FieldFlowTags/ multi-value chip input
|
|
1152
|
+
│ │ ├── FieldFlowPasswordStrength/ strength meter + rules
|
|
1153
|
+
│ │ ├── DescriptionField/ auto-growing multiline field
|
|
1154
|
+
│ │ ├── ChatInput/ chat composer + attachment toolbar
|
|
1155
|
+
│ │ ├── FieldFlowDropdown/ single/multi select
|
|
476
1156
|
│ │ └── KeyboardAwareFormWrapper/
|
|
477
|
-
│ ├──
|
|
478
|
-
│ ├──
|
|
479
|
-
│ ├──
|
|
480
|
-
│ ├──
|
|
481
|
-
│ ├──
|
|
482
|
-
│
|
|
483
|
-
├──
|
|
1157
|
+
│ ├── adapters/ react-hook-form Controllers
|
|
1158
|
+
│ ├── hooks/ form, array, draft, intelligence, keyboard
|
|
1159
|
+
│ ├── intelligence/ a11y helpers + friction report types
|
|
1160
|
+
│ ├── motion/ field motion + reduce-motion hooks
|
|
1161
|
+
│ ├── theme/ ThemeProvider + presets + default/dark
|
|
1162
|
+
│ ├── validation/ validators, Zod adapter
|
|
1163
|
+
│ ├── icons/ dependency-free icon set
|
|
1164
|
+
│ ├── utils/ masks, affordance, password strength, …
|
|
1165
|
+
│ ├── __tests__/ Jest unit tests
|
|
1166
|
+
│ └── index.ts public API
|
|
1167
|
+
├── example/App.tsx full usage reference
|
|
484
1168
|
├── package.json
|
|
485
1169
|
└── tsconfig*.json
|
|
486
1170
|
```
|