aboutsummaryrefslogtreecommitdiffstats
path: root/packages/forms/src/select/index.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/forms/src/select/index.tsx')
-rw-r--r--packages/forms/src/select/index.tsx119
1 files changed, 67 insertions, 52 deletions
diff --git a/packages/forms/src/select/index.tsx b/packages/forms/src/select/index.tsx
index e5b59cb19..4a5775579 100644
--- a/packages/forms/src/select/index.tsx
+++ b/packages/forms/src/select/index.tsx
@@ -1,4 +1,8 @@
1import { mdiArrowRightDropCircleOutline, mdiCloseCircle, mdiMagnify } from '@mdi/js'; 1import {
2 mdiArrowRightDropCircleOutline,
3 mdiCloseCircle,
4 mdiMagnify,
5} from '@mdi/js';
2import Icon from '@mdi/react'; 6import Icon from '@mdi/react';
3import classnames from 'classnames'; 7import classnames from 'classnames';
4import React, { Component, createRef } from 'react'; 8import React, { Component, createRef } from 'react';
@@ -58,7 +62,7 @@ const styles = (theme: Theme) => ({
58 label: { 62 label: {
59 '& > div': { 63 '& > div': {
60 marginTop: 5, 64 marginTop: 5,
61 } 65 },
62 }, 66 },
63 popup: { 67 popup: {
64 opacity: 0, 68 opacity: 0,
@@ -153,9 +157,13 @@ class SelectComponent extends Component<IProps> {
153 }; 157 };
154 158
155 private componentRef = createRef<HTMLDivElement>(); 159 private componentRef = createRef<HTMLDivElement>();
160
156 private inputRef = createRef<HTMLInputElement>(); 161 private inputRef = createRef<HTMLInputElement>();
162
157 private searchInputRef = createRef<HTMLInputElement>(); 163 private searchInputRef = createRef<HTMLInputElement>();
164
158 private scrollContainerRef = createRef<HTMLDivElement>(); 165 private scrollContainerRef = createRef<HTMLDivElement>();
166
159 private activeOptionRef = createRef<HTMLDivElement>(); 167 private activeOptionRef = createRef<HTMLDivElement>();
160 168
161 private keyListener: any; 169 private keyListener: any;
@@ -168,7 +176,7 @@ class SelectComponent extends Component<IProps> {
168 } 176 }
169 } 177 }
170 178
171 componentDidUpdate(prevProps: IProps, prevState: IState) { 179 componentDidUpdate() {
172 const { open } = this.state; 180 const { open } = this.state;
173 181
174 if (this.searchInputRef && this.searchInputRef.current) { 182 if (this.searchInputRef && this.searchInputRef.current) {
@@ -183,7 +191,9 @@ class SelectComponent extends Component<IProps> {
183 const { data } = this.props; 191 const { data } = this.props;
184 192
185 if (data) { 193 if (data) {
186 Object.keys(data).map(key => this.inputRef.current!.dataset[key] = data[key]); 194 Object.keys(data).map(
195 key => (this.inputRef.current!.dataset[key] = data[key]),
196 );
187 } 197 }
188 } 198 }
189 199
@@ -194,7 +204,10 @@ class SelectComponent extends Component<IProps> {
194 const { value } = this.props; 204 const { value } = this.props;
195 205
196 if (this.componentRef && this.componentRef.current) { 206 if (this.componentRef && this.componentRef.current) {
197 this.componentRef.current.removeEventListener('keydown', this.keyListener); 207 this.componentRef.current.removeEventListener(
208 'keydown',
209 this.keyListener,
210 );
198 } 211 }
199 212
200 if (value) { 213 if (value) {
@@ -210,13 +223,18 @@ class SelectComponent extends Component<IProps> {
210 window.removeEventListener('keydown', this.arrowKeysHandler.bind(this)); 223 window.removeEventListener('keydown', this.arrowKeysHandler.bind(this));
211 } 224 }
212 225
213 setFilter(needle: string = '') { 226 setFilter(needle = '') {
214 const { options } = this.props; 227 const { options } = this.props;
215 228
216 let filteredOptions = {}; 229 let filteredOptions = {};
217 if (needle) { 230 if (needle) {
218 Object.keys(options).map((key) => { 231 Object.keys(options).map(key => {
219 if (key.toLocaleLowerCase().startsWith(needle.toLocaleLowerCase()) || options[key].toLocaleLowerCase().startsWith(needle.toLocaleLowerCase())) { 232 if (
233 key.toLocaleLowerCase().startsWith(needle.toLocaleLowerCase()) ||
234 options[key]
235 .toLocaleLowerCase()
236 .startsWith(needle.toLocaleLowerCase())
237 ) {
220 Object.assign(filteredOptions, { 238 Object.assign(filteredOptions, {
221 [`${key}`]: options[key], 239 [`${key}`]: options[key],
222 }); 240 });
@@ -234,7 +252,7 @@ class SelectComponent extends Component<IProps> {
234 } 252 }
235 253
236 select(key: string) { 254 select(key: string) {
237 this.setState((state: IState) => ({ 255 this.setState(() => ({
238 value: key, 256 value: key,
239 open: false, 257 open: false,
240 })); 258 }));
@@ -247,11 +265,7 @@ class SelectComponent extends Component<IProps> {
247 } 265 }
248 266
249 arrowKeysHandler(e: KeyboardEvent) { 267 arrowKeysHandler(e: KeyboardEvent) {
250 const { 268 const { selected, open, options } = this.state;
251 selected,
252 open,
253 options,
254 } = this.state;
255 269
256 if (!open) return; 270 if (!open) return;
257 271
@@ -264,7 +278,10 @@ class SelectComponent extends Component<IProps> {
264 this.setState((state: IState) => ({ 278 this.setState((state: IState) => ({
265 selected: state.selected - 1, 279 selected: state.selected - 1,
266 })); 280 }));
267 } else if (e.keyCode === 40 && selected < Object.keys(options!).length - 1) { 281 } else if (
282 e.keyCode === 40 &&
283 selected < Object.keys(options!).length - 1
284 ) {
268 this.setState((state: IState) => ({ 285 this.setState((state: IState) => ({
269 selected: state.selected + 1, 286 selected: state.selected + 1,
270 })); 287 }));
@@ -272,7 +289,12 @@ class SelectComponent extends Component<IProps> {
272 this.select(Object.keys(options!)[selected]); 289 this.select(Object.keys(options!)[selected]);
273 } 290 }
274 291
275 if (this.activeOptionRef && this.activeOptionRef.current && this.scrollContainerRef && this.scrollContainerRef.current) { 292 if (
293 this.activeOptionRef &&
294 this.activeOptionRef.current &&
295 this.scrollContainerRef &&
296 this.scrollContainerRef.current
297 ) {
276 const containerTopOffset = this.scrollContainerRef.current.offsetTop; 298 const containerTopOffset = this.scrollContainerRef.current.offsetTop;
277 const optionTopOffset = this.activeOptionRef.current.offsetTop; 299 const optionTopOffset = this.activeOptionRef.current.offsetTop;
278 300
@@ -282,10 +304,15 @@ class SelectComponent extends Component<IProps> {
282 } 304 }
283 } 305 }
284 306
285 switch (e.keyCode){ 307 switch (e.keyCode) {
286 case 37: case 39: case 38: case 40: // Arrow keys 308 case 37:
287 case 32: break; // Space 309 case 39:
288 default: break; // do not block other keys 310 case 38:
311 case 40: // Arrow keys
312 case 32:
313 break; // Space
314 default:
315 break; // do not block other keys
289 } 316 }
290 } 317 }
291 318
@@ -307,13 +334,7 @@ class SelectComponent extends Component<IProps> {
307 required, 334 required,
308 } = this.props; 335 } = this.props;
309 336
310 const { 337 const { open, needle, value, selected, options } = this.state;
311 open,
312 needle,
313 value,
314 selected,
315 options,
316 } = this.state;
317 338
318 let selection = ''; 339 let selection = '';
319 if (!value && defaultValue && options![defaultValue]) { 340 if (!value && defaultValue && options![defaultValue]) {
@@ -325,10 +346,7 @@ class SelectComponent extends Component<IProps> {
325 } 346 }
326 347
327 return ( 348 return (
328 <Wrapper 349 <Wrapper className={className} identifier="franz-select">
329 className={className}
330 identifier="franz-select"
331 >
332 <Label 350 <Label
333 title={label} 351 title={label}
334 showLabel={showLabel} 352 showLabel={showLabel}
@@ -345,14 +363,19 @@ class SelectComponent extends Component<IProps> {
345 > 363 >
346 <button 364 <button
347 type="button" 365 type="button"
348 className={classnames({ 366 className={classnames({
349 [`${inputClassName}`]: inputClassName, 367 [`${inputClassName}`]: inputClassName,
350 [`${classes.select}`]: true, 368 [`${classes.select}`]: true,
351 [`${classes.hasError}`]: error, 369 [`${classes.hasError}`]: error,
352 })} 370 })}
353 onClick= {!disabled ? () => this.setState((state: IState) => ({ 371 onClick={
354 open: !state.open, 372 !disabled
355 })) : () => {}} 373 ? () =>
374 this.setState((state: IState) => ({
375 open: !state.open,
376 }))
377 : () => {}
378 }
356 > 379 >
357 {selection} 380 {selection}
358 <Icon 381 <Icon
@@ -366,10 +389,7 @@ class SelectComponent extends Component<IProps> {
366 </button> 389 </button>
367 {showSearch && open && ( 390 {showSearch && open && (
368 <div className={classes.searchContainer}> 391 <div className={classes.searchContainer}>
369 <Icon 392 <Icon path={mdiMagnify} size={0.8} />
370 path={mdiMagnify}
371 size={0.8}
372 />
373 <input 393 <input
374 type="text" 394 type="text"
375 value={needle} 395 value={needle}
@@ -384,10 +404,7 @@ class SelectComponent extends Component<IProps> {
384 className={classes.clearNeedle} 404 className={classes.clearNeedle}
385 onClick={() => this.setFilter()} 405 onClick={() => this.setFilter()}
386 > 406 >
387 <Icon 407 <Icon path={mdiCloseCircle} size={0.7} />
388 path={mdiCloseCircle}
389 size={0.7}
390 />
391 </button> 408 </button>
392 )} 409 )}
393 </div> 410 </div>
@@ -399,7 +416,7 @@ class SelectComponent extends Component<IProps> {
399 })} 416 })}
400 ref={this.scrollContainerRef} 417 ref={this.scrollContainerRef}
401 > 418 >
402 {Object.keys(options!).map(((key, i) => ( 419 {Object.keys(options!).map((key, i) => (
403 <div 420 <div
404 key={key} 421 key={key}
405 onClick={() => this.select(key)} 422 onClick={() => this.select(key)}
@@ -413,7 +430,7 @@ class SelectComponent extends Component<IProps> {
413 > 430 >
414 {options![key]} 431 {options![key]}
415 </div> 432 </div>
416 )))} 433 ))}
417 </div> 434 </div>
418 </div> 435 </div>
419 <input 436 <input
@@ -427,9 +444,7 @@ class SelectComponent extends Component<IProps> {
427 ref={this.inputRef} 444 ref={this.inputRef}
428 /> 445 />
429 </Label> 446 </Label>
430 {error && ( 447 {error && <Error message={error} />}
431 <Error message={error} />
432 )}
433 </Wrapper> 448 </Wrapper>
434 ); 449 );
435 } 450 }