Skip to content

Commit bca683f

Browse files
Merge branch 'master' into fix/spacebar-enable-opened
2 parents f366628 + 2cc7ab3 commit bca683f

File tree

4 files changed

+104
-3
lines changed

4 files changed

+104
-3
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@rc-component/select",
3-
"version": "1.6.5",
3+
"version": "1.6.10",
44
"description": "React Select",
55
"engines": {
66
"node": ">=8.x"

src/BaseSelect/index.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,8 +468,15 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
468468
const isEnterKey = key === 'Enter';
469469
const isSpaceKey = key === ' ';
470470

471-
471+
// Enter or Space opens dropdown (ARIA combobox: spacebar should open)
472472
if (isEnterKey || isSpaceKey) {
473+
// Do not submit form when type in the input; prevent Space from scrolling page
474+
const isCombobox = mode === 'combobox';
475+
const isEditable = isCombobox || showSearch;
476+
if ((isSpaceKey && !isEditable) || (isEnterKey && !isCombobox)) {
477+
event.preventDefault();
478+
}
479+
473480
// We only manage open state here, close logic should handle by list component
474481
if (!mergedOpen) {
475482
// Do not submit form when type in the input

src/SelectInput/Content/SingleContent.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ const SingleContent = React.forwardRef<HTMLInputElement, SharedContentProps>(
6363
}, [combobox, activeValue]);
6464

6565
// ========================== Render ==========================
66+
const showHasValueCls =
67+
displayValue &&
68+
displayValue.label !== null &&
69+
displayValue.label !== undefined &&
70+
String(displayValue.label).trim() !== '';
71+
6672
// Render value
6773
const renderValue = displayValue ? (
6874
hasOptionStyle ? (
@@ -88,7 +94,7 @@ const SingleContent = React.forwardRef<HTMLInputElement, SharedContentProps>(
8894
<div
8995
className={clsx(
9096
`${prefixCls}-content`,
91-
displayValue && `${prefixCls}-content-has-value`,
97+
showHasValueCls && `${prefixCls}-content-has-value`,
9298
mergedSearchValue && `${prefixCls}-content-has-search-value`,
9399
hasOptionStyle && `${prefixCls}-content-has-option-style`,
94100
classNames?.content,

tests/Select.test.tsx

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,34 @@ describe('Select.Basic', () => {
273273
expect(container.querySelector('.rc-select-content-has-option-style')).toBeTruthy();
274274
});
275275

276+
it('should not add -content-has-value className when value is empty string', () => {
277+
const { container } = render(
278+
<Select value="">
279+
<Option value="1">One</Option>
280+
</Select>,
281+
);
282+
expect(container.querySelector('.rc-select-content-has-value')).toBeFalsy();
283+
});
284+
285+
it('should add -content-has-value className when value is number 0', () => {
286+
const { container } = render(
287+
<Select value={0}>
288+
<Option value={0}>0</Option>
289+
<Option value={1}>1</Option>
290+
</Select>,
291+
);
292+
expect(container.querySelector('.rc-select-content-has-value')).toBeTruthy();
293+
});
294+
295+
it('should not add -content-has-value className when value is whitespace string', () => {
296+
const { container } = render(
297+
<Select value=" ">
298+
<Option value="1">One</Option>
299+
</Select>,
300+
);
301+
expect(container.querySelector('.rc-select-content-has-value')).toBeFalsy();
302+
});
303+
276304
it('should default select the right option', () => {
277305
const { container } = render(
278306
<Select defaultValue="2">
@@ -2957,4 +2985,64 @@ describe('Select.Basic', () => {
29572985

29582986
expect(selectedItem).not.toHaveAttribute('xxx');
29592987
});
2988+
2989+
describe('Space key behavior with showSearch', () => {
2990+
it('should not call preventDefault on space when showSearch is enabled', () => {
2991+
const { container } = render(
2992+
<Select showSearch options={[{ value: 'test', label: 'test' }]} />,
2993+
);
2994+
2995+
const input = container.querySelector('input');
2996+
input.focus();
2997+
2998+
const keyDownEvent = new KeyboardEvent('keydown', {
2999+
key: ' ',
3000+
code: 'Space',
3001+
bubbles: true,
3002+
});
3003+
const preventDefaultSpy = jest.spyOn(keyDownEvent, 'preventDefault');
3004+
3005+
input.dispatchEvent(keyDownEvent);
3006+
3007+
expect(preventDefaultSpy).not.toHaveBeenCalled();
3008+
});
3009+
3010+
it('should call preventDefault on space when showSearch is disabled', () => {
3011+
const { container } = render(<Select options={[{ value: 'test', label: 'test' }]} />);
3012+
3013+
const input = container.querySelector('input');
3014+
input.focus();
3015+
3016+
const keyDownEvent = new KeyboardEvent('keydown', {
3017+
key: ' ',
3018+
code: 'Space',
3019+
bubbles: true,
3020+
});
3021+
const preventDefaultSpy = jest.spyOn(keyDownEvent, 'preventDefault');
3022+
3023+
input.dispatchEvent(keyDownEvent);
3024+
3025+
expect(preventDefaultSpy).toHaveBeenCalled();
3026+
});
3027+
3028+
it('should not call preventDefault on space in combobox mode', () => {
3029+
const { container } = render(
3030+
<Select mode="combobox" options={[{ value: 'test', label: 'test' }]} />,
3031+
);
3032+
3033+
const input = container.querySelector('input');
3034+
input.focus();
3035+
3036+
const keyDownEvent = new KeyboardEvent('keydown', {
3037+
key: ' ',
3038+
code: 'Space',
3039+
bubbles: true,
3040+
});
3041+
const preventDefaultSpy = jest.spyOn(keyDownEvent, 'preventDefault');
3042+
3043+
input.dispatchEvent(keyDownEvent);
3044+
3045+
expect(preventDefaultSpy).not.toHaveBeenCalled();
3046+
});
3047+
});
29603048
});

0 commit comments

Comments
 (0)