2

I am trying to create a custom input field using typescript and Formik. Could I please get some help on the best way of completing the code below? I need to add in additional props label & name... I have been stuck on this for a while and am hoping that I am missing something very easy here!?

{/* {label && <label htmlFor={name} className="text-input-label">{label}</label>} */}

Please see the above line in the below code.

import React from "react";
import styled from "styled-components";
import { FieldHookConfig, useField } from "formik";

interface AdditionalProps {
  label: string;
  name: string;
}

const MyTextInput = (props: FieldHookConfig<string>) => {
  const [field, meta] = useField(props);
  return (
    <div className={"text-input " + props.className}>
      {/* {label && <label htmlFor={name} className="text-input-label">{label}</label>} */}
      <div className="card-backdrop">
        <input {...field} placeholder={props.placeholder} />
      </div>
    </div>
  );
};

export default styled(MyTextInput)``

Thank you!!!

1
  • 1
    props: FieldHookConfig<string> & { name: string, label: string } Commented Sep 7, 2020 at 22:13

2 Answers 2

2

Create a new prop as an interface as below and use it in your component as props type

interface ComponentProps<T> {
  config : FieldHookConfig<T>;
  label: string;
  name: string;
}
const MyTextInput = (props: ComponentProps<string>) => {}

So you can use your formik config(FieldHookConfig) in your component like below props.config.className or props.config.placeholder and You can use your additional props like props.label and props.name

And finally your component looks like

import React from "react";
import styled from "styled-components";
import { FieldHookConfig, useField } from "formik";

interface ComponentProps<T> {
  config : FieldHookConfig<T>;
  label: string;
  name: string;
}

const MyTextInput = (props: ComponentProps<string>) => {
  const [field, meta] = useField(props.config);
  return (
    <div className={"text-input " + props.config.className}>
      {props.label && <label htmlFor={props.name} className="text-input-label">{props.label}</label>}
      <div className="card-backdrop">
        <input {...field} placeholder={props.config.placeholder} />
      </div>
    </div>
  );
};

export default styled(MyTextInput)
Sign up to request clarification or add additional context in comments.

3 Comments

Hi there, - thank you for such a quick response. TS like that, however, I have created an error that I have been seeing along the way.... The way that I am calling the component is as follows: <MyTextInput name="displayName" placeholder="Display Name" /> I am now getting an error: Property 'placeholder' does not exist on type 'IntrinsicAttributes & Pick<Pick<ComponentProps<string>, "label" | "name" | "config"> & Partial<Pick<ComponentProps<string>, never>>, "label" | ... 1 more ... | "config"> & { ...; } & { ...; }'.
Thanks - but that is how I have called it as per the comment above..?
placeholder props is in your config so you call it like <MyTextInput config = { /* put it your fieldhookconfig object */ } name = {"DisplayName"} label = {"Display Name"} ></MyTextInput>
0

I found a way to get the desired outcome by using formiks Field & FieldAttributes component.

I am able to use all of formiks inbuilt props & useField hook with the ability to pass down additional props to enable complete control over styling.

See below for the code that I have used. :)

import React from "react";
import styled from "styled-components";
import { useField, FieldAttributes, Field } from "formik";

type MyTextInputProps = {
  label?: string;
  name: string;
  className?: string;
} & FieldAttributes<{}>;

const MyTextInput: React.SFC<MyTextInputProps> = ({
  label,
  placeholder,
  type,
  className,
  ...props
}) => {
  const [field, meta] = useField<{}>(props);
  return (
    <div className={"text-input " + className}>
      {label && <label className="text-input-label">{label}</label>}
      <div className="card-backdrop">
        <Field placeholder={placeholder} type={type} {...field} />
        {meta.touched && meta.error && (
          <div className="text-input-error">{meta.error}</div>
        )}
      </div>
    </div>
  );
};

export default styled(MyTextInput)

this is then called with the following

<MyTextInput name="displayName" placeholder="Display Name" />

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.