Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add floating ui to dropdown #16492

Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
ea5971a
feat: implement floating ui to dropdown
preetibansalui May 17, 2024
9d08d0c
feat: adds floatingStyles to dropdown & demo according example
2nikhiltom May 21, 2024
573b9db
fix: update snapShots
2nikhiltom May 21, 2024
9493f0c
feat: added demo example in DataTable
preetibansalui May 22, 2024
9f2e7a2
feat: added demo example in Modal popup
preetibansalui May 22, 2024
3443ca2
feat: added autoalign class in case autoalign is true
preetibansalui May 22, 2024
b6b372e
Merge branch 'main' into 15865-add-floatin-ui-to-dropdown
preetibansalui May 22, 2024
dae7420
fix: act issue in test cases
preetibansalui Jun 5, 2024
2e5d109
Merge branch 'main' into 15865-add-floatin-ui-to-dropdown
preetibansalui Jun 5, 2024
1e5f8e2
fix: test case fail in FluidDropdown
preetibansalui Jun 5, 2024
26ae290
fix: removed dropdown example from dataTable
preetibansalui Jun 5, 2024
4188d60
Merge branch 'main' into 15865-add-floatin-ui-to-dropdown
preetibansalui Jun 5, 2024
c21843b
fix: remove modal popup example
preetibansalui Jun 10, 2024
fc5e639
fix: remove modal popup example css
preetibansalui Jun 10, 2024
bae24bf
fix: remove modal popup example css
preetibansalui Jun 10, 2024
bbd3ff4
fix: removed example from Accordion
preetibansalui Jun 10, 2024
c9b8bd6
Merge branch 'main' into 15865-add-floatin-ui-to-dropdown
preetibansalui Jun 10, 2024
1f599f4
Merge branch 'main' into 15865-add-floatin-ui-to-dropdown
preetibansalui Jun 14, 2024
549b05b
fix: apply size and other changes as suggested by PR review
preetibansalui Jun 14, 2024
866e04b
Merge branch 'main' into 15865-add-floatin-ui-to-dropdown
tay1orjones Jun 20, 2024
f070c59
Merge branch 'main' into 15865-add-floatin-ui-to-dropdown
preetibansalui Jun 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2813,6 +2813,9 @@ Map {
"type": "string",
},
"ariaLabel": [Function],
"autoAlign": Object {
"type": "bool",
},
"className": Object {
"type": "string",
},
Expand Down
55 changes: 41 additions & 14 deletions packages/react/src/components/Accordion/Accordion.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Button from '../Button';
import ButtonSet from '../ButtonSet';
import mdx from './Accordion.mdx';
import { WithLayer } from '../../../.storybook/templates/WithLayer';
import Dropdown from '../Dropdown';

export default {
title: 'Components/Accordion',
Expand All @@ -33,23 +34,49 @@ export default {
},
};

const items = [
{
id: 'option-0',
text: 'Lorem, ipsum dolor sit amet consectetur adipisicing elit.',
},
{
id: 'option-1',
text: 'Option 1',
},
{
id: 'option-2',
text: 'Option 2',
},
{
id: 'option-3',
text: 'Option 3 - a disabled item',
disabled: true,
},
{
id: 'option-4',
text: 'Option 4',
},
{
id: 'option-5',
text: 'Option 5',
},
];

