Created
December 6, 2023 20:05
-
-
Save serifcolakel/9204e60bc4a401217a5b49ebfa79c07a to your computer and use it in GitHub Desktop.
These form elements can include buttons, links, inputs, selects, and text areas, each with various styling options. Instead of creating separate components for each form element, we can build a polymorphic React FormElement component.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
type FormElementBaseProps = { | |
children?: React.ReactNode; | |
variant?: 'primary' | 'secondary' | 'outline' | 'link'; | |
}; | |
type FormElementProps = FormElementBaseProps & | |
( | |
| (React.ButtonHTMLAttributes<HTMLButtonElement> & { | |
as: 'button'; | |
}) | |
| (React.AnchorHTMLAttributes<HTMLAnchorElement> & { | |
as: 'a'; | |
}) | |
| (React.InputHTMLAttributes<HTMLInputElement> & { | |
as: 'input'; | |
}) | |
| (React.SelectHTMLAttributes<HTMLSelectElement> & { | |
as: 'select'; | |
}) | |
| (React.TextareaHTMLAttributes<HTMLTextAreaElement> & { | |
as: 'textarea'; | |
}) | |
); | |
export function FormElement({ variant, ...props }: FormElementProps) { | |
switch (props.as) { | |
case 'button': | |
return <button {...props}>{props.children}</button>; | |
case 'a': | |
return <a {...props}>{props.children}</a>; | |
case 'input': | |
return <input {...props} />; | |
case 'select': | |
return <select {...props}>{props.children}</select>; | |
case 'textarea': | |
return <textarea {...props} />; | |
default: | |
return null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment