Skip to content

Commit b89bfc9

Browse files
authored
fix: window is undefined error in next.js projects
the issue is solved by updating `react-window-select` library to v4 The update brought some follow-up changes described in the pull request #222
1 parent e012ba5 commit b89bfc9

File tree

10 files changed

+616
-457
lines changed

10 files changed

+616
-457
lines changed

package-lock.json

+564-422
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,14 @@
116116
"@popperjs/core": "^2.11.5",
117117
"@styled-system/theme-get": "^5.1.2",
118118
"@testing-library/react-hooks": "^8.0.0",
119-
"@types/react-select": "^3.0.13",
119+
"@types/react-select": "^4.0.18",
120120
"@types/styled-system": "^5.1.9",
121121
"date-fns": "^2.11.1",
122122
"nanoid": "^3.1.23",
123123
"react-popper": "^2.3.0",
124124
"react-tether": "^2.0.7",
125125
"react-transition-group": "^4.3.0",
126-
"react-windowed-select": "^2.0.2",
126+
"react-windowed-select": "^4.0.0",
127127
"styled-system": "^5.1.5",
128128
"warning": "^4.0.3"
129129
}

src/components/Pagination/Pagination.spec.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ describe('Pagination', () => {
8181

8282
const container = queryByLabelText('Select page size container');
8383

84-
const pageSizeSelectList = within(container).queryByRole('textbox');
84+
const pageSizeSelectList = within(container).queryByRole('combobox');
8585

8686
userEvent.type(pageSizeSelectList, '1');
8787

src/components/PhoneInput/PhoneInput.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ const PhoneInput: React.FC<PhoneInputProps> = ({ width, variant = 'boxed', ...pr
6666
// eslint-disable-next-line unicorn/no-null
6767
IndicatorSeparator: () => null,
6868
Option,
69+
// DynamicWidthMenu is a styled-component with its own `theme` prop since menuProps has `theme` prop
70+
// from emotion and conflicts in TS
71+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
72+
// @ts-ignore
6973
Menu: menuProps => <DynamicWidthMenu {...menuProps} width={containerRef.current?.offsetWidth} />
7074
}}
7175
variant={variant}

src/components/PhoneInput/components/Option.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ const OptionWithFlag = styled(components.Option).attrs({ role: 'option' })`
1616

1717
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1818
const Option: FC<OptionProps<any>> = (props: OptionProps<PhoneAreaCodeCountry>) => {
19-
const data = props.data as PhoneAreaCodeCountry;
19+
const { data } = props;
2020

2121
return (
22+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
23+
// @ts-ignore
2224
<OptionWithFlag {...props}>
2325
<Flag code={isFlagAvailable(data.value) ? data.value : 'WW'} />
2426
{data.label}

src/components/PhoneInput/components/SingleValue.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ const SingleValue: FC<SingleValueProps<any>> = (props: SingleValueProps<PhoneAre
2222
return props.children as ReactElement;
2323
}
2424

25-
const selectedOption = props.getValue()[0] as PhoneAreaCodeCountry;
25+
const selectedOption: PhoneAreaCodeCountry = props.getValue()[0];
2626

2727
return (
28+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
29+
// @ts-ignore
2830
<StyledSingleValue {...props}>
2931
<Flag code={isFlagAvailable(selectedOption.value) ? selectedOption.value : 'WW'} />
3032
<Text>{selectedOption.dialCode}</Text>

src/components/SelectList/SelectList.tsx

+24-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1-
import React, { CSSProperties, FC } from 'react';
2-
import { components as ReactSelectComponents, IndicatorProps, Props, StylesConfig } from 'react-select';
1+
import React, { FC } from 'react';
2+
import {
3+
components as ReactSelectComponents,
4+
DropdownIndicatorProps,
5+
ClearIndicatorProps,
6+
ControlProps,
7+
Props,
8+
StylesConfig
9+
} from 'react-select';
310
import WindowedSelect from 'react-windowed-select';
411

512
import { Colors, Elevation } from '../../essentials';
@@ -12,8 +19,10 @@ import { Wrapper } from './components/Wrapper';
1219
import { disabledStyles, errorStyles, variantStyles } from './styles';
1320
import { SelectListProps } from './types';
1421

22+
type WithSelectProps<T> = T & { selectProps: SelectListProps };
23+
1524
const customStyles: StylesConfig = {
16-
container: (provided, { selectProps }: Props & { selectProps: SelectListProps }) => {
25+
container: (provided, { selectProps }: WithSelectProps<Props>) => {
1726
const bSize = {
1827
small: {
1928
fontSize: get('fontSizes.1')(selectProps)
@@ -28,11 +37,9 @@ const customStyles: StylesConfig = {
2837
...bSize[selectProps.size]
2938
};
3039
},
31-
control: (_, state: Props & { selectProps: SelectListProps }) => {
32-
const disabled =
33-
state.isDisabled && disabledStyles.control({ isFocused: state.isFocused, ...state.selectProps });
34-
const error =
35-
state.selectProps.error && errorStyles.control({ isFocused: state.isFocused, ...state.selectProps });
40+
control: (_, state: WithSelectProps<ControlProps>) => {
41+
const disabled = state.isDisabled && disabledStyles.control(state.selectProps);
42+
const error = state.selectProps.error && errorStyles.control(state.selectProps);
3643
const variant = variantStyles.control({ isFocused: state.isFocused, ...state.selectProps });
3744

3845
return {
@@ -55,7 +62,7 @@ const customStyles: StylesConfig = {
5562
...provided,
5663
boxShadow: `0 0.125rem 0.5rem 0.0625rem ${Colors.AUTHENTIC_BLUE_200}`
5764
}),
58-
valueContainer: (provided, { selectProps: { size, variant } }: Props & { selectProps: SelectListProps }) => {
65+
valueContainer: (provided, { selectProps: { size, variant } }: WithSelectProps<Props>) => {
5966
let margin;
6067

6168
if (variant === 'boxed') {
@@ -94,7 +101,7 @@ const customStyles: StylesConfig = {
94101
...provided,
95102
color: 'inherit'
96103
}),
97-
dropdownIndicator: (provided, state: Props & { selectProps: SelectListProps }) => {
104+
dropdownIndicator: (provided, state: WithSelectProps<Props>) => {
98105
const disabled = state.isDisabled && disabledStyles.icons(state.selectProps);
99106

100107
return {
@@ -106,7 +113,7 @@ const customStyles: StylesConfig = {
106113
...disabled
107114
};
108115
},
109-
clearIndicator: (provided, state: Props & { selectProps: SelectListProps }) => {
116+
clearIndicator: (provided, state: WithSelectProps<Props>) => {
110117
const disabled = state.isDisabled && disabledStyles.icons(state.selectProps);
111118

112119
return {
@@ -117,7 +124,7 @@ const customStyles: StylesConfig = {
117124
...disabled
118125
};
119126
},
120-
placeholder: (provided: CSSProperties, state: Props & { selectProps: SelectListProps }) => {
127+
placeholder: (provided, state: WithSelectProps<Props>) => {
121128
const disabled = state.isDisabled && disabledStyles.placeholder(state.selectProps);
122129

123130
return {
@@ -126,7 +133,7 @@ const customStyles: StylesConfig = {
126133
...disabled
127134
};
128135
},
129-
option: (provided, state: Props & { selectProps: SelectListProps }) => {
136+
option: (provided, state: WithSelectProps<Props>) => {
130137
const colorsByState = {
131138
isDisabled: {
132139
color: Colors.AUTHENTIC_BLUE_350
@@ -162,7 +169,7 @@ const customStyles: StylesConfig = {
162169
cursor: state.isDisabled ? 'not-allowed' : 'default'
163170
};
164171
},
165-
multiValue: (provided: CSSProperties, { selectProps }: { selectProps: Props }) => {
172+
multiValue: (provided, { selectProps }: { selectProps: Props }) => {
166173
const styles = {
167174
...provided,
168175
color: Colors.ACTION_BLUE_900,
@@ -216,7 +223,7 @@ const customStyles: StylesConfig = {
216223

217224
const getIconSize = sizeAsString => (sizeAsString === 'medium' ? 24 : 18);
218225

219-
const DropdownIndicator = (props: IndicatorProps<unknown> & { selectProps: Props }) => (
226+
const DropdownIndicator = (props: WithSelectProps<DropdownIndicatorProps>) => (
220227
<ReactSelectComponents.DropdownIndicator {...props}>
221228
{props.selectProps.menuIsOpen ? (
222229
<ChevronUpIcon data-testid="close-icon" color="inherit" size={getIconSize(props.selectProps.size)} />
@@ -226,7 +233,7 @@ const DropdownIndicator = (props: IndicatorProps<unknown> & { selectProps: Props
226233
</ReactSelectComponents.DropdownIndicator>
227234
);
228235

229-
const ClearIndicator = (props: IndicatorProps<unknown>) => (
236+
const ClearIndicator = (props: WithSelectProps<ClearIndicatorProps>) => (
230237
<ReactSelectComponents.ClearIndicator {...props}>
231238
<CloseIcon color="inherit" size={getIconSize(props.selectProps.size)} />
232239
</ReactSelectComponents.ClearIndicator>
@@ -255,6 +262,7 @@ const SelectList: FC<SelectListProps> = (props: SelectListProps) => {
255262
<WindowedSelect
256263
inputId={id}
257264
styles={customStyles}
265+
windowThreshold={100}
258266
components={{
259267
DropdownIndicator,
260268
IndicatorSeparator,

src/components/SelectList/__tests__/SelectList.spec.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe('SelectList', () => {
3535
/>
3636
);
3737

38-
const selectInput = screen.getByRole('textbox');
38+
const selectInput = screen.getByRole('combobox');
3939

4040
expect(screen.getByTestId('open-icon')).toBeInTheDocument();
4141

src/components/SelectList/components/Label.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ export const Label = styled.label<LabelProps>`
2525
transition: color 125ms ease;
2626
2727
${p => p.error && errorStyles.label()}
28-
${p => p.isDisabled && disabledStyles.label(p)}
29-
${p => variantStyles.label(p)}
28+
${({ isDisabled, inverted }) => isDisabled && disabledStyles.label({ inverted })}
29+
${({ variant, size }) => variantStyles.label({ variant, size })}
3030
`;

src/components/SelectList/styles.ts

+12-11
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
import { CSSObject } from 'styled-components';
2+
import { CSSObjectWithLabel } from 'react-select';
23
import { Colors } from '../../essentials';
34
import { get } from '../../utils/themeGet';
45
import { SelectListProps } from './types';
56

67
export const disabledStyles = {
7-
control: ({ inverted }: SelectListProps): CSSObject => ({
8+
control: ({ inverted }: SelectListProps): CSSObjectWithLabel => ({
89
color: inverted ? Colors.AUTHENTIC_BLUE_550 : Colors.AUTHENTIC_BLUE_200,
910
borderColor: inverted ? Colors.AUTHENTIC_BLUE_550 : Colors.AUTHENTIC_BLUE_200,
1011
boxShadow: 'none'
1112
}),
12-
placeholder: ({ inverted }: SelectListProps): CSSObject => ({
13+
placeholder: ({ inverted }: SelectListProps): CSSObjectWithLabel => ({
1314
color: inverted ? Colors.AUTHENTIC_BLUE_550 : Colors.AUTHENTIC_BLUE_200
1415
}),
15-
label: ({ inverted }: SelectListProps): CSSObject => ({
16+
label: ({ inverted }: Pick<SelectListProps, 'inverted'>): CSSObject => ({
1617
color: inverted ? Colors.AUTHENTIC_BLUE_550 : Colors.AUTHENTIC_BLUE_200
1718
}),
18-
icons: ({ inverted }: SelectListProps): CSSObject => ({
19+
icons: ({ inverted }: SelectListProps): CSSObjectWithLabel => ({
1920
color: inverted ? Colors.AUTHENTIC_BLUE_550 : Colors.AUTHENTIC_BLUE_200
2021
})
2122
};
2223

2324
export const errorStyles = {
24-
control: ({ variant }: SelectListProps): CSSObject => ({
25+
control: ({ variant }: SelectListProps): CSSObjectWithLabel => ({
2526
borderColor: Colors.NEGATIVE_ORANGE_900,
2627
boxShadow:
2728
variant === 'boxed'
@@ -34,7 +35,7 @@ export const errorStyles = {
3435
};
3536

3637
export const variantStyles = {
37-
control: (props: SelectListProps): CSSObject => {
38+
control: (props: { isFocused: boolean } & SelectListProps): CSSObjectWithLabel => {
3839
switch (props.variant) {
3940
case 'boxed': {
4041
const bSize = {
@@ -57,7 +58,7 @@ export const variantStyles = {
5758
borderRadius: get('radii.2')(props),
5859
border: `0.0625rem solid ${Colors.AUTHENTIC_BLUE_200}`,
5960
...isBFocused,
60-
...bSize[ props.size ]
61+
...bSize[props.size]
6162
};
6263
}
6364
case 'bottom-lined': {
@@ -82,14 +83,14 @@ export const variantStyles = {
8283
borderTopRightRadius: get('radii.1')(props),
8384
borderBottom: `0.0625rem solid ${Colors.AUTHENTIC_BLUE_200}`,
8485
...isBLFocused,
85-
...btSize[ props.size ]
86+
...btSize[props.size]
8687
};
8788
}
8889
default:
8990
return {};
9091
}
9192
},
92-
label: (props: SelectListProps): CSSObject => {
93+
label: (props: Pick<SelectListProps, 'variant' | 'size'>): CSSObject => {
9394
switch (props.variant) {
9495
case 'boxed': {
9596
const bSize = {
@@ -107,7 +108,7 @@ export const variantStyles = {
107108
}
108109
};
109110

110-
return bSize[ props.size ];
111+
return bSize[props.size];
111112
}
112113
case 'bottom-lined': {
113114
const btSize = {
@@ -125,7 +126,7 @@ export const variantStyles = {
125126
}
126127
};
127128

128-
return btSize[ props.size ];
129+
return btSize[props.size];
129130
}
130131
default:
131132
return {};

0 commit comments

Comments
 (0)