@react-spectrum/button 3.12.3 → 3.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/import.mjs +302 -7
- package/dist/main.css +1 -1
- package/dist/main.js +301 -6
- package/dist/main.js.map +1 -1
- package/dist/module.js +302 -7
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +15 -12
- package/src/Button.tsx +54 -3
- package/src/FieldButton.tsx +3 -1
package/src/Button.tsx
CHANGED
@@ -20,18 +20,39 @@ import {
|
|
20
20
|
} from '@react-spectrum/utils';
|
21
21
|
import {FocusableRef} from '@react-types/shared';
|
22
22
|
import {FocusRing} from '@react-aria/focus';
|
23
|
+
// @ts-ignore
|
24
|
+
import intlMessages from '../intl/*.json';
|
23
25
|
import {mergeProps} from '@react-aria/utils';
|
24
|
-
import
|
26
|
+
import {ProgressCircle} from '@react-spectrum/progress';
|
27
|
+
import React, {ElementType, ReactElement, useEffect, useState} from 'react';
|
25
28
|
import {SpectrumButtonProps} from '@react-types/button';
|
26
29
|
import styles from '@adobe/spectrum-css-temp/components/button/vars.css';
|
27
30
|
import {Text} from '@react-spectrum/text';
|
28
31
|
import {useButton} from '@react-aria/button';
|
29
32
|
import {useHover} from '@react-aria/interactions';
|
33
|
+
import {useLocalizedStringFormatter} from '@react-aria/i18n';
|
30
34
|
import {useProviderProps} from '@react-spectrum/provider';
|
31
35
|
|
36
|
+
function disablePendingProps(props) {
|
37
|
+
// Don't allow interaction while UNSTABLE_isPending is true
|
38
|
+
if (props.UNSTABLE_isPending) {
|
39
|
+
props.onPress = undefined;
|
40
|
+
props.onPressStart = undefined;
|
41
|
+
props.onPressEnd = undefined;
|
42
|
+
props.onPressChange = undefined;
|
43
|
+
props.onPressUp = undefined;
|
44
|
+
props.onKeyDown = undefined;
|
45
|
+
props.onKeyUp = undefined;
|
46
|
+
props.onClick = undefined;
|
47
|
+
props.href = undefined;
|
48
|
+
}
|
49
|
+
return props;
|
50
|
+
}
|
51
|
+
|
32
52
|
function Button<T extends ElementType = 'button'>(props: SpectrumButtonProps<T>, ref: FocusableRef<HTMLElement>) {
|
33
53
|
props = useProviderProps(props);
|
34
54
|
props = useSlotProps(props, 'button');
|
55
|
+
props = disablePendingProps(props);
|
35
56
|
let {
|
36
57
|
elementType: ElementType = 'button',
|
37
58
|
children,
|
@@ -39,15 +60,36 @@ function Button<T extends ElementType = 'button'>(props: SpectrumButtonProps<T>,
|
|
39
60
|
style = variant === 'accent' || variant === 'cta' ? 'fill' : 'outline',
|
40
61
|
staticColor,
|
41
62
|
isDisabled,
|
63
|
+
UNSTABLE_isPending,
|
42
64
|
autoFocus,
|
43
65
|
...otherProps
|
44
66
|
} = props;
|
45
67
|
let domRef = useFocusableRef(ref);
|
46
68
|
let {buttonProps, isPressed} = useButton(props, domRef);
|
47
69
|
let {hoverProps, isHovered} = useHover({isDisabled});
|
70
|
+
let stringFormatter = useLocalizedStringFormatter(intlMessages);
|
48
71
|
let {styleProps} = useStyleProps(otherProps);
|
49
72
|
let hasLabel = useHasChild(`.${styles['spectrum-Button-label']}`, domRef);
|
50
73
|
let hasIcon = useHasChild(`.${styles['spectrum-Icon']}`, domRef);
|
74
|
+
let [isProgressVisible, setIsProgressVisible] = useState(false);
|
75
|
+
|
76
|
+
useEffect(() => {
|
77
|
+
let timeout: ReturnType<typeof setTimeout>;
|
78
|
+
|
79
|
+
if (UNSTABLE_isPending) {
|
80
|
+
// Start timer when UNSTABLE_isPending is set to true.
|
81
|
+
timeout = setTimeout(() => {
|
82
|
+
setIsProgressVisible(true);
|
83
|
+
}, 1000);
|
84
|
+
} else {
|
85
|
+
// Exit loading state when UNSTABLE_isPending is set to false. */
|
86
|
+
setIsProgressVisible(false);
|
87
|
+
}
|
88
|
+
return () => {
|
89
|
+
// Clean up on unmount or when user removes UNSTABLE_isPending prop before entering loading state.
|
90
|
+
clearTimeout(timeout);
|
91
|
+
};
|
92
|
+
}, [UNSTABLE_isPending]);
|
51
93
|
|
52
94
|
if (variant === 'cta') {
|
53
95
|
variant = 'accent';
|
@@ -65,15 +107,18 @@ function Button<T extends ElementType = 'button'>(props: SpectrumButtonProps<T>,
|
|
65
107
|
data-variant={variant}
|
66
108
|
data-style={style}
|
67
109
|
data-static-color={staticColor || undefined}
|
110
|
+
aria-disabled={UNSTABLE_isPending || undefined}
|
111
|
+
aria-live={UNSTABLE_isPending ? 'polite' : undefined}
|
68
112
|
className={
|
69
113
|
classNames(
|
70
114
|
styles,
|
71
115
|
'spectrum-Button',
|
72
116
|
{
|
73
117
|
'spectrum-Button--iconOnly': hasIcon && !hasLabel,
|
74
|
-
'is-disabled': isDisabled,
|
118
|
+
'is-disabled': isDisabled || isProgressVisible,
|
75
119
|
'is-active': isPressed,
|
76
|
-
'is-hovered': isHovered
|
120
|
+
'is-hovered': isHovered,
|
121
|
+
'spectrum-Button--pending': isProgressVisible
|
77
122
|
},
|
78
123
|
styleProps.className
|
79
124
|
)
|
@@ -88,6 +133,12 @@ function Button<T extends ElementType = 'button'>(props: SpectrumButtonProps<T>,
|
|
88
133
|
UNSAFE_className: classNames(styles, 'spectrum-Button-label')
|
89
134
|
}
|
90
135
|
}}>
|
136
|
+
{isProgressVisible && <ProgressCircle
|
137
|
+
aria-label={stringFormatter.format('loading')}
|
138
|
+
isIndeterminate
|
139
|
+
size="S"
|
140
|
+
UNSAFE_className={classNames(styles, 'spectrum-Button-circleLoader')}
|
141
|
+
variant={staticColor ? 'overBackground' : undefined} />}
|
91
142
|
{typeof children === 'string'
|
92
143
|
? <Text>{children}</Text>
|
93
144
|
: children}
|
package/src/FieldButton.tsx
CHANGED
@@ -24,6 +24,7 @@ interface FieldButtonProps extends ButtonProps, DOMProps, StyleProps {
|
|
24
24
|
isQuiet?: boolean,
|
25
25
|
isActive?: boolean,
|
26
26
|
validationState?: 'valid' | 'invalid',
|
27
|
+
isInvalid?: boolean,
|
27
28
|
focusRingClass?: string
|
28
29
|
}
|
29
30
|
|
@@ -34,6 +35,7 @@ function FieldButton(props: FieldButtonProps, ref: FocusableRef) {
|
|
34
35
|
isQuiet,
|
35
36
|
isDisabled,
|
36
37
|
validationState,
|
38
|
+
isInvalid,
|
37
39
|
children,
|
38
40
|
autoFocus,
|
39
41
|
isActive,
|
@@ -58,7 +60,7 @@ function FieldButton(props: FieldButtonProps, ref: FocusableRef) {
|
|
58
60
|
'spectrum-FieldButton--quiet': isQuiet,
|
59
61
|
'is-active': isActive || isPressed,
|
60
62
|
'is-disabled': isDisabled,
|
61
|
-
'spectrum-FieldButton--invalid': validationState === 'invalid',
|
63
|
+
'spectrum-FieldButton--invalid': isInvalid || validationState === 'invalid',
|
62
64
|
'is-hovered': isHovered
|
63
65
|
},
|
64
66
|
styleProps.className
|