Skip to content

Commit 8f2dc84

Browse files
committed
fix: only block form submission if the validation behavior is native
1 parent 62cdb87 commit 8f2dc84

File tree

2 files changed

+32
-16
lines changed

2 files changed

+32
-16
lines changed

packages/@react-aria/select/src/HiddenSelect.tsx

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*/
1212

1313
import {FocusableElement, RefObject} from '@react-types/shared';
14-
import React, {JSX, ReactNode, useRef} from 'react';
14+
import React, {InputHTMLAttributes, JSX, ReactNode, useRef} from 'react';
1515
import {selectData} from './useSelect';
1616
import {SelectState} from '@react-stately/select';
1717
import {useFormReset} from '@react-aria/utils';
@@ -142,19 +142,29 @@ export function HiddenSelect<T>(props: HiddenSelectProps<T>): JSX.Element | null
142142
);
143143
} else if (name) {
144144
let data = selectData.get(state) || {};
145-
// Use a hidden <input type="text"> rather than <input type="hidden">
146-
// so that an empty value blocks HTML form submission when the field is required.
145+
let {validationBehavior} = data;
146+
147+
let inputProps: InputHTMLAttributes<HTMLInputElement> = {
148+
type: 'hidden',
149+
autoComplete: selectProps.autoComplete,
150+
name,
151+
disabled: isDisabled,
152+
value: state.selectedKey ?? ''
153+
};
154+
155+
if (validationBehavior === "native") {
156+
// Use a hidden <input type="text"> rather than <input type="hidden">
157+
// so that an empty value blocks HTML form submission when the field is required.
158+
inputProps.type = 'text';
159+
inputProps.hidden = true;
160+
inputProps.required = selectProps.required;
161+
// Ignore react warning.
162+
inputProps.onChange = () => {};
163+
}
164+
147165
return (
148-
<input
149-
type="text"
150-
autoComplete={selectProps.autoComplete}
151-
name={name}
152-
disabled={isDisabled}
153-
value={state.selectedKey ?? ''}
154-
onChange={() => {/** Ignore react warning. */}}
155-
required={data.isRequired}
156-
hidden />
157-
);
166+
<input {...inputProps} />
167+
)
158168
}
159169

160170
return null;

packages/react-aria-components/stories/Select.stories.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@ import {UNSTABLE_ListBoxLoadingSentinel} from '../src/ListBox';
1818
import {useAsyncList} from 'react-stately';
1919

2020
export default {
21-
title: 'React Aria Components'
21+
title: 'React Aria Components',
22+
argTypes: {
23+
validationBehavior: {
24+
control: 'select',
25+
options: ['native', 'aria']
26+
}
27+
}
2228
};
2329

2430
export const SelectExample = () => (
@@ -183,9 +189,9 @@ AsyncVirtualizedCollectionRenderSelect.story = {
183189
// Required select validation cannot currently be tested in the jsdom environment.
184190
// In jsdom, forms are submitted even when required fields are empty.
185191
// See: https://github.com/jsdom/jsdom/issues/2898
186-
export const RequiredSelectWithManyItems = () => (
192+
export const RequiredSelectWithManyItems = (props) => (
187193
<form>
188-
<Select name="select" isRequired>
194+
<Select {...props} name="select" isRequired>
189195
<Label style={{display: 'block'}}>Required Select with many items</Label>
190196
<Button>
191197
<SelectValue />

0 commit comments

Comments
 (0)