Skip to content

Commit 2bccd91

Browse files
moire
1 parent 70267de commit 2bccd91

File tree

7 files changed

+181
-91
lines changed

7 files changed

+181
-91
lines changed

docs/examples/spinner/dontLabel.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import { Flex, Spinner, Text } from 'gestalt';
1+
import { Flex, Spinner } from 'gestalt';
22

33
export default function Example() {
44
return (
55
<Flex alignItems="center" height="100%" justifyContent="center" width="100%">
66
<Flex direction="column" gap={2}>
7-
<Spinner accessibilityLabel="Example spinner" show />
8-
9-
<Text weight="bold">Loading…</Text>
7+
<Spinner accessibilityLabel="Dont Label improperly" label="Loading…" show />
108
</Flex>
119
</Flex>
1210
);

docs/examples/spinner/label.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default function Example() {
55
return (
66
<Box height="100%" width="100%">
77
<Flex alignItems="center" height="100%" justifyContent="center" width="100%">
8-
<Spinner label="We’re adding new ideas to your homefeed" show={!reduced} />
8+
<Spinner accessibilityLabel="test" label="We’re adding new ideas to your homefeed" show={!reduced} />
99
</Flex>
1010
</Box>
1111
);

packages/gestalt/src/Spinner.tsx

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useId } from 'react';
12
import classnames from 'classnames';
23
import Box from './Box';
34
import { useDefaultLabelContext } from './contexts/DefaultLabelProvider';
@@ -56,6 +57,7 @@ export default function Spinner({
5657
size = 'md',
5758
}: Props) {
5859
const { accessibilityLabel: accessibilityLabelDefault } = useDefaultLabelContext('Spinner');
60+
const id = useId();
5961

6062
const isInVRExperiment = useInExperiment({
6163
webExperimentName: 'web_gestalt_visualRefresh',
@@ -69,34 +71,37 @@ export default function Spinner({
6971
// 'subtle' maps to 'default' as it is not a VR color variant
7072
color={color === 'subtle' ? 'default' : color}
7173
delay={delay}
72-
show={show}
74+
label={label}
7375
// 'md' maps to 'lg' as it doesn't exist in VR Spinner
76+
show={show}
7477
size={size === 'md' ? 'lg' : size}
7578
/>
7679
);
7780
}
7881

7982
return show ? (
80-
<Flex gap={6}>
81-
<Box display="flex" justifyContent="around" overflow="hidden">
82-
<div className={classnames(styles.icon, { [styles.delay]: delay })}>
83-
<Icon
84-
accessibilityLabel={accessibilityLabel ?? accessibilityLabelDefault}
85-
// map non-classic colors to subtle
86-
color={color === 'default' || color === 'subtle' ? color : 'subtle'}
87-
icon="knoop"
88-
size={SIZE_NAME_TO_PIXEL[size]}
89-
/>
90-
</div>
91-
</Box>
92-
{label && (
93-
<Box minWidth={200}>
94-
<TextUI align="center" size="sm">
95-
{label}
96-
</TextUI>
83+
<Box padding={label ? 1 : undefined}>
84+
<Flex direction="column" gap={6}>
85+
<Box display="flex" justifyContent="around" overflow="hidden">
86+
<div aria-describedby={id} className={classnames(styles.icon, { [styles.delay]: delay })}>
87+
<Icon
88+
accessibilityLabel={accessibilityLabel ?? label ?? accessibilityLabelDefault}
89+
// map non-classic colors to subtle
90+
color={color === 'default' || color === 'subtle' ? color : 'subtle'}
91+
icon="knoop"
92+
size={SIZE_NAME_TO_PIXEL[size]}
93+
/>
94+
</div>
9795
</Box>
98-
)}
99-
</Flex>
96+
{label && (
97+
<Box minWidth={200}>
98+
<TextUI align="center" id={id} size="sm">
99+
{label}
100+
</TextUI>
101+
</Box>
102+
)}
103+
</Flex>{' '}
104+
</Box>
100105
) : (
101106
<div />
102107
);

packages/gestalt/src/Spinner/VRSpinner.tsx

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
import { useEffect, useState } from 'react';
1+
import { useEffect, useId, useState } from 'react';
22
import classnames from 'classnames';
33
import vrLightDesignTokens from 'gestalt-design-tokens/dist/json/vr-theme/variables-light.json';
44
import styles from './VRSpinner.css';
55
import Box from '../Box';
66
import { useDefaultLabelContext } from '../contexts/DefaultLabelProvider';
7+
import Flex from '../Flex';
8+
import TextUI from '../TextUI';
79

810
const SIZE_NAME_TO_PIXEL = {
911
sm: 32,
1012
lg: 56,
1113
} as const;
1214

1315
type SpinnerBodyProps = {
16+
accessibilityDescribedby?: string;
1417
accessibilityLabel: string;
1518
delay: boolean;
1619
show: boolean;
@@ -20,6 +23,7 @@ type SpinnerBodyProps = {
2023
};
2124

2225
function SpinnerBody({
26+
accessibilityDescribedby,
2327
accessibilityLabel,
2428
delay,
2529
show,
@@ -39,7 +43,7 @@ function SpinnerBody({
3943
: {};
4044

4145
return (
42-
<Box display="flex" justifyContent="around">
46+
<Box aria-describedby={accessibilityDescribedby} display="flex" justifyContent="around">
4347
<div
4448
aria-label={accessibilityLabel}
4549
className={classnames(styles.spinner, {
@@ -81,6 +85,7 @@ function SpinnerBody({
8185

8286
type Props = {
8387
accessibilityLabel?: string;
88+
label?: string;
8489
delay?: boolean;
8590
show: boolean;
8691
size?: 'sm' | 'lg';
@@ -90,12 +95,14 @@ type Props = {
9095
export default function Spinner({
9196
accessibilityLabel,
9297
delay = true,
98+
label,
9399
show: showProp,
94100
size = 'lg',
95101
color = 'default',
96102
}: Props) {
97103
const [show, setShow] = useState(showProp);
98104
const { accessibilityLabel: accessibilityLabelDefault } = useDefaultLabelContext('Spinner');
105+
const id = useId();
99106

100107
const unmountSpinner = () => {
101108
if (!showProp) setShow(false);
@@ -108,14 +115,26 @@ export default function Spinner({
108115
if (!show) return null;
109116

110117
return (
111-
<SpinnerBody
112-
accessibilityLabel={accessibilityLabel || accessibilityLabelDefault}
113-
color={color}
114-
delay={delay}
115-
onExitAnimationEnd={unmountSpinner}
116-
show={showProp}
117-
size={size}
118-
/>
118+
<Box padding={label ? 1 : undefined}>
119+
<Flex direction="column" gap={6}>
120+
<SpinnerBody
121+
accessibilityDescribedby={id}
122+
accessibilityLabel={accessibilityLabel ?? label ?? accessibilityLabelDefault}
123+
color={color}
124+
delay={delay}
125+
onExitAnimationEnd={unmountSpinner}
126+
show={showProp}
127+
size={size}
128+
/>
129+
{label && (
130+
<Box minWidth={200}>
131+
<TextUI align="center" id={id} size="sm">
132+
{label}
133+
</TextUI>
134+
</Box>
135+
)}
136+
</Flex>
137+
</Box>
119138
);
120139
}
121140

packages/gestalt/src/Text.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ type Props = {
4242
* Available for testing purposes, if needed. Consider [better queries](https://testing-library.com/docs/queries/about/#priority) before using this prop.
4343
*/
4444
dataTestId?: string;
45+
/**
46+
* A unique identifier for the element.
47+
*/
48+
id?: string;
4549
/**
4650
* Indicates how the text should flow with the surrounding content. See the [block vs inline variant](https://gestalt.pinterest.systems/web/text#Block-vs.-inline) for more details.
4751
*/
@@ -92,6 +96,7 @@ const TextWithForwardRef = forwardRef<HTMLDivElement, Props>(function Text(
9296
children,
9397
color = 'default',
9498
dataTestId,
99+
id,
95100
inline = false,
96101
italic = false,
97102
lineClamp,
@@ -170,6 +175,7 @@ const TextWithForwardRef = forwardRef<HTMLDivElement, Props>(function Text(
170175
<Tag
171176
className={cs}
172177
data-test-id={dataTestId}
178+
id={id}
173179
title={
174180
title ?? (isNotNullish(lineClamp) && typeof children === 'string' ? children : undefined)
175181
}

packages/gestalt/src/TextUI.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ type Props = {
4343
* Available for testing purposes, if needed. Consider [better queries](https://testing-library.com/docs/queries/about/#priority) before using this prop.
4444
*/
4545
dataTestId?: string;
46+
/**
47+
* A unique identifier for the element.
48+
*/
49+
id?: string;
4650
/**
4751
* Indicates how the text should flow with the surrounding content. See the [block vs inline variant](https://gestalt.pinterest.systems/web/text#Block-vs.-inline) for more details.
4852
*/
@@ -91,6 +95,7 @@ const TextUIWithForwardRef = forwardRef<HTMLDivElement, Props>(function Text(
9195
overflow = 'breakWord',
9296
size = 'md',
9397
title,
98+
id,
9499
}: Props,
95100
ref,
96101
): ReactElement {
@@ -148,6 +153,7 @@ const TextUIWithForwardRef = forwardRef<HTMLDivElement, Props>(function Text(
148153
<Tag
149154
className={cs}
150155
data-test-id={dataTestId}
156+
id={id}
151157
title={
152158
title ?? (isNotNullish(lineClamp) && typeof children === 'string' ? children : undefined)
153159
}

0 commit comments

Comments
 (0)