refactor: create reusable buttons

This commit is contained in:
Carlos Valente
2025-06-03 21:44:15 +02:00
committed by Carlos Valente
parent 44d5859844
commit 97e3e8f435
4 changed files with 125 additions and 8 deletions
@@ -0,0 +1,52 @@
@use '../../../theme/viewerDefs' as *;
.baseButton {
height: 2rem;
padding-inline: 1em;
display: flex;
align-items: center;
gap: 0.5em;
border: 1px solid transparent;
border-radius: 3px;
cursor: pointer;
&:disabled {
opacity: 0.4;
cursor: not-allowed;
}
}
.subtle {
background: $gray-1050;
color: $blue-400;
&:hover:not(:disabled):not(:active) {
background: $gray-1000;
color: $blue-500;
}
&:active:not(:disabled) {
background: $gray-1100;
border-color: $gray-1250;
}
}
.primary {
background: $blue-700;
color: $ui-white;
&:hover:not(:disabled):not(:active) {
background: $blue-600;
}
&:active:not(:disabled) {
background: $blue-800;
border-color: $blue-900;
}
&:disabled {
opacity: $viewer-opacity-disabled;
}
}
@@ -0,0 +1,19 @@
import { ButtonHTMLAttributes } from 'react';
import { cx } from '../../utils/styleUtils';
import style from './Button.module.scss';
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'subtle' | 'primary';
}
export default function Button(props: ButtonProps) {
const { className, children, variant = 'subtle', ...buttonProps } = props;
return (
<button className={cx([style.baseButton, style[variant], className])} type='button' {...buttonProps}>
{children}
</button>
);
}
@@ -1,21 +1,28 @@
.subtle { @use '../../../theme/viewerDefs' as *;
.baseIconButton {
aspect-ratio: 1; aspect-ratio: 1;
height: 2rem; height: 2rem;
height: 2rem; width: 2rem;
display: grid; display: grid;
place-content: center; place-content: center;
background: $gray-1050;
color: $blue-400;
border: 1px solid transparent; border: 1px solid transparent;
border-radius: 3px; border-radius: 3px;
cursor: pointer;
}
.subtle {
background: $gray-1050;
color: $blue-400;
&:hover:not(:disabled):not(:active) { &:hover:not(:disabled):not(:active) {
background: $gray-1000; background: $gray-1000;
color: $blue-500; color: $blue-500;
} }
&:active { &:active:not(:disabled){
background: $gray-1100; background: $gray-1100;
border-color: $gray-1250; border-color: $gray-1250;
} }
@@ -24,3 +31,37 @@
background: $gray-1050; background: $gray-1050;
} }
} }
.subtle-white {
background: $gray-1050;
color: $ui-white;
&:hover:not(:disabled):not(:active) {
background: $gray-1000;
color: $ui-white;
}
&:active:not(:disabled) {
background: $gray-1100;
border-color: $gray-1250;
}
&:disabled {
background: $gray-1050;
}
}
.destructive {
background: $red-700;
color: $ui-white;
&:hover:not(:disabled):not(:active) {
background: $red-600;
color: $ui-white;
}
&:active:not(:disabled) {
background: $red-800;
border-color: $red-900;
}
}
@@ -4,10 +4,15 @@ import { cx } from '../../utils/styleUtils';
import style from './IconButton.module.scss'; import style from './IconButton.module.scss';
export default function IconButton(props: ButtonHTMLAttributes<HTMLButtonElement>) { interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
const { className, children, ...buttonProps } = props; variant?: 'subtle' | 'subtle-white' | 'destructive';
}
export default function IconButton(props: IconButtonProps) {
const { className, children, variant = 'subtle', ...buttonProps } = props;
return ( return (
<button className={cx([style.subtle, className])} {...buttonProps}> <button className={cx([style.baseIconButton, style[variant], className])} type='button' {...buttonProps}>
{children} {children}
</button> </button>
); );