export const Default = () => (
<Accordion>
<AccordionItem title="Section 1 title">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat.
</p>
</AccordionItem>
<AccordionItem title="Section 1 title"></AccordionItem>
<AccordionItem title="Section 2 title">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat.
</p>
<Dropdown
autoAlign={true}
id="default"
titleText="Dropdown label"
helperText="This is some helper text"
initialSelectedItem={items[1]}
label="Option 1"
items={items}
itemToString={(item) => (item ? item.text : '')}
direction="top"
/>
</AccordionItem>
<AccordionItem title="Section 3 title">
<p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import React from 'react';
import Button from '../../Button';
import OverflowMenu from '../../OverflowMenu';
import OverflowMenuItem from '../../OverflowMenuItem';
import Dropdown from '../../Dropdown';
import {
default as DataTable,
TableContainer,
Expand Down Expand Up @@ -93,9 +94,49 @@ export const Default = () => (
<TableBody>
{rows.map((row) => (
<TableRow key={row.id} {...getRowProps({ row })}>
{row.cells.map((cell) => (
<TableCell key={cell.id}>{cell.value}</TableCell>
))}
{row.cells.map((cell) => {
return cell.id == 'b:port' ? (
<Dropdown
autoAlign={true}
id="default"
titleText="Dropdown label"
helperText="This is some helper text"
// initialSelectedItem={items[1]}
label="Option 1"
items={[
{
id: 'option-0',
text: 'Lorem, ipsum dolor sit amet consectetur adipisicing elit.',
},
{
id: 'option-1',
text: 'Option 1',
},
{
id: 'option-2',
text: 'Option 2',
},
{
id: 'option-3',
text: 'Option 3 - a disabled item',
disabled: true,
},
{
id: 'option-4',
text: 'Option 4',
},
{
id: 'option-5',
text: 'Option 5',
},
]}
itemToString={(item) => (item ? item.text : '')}
direction="top"
/>
) : (
<TableCell key={cell.id}>{cell.value}</TableCell>
);
})}
</TableRow>
))}
</TableBody>
Expand Down
32 changes: 21 additions & 11 deletions packages/react/src/components/Dropdown/Dropdown-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
openMenu,
generateItems,
generateGenericItem,
waitForPosition,
} from '../ListBox/test-helpers';
import Dropdown from '../Dropdown';
import DropdownSkeleton from '../Dropdown/Dropdown.Skeleton';
Expand All @@ -35,8 +36,9 @@ describe('Dropdown', () => {
};
});

it('should initially render with the menu not open', () => {
it('should initially render with the menu not open', async () => {
render(<Dropdown {...mockProps} />);
await waitForPosition();
assertMenuClosed();
});

Expand Down Expand Up @@ -65,7 +67,7 @@ describe('Dropdown', () => {
expect(itemToElement).toHaveBeenCalled();
});

it('should render selectedItem as an element', () => {
it('should render selectedItem as an element', async () => {
render(
<Dropdown
{...mockProps}
Expand All @@ -81,6 +83,7 @@ describe('Dropdown', () => {
)}
/>
);
await waitForPosition();
// custom element should be rendered for the selected item
expect(
// eslint-disable-next-line testing-library/no-node-access
Expand All @@ -92,24 +95,27 @@ describe('Dropdown', () => {
});

describe('title', () => {
it('renders a title', () => {
it('renders a title', async () => {
render(<Dropdown {...mockProps} titleText="Email Input" />);
await waitForPosition();
expect(screen.getByText('Email Input')).toBeInTheDocument();
});

it('has the expected classes', () => {
it('has the expected classes', async () => {
render(<Dropdown {...mockProps} titleText="Email Input" />);
await waitForPosition();
expect(screen.getByText('Email Input')).toHaveClass(`${prefix}--label`);
});
});

describe('helper', () => {
it('renders a helper', () => {
it('renders a helper', async () => {
render(<Dropdown helperText="Email Input" {...mockProps} />);
await waitForPosition();
expect(screen.getByText('Email Input')).toBeInTheDocument();
});

it('renders children as expected', () => {
it('renders children as expected', async () => {
render(
<Dropdown
helperText={
Expand All @@ -120,6 +126,7 @@ describe('Dropdown', () => {
{...mockProps}
/>
);
await waitForPosition();

expect(screen.getByRole('link')).toBeInTheDocument();
});
Expand All @@ -128,7 +135,6 @@ describe('Dropdown', () => {
it('should let the user select an option by clicking on the option node', async () => {
render(<Dropdown {...mockProps} />);
await openMenu();

await userEvent.click(screen.getByText('Item 0'));
expect(mockProps.onChange).toHaveBeenCalledTimes(1);
expect(mockProps.onChange).toHaveBeenCalledWith({
Expand Down Expand Up @@ -161,15 +167,16 @@ describe('Dropdown', () => {
});

describe('should display initially selected item found in `initialSelectedItem`', () => {
it('using an object type for the `initialSelectedItem` prop', () => {
it('using an object type for the `initialSelectedItem` prop', async () => {
render(
<Dropdown {...mockProps} initialSelectedItem={mockProps.items[0]} />
);
await waitForPosition();

expect(screen.getByText(mockProps.items[0].label)).toBeInTheDocument();
});

it('using a string type for the `initialSelectedItem` prop', () => {
it('using a string type for the `initialSelectedItem` prop', async () => {
// Replace the 'items' property in mockProps with a list of strings
mockProps = {
...mockProps,
Expand All @@ -179,20 +186,23 @@ describe('Dropdown', () => {
render(
<Dropdown {...mockProps} initialSelectedItem={mockProps.items[1]} />
);
await waitForPosition();

expect(screen.getByText(mockProps.items[1])).toBeInTheDocument();
});
});

describe('Component API', () => {
it('should accept a `ref` for the underlying button element', () => {
it('should accept a `ref` for the underlying button element', async () => {
const ref = React.createRef();
render(<Dropdown {...mockProps} ref={ref} />);
await waitForPosition();
expect(ref.current).toHaveAttribute('aria-haspopup', 'listbox');
});

it('should respect slug prop', () => {
it('should respect slug prop', async () => {
const { container } = render(<Dropdown {...mockProps} slug={<Slug />} />);
await waitForPosition();
expect(container.firstChild).toHaveClass(
`${prefix}--list-box__wrapper--slug`
);
Expand Down
18 changes: 18 additions & 0 deletions packages/react/src/components/Dropdown/Dropdown.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,24 @@ const items = [
},
];

export const ExperimentalAutoAlign = () => (
<div style={{ width: 400 }}>
<div style={{ height: 300 }}></div>
<Dropdown
autoAlign={true}
id="default"
titleText="Dropdown label"
helperText="This is some helper text"
initialSelectedItem={items[1]}
label="Option 1"
items={items}
itemToString={(item) => (item ? item.text : '')}
direction="top"
/>
<div style={{ height: 800 }}></div>
</div>
);

export const Playground = (args) => (
<div style={{ width: 400 }}>
<Dropdown
Expand Down
Loading
Loading