Dan0z_Direct
Dan0z_Direct

Reputation: 81

Typescript additional props

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!!!

Upvotes: 2

Views: 2372

Answers (2)

Dan0z_Direct
Dan0z_Direct

Reputation: 81

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" />

Upvotes: 0

Yusuf Kayikci
Yusuf Kayikci

Reputation: 332

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)

Upvotes: 2

Related Questions