parent
4ea8c95d9a
commit
56c795206e
|
|
@ -33,6 +33,11 @@ export interface ButtonProps extends Omit<HeadlessButtonProps, "className"> {
|
|||
iconPosition?: (typeof BUTTON_ICON_POSITIONS)[keyof typeof BUTTON_ICON_POSITIONS];
|
||||
/** Makes the button visually and functionaly disabled but focusable */
|
||||
visuallyDisabled?: boolean;
|
||||
/** Indicates the loading text that will be used by screen readers
|
||||
* when the button is in loading state
|
||||
* @default Loading...
|
||||
*/
|
||||
loadingText?: string;
|
||||
}
|
||||
|
||||
export const Button = forwardRef(
|
||||
|
|
@ -44,6 +49,7 @@ export const Button = forwardRef(
|
|||
icon,
|
||||
iconPosition = "start",
|
||||
isLoading,
|
||||
loadingText = "Loading...",
|
||||
// eslint-disable-next-line -- TODO add onKeyUp when the bug is fixed https://github.com/adobe/react-spectrum/issues/4350
|
||||
onKeyUp,
|
||||
variant = "filled",
|
||||
|
|
@ -53,24 +59,21 @@ export const Button = forwardRef(
|
|||
const { visuallyHiddenProps } = useVisuallyHidden();
|
||||
|
||||
const renderChildren = () => {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<>
|
||||
return (
|
||||
<>
|
||||
<span aria-hidden={isLoading ? true : undefined} data-content="">
|
||||
{icon}
|
||||
<Text lineClamp={1} textAlign="center">
|
||||
{children}
|
||||
</Text>
|
||||
</span>
|
||||
|
||||
<span aria-hidden={!isLoading ? true : undefined} data-loader="">
|
||||
<HeadlessIcon>
|
||||
<Spinner />
|
||||
</HeadlessIcon>
|
||||
{/* TODO(pawan): How to make sure "Loading..." text is internationalized? */}
|
||||
<span {...visuallyHiddenProps}>Loading...</span>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{icon}
|
||||
<Text lineClamp={1} textAlign="center">
|
||||
{children}
|
||||
</Text>
|
||||
<span {...visuallyHiddenProps}>{loadingText}</span>
|
||||
</span>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
@ -93,7 +96,7 @@ export const Button = forwardRef(
|
|||
{...rest}
|
||||
>
|
||||
{renderChildren()}
|
||||
<DragContainer data-hidden="" />
|
||||
<DragContainer aria-hidden="true" />
|
||||
</StyledButton>
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ export const buttonStyles = css<StyledButtonProps>`
|
|||
background-color: transparent;
|
||||
color: var(--color-fg-${$color});
|
||||
border-color: var(--color-bd-${$color});
|
||||
border-width: var(--border-width-1);
|
||||
|
||||
&[data-hovered]:not([aria-disabled]) {
|
||||
background-color: var(--color-bg-${$color}-subtle-hover);
|
||||
|
|
@ -52,7 +51,6 @@ export const buttonStyles = css<StyledButtonProps>`
|
|||
background: transparent;
|
||||
color: var(--color-fg-${$color});
|
||||
border-color: transparent;
|
||||
border-width: 0;
|
||||
|
||||
&[data-hovered]:not([aria-disabled]) {
|
||||
background: var(--color-bg-${$color}-subtle-hover);
|
||||
|
|
@ -70,41 +68,18 @@ export const StyledButton = styled(HeadlessButton)<StyledButtonProps>`
|
|||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
outline: 0;
|
||||
padding: var(--spacing-2) var(--spacing-4);
|
||||
block-size: var(--sizing-8);
|
||||
border-radius: var(--border-radius-1);
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
min-inline-size: var(--sizing-8);
|
||||
position: relative;
|
||||
font-weight: 600;
|
||||
border-width: 0;
|
||||
border-style: solid;
|
||||
font-family: inherit;
|
||||
|
||||
&[data-icon-position="start"] *:not([data-hidden]) + *:not([data-hidden]) {
|
||||
margin-inline-start: var(--spacing-1);
|
||||
}
|
||||
|
||||
&[data-icon-position="end"] *:not([data-hidden]) + *:not([data-hidden]) {
|
||||
margin-inline-end: var(--spacing-1);
|
||||
}
|
||||
|
||||
${buttonStyles}
|
||||
|
||||
&[data-icon-position="end"] {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
/** Note: adding direct selector ">" here because blueprint also has data-icon attribute on their icons */
|
||||
& > [data-icon] {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: var(--sizing-4);
|
||||
width: var(--sizing-4);
|
||||
}
|
||||
border-style: solid;
|
||||
border-width: var(--border-width-1);
|
||||
padding-inline: var(--spacing-4);
|
||||
block-size: var(--sizing-8);
|
||||
min-inline-size: var(--sizing-8);
|
||||
border-radius: var(--border-radius-1);
|
||||
|
||||
// Note: adding important here as ADS is overriding the color of blueprint icon globally
|
||||
// TODO(pawan): Remove this once ADS team removes the global override
|
||||
|
|
@ -112,6 +87,44 @@ export const StyledButton = styled(HeadlessButton)<StyledButtonProps>`
|
|||
color: currentColor !important;
|
||||
}
|
||||
|
||||
${buttonStyles}
|
||||
|
||||
/**
|
||||
* ----------------------------------------------------------------------------
|
||||
* CONTENT
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
& [data-content] {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&[data-icon-position="start"] {
|
||||
[data-content] *:not([data-hidden]) + *:not([data-hidden]) {
|
||||
margin-inline-start: var(--spacing-1);
|
||||
}
|
||||
}
|
||||
|
||||
&[data-icon-position="end"] {
|
||||
[data-content] *:not([data-hidden]) + *:not([data-hidden]) {
|
||||
margin-inline-end: var(--spacing-1);
|
||||
}
|
||||
}
|
||||
|
||||
&[data-icon-position="end"] [data-content] {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
/** Note: adding direct selector ">" here because blueprint also has data-icon attribute on their icons */
|
||||
& [data-content] > [data-icon] {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: var(--sizing-4);
|
||||
width: var(--sizing-4);
|
||||
}
|
||||
|
||||
/**
|
||||
* ----------------------------------------------------------------------------
|
||||
* FOCUSSED
|
||||
|
|
@ -133,14 +146,33 @@ export const StyledButton = styled(HeadlessButton)<StyledButtonProps>`
|
|||
|
||||
/**
|
||||
* ----------------------------------------------------------------------------
|
||||
* LOADING
|
||||
* LOADING AND LOADER
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
&[data-loading] {
|
||||
cursor: default;
|
||||
/** adding opacity 1 here because we are lowering opacity for aria-disabled and when loading is true, aria-disabled is also true */
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&[data-loading] [data-content] {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
& [data-loader] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&[data-loading] [data-loader] {
|
||||
display: block;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: inherit;
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user