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(Overlay): Convert Overlay to CSS modules behind team feature flag #5310

Draft
wants to merge 25 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c269372
feat(Overlay): Convert Overlay to CSS modules behind team feature flag
francinelucca Nov 18, 2024
2b11e4c
Create nice-boxes-sell.md
francinelucca Nov 18, 2024
e9f3e29
fix(Overlay): types and format
francinelucca Nov 19, 2024
65c01bf
Merge branch 'francinelucca/4135-update-overlay-to-css-modules' of gi…
francinelucca Nov 19, 2024
4eb9e97
fix(Overlay): correct typos and add aria-label to dialog stories
francinelucca Nov 19, 2024
1ec3997
fix(Overlay): use sentence-case for aria-label in stories
francinelucca Nov 19, 2024
a1abf51
Update packages/react/src/Overlay/Overlay.module.css
francinelucca Nov 19, 2024
dceb73a
Merge branch 'main' into francinelucca/4135-update-overlay-to-css-mod…
francinelucca Nov 19, 2024
3dbdaa4
fix(Overlay): pull keyframes out of class definition
francinelucca Nov 19, 2024
c61f977
test(Overlay): skip story setup in e2e testing
francinelucca Nov 19, 2024
c71e160
Merge branch 'main' into francinelucca/4135-update-overlay-to-css-mod…
francinelucca Nov 25, 2024
a6c97b9
test(Overlay): re-add empty line
francinelucca Nov 25, 2024
4f5237e
test(vrt): update snapshots
francinelucca Nov 25, 2024
790c11f
Merge branch 'main' into francinelucca/4135-update-overlay-to-css-mod…
francinelucca Nov 26, 2024
7c8f8ea
fix(Overlay): separate concerns between BaseOverlay and Overlay
francinelucca Nov 27, 2024
aaa8a9c
Merge branch 'francinelucca/4135-update-overlay-to-css-modules' of gi…
francinelucca Nov 27, 2024
297e9f8
Merge branch 'main' into francinelucca/4135-update-overlay-to-css-mod…
francinelucca Nov 27, 2024
5779a79
test(vrt): update snapshots
francinelucca Nov 27, 2024
69a51a9
fix(Overlay): fix maxHeight maxWidth visual regression
francinelucca Nov 27, 2024
cbb1b3b
Merge branch 'francinelucca/4135-update-overlay-to-css-modules' of gi…
francinelucca Nov 27, 2024
4950b60
test(vrt): update snapshots
francinelucca Nov 27, 2024
7fa6584
Merge branch 'main' into francinelucca/4135-update-overlay-to-css-mod…
francinelucca Nov 27, 2024
34e6a66
Revert "test(vrt): update snapshots"
francinelucca Nov 27, 2024
6ac400b
Revert "test(vrt): update snapshots"
francinelucca Nov 27, 2024
3509dab
Revert "test(vrt): update snapshots"
francinelucca Nov 27, 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
5 changes: 5 additions & 0 deletions .changeset/nice-boxes-sell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": minor
---

feat(Overlay): Convert Overlay to CSS modules behind team feature flag
134 changes: 134 additions & 0 deletions e2e/components/Overlay.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import {test, expect, type Page} from '@playwright/test'
import {visit} from '../test-helpers/storybook'
import {themes} from '../test-helpers/themes'

const stories = [
{
title: 'Default',
id: 'private-components-overlay--default',
setup: async (page: Page) => {
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
},
},
{
title: 'Playground',
id: 'private-components-overlay-dev--sx-props',
setup: async (page: Page) => {
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
},
},
{
title: 'Dialog Overlay',
id: 'private-components-overlay-features--dialog-overlay',
setup: async (page: Page) => {
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
},
},
{
title: 'Dropdown Overlay',
id: 'private-components-overlay-features--dropdown-overlay',
setup: async (page: Page) => {
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
},
},
{
title: 'Memex Issue Overlay',
id: 'private-components-overlay-features--memex-issue-overlay',
setup: async (page: Page) => {
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
},
},
{
title: 'Memex Nested Overlays',
id: 'private-components-overlay-features--memex-nested-overlays',
setup: async (page: Page) => {
await page.keyboard.press('Tab')
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
},
},
{
title: 'Nested Overlays',
id: 'private-components-overlay-features--nested-overlays',
setup: async (page: Page) => {
await page.keyboard.press('Tab')
await page.keyboard.press('Tab')
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
await page.keyboard.press('Tab')
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
},
},
{
title: 'Overlay On Top Of Overlay',
id: 'private-components-overlay-features--overlay-on-top-of-overlay',
setup: async (page: Page) => {
await page.keyboard.press('Tab')
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
await page.keyboard.press('Enter')
await page.keyboard.press('Enter')
},
},
{
title: 'Positioned Overlays',
id: 'private-components-overlay-features--positioned-overlays',
setup: async (page: Page) => {
await page.keyboard.press('Tab')
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
},
},
{
title: 'SX Props',
id: 'private-components-overlay-dev--sx-props',
setup: async (page: Page) => {
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
},
},
] as const

test.describe('Overlay ', () => {
for (const story of stories) {
test.describe(story.title, () => {
for (const theme of themes) {
test.describe(theme, () => {
test('@vrt', async ({page}) => {
await visit(page, {
id: story.id,
globals: {
colorScheme: theme,
},
})

await story.setup(page)

// Default state
expect(await page.screenshot()).toMatchSnapshot(`Overlay.${story.title}.${theme}.png`)
})

test('axe @aat', async ({page}) => {
await visit(page, {
id: story.id,
globals: {
colorScheme: theme,
},
})
await story.setup(page)

await expect(page).toHaveNoViolations()
})
})
}
})
}
})
82 changes: 82 additions & 0 deletions packages/react/src/Overlay/Overlay.dev.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React, {useRef, useState} from 'react'
import type {Meta} from '@storybook/react'
import Text from '../Text'
import {Button, IconButton} from '../Button'
import Overlay from './Overlay'
import {useFocusTrap} from '../hooks/useFocusTrap'
import Box from '../Box'
import {XIcon} from '@primer/octicons-react'

