Skip to content

Commit a98c2a5

Browse files
authored
fix: Avoid need to document Select "gotcha" (#8579)
1 parent 2028b98 commit a98c2a5

File tree

7 files changed

+125
-36
lines changed

7 files changed

+125
-36
lines changed

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,14 @@ export function useHiddenSelect<T>(props: AriaHiddenSelectOptions, state: Select
7474
let data = selectData.get(state) || {};
7575
let {autoComplete, name = data.name, form = data.form, isDisabled = data.isDisabled} = props;
7676
let {validationBehavior, isRequired} = data;
77-
let {visuallyHiddenProps} = useVisuallyHidden();
77+
let {visuallyHiddenProps} = useVisuallyHidden({
78+
style: {
79+
// Prevent page scrolling.
80+
position: 'fixed',
81+
top: 0,
82+
left: 0
83+
}
84+
});
7885

7986
useFormReset(props.selectRef, state.defaultSelectedKey, state.setSelectedKey);
8087
useFormValidation({

packages/@react-spectrum/s2/src/Picker.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ export const Picker = /*#__PURE__*/ (forwardRef as forwardRefType)(function Pick
340340
aria-describedby={spinnerId}
341341
placeholder={placeholder}
342342
style={UNSAFE_style}
343-
className={UNSAFE_className + style({...field(), position: 'relative'}, getAllowedOverrides())({
343+
className={UNSAFE_className + style(field(), getAllowedOverrides())({
344344
isInForm: !!formContext,
345345
labelPosition,
346346
size

packages/react-aria-components/docs/Select.mdx

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ import {ChevronDown} from 'lucide-react';
8686

8787
.react-aria-Select {
8888
color: var(--text-color);
89-
position: relative;
9089
max-width: 250px;
9190
width: fit-content;
9291

@@ -1334,27 +1333,3 @@ it('Select can select an option via keyboard', async function () {
13341333
```
13351334

13361335
<ClassAPI links={selectUtil.links} class={selectUtil.exports.SelectTester} />
1337-
1338-
## Gotchas
1339-
1340-
`Select` requires a `position: relative` either on itself or on a close parent. This is because
1341-
the `Popover` component uses a hidden input to manage native form functionality. The hidden input
1342-
is absolutely positioned and can spill out unexpectedly if the parent is not positioned relative
1343-
causing unintended scroll bars to appear.
1344-
1345-
Note: you do not need to set the style inline, you can use any CSS method to do it.
1346-
1347-
```tsx render=false
1348-
<Select style={{position: 'relative'}}>
1349-
<Label>Favorite Animal</Label>
1350-
<Button>
1351-
<SelectValue />
1352-
<span aria-hidden="true"><ChevronDown size={16} /></span>
1353-
</Button>
1354-
<Popover>
1355-
<ListBox>
1356-
...
1357-
</ListBox>
1358-
</Popover>
1359-
</Select>
1360-
```

packages/react-aria-components/src/HiddenDateInput.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,14 @@ export function useHiddenDateInput(props: HiddenDateInputProps, state: DateField
5050
isDisabled,
5151
name
5252
} = props;
53-
let {visuallyHiddenProps} = useVisuallyHidden();
53+
let {visuallyHiddenProps} = useVisuallyHidden({
54+
style: {
55+
// Prevent page scrolling.
56+
position: 'fixed',
57+
top: 0,
58+
left: 0
59+
}
60+
});
5461

5562
let inputStep = 60;
5663
if (state.granularity === 'second') {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ export const AutocompleteMenuInPopoverDialogTrigger: MenuStory = {
838838
let manyItems = [...Array(100)].map((_, i) => ({id: i, name: `Item ${i}`}));
839839

840840
export const AutocompleteSelect = (): React.ReactElement => (
841-
<Select style={{marginBottom: 40, position: 'relative'}}>
841+
<Select style={{marginBottom: 40}}>
842842
<Label style={{display: 'block'}}>Test</Label>
843843
<Button>
844844
<SelectValue />

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export const FormAutoFillExample: FormStory = () => {
4848
<Label>Zip</Label>
4949
<Input name="city" type="text" id="city" autoComplete="shipping postal-code" />
5050
</TextField>
51-
<Select style={{position: 'relative'}} name="country" id="country" autoComplete="shipping country">
51+
<Select name="country" id="country" autoComplete="shipping country">
5252
<Label>Country</Label>
5353
<Button>
5454
<SelectValue />

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

Lines changed: 106 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export default {
3333
export type SelectStory = StoryFn<typeof Select>;
3434

3535
export const SelectExample: SelectStory = () => (
36-
<Select data-testid="select-example" id="select-example-id" style={{position: 'relative'}}>
36+
<Select data-testid="select-example" id="select-example-id">
3737
<Label style={{display: 'block'}}>Test</Label>
3838
<Button>
3939
<SelectValue />
@@ -54,7 +54,7 @@ export const SelectExample: SelectStory = () => (
5454
);
5555

5656
export const SelectRenderProps: SelectStory = () => (
57-
<Select data-testid="select-render-props" style={{position: 'relative'}}>
57+
<Select data-testid="select-render-props">
5858
{({isOpen}) => (
5959
<>
6060
<Label style={{display: 'block'}}>Test</Label>
@@ -144,7 +144,7 @@ const usStateOptions = [
144144
];
145145

146146
export const SelectManyItems: SelectStory = () => (
147-
<Select style={{position: 'relative'}}>
147+
<Select>
148148
<Label style={{display: 'block'}}>Test</Label>
149149
<Button>
150150
<SelectValue />
@@ -162,7 +162,7 @@ export const SelectManyItems: SelectStory = () => (
162162
);
163163

164164
export const VirtualizedSelect: SelectStory = () => (
165-
<Select style={{position: 'relative'}}>
165+
<Select>
166166
<Label style={{display: 'block'}}>Test</Label>
167167
<Button>
168168
<SelectValue />
@@ -215,9 +215,9 @@ function AsyncVirtualizedCollectionRenderSelectRender(args: {delay: number}): JS
215215
});
216216

217217
return (
218-
<Select style={{position: 'relative'}}>
218+
<Select>
219219
<Label style={{display: 'block'}}>Async Virtualized Collection render Select</Label>
220-
<Button style={{position: 'relative'}}>
220+
<Button>
221221
<SelectValue />
222222
{list.isLoading && <LoadingSpinner style={{right: '20px', left: 'unset', top: '0px', height: '100%', width: 20}} />}
223223
<span aria-hidden="true" style={{paddingLeft: 25}}></span>
@@ -312,3 +312,103 @@ export const RequiredSelectWithManyItems = (props) => (
312312
<Button type="submit">Submit</Button>
313313
</form>
314314
);
315+
316+
export const SelectScrollBug = () => {
317+
return (
318+
<div style={{display: 'flex', flexDirection: 'row', height: '100vh'}}>
319+
<div style={{flex: 3}}>
320+
Scrolling here should do nothing.
321+
</div>
322+
323+
<div style={{flex: 1, overflowY: 'auto'}}>
324+
Scrolling here should scroll the right side.
325+
<br />
326+
<br />
327+
<br />
328+
<br />
329+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Error
330+
voluptatibus esse qui enim neque aliquam facere velit ipsa non,
331+
voluptates aperiam odit minima dolorum harum! Facere eligendi officia
332+
ipsam mollitia!
333+
<br />
334+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Error
335+
voluptatibus esse qui enim neque aliquam facere velit ipsa non,
336+
voluptates aperiam odit minima dolorum harum! Facere eligendi officia
337+
ipsam mollitia!
338+
<br />
339+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Error
340+
voluptatibus esse qui enim neque aliquam facere velit ipsa non,
341+
voluptates aperiam odit minima dolorum harum! Facere eligendi officia
342+
ipsam mollitia!
343+
<br />
344+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Error
345+
voluptatibus esse qui enim neque aliquam facere velit ipsa non,
346+
voluptates aperiam odit minima dolorum harum! Facere eligendi officia
347+
ipsam mollitia!
348+
<br />
349+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Error
350+
voluptatibus esse qui enim neque aliquam facere velit ipsa non,
351+
voluptates aperiam odit minima dolorum harum! Facere eligendi officia
352+
ipsam mollitia!
353+
<br />
354+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Error
355+
voluptatibus esse qui enim neque aliquam facere velit ipsa non,
356+
voluptates aperiam odit minima dolorum harum! Facere eligendi officia
357+
ipsam mollitia!
358+
<br />
359+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Error
360+
voluptatibus esse qui enim neque aliquam facere velit ipsa non,
361+
voluptates aperiam odit minima dolorum harum! Facere eligendi officia
362+
ipsam mollitia!
363+
<br />
364+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Error
365+
voluptatibus esse qui enim neque aliquam facere velit ipsa non,
366+
voluptates aperiam odit minima dolorum harum! Facere eligendi officia
367+
ipsam mollitia!
368+
<br />
369+
<br />
370+
<br />
371+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Error
372+
voluptatibus esse qui enim neque aliquam facere velit ipsa non,
373+
voluptates aperiam odit minima dolorum harum! Facere eligendi officia
374+
ipsam mollitia!
375+
<br />
376+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Error
377+
voluptatibus esse qui enim neque aliquam facere velit ipsa non,
378+
voluptates aperiam odit minima dolorum harum! Facere eligendi officia
379+
ipsam mollitia!
380+
<br />
381+
<br />
382+
<br />
383+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Error
384+
voluptatibus esse qui enim neque aliquam facere velit ipsa non,
385+
voluptates aperiam odit minima dolorum harum! Facere eligendi officia
386+
ipsam mollitia!
387+
<br />
388+
<br />
389+
<br />
390+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Error
391+
voluptatibus esse qui enim neque aliquam facere velit ipsa non,
392+
voluptates aperiam odit minima dolorum harum! Facere eligendi officia
393+
ipsam mollitia!
394+
<br />
395+
<br />
396+
<br />
397+
<Select>
398+
<Label>Favorite Animal</Label>
399+
<Button>
400+
<SelectValue />
401+
<span aria-hidden="true"></span>
402+
</Button>
403+
<Popover>
404+
<ListBox>
405+
<MyListBoxItem>Cat</MyListBoxItem>
406+
<MyListBoxItem>Dog</MyListBoxItem>
407+
<MyListBoxItem>Kangaroo</MyListBoxItem>
408+
</ListBox>
409+
</Popover>
410+
</Select>
411+
</div>
412+
</div>
413+
);
414+
};

0 commit comments

Comments
 (0)