Responsive button design with single React component with Tailwind CSS.
Here I'll show how you can design different types of buttons for both light and dark mode with tailwind. I have used Gatsby, TypeScript in my project.
Props
import { Link } from 'gatsby';
import React, { ReactNode } from 'react';
interface Props {
type?: 'primary' | 'secondary' | 'text';
children: ReactNode;
onClick?: () => void;
isBlock?: boolean;
disabled?: boolean;
className?: string;
href?: string;
target?: string;
width?: string;
}
Define the styles.
Added different text sizes and paddings for mobile and desktop devices. According to button type, text color, background and border are varied.
const textSize = 'text-base lg:text-lg';
const padding = 'px-7 lg:px-10 py-3 lg:py-4';
const color = {
primary: 'text-white',
secondary: 'text-slate-700 dark:text-slate-200',
text: 'text-slate-700 hover:text-white dark:text-slate-200 dark:hover:text-white',
};
const backgroundColors = {
primary: 'bg-blue-500',
secondary: 'bg-transparent',
text: 'bg-light-button hover:bg-blue-500 dark:bg-gray-800 dark:hover:bg-blue-500',
};
const border = {
primary: 'border-none',
secondary: 'border-2 border-gray-800 dark:border-white',
text: 'border-none',
};
Button Component
I have used custom google font here. Check out this link if you like to add a custom google font to your tailwind project.
For button with links or href, I have used Gatsby Link.
const Button = ({
type = 'primary',
children,
onClick,
className = '',
disabled = false,
href,
target,
isBlock = true,
width,
}: Props): JSX.Element => {
const disabledStyle = disabled
? 'opacity-50 cursor-not-allowed'
: 'transition ease-in-out duration-300 hover:cursor-pointer';
let baseClasses = [
'uppercase',
'font-oswald',
textSize,
border[type],
backgroundColors[type],
color[type],
padding,
disabledStyle,
];
if (className) {
baseClasses = [...baseClasses, ...className.split(' ')];
}
if (isBlock) {
baseClasses = [...baseClasses, 'block w-full'];
}
if (!!width) {
baseClasses = [...baseClasses, width];
}
if (href) {
let linkClasses = [...baseClasses, 'flex items-center justify-center whitespace-nowrap'];
return (
<Link to={href} target={target} onClick={onClick} className={linkClasses.join(' ')}>
{children}
</Link>
);
}
return (
<button onClick={onClick} className={baseClasses.join(' ')} disabled={disabled}>
{children}
</button>
);
};
export default Button;
I have built the UI component with Storybook
Top comments (0)