sanniassin / react-input-mask

Input masking component for React. Made with attention to UX.
MIT License
2.23k stars 256 forks source link

Use cases for children component #139

Open sanniassin opened 6 years ago

sanniassin commented 6 years ago

It's not clear whether children components are mostly self made components from projects or third-party components from npm. That's why I need stats.

If you're passing another component as a children, please write what component you use (and what is the name of it if it's a third-party component) and why do you need to mix it with react-input-mask.

Thanks.

jpggvilaca commented 6 years ago

Hi, I think we might want different type of inputs and several conditional renderings inside it. So, normally one does its own component, so it's very important to have this children prop bulletproofed. I'll share my own example here.

// Input.js

 <Fragment>
      {
         !multiline
            ? autoComplete
               ? <AutoComplete inputProps={inputProps} items={autoComplete} />
               : <input {...inputProps} />
            : <TextArea {...inputProps} />
     }
    <Error {...error} />
  </Fragment>

Let me know if you want to discuss it further.

sanniassin commented 6 years ago

@jpggvilaca Can you share your project or, if it's private, make a repo with input-related code only?

You have a very different kinds of inputs here. react-input-mask isn't compatible with textarea element and, I guess, AutoComplete is used for irregular texts like names or cities. In that case the only input that is suitable for masking is regular input and there's no need to use the children prop then.

slashrune commented 6 years ago

Hi! It would be great if we are able to wrap Ant D's .

Ant D's datepicker is completely useless for keyboard input, and adding an input mask to the regular Input would be a great solution for that.

<InputMask mask='99/99/9999' onChange={handleUpdate}>
    {(inputProps) => <Input {...inputProps} placeholder={placeholder} />}
</InputMask>

This is not supported at the moment as react-input-mask throws this: react-input-mask: the following props should be passed to the react-input-mask's component and should not be altered in children's function: disabled.

sanniassin commented 6 years ago

@slashrune Could you please make a demo at https://codesandbox.io?

slashrune commented 6 years ago

@slashrune Could you please make a demo at https://codesandbox.io?

Thank you for your response!

I have replicated an example here: https://codesandbox.io/s/l5zk123y1l

sanniassin commented 6 years ago

@slashrune Thanks. The problem is that react-input-mask doesn't check if children's props are taken from defaultProps. The disabled prop of parent and children components must be in sync and, in your case, children's defaultProp value for it is false, so the error can be fixed by adding disabled={false} to the InputMask component.

Hence, the error message should be rewritten to make it clear if error is caused by defaultProps. Would you like to submit a PR?

slashrune commented 6 years ago

@slashrune Thanks. The problem is that react-input-mask doesn't check if children's props are taken from defaultProps. The disabled prop of parent and children components must be in sync and, in your case, children's defaultProp value for it is false, so the error can be fixed by adding disabled={false} to the InputMask component.

Hence, the error message should be rewritten to make it clear if error is caused by defaultProps. Would you like to submit a PR?

Thank you for that!

I am still trying to assess if there are other complications with Ant D at the moment, I will get back to you regarding the PR.

deser commented 5 years ago

Bootstrap input

mahammedzkhan commented 5 years ago

Some attributes aren't passed to the children in inputProps, for example disabled: <InputMask disabled={true}> {(inputProps) => <input type="text" {...inputProps} />} </InputMask>

zubair1103 commented 5 years ago

One use case of children is: Mask an input as date but also use a date picker (react-datepicker). User either enters value according to mask or picks from date picker.

iloveip commented 5 years ago

Hi @sanniassin,

I would also like to use react-input-mask with antd Input field. I added disabled={false} to the InputMask, but the mask is not working (it skips some characters and types outside the mask). Here is a demo.

Is there any way to fix it?

italoiz commented 4 years ago

@iloveip Here is an implementation with Antd:

import React from 'react';
import InputMask from 'react-input-mask';
import { Input } from 'antd';

export interface InputProps {
  mask: string;
  placeholder: string;
  disabled?: boolean;
  onChange?: (event: React.SyntheticEvent) => void;
  value?: string;
}

const InputComponent: React.FC<InputProps> = ({ disabled, onChange, value, mask, ...rest }) => (
  <InputMask mask={mask} disabled={disabled} value={value} onChange={onChange}>
    {(inputProps: any) => (
      <Input {...inputProps} {...rest} disabled={disabled} />
    )}
  </InputMask>
)

export default InputComponent;

But I would like to leave a doubt. @sanniassin

Why can't you pass on the disabled property to the children?

iloveip commented 4 years ago

@italoiz Hi there, thank you for your reply. I would like to use antd with react-final-form, but it doesn't work. Here is the codesandbox with your example https://codesandbox.io/s/react-final-form-wreact-number-format-04kcd?fontsize=14&hidenavigation=1&theme=dark.

annezao commented 4 years ago

Have someone a sample using material-ui InputBase?

italoiz commented 4 years ago

@annemacena The above example also works with Material UI. Only change the Antd component to the Material UI component.

iloveip commented 4 years ago

@italoiz For me your example doesn't work with Antd. See the link to codesandbox in my comment above.

italoiz commented 4 years ago

@iloveip see this Stackblitz example create with react-final-form, react-input-mask and antd.

annezao commented 4 years ago

@iloveip Here is an implementation with Antd:

import React from 'react';
import InputMask from 'react-input-mask';
import { Input } from 'antd';

export interface InputProps {
  mask: string;
  placeholder: string;
  disabled?: boolean;
  onChange?: (event: React.SyntheticEvent) => void;
  value?: string;
}

const InputComponent: React.FC<InputProps> = ({ disabled, onChange, value, mask, ...rest }) => (
  <InputMask mask={mask} disabled={disabled} value={value} onChange={onChange}>
    {(inputProps: any) => (
      <Input {...inputProps} {...rest} disabled={disabled} />
    )}
  </InputMask>
)

export default InputComponent;

But I would like to leave a doubt. @sanniassin

Why can't you pass on the disabled property to the children?

Okay, so, this sample didn't work for me. I'm using Formik, and Material-UI. BUT, it worked using like this:

<InputMask
              onChange={OnChangeFunction}
              mask={maskVariable}
              onBlur={onBlurFunction}
              value={valueVariable}
              name={nameVariable}
              maskPlaceholder={" "}>
      <TextField className={customClasses} fullWidth id={customId} />
</InputMask>
yilunc commented 2 years ago

Was anybody able to successfully use AntD's Form with InputMask? When I call form.resetFields() this component seems to break things:

Screen Shot 2022-07-26 at 3 59 43 PM

Everything else works well! It's just that the resetFields call breaks. This is how I am wrapping the Input.

  return (
    <InputMask
      {...props}
      mask={mask}
      maskChar={null}
      beforeMaskedValueChange={beforeMaskedValueChange}
    >
      {(inputProps: any) => <Input {...inputProps} />}
    </InputMask>
  );
LeonardoRochaLima commented 2 years ago

All of these samples didn't work for me.

I tried in two different ways 👎🏻 :

<InputMask
    mask="99.999.999/9999-99"
    error={!!errors?.cnpj}
    fullWidth
    autoFocus
    label={'CNPJ'}
>
    {(inputProps: any) => {
        return <TextFieldCustomizado {...inputProps} />
    }}
</InputMask>

So, I have this error: No overload matches this call. Overload 1 of 2, '(props: Props | Readonly<Props>): ReactInputMask', gave the following error. Type '(inputProps: any) => JSX.Element' is not assignable to type 'ReactNode'. Overload 2 of 2, '(props: Props, context: any): ReactInputMask', gave the following error. Type '(inputProps: any) => JSX.Element' is not assignable to type 'ReactNode'.ts(2769)

And with this way 👎🏻 :

<InputMask
    mask="99.999.999/9999-99"
    error={!!errors?.cnpj}
    fullWidth
    autoFocus
    label={'CNPJ'}
>
    <TextFieldCustomizado {...inputProps} />
</InputMask>

I have a runtime error:

image

I'm using TextField of Material UI. I appreciate any help. Thanks.

italoiz commented 2 years ago

@LeonardoRochaLima try to follow this example on StackBlitz: https://stackblitz.com/edit/react-ts-u5u2rb?file=TextFieldMask.tsx

LeonardoRochaLima commented 2 years ago

@LeonardoRochaLima try to follow this example on StackBlitz: https://stackblitz.com/edit/react-ts-u5u2rb?file=TextFieldMask.tsx

Are sure that is correct?

image

If I do exactly like this I still have a problem to building the application.

