diff --git a/Parts/Input.tsx b/Parts/Input.tsx index 853c854..686054e 100644 --- a/Parts/Input.tsx +++ b/Parts/Input.tsx @@ -2,6 +2,7 @@ import React from "react"; import tw from "twin.macro"; import { useField as useFormikField, useFormikContext, FieldHookConfig } from "formik"; +import { IMaskInput, IMaskInputProps, IMaskMixinProps } from 'react-imask'; //const useFormikField = null; //const useFormikContext = ()=>{}; @@ -17,7 +18,7 @@ export function useField(props) { } export default function Input( - props: React.InputHTMLAttributes & { + props: React.InputHTMLAttributes & FieldHookConfig & { label?: React.ComponentPropsWithoutRef<"label">; title?: string; children?: React.ReactNode; @@ -44,7 +45,7 @@ export default function Input( {/*name={name || title} id={id || name || title}*/} @@ -55,6 +56,54 @@ export default function Input( ); } + +export function MaskedInput( + props: Omit, "validate" | "label"> & FieldHookConfig & { + definitions: { [k: string]: RegExp }; + + label?: React.ComponentPropsWithoutRef<"label">; + title?: string; + children?: React.ReactNode; + className?: string; + } +) { + /*name, id*/ + let { children, validate, ...otherProps } = props; + + const [field, meta, helpers] = useField({ ...otherProps, validate }); + + return ( +
+ {props.title && ( + + )} + {/*name={name || title} id={id || name || title}*/} + field.onChange({ target: { value, name: field.name } }) + } + onBlur={field.onBlur} + tw="bg-primary appearance-none border-2 border-secondary rounded w-full py-2 px-4 text-primary leading-tight focus:outline-none focus:bg-secondary focus:border-accent transition duration-150 " + /> + {props.children} + {meta?.touched && meta.error ? ( +
{meta.error}
+ ) : null} +
+ ); +} + export function TextArea({ title, children = null, diff --git a/Parts/PreMaskedInput.tsx b/Parts/PreMaskedInput.tsx new file mode 100644 index 0000000..6c2fe2a --- /dev/null +++ b/Parts/PreMaskedInput.tsx @@ -0,0 +1,37 @@ +import { MaskedInput } from "./Input"; + +export type PreMaskedProps = Omit, "mask" | "definitions"> + +export function IbanInput(props: PreMaskedProps) { + return str.toUpperCase()} + validate={(iban: string) => { + console.log(iban); + + if (iban.length < 15 || iban.length > 34) + return "Invalid length"; + + // Rearranged IBAN + const rearranged = iban.slice(4) + iban.slice(0, 4); + + // Convert letters to numbers (A=10 ... Z=35) + const converted = rearranged.replace(/[A-Z]/g, ch => (ch.charCodeAt(0) - 55).toString()); + + // Perform mod-97 check + let remainder = converted; + let block; + + while (remainder.length > 2) { + block = remainder.slice(0, 9); + remainder = (parseInt(block, 10) % 97).toString() + remainder.slice(block.length); + } + + if (parseInt(remainder, 10) % 97 !== 1) + return "Invalid checksum"; + + return null; + }} + /> +} \ No newline at end of file