Skip to content

Commit 865de77

Browse files
authored
fix(theme): adjust react-select theme access (#106127)
In the course of #106037, I hit a fun exception in the `TeamSelector`. Previously, the style functions accessed `state.theme` from the `react-select` callback, casting it as Sentry's global theme because it also uses Emotion. In the test environment, `react-select` provided a theme object that didn't have Sentry's `tokens` property, causing `theme.tokens.background` to fail. In this PR, we've refactored the `TeamSelector` to have receive the theme from `useTheme()` hook instead of expecting Emotion to automatically merge `react-select`'s theme with ours.
1 parent e750cbe commit 865de77

File tree

1 file changed

+28
-35
lines changed

1 file changed

+28
-35
lines changed

static/app/components/teamSelector.tsx

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {useCallback, useEffect, useMemo, useRef} from 'react';
22
import type {Theme} from '@emotion/react';
3+
import {useTheme} from '@emotion/react';
34
import styled from '@emotion/styled';
45
import debounce from 'lodash/debounce';
56

@@ -60,43 +61,34 @@ const filterOption = (canditate: any, input: any) =>
6061
const getOptionValue = (option: TeamOption) => option.value;
6162

6263
// Ensures that the svg icon is white when selected
63-
const unassignedSelectStyles: StylesConfig = {
64-
option: (provided, state) => {
65-
// XXX: The `state.theme` is an emotion theme object, but it is not typed
66-
// as the emotion theme object in react-select
67-
const theme = state.theme as unknown as Theme;
68-
69-
return {...provided, svg: {color: state.isSelected ? theme.white : undefined}};
70-
},
71-
};
64+
const getUnassignedSelectStyles = (theme: Theme): StylesConfig => ({
65+
option: (provided, state) => ({
66+
...provided,
67+
svg: {color: state.isSelected ? theme.white : undefined},
68+
}),
69+
});
7270

73-
const placeholderSelectStyles: StylesConfig = {
74-
input: (provided, state) => {
75-
// XXX: The `state.theme` is an emotion theme object, but it is not typed
76-
// as the emotion theme object in react-select
77-
const theme = state.theme as unknown as Theme;
78-
79-
return {
80-
...provided,
81-
display: 'grid',
82-
gridTemplateColumns: 'max-content 1fr',
83-
alignItems: 'center',
84-
gridGap: space(1),
85-
':before': {
86-
backgroundColor: theme.backgroundSecondary,
87-
height: 24,
88-
width: 24,
89-
borderRadius: 3,
90-
content: '""',
91-
display: 'block',
92-
},
93-
};
94-
},
71+
const getPlaceholderSelectStyles = (theme: Theme): StylesConfig => ({
72+
input: provided => ({
73+
...provided,
74+
display: 'grid',
75+
gridTemplateColumns: 'max-content 1fr',
76+
alignItems: 'center',
77+
gridGap: space(1),
78+
':before': {
79+
backgroundColor: theme.tokens.background.secondary,
80+
height: 24,
81+
width: 24,
82+
borderRadius: 3,
83+
content: '""',
84+
display: 'block',
85+
},
86+
}),
9587
placeholder: provided => ({
9688
...provided,
9789
paddingLeft: 32,
9890
}),
99-
};
91+
});
10092

10193
interface Props extends ControlProps {
10294
onChange: (value: any) => any;
@@ -139,6 +131,7 @@ export interface TeamOption extends GeneralSelectValue {
139131
}
140132

141133
export function TeamSelector(props: Props) {
134+
const theme = useTheme();
142135
const organization = useOrganization();
143136
const {
144137
allowCreate,
@@ -361,11 +354,11 @@ export function TeamSelector(props: Props) {
361354

362355
const styles = useMemo(
363356
() => ({
364-
...(includeUnassigned ? unassignedSelectStyles : {}),
365-
...(multiple ? {} : placeholderSelectStyles),
357+
...(includeUnassigned ? getUnassignedSelectStyles(theme) : {}),
358+
...(multiple ? {} : getPlaceholderSelectStyles(theme)),
366359
...stylesProp,
367360
}),
368-
[includeUnassigned, multiple, stylesProp]
361+
[includeUnassigned, multiple, stylesProp, theme]
369362
);
370363

371364
useEffect(() => {

0 commit comments

Comments
 (0)