Skip to content

Instantly share code, notes, and snippets.

@domosedov
Last active November 10, 2021 12:59
Show Gist options
  • Save domosedov/01db922d3df4215d2cbeb2b40e7c9a80 to your computer and use it in GitHub Desktop.
Save domosedov/01db922d3df4215d2cbeb2b40e7c9a80 to your computer and use it in GitHub Desktop.
React TailwindCSS component example
import type { FC, HTMLAttributes } from "react";
type BoxProps = {
as?: keyof JSX.IntrinsicElements;
} & HTMLAttributes<HTMLOrSVGElement>;
export const Box: FC<BoxProps> = ({ as: Component = "div", ...props }) => {
return <Component {...props} />;
};
import type { ButtonHTMLAttributes } from "react";
import { forwardRef } from "react";
import clsx from "clsx";
const sizeMap = {
sm: "text-xs py-2 px-2 md:py-1",
md: "text-sm py-3 px-2 md:py-2",
lg: "text-lg py-2 px-4",
xl: "text-xl py-3 px-6",
} as const;
const variantMap = {
primary: "bg-blue-500 hover:bg-blue-600",
danger: "bg-red-500 hover:bg-red-600",
} as const;
type ButtonProps = {
size?: keyof typeof sizeMap;
variant?: keyof typeof variantMap;
rounded?: boolean;
} & ButtonHTMLAttributes<HTMLButtonElement>;
const baseStyles = "rounded text-white transition-all duration-200";
const focusStyles =
"outline-none focus:outline-none focus:ring-4 focus:ring-yellow-300";
const disabledStyles = "disabled:bg-gray-400 disabled:cursor-not-allowed";
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
(
{
size = "md",
variant = "primary",
rounded = false,
disabled = false,
className = "",
...props
},
ref
) => {
const instanceStyles = clsx(
baseStyles,
sizeMap[size],
variantMap[variant],
focusStyles,
rounded && "rounded-full",
disabled && disabledStyles
);
return (
<button
ref={ref}
className={clsx(instanceStyles, className)}
disabled={disabled}
{...props}
/>
);
}
);
Button.displayName = "Button";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment