Skip to content

Commit 789fdff

Browse files
committed
useImperativeHandle hook in Select.tsx component - add Dependency list passed as the third param to re-create the handle when one of them updates.
1 parent 98f53a5 commit 789fdff

File tree

7 files changed

+40
-41
lines changed

7 files changed

+40
-41
lines changed

__tests__/AutosizeInput.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { ThemeTestHOC } from './helpers';
22
import userEvent from '@testing-library/user-event';
33
import { render, fireEvent } from '@testing-library/react';
4+
import { AUTOSIZE_INPUT_CLS, AUTOSIZE_INPUT_TESTID } from '../src/constants';
45
import AutosizeInput, { AutosizeInputProps } from '../src/components/input/AutosizeInput';
5-
import { EMPTY_ARRAY, AUTOSIZE_INPUT_CLS, AUTOSIZE_INPUT_TESTID } from '../src/constants';
66

77
import type { RenderResult } from '@testing-library/react';
88

@@ -29,7 +29,7 @@ const createAutosizeInputProps = () => {
2929
onBlur: onBlurSpy,
3030
onFocus: onFocusSpy,
3131
onChange: onChangeSpy,
32-
selectedOption: EMPTY_ARRAY
32+
hasSelectedOptions: false
3333
};
3434

3535
return {

docs/asset-manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"files": {
3-
"main.js": "./main.eeb30b91.iframe.bundle.js",
3+
"main.js": "./main.5ac201dc.iframe.bundle.js",
44
"runtime~main.js": "./runtime~main.f398e60b.iframe.bundle.js",
55
"vendors~main.js": "./vendors~main.31a06b8d.iframe.bundle.js",
66
"vendors~main.js.map": "./vendors~main.31a06b8d.iframe.bundle.js.map",
@@ -10,6 +10,6 @@
1010
"entrypoints": [
1111
"runtime~main.f398e60b.iframe.bundle.js",
1212
"vendors~main.31a06b8d.iframe.bundle.js",
13-
"main.eeb30b91.iframe.bundle.js"
13+
"main.5ac201dc.iframe.bundle.js"
1414
]
1515
}

docs/iframe.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,4 @@
130130

131131

132132

133-
window['FRAMEWORK_OPTIONS'] = {"fastRefresh":true};</script><script src="runtime~main.f398e60b.iframe.bundle.js"></script><script src="vendors~main.31a06b8d.iframe.bundle.js"></script><script src="main.eeb30b91.iframe.bundle.js"></script></body></html>
133+
window['FRAMEWORK_OPTIONS'] = {"fastRefresh":true};</script><script src="runtime~main.f398e60b.iframe.bundle.js"></script><script src="vendors~main.31a06b8d.iframe.bundle.js"></script><script src="main.5ac201dc.iframe.bundle.js"></script></body></html>

docs/main.5ac201dc.iframe.bundle.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/main.eeb30b91.iframe.bundle.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/Select.tsx

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -417,39 +417,39 @@ const Select = forwardRef<SelectRef, SelectProps>((
417417
}
418418
}, [isMulti, closeMenuOnSelect, removeSelectedOption, blurInputOnSelect]);
419419

