Skip to content

Commit e3a95c4

Browse files
committed
Replace deprecated StylesProvider and useStyles with createStylesContext
- Consolidate files in order to make this change - Remove `isFocused`/`data-focused` from `ClearIndicator` - Remove all `ReactElement` return typings - Unify the way the icons are defined
1 parent 7ea2612 commit e3a95c4

File tree

11 files changed

+525
-543
lines changed

11 files changed

+525
-543
lines changed

src/chakra-components/containers.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React from "react";
2-
import type { ReactElement } from "react";
32
import { Box } from "@chakra-ui/layout";
43
import type { SystemStyleObject } from "@chakra-ui/system";
54
import type {
@@ -16,7 +15,7 @@ export const SelectContainer = <
1615
Group extends GroupBase<Option>
1716
>(
1817
props: ContainerProps<Option, IsMulti, Group>
19-
): ReactElement => {
18+
) => {
2019
const {
2120
children,
2221
className,
@@ -65,7 +64,7 @@ export const ValueContainer = <
6564
Group extends GroupBase<Option>
6665
>(
6766
props: ValueContainerProps<Option, IsMulti, Group>
68-
): ReactElement => {
67+
) => {
6968
const {
7069
children,
7170
className,
@@ -119,7 +118,7 @@ export const IndicatorsContainer = <
119118
Group extends GroupBase<Option>
120119
>(
121120
props: IndicatorsContainerProps<Option, IsMulti, Group>
122-
): ReactElement => {
121+
) => {
123122
const {
124123
children,
125124
className,

src/chakra-components/control.tsx

Lines changed: 265 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,33 @@
11
import React from "react";
2-
import type { ReactElement } from "react";
3-
import { Box } from "@chakra-ui/layout";
2+
import type { IconProps } from "@chakra-ui/icon";
3+
import { Icon } from "@chakra-ui/icon";
4+
import { Box, Divider } from "@chakra-ui/layout";
5+
import { Spinner } from "@chakra-ui/spinner";
46
import type { SystemStyleObject } from "@chakra-ui/system";
5-
import { StylesProvider, useMultiStyleConfig } from "@chakra-ui/system";
6-
import type { ControlProps, GroupBase } from "react-select";
7+
import {
8+
createStylesContext,
9+
useMultiStyleConfig,
10+
useStyleConfig,
11+
} from "@chakra-ui/system";
12+
import type {
13+
ClearIndicatorProps,
14+
ControlProps,
15+
DropdownIndicatorProps,
16+
GroupBase,
17+
IndicatorSeparatorProps,
18+
LoadingIndicatorProps,
19+
} from "react-select";
720
import type { SizeProps } from "../types";
821

22+
const [InputStylesProvider, useInputStyles] = createStylesContext("Input");
23+
924
const Control = <
1025
Option,
1126
IsMulti extends boolean,
1227
Group extends GroupBase<Option>
1328
>(
1429
props: ControlProps<Option, IsMulti, Group>
15-
): ReactElement => {
30+
) => {
1631
const {
1732
className,
1833
cx,
@@ -57,7 +72,7 @@ const Control = <
5772
: initialStyles;
5873

5974
return (
60-
<StylesProvider value={inputStyles}>
75+
<InputStylesProvider value={inputStyles}>
6176
<Box
6277
ref={innerRef}
6378
className={cx(
@@ -78,7 +93,250 @@ const Control = <
7893
>
7994
{children}
8095
</Box>
81-
</StylesProvider>
96+
</InputStylesProvider>
97+
);
98+
};
99+
100+
export const IndicatorSeparator = <
101+
Option,
102+
IsMulti extends boolean,
103+
Group extends GroupBase<Option>
104+
>(
105+
props: IndicatorSeparatorProps<Option, IsMulti, Group>
106+
) => {
107+
const {
108+
className,
109+
cx,
110+
selectProps: { chakraStyles, useBasicStyles },
111+
} = props;
112+
113+
const initialStyles: SystemStyleObject = {
114+
opacity: 1,
115+
...(useBasicStyles && { display: "none" }),
116+
};
117+
118+
const sx: SystemStyleObject = chakraStyles?.indicatorSeparator
119+
? chakraStyles.indicatorSeparator(initialStyles, props)
120+
: initialStyles;
121+
122+
return (
123+
<Divider
124+
className={cx({ "indicator-separator": true }, className)}
125+
sx={sx}
126+
orientation="vertical"
127+
/>
128+
);
129+
};
130+
131+
/**
132+
* Borrowed from the `@chakra-ui/icons` package to prevent needing it as a dependency
133+
*
134+
* @see {@link https://github.com/chakra-ui/chakra-ui/blob/main/packages/icons/src/ChevronDown.tsx}
135+
*/
136+
export const DownChevron = (props: IconProps) => (
137+
<Icon {...props}>
138+
<path
139+
fill="currentColor"
140+
d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"
141+
/>
142+
</Icon>
143+
);
144+
145+
export const DropdownIndicator = <
146+
Option,
147+
IsMulti extends boolean,
148+
Group extends GroupBase<Option>
149+
>(
150+
props: DropdownIndicatorProps<Option, IsMulti, Group>
151+
) => {
152+
const {
153+
children,
154+
className,
155+
cx,
156+
innerProps,
157+
selectProps: { size, chakraStyles, useBasicStyles },
158+
} = props;
159+
160+
const { addon } = useInputStyles();
161+
162+
const iconSizes: SizeProps = {
163+
sm: "16px",
164+
md: "20px",
165+
lg: "24px",
166+
};
167+
const iconSize = iconSizes[size || "md"];
168+
169+
const initialStyles: SystemStyleObject = {
170+
...addon,
171+
display: "flex",
172+
alignItems: "center",
173+
justifyContent: "center",
174+
height: "100%",
175+
borderRadius: 0,
176+
borderWidth: 0,
177+
cursor: "pointer",
178+
fontSize: iconSize,
179+
...(useBasicStyles && {
180+
background: "transparent",
181+
padding: 0,
182+
width: 6,
183+
marginRight: 2,
184+
marginLeft: 1,
185+
cursor: "inherit",
186+
}),
187+
};
188+
const sx: SystemStyleObject = chakraStyles?.dropdownIndicator
189+
? chakraStyles.dropdownIndicator(initialStyles, props)
190+
: initialStyles;
191+
192+
const initialIconStyles = {
193+
height: "1em",
194+
width: "1em",
195+
};
196+
const iconSx: SystemStyleObject = chakraStyles?.downChevron
197+
? chakraStyles.downChevron(initialIconStyles, props)
198+
: initialIconStyles;
199+
200+
return (
201+
<Box
202+
{...innerProps}
203+
className={cx(
204+
{
205+
indicator: true,
206+
"dropdown-indicator": true,
207+
},
208+
className
209+
)}
210+
sx={sx}
211+
>
212+
{children || <DownChevron sx={iconSx} />}
213+
</Box>
214+
);
215+
};
216+
217+
/**
218+
* Borrowed from Chakra UI source
219+
*
220+
* @see {@link https://github.com/chakra-ui/chakra-ui/blob/13c6d2e08b61e179773be4722bb81173dd599306/packages/close-button/src/close-button.tsx#L14}
221+
*/
222+
export const CrossIcon = (props: IconProps) => (
223+
<Icon focusable="false" aria-hidden {...props}>
224+
<path
225+
fill="currentColor"
226+
d="M.439,21.44a1.5,1.5,0,0,0,2.122,2.121L11.823,14.3a.25.25,0,0,1,.354,0l9.262,9.263a1.5,1.5,0,1,0,2.122-2.121L14.3,12.177a.25.25,0,0,1,0-.354l9.263-9.262A1.5,1.5,0,0,0,21.439.44L12.177,9.7a.25.25,0,0,1-.354,0L2.561.44A1.5,1.5,0,0,0,.439,2.561L9.7,11.823a.25.25,0,0,1,0,.354Z"
227+
/>
228+
</Icon>
229+
);
230+
231+
export const ClearIndicator = <
232+
Option,
233+
IsMulti extends boolean,
234+
Group extends GroupBase<Option>
235+
>(
236+
props: ClearIndicatorProps<Option, IsMulti, Group>
237+
) => {
238+
const {
239+
children,
240+
className,
241+
cx,
242+
innerProps,
243+
selectProps: { size, chakraStyles },
244+
} = props;
245+
246+
const closeButtonStyles = useStyleConfig("CloseButton", {
247+
size,
248+
});
249+
250+
const initialStyles: SystemStyleObject = {
251+
...closeButtonStyles,
252+
marginX: 1,
253+
display: "flex",
254+
alignItems: "center",
255+
justifyContent: "center",
256+
flexShrink: 0,
257+
cursor: "pointer",
258+
};
259+
const sx: SystemStyleObject = chakraStyles?.clearIndicator
260+
? chakraStyles.clearIndicator(initialStyles, props)
261+
: initialStyles;
262+
263+
const initialIconStyles: SystemStyleObject = {
264+
width: "1em",
265+
height: "1em",
266+
};
267+
const iconSx: SystemStyleObject = chakraStyles?.crossIcon
268+
? chakraStyles.crossIcon(initialIconStyles, props)
269+
: initialIconStyles;
270+
271+
return (
272+
<Box
273+
role="button"
274+
className={cx(
275+
{
276+
indicator: true,
277+
"clear-indicator": true,
278+
},
279+
className
280+
)}
281+
sx={sx}
282+
aria-label="Clear selected options"
283+
{...innerProps}
284+
>
285+
{children || <CrossIcon sx={iconSx} />}
286+
</Box>
287+
);
288+
};
289+
290+
export const LoadingIndicator = <
291+
Option,
292+
IsMulti extends boolean,
293+
Group extends GroupBase<Option>
294+
>(
295+
props: LoadingIndicatorProps<Option, IsMulti, Group>
296+
) => {
297+
const {
298+
className,
299+
cx,
300+
innerProps,
301+
selectProps: { size, chakraStyles },
302+
color,
303+
emptyColor,
304+
speed,
305+
thickness,
306+
spinnerSize: propsSpinnerSize,
307+
} = props;
308+
309+
const spinnerSizes: SizeProps<string> = {
310+
sm: "xs",
311+
md: "sm",
312+
lg: "md",
313+
};
314+
315+
const spinnerSize = spinnerSizes[size || "md"];
316+
317+
const initialStyles: SystemStyleObject = { marginRight: 3 };
318+
319+
const sx: SystemStyleObject = chakraStyles?.loadingIndicator
320+
? chakraStyles.loadingIndicator(initialStyles, props)
321+
: initialStyles;
322+
323+
return (
324+
<Spinner
325+
className={cx(
326+
{
327+
indicator: true,
328+
"loading-indicator": true,
329+
},
330+
className
331+
)}
332+
sx={sx}
333+
{...innerProps}
334+
size={propsSpinnerSize || spinnerSize}
335+
color={color}
336+
emptyColor={emptyColor}
337+
speed={speed}
338+
thickness={thickness}
339+
/>
82340
);
83341
};
84342

0 commit comments

Comments
 (0)