diff --git a/e2e/components/Axe.test.ts b/e2e/components/Axe.test.ts new file mode 100644 index 00000000000..2432531f74e --- /dev/null +++ b/e2e/components/Axe.test.ts @@ -0,0 +1,51 @@ +import {test, expect} from '@playwright/test' +// @ts-ignore since this file is generated in the ci to generate this file run npx build storybook in packages/react +import componentsConfig from '../../packages/react/storybook-static/index.json' +import {visit} from '../test-helpers/storybook' +import {themes} from '../test-helpers/themes' + +/** + * These stories should not be tested in the CI because they are stress-tests and + * perform slowly + */ +const SKIPPED_TESTS = [ + 'components-treeview-features--stress-test', + 'components-treeview-features--contain-intrinsic-size', + 'components-flash-features--with-icon-action-dismiss', // TODO: Remove once color-contrast issues have been resolved + 'components-flash-features--with-icon-and-action', // TODO: Remove once color-contrast issues have been resolved +] + +type Component = { + name: string +} + +const {entries} = componentsConfig + +test.describe('@aat', () => { + for (const [id, entry] of Object.entries(entries as Record)) { + if (SKIPPED_TESTS.includes(id)) { + continue + } + + const {name} = entry + // remove parentheses and slashes from the name to avoid playwright file issues + // eslint-disable-next-line no-useless-escape + const cleanedName = name.replaceAll(/[\(\)\/]/g, '') + + test.describe(id, () => { + for (const theme of themes) { + test.describe(theme, () => { + test(`${cleanedName} @aat`, async ({page}) => { + await visit(page, { + id, + globals: { + colorScheme: theme, + }, + }) + await expect(page).toHaveNoViolations() + }) + }) + } + }) + } +}) diff --git a/packages/react/src/ActionMenu/ActionMenu.examples.stories.tsx b/packages/react/src/ActionMenu/ActionMenu.examples.stories.tsx index ce1ca3662de..94986df4c28 100644 --- a/packages/react/src/ActionMenu/ActionMenu.examples.stories.tsx +++ b/packages/react/src/ActionMenu/ActionMenu.examples.stories.tsx @@ -410,15 +410,15 @@ export const MultipleSections = () => { - + Raw file content - alert('Workflows clicked')}>Download + alert('Workflows clicked')}>Download - alert('Workflows clicked')}>Jump to line - alert('Workflows clicked')}>Find in file + alert('Workflows clicked')}>Jump to line + alert('Workflows clicked')}>Find in file - alert('Workflows clicked')}>Copy path - alert('Workflows clicked')}>Copy permalink + alert('Workflows clicked')}>Copy path + alert('Workflows clicked')}>Copy permalink @@ -434,9 +434,9 @@ export const MultipleSections = () => { ))} - + View options - alert('Delete file')} variant="danger"> + alert('Delete file')} variant="danger"> Delete file diff --git a/packages/react/src/ActionMenu/ActionMenu.tsx b/packages/react/src/ActionMenu/ActionMenu.tsx index b2dd4b81a9b..2e08c000876 100644 --- a/packages/react/src/ActionMenu/ActionMenu.tsx +++ b/packages/react/src/ActionMenu/ActionMenu.tsx @@ -217,9 +217,8 @@ const Anchor = React.forwardRef(({children: }) /** this component is syntactical sugar 🍭 */ -export type ActionMenuButtonProps = Omit & { - children: React.ReactNode -} +export type ActionMenuButtonProps = ButtonProps + const MenuButton = React.forwardRef(({...props}, anchorRef) => { return ( diff --git a/packages/react/src/Banner/Banner.stories.tsx b/packages/react/src/Banner/Banner.stories.tsx index 02d27d752d7..2dd11f58630 100644 --- a/packages/react/src/Banner/Banner.stories.tsx +++ b/packages/react/src/Banner/Banner.stories.tsx @@ -38,6 +38,7 @@ export const Playground: StoryObj = { {primaryAction} : null} secondaryAction={ @@ -49,6 +50,7 @@ export const Playground: StoryObj = { {primaryAction} : null} secondaryAction={ diff --git a/packages/react/src/Button/ButtonBase.tsx b/packages/react/src/Button/ButtonBase.tsx index 6303ffc5e5c..eb214607125 100644 --- a/packages/react/src/Button/ButtonBase.tsx +++ b/packages/react/src/Button/ButtonBase.tsx @@ -72,7 +72,8 @@ const ButtonBase = forwardRef( if ( innerRef.current && !(innerRef.current instanceof HTMLButtonElement) && - !((innerRef.current as unknown) instanceof HTMLAnchorElement) + !((innerRef.current as unknown) instanceof HTMLAnchorElement) && + !((innerRef.current as HTMLElement).tagName === 'SUMMARY') ) { // eslint-disable-next-line no-console console.warn('This component should be an instanceof a semantic button or anchor') diff --git a/packages/react/src/ButtonGroup/ButtonGroup.features.stories.tsx b/packages/react/src/ButtonGroup/ButtonGroup.features.stories.tsx index da2b99ff6e6..1325f09c8c2 100644 --- a/packages/react/src/ButtonGroup/ButtonGroup.features.stories.tsx +++ b/packages/react/src/ButtonGroup/ButtonGroup.features.stories.tsx @@ -73,7 +73,7 @@ export const InactiveButtonsGroup = () => { ) const secondaryButton = ( - + ) return ( @@ -84,7 +84,7 @@ export const InactiveButtonsGroup = () => { {}}> - + {secondaryButton} @@ -111,7 +111,7 @@ export const DropdownSplit = () => { {selectedAction} - More options + {actions.map((action, index) => { diff --git a/packages/react/src/FilteredActionList/FilteredActionList.stories.tsx b/packages/react/src/FilteredActionList/FilteredActionList.stories.tsx index 288044c974b..637a6a57455 100644 --- a/packages/react/src/FilteredActionList/FilteredActionList.stories.tsx +++ b/packages/react/src/FilteredActionList/FilteredActionList.stories.tsx @@ -4,6 +4,7 @@ import {ThemeProvider} from '..' import {FilteredActionList} from '../FilteredActionList' import BaseStyles from '../BaseStyles' import Box from '../Box' +import {FeatureFlags} from '../FeatureFlags' const meta: Meta = { title: 'Components/FilteredActionList', @@ -57,7 +58,7 @@ export function Default(): JSX.Element { const filteredItems = items.filter(item => item.text.toLowerCase().startsWith(filter.toLowerCase())) return ( - <> +

Filtered Action List

Please select labels that describe your issue:
- +
) } diff --git a/packages/react/src/Header/Header.dev.module.css b/packages/react/src/Header/Header.dev.module.css index 8d90de7725a..4cc998f661c 100644 --- a/packages/react/src/Header/Header.dev.module.css +++ b/packages/react/src/Header/Header.dev.module.css @@ -1,5 +1,7 @@ .HeaderDev { - background-color: var(--label-olive-bgColor-active); + color: var(--color-prettylights-syntax-carriage-return-text); + /* stylelint-disable-next-line primer/no-display-colors */ + background-color: var(--display-pine-bgColor-emphasis); } .HeaderDevItem { @@ -7,5 +9,5 @@ } .HeaderDevLink { - color: var(--color-prettylights-syntax-markup-inserted-text); + color: var(--color-prettylights-syntax-carriage-return-text); } diff --git a/packages/react/src/Header/Header.dev.stories.tsx b/packages/react/src/Header/Header.dev.stories.tsx index 66756f36e93..a05c9898420 100644 --- a/packages/react/src/Header/Header.dev.stories.tsx +++ b/packages/react/src/Header/Header.dev.stories.tsx @@ -22,7 +22,7 @@ export const WithCss = () => ( primer_react_css_modules_ga: true, }} > -
+
@@ -38,7 +38,7 @@ export const WithCss = () => ( ) export const WithSx = () => ( -
+
@@ -60,7 +60,7 @@ export const WithSxAndCSS = () => ( primer_react_css_modules_ga: true, }} > -
+
diff --git a/packages/react/src/ProgressBar/ProgressBar.features.stories.tsx b/packages/react/src/ProgressBar/ProgressBar.features.stories.tsx index 145dae260e7..0e79793d71a 100644 --- a/packages/react/src/ProgressBar/ProgressBar.features.stories.tsx +++ b/packages/react/src/ProgressBar/ProgressBar.features.stories.tsx @@ -19,10 +19,10 @@ export const Inline = () => export const MultipleItems = () => ( - - - - + + + + ) diff --git a/packages/react/src/UnderlineNav/UnderlineNav.dev.stories.tsx b/packages/react/src/UnderlineNav/UnderlineNav.dev.stories.tsx deleted file mode 100644 index f5003789d90..00000000000 --- a/packages/react/src/UnderlineNav/UnderlineNav.dev.stories.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react' -import type {Meta} from '@storybook/react' -import {UnderlineNav} from './index' - -export default { - title: 'Components/UnderlineNav/DevOnly', -} as Meta - -export const IllegalState = () => { - return ( - - Code - Issues - Pull Requests - - ) -} diff --git a/packages/react/src/__tests__/ActionMenu.types.test.tsx b/packages/react/src/__tests__/ActionMenu.types.test.tsx index 5e26f333e7f..753e7b24e20 100644 --- a/packages/react/src/__tests__/ActionMenu.types.test.tsx +++ b/packages/react/src/__tests__/ActionMenu.types.test.tsx @@ -2,7 +2,6 @@ import {ActionMenu} from '..' import React from 'react' export function actionButtonWithoutProps() { - // @ts-expect-error requires children return } diff --git a/packages/react/src/__tests__/storybook.test.tsx b/packages/react/src/__tests__/storybook.test.tsx index d0bc7d1a7b7..67f985a3e34 100644 --- a/packages/react/src/__tests__/storybook.test.tsx +++ b/packages/react/src/__tests__/storybook.test.tsx @@ -4,6 +4,7 @@ import fs from 'node:fs' import path from 'node:path' const ROOT_DIRECTORY = path.resolve(__dirname, '..', '..') + // Components opted into the new story format // TODO: Remove this allowlist when all components use the new story format const allowlist = [ @@ -56,6 +57,7 @@ const allowlist = [ 'Token', 'UnderlineNav2', ] + const stories = glob .sync('src/**/*.stories.tsx', { cwd: ROOT_DIRECTORY, @@ -72,7 +74,12 @@ const stories = glob const type = path.basename(filepath, '.stories.tsx').endsWith('features') ? 'feature' : 'default' const name = type === 'feature' ? path.basename(file, '.features.stories.tsx') : path.basename(file, '.stories.tsx') - return {name, story: require(filepath), type, relativeFilepath: path.relative(ROOT_DIRECTORY, filepath)} + return { + name, + story: require(filepath), + type, + relativeFilepath: path.relative(ROOT_DIRECTORY, filepath), + } }) const components = Object.entries( diff --git a/packages/react/src/experimental/UnderlinePanels/UnderlinePanels.stories.tsx b/packages/react/src/experimental/UnderlinePanels/UnderlinePanels.stories.tsx index bcbf370d80f..788a2fc12cb 100644 --- a/packages/react/src/experimental/UnderlinePanels/UnderlinePanels.stories.tsx +++ b/packages/react/src/experimental/UnderlinePanels/UnderlinePanels.stories.tsx @@ -16,11 +16,6 @@ const meta: Meta = { name: 'string', }, }, - 'aria-labelledby': { - type: { - name: 'string', - }, - }, id: { type: { name: 'string', @@ -34,7 +29,6 @@ const meta: Meta = { }, args: { 'aria-label': 'Select a tab', - 'aria-labelledby': 'tab', id: 'test', loadingCounters: false, }, diff --git a/packages/react/src/stories/deprecated/ActionMenu.stories.tsx b/packages/react/src/stories/deprecated/ActionMenu.stories.tsx index 89918a136eb..45355491f75 100644 --- a/packages/react/src/stories/deprecated/ActionMenu.stories.tsx +++ b/packages/react/src/stories/deprecated/ActionMenu.stories.tsx @@ -15,13 +15,11 @@ import type {Meta} from '@storybook/react' import React, {useCallback, useState, useRef} from 'react' import styled from 'styled-components' import {ThemeProvider} from '../..' -import type {LinkProps} from '../../Link' -import Link from '../../Link' import type {ActionMenuProps} from '../../deprecated' import {ActionMenu, ActionList} from '../../deprecated' import type {ItemProps} from '../../deprecated/ActionList' import BaseStyles from '../../BaseStyles' -import {Button} from '../../Button' +import {Button, type ButtonProps} from '../../Button' const meta: Meta = { title: 'Deprecated/Components/ActionMenu', @@ -233,7 +231,7 @@ export function ComplexListStory(): JSX.Element { ComplexListStory.storyName = 'Complex List' export function CustomTrigger(): JSX.Element { - const customAnchor = (props: LinkProps) => + const customAnchor = (props: ButtonProps) =>