Skip to content

Commit e243edf

Browse files
authored
Move shared utilities out of React component files (#7940)
1 parent 71d2772 commit e243edf

17 files changed

Lines changed: 203 additions & 174 deletions

File tree

packages/react/src/FilteredActionList/FilteredActionListLoaders.tsx

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,11 @@ import Spinner from '../Spinner'
22
import {Stack} from '../Stack/Stack'
33
import {SkeletonBox} from '../Skeleton/SkeletonBox'
44
import classes from './FilteredActionListLoaders.module.css'
5+
import {FilteredActionListLoadingType, FilteredActionListLoadingTypes} from './constants'
56

67
import type {JSX} from 'react'
78

8-
export class FilteredActionListLoadingType {
9-
public name: string
10-
public appearsInBody: boolean
11-
12-
constructor(name: string, appearsInBody: boolean) {
13-
this.name = name
14-
this.appearsInBody = appearsInBody
15-
}
16-
}
17-
18-
export const FilteredActionListLoadingTypes = {
19-
bodySpinner: new FilteredActionListLoadingType('body-spinner', true),
20-
bodySkeleton: new FilteredActionListLoadingType('body-skeleton', true),
21-
input: new FilteredActionListLoadingType('input', false),
22-
}
9+
export {FilteredActionListLoadingType, FilteredActionListLoadingTypes}
2310

2411
const SKELETON_ROW_HEIGHT = 24
2512
const SKELETON_MIN_ROWS = 3
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export class FilteredActionListLoadingType {
2+
public name: string
3+
public appearsInBody: boolean
4+
5+
constructor(name: string, appearsInBody: boolean) {
6+
this.name = name
7+
this.appearsInBody = appearsInBody
8+
}
9+
}
10+
11+
export const FilteredActionListLoadingTypes = {
12+
bodySpinner: new FilteredActionListLoadingType('body-spinner', true),
13+
bodySkeleton: new FilteredActionListLoadingType('body-skeleton', true),
14+
input: new FilteredActionListLoadingType('input', false),
15+
}

packages/react/src/KeybindingHint/components/Chord.tsx

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,9 @@ import {Fragment} from 'react'
22
import Text from '../../Text'
33
import type {KeybindingHintProps} from '../props'
44
import {Key} from './Key'
5-
import {accessibleKeyName} from '../key-names'
6-
import type {Platform} from '../platform'
75
import {clsx} from 'clsx'
86
import classes from './Chord.module.css'
9-
10-
/**
11-
* Consistent sort order for modifier keys. There should never be more than one non-modifier
12-
* key in a chord, so we don't need to worry about sorting those - we just put them at
13-
* the end.
14-
*/
15-
const keySortPriorities: Partial<Record<string, number>> = {
16-
control: 1,
17-
meta: 2,
18-
alt: 3,
19-
option: 4,
20-
shift: 5,
21-
function: 6,
22-
}
23-
24-
const keySortPriority = (priority: string) => keySortPriorities[priority] ?? Infinity
25-
26-
const compareLowercaseKeys = (a: string, b: string) => keySortPriority(a) - keySortPriority(b)
27-
28-
/** Split and sort the chord keys in standard order. */
29-
const splitChord = (chord: string) =>
30-
chord
31-
.split('+')
32-
.map(k => k.toLowerCase())
33-
.sort(compareLowercaseKeys)
7+
import {accessibleChordString, splitChord} from './utils'
348

359
export const Chord = ({keys, format = 'condensed', variant = 'normal', size = 'normal'}: KeybindingHintProps) => (
3610
<Text
@@ -56,8 +30,4 @@ export const Chord = ({keys, format = 'condensed', variant = 'normal', size = 'n
5630
</Text>
5731
)
5832

59-
/** Plain string version of `Chord` for use in `aria` string attributes. */
60-
export const accessibleChordString = (chord: string, platform: Platform) =>
61-
splitChord(chord)
62-
.map(key => accessibleKeyName(key, platform))
63-
.join(' ')
33+
export {accessibleChordString}

packages/react/src/KeybindingHint/components/Sequence.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import {Fragment} from 'react'
22
import type {KeybindingHintProps} from '../props'
33
import VisuallyHidden from '../../_VisuallyHidden'
4-
import {accessibleChordString, Chord} from './Chord'
5-
import type {Platform} from '../platform'
4+
import {Chord} from './Chord'
5+
import {accessibleSequenceString} from './utils'
66

77
const splitSequence = (sequence: string) => sequence.split(' ')
88

@@ -21,8 +21,4 @@ export const Sequence = ({keys, ...chordProps}: KeybindingHintProps) =>
2121
</Fragment>
2222
))
2323

24-
/** Plain string version of `Sequence` for use in `aria` string attributes. */
25-
export const accessibleSequenceString = (sequence: string, platform: Platform) =>
26-
splitSequence(sequence)
27-
.map(chord => accessibleChordString(chord, platform))
28-
.join(' then ')
24+
export {accessibleSequenceString}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import {accessibleKeyName} from '../key-names'
2+
import type {Platform} from '../platform'
3+
4+
/**
5+
* Consistent sort order for modifier keys. There should never be more than one non-modifier
6+
* key in a chord, so we don't need to worry about sorting those - we just put them at
7+
* the end.
8+
*/
9+
const keySortPriorities: Partial<Record<string, number>> = {
10+
control: 1,
11+
meta: 2,
12+
alt: 3,
13+
option: 4,
14+
shift: 5,
15+
function: 6,
16+
}
17+
18+
const keySortPriority = (priority: string) => keySortPriorities[priority] ?? Infinity
19+
20+
const compareLowercaseKeys = (a: string, b: string) => keySortPriority(a) - keySortPriority(b)
21+
22+
/** Split and sort the chord keys in standard order. */
23+
export const splitChord = (chord: string) =>
24+
chord
25+
.split('+')
26+
.map(k => k.toLowerCase())
27+
.sort(compareLowercaseKeys)
28+
29+
const splitSequence = (sequence: string) => sequence.split(' ')
30+
31+
/** Plain string version of `Chord` for use in `aria` string attributes. */
32+
export const accessibleChordString = (chord: string, platform: Platform) =>
33+
splitChord(chord)
34+
.map(key => accessibleKeyName(key, platform))
35+
.join(' ')
36+
37+
/** Plain string version of `Sequence` for use in `aria` string attributes. */
38+
export const accessibleSequenceString = (sequence: string, platform: Platform) =>
39+
splitSequence(sequence)
40+
.map(chord => accessibleChordString(chord, platform))
41+
.join(' then ')

packages/react/src/Overlay/Overlay.tsx

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../uti
1010
import classes from './Overlay.module.css'
1111
import {clsx} from 'clsx'
1212
import {useFeatureFlag} from '../FeatureFlags'
13+
import {heightMap, widthMap} from './constants'
1314

1415
type StyledOverlayProps = {
1516
width?: keyof typeof widthMap
@@ -21,25 +22,7 @@ type StyledOverlayProps = {
2122
style?: React.CSSProperties
2223
}
2324

24-
export const heightMap = {
25-
xsmall: '192px',
26-
small: '256px',
27-
medium: '320px',
28-
large: '432px',
29-
xlarge: '600px',
30-
auto: 'auto',
31-
initial: 'auto', // Passing 'initial' initially applies 'auto'
32-
'fit-content': 'fit-content',
33-
}
34-
35-
export const widthMap = {
36-
small: '256px',
37-
medium: '320px',
38-
large: '480px',
39-
xlarge: '640px',
40-
xxlarge: '960px',
41-
auto: 'auto',
42-
}
25+
export {heightMap, widthMap}
4326
const animationDuration = 200
4427

4528
function getSlideAnimationStartingVector(anchorSide?: AnchorSide): {x: number; y: number} {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export const heightMap = {
2+
xsmall: '192px',
3+
small: '256px',
4+
medium: '320px',
5+
large: '432px',
6+
xlarge: '600px',
7+
auto: 'auto',
8+
initial: 'auto',
9+
'fit-content': 'fit-content',
10+
}
11+
12+
export const widthMap = {
13+
small: '256px',
14+
medium: '320px',
15+
large: '480px',
16+
xlarge: '640px',
17+
xxlarge: '960px',
18+
auto: 'auto',
19+
}

packages/react/src/Timeline/Timeline.tsx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {clsx} from 'clsx'
22
import React from 'react'
33
import {useFeatureFlag} from '../FeatureFlags'
44
import classes from './Timeline.module.css'
5+
import {TimelineBadgeVariants} from './constants'
56

67
type StyledTimelineProps = {clipSidebar?: boolean | 'start' | 'end' | 'both'; className?: string}
78

@@ -83,17 +84,7 @@ const TimelineItem = React.forwardRef<HTMLDivElement | HTMLLIElement, TimelineIt
8384

8485
TimelineItem.displayName = 'TimelineItem'
8586

86-
export const TimelineBadgeVariants = [
87-
'accent',
88-
'success',
89-
'attention',
90-
'severe',
91-
'danger',
92-
'done',
93-
'open',
94-
'closed',
95-
'sponsors',
96-
] as const
87+
export {TimelineBadgeVariants}
9788

9889
export type TimelineBadgeVariant = (typeof TimelineBadgeVariants)[number]
9990

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export const TimelineBadgeVariants = [
2+
'accent',
3+
'success',
4+
'attention',
5+
'severe',
6+
'danger',
7+
'done',
8+
'open',
9+
'closed',
10+
'sponsors',
11+
] as const

packages/react/src/Token/TokenBase.tsx

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
1-
import type {ComponentProps, KeyboardEvent} from 'react'
1+
import type {KeyboardEvent} from 'react'
22
import React from 'react'
33
import {clsx} from 'clsx'
44
import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic'
55
import classes from './TokenBase.module.css'
6+
import {defaultTokenSize, type TokenSizeKeys, tokenSizes} from './constants'
7+
import {isTokenInteractive} from './utils'
68

7-
export type TokenSizeKeys = 'small' | 'medium' | 'large' | 'xlarge'
8-
9-
export const tokenSizes: Record<TokenSizeKeys, string> = {
10-
small: '16px',
11-
medium: '20px',
12-
large: '24px',
13-
xlarge: '32px',
14-
}
15-
16-
export const defaultTokenSize: TokenSizeKeys = 'medium'
9+
export {defaultTokenSize, isTokenInteractive, tokenSizes}
10+
export type {TokenSizeKeys}
1711

1812
export interface TokenBaseProps
1913
extends Omit<React.HTMLProps<HTMLSpanElement | HTMLButtonElement | HTMLAnchorElement>, 'size' | 'id'> {
@@ -48,19 +42,6 @@ export interface TokenBaseProps
4842
disabled?: boolean
4943
}
5044

51-
export const isTokenInteractive = ({
52-
as = 'span',
53-
onClick,
54-
onFocus,
55-
tabIndex = -1,
56-
disabled,
57-
}: Pick<ComponentProps<typeof TokenBase>, 'disabled' | 'as' | 'onClick' | 'onFocus' | 'tabIndex'>) => {
58-
if (disabled) {
59-
return false
60-
}
61-
return Boolean(onFocus || onClick || tabIndex > -1 || ['a', 'button'].includes(as))
62-
}
63-
6445
const TokenBase = React.forwardRef<HTMLButtonElement | HTMLAnchorElement | HTMLSpanElement | undefined, TokenBaseProps>(
6546
(
6647
{

0 commit comments

Comments
 (0)