Skip to content

Commit a514b25

Browse files
committed
refactor(select): ♻️ add optional chain & memoize
1 parent a4bcb6f commit a514b25

File tree

3 files changed

+61
-45
lines changed

3 files changed

+61
-45
lines changed

src/select/SelectBase.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,15 @@ import {
66
} from "ariakit-utils/system";
77
import { As, Props } from "ariakit-utils/types";
88

9-
import { BoxOptions, useBox } from "../box";
109
import { useTheme } from "../theme";
11-
import { cx } from "../utils";
10+
import { cx, tcm } from "../utils";
1211

1312
import { SelectUIProps } from "./SelectProps";
1413

1514
export const useSelectBase = createHook<SelectBaseOptions>(
1615
({ prefix, suffix, size, variant, invalid, loading, spinner, ...props }) => {
1716
const theme = useTheme("select");
18-
const className = cx(
17+
const className = tcm(
1918
theme.base,
2019
size ? theme.size[size]?.base?.default : "",
2120
size && (!prefix || !suffix) ? theme.size[size]?.base?.withoutAddon : "",
@@ -35,7 +34,6 @@ export const useSelectBase = createHook<SelectBaseOptions>(
3534
);
3635

3736
props = { "aria-invalid": invalid, ...props, className };
38-
props = useBox(props);
3937
props = useFocusable(props);
4038

4139
return props;
@@ -48,8 +46,7 @@ export const SelectBase = createComponent<SelectBaseOptions>(props => {
4846
return createElement("select", htmlProps);
4947
});
5048

51-
export type SelectBaseOptions<T extends As = "select"> = BoxOptions<T> &
52-
FocusableOptions<T> &
49+
export type SelectBaseOptions<T extends As = "select"> = FocusableOptions<T> &
5350
Partial<SelectUIProps> & {};
5451

5552
export type SelectBaseProps<T extends As = "select"> = Props<

src/select/SelectPrefix.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,19 @@ export const useSelectPrefix = createHook<SelectPrefixOptions>(
2727
const theme = useTheme("select");
2828
const className = cx(
2929
theme.prefix,
30-
size ? theme.size[size].prefix : "",
30+
size ? theme.size[size]?.prefix : "",
3131
disabled
3232
? ""
3333
: variant
3434
? cx(
35-
theme.variant[variant].default.prefix,
36-
theme.variant[variant].hover.prefix,
37-
theme.variant[variant].active.prefix,
38-
theme.variant[variant].focus.prefix,
39-
invalid ? theme.variant[variant].invalid.prefix : "",
35+
theme.variant[variant]?.default?.prefix,
36+
theme.variant[variant]?.hover?.prefix,
37+
theme.variant[variant]?.active?.prefix,
38+
theme.variant[variant]?.focus?.prefix,
39+
invalid ? theme.variant[variant]?.invalid?.prefix : "",
4040
)
4141
: "",
42-
variant && disabled ? theme.variant[variant].disabled.prefix : "",
42+
variant && disabled ? theme.variant[variant]?.disabled?.prefix : "",
4343
props.className,
4444
);
4545

src/select/SelectProps.tsx

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from "react";
2-
import { useSafeLayoutEffect } from "ariakit-utils";
2+
import { useForkRef, useSafeLayoutEffect } from "ariakit-utils";
33

44
import { getComponentProps, RenderProp, runIfFn, withIconA11y } from "../utils";
55

@@ -67,8 +67,16 @@ export const useSelectProps = ({
6767
uiProps = { ...uiProps, prefix: _prefix, suffix: _suffix };
6868

6969
const selectInlineStyles = React.useRef<Record<string, any>>({});
70-
const prefixRef = React.useRef<HTMLElement>(null);
71-
const suffixRef = React.useRef<HTMLElement>(null);
70+
let prefixRef = React.useRef<HTMLElement>(null);
71+
let suffixRef = React.useRef<HTMLElement>(null);
72+
prefixRef = useForkRef(
73+
prefixRef,
74+
componentProps?.prefixProps?.ref,
75+
) as unknown as React.RefObject<HTMLElement>;
76+
suffixRef = useForkRef(
77+
suffixRef,
78+
componentProps?.suffixProps?.ref,
79+
) as unknown as React.RefObject<HTMLElement>;
7280

7381
useSafeLayoutEffect(() => {
7482
let key = "";
@@ -94,38 +102,49 @@ export const useSelectProps = ({
94102
setHasPaddingCalculated(true);
95103
}, [uiProps.prefix, uiProps.suffix]);
96104

97-
const wrapperProps: SelectWrapperProps = {
98-
...uiProps,
99-
className,
100-
style,
101-
...componentProps.wrapperProps,
102-
};
103-
104-
const baseProps: SelectBaseProps = {
105-
...uiProps,
106-
disabled,
107-
...restProps,
108-
style: { ...selectInlineStyles.current },
109-
children: finalChildren,
110-
...componentProps.baseProps,
111-
};
105+
const wrapperProps: SelectWrapperProps = React.useMemo(
106+
() => ({
107+
...uiProps,
108+
className,
109+
style,
110+
...componentProps.wrapperProps,
111+
}),
112+
[className, componentProps.wrapperProps, style, uiProps],
113+
);
112114

113-
const prefixProps: SelectPrefixProps = {
114-
...uiProps,
115-
disabled,
116-
...componentProps.prefixProps,
117-
ref: prefixRef,
118-
children: withIconA11y(runIfFn(uiProps.prefix, uiProps)),
119-
};
115+
const baseProps: SelectBaseProps = React.useMemo(
116+
() => ({
117+
...uiProps,
118+
disabled,
119+
...restProps,
120+
style: { ...selectInlineStyles.current },
121+
...componentProps.baseProps,
122+
children: finalChildren,
123+
}),
124+
[componentProps.baseProps, disabled, finalChildren, restProps, uiProps],
125+
);
120126

121-
const suffixProps: SelectSuffixProps = {
122-
...uiProps,
123-
disabled,
124-
...componentProps.suffixProps,
125-
ref: suffixRef,
126-
children: uiProps.suffix,
127-
};
127+
const prefixProps: SelectPrefixProps = React.useMemo(
128+
() => ({
129+
...uiProps,
130+
disabled,
131+
...componentProps.prefixProps,
132+
ref: prefixRef,
133+
children: withIconA11y(runIfFn(uiProps.prefix, uiProps)),
134+
}),
135+
[componentProps.prefixProps, disabled, uiProps],
136+
);
128137

138+
const suffixProps: SelectSuffixProps = React.useMemo(
139+
() => ({
140+
...uiProps,
141+
disabled,
142+
...componentProps.suffixProps,
143+
ref: suffixRef,
144+
children: uiProps.suffix,
145+
}),
146+
[componentProps.suffixProps, disabled, uiProps],
147+
);
129148
return {
130149
uiProps,
131150
wrapperProps,

0 commit comments

Comments
 (0)