mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-25 06:14:59 +00:00
114 lines
3.0 KiB
TypeScript
114 lines
3.0 KiB
TypeScript
import React, { forwardRef } from 'react'
|
|
import { classNames } from '../utils/classNames'
|
|
|
|
export interface LoadingButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
children?: React.ReactNode
|
|
loading?: boolean
|
|
loadingIndicator?: React.ReactNode
|
|
loadingPosition?: 'start' | 'end' | 'center'
|
|
disabled?: boolean
|
|
startIcon?: React.ReactNode
|
|
endIcon?: React.ReactNode
|
|
variant?: 'text' | 'outlined' | 'contained'
|
|
color?: 'primary' | 'secondary' | 'success' | 'error' | 'info' | 'warning'
|
|
size?: 'small' | 'medium' | 'large'
|
|
fullWidth?: boolean
|
|
/** Test ID for automated testing */
|
|
testId?: string
|
|
}
|
|
|
|
/**
|
|
* LoadingButton - A button with loading state
|
|
*/
|
|
export const LoadingButton = forwardRef<HTMLButtonElement, LoadingButtonProps>(function LoadingButton(
|
|
{
|
|
children,
|
|
loading = false,
|
|
loadingIndicator,
|
|
loadingPosition = 'center',
|
|
disabled,
|
|
startIcon,
|
|
endIcon,
|
|
variant = 'contained',
|
|
color = 'primary',
|
|
size = 'medium',
|
|
fullWidth = false,
|
|
className,
|
|
testId,
|
|
...props
|
|
},
|
|
ref
|
|
) {
|
|
const isDisabled = disabled || loading
|
|
|
|
const defaultLoadingIndicator = (
|
|
<span className="fakemui-loading-button-spinner">
|
|
<svg className="fakemui-loading-button-spinner-svg" viewBox="22 22 44 44">
|
|
<circle
|
|
className="fakemui-loading-button-spinner-circle"
|
|
cx="44"
|
|
cy="44"
|
|
r="20.2"
|
|
fill="none"
|
|
strokeWidth="3.6"
|
|
/>
|
|
</svg>
|
|
</span>
|
|
)
|
|
|
|
const indicator = loadingIndicator || defaultLoadingIndicator
|
|
|
|
const renderContent = () => {
|
|
if (loading && loadingPosition === 'center') {
|
|
return (
|
|
<>
|
|
<span className="fakemui-loading-button-label-hidden">{children}</span>
|
|
<span className="fakemui-loading-button-loading-indicator">{indicator}</span>
|
|
</>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<>
|
|
{loading && loadingPosition === 'start' ? (
|
|
<span className="fakemui-loading-button-loading-indicator-start">{indicator}</span>
|
|
) : (
|
|
startIcon && <span className="fakemui-loading-button-start-icon">{startIcon}</span>
|
|
)}
|
|
{children}
|
|
{loading && loadingPosition === 'end' ? (
|
|
<span className="fakemui-loading-button-loading-indicator-end">{indicator}</span>
|
|
) : (
|
|
endIcon && <span className="fakemui-loading-button-end-icon">{endIcon}</span>
|
|
)}
|
|
</>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<button
|
|
ref={ref}
|
|
className={classNames(
|
|
'fakemui-loading-button',
|
|
`fakemui-loading-button-${variant}`,
|
|
`fakemui-loading-button-${color}`,
|
|
`fakemui-loading-button-${size}`,
|
|
className,
|
|
{
|
|
'fakemui-loading-button-loading': loading,
|
|
'fakemui-loading-button-disabled': isDisabled,
|
|
'fakemui-loading-button-fullwidth': fullWidth,
|
|
}
|
|
)}
|
|
disabled={isDisabled}
|
|
aria-busy={loading}
|
|
data-testid={testId}
|
|
{...props}
|
|
>
|
|
{renderContent()}
|
|
</button>
|
|
)
|
|
})
|
|
|
|
export default LoadingButton
|