feat: More obvious loading state when submitting a post (#35153)

This commit is contained in:
diondiondion 2025-06-24 16:08:48 +02:00 committed by GitHub
commit 644da36336
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 120 additions and 28 deletions

View file

@ -3,12 +3,15 @@ import { useCallback } from 'react';
import classNames from 'classnames';
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
interface BaseProps
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
block?: boolean;
secondary?: boolean;
compact?: boolean;
dangerous?: boolean;
loading?: boolean;
}
interface PropsChildren extends PropsWithChildren<BaseProps> {
@ -34,6 +37,7 @@ export const Button: React.FC<Props> = ({
secondary,
compact,
dangerous,
loading,
className,
title,
text,
@ -42,13 +46,18 @@ export const Button: React.FC<Props> = ({
}) => {
const handleClick = useCallback<React.MouseEventHandler<HTMLButtonElement>>(
(e) => {
if (!disabled && onClick) {
if (disabled || loading) {
e.stopPropagation();
e.preventDefault();
} else if (onClick) {
onClick(e);
}
},
[disabled, onClick],
[disabled, loading, onClick],
);
const label = text ?? children;
return (
<button
className={classNames('button', className, {
@ -56,14 +65,27 @@ export const Button: React.FC<Props> = ({
'button--compact': compact,
'button--block': block,
'button--dangerous': dangerous,
loading,
})}
disabled={disabled}
// Disabled buttons can't have focus, so we don't really
// disable the button during loading
disabled={disabled && !loading}
aria-disabled={loading}
// If the loading prop is used, announce label changes
aria-live={loading !== undefined ? 'polite' : undefined}
onClick={handleClick}
title={title}
type={type}
{...props}
>
{text ?? children}
{loading ? (
<>
<span className='button__label-wrapper'>{label}</span>
<LoadingIndicator role='none' />
</>
) : (
label
)}
</button>
);
};