Add custom spinner to button

This commit is contained in:
jeffvli
2022-11-14 14:25:38 -08:00
parent 4029b149ee
commit 7061e16fb4
+71 -2
View File
@@ -6,10 +6,12 @@ import {
TooltipProps, TooltipProps,
} from '@mantine/core'; } from '@mantine/core';
import styled from 'styled-components'; import styled from 'styled-components';
import { Spinner } from '@/renderer/components/spinner';
import { Tooltip } from '@/renderer/components/tooltip'; import { Tooltip } from '@/renderer/components/tooltip';
interface ButtonProps extends MantineButtonProps { interface ButtonProps extends MantineButtonProps {
children: React.ReactNode; children: React.ReactNode;
loading?: boolean;
onClick?: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void; onClick?: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
tooltip?: Omit<TooltipProps, 'children'>; tooltip?: Omit<TooltipProps, 'children'>;
} }
@@ -31,6 +33,7 @@ const StyledButton = styled(MantineButton)<StyledButtonProps>`
return ''; return '';
} }
}}; }};
font-weight: normal;
background: ${(props) => { background: ${(props) => {
switch (props.variant) { switch (props.variant) {
case 'default': case 'default':
@@ -44,6 +47,23 @@ const StyledButton = styled(MantineButton)<StyledButtonProps>`
} }
}}; }};
border: none; border: none;
transition: background 0.2s ease-in-out, color 0.2s ease-in-out;
svg {
transition: fill 0.2s ease-in-out;
fill: ${(props) => {
switch (props.variant) {
case 'default':
return 'var(--btn-default-fg)';
case 'filled':
return 'var(--btn-primary-fg)';
case 'subtle':
return 'var(--btn-subtle-fg)';
default:
return '';
}
}};
}
&:disabled { &:disabled {
color: ${(props) => { color: ${(props) => {
@@ -99,6 +119,21 @@ const StyledButton = styled(MantineButton)<StyledButtonProps>`
return ''; return '';
} }
}}; }};
svg {
fill: ${(props) => {
switch (props.variant) {
case 'default':
return 'var(--btn-default-fg-hover)';
case 'filled':
return 'var(--btn-primary-fg-hover)';
case 'subtle':
return 'var(--btn-subtle-fg-hover)';
default:
return '';
}
}};
}
} }
&:focus-visible { &:focus-visible {
@@ -131,6 +166,25 @@ const StyledButton = styled(MantineButton)<StyledButtonProps>`
&:active { &:active {
transform: scale(0.98); transform: scale(0.98);
} }
& .mantine-Button-centerLoader {
display: none;
}
& .mantine-Button-leftIcon {
margin-right: 0.5rem;
}
`;
const ButtonChildWrapper = styled.span<ButtonProps>`
color: ${(props) => props.loading && 'transparent !important'};
`;
const SpinnerWrapper = styled.div`
position: absolute;
top: 50%;
left: 50%;
transform: translate3d(-50%, -50%, 0);
`; `;
export const _Button = forwardRef<HTMLButtonElement, ButtonProps>( export const _Button = forwardRef<HTMLButtonElement, ButtonProps>(
@@ -139,7 +193,14 @@ export const _Button = forwardRef<HTMLButtonElement, ButtonProps>(
return ( return (
<Tooltip withinPortal {...tooltip}> <Tooltip withinPortal {...tooltip}>
<StyledButton ref={ref} loaderPosition="center" {...props}> <StyledButton ref={ref} loaderPosition="center" {...props}>
{children} <ButtonChildWrapper loading={props.loading}>
{children}
</ButtonChildWrapper>
{props.loading && (
<SpinnerWrapper>
<Spinner />
</SpinnerWrapper>
)}
</StyledButton> </StyledButton>
</Tooltip> </Tooltip>
); );
@@ -147,7 +208,14 @@ export const _Button = forwardRef<HTMLButtonElement, ButtonProps>(
return ( return (
<StyledButton ref={ref} loaderPosition="center" {...props}> <StyledButton ref={ref} loaderPosition="center" {...props}>
{children} <ButtonChildWrapper loading={props.loading}>
{children}
</ButtonChildWrapper>
{props.loading && (
<SpinnerWrapper>
<Spinner />
</SpinnerWrapper>
)}
</StyledButton> </StyledButton>
); );
} }
@@ -158,6 +226,7 @@ export const Button = createPolymorphicComponent<'button', ButtonProps>(
); );
_Button.defaultProps = { _Button.defaultProps = {
loading: undefined,
onClick: undefined, onClick: undefined,
tooltip: undefined, tooltip: undefined,
}; };