feat: paste multiple lines in parameters input

This commit is contained in:
jialin
2026-03-17 16:35:55 +08:00
committed by jialin
parent 556c4a434d
commit 4f02bcd40c
11 changed files with 76 additions and 58 deletions
+11 -1
View File
@@ -7,6 +7,7 @@ interface HintInputProps {
label?: string;
onChange: (value: string) => void;
onBlur?: (e: any) => void;
onPaste?: (e: any) => void;
placeholder?: string;
trim?: boolean;
sourceOptions?: Global.HintOptions[];
@@ -15,7 +16,15 @@ interface HintInputProps {
const matchReg = /[^=]+=[^=]*$/;
const HintInput: React.FC<HintInputProps> = (props) => {
const { value, label, onChange, onBlur, sourceOptions, trim = true } = props;
const {
value,
label,
onChange,
onBlur,
onPaste,
sourceOptions,
trim = true
} = props;
const cursorPosRef = React.useRef(0);
const contextBeforeCursorRef = React.useRef('');
const [options, setOptions] = React.useState<
@@ -92,6 +101,7 @@ const HintInput: React.FC<HintInputProps> = (props) => {
options={options}
trim={trim}
style={{ flex: 1 }}
onPaste={onPaste}
/>
);
};
+36
View File
@@ -79,6 +79,41 @@ const ListInput: React.FC<ListInputProps> = (props) => {
setList(values);
};
const handleOnPaste = (e: any, index: number) => {
const pastedText = e.clipboardData?.getData('text');
if (!pastedText) return;
const lines = pastedText.split(/\r?\n/).filter((line: string) => {
const trimmedLine = trim ? line.trim() : line;
return trimmedLine.length > 0;
});
if (lines.length <= 1) {
// if there's only one line, let the default paste behavior handle it
return;
}
e.preventDefault();
const values = _.cloneDeep(list);
// replace the current item with the first line of the pasted text
values[index].value = trim ? lines[0].trim() : lines[0];
// create new list items for the remaining lines
for (let i = 1; i < lines.length; i++) {
updateCountRef();
values.splice(index + i, 0, {
value: trim ? lines[i].trim() : lines[i],
uid: countRef.current
});
}
const valueList = _.map(values, 'value').filter((val: string) => !!val);
setList(values);
onChange(valueList);
};
React.useEffect(() => {
const valueList = _.map(list, 'value').filter((val: string) => !!val);
if (!_.isEqual(valueList, dataList)) {
@@ -122,6 +157,7 @@ const ListInput: React.FC<ListInputProps> = (props) => {
onBlur={(e) => onBlur?.(e, index)}
onRemove={() => handleOnRemove(index)}
onChange={(val) => handleOnChange(val, index)}
onPaste={(e) => handleOnPaste(e, index)}
trim={trim}
renderItem={renderItem}
/>
+6 -1
View File
@@ -8,11 +8,13 @@ interface LabelItemProps {
onRemove: () => void;
onChange: (value: string) => void;
onBlur?: (e: any) => void;
onPaste?: (e: any) => void;
renderItem?: (
data: any,
props: {
onChange: (value: string) => void;
onBlur?: (e: any) => void;
onPaste?: (e: any) => void;
}
) => React.ReactNode;
value: string;
@@ -29,6 +31,7 @@ const ListItem: React.FC<LabelItemProps> = (props) => {
onRemove,
onChange,
onBlur,
onPaste,
label,
value,
options,
@@ -47,13 +50,15 @@ const ListItem: React.FC<LabelItemProps> = (props) => {
{renderItem ? (
renderItem(data, {
onChange: handleOnChange,
onBlur
onBlur,
onPaste
})
) : (
<HintInput
value={value}
onChange={handleOnChange}
onBlur={onBlur}
onPaste={onPaste}
label={label}
sourceOptions={options}
trim={trim}
@@ -12,6 +12,7 @@ const Link = Typography.Link;
const SealAutoComplete: React.FC<
AutoCompleteProps &
SealFormItemProps & {
onPaste?: (e: any) => void;
onInput?: (e: Event) => void;
clearSpaceOnBlur?: boolean;
}
@@ -148,6 +149,7 @@ const SealAutoComplete: React.FC<
onChange={handleChange}
popupRender={popupRender}
onInput={handleOnInput}
onPaste={props.onPaste}
></AutoComplete>
</Wrapper>
</SelectWrapper>