Skip to content
5 changes: 3 additions & 2 deletions packages/gamut/src/Form/SelectDropdown/SelectDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export const SelectDropdown: React.FC<SelectDropdownProps> = ({
shownOptionsLimit = 6,
size,
value,
zIndex,
...rest
}) => {
const rawInputId = useId();
Expand Down Expand Up @@ -243,8 +244,8 @@ export const SelectDropdown: React.FC<SelectDropdownProps> = ({

const theme = useTheme();
const memoizedStyles = useMemo((): StylesConfig<any, false> => {
return getMemoizedStyles(theme);
}, [theme]);
return getMemoizedStyles(theme, zIndex);
}, [theme, zIndex]);

return (
<SelectDropdownContext.Provider
Expand Down
24 changes: 13 additions & 11 deletions packages/gamut/src/Form/SelectDropdown/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,16 @@ const dropdownBorderStates = states({
error: { borderColorTop: 'feedback-error' },
});

const dropdownBorderStyles = css({
...formBaseComponentStyles,
border: 1,
borderColor: 'currentColor',
position: 'absolute',
marginTop: 0,
borderRadius: 'none',
zIndex: 2,
});
const dropdownBorderStyles = (zIndex = 2) =>
css({
...formBaseComponentStyles,
border: 1,
borderColor: 'currentColor',
position: 'absolute',
marginTop: 0,
borderRadius: 'none',
zIndex,
});

const getOptionBackground = (isSelected: boolean, isFocused: boolean) =>
css({
Expand All @@ -89,7 +90,8 @@ const placeholderColor = css({
});

export const getMemoizedStyles = (
theme: typeof GamutTheme
theme: typeof GamutTheme,
zIndex?: number
): StylesConfig<any, false> => {
return {
clearIndicator: (provided) => ({
Expand Down Expand Up @@ -146,7 +148,7 @@ export const getMemoizedStyles = (

return {
...provided,
...dropdownBorderStyles({ theme }),
...dropdownBorderStyles(zIndex)({ theme }),
...dropdownBorderStates({ error: state.selectProps.error, theme }),
...(dropdownWidth
? {
Expand Down
2 changes: 2 additions & 0 deletions packages/gamut/src/Form/SelectDropdown/types/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export interface SharedProps extends InternalInputsProps, SelectDropdownSizes {
* This is only relevant when the dropdown width is set to be larger or smaller than the input width.
*/
menuAlignment?: 'left' | 'right';
/** Z-index for the dropdown menu */
zIndex?: number;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export const parameters = {
};

<Meta of={SelectDropdownStories} />

<ComponentHeader {...parameters} />

## Usage
Expand Down Expand Up @@ -199,6 +198,14 @@ When using different widths for the input and dropdown, you can control how the

<Canvas of={SelectDropdownStories.MenuAlignmentRight} />

### Selectdropdown options menu z-index

You can control the z-index of the dropdown menu using the `zIndex` prop. This is useful when you have other elements on the page that might overlap with the dropdown.

In the example below, the z-index menu is configured to the default value (`auto`) and `5` respectively. The DataTable below the `SelectDropdown` has a z-index of `2` since it's sticky and intended to float above other content.

<Canvas of={SelectDropdownStories.zIndexOnMenu} />

## Multiple select

<Canvas of={SelectDropdownStories.MultipleSelect} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { Box, FlexBox, FormGroup, SelectDropdown } from '@codecademy/gamut';
import {
Box,
DataList,
FlexBox,
FormGroup,
SelectDropdown,
Text,
} from '@codecademy/gamut';
import { RadarIcon, ResponsiveIcon, RocketIcon } from '@codecademy/gamut-icons';
import type { Meta, StoryObj } from '@storybook/react';

Expand Down Expand Up @@ -995,3 +1002,64 @@ export const LongPlaceholderAgain: Story = {
</Box>
),
};

export const zIndexOnMenu: Story = {
render: (args) => (
<FlexBox column height="500px">
<Text mb={16}>Notice how the menu renders based on using zIndex</Text>
<FlexBox gap={16}>
<FormGroup
htmlFor="usesDefaultZIndex"
isSoloField
label="This menu is rendered behind the header"
>
<SelectDropdown
name="usesDefaultZIndex"
options={args.options}
placeholder="Uses the default zIndex of 2"
/>
</FormGroup>
<FormGroup
htmlFor="hasSetZIndex"
isSoloField
label="This menu floats above the table's header"
>
<SelectDropdown
name="hasSetZIndex"
options={args.options}
placeholder="Has a zIndex of 5"
zIndex={5}
/>
</FormGroup>
</FlexBox>
<DataList
columns={[
{
header: 'Name',
key: 'name',
size: 'lg',
type: 'header',
sortable: true,
},
{ header: 'Rank', key: 'role', size: 'lg', sortable: true },
{ header: 'Ship', key: 'ship', size: 'lg', sortable: true },
]}
disableContainerQuery
id="crew"
idKey="name"
rows={[
{
name: 'Jean Luc Picard',
role: 'Captain',
ship: 'USS Enterprise',
},
{
name: 'Wesley Crusher',
role: 'Deus Ex Machina',
ship: 'USS Enterprise',
},
]}
/>
</FlexBox>
),
};
Loading