Button styling cleanup, prop consistency

This commit is contained in:
DaneEveritt 2022-06-20 12:38:23 -04:00
parent 7dd74ecc9d
commit 7b0e2ce99d
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
9 changed files with 121 additions and 46 deletions

View file

@ -1,18 +1,24 @@
import React, { forwardRef } from 'react';
import classNames from 'classnames';
import { ButtonProps, Options } from '@/components/elements/button/types';
import styles from './style.module.css';
export type ButtonProps = JSX.IntrinsicElements['button'] & {
square?: boolean;
small?: boolean;
}
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ children, square, small, className, ...rest }, ref) => {
({ children, shape, size, variant, className, ...rest }, ref) => {
return (
<button
ref={ref}
className={classNames(styles.button, { [styles.square]: square, [styles.small]: small }, className)}
className={classNames(
styles.button,
styles.primary,
{
[styles.secondary]: variant === Options.Variant.Secondary,
[styles.square]: shape === Options.Shape.IconSquare,
[styles.small]: size === Options.Size.Small,
[styles.large]: size === Options.Size.Large,
},
className,
)}
{...rest}
>
{children}
@ -31,6 +37,12 @@ const DangerButton = forwardRef<HTMLButtonElement, ButtonProps>(({ className, ..
<Button ref={ref} className={classNames(styles.danger, className)} {...props} />
));
const _Button = Object.assign(Button, { Text: TextButton, Danger: DangerButton });
const _Button = Object.assign(Button, {
Sizes: Options.Size,
Shapes: Options.Shape,
Variants: Options.Variant,
Text: TextButton,
Danger: DangerButton,
});
export default _Button;

View file

@ -1,2 +1,3 @@
export { ButtonProps } from './types';
export { default as Button } from './Button';
export { default as styles } from './style.module.css';

View file

@ -1,38 +1,73 @@
.button {
@apply px-4 py-2 inline-flex items-center justify-center;
@apply bg-blue-600 rounded text-base font-semibold text-blue-50 transition-all duration-100;
@apply hover:bg-blue-500 active:bg-blue-500;
&.square {
@apply p-2;
}
&:focus {
@apply ring-[3px] ring-blue-500 ring-offset-2 ring-offset-neutral-700;
}
@apply rounded text-base font-semibold transition-all duration-100;
@apply focus:ring-[3px] focus:ring-offset-2 focus:ring-offset-gray-700 focus:ring-opacity-50;
/* Sizing Controls */
&.small {
@apply px-3 py-1 font-normal focus:ring-2;
@apply px-4 py-1 font-normal text-sm focus:ring-2;
}
&.square {
@apply p-1;
&.large {
@apply px-5 py-3;
}
&.secondary {
@apply text-gray-50 bg-transparent;
&:disabled {
@apply bg-transparent;
}
}
&:disabled {
@apply cursor-not-allowed;
}
&.square {
@apply p-0 w-12 h-12;
&.small {
@apply w-8 h-8;
}
}
}
.primary {
@apply bg-blue-600 text-blue-50;
@apply hover:bg-blue-500 active:bg-blue-500 focus:ring-blue-400 focus:ring-opacity-75;
&.secondary {
@apply hover:bg-blue-600 active:bg-blue-600;
}
&:disabled {
@apply bg-blue-500/75 text-blue-200/75;
}
}
.text {
@apply text-gray-50 bg-transparent focus:ring-neutral-300 focus:ring-opacity-50 hover:bg-neutral-500 active:bg-neutral-500;
@apply bg-gray-500 text-gray-50;
@apply hover:bg-gray-400 active:bg-gray-400 focus:ring-gray-300 focus:ring-opacity-50;
&.secondary {
@apply hover:bg-gray-500 active:bg-gray-500;
}
&:disabled {
@apply hover:bg-transparent text-gray-300;
@apply bg-gray-500/75 text-gray-200/75;
}
}
.danger {
@apply bg-red-600 hover:bg-red-500 active:bg-red-500 focus:ring-red-500 text-red-50;
@apply bg-red-600 text-gray-50;
@apply hover:bg-red-500 active:bg-red-500 focus:ring-red-400 focus:ring-opacity-75;
&.secondary {
@apply hover:bg-red-600 active:bg-red-600;
}
&:disabled {
@apply bg-red-600/75 text-red-50/75;
}
}

View file

@ -0,0 +1,23 @@
enum Shape {
Default,
IconSquare,
}
enum Size {
Default,
Small,
Large,
}
enum Variant {
Primary,
Secondary,
}
export const Options = { Shape, Size, Variant };
export type ButtonProps = JSX.IntrinsicElements['button'] & {
shape?: Shape;
size?: Size;
variant?: Variant;
}