Skip to content

Commit

Permalink
chore(SelectPanel): Add dev stories and update vrt snapshots (#5322)
Browse files Browse the repository at this point in the history
* chore(SelectPanel): Add dev stories and update vrt snapshots

* Adds e2e tests for SelectPanel2

* test(vrt): update snapshots

* Add missing classname props and test

* test(vrt): update snapshots

* wait for thumbnails and fix aat tests

* test(vrt): update snapshots

* add missing label

* test(vrt): update snapshots

---------

Co-authored-by: hussam-i-am <[email protected]>
  • Loading branch information
hussam-i-am and hussam-i-am authored Nov 21, 2024
1 parent 84c3e62 commit 82c7923
Show file tree
Hide file tree
Showing 108 changed files with 296 additions and 38 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 22 additions & 4 deletions e2e/components/SelectPanel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ const scenarios = matrix({
id: 'components-selectpanel-examples--height-initial-with-underflowing-items-after-fetch',
name: 'Height Initial with Underflowing Items After Fetch',
},
{
id: 'components-selectpanel-dev--with-css',
name: 'With Css',
},
{
id: 'components-selectpanel-dev--with-sx',
name: 'With Sx',
},
{
id: 'components-selectpanel-dev--with-sx-and-css',
name: 'With Sx and Css',
},
],
})

Expand All @@ -50,8 +62,11 @@ test.describe('SelectPanel', () => {
await visit(page, {id: scenario.story.id, globals})

// Open select panel
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
const isPanelOpen = await page.isVisible('[role="listbox"]')
if (!isPanelOpen) {
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
}
expect(await page.screenshot({animations: 'disabled'})).toMatchSnapshot(`SelectPanel.${name}.${theme}${flag}.png`)
})

Expand All @@ -68,8 +83,11 @@ test.describe('SelectPanel', () => {
})

// Open select panel
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
const isPanelOpen = await page.isVisible('[role="listbox"]')
if (!isPanelOpen) {
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
}

// windows high contrast mode: light
await page.emulateMedia({forcedColors: 'active', colorScheme: 'light'})
Expand Down
95 changes: 69 additions & 26 deletions e2e/components/drafts/SelectPanel.test.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,80 @@
import {test, expect} from '@playwright/test'
import {visit} from '../../test-helpers/storybook'
import {themes} from '../../test-helpers/themes'
import {waitForImages} from '../../test-helpers/waitForImages'

const stories: Array<{
title: string
id: string
buttonText?: string
}> = [
{
title: 'Default',
id: 'experimental-components-selectpanel--default',
},
{
id: 'experimental-components-selectpanel-features--as-modal',
title: 'As Modal',
},
{
id: 'experimental-components-selectpanel-features--external-anchor',
title: 'External Anchor',
},
{
id: 'experimental-components-selectpanel-features--instant-selection-variant',
title: 'Instant Selection Variant',
buttonText: 'Choose a tag',
},
{
id: 'experimental-components-selectpanel-features--with-warning',
title: 'With Warning',
buttonText: 'Assignees',
},
{
id: 'experimental-components-selectpanel-features--with-errors',
title: 'With Errors',
buttonText: 'Assignees',
},
] as const