export default {
title: 'Private/Components/Overlay/Dev',
component: Overlay,
} as Meta<typeof Overlay>

export const SxProps = () => {
const [isOpen, setIsOpen] = useState(false)
const buttonRef = useRef<HTMLButtonElement>(null)
const confirmButtonRef = useRef<HTMLButtonElement>(null)
const anchorRef = useRef<HTMLDivElement>(null)
const closeOverlay = () => setIsOpen(false)
const containerRef = useRef<HTMLDivElement>(null)
useFocusTrap({
containerRef,
disabled: !isOpen,
})
return (
<Box ref={anchorRef}>
<Button
ref={buttonRef}
onClick={() => {
setIsOpen(!isOpen)
}}
>
Open overlay
</Button>
{isOpen ? (
<Overlay
initialFocusRef={confirmButtonRef}
returnFocusRef={buttonRef}
ignoreClickRefs={[buttonRef]}
onEscape={closeOverlay}
onClickOutside={closeOverlay}
width="large"
anchorSide="inside-right"
role="dialog"
aria-modal="true"
aria-label="Sample overlay"
ref={containerRef}
sx={{
left: '50%',
mt: 2,
color: 'var(--bgColor-danger-muted)',
}}
style={{padding: '16px'}}
>
<Box
sx={{
height: '100vh',
maxWidth: 'calc(-1rem + 100vw)',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<IconButton
aria-label="Close"
onClick={closeOverlay}
icon={XIcon}
variant="invisible"
sx={{
position: 'absolute',
left: '5px',
top: '5px',
}}
/>
<Text>Look! an overlay</Text>
</Box>
</Overlay>
) : null}
</Box>
)
}
9 changes: 9 additions & 0 deletions packages/react/src/Overlay/Overlay.features.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export const DialogOverlay = ({anchorSide, role}: OverlayProps) => {
anchorSide={anchorSide}
role={role}
aria-modal={role === 'dialog' ? 'true' : undefined}
aria-label={role === 'list' ? 'Confirmation screen' : undefined}
ref={containerRef}
>
<Box display="flex" flexDirection="column" p={2}>
Expand Down Expand Up @@ -171,6 +172,7 @@ export const OverlayOnTopOfOverlay = ({anchorSide, role}: OverlayProps) => {
anchorSide={anchorSide}
role={role}
aria-modal={role === 'dialog' ? 'true' : undefined}
aria-label={role === 'list' ? 'Open overlay' : undefined}
ref={primaryContainer}
preventOverflow={false}
>
Expand All @@ -188,6 +190,7 @@ export const OverlayOnTopOfOverlay = ({anchorSide, role}: OverlayProps) => {
anchorSide={anchorSide}
role={role}
aria-modal={role === 'dialog' ? 'true' : undefined}
aria-label={role === 'list' ? 'Options' : undefined}
ref={secondaryContainer}
preventOverflow={false}
>
Expand Down Expand Up @@ -249,6 +252,7 @@ export const MemexNestedOverlays = ({role}: OverlayProps) => {
left={16}
role={role}
aria-modal={role === 'dialog' ? 'true' : undefined}
aria-label={role === 'list' ? 'Add iteration' : undefined}
ref={containerRef}
preventOverflow={false}
>
Expand Down Expand Up @@ -334,6 +338,7 @@ export const NestedOverlays = ({role}: OverlayProps) => {
ref={primaryContainer}
role={role}
aria-modal={role === 'dialog' ? 'true' : undefined}
aria-label={role === 'list' ? 'Sample list' : undefined}
>
<Box sx={{display: 'flex', flexDirection: 'column', py: 2}}>
<Box sx={{paddingX: 3, paddingY: 2}}>
Expand Down Expand Up @@ -375,6 +380,7 @@ export const NestedOverlays = ({role}: OverlayProps) => {
left={64}
role={role}
aria-modal={role === 'dialog' ? 'true' : undefined}
aria-label={role === 'list' ? 'Create a list' : undefined}
ref={secondaryContainer}
>
<Box as="form" sx={{display: 'flex', flexDirection: 'column', p: 3}}>
Expand Down Expand Up @@ -446,6 +452,7 @@ export const MemexIssueOverlay = ({role}: OverlayProps) => {
left="calc(100vw - 350px)"
role={role}
aria-modal={role === 'dialog' ? 'true' : undefined}
aria-label={role === 'list' ? 'Draft issue editor' : undefined}
ref={containerRef}
>
<Box sx={{p: 4, height: '100vh', width: '350px'}}>
Expand Down Expand Up @@ -559,6 +566,7 @@ export const PositionedOverlays = ({right, role}: OverlayProps) => {
anchorSide="inside-right"
role={role}
aria-modal={role === 'dialog' ? 'true' : undefined}
aria-label={role === 'list' ? 'Left aligned overlay' : undefined}
ref={containerRef}
>
<Box
Expand Down Expand Up @@ -603,6 +611,7 @@ export const PositionedOverlays = ({right, role}: OverlayProps) => {
position="fixed"
role={role}
aria-modal={role === 'dialog' ? 'true' : undefined}
aria-label={role === 'list' ? 'Right aligned overlay' : undefined}
ref={containerRef}
>
<Box
Expand Down
Loading
Loading