붙여넣기 시 url만 추출 기능 추가
parent
5b7eba9540
commit
e2b22bd8e9
|
|
@ -18,6 +18,23 @@ const isValidUrl = (string: string): boolean => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// URL 형태로 판단되는 입력: 프로토콜/www. 시작 또는 도메인 형태(naver.me/xxx 등)
|
||||||
|
const isUrlLike = (value: string): boolean => {
|
||||||
|
const trimmed = value.trim();
|
||||||
|
return /^(https?:\/\/|www\.)/i.test(trimmed)
|
||||||
|
|| /^[a-z0-9-]+(\.[a-z0-9-]+)+([/?#]|$)/i.test(trimmed);
|
||||||
|
};
|
||||||
|
|
||||||
|
const sanitizeUrlInput = (value: string): string => {
|
||||||
|
return value.replace(/[^\x00-\x7F]/g, '');
|
||||||
|
};
|
||||||
|
|
||||||
|
// 텍스트 안에 포함된 첫 번째 URL을 추출 (없으면 null)
|
||||||
|
const extractUrl = (text: string): string | null => {
|
||||||
|
const match = text.match(/(https?:\/\/|www\.)[^\s]+/i);
|
||||||
|
return match ? match[0] : null;
|
||||||
|
};
|
||||||
|
|
||||||
interface SearchInputFormProps {
|
interface SearchInputFormProps {
|
||||||
onAnalyze?: (value: string, type: SearchType) => void;
|
onAnalyze?: (value: string, type: SearchType) => void;
|
||||||
onAutocomplete?: (data: AutocompleteRequest) => void;
|
onAutocomplete?: (data: AutocompleteRequest) => void;
|
||||||
|
|
@ -142,6 +159,47 @@ const SearchInputForm: React.FC<SearchInputFormProps> = ({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const applyInputChange = (value: string) => {
|
||||||
|
setInputValue(value);
|
||||||
|
setSelectedItem(null);
|
||||||
|
setHighlightedIndex(-1);
|
||||||
|
hideOnInput(value);
|
||||||
|
if (localError) setLocalError('');
|
||||||
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
||||||
|
if (isValidUrl(value)) {
|
||||||
|
setAutocompleteResults([]);
|
||||||
|
setShowAutocomplete(false);
|
||||||
|
} else {
|
||||||
|
debounceRef.current = setTimeout(() => handleAutocompleteSearch(value), 300);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePaste = (e: React.ClipboardEvent<HTMLInputElement>) => {
|
||||||
|
const pastedText = e.clipboardData.getData('text');
|
||||||
|
|
||||||
|
// 붙여넣은 텍스트에 URL이 포함되어 있고 URL 외 다른 텍스트도 있으면 URL만 추출해서 입력창에 넣기
|
||||||
|
const extracted = extractUrl(pastedText);
|
||||||
|
if (extracted && extracted !== pastedText.trim()) {
|
||||||
|
e.preventDefault();
|
||||||
|
applyInputChange(sanitizeUrlInput(extracted));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const input = e.currentTarget;
|
||||||
|
const start = input.selectionStart ?? inputValue.length;
|
||||||
|
const end = input.selectionEnd ?? inputValue.length;
|
||||||
|
const merged = inputValue.slice(0, start) + pastedText + inputValue.slice(end);
|
||||||
|
|
||||||
|
// 붙여넣은 후 완성될 전체 값이 URL 형태일 때만 비영문 문자 제거
|
||||||
|
if (!isUrlLike(merged)) return;
|
||||||
|
|
||||||
|
const sanitized = sanitizeUrlInput(merged);
|
||||||
|
if (sanitized === merged) return;
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
applyInputChange(sanitized);
|
||||||
|
};
|
||||||
|
|
||||||
const handleManualButtonClick = () => {
|
const handleManualButtonClick = () => {
|
||||||
if (onManualButtonClick) {
|
if (onManualButtonClick) {
|
||||||
onManualButtonClick();
|
onManualButtonClick();
|
||||||
|
|
@ -169,21 +227,8 @@ const SearchInputForm: React.FC<SearchInputFormProps> = ({
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={inputValue}
|
value={inputValue}
|
||||||
onChange={(e) => {
|
onChange={(e) => applyInputChange(e.target.value)}
|
||||||
const value = e.target.value;
|
onPaste={handlePaste}
|
||||||
setInputValue(value);
|
|
||||||
setSelectedItem(null);
|
|
||||||
setHighlightedIndex(-1);
|
|
||||||
hideOnInput(value);
|
|
||||||
if (localError) setLocalError('');
|
|
||||||
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
||||||
if (isValidUrl(value)) {
|
|
||||||
setAutocompleteResults([]);
|
|
||||||
setShowAutocomplete(false);
|
|
||||||
} else {
|
|
||||||
debounceRef.current = setTimeout(() => handleAutocompleteSearch(value), 300);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onFocus={() => {
|
onFocus={() => {
|
||||||
setIsFocused(true);
|
setIsFocused(true);
|
||||||
if (autocompleteResults.length > 0) setShowAutocomplete(true);
|
if (autocompleteResults.length > 0) setShowAutocomplete(true);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue