Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Button): add loading state #990

Merged
merged 3 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ exports[`BentoMenuButton Matches Snapshot (productGroups and externalLinks) 1`]
}

.c2 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -874,7 +873,6 @@ exports[`BentoMenuButton Matches Snapshot (productLinks and externalLinks) 1`] =
}

.c2 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -1607,7 +1605,6 @@ exports[`BentoMenuButton Matches Snapshot (tag="nav") 1`] = `
}

.c2 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ export const defaultButtonStyles = css<{ $focusable?: boolean, isMobile: boolean
${(props) => props.$focusable !== false && focus};

> svg {
color: inherit;
height: ${({ isMobile }) => (isMobile ? 'var(--size-1halfx)' : 'var(--size-1x)')};
width: ${({ isMobile }) => (isMobile ? 'var(--size-1halfx)' : 'var(--size-1x)')};
}
Expand Down
15 changes: 0 additions & 15 deletions packages/react/src/components/buttons/button.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ exports[`Button has destructive styles (inverted) 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -158,7 +157,6 @@ exports[`Button has destructive styles 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -263,7 +261,6 @@ exports[`Button has destructive-secondary styles (inverted) 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -360,7 +357,6 @@ exports[`Button has destructive-secondary styles 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -465,7 +461,6 @@ exports[`Button has left and right icons 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -588,7 +583,6 @@ exports[`Button has mobile styles 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1halfx);
width: var(--size-1halfx);
}
Expand Down Expand Up @@ -685,7 +679,6 @@ exports[`Button has primary disabled styles 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -783,7 +776,6 @@ exports[`Button has primary styles (inverted) 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -880,7 +872,6 @@ exports[`Button has primary styles 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -977,7 +968,6 @@ exports[`Button has secondary styles (inverted) 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -1074,7 +1064,6 @@ exports[`Button has secondary styles 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -1171,7 +1160,6 @@ exports[`Button has small styles 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -1268,7 +1256,6 @@ exports[`Button has small styles on mobile 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1halfx);
width: var(--size-1halfx);
}
Expand Down Expand Up @@ -1365,7 +1352,6 @@ exports[`Button has tertiary styles (inverted) 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -1462,7 +1448,6 @@ exports[`Button has tertiary styles 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down
55 changes: 39 additions & 16 deletions packages/react/src/components/buttons/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import {
Icon,
IconName,
} from '../icon/icon';
import { Spinner } from '../spinner/spinner';
import { ResolvedTheme } from '../../themes/theme';
import { useTranslation } from '../../i18n/use-translation';
import { useDeviceContext } from '../device-context-provider/device-context-provider';
import { AbstractButton, ButtonType, getButtonTypeStyles } from './abstract-button';

Expand All @@ -36,6 +38,11 @@ export interface ButtonProps {
focusable?: boolean;
inverted?: boolean;
label?: string;
loading?: boolean;
/**
* @default Loading...
*/
loadingLabel?: string;
/**
* Size variant
* @default medium
Expand All @@ -53,6 +60,10 @@ export interface ButtonProps {
onKeyDown?(event: KeyboardEvent<HTMLButtonElement>): void;
}

const StyledSpinner = styled(Spinner)`
margin-right: var(--spacing-1x);
`;

const LeftIcon = styled(Icon)`
margin-right: var(--spacing-1x);
`;
Expand All @@ -73,6 +84,8 @@ export const Button = forwardRef<HTMLButtonElement, PropsWithChildren<ButtonProp
disabled,
focusable = true,
label,
loading,
loadingLabel,
onClick,
onFocus,
onBlur,
Expand All @@ -84,6 +97,7 @@ export const Button = forwardRef<HTMLButtonElement, PropsWithChildren<ButtonProp
...props
}: PropsWithChildren<ButtonProps>, ref: Ref<HTMLButtonElement>): ReactElement => {
const { isMobile } = useDeviceContext();
const { t } = useTranslation('button');
const iconSize = props?.size === 'small' && !isMobile ? '16' : '24';

const handleClick = (event: MouseEvent<HTMLButtonElement>): void => {
Expand Down Expand Up @@ -122,22 +136,31 @@ export const Button = forwardRef<HTMLButtonElement, PropsWithChildren<ButtonProp
{...props /* eslint-disable-line react/jsx-props-no-spreading *//* To spread aria-* and data-* */}
>
{children}
{leftIconName && (
<LeftIcon
aria-hidden="true"
data-testid="left-icon"
name={leftIconName}
size={iconSize}
/>
)}
{label}
{rightIconName && (
<RightIcon
aria-hidden="true"
data-testid="right-icon"
name={rightIconName}
size={iconSize}
/>
{loading ? (
<>
<StyledSpinner />
{loadingLabel || t('loadingLabel')}
</>
) : (
<>
{leftIconName && (
<LeftIcon
aria-hidden="true"
data-testid="left-icon"
name={leftIconName}
size={iconSize}
/>
)}
{label}
{rightIconName && (
<RightIcon
aria-hidden="true"
data-testid="right-icon"
name={rightIconName}
size={iconSize}
/>
)}
</>
)}
</StyledButton>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ exports[`Icon Button Has destructive-secondary styles 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -164,7 +163,6 @@ exports[`Icon Button Has disabled styles 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -276,7 +274,6 @@ exports[`Icon Button Has mobile styles 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1halfx);
width: var(--size-1halfx);
}
Expand Down Expand Up @@ -387,7 +384,6 @@ exports[`Icon Button Has primary styles 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -498,7 +494,6 @@ exports[`Icon Button Has secondary styles 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -609,7 +604,6 @@ exports[`Icon Button Has small styles 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -721,7 +715,6 @@ exports[`Icon Button Has tertiary styles 1`] = `
}

.c0 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ exports[`Carousel should match snapshot 1`] = `
}

.c1 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ exports[`Combobox matches the snapshot (disabled) 1`] = `
}

.c6 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -522,7 +521,6 @@ exports[`Combobox matches the snapshot (invalid) 1`] = `
}

.c8 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down Expand Up @@ -1042,7 +1040,6 @@ exports[`Combobox matches the snapshot (mobile) 1`] = `
}

.c4 > svg {
color: inherit;
height: var(--size-1halfx);
width: var(--size-1halfx);
}
Expand Down Expand Up @@ -1492,7 +1489,6 @@ exports[`Combobox matches the snapshot 1`] = `
}

.c7 > svg {
color: inherit;
height: var(--size-1x);
width: var(--size-1x);
}
Expand Down
Loading