test.describe('SelectPanel', () => {
test.describe('Default', () => {
for (const theme of themes) {
test.describe(theme, () => {
test('default @vrt', async ({page}) => {
await visit(page, {
id: 'experimental-components-selectpanel--default',
globals: {
colorScheme: theme,
},
for (const story of stories) {
test.describe(story.title, () => {
for (const theme of themes) {
test.describe(theme, () => {
test('default @vrt', async ({page}) => {
await visit(page, {
id: story.id,
globals: {
colorScheme: theme,
},
})

// Default state
const buttonText = story.buttonText || 'Assign label'
await page.getByText(buttonText).click()
await waitForImages(page)
expect(await page.screenshot({animations: 'disabled'})).toMatchSnapshot(
`drafts.SelectPanel.${story.title}.${theme}.png`,
)
})

// Default state
await page.getByText('Assign label').click()
expect(await page.screenshot({animations: 'disabled'})).toMatchSnapshot(
`drafts.SelectPanel.Default.${theme}.png`,
)
})
test('axe @aat', async ({page}) => {
await visit(page, {
id: story.id,
globals: {
colorScheme: theme,
},
})

test('axe @aat', async ({page}) => {
await visit(page, {
id: 'experimental-components-selectpanel--default',
globals: {
colorScheme: theme,
},
// Default state
const buttonText = story.buttonText || 'Assign label'
await page.getByText(buttonText).click()
await waitForImages(page)
await expect(page).toHaveNoViolations()
})
await page.getByText('Assign label').click()
await expect(page).toHaveNoViolations()
})
})
}
})
}
})
}
})
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export interface FilteredActionListProps
onFilterChange: (value: string, e: React.ChangeEvent<HTMLInputElement>) => void
textInputProps?: Partial<Omit<TextInputProps, 'onChange'>>
inputRef?: React.RefObject<HTMLInputElement>
className?: string
}

const StyledHeader = styled.div`
Expand All @@ -46,6 +47,7 @@ export function FilteredActionList({
textInputProps,
inputRef: providedInputRef,
sx,
className,
...listProps
}: FilteredActionListProps): JSX.Element {
const [filterValue, setInternalFilterValue] = useProvidedStateOrCreate(externalFilterValue, undefined, '')
Expand Down Expand Up @@ -110,7 +112,14 @@ export function FilteredActionList({
useScrollFlash(scrollContainerRef)

return (
<Box display="flex" flexDirection="column" overflow="hidden" sx={sx}>
<Box
display="flex"
flexDirection="column"
overflow="hidden"
sx={sx}
className={className}
data-testid="filtered-action-list"
>
<StyledHeader>
<TextInput
ref={inputRef}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface FilteredActionListProps
onFilterChange: (value: string, e: React.ChangeEvent<HTMLInputElement>) => void
textInputProps?: Partial<Omit<TextInputProps, 'onChange'>>
inputRef?: React.RefObject<HTMLInputElement>
className?: string
}

const StyledHeader = styled.div`
Expand All @@ -52,6 +53,7 @@ export function FilteredActionList({
sx,
groupMetadata,
showItemDividers,
className,
...listProps
}: FilteredActionListProps): JSX.Element {
const [filterValue, setInternalFilterValue] = useProvidedStateOrCreate(externalFilterValue, undefined, '')
Expand Down Expand Up @@ -129,7 +131,14 @@ export function FilteredActionList({
}

return (
<Box display="flex" flexDirection="column" overflow="hidden" sx={sx}>
<Box
display="flex"
flexDirection="column"
overflow="hidden"
sx={sx}
className={className}
data-testid="filtered-action-list"
>
<StyledHeader>
<TextInput
ref={inputRef}
Expand Down
166 changes: 166 additions & 0 deletions packages/react/src/SelectPanel/SelectPanel.dev.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import {TriangleDownIcon} from '@primer/octicons-react'
import type {Meta} from '@storybook/react'
import React, {useState} from 'react'

import Box from '../Box'
import {Button} from '../Button'
import {SelectPanel} from '.'
import type {ItemInput} from '../deprecated/ActionList/List'
import {FeatureFlags} from '../FeatureFlags'

const meta = {
title: 'Components/SelectPanel/Dev',
component: SelectPanel,
} satisfies Meta<typeof SelectPanel>

export default meta

function getColorCircle(color: string) {
return function () {
return (
<Box
sx={{
backgroundColor: color,
borderColor: color,
width: 14,
height: 14,
borderRadius: 10,
margin: 'auto',
borderWidth: '1px',
borderStyle: 'solid',
}}
/>
)
}
}

const items: ItemInput[] = [
{leadingVisual: getColorCircle('#a2eeef'), text: 'enhancement', description: 'New feature or request', id: 1},
{leadingVisual: getColorCircle('#d73a4a'), text: 'bug', description: "Something isn't working", id: 2},
{leadingVisual: getColorCircle('#0cf478'), text: 'good first issue', description: 'Good for newcomers', id: 3},
{leadingVisual: getColorCircle('#ffd78e'), text: 'design', id: 4},
{leadingVisual: getColorCircle('#ff0000'), text: 'blocker', id: 5},
{leadingVisual: getColorCircle('#a4f287'), text: 'backend', id: 6},
{leadingVisual: getColorCircle('#8dc6fc'), text: 'frontend', id: 7},
].map(item => ({...item, descriptionVariant: 'block'}))

export const WithCss = () => {
const [selected, setSelected] = React.useState<ItemInput[]>([items[0], items[1]])
const [filter, setFilter] = React.useState('')
const filteredItems = items.filter(item => item.text?.toLowerCase().startsWith(filter.toLowerCase()))
const [open, setOpen] = useState(true)

return (
<FeatureFlags
flags={{
primer_react_css_modules_team: true,
primer_react_css_modules_staff: true,
primer_react_css_modules_ga: true,
}}
>
<h1>Multi Select Panel</h1>
<SelectPanel
title="Select labels"
subtitle="Use labels to organize issues and pull requests"
renderAnchor={({children, 'aria-labelledby': ariaLabelledBy, ...anchorProps}) => (
<Button
trailingAction={TriangleDownIcon}
aria-labelledby={` ${ariaLabelledBy}`}
{...anchorProps}
aria-haspopup="dialog"
>
{children ?? 'Select Labels'}
</Button>
)}
open={open}
onOpenChange={setOpen}
items={filteredItems}
selected={selected}
onSelectedChange={setSelected}
onFilterChange={setFilter}
className="testCustomClassnameMono"
/>
</FeatureFlags>
)
}

export const WithSx = () => {
const [selected, setSelected] = React.useState<ItemInput[]>([items[0], items[1]])
const [filter, setFilter] = React.useState('')
const filteredItems = items.filter(item => item.text?.toLowerCase().startsWith(filter.toLowerCase()))
const [open, setOpen] = useState(true)

return (
<FeatureFlags
flags={{
primer_react_css_modules_team: true,
primer_react_css_modules_staff: true,
primer_react_css_modules_ga: true,
}}
>
<h1>Multi Select Panel</h1>
<SelectPanel
title="Select labels"
subtitle="Use labels to organize issues and pull requests"
renderAnchor={({children, 'aria-labelledby': ariaLabelledBy, ...anchorProps}) => (
<Button
trailingAction={TriangleDownIcon}
aria-labelledby={` ${ariaLabelledBy}`}
{...anchorProps}
aria-haspopup="dialog"
>
{children ?? 'Select Labels'}
</Button>
)}
open={open}
onOpenChange={setOpen}
items={filteredItems}
selected={selected}
onSelectedChange={setSelected}
onFilterChange={setFilter}
sx={{fontFamily: 'Times New Roman'}}
/>
</FeatureFlags>
)
}

export const WithSxAndCSS = () => {
const [selected, setSelected] = React.useState<ItemInput[]>([items[0], items[1]])
const [filter, setFilter] = React.useState('')
const filteredItems = items.filter(item => item.text?.toLowerCase().startsWith(filter.toLowerCase()))
const [open, setOpen] = useState(true)

return (
<FeatureFlags
flags={{
primer_react_css_modules_team: true,
primer_react_css_modules_staff: true,
primer_react_css_modules_ga: true,
}}
>
<h1>Multi Select Panel</h1>
<SelectPanel
title="Select labels"
subtitle="Use labels to organize issues and pull requests"
renderAnchor={({children, 'aria-labelledby': ariaLabelledBy, ...anchorProps}) => (
<Button
trailingAction={TriangleDownIcon}
aria-labelledby={` ${ariaLabelledBy}`}
{...anchorProps}
aria-haspopup="dialog"
>
{children ?? 'Select Labels'}
</Button>
)}
open={open}
onOpenChange={setOpen}
items={filteredItems}
selected={selected}
onSelectedChange={setSelected}
onFilterChange={setFilter}
sx={{fontFamily: 'Times New Roman'}}
className="testCustomClassnameMono"
/>
</FeatureFlags>
)
}
Loading

0 comments on commit 82c7923

Please sign in to comment.