Larrianton commented 1 year ago
import React from 'react';
import InputMask from 'react-input-mask';
import { Input } from 'antd';

export interface InputProps {
  mask: string;
  placeholder: string;
  disabled?: boolean;
  onChange?: (event: React.SyntheticEvent) => void;
  value?: string;
}

const InputComponent: React.FC<InputProps> = ({ disabled, onChange, value, mask, ...rest }) => (
  <InputMask mask={mask} disabled={disabled} value={value} onChange={onChange}>
    {(inputProps: any) => (
      <Input {...inputProps} {...rest} disabled={disabled} />
    )}
  </InputMask>
)

export default InputComponent;

But I would like to leave a doubt. @sanniassin

Why can't you pass on the disabled property to the children?

Hello , i faced the same problem , i can't pass disabled property to the children , how is this solvable?

``

ozkary commented 1 year ago

To solve a problem from this thread, I had to upgrade to react-input-mask-3.0.0. I also upgraded the @types/react-input-component@3.0.0 for typescript projects.

To solve the children must be a function error, just wrap the custom input element in a function as such:


const addInput = (props: S.Props) => (
  <Input {...props} />
)

export const YourMaskedInput = (props: S.Props): JSX.Element => {
  return (
    <InputMask
      formatChars={props.formatChars}
      {...props}
    >   
    {addInput(props)}
    </InputMask>
  );
};

But after the upgrade, you can use custom input components without the function.


export const YourMaskedInput = (props: S.Props): JSX.Element => {
  return (
    <InputMask
      formatChars={props.formatChars}
      {...props}
    >   
    <Input {...props} />
    </InputMask>
  );
};
PetePearl commented 1 year ago

I can offer you temporary bad but working solution.

import InputMask, { Props } from 'react-input-mask';

type TInputMaskCorrect = Omit<Props, 'children'> & { children?: () => JSX. Element };
const InputMaskCorrect: FC<TInputMaskCorrect> = ( { children, ...props }) => {
    const child = children as ReactNode;
    return <InputMask children={child} {...props} />
}

now you have to use InputMaskCorrect similar to InputMask

ShareinSK commented 1 year ago

How to add a mask and not allow the user to enter space manually? I am using react-final-form.


<InputMask
    mask={'### ### ####'}
    formatChars={{
      '#': '[0-9]',
    }}
    {...fieldProps}
    maskChar=' '>
mbalestrini-tecla commented 1 year ago

All of these samples didn't work for me.

I tried in two different ways 👎🏻 :

<InputMask
  mask="99.999.999/9999-99"
  error={!!errors?.cnpj}
  fullWidth
  autoFocus
  label={'CNPJ'}
>
  {(inputProps: any) => {
      return <TextFieldCustomizado {...inputProps} />
  }}
</InputMask>

So, I have this error: No overload matches this call. Overload 1 of 2, '(props: Props | Readonly<Props>): ReactInputMask', gave the following error. Type '(inputProps: any) => JSX.Element' is not assignable to type 'ReactNode'. Overload 2 of 2, '(props: Props, context: any): ReactInputMask', gave the following error. Type '(inputProps: any) => JSX.Element' is not assignable to type 'ReactNode'.ts(2769)

And with this way 👎🏻 :

<InputMask
  mask="99.999.999/9999-99"
  error={!!errors?.cnpj}
  fullWidth
  autoFocus
  label={'CNPJ'}
>
  <TextFieldCustomizado {...inputProps} />
</InputMask>

I have a runtime error:

image

I'm using TextField of Material UI. I appreciate any help. Thanks.

I've got the same problem, and i solved this way:

<InputMask
    mask="99.999.999/9999-99"
    error={!!errors?.cnpj}
    fullWidth
    autoFocus
    label={'CNPJ'}
>
    {((inputProps: any) => {
        return <TextFieldCustomizado {...inputProps} />
    }) as any}

</InputMask>

Basically i turned off typescript using any because the library types seems wrong.

marcosabb commented 6 months ago
{((inputProps: DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>) => (
  <Input
    {...inputProps}
  />
)) as unknown as React.ReactNode}
lokinmodar commented 3 months ago
{((inputProps: DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>) => (
  <Input
    {...inputProps}
  />
)) as unknown as React.ReactNode}

THIS is the real solution