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(Popover): allow focus upon popover panel open #1782

Merged
merged 1 commit into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
29 changes: 29 additions & 0 deletions src/components/Popover/Popover.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import React from 'react';
import { Popover } from './Popover';
import type { PopoverProps } from './Popover';
import Button from '../Button';
import Hr from '../Hr';

export default {
title: 'Components/Popover',
Expand Down Expand Up @@ -147,3 +148,31 @@ export const LeftEnd: StoryObj<PopoverProps> = {
},
...Default,
};

export const FocusClickableElement: StoryObj<PopoverProps> = {
play: async ({ canvasElement }) => {
// We want to test visual regression for the Popover.Content as well as the button,
// but don't want the drawer open initally outside Chromatic.
if (isChromatic()) {
const canvas = within(canvasElement);
const filtersTrigger = await canvas.findByRole('button');
await userEvent.click(filtersTrigger);
}
},
render: (args) => {
return (
<Popover {...args}>
<Popover.Button as={Button} data-testid="popover-trigger-button">
Open Popover
</Popover.Button>
<Popover.Content data-testid="popover-content" focus>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may be missing something, why does the content need focus set?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

focus enables the behavior where it will focus on the element once the popover is generated

<div className="fpo m-2 p-6">
Popover Content goes here
<Hr />
<Button>Focus on me upon open</Button>
</div>
</Popover.Content>
</Popover>
);
},
};
24 changes: 12 additions & 12 deletions src/components/Popover/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const PopoverButton = (props: PopoverButtonProps) => {
return <HeadlessPopover.Button {...props} ref={setReferenceElement} />;
};

export type PopoverContentProps = {
export type PopoverContentProps = ExtractProps<typeof HeadlessPopover.Panel> & {
/**
* Custom classname for additional styles for the arrow.
*/
Expand All @@ -100,17 +100,17 @@ export type PopoverContentProps = {
*/
className?: string;
} & RenderProps<{
/**
* Render prop indicating popover open status.
*/
open: boolean;
/**
* Render prop that closes popover when called.
*/
close: (
focusableElement?: HTMLElement | React.RefObject<HTMLElement>,
) => void;
}>;
/**
* Render prop indicating popover open status.
*/
open: boolean;
/**
* Render prop that closes popover when called.
*/
close: (
focusableElement?: HTMLElement | React.RefObject<HTMLElement>,
) => void;
}>;

/**
* A floating container that can be resized to fit content inside
Expand Down
25 changes: 25 additions & 0 deletions src/components/Popover/__snapshots__/Popover.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,31 @@ exports[`<Popover /> Default story renders snapshot 1`] = `
</div>
`;

exports[`<Popover /> FocusClickableElement story renders snapshot 1`] = `
<div
data-headlessui-state="open"
>
<button
aria-controls="headlessui-popover-panel-:r23:"
aria-expanded="true"
class="clickable-style clickable-style--lg clickable-style--secondary clickable-style--brand button button--secondary"
data-headlessui-state="open"
data-testid="popover-trigger-button"
id="headlessui-popover-button-:r21:"
type="button"
>
Open Popover
</button>
<button
aria-hidden="true"
data-headlessui-focus-guard="true"
id="headlessui-focus-sentinel-:r22:"
style="position: fixed; top: 1px; left: 1px; width: 1px; height: 0px; padding: 0px; margin: -1px; overflow: hidden; clip: rect(0px, 0px, 0px, 0px); white-space: nowrap; border-width: 0px;"
type="button"
/>
</div>
`;

exports[`<Popover /> Left story renders snapshot 1`] = `
<div
data-headlessui-state="open"
Expand Down