Skip to content

Commit a8ca6ec

Browse files
committed
chore: support components
1 parent de3f3a6 commit a8ca6ec

File tree

4 files changed

+48
-28
lines changed

4 files changed

+48
-28
lines changed

src/BaseSelect/index.tsx

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { BaseSelectContext } from '../hooks/useBaseProps';
1010
import type { BaseSelectContextProps } from '../hooks/useBaseProps';
1111
import useLock from '../hooks/useLock';
1212
import useSelectTriggerControl from '../hooks/useSelectTriggerControl';
13-
import useComponents, { type ComponentsConfig } from '../hooks/useComponents';
1413
import type {
1514
DisplayInfoType,
1615
DisplayValueType,
@@ -28,6 +27,8 @@ import Polite from './Polite';
2827
import useOpen from '../hooks/useOpen';
2928
import { useEvent } from '@rc-component/util';
3029
import type { SelectInputRef } from '../SelectInput';
30+
import SelectInput from '../SelectInput';
31+
import type { ComponentsConfig } from '../hooks/useComponents';
3132
export type BaseSelectSemanticName = 'prefix' | 'suffix' | 'input' | 'clear';
3233

3334
/**
@@ -312,7 +313,7 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
312313
onMouseDown,
313314

314315
// Components
315-
components,
316+
components = {},
316317

317318
// Rest Props
318319
...restProps
@@ -904,11 +905,8 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
904905
// );
905906
// }
906907

907-
const mergedComponents = useComponents(components);
908-
const { root: RootComponent } = mergedComponents;
909-
910908
renderNode = (
911-
<RootComponent
909+
<SelectInput
912910
{...restProps}
913911
// Ref
914912
ref={containerRef}
@@ -943,7 +941,7 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
943941
// Open
944942
onMouseDown={onInternalMouseDown}
945943
// Components
946-
components={mergedComponents}
944+
components={components}
947945
/>
948946
);
949947

src/SelectInput/Input.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>((props, ref) => {
4242
onInputBlur,
4343
autoFocus,
4444
tokenWithEnter,
45-
components: { input: InputComponent },
45+
components: { input: InputComponent = 'input' },
4646
} = useSelectInputContext();
4747
const { id, classNames, styles, open, activeDescendantId, role, disabled } = useBaseProps() || {};
4848

src/SelectInput/index.tsx

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { omit, useEvent } from '@rc-component/util';
88
import KeyCode from '@rc-component/util/lib/KeyCode';
99
import { isValidateOpenKey } from '../utils/keyUtil';
1010
import clsx from 'clsx';
11-
import type { FilledComponentsConfig } from '../hooks/useComponents';
11+
import type { ComponentsConfig } from '../hooks/useComponents';
1212
import { getDOM } from '@rc-component/util/lib/Dom/findDOMNode';
1313

1414
export interface SelectInputRef {
@@ -43,7 +43,7 @@ export interface SelectInputProps extends Omit<React.HTMLAttributes<HTMLDivEleme
4343
className?: string;
4444
style?: React.CSSProperties;
4545
focused?: boolean;
46-
components: FilledComponentsConfig;
46+
components: ComponentsConfig;
4747
}
4848

4949
const DEFAULT_OMIT_PROPS = [
@@ -104,19 +104,14 @@ export default React.forwardRef<SelectInputRef, SelectInputProps>(function Selec
104104
// Token handling
105105
tokenWithEnter,
106106

107+
// Components
108+
components,
109+
107110
...restProps
108111
} = props;
109112

110-
const {
111-
triggerOpen,
112-
toggleOpen,
113-
showSearch,
114-
disabled,
115-
loading,
116-
classNames,
117-
styles,
118-
autoClearSearchValue,
119-
} = useBaseProps();
113+
const { triggerOpen, toggleOpen, showSearch, disabled, loading, classNames, styles } =
114+
useBaseProps();
120115

121116
const rootRef = React.useRef<HTMLDivElement>(null);
122117
const inputRef = React.useRef<HTMLInputElement>(null);
@@ -161,10 +156,10 @@ export default React.forwardRef<SelectInputRef, SelectInputProps>(function Selec
161156
() => ({
162157
focus: (options?: FocusOptions) => {
163158
// Focus the inner input if available, otherwise fall back to root div.
164-
inputRef.current.focus?.(options);
159+
(inputRef.current || rootRef.current).focus?.(options);
165160
},
166161
blur: () => {
167-
inputRef.current.blur?.();
162+
(inputRef.current || rootRef.current).blur?.();
168163
},
169164
nativeElement: rootRef.current,
170165
}),
@@ -203,6 +198,9 @@ export default React.forwardRef<SelectInputRef, SelectInputProps>(function Selec
203198
onBlur?.(event);
204199
};
205200

201+
// =================== Components ===================
202+
const { root: RootComponent } = components;
203+
206204
// ===================== Render =====================
207205
const domProps = omit(restProps, DEFAULT_OMIT_PROPS);
208206

@@ -212,6 +210,31 @@ export default React.forwardRef<SelectInputRef, SelectInputProps>(function Selec
212210
onInputKeyDown: onInternalInputKeyDown,
213211
};
214212

213+
const sharedProps = {
214+
// Open
215+
onMouseDown: onInternalMouseDown,
216+
onBlur: onInternalBlur,
217+
} as const;
218+
219+
if (RootComponent) {
220+
if (React.isValidElement<any>(RootComponent)) {
221+
const oriProps = RootComponent.props || {};
222+
return React.cloneElement(RootComponent, {
223+
...sharedProps,
224+
onMouseDown: (e: React.MouseEvent<HTMLDivElement>) => {
225+
sharedProps.onMouseDown(e);
226+
oriProps.onMouseDown?.(e);
227+
},
228+
onBlur: (e: React.FocusEvent<HTMLDivElement>) => {
229+
sharedProps.onBlur(e);
230+
oriProps.onBlur?.(e);
231+
},
232+
ref: rootRef,
233+
});
234+
}
235+
return <RootComponent {...sharedProps} ref={rootRef} />;
236+
}
237+
215238
return (
216239
<SelectInputContext.Provider value={contextValue}>
217240
<div
@@ -220,9 +243,8 @@ export default React.forwardRef<SelectInputRef, SelectInputProps>(function Selec
220243
ref={rootRef}
221244
className={className}
222245
style={style}
223-
// Open
224-
onMouseDown={onInternalMouseDown}
225-
onBlur={onInternalBlur}
246+
// Shared Props
247+
{...sharedProps}
226248
>
227249
{/* Prefix */}
228250
<Affix className={clsx(`${prefixCls}-prefix`, classNames?.prefix)} style={styles?.prefix}>

src/hooks/useComponents.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import * as React from 'react';
2-
import SelectInput, { type SelectInputRef, type SelectInputProps } from '../SelectInput';
2+
import type { SelectInputRef, SelectInputProps } from '../SelectInput';
33

44
export interface ComponentsConfig {
5-
root?: React.ComponentType<any> | string;
5+
root?: React.ComponentType<any> | string | React.ReactElement;
66
input?: React.ComponentType<any> | string;
77
}
88

@@ -17,7 +17,7 @@ export interface FilledComponentsConfig {
1717

1818
export default function useComponents(components?: ComponentsConfig) {
1919
return React.useMemo(() => {
20-
const { root: RootComponent = SelectInput, input: InputComponent = 'input' } = components || {};
20+
const { root: RootComponent, input: InputComponent } = components || {};
2121

2222
return { root: RootComponent, input: InputComponent } as FilledComponentsConfig;
2323
}, [components]);

0 commit comments

Comments
 (0)