diff --git a/examples/tags.tsx b/examples/tags.tsx
index 5e8d67af5..20368ce26 100644
--- a/examples/tags.tsx
+++ b/examples/tags.tsx
@@ -70,6 +70,34 @@ const Test: React.FC = () => {
toggle maxTagCount (null)
+ tags select with open = false
+
+
+
);
};
diff --git a/index.js b/index.js
deleted file mode 100644
index 3151c2a2a..000000000
--- a/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-'use strict';
-
-module.exports = require('./src/');
diff --git a/src/Selector/MultipleSelector.tsx b/src/Selector/MultipleSelector.tsx
index 7e0b6b29f..43eea3a6f 100644
--- a/src/Selector/MultipleSelector.tsx
+++ b/src/Selector/MultipleSelector.tsx
@@ -74,7 +74,7 @@ const SelectSelector: React.FC = props => {
}, []);
// ===================== Search ======================
- const inputValue = open ? searchValue : '';
+ const inputValue = open || mode === 'tags' ? searchValue : '';
const inputEditable: boolean = mode === 'tags' || (open && showSearch);
// We measure width and set to the input immediately
diff --git a/src/Selector/index.tsx b/src/Selector/index.tsx
index 698896de9..7dc36c7a5 100644
--- a/src/Selector/index.tsx
+++ b/src/Selector/index.tsx
@@ -78,6 +78,7 @@ export interface SelectorProps {
onToggleOpen: (open?: boolean) => void;
/** `onSearch` returns go next step boolean to check if need do toggle open */
onSearch: (searchText: string, fromTyping: boolean, isCompositing: boolean) => boolean;
+ onSearchSubmit: (searchText: string) => void;
onSelect: (value: RawValueType, option: { selected: boolean }) => void;
onInputKeyDown?: React.KeyboardEventHandler;
@@ -100,6 +101,7 @@ const Selector: React.RefForwardingComponent =
showSearch,
onSearch,
+ onSearchSubmit,
onToggleOpen,
onInputKeyDown,
@@ -130,6 +132,12 @@ const Selector: React.RefForwardingComponent =
onInputKeyDown(event);
}
+ if (which === KeyCode.ENTER && mode === 'tags' && !compositionStatusRef.current && !open) {
+ // When menu isn't open, OptionList won't trigger a value change
+ // So when enter is pressed, the tag's input value should be emitted here to let selector know
+ onSearchSubmit((event.target as HTMLInputElement).value);
+ }
+
if (![KeyCode.SHIFT, KeyCode.TAB, KeyCode.BACKSPACE, KeyCode.ESC].includes(which)) {
onToggleOpen(true);
}
diff --git a/src/generate.tsx b/src/generate.tsx
index 5336b1bfb..cf0631288 100644
--- a/src/generate.tsx
+++ b/src/generate.tsx
@@ -673,6 +673,18 @@ export default function generateSelector<
return ret;
};
+ // Only triggered when menu is closed & mode is tags
+ // If menu is open, OptionList will take charge
+ // If mode isn't tags, press enter is not meaningful when you can't see any option
+ const onSearchSubmit = (searchText: string) => {
+ const newRawValues = Array.from(new Set([...mergedRawValue, searchText]));
+ triggerChange(newRawValues);
+ newRawValues.forEach(newRawValue => {
+ triggerSelect(newRawValue, true, 'input');
+ });
+ setInnerSearchValue('');
+ };
+
// Close dropdown when disabled change
useEffect(() => {
if (innerOpen && !!disabled) {
@@ -1014,6 +1026,7 @@ export default function generateSelector<
searchValue={mergedSearchValue}
activeValue={activeValue}
onSearch={triggerSearch}
+ onSearchSubmit={onSearchSubmit}
onSelect={onInternalSelectionSelect}
/>
diff --git a/tests/Multiple.test.tsx b/tests/Multiple.test.tsx
index 10bdbbd3c..bcb014495 100644
--- a/tests/Multiple.test.tsx
+++ b/tests/Multiple.test.tsx
@@ -79,7 +79,49 @@ describe('Select.Multiple', () => {
expectOpen(wrapper, false);
});
- it(`shouldn't separate words when compositing`, () => {
+ it('tokenize input when mode=tags and open=false', () => {
+ const handleChange = jest.fn();
+ const handleSelect = jest.fn();
+ const wrapper = mount(
+ ,
+ );
+
+ wrapper.find('input').simulate('change', {
+ target: {
+ value: 'One',
+ },
+ });
+ expect(handleChange).not.toHaveBeenCalled();
+
+ handleChange.mockReset();
+ wrapper.find('input').simulate('change', {
+ target: {
+ value: 'One,Two,Three,',
+ },
+ });
+ expect(handleChange).toHaveBeenCalledWith(['One', 'Two', 'Three'], expect.anything());
+
+ handleChange.mockReset();
+ wrapper.find('input').simulate('change', {
+ target: {
+ value: 'One,Two,',
+ },
+ });
+ expect(handleChange).toHaveBeenCalledWith(['One', 'Two', 'Three'], expect.anything());
+
+ expect(wrapper.find('input').props().value).toBe('');
+ });
+
+ it('shouldn\'t separate words when compositing', () => {
const handleChange = jest.fn();
const handleSelect = jest.fn();
const wrapper = mount(
diff --git a/tests/Tags.test.tsx b/tests/Tags.test.tsx
index fea2d30af..b016e1fd4 100644
--- a/tests/Tags.test.tsx
+++ b/tests/Tags.test.tsx
@@ -73,8 +73,6 @@ describe('Select.Tags', () => {
,
);
- (wrapper.find('input').instance() as any).focus = jest.fn();
-
wrapper.find('input').simulate('change', { target: { value: '2,3,4' } });
expect(handleChange).toHaveBeenCalledWith(['2', '3', '4'], expect.anything());
@@ -90,15 +88,13 @@ describe('Select.Tags', () => {
it("shounld't separate words when compositing", () => {
const handleChange = jest.fn();
const handleSelect = jest.fn();
- const option2 = ;
const wrapper = mount(
,
);
- (wrapper.find('input').instance() as any).focus = jest.fn();
wrapper.find('input').simulate('compositionstart');
wrapper.find('input').simulate('change', { target: { value: '2,3,4' } });
expect(handleChange).not.toHaveBeenCalled();
@@ -115,6 +111,35 @@ describe('Select.Tags', () => {
expectOpen(wrapper, false);
});
+ it('should work when menu is closed', () => {
+ const handleChange = jest.fn();
+ const handleSelect = jest.fn();
+ const wrapper = mount(
+ ,
+ );
+ wrapper.find('input').simulate('compositionstart');
+ wrapper.find('input').simulate('change', { target: { value: 'Star Kirby' } });
+ wrapper.find('input').simulate('keydown', { which: KeyCode.ENTER });
+ expect(handleChange).not.toHaveBeenCalled();
+ handleChange.mockReset();
+ wrapper.find('input').simulate('compositionend');
+ wrapper.find('input').simulate('keydown', { which: KeyCode.ENTER });
+ expect(handleChange).toHaveBeenCalledWith(['Star Kirby'], expect.anything());
+ expect(handleSelect).toHaveBeenCalledTimes(1);
+ expect(findSelection(wrapper).text()).toEqual('Star Kirby');
+ expect(wrapper.find('input').props().value).toBe('');
+ expectOpen(wrapper, false);
+ });
+
it('paste content to split', () => {
const onChange = jest.fn();
const wrapper = mount(
@@ -221,8 +246,6 @@ describe('Select.Tags', () => {
};
const wrapper = mount();
- (wrapper.find('input').instance() as any).focus = jest.fn();
-
wrapper.find('input').simulate('change', { target: { value: '1,A,42' } });
expect(wrapper.find('span.A').length).toBe(1);