rn-inputforge 0.3.1 → 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 +909 -20
- 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/FieldFlowCheckbox/FieldFlowCheckbox.js +131 -0
- package/lib/commonjs/components/FieldFlowCheckbox/FieldFlowCheckbox.js.map +1 -0
- package/lib/commonjs/components/FieldFlowCheckbox/index.js +13 -0
- package/lib/commonjs/components/FieldFlowCheckbox/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/FieldFlowDateTimePicker/FieldFlowDateTimePicker.js +536 -0
- package/lib/commonjs/components/FieldFlowDateTimePicker/FieldFlowDateTimePicker.js.map +1 -0
- package/lib/commonjs/components/FieldFlowDateTimePicker/index.js +13 -0
- package/lib/commonjs/components/FieldFlowDateTimePicker/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowDateTimePicker/types.js +6 -0
- package/lib/commonjs/components/FieldFlowDateTimePicker/types.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/FieldFlowDropdown/FieldFlowDropdown.js +24 -9
- package/lib/commonjs/components/FieldFlowDropdown/FieldFlowDropdown.js.map +1 -1
- package/lib/commonjs/components/FieldFlowInput/FieldFlowInput.js +187 -56
- package/lib/commonjs/components/FieldFlowInput/FieldFlowInput.js.map +1 -1
- package/lib/commonjs/components/FieldFlowInput/styles.js +48 -11
- package/lib/commonjs/components/FieldFlowInput/styles.js.map +1 -1
- package/lib/commonjs/components/FieldFlowMaskedInput/FieldFlowMaskedInput.js +66 -0
- package/lib/commonjs/components/FieldFlowMaskedInput/FieldFlowMaskedInput.js.map +1 -0
- package/lib/commonjs/components/FieldFlowMaskedInput/index.js +13 -0
- package/lib/commonjs/components/FieldFlowMaskedInput/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowMaskedInput/types.js +6 -0
- package/lib/commonjs/components/FieldFlowMaskedInput/types.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/FieldFlowOTP/FieldFlowOTP.js +255 -0
- package/lib/commonjs/components/FieldFlowOTP/FieldFlowOTP.js.map +1 -0
- package/lib/commonjs/components/FieldFlowOTP/index.js +13 -0
- package/lib/commonjs/components/FieldFlowOTP/index.js.map +1 -0
- package/lib/commonjs/components/FieldFlowOTP/types.js +6 -0
- package/lib/commonjs/components/FieldFlowOTP/types.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/FieldFlowRadio/FieldFlowRadio.js +164 -0
- package/lib/commonjs/components/FieldFlowRadio/FieldFlowRadio.js.map +1 -0
- package/lib/commonjs/components/FieldFlowRadio/index.js +13 -0
- package/lib/commonjs/components/FieldFlowRadio/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/FieldFlowSwitch/FieldFlowSwitch.js +152 -0
- package/lib/commonjs/components/FieldFlowSwitch/FieldFlowSwitch.js.map +1 -0
- package/lib/commonjs/components/FieldFlowSwitch/index.js +13 -0
- package/lib/commonjs/components/FieldFlowSwitch/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 +350 -41
- 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/icons/Icon.js +719 -30
- package/lib/commonjs/icons/Icon.js.map +1 -1
- package/lib/commonjs/icons/index.js +7 -0
- package/lib/commonjs/icons/index.js.map +1 -1
- package/lib/commonjs/icons/renderIcon.js +24 -0
- package/lib/commonjs/icons/renderIcon.js.map +1 -0
- package/lib/commonjs/index.js +449 -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/masks.js +130 -0
- package/lib/commonjs/utils/masks.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/index.js +25 -0
- package/lib/commonjs/validation/index.js.map +1 -1
- package/lib/commonjs/validation/validators.js +10 -7
- package/lib/commonjs/validation/validators.js.map +1 -1
- package/lib/commonjs/validation/zodAdapter.js +91 -0
- package/lib/commonjs/validation/zodAdapter.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/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/FieldFlowCheckbox/FieldFlowCheckbox.js +126 -0
- package/lib/module/components/FieldFlowCheckbox/FieldFlowCheckbox.js.map +1 -0
- package/lib/module/components/FieldFlowCheckbox/index.js +4 -0
- package/lib/module/components/FieldFlowCheckbox/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/FieldFlowDateTimePicker/FieldFlowDateTimePicker.js +531 -0
- package/lib/module/components/FieldFlowDateTimePicker/FieldFlowDateTimePicker.js.map +1 -0
- package/lib/module/components/FieldFlowDateTimePicker/index.js +4 -0
- package/lib/module/components/FieldFlowDateTimePicker/index.js.map +1 -0
- package/lib/module/components/FieldFlowDateTimePicker/types.js +4 -0
- package/lib/module/components/FieldFlowDateTimePicker/types.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/FieldFlowDropdown/FieldFlowDropdown.js +24 -9
- package/lib/module/components/FieldFlowDropdown/FieldFlowDropdown.js.map +1 -1
- package/lib/module/components/FieldFlowInput/FieldFlowInput.js +190 -59
- package/lib/module/components/FieldFlowInput/FieldFlowInput.js.map +1 -1
- package/lib/module/components/FieldFlowInput/styles.js +48 -11
- package/lib/module/components/FieldFlowInput/styles.js.map +1 -1
- package/lib/module/components/FieldFlowMaskedInput/FieldFlowMaskedInput.js +61 -0
- package/lib/module/components/FieldFlowMaskedInput/FieldFlowMaskedInput.js.map +1 -0
- package/lib/module/components/FieldFlowMaskedInput/index.js +4 -0
- package/lib/module/components/FieldFlowMaskedInput/index.js.map +1 -0
- package/lib/module/components/FieldFlowMaskedInput/types.js +4 -0
- package/lib/module/components/FieldFlowMaskedInput/types.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/FieldFlowOTP/FieldFlowOTP.js +250 -0
- package/lib/module/components/FieldFlowOTP/FieldFlowOTP.js.map +1 -0
- package/lib/module/components/FieldFlowOTP/index.js +4 -0
- package/lib/module/components/FieldFlowOTP/index.js.map +1 -0
- package/lib/module/components/FieldFlowOTP/types.js +4 -0
- package/lib/module/components/FieldFlowOTP/types.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/FieldFlowRadio/FieldFlowRadio.js +159 -0
- package/lib/module/components/FieldFlowRadio/FieldFlowRadio.js.map +1 -0
- package/lib/module/components/FieldFlowRadio/index.js +4 -0
- package/lib/module/components/FieldFlowRadio/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/FieldFlowSwitch/FieldFlowSwitch.js +147 -0
- package/lib/module/components/FieldFlowSwitch/FieldFlowSwitch.js.map +1 -0
- package/lib/module/components/FieldFlowSwitch/index.js +4 -0
- package/lib/module/components/FieldFlowSwitch/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 +351 -42
- 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/icons/Icon.js +720 -31
- package/lib/module/icons/Icon.js.map +1 -1
- package/lib/module/icons/index.js +1 -0
- package/lib/module/icons/index.js.map +1 -1
- package/lib/module/icons/renderIcon.js +19 -0
- package/lib/module/icons/renderIcon.js.map +1 -0
- package/lib/module/index.js +42 -5
- 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/masks.js +118 -0
- package/lib/module/utils/masks.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/index.js +1 -0
- package/lib/module/validation/index.js.map +1 -1
- package/lib/module/validation/validators.js +10 -7
- package/lib/module/validation/validators.js.map +1 -1
- package/lib/module/validation/zodAdapter.js +84 -0
- package/lib/module/validation/zodAdapter.js.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/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/FieldFlowCheckbox/FieldFlowCheckbox.d.ts +36 -0
- package/lib/typescript/components/FieldFlowCheckbox/FieldFlowCheckbox.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowCheckbox/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowCheckbox/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/FieldFlowDateTimePicker/FieldFlowDateTimePicker.d.ts +4 -0
- package/lib/typescript/components/FieldFlowDateTimePicker/FieldFlowDateTimePicker.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowDateTimePicker/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowDateTimePicker/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowDateTimePicker/types.d.ts +55 -0
- package/lib/typescript/components/FieldFlowDateTimePicker/types.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/FieldFlowDropdown/FieldFlowDropdown.d.ts.map +1 -1
- package/lib/typescript/components/FieldFlowDropdown/types.d.ts +7 -1
- package/lib/typescript/components/FieldFlowDropdown/types.d.ts.map +1 -1
- package/lib/typescript/components/FieldFlowInput/FieldFlowInput.d.ts.map +1 -1
- package/lib/typescript/components/FieldFlowInput/styles.d.ts +35 -2
- package/lib/typescript/components/FieldFlowInput/styles.d.ts.map +1 -1
- package/lib/typescript/components/FieldFlowInput/types.d.ts +55 -4
- package/lib/typescript/components/FieldFlowInput/types.d.ts.map +1 -1
- package/lib/typescript/components/FieldFlowMaskedInput/FieldFlowMaskedInput.d.ts +5 -0
- package/lib/typescript/components/FieldFlowMaskedInput/FieldFlowMaskedInput.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowMaskedInput/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowMaskedInput/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowMaskedInput/types.d.ts +20 -0
- package/lib/typescript/components/FieldFlowMaskedInput/types.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/FieldFlowOTP/FieldFlowOTP.d.ts +4 -0
- package/lib/typescript/components/FieldFlowOTP/FieldFlowOTP.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowOTP/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowOTP/index.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowOTP/types.d.ts +52 -0
- package/lib/typescript/components/FieldFlowOTP/types.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/FieldFlowRadio/FieldFlowRadio.d.ts +39 -0
- package/lib/typescript/components/FieldFlowRadio/FieldFlowRadio.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowRadio/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowRadio/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/FieldFlowSwitch/FieldFlowSwitch.d.ts +31 -0
- package/lib/typescript/components/FieldFlowSwitch/FieldFlowSwitch.d.ts.map +1 -0
- package/lib/typescript/components/FieldFlowSwitch/index.d.ts +3 -0
- package/lib/typescript/components/FieldFlowSwitch/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 +124 -7
- 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/icons/Icon.d.ts +2 -2
- package/lib/typescript/icons/Icon.d.ts.map +1 -1
- package/lib/typescript/icons/index.d.ts +2 -0
- package/lib/typescript/icons/index.d.ts.map +1 -1
- package/lib/typescript/icons/renderIcon.d.ts +6 -0
- package/lib/typescript/icons/renderIcon.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +67 -9
- 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/types/index.d.ts +4 -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/masks.d.ts +37 -0
- package/lib/typescript/utils/masks.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/index.d.ts +2 -0
- package/lib/typescript/validation/index.d.ts.map +1 -1
- package/lib/typescript/validation/validators.d.ts +3 -1
- package/lib/typescript/validation/validators.d.ts.map +1 -1
- package/lib/typescript/validation/zodAdapter.d.ts +53 -0
- package/lib/typescript/validation/zodAdapter.d.ts.map +1 -0
- package/package.json +34 -3
- 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/FieldFlowCheckbox/FieldFlowCheckbox.tsx +174 -0
- package/src/components/FieldFlowCheckbox/index.ts +2 -0
- package/src/components/FieldFlowCreditCard/FieldFlowCreditCard.tsx +152 -0
- package/src/components/FieldFlowCreditCard/index.ts +2 -0
- package/src/components/FieldFlowDateTimePicker/FieldFlowDateTimePicker.tsx +585 -0
- package/src/components/FieldFlowDateTimePicker/index.ts +2 -0
- package/src/components/FieldFlowDateTimePicker/types.ts +57 -0
- package/src/components/FieldFlowDraftBanner/FieldFlowDraftBanner.tsx +169 -0
- package/src/components/FieldFlowDraftBanner/index.ts +2 -0
- package/src/components/FieldFlowDropdown/FieldFlowDropdown.tsx +17 -7
- package/src/components/FieldFlowDropdown/types.ts +8 -1
- package/src/components/FieldFlowInput/FieldFlowInput.tsx +230 -66
- package/src/components/FieldFlowInput/styles.ts +57 -6
- package/src/components/FieldFlowInput/types.ts +56 -4
- package/src/components/FieldFlowMaskedInput/FieldFlowMaskedInput.tsx +76 -0
- package/src/components/FieldFlowMaskedInput/index.ts +2 -0
- package/src/components/FieldFlowMaskedInput/types.ts +22 -0
- package/src/components/FieldFlowNumberStepper/FieldFlowNumberStepper.tsx +156 -0
- package/src/components/FieldFlowNumberStepper/index.ts +2 -0
- package/src/components/FieldFlowOTP/FieldFlowOTP.tsx +305 -0
- package/src/components/FieldFlowOTP/index.ts +2 -0
- package/src/components/FieldFlowOTP/types.ts +57 -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/FieldFlowRadio/FieldFlowRadio.tsx +215 -0
- package/src/components/FieldFlowRadio/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/FieldFlowSwitch/FieldFlowSwitch.tsx +172 -0
- package/src/components/FieldFlowSwitch/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 +34 -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 +545 -40
- 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/icons/Icon.tsx +451 -5
- package/src/icons/index.ts +2 -0
- package/src/icons/renderIcon.tsx +17 -0
- package/src/index.ts +208 -7
- 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/types/index.ts +5 -0
- package/src/utils/affordance.ts +138 -0
- package/src/utils/masks.ts +137 -0
- package/src/utils/passwordStrength.ts +109 -0
- package/src/utils/phoneCountries.ts +44 -0
- package/src/validation/index.ts +7 -0
- package/src/validation/validators.ts +17 -7
- package/src/validation/zodAdapter.ts +103 -0
package/README.md
CHANGED
|
@@ -1,8 +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
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
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)
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## What's new in 0.5.0
|
|
75
|
+
|
|
76
|
+
| Addition | What you get |
|
|
77
|
+
| -------- | ------------ |
|
|
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>`.
|
|
6
105
|
|
|
7
106
|
---
|
|
8
107
|
|
|
@@ -18,13 +117,16 @@ npm install rn-inputforge
|
|
|
18
117
|
yarn add rn-inputforge
|
|
19
118
|
```
|
|
20
119
|
|
|
21
|
-
That's it — this is a pure JavaScript/TypeScript package (no native code), so
|
|
120
|
+
That's it — this is a pure JavaScript/TypeScript package (no native code), so there is **no pod install step and no manual linking** required on bare React Native CLI. Same install works in **Expo** (Managed or Dev Client) — just `npx expo install` is not required for this package because it has no native dependencies; `npm install rn-inputforge` / `yarn add rn-inputforge` is enough.
|
|
22
121
|
|
|
23
122
|
### Requirements
|
|
24
123
|
|
|
25
124
|
- `react` >= 18 (tested against 19.2.x)
|
|
26
125
|
- `react-native` >= 0.73 (tested against 0.86.x)
|
|
126
|
+
- Works with Expo SDK that ships RN ≥ 0.73
|
|
27
127
|
- TypeScript is optional but recommended (type defs are bundled)
|
|
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`)
|
|
28
130
|
|
|
29
131
|
---
|
|
30
132
|
|
|
@@ -68,6 +170,24 @@ Setting `type="email"` automatically wires up the email keyboard, disables autoc
|
|
|
68
170
|
| `description` | default, multi-line | used internally by `DescriptionField` |
|
|
69
171
|
| `chat` | default | used internally by `ChatInput` |
|
|
70
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
|
+
|
|
71
191
|
---
|
|
72
192
|
|
|
73
193
|
## Validation
|
|
@@ -112,7 +232,613 @@ const form = useFieldFlowForm({
|
|
|
112
232
|
/>;
|
|
113
233
|
```
|
|
114
234
|
|
|
115
|
-
`form.submit()` validates every field and only calls `onSubmit` if everything passes.
|
|
235
|
+
`form.submit()` validates every field (including async + cross-field rules) and only calls `onSubmit` if everything passes.
|
|
236
|
+
|
|
237
|
+
### Cross-field & async validation
|
|
238
|
+
|
|
239
|
+
```tsx
|
|
240
|
+
const form = useFieldFlowForm({
|
|
241
|
+
initialValues: { password: '', confirm: '', email: '' },
|
|
242
|
+
rules: {
|
|
243
|
+
password: { required: true, minLength: 8 },
|
|
244
|
+
confirm: { required: true },
|
|
245
|
+
email: { required: true, email: true },
|
|
246
|
+
},
|
|
247
|
+
crossFieldRules: [
|
|
248
|
+
{
|
|
249
|
+
target: 'confirm',
|
|
250
|
+
deps: ['password'],
|
|
251
|
+
validate: v =>
|
|
252
|
+
v.password === v.confirm
|
|
253
|
+
? { valid: true }
|
|
254
|
+
: { valid: false, message: 'Passwords must match' },
|
|
255
|
+
},
|
|
256
|
+
],
|
|
257
|
+
asyncValidators: {
|
|
258
|
+
email: async value => {
|
|
259
|
+
const taken = await api.isEmailTaken(value);
|
|
260
|
+
return taken
|
|
261
|
+
? { valid: false, message: 'Email is already taken' }
|
|
262
|
+
: { valid: true };
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
// form.validating.email === true while the async check runs
|
|
268
|
+
// form.isValidating === true if any async validator is in flight
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
> **Note (0.4.0):** `validateField` and `validateAll` are now `async` and return `Promise<boolean>`.
|
|
272
|
+
|
|
273
|
+
### Zod (optional)
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
npm install zod
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
```tsx
|
|
280
|
+
import { z } from 'zod';
|
|
281
|
+
import { useFieldFlowForm, zodFormValidate } from 'rn-inputforge';
|
|
282
|
+
|
|
283
|
+
const schema = z.object({
|
|
284
|
+
email: z.string().email(),
|
|
285
|
+
password: z.string().min(8),
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
const form = useFieldFlowForm({
|
|
289
|
+
initialValues: { email: '', password: '' },
|
|
290
|
+
formValidate: zodFormValidate(schema),
|
|
291
|
+
onSubmit: async values => api.login(values),
|
|
292
|
+
});
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Also exported: `zodToFormErrors`, `createZodSubmitGuard`, `fieldRulesFromZodString`.
|
|
296
|
+
|
|
297
|
+
---
|
|
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
|
+
|
|
722
|
+
## Variants
|
|
723
|
+
|
|
724
|
+
Every text-like field (`FieldFlowInput`, `FieldFlowMaskedInput`, date picker trigger) supports:
|
|
725
|
+
|
|
726
|
+
| `variant` | Look |
|
|
727
|
+
| ------------ | ----------------------------------------- |
|
|
728
|
+
| `outlined` | Bordered box (default) |
|
|
729
|
+
| `filled` | Soft filled background |
|
|
730
|
+
| `underline` | Bottom border only |
|
|
731
|
+
| `floating` | Label animates into the border when filled / focused |
|
|
732
|
+
|
|
733
|
+
```tsx
|
|
734
|
+
<FieldFlowInput variant="floating" label="Email" type="email" value={email} onChangeText={setEmail} />
|
|
735
|
+
<FieldFlowInput variant="underline" label="Name" leftIcon="user" value={name} onChangeText={setName} />
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
## Icons
|
|
739
|
+
|
|
740
|
+
Built-in, dependency-free icons — pass a name **or** any custom React node:
|
|
741
|
+
|
|
742
|
+
```tsx
|
|
743
|
+
<FieldFlowInput leftIcon="mail" rightIcon={<MyLucideIcon />} />
|
|
744
|
+
<FieldFlowInput type="email" /> // auto leftIcon="mail"
|
|
745
|
+
<FieldFlowInput type="password" /> // auto leftIcon="lock" + show/hide
|
|
746
|
+
<FieldFlowMaskedInput mask="card" /> // auto leftIcon="creditCard"
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
Built-in names include: `eye`, `eyeOff`, `clear`, `check`, `alert`, `search`, `send`, `camera`, `image`, `paperclip`, `mic`, `mapPin`, `chevronDown/Up/Left/Right`, `calendar`, `clock`, `creditCard`, `currency`, `phone`, `mail`, `lock`, `user`, `key`, `hash`, `otp`, `radio`, `radioFilled`, `switch`, `star`, `plus`, `minus`, `info`, `home`, `settings`, `edit`, `trash`, `link`, `globe`, `file`, `folder`, `bell`, `heart`, `spinner`.
|
|
750
|
+
|
|
751
|
+
Use `FieldFlowIcon` / `renderFieldFlowIcon` anywhere in your app. Set `iconSize` on components to scale them. Pass `leftIcon={null}` / `undefined` carefully — omit the prop to keep defaults, or pass a custom node to replace.
|
|
752
|
+
|
|
753
|
+
## OTP / PIN
|
|
754
|
+
|
|
755
|
+
```tsx
|
|
756
|
+
import { FieldFlowOTP } from 'rn-inputforge';
|
|
757
|
+
|
|
758
|
+
<FieldFlowOTP
|
|
759
|
+
label="Verification code"
|
|
760
|
+
leftIcon="otp"
|
|
761
|
+
length={6}
|
|
762
|
+
value={code}
|
|
763
|
+
onChangeText={setCode}
|
|
764
|
+
onComplete={value => verify(value)}
|
|
765
|
+
cellSize={48}
|
|
766
|
+
/>
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
Supports paste/autofill (`textContentType="oneTimeCode"`), backspace navigation, secure mode, custom `renderCell`, cell styles, and icons.
|
|
770
|
+
|
|
771
|
+
---
|
|
772
|
+
|
|
773
|
+
## Masked inputs
|
|
774
|
+
|
|
775
|
+
```tsx
|
|
776
|
+
import { FieldFlowMaskedInput } from 'rn-inputforge';
|
|
777
|
+
|
|
778
|
+
<FieldFlowMaskedInput mask="phone" label="Phone" value={phone} onChangeText={setPhone} />
|
|
779
|
+
<FieldFlowMaskedInput mask="card" label="Card" valueMode="raw" value={card} onChangeText={(_, raw) => setCard(raw)} />
|
|
780
|
+
<FieldFlowMaskedInput mask="currency" maskOptions={{ currencySymbol: '$' }} value={amount} onChangeText={setAmount} />
|
|
781
|
+
<FieldFlowMaskedInput mask="date" label="Date" value={date} onChangeText={setDate} />
|
|
782
|
+
<FieldFlowMaskedInput mask="custom" maskOptions={{ pattern: '###-##-####' }} value={ssn} onChangeText={setSsn} />
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
Built-in masks: `phone`, `card`, `currency`, `date`, `custom` (pattern with `#` = digit). `onChangeText(formatted, raw)` always receives both; `valueMode` controls which string you store (`'formatted'` default, or `'raw'`).
|
|
786
|
+
|
|
787
|
+
Low-level helpers are also exported: `applyMask`, `formatMasked`, `unmask`, `digitsOnly`.
|
|
788
|
+
|
|
789
|
+
---
|
|
790
|
+
|
|
791
|
+
## Date & time picker
|
|
792
|
+
|
|
793
|
+
Pure JS calendar / time sheet (no native modules):
|
|
794
|
+
|
|
795
|
+
```tsx
|
|
796
|
+
import { FieldFlowDateTimePicker } from 'rn-inputforge';
|
|
797
|
+
|
|
798
|
+
<FieldFlowDateTimePicker mode="date" label="Birthday" value={dob} onChange={setDob} clearable />
|
|
799
|
+
<FieldFlowDateTimePicker mode="time" label="Start time" value={time} onChange={setTime} hourCycle={12} />
|
|
800
|
+
<FieldFlowDateTimePicker
|
|
801
|
+
mode="datetime"
|
|
802
|
+
label="Appointment"
|
|
803
|
+
value={appt}
|
|
804
|
+
onChange={setAppt}
|
|
805
|
+
leftIcon="calendar"
|
|
806
|
+
minimumDate="2020-01-01"
|
|
807
|
+
formatDisplay={(d) => d.toLocaleString()}
|
|
808
|
+
/>
|
|
809
|
+
```
|
|
810
|
+
|
|
811
|
+
Fully customizable: icons, labels, confirm/cancel text, `renderTrigger`, `formatDisplay`, min/max dates, theme, styles.
|
|
812
|
+
|
|
813
|
+
## Checkbox, radio & switch
|
|
814
|
+
|
|
815
|
+
```tsx
|
|
816
|
+
import { FieldFlowCheckbox, FieldFlowRadio, FieldFlowSwitch } from 'rn-inputforge';
|
|
817
|
+
|
|
818
|
+
<FieldFlowCheckbox
|
|
819
|
+
label="I agree to the Terms"
|
|
820
|
+
leftIcon="file"
|
|
821
|
+
checkedIcon="check"
|
|
822
|
+
value={accepted}
|
|
823
|
+
onChange={setAccepted}
|
|
824
|
+
required
|
|
825
|
+
/>
|
|
826
|
+
|
|
827
|
+
<FieldFlowRadio
|
|
828
|
+
label="Plan"
|
|
829
|
+
leftIcon="star"
|
|
830
|
+
value={plan}
|
|
831
|
+
onChange={setPlan}
|
|
832
|
+
options={[
|
|
833
|
+
{ label: 'Starter', value: 'starter', icon: 'home' },
|
|
834
|
+
{ label: 'Pro', value: 'pro', description: 'Most popular', icon: 'star' },
|
|
835
|
+
]}
|
|
836
|
+
/>
|
|
837
|
+
|
|
838
|
+
<FieldFlowSwitch label="Push notifications" leftIcon="bell" value={pushOn} onChange={setPushOn} />
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
Override colors (`checkedColor`, `onTrackColor`, …), icons, sizes, and `renderOption` when you need full control.
|
|
116
842
|
|
|
117
843
|
---
|
|
118
844
|
|
|
@@ -225,15 +951,115 @@ Handles expandable height, keyboard-avoiding behavior, and a send button that's
|
|
|
225
951
|
|
|
226
952
|
---
|
|
227
953
|
|
|
228
|
-
##
|
|
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
|
|
229
1034
|
|
|
230
|
-
|
|
1035
|
+
Group related fields into a themed card with optional collapse:
|
|
231
1036
|
|
|
232
1037
|
```tsx
|
|
233
|
-
|
|
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>;
|
|
234
1044
|
```
|
|
235
1045
|
|
|
236
|
-
|
|
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
|
+
```
|
|
237
1063
|
|
|
238
1064
|
---
|
|
239
1065
|
|
|
@@ -242,8 +1068,14 @@ Any prop that accepts an icon also accepts a raw `ReactNode`, so you can swap in
|
|
|
242
1068
|
Wrap your app (or just a screen) in `FieldFlowThemeProvider` and override only what you need — everything else falls back to the default theme:
|
|
243
1069
|
|
|
244
1070
|
```tsx
|
|
245
|
-
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>
|
|
246
1077
|
|
|
1078
|
+
// Or merge your own tokens
|
|
247
1079
|
<FieldFlowThemeProvider
|
|
248
1080
|
theme={{
|
|
249
1081
|
colors: { borderFocused: '#7C3AED', labelFocused: '#7C3AED' },
|
|
@@ -254,8 +1086,49 @@ import { FieldFlowThemeProvider } from 'rn-inputforge';
|
|
|
254
1086
|
</FieldFlowThemeProvider>;
|
|
255
1087
|
```
|
|
256
1088
|
|
|
1089
|
+
**Bundled presets:** `default`, `dark`, `soft`, `warm`, `teal`, `midnight`, `contrast`. Use `getThemePreset('teal')` if you prefer a function call.
|
|
1090
|
+
|
|
257
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.
|
|
258
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
|
+
|
|
259
1132
|
---
|
|
260
1133
|
|
|
261
1134
|
## Project structure
|
|
@@ -264,18 +1137,34 @@ You can also pass a one-off `theme` prop directly to any single field to overrid
|
|
|
264
1137
|
rn-inputforge/
|
|
265
1138
|
├── src/
|
|
266
1139
|
│ ├── components/
|
|
267
|
-
│ │ ├── FieldFlowInput/
|
|
268
|
-
│ │ ├──
|
|
269
|
-
│ │ ├──
|
|
270
|
-
│ │ ├──
|
|
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
|
|
271
1156
|
│ │ └── KeyboardAwareFormWrapper/
|
|
272
|
-
│ ├──
|
|
273
|
-
│ ├──
|
|
274
|
-
│ ├──
|
|
275
|
-
│ ├──
|
|
276
|
-
│ ├──
|
|
277
|
-
│
|
|
278
|
-
├──
|
|
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
|
|
279
1168
|
├── package.json
|
|
280
1169
|
└── tsconfig*.json
|
|
281
1170
|
```
|