Skip to content

Commit 1faca1f

Browse files
committed
chore: multiple of it
1 parent 0a18a4f commit 1faca1f

File tree

3 files changed

+79
-39
lines changed

3 files changed

+79
-39
lines changed

assets/patch.less

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,10 @@
7474
border-radius: 8px;
7575
margin-right: 4px;
7676
}
77+
78+
.@{select-prefix}-input {
79+
width: calc(var(--select-input-width, 10) * 1px);
80+
min-width: 4px;
81+
}
7782
}
7883
}

src/SelectInput/Content/MultipleContent.tsx

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type { DisplayValueType, RawValueType } from '../../interface';
99
import type { RenderNode, CustomTagProps } from '../../BaseSelect';
1010
import TransBtn from '../../TransBtn';
1111
import { getTitle } from '../../utils/commonUtil';
12-
import useLayoutEffect from '../../hooks/useLayoutEffect';
12+
import useLayoutEffect from '@rc-component/util/lib/hooks/useLayoutEffect';
1313
import useBaseProps from '../../hooks/useBaseProps';
1414

1515
function itemKey(value: DisplayValueType) {
@@ -25,9 +25,18 @@ export default React.forwardRef<HTMLInputElement, SharedContentProps>(function M
2525
{ inputProps },
2626
ref,
2727
) {
28-
const { prefixCls, displayValues, searchValue, onSelectorRemove } = useSelectInputContext();
29-
const baseProps = useBaseProps();
30-
const { disabled, showSearch, open, toggleOpen } = baseProps;
28+
const {
29+
prefixCls,
30+
displayValues,
31+
searchValue,
32+
onSelectorRemove,
33+
removeIcon: removeIconFromContext,
34+
maxTagPlaceholder: maxTagPlaceholderFromContext,
35+
maxTagTextLength,
36+
maxTagCount,
37+
tagRender: tagRenderFromContext,
38+
} = useSelectInputContext();
39+
const { disabled, showSearch, open, toggleOpen } = useBaseProps();
3140

3241
const measureRef = React.useRef<HTMLSpanElement>(null);
3342
const [inputWidth, setInputWidth] = useState(0);
@@ -44,12 +53,15 @@ export default React.forwardRef<HTMLInputElement, SharedContentProps>(function M
4453
}
4554
}, [inputValue]);
4655

47-
// These would typically come from parent props - using defaults for now
48-
const removeIcon: RenderNode = '×';
49-
const maxTagTextLength: number | undefined = undefined;
50-
const maxTagCount: number | 'responsive' | undefined = undefined;
51-
const maxTagPlaceholder = (omittedValues: DisplayValueType[]) => `+ ${omittedValues.length} ...`;
52-
const tagRender: ((props: CustomTagProps) => React.ReactElement) | undefined = undefined;
56+
// Props from context with safe defaults
57+
const removeIcon: RenderNode = removeIconFromContext ?? '×';
58+
const maxTagPlaceholder:
59+
| React.ReactNode
60+
| ((omittedValues: DisplayValueType[]) => React.ReactNode) =
61+
maxTagPlaceholderFromContext ??
62+
((omittedValues: DisplayValueType[]) => `+ ${omittedValues.length} ...`);
63+
const tagRender: ((props: CustomTagProps) => React.ReactElement) | undefined =
64+
tagRenderFromContext;
5365

5466
const onToggleOpen = (newOpen?: boolean) => {
5567
toggleOpen(newOpen);
@@ -208,7 +220,17 @@ export default React.forwardRef<HTMLInputElement, SharedContentProps>(function M
208220
data={displayValues}
209221
renderItem={renderItem}
210222
renderRest={renderRest}
211-
suffix={inputNode}
223+
// suffix={inputNode}
224+
suffix={
225+
<Input
226+
ref={ref}
227+
disabled={disabled}
228+
readOnly={!inputEditable}
229+
{...inputProps}
230+
value={inputValue || ''}
231+
syncWidth
232+
/>
233+
}
212234
itemKey={itemKey}
213235
maxCount={maxTagCount}
214236
/>

src/SelectInput/Input.tsx

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as React from 'react';
22
import { useSelectInputContext } from './context';
3+
import useLayoutEffect from '@rc-component/util/lib/hooks/useLayoutEffect';
34

45
export interface InputProps {
56
disabled?: boolean;
@@ -13,10 +14,12 @@ export interface InputProps {
1314
className?: string;
1415
style?: React.CSSProperties;
1516
maxLength?: number;
17+
/** width always match content width */
18+
syncWidth?: boolean;
1619
}
1720

1821
const Input = React.forwardRef<HTMLInputElement, InputProps>((props, ref) => {
19-
const { onChange, onKeyDown, onBlur, ...restProps } = props;
22+
const { onChange, onKeyDown, onBlur, style, syncWidth, value, ...restProps } = props;
2023
const { prefixCls, mode, onSearch, onSearchSubmit, onInputBlur, autoFocus } =
2124
useSelectInputContext();
2225

@@ -25,27 +28,34 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>((props, ref) => {
2528
// Used to handle input method composition status
2629
const compositionStatusRef = React.useRef<boolean>(false);
2730

31+
// ============================== Refs ==============================
32+
const inputRef = React.useRef<HTMLInputElement>(null);
33+
34+
React.useImperativeHandle(ref, () => inputRef.current);
35+
36+
// ============================== Data ==============================
2837
// Handle input changes
2938
const handleChange: React.ChangeEventHandler<HTMLInputElement> = (event) => {
30-
const { value } = event.target;
39+
const { value: nextVal } = event.target;
3140

3241
// Call onSearch callback
3342
if (onSearch) {
34-
onSearch(value, true, compositionStatusRef.current);
43+
onSearch(nextVal, true, compositionStatusRef.current);
3544
}
3645

3746
// Call original onChange callback
3847
onChange?.(event);
3948
};
4049

50+
// ============================ Keyboard ============================
4151
// Handle keyboard events
4252
const handleKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (event) => {
4353
const { key } = event;
44-
const { value } = event.currentTarget;
54+
const { value: nextVal } = event.currentTarget;
4555

4656
// Handle Enter key submission - referencing Selector implementation
4757
if (key === 'Enter' && mode === 'tags' && !compositionStatusRef.current && onSearchSubmit) {
48-
onSearchSubmit(value);
58+
onSearchSubmit(nextVal);
4959
}
5060

5161
// Call original onKeyDown callback
@@ -71,38 +81,41 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>((props, ref) => {
7181
compositionStatusRef.current = false;
7282

7383
// Trigger search when input method composition ends
74-
const { value } = event.currentTarget;
75-
onSearch?.(value, true, false);
84+
const { value: nextVal } = event.currentTarget;
85+
onSearch?.(nextVal, true, false);
7686
};
7787

78-
// ============================= Mouse ==============================
79-
// const onMouseDown: React.MouseEventHandler<HTMLElement> = (event) => {
80-
// // const inputMouseDown = getInputMouseDown();
81-
// // // when mode is combobox and it is disabled, don't prevent default behavior
82-
// // // https://github.com/ant-design/ant-design/issues/37320
83-
// // // https://github.com/ant-design/ant-design/issues/48281
84-
// // if (
85-
// // event.target !== inputRef.current &&
86-
// // !inputMouseDown &&
87-
// // !(mode === 'combobox' && disabled)
88-
// // ) {
89-
// // event.preventDefault();
90-
// // }
91-
// // if ((mode !== 'combobox' && (!showSearch || !inputMouseDown)) || !open) {
92-
// // if (open && autoClearSearchValue !== false) {
93-
// // onSearch('', true, false);
94-
// // }
95-
// // onToggleOpen();
96-
// // }
97-
// };
88+
// ============================= Width ==============================
89+
const [widthCssVar, setWidthCssVar] = React.useState<number | undefined>(undefined);
90+
91+
// When syncWidth is enabled, adjust input width based on content
92+
useLayoutEffect(() => {
93+
const input = inputRef.current;
94+
95+
if (syncWidth && input) {
96+
input.style.width = '0px';
97+
const scrollWidth = input.scrollWidth;
98+
setWidthCssVar(scrollWidth);
99+
100+
// Reset input style
101+
input.style.width = '';
102+
}
103+
}, [syncWidth, value]);
98104

99105
// ============================= Render =============================
100106
return (
101107
<input
102108
{...restProps}
103-
ref={ref}
109+
ref={inputRef}
110+
style={
111+
{
112+
...style,
113+
'--select-input-width': widthCssVar,
114+
} as React.CSSProperties
115+
}
104116
autoFocus={autoFocus}
105117
className={inputCls}
118+
value={value || ''}
106119
onChange={handleChange}
107120
onKeyDown={handleKeyDown}
108121
onBlur={handleBlur}

0 commit comments

Comments
 (0)