420+
const hasSelectedOptions = isArrayWithLength(selectedOption);
421+
420422
/**
421423
* useImperativeHandle.
422424
* Exposed API methods/properties available on a ref instance of this Select.tsx component.
425+
* Dependency list passed as the third param to re-create the handle when one of them updates.
423426
*/
424-
useImperativeHandle(ref, () => ({
425-
empty: !isArrayWithLength(selectedOption),
426-
menuOpen,
427-
blur: blurInput,
428-
focus: focusInput,
429-
clearValue: () => {
430-
if (selectOption.length)
427+
useImperativeHandle(
428+
ref,
429+
() => ({
430+
empty: !hasSelectedOptions,
431+
menuOpen: menuOpenRef.current,
432+
blur: blurInput,
433+
focus: focusInput,
434+
clearValue: () => {
431435
setSelectedOption(EMPTY_ARRAY);
432-
if (focusedOption.data)
433436
setFocusedOption(FOCUSED_OPTION_DEFAULT);
434-
},
435-
setValue: (option?: OptionData) => {
436-
const normalizedOptions = normalizeValue(
437-
option,
438-
getOptionValueFn,
439-
getOptionLabelFn
440-
);
441-
442-
setSelectedOption(normalizedOptions);
443-
},
444-
toggleMenu: (state?: boolean) => {
445-
if (state === true || (state === undefined && !menuOpen)) {
446-
!isFocused && focusInput();
447-
openMenuAndFocusOption(OptionIndexEnum.FIRST);
448-
} else {
449-
blurInput();
437+
},
438+
setValue: (option?: OptionData) => {
439+
const normalizedOptions = normalizeValue(option, getOptionValueFn, getOptionLabelFn);
440+
setSelectedOption(normalizedOptions);
441+
},
442+
toggleMenu: (state?: boolean) => {
443+
if (state === true || (state === undefined && !menuOpenRef.current)) {
444+
focusInput();
445+
openMenuAndFocusOption(OptionIndexEnum.FIRST);
446+
} else {
447+
blurInput();
448+
}
450449
}
451-
}
452-
}));
450+
}),
451+
[hasSelectedOptions, getOptionValueFn, getOptionLabelFn, openMenuAndFocusOption]
452+
);
453453

454454
/**
455455
* useMountEffect:
@@ -543,7 +543,7 @@ const Select = forwardRef<SelectRef, SelectProps>((
543543

544544
// Only Multiselect mode supports value focusing
545545
const focusValueOnArrowKey = (direction: ValueIndexEnum): void => {
546-
if (!isArrayWithLength(selectedOption)) return;
546+
if (!hasSelectedOptions) return;
547547

548548
let nextFocusedIdx = -1;
549549
const lastValueIdx = selectedOption.length - 1;
@@ -662,7 +662,7 @@ const Select = forwardRef<SelectRef, SelectProps>((
662662
setFocusedMultiValue(nexFocusedMultiValue);
663663
} else {
664664
if (!backspaceClearsValue) return;
665-
if (!isArrayWithLength(selectedOption)) break;
665+
if (!hasSelectedOptions) break;
666666

667667
if (isMulti && !renderMultiOptions) {
668668
const { value } = selectedOption[selectedOption.length - 1];
@@ -735,8 +735,8 @@ const Select = forwardRef<SelectRef, SelectProps>((
735735
}, []);
736736

737737
const renderMenu = !lazyLoadMenu || (lazyLoadMenu && menuOpen);
738+
const showClear = !!(isClearable && !isDisabled && hasSelectedOptions);
738739
const inputReadOnly = isDisabled || !isSearchable || !!focusedMultiValue;
739-
const showClear = !!(isClearable && !isDisabled && isArrayWithLength(selectedOption));
740740
const handleOnCaretMouseDownOrNoop = (!isDisabled && !openMenuOnClick) ? handleOnCaretMouseDown : undefined;
741741

742742
return (
@@ -779,7 +779,7 @@ const Select = forwardRef<SelectRef, SelectProps>((
779779
onFocus={handleOnInputFocus}
780780
onChange={handleOnInputChange}
781781
ariaLabelledBy={ariaLabelledBy}
782-
selectedOption={selectedOption}
782+
hasSelectedOptions={hasSelectedOptions}
783783
/>
784784
</ValueWrapper>
785785
<IndicatorIcons

src/components/input/AutosizeInput.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import React, { memo, useRef, useState, Fragment, forwardRef } from 'react';
22
import styled from 'styled-components';
33
import { useUpdateEffect } from '../../hooks';
4+
import { IS_MICROSOFT_BROWSER } from '../../utils';
45
import { AUTOSIZE_INPUT_ATTRS } from '../../constants';
5-
import { isArrayWithLength, IS_MICROSOFT_BROWSER } from '../../utils';
66

7-
import type { SelectedOption } from '../../types';
87
import type { Ref, FormEventHandler, FocusEventHandler } from 'react';
98

109
export type AutosizeInputProps = Readonly<{
@@ -14,7 +13,7 @@ export type AutosizeInputProps = Readonly<{
1413
inputValue: string;
1514
required?: boolean;
1615
ariaLabelledBy?: string;
17-
selectedOption: SelectedOption[];
16+
hasSelectedOptions: boolean;
1817
onBlur: FocusEventHandler<HTMLInputElement>;
1918
onFocus: FocusEventHandler<HTMLInputElement>;
2019
onChange: FormEventHandler<HTMLInputElement>;
@@ -73,13 +72,13 @@ const AutosizeInput = memo(
7372
ariaLabel,
7473
inputValue,
7574
ariaLabelledBy,
76-
selectedOption
75+
hasSelectedOptions
7776
},
7877
ref: Ref<HTMLInputElement>
7978
) => {
8079
const sizerRef = useRef<HTMLDivElement | null>(null);
8180
const [inputWidth, setInputWidth] = useState<number>(INPUT_MIN_WIDTH_PX);
82-
const isInvalid = !!required && !isArrayWithLength(selectedOption);
81+
const isInvalid = !!required && !hasSelectedOptions;
8382

8483
useUpdateEffect(() => {
8584
if (sizerRef.current) {

0 commit comments

Comments
 (0)