Skip to content

Commit f9ac9a4

Browse files
committed
refactor(core): consolidate inline visually-hidden styles into VisuallyHidden primitive
1 parent 72bff93 commit f9ac9a4

6 files changed

Lines changed: 18 additions & 61 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@astryxdesign/core': patch
3+
---
4+
5+
[refactor] Consolidated 5 inline visually-hidden style blocks into the shared VisuallyHidden primitive (Button, Link, ProgressBar, Switch, TextArea); no behavior change.
6+
@cixzhang

packages/core/src/Button/Button.tsx

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import {
3434
} from '../theme/tokens.stylex';
3535
import {Tooltip} from '../Tooltip/Tooltip';
3636
import {Spinner} from '../Spinner';
37+
import {VisuallyHidden} from '../VisuallyHidden';
3738

3839
import {EDGE_COMP_ATTR} from '../Layout/edgeCompensation.stylex';
3940
import {useSize} from '../SizeContext/SizeContext';
@@ -124,17 +125,6 @@ const styles = stylex.create({
124125
textOverflow: 'ellipsis',
125126
minWidth: 0,
126127
},
127-
visuallyHidden: {
128-
position: 'absolute',
129-
width: '1px',
130-
height: '1px',
131-
padding: 0,
132-
margin: '-1px',
133-
overflow: 'hidden',
134-
clip: 'rect(0, 0, 0, 0)',
135-
whiteSpace: 'nowrap',
136-
borderWidth: 0,
137-
},
138128
link: {
139129
textDecoration: 'none',
140130
},
@@ -690,12 +680,9 @@ export function Button({
690680
)}
691681
</span>
692682
{/* Live region for loading state announcements */}
693-
<span
694-
{...stylex.props(styles.visuallyHidden)}
695-
role="status"
696-
aria-live="polite">
683+
<VisuallyHidden role="status" aria-live="polite">
697684
{isLoadingState ? 'Loading' : ''}
698-
</span>
685+
</VisuallyHidden>
699686
</>
700687
);
701688

packages/core/src/Link/Link.tsx

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
import {Icon} from '../Icon';
3131
import {Tooltip} from '../Tooltip';
3232
import {Text} from '../Text';
33+
import {VisuallyHidden} from '../VisuallyHidden';
3334
import type {
3435
TextType,
3536
TextSize,
@@ -98,18 +99,6 @@ const styles = stylex.create({
9899
fontSize: typeScaleVars['--text-body-size'],
99100
lineHeight: typeScaleVars['--text-body-leading'],
100101
},
101-
// Screen-reader-only text (announces the new-tab context change).
102-
visuallyHidden: {
103-
position: 'absolute',
104-
width: 1,
105-
height: 1,
106-
margin: -1,
107-
padding: 0,
108-
overflow: 'hidden',
109-
clip: 'rect(0, 0, 0, 0)',
110-
whiteSpace: 'nowrap',
111-
borderStyle: 'none',
112-
},
113102
});
114103

115104
/**
@@ -345,7 +334,7 @@ export function Link({
345334
{isExternalLink && !renderAsButton && (
346335
<>
347336
<Icon icon="externalLink" size="xsm" color="inherit" />
348-
<span {...stylex.props(styles.visuallyHidden)}>{newTabLabel}</span>
337+
<VisuallyHidden>{newTabLabel}</VisuallyHidden>
349338
</>
350339
)}
351340
</>

packages/core/src/ProgressBar/ProgressBar.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
import {mergeProps} from '../utils';
3232
import type {BaseProps} from '../BaseProps';
3333
import {themeProps} from '../utils/themeProps';
34+
import {VisuallyHidden} from '../VisuallyHidden';
3435

3536
/**
3637
* Extensible variant map for ProgressBar.
@@ -313,9 +314,7 @@ export function ProgressBar({
313314
)}
314315
</div>
315316
) : (
316-
<span id={labelId} {...stylex.props(styles.visuallyHidden)}>
317-
{label}
318-
</span>
317+
<VisuallyHidden id={labelId}>{label}</VisuallyHidden>
319318
)}
320319

321320
{/* Progress track */}

packages/core/src/Switch/Switch.tsx

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {switchScope} from './switch.markers.stylex';
4444
import type {BaseProps} from '../BaseProps';
4545
import type {SizeValue} from '../utils/types';
4646
import {themeProps} from '../utils/themeProps';
47+
import {VisuallyHidden} from '../VisuallyHidden';
4748

4849
// Fixed dimensions: 40px width, 24px height, 16px thumb (off), 20px thumb (on)
4950
const SWITCH_WIDTH = 40;
@@ -179,17 +180,6 @@ const styles = stylex.create({
179180
fontSize: typeScaleVars['--text-supporting-size'],
180181
color: colorVars['--color-text-secondary'],
181182
},
182-
srOnly: {
183-
position: 'absolute',
184-
width: 1,
185-
height: 1,
186-
padding: 0,
187-
margin: -1,
188-
overflow: 'hidden',
189-
clip: 'rect(0, 0, 0, 0)',
190-
whiteSpace: 'nowrap',
191-
borderWidth: 0,
192-
},
193183
});
194184

195185
export type SwitchLabelPosition = 'start' | 'end';
@@ -416,11 +406,7 @@ export function Switch({
416406
{isBusy && <Spinner size="sm" />}
417407
</div>
418408
</div>
419-
{isBusy && (
420-
<span {...stylex.props(styles.srOnly)} role="status">
421-
Loading
422-
</span>
423-
)}
409+
{isBusy && <VisuallyHidden role="status">Loading</VisuallyHidden>}
424410
</div>
425411
);
426412

packages/core/src/TextArea/TextArea.tsx

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import type {SizeValue} from '../utils/types';
4949
import {useInputContainer} from '../hooks/useInputContainer';
5050
import {useSize} from '../SizeContext/SizeContext';
5151
import {themeProps} from '../utils/themeProps';
52+
import {VisuallyHidden} from '../VisuallyHidden';
5253

5354
const COUNTER_WARNING_THRESHOLD = 0.8;
5455

@@ -93,17 +94,6 @@ const styles = stylex.create({
9394
counterError: {
9495
color: colorVars['--color-error'],
9596
},
96-
srOnly: {
97-
position: 'absolute',
98-
width: '1px',
99-
height: '1px',
100-
padding: 0,
101-
margin: '-1px',
102-
overflow: 'hidden',
103-
clip: 'rect(0,0,0,0)',
104-
whiteSpace: 'nowrap',
105-
borderWidth: 0,
106-
},
10797
statusIcon: {
10898
position: 'absolute',
10999
top: spacingVars['--spacing-2'],
@@ -451,13 +441,13 @@ export function TextArea({
451441
optimisticValue.length > maxLength && styles.counterError,
452442
)}>
453443
{optimisticValue.length}/{maxLength}
454-
<span aria-live="polite" {...stylex.props(styles.srOnly)}>
444+
<VisuallyHidden aria-live="polite">
455445
{optimisticValue.length >= maxLength * COUNTER_WARNING_THRESHOLD
456446
? optimisticValue.length > maxLength
457447
? `${optimisticValue.length - maxLength} characters over limit`
458448
: `${maxLength - optimisticValue.length} characters remaining`
459449
: ''}
460-
</span>
450+
</VisuallyHidden>
461451
</div>
462452
)}
463453
</Field>

0 commit comments

Comments
 (0)