1
- import { Col , Input , Row , Space , Typography } from 'antd' ;
1
+ import { Col , Input , Row , Typography } from 'antd' ;
2
2
import classNames from 'classnames' ;
3
3
import React from 'react' ;
4
4
import { AiFillCloseCircle } from 'react-icons/ai' ;
@@ -33,6 +33,7 @@ const styles = (theme: CommitComposerTheme) => ({
33
33
description : {
34
34
fontSize : 12 ,
35
35
paddingRight : 9 ,
36
+ marginBottom : '0 !important' ,
36
37
} ,
37
38
searchRow : { } ,
38
39
itemRow : {
@@ -61,6 +62,7 @@ type Props = WithStylesProps<typeof styles> & OwnProps & ReduxProps & DispatchPr
61
62
export interface State {
62
63
searchInputRef : React . RefObject < Input > ;
63
64
visibleItems : RenderedItem [ ] ;
65
+ query : string ;
64
66
}
65
67
66
68
class SearchableMenuComponent extends React . Component < Props , State > {
@@ -69,14 +71,15 @@ class SearchableMenuComponent extends React.Component<Props, State> {
69
71
this . state = {
70
72
searchInputRef : React . createRef ( ) ,
71
73
visibleItems : this . renderItems ( props . items ) ,
74
+ query : '' ,
72
75
} ;
73
76
}
74
77
75
78
componentDidMount ( ) : void {
76
79
this . focus ( ) ;
77
80
}
78
81
79
- componentDidUpdate ( prevProps : Readonly < Props > ) : void {
82
+ componentDidUpdate ( prevProps : Readonly < Props > , prevState : Readonly < State > ) : void {
80
83
const { focus, items } = this . props ;
81
84
82
85
if ( ! prevProps . focus && focus ) {
@@ -85,7 +88,7 @@ class SearchableMenuComponent extends React.Component<Props, State> {
85
88
86
89
if ( prevProps . items !== items ) {
87
90
this . setState ( {
88
- visibleItems : this . renderItems ( items ) ,
91
+ visibleItems : this . renderItems ( items , prevState . query ) ,
89
92
} ) ;
90
93
}
91
94
}
@@ -120,38 +123,40 @@ class SearchableMenuComponent extends React.Component<Props, State> {
120
123
onSearch ( query ?: string ) : void {
121
124
const { items } = this . props ;
122
125
const visibleItems = this . renderItems ( items , query ) ;
123
- this . setState ( { visibleItems } ) ;
126
+ this . setState ( { visibleItems, query } ) ;
124
127
}
125
128
126
129
onSelect ( item : string ) : void {
127
130
this . clear ( ) ;
128
131
this . props . onClick ?.( item ) ;
129
132
}
130
133
131
- renderItems ( items : SearchableItem [ ] , query ?: string ) : RenderedItem [ ] {
134
+ highlight ( input : string , regex ?: RegExp ) : { elem : JSX . Element ; found : boolean } {
132
135
const { classes } = this . props ;
133
136
134
- const highlight = ( input : string , regex ?: RegExp ) : { elem : JSX . Element ; found : boolean } => {
135
- if ( input === '' || input === undefined ) {
136
- return ;
137
- }
137
+ if ( input === '' || input === undefined ) {
138
+ return ;
139
+ }
138
140
139
- const parts : React . ReactNode [ ] = input . split ( regex ) ;
140
- let found = false ;
141
+ const parts : React . ReactNode [ ] = input . split ( regex ) ;
142
+ let found = false ;
141
143
142
- for ( let i = 1 ; i < parts . length ; i += 2 ) {
143
- parts [ i ] = (
144
- < span key = { i } className = { classes . highlight } >
145
- { parts [ i ] }
146
- </ span >
147
- ) ;
148
- found = true ;
149
- }
150
- return {
151
- elem : < Typography . Text > { parts } </ Typography . Text > ,
152
- found,
153
- } ;
144
+ for ( let i = 1 ; i < parts . length ; i += 2 ) {
145
+ parts [ i ] = (
146
+ < span key = { i } className = { classes . highlight } >
147
+ { parts [ i ] }
148
+ </ span >
149
+ ) ;
150
+ found = true ;
151
+ }
152
+ return {
153
+ elem : < > { parts } </ > ,
154
+ found,
154
155
} ;
156
+ }
157
+
158
+ renderItems ( items : SearchableItem [ ] , query ?: string ) : RenderedItem [ ] {
159
+ const { classes } = this . props ;
155
160
156
161
const escapeRegExp = ( str : string ) : string => {
157
162
return str . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) ;
@@ -160,18 +165,23 @@ class SearchableMenuComponent extends React.Component<Props, State> {
160
165
return items
161
166
. map ( ( x ) => {
162
167
const titleRegex = query ? new RegExp ( `(${ escapeRegExp ( query ) } )` , 'gi' ) : undefined ;
163
- const title = highlight ( x . title , titleRegex ) ;
168
+ const title = this . highlight ( x . title , titleRegex ) ;
164
169
const descriptionRegex = query ? new RegExp ( `(${ escapeRegExp ( query ) } )` , 'gi' ) : undefined ;
165
- const description = highlight ( x . description , descriptionRegex ) ;
170
+ const description = this . highlight ( x . description , descriptionRegex ) ;
166
171
167
172
const found =
168
173
query === undefined || query === '' || title . found || ( description && description . found ) ;
169
174
170
175
if ( description ) {
171
- description . elem = React . cloneElement ( description . elem , {
172
- type : 'secondary' ,
173
- className : classes . description ,
174
- } ) ;
176
+ description . elem = (
177
+ < Typography . Paragraph type = "secondary" className = { classes . description } ellipsis >
178
+ { description . elem }
179
+ </ Typography . Paragraph >
180
+ ) ;
181
+ }
182
+
183
+ if ( title ) {
184
+ title . elem = < Typography . Text > { title . elem } </ Typography . Text > ;
175
185
}
176
186
177
187
return {
@@ -187,7 +197,7 @@ class SearchableMenuComponent extends React.Component<Props, State> {
187
197
188
198
render ( ) : JSX . Element {
189
199
const { classes, className, searchBarClassName, children } = this . props ;
190
- const { visibleItems } = this . state ;
200
+ const { visibleItems, query } = this . state ;
191
201
192
202
return (
193
203
< div className = { classNames ( classes . root , className ) } >
@@ -202,7 +212,7 @@ class SearchableMenuComponent extends React.Component<Props, State> {
202
212
/>
203
213
< span
204
214
className = { classNames ( 'ant-input-suffix' , {
205
- [ classes . hidden ] : ! this . state . searchInputRef ?. current ?. input . value ,
215
+ [ classes . hidden ] : ! query ,
206
216
} ) } >
207
217
< span
208
218
tabIndex = { - 1 }
@@ -224,15 +234,15 @@ class SearchableMenuComponent extends React.Component<Props, State> {
224
234
key = { x . item }
225
235
item = { x . item }
226
236
icon = { x . icon } >
227
- < Space size = { 1 } direction = "vertical" >
237
+ < >
228
238
{ x . title }
229
239
{ x . description }
230
- </ Space >
240
+ </ >
231
241
</ SearchableMenuItemComponent >
232
242
) ) }
233
243
</ Col >
234
244
</ Row >
235
- < Row onClick = { ( e ) => e . stopPropagation ( ) } >
245
+ < Row >
236
246
< Col flex = "auto" > { children } </ Col >
237
247
</ Row >
238
248
</ div >
0 commit comments