Skip to content

Commit 0052f52

Browse files
authored
feat(component): search input support text wrap (#169)
1 parent 8e40782 commit 0052f52

File tree

2 files changed

+62
-16
lines changed

2 files changed

+62
-16
lines changed

src/components/search/input.tsx

+39-7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ export interface IBaseInputProps {
2727
onToolbarClick?: (addon) => void;
2828
}
2929

30+
/**
31+
* Mock an Input by textarea
32+
* 'Cause we have to achieve text wrap and input cannot achieve it
33+
*/
3034
function Input(props: IBaseInputProps) {
3135
const {
3236
className,
@@ -38,11 +42,11 @@ function Input(props: IBaseInputProps) {
3842
} = props;
3943

4044
const [focusStatus, setFocus] = React.useState(false);
41-
const inputRef = React.useRef<HTMLInputElement>(null);
45+
const textareaRef = React.useRef<HTMLTextAreaElement>(null);
4246

4347
const onToolbarClick = (e, item) => {
4448
// toolbar click can trigger input focus
45-
inputRef.current?.focus();
49+
textareaRef.current?.focus();
4650
props.onToolbarClick?.(item);
4751
};
4852

@@ -67,18 +71,46 @@ function Input(props: IBaseInputProps) {
6771
setFocus(false);
6872
};
6973

74+
const handleInputChange = (e) => {
75+
if (textareaRef.current) {
76+
// base height
77+
textareaRef.current.style.height = '24px';
78+
const curretnScollerHeight = textareaRef.current.scrollHeight;
79+
// count the lines
80+
const lines = curretnScollerHeight / 24;
81+
const maxLines = 5;
82+
if (lines > maxLines) {
83+
textareaRef.current.style.height = `${24 * maxLines}px`;
84+
} else {
85+
textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;
86+
}
87+
}
88+
onChange?.(e.target.value || '');
89+
};
90+
91+
const handleInputKeyPress = (e) => {
92+
// detect Enter press
93+
if (e.keyCode === 13) {
94+
onChange?.(e.target.value || '');
95+
e.preventDefault();
96+
}
97+
};
98+
7099
return (
71100
<div className={className}>
72-
<input
73-
ref={inputRef}
101+
<textarea
102+
ref={textareaRef}
103+
spellCheck={false}
104+
autoCorrect="off"
105+
autoCapitalize="off"
74106
className={classNames(getInfoClassName(info?.type || ''))}
75107
value={value || ''}
76108
placeholder={placeholder}
109+
title={placeholder}
110+
onKeyDown={handleInputKeyPress}
77111
onFocus={handleInputFocus}
78112
onBlur={handleInputBlur}
79-
onChange={(e) => {
80-
onChange?.(e.target.value || '');
81-
}}
113+
onChange={handleInputChange}
82114
/>
83115
{info && focusStatus && (
84116
<div

src/components/search/style.scss

+23-9
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
box-sizing: border-box;
1414
color: inherit;
1515
cursor: pointer;
16-
height: 100%;
16+
height: calc(100% - 3px);
1717
transition: background 0.3s;
1818

1919
&.codicon {
@@ -27,22 +27,36 @@
2727
}
2828
}
2929

30-
input {
30+
textarea {
31+
background: var(--input-background);
3132
border: 1px solid transparent;
3233
box-sizing: border-box;
34+
color: var(--input-foreground);
35+
font-family: inherit;
3336
font-size: inherit;
34-
height: 23px;
35-
padding: 3px;
36-
padding-right: 4px;
37-
text-indent: 4px;
37+
height: 24px;
38+
line-height: 18px;
39+
outline: none;
40+
padding: 3px 62px 3px 4px;
41+
resize: none;
3842
width: 100%;
3943

40-
&:focus,
41-
&:active {
42-
outline: none;
44+
&:focus {
45+
border-color: var(--focusBorder);
46+
}
47+
48+
// TODO: better to mock a scoll bar
49+
// invisible scroll bar
50+
&::-webkit-scrollbar {
51+
opacity: 0;
4352
}
4453
}
4554

55+
.scrollbar-invisible {
56+
position: absolute;
57+
right: 0;
58+
}
59+
4660
&__toolbar {
4761
height: 100%;
4862
position: absolute;

0 commit comments

Comments
 (0)