diff --git a/packages/fuselage/.jest/setup.ts b/packages/fuselage/.jest/setup.ts index 6dc9787551..9fa64ce408 100644 --- a/packages/fuselage/.jest/setup.ts +++ b/packages/fuselage/.jest/setup.ts @@ -1,3 +1,5 @@ +import { toHaveNoViolations } from 'jest-axe'; + const cssInJsClassRegex = /^rcx-css-[a-z0-9]+$/; expect.extend({ @@ -28,3 +30,5 @@ expect.extend({ }; }, }); + +expect.extend(toHaveNoViolations); diff --git a/packages/fuselage/src/components/Accordion/Accordion.spec.tsx b/packages/fuselage/src/components/Accordion/Accordion.spec.tsx index 84ca97dcda..d4150fee4b 100644 --- a/packages/fuselage/src/components/Accordion/Accordion.spec.tsx +++ b/packages/fuselage/src/components/Accordion/Accordion.spec.tsx @@ -1,12 +1,11 @@ import { composeStories } from '@storybook/testing-react'; import { render } from '@testing-library/react'; -import { axe, toHaveNoViolations } from 'jest-axe'; +import { axe } from 'jest-axe'; import React from 'react'; import * as stories from './Accordion.stories'; const { Default } = composeStories(stories); -expect.extend(toHaveNoViolations); describe('[Accordion Component]', () => { it('renders without crashing', () => { diff --git a/packages/fuselage/src/components/Button/Button.spec.tsx b/packages/fuselage/src/components/Button/Button.spec.tsx index 42b07978d0..3e838464c6 100644 --- a/packages/fuselage/src/components/Button/Button.spec.tsx +++ b/packages/fuselage/src/components/Button/Button.spec.tsx @@ -1,10 +1,14 @@ import { composeStories } from '@storybook/testing-react'; import { render } from '@testing-library/react'; +import { axe } from 'jest-axe'; import React from 'react'; import * as stories from './Button.stories'; +import * as iconButtonStories from './IconButton.stories'; const { Default, AsIconButton } = composeStories(stories); +const { _IconButton, _IconButtonInfo, _IconButtonSuccess } = + composeStories(iconButtonStories); describe('[Button Component]', () => { it('renders Button without crashing', () => { @@ -14,4 +18,38 @@ describe('[Button Component]', () => { it('renders ActionButton without crashing', () => { render(); }); + + it('should have no a11y violations', async () => { + const { container } = render(); + + const results = await axe(container); + expect(results).toHaveNoViolations(); + }); +}); + +describe('[IconButton Component]', () => { + it('renders IconButton without crashing', () => { + render(); + }); + + it('IconButton default should have no a11y violations', async () => { + const { container } = render(<_IconButton />); + + const results = await axe(container); + expect(results).toHaveNoViolations(); + }); + + it('IconButtonInfo should have no a11y violations', async () => { + const { container } = render(<_IconButtonInfo />); + + const results = await axe(container); + expect(results).toHaveNoViolations(); + }); + + it('IconButtonSuccess should have no a11y violations', async () => { + const { container } = render(<_IconButtonSuccess />); + + const results = await axe(container); + expect(results).toHaveNoViolations(); + }); }); diff --git a/packages/fuselage/src/components/Button/Button.stories.tsx b/packages/fuselage/src/components/Button/Button.stories.tsx index 2a523ba594..3c911f6b18 100644 --- a/packages/fuselage/src/components/Button/Button.stories.tsx +++ b/packages/fuselage/src/components/Button/Button.stories.tsx @@ -11,7 +11,7 @@ import { import type { ComponentStory, ComponentMeta } from '@storybook/react'; import React from 'react'; -import { Button, ButtonGroup, Icon, IconButton, Margins } from '../..'; +import { Button, ButtonGroup, IconButton, Margins } from '../..'; import { PropsVariationSection } from '../../../.storybook/helpers'; export default { @@ -40,12 +40,6 @@ export const Default: ComponentStory = () => ( ); -export const Square: ComponentStory = () => ( - -); - export const Variants: ComponentStory = () => ( @@ -74,27 +68,11 @@ export const Variants: ComponentStory = () => ( ); export const Sizes: ComponentStory = () => ( - <> - - - - - - - - - - - - + + + + + ); export const AsLink: ComponentStory = () => ( @@ -116,10 +94,6 @@ export const States = () => ( disabled: { disabled: true }, }} yAxis={{ - 'square + icon': { - square: true, - children: , - }, 'icon + text': { children: 'Button', icon: 'baloon-text', @@ -178,10 +152,6 @@ export const States = () => ( disabled: { disabled: true }, }} yAxis={{ - 'square + icon': { - square: true, - children: , - }, 'icon + text': { children: 'Button', icon: 'baloon-text', @@ -232,3 +202,12 @@ export const States = () => ( export const AsIconButton: ComponentStory = (args) => ( ); + +AsIconButton.parameters = { + docs: { + description: { + story: + 'See full IconButton documentation [here](../?path=/docs/inputs-iconbutton)', + }, + }, +}; diff --git a/packages/fuselage/src/components/Button/Button.styles.scss b/packages/fuselage/src/components/Button/Button.styles.scss index 63808f74b8..8f1a2c02fd 100644 --- a/packages/fuselage/src/components/Button/Button.styles.scss +++ b/packages/fuselage/src/components/Button/Button.styles.scss @@ -9,6 +9,7 @@ .rcx-button { @mixin with-rectangular-size($height, $padding-x, $line-height) { min-width: calc(lengths.size($height) * 2); + height: lengths.size($height); padding: calc((lengths.padding($height) - $line-height) / 2 - 2px) calc(lengths.padding($padding-x) - 2px); padding-block: calc((lengths.padding($height) - $line-height) / 2 - 2px); diff --git a/packages/fuselage/src/components/Button/Button.tsx b/packages/fuselage/src/components/Button/Button.tsx index e30b8a2b95..e9d03db2a2 100644 --- a/packages/fuselage/src/components/Button/Button.tsx +++ b/packages/fuselage/src/components/Button/Button.tsx @@ -1,4 +1,4 @@ -import type { ComponentProps, Ref } from 'react'; +import type { AllHTMLAttributes, ComponentProps, Ref } from 'react'; import React, { forwardRef, useMemo } from 'react'; import Box from '../Box'; @@ -19,7 +19,10 @@ export type ButtonProps = ComponentProps & { square?: boolean; external?: boolean; icon?: ComponentProps['name']; -}; +} & Omit< + AllHTMLAttributes, + 'is' | 'className' | 'size' + >; export const Button = forwardRef(function Button( { @@ -41,7 +44,7 @@ export const Button = forwardRef(function Button( children, ...props }: ButtonProps, - ref: Ref + ref: Ref ) { const extraProps = (is === 'a' && { diff --git a/packages/fuselage/src/components/Button/IconButton.tsx b/packages/fuselage/src/components/Button/IconButton.tsx index 05293e97ca..547e5bf09d 100644 --- a/packages/fuselage/src/components/Button/IconButton.tsx +++ b/packages/fuselage/src/components/Button/IconButton.tsx @@ -121,6 +121,7 @@ export const IconButton = forwardRef( {...getSizeClass()} rcx-button--icon-pressed={pressed} ref={ref} + aria-label={props['aria-label'] || icon} {...props} > {children} diff --git a/packages/fuselage/src/components/ButtonGroup/ButtonGroup.spec.tsx b/packages/fuselage/src/components/ButtonGroup/ButtonGroup.spec.tsx index 22c90a451c..477afec4df 100644 --- a/packages/fuselage/src/components/ButtonGroup/ButtonGroup.spec.tsx +++ b/packages/fuselage/src/components/ButtonGroup/ButtonGroup.spec.tsx @@ -1,5 +1,6 @@ import { composeStories } from '@storybook/testing-react'; import { render } from '@testing-library/react'; +import { axe } from 'jest-axe'; import React from 'react'; import * as stories from './ButtonGroup.stories'; @@ -10,4 +11,11 @@ describe('[ButtonGroup Component]', () => { it('renders without crashing', () => { render(); }); + + it('should have no a11y violations', async () => { + const { container } = render(); + + const results = await axe(container); + expect(results).toHaveNoViolations(); + }); }); diff --git a/packages/fuselage/src/components/CheckBox/CheckBox.spec.tsx b/packages/fuselage/src/components/CheckBox/CheckBox.spec.tsx index 603dff5d8a..f747c29e54 100644 --- a/packages/fuselage/src/components/CheckBox/CheckBox.spec.tsx +++ b/packages/fuselage/src/components/CheckBox/CheckBox.spec.tsx @@ -1,6 +1,6 @@ import { composeStories } from '@storybook/testing-react'; import { fireEvent, getByRole, render } from '@testing-library/react'; -import { axe, toHaveNoViolations } from 'jest-axe'; +import { axe } from 'jest-axe'; import React from 'react'; import * as stories from './CheckBox.stories'; @@ -8,8 +8,6 @@ import * as stories from './CheckBox.stories'; const { Default, Indeterminate, Disabled, DefaultChecked } = composeStories(stories); -expect.extend(toHaveNoViolations); - const testCases = Object.values(composeStories(stories)).map((Story) => [ Story.storyName || 'Story', Story, diff --git a/packages/fuselage/src/components/Field/Field.spec.tsx b/packages/fuselage/src/components/Field/Field.spec.tsx index 74c839b63b..57d8bf0668 100644 --- a/packages/fuselage/src/components/Field/Field.spec.tsx +++ b/packages/fuselage/src/components/Field/Field.spec.tsx @@ -1,12 +1,10 @@ import { composeStories } from '@storybook/testing-react'; import { render } from '@testing-library/react'; -import { axe, toHaveNoViolations } from 'jest-axe'; +import { axe } from 'jest-axe'; import React from 'react'; import * as stories from './Field.stories'; -expect.extend(toHaveNoViolations); - const testCases = Object.values(composeStories(stories)).map((Story) => [ Story.storyName || 'Story', Story, diff --git a/packages/fuselage/src/components/Label/Label.spec.tsx b/packages/fuselage/src/components/Label/Label.spec.tsx index 68598b48f4..9d47bc7817 100644 --- a/packages/fuselage/src/components/Label/Label.spec.tsx +++ b/packages/fuselage/src/components/Label/Label.spec.tsx @@ -1,12 +1,10 @@ import { composeStories } from '@storybook/testing-react'; import { render } from '@testing-library/react'; -import { axe, toHaveNoViolations } from 'jest-axe'; +import { axe } from 'jest-axe'; import React from 'react'; import * as stories from './Label.stories'; -expect.extend(toHaveNoViolations); - const testCases = Object.values(composeStories(stories)).map((Story) => [ Story.storyName || 'Story', Story, diff --git a/packages/fuselage/src/components/Table/Table.spec.tsx b/packages/fuselage/src/components/Table/Table.spec.tsx index 265c6ddc8c..873dc800f0 100644 --- a/packages/fuselage/src/components/Table/Table.spec.tsx +++ b/packages/fuselage/src/components/Table/Table.spec.tsx @@ -1,13 +1,12 @@ import { composeStories } from '@storybook/testing-react'; import { render } from '@testing-library/react'; -import { axe, toHaveNoViolations } from 'jest-axe'; +import { axe } from 'jest-axe'; import React from 'react'; import { Table, TableRow, TableHead, TableBody, TableCell, TableFoot } from '.'; import * as stories from './Table.stories'; const { Default, Selected } = composeStories(stories); -expect.extend(toHaveNoViolations); describe('[Table Component]', () => { it('renders Table without crashing', () => { diff --git a/packages/fuselage/src/components/ToastBar/ToastBar.spec.tsx b/packages/fuselage/src/components/ToastBar/ToastBar.spec.tsx index acdbd086a9..8fd9218621 100644 --- a/packages/fuselage/src/components/ToastBar/ToastBar.spec.tsx +++ b/packages/fuselage/src/components/ToastBar/ToastBar.spec.tsx @@ -1,11 +1,9 @@ import { render } from '@testing-library/react'; -import { axe, toHaveNoViolations } from 'jest-axe'; +import { axe } from 'jest-axe'; import React from 'react'; import { ToastBar } from '.'; -expect.extend(toHaveNoViolations); - describe('[ToastBar Component]', () => { it('renders without crashing', () => { render();