Skip to content

Commit

Permalink
merging in main
Browse files Browse the repository at this point in the history
  • Loading branch information
recondesigns committed Mar 3, 2024
2 parents 27a9be0 + beb9f02 commit ec58180
Show file tree
Hide file tree
Showing 22 changed files with 216 additions and 155 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useState } from 'react';
import { arrayOf, bool, node, number, shape, string, oneOfType } from 'prop-types';
import classNames from 'classnames';
import Chevron from 'public/static/images/icons/FontAwesome/angle-right-solid.svg';
import { ACCORDION_CONTENT, ACCORDION_TOGGLE_BUTTON } from 'common/constants/testIDs';
Expand All @@ -10,33 +9,47 @@ import styles from './Accordion.module.css';
const ChevronRight = () => <Chevron className={styles.icon} />;
const ChevronDown = () => <Chevron className={classNames(styles.icon, styles.rotate90)} />;

Accordion.propTypes = {
/** Accessibility ID to use for joining elements together
* with ARIA attributes */
accessibilityId: oneOfType([number, string]).isRequired,
/** Name of style class to use */
className: string,
/** Composition of the Accordion */
content: shape({
/** Labels or thumbnails representing sections of content */
headingChildren: oneOfType([node, arrayOf(node)]).isRequired,
/** Section of content associated with header */
bodyChildren: oneOfType([node, arrayOf(node)]).isRequired,
}).isRequired,
/** Should Accordion have animation on hover */
hasAnimationOnHover: bool,
type ContentPropType = {
/**
* Labels or thumbnails representing sections of content.
*/
headingChildren: React.ReactNode | React.ReactNode[];
/**
* Section of content associated with header.
*/
bodyChildren: React.ReactNode | React.ReactNode[];
};

Accordion.defaultProps = {
className: undefined,
hasAnimationOnHover: false,
export type AccordionPropsType = {
/**
* Accessibility ID to use for joining elements together with ARIA attributes
*/
accessibilityId: number | string;
/**
* Composition of the Accordion.
*/
content: ContentPropType;
/**
* Name of style class to use.
*/
className?: string;
/**
* Should Accordion have animation on hover.
* @default - false
*/
hasAnimationOnHover?: boolean;
};

/**
* @description A component whose main content is invisible until revealed by the user
* @see http://web-accessibility.carnegiemuseums.org/code/accordions/
*/
function Accordion({ accessibilityId, className, content, hasAnimationOnHover }) {
function Accordion({
accessibilityId,
className,
content,
hasAnimationOnHover = false,
}: AccordionPropsType) {
const [isContentVisible, setContentVisibility] = useState(false);

const toggleAccordionContent = () => setContentVisibility(previousState => !previousState);
Expand Down
18 changes: 0 additions & 18 deletions components/Accordion/__stories__/Accordion.stories.js

This file was deleted.

22 changes: 22 additions & 0 deletions components/Accordion/__stories__/Accordion.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Meta, StoryObj } from '@storybook/react';
import Accordion from '../Accordion';

type AccordionStoryType = StoryObj<typeof Accordion>;

const meta: Meta<typeof Accordion> = {
title: 'Accordion',
component: Accordion,
args: {
accessibilityId: '1',
content: {
headingChildren: <h5>Can be JSX</h5>,
bodyChildren: <p>Can also be JSX</p>,
},
},
};

export default meta;

export const Default: AccordionStoryType = {
render: args => <Accordion {...args} />,
};
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import { fireEvent, render } from '@testing-library/react';

import { composeStory } from '@storybook/react';
import {
ACCORDION_CONTENT,
ACCORDION_TOGGLE_BUTTON,
SCREEN_READER_ONLY,
} from 'common/constants/testIDs';
import { Default } from '../__stories__/Accordion.stories';
import { toggleMessages } from '../../ScreenReaderOnly/ScreenReaderOnly';
import meta, { Default } from '../__stories__/Accordion.stories';

const AccordionStory = composeStory(Default, meta);

describe('Accordion', () => {
it('should render invisible text that turns visible on toggle click', async () => {
const component = render(<Default {...Default.args} />);
const component = render(<AccordionStory />);
const Content = component.queryByTestId(ACCORDION_CONTENT);

expect(Content).not.toBeVisible();

// @ts-expect-error
fireEvent.click(component.queryByTestId(ACCORDION_TOGGLE_BUTTON));

expect(Content).toBeVisible();
Expand All @@ -23,13 +26,14 @@ describe('Accordion', () => {

describe('Accordion Accessibility', () => {
it('should display the correct screenReader text for toggle button', async () => {
const component = render(<Default {...Default.args} />);
const component = render(<AccordionStory />);
const Button = component.queryByTestId(SCREEN_READER_ONLY);

//@ts-expect-error
expect(Button.textContent).toBe(toggleMessages.open);

//@ts-expect-error
fireEvent.click(Button);

//@ts-expect-error
expect(Button.textContent).toBe(toggleMessages.close);
});
});
27 changes: 13 additions & 14 deletions components/Alert/Alert.js → components/Alert/Alert.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import { func, node, oneOf, string } from 'prop-types';
import classNames from 'classnames';
import { ALERT, ALERT_CLOSE_BUTTON } from 'common/constants/testIDs';
import ScreenReaderOnly from 'components/ScreenReaderOnly/ScreenReaderOnly';
import styles from './Alert.module.css';

Alert.propTypes = {
children: node.isRequired,
className: string,
'data-testid': string,
onClose: func,
type: oneOf(['error', 'success', 'warning']).isRequired,
export type AlertPropsType = {
type: 'error' | 'success' | 'warning';
children: React.ReactNode;
className?: string;
'data-testid'?: string;
onClose?: () => void;
};

Alert.defaultProps = {
className: undefined,
'data-testid': ALERT,
onClose: undefined,
};

function Alert({ children, className, 'data-testid': testID, onClose, type }) {
function Alert({
children,
className,
'data-testid': testID = ALERT,
onClose,
type,
}: AlertPropsType) {
return (
<div
className={classNames(styles.Alert, className, {
Expand Down
26 changes: 0 additions & 26 deletions components/Alert/__stories__/Alert.stories.js

This file was deleted.

39 changes: 39 additions & 0 deletions components/Alert/__stories__/Alert.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Meta, StoryObj } from '@storybook/react';
import Alert from '../Alert';

type AlertStoryType = StoryObj<typeof Alert>;

const meta: Meta<typeof Alert> = {
title: 'Alert',
component: Alert,
};

export default meta;

const AlertStoryTemplate: AlertStoryType = {
render: args => <Alert {...args} />,
};

export const ErrorAlert: AlertStoryType = {
...AlertStoryTemplate,
args: {
children: 'Error Alert JSX or Text',
type: 'error',
},
};

export const SuccessAlert: AlertStoryType = {
...AlertStoryTemplate,
args: {
children: 'Success Alert JSX or Text',
type: 'success',
},
};

export const WarningAlert: AlertStoryType = {
...AlertStoryTemplate,
args: {
children: 'Warning Alert JSX or Text',
type: 'warning',
},
};
Original file line number Diff line number Diff line change
@@ -1,28 +1,33 @@
import { fireEvent, render } from '@testing-library/react';
import { composeStory } from '@storybook/react';
import createSnapshotTest from 'test-utils/createSnapshotTest';
import { ALERT_CLOSE_BUTTON } from 'common/constants/testIDs';
import meta, { ErrorAlert, SuccessAlert, WarningAlert } from '../__stories__/Alert.stories';

import { ErrorAlert, SuccessAlert, WarningAlert } from '../__stories__/Alert.stories';
const ErrorAlertStory = composeStory(ErrorAlert, meta);
const SuccessAlertStory = composeStory(SuccessAlert, meta);
const WarningAlertStory = composeStory(WarningAlert, meta);

describe('Alert', () => {
it('should render error alert with required props', () => {
createSnapshotTest(<ErrorAlert {...ErrorAlert.args} />);
createSnapshotTest(<ErrorAlertStory />);
});

it('should call close handler when close alert button clicked', () => {
const onCloseMock = vi.fn();

const { queryByTestId } = render(<SuccessAlert {...SuccessAlert.args} onClose={onCloseMock} />);
const { queryByTestId } = render(<SuccessAlertStory onClose={onCloseMock} />);

expect(onCloseMock).toHaveBeenCalledTimes(0);

// @ts-expect-error
fireEvent.click(queryByTestId(ALERT_CLOSE_BUTTON));

expect(onCloseMock).toHaveBeenCalledTimes(1);
});

it('should NOT render button if close handler not provided', () => {
const { queryByTestId } = render(<WarningAlert {...WarningAlert.args} />);
const { queryByTestId } = render(<WarningAlertStory />);

expect(queryByTestId(ALERT_CLOSE_BUTTON)).toBeNull();
});
Expand Down
14 changes: 7 additions & 7 deletions components/Buttons/Button/__stories__/Button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,6 @@ import Button from '../Button';

type ButtonStoryType = StoryObj<typeof Button>;

export const Default: ButtonStoryType = {
render: args => <Button {...args} />,
args: {
children: 'Button',
},
};

const meta: Meta<typeof Button> = {
title: 'Buttons/Button',
component: Button,
Expand All @@ -21,3 +14,10 @@ const meta: Meta<typeof Button> = {
};

export default meta;

export const Default: ButtonStoryType = {
render: args => <Button {...args} />,
args: {
children: 'Button',
},
};
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import { bool, func, oneOf } from 'prop-types';
import classNames from 'classnames';
import { CLOSE_BUTTON } from 'common/constants/testIDs';
import ScreenReaderOnly from 'components/ScreenReaderOnly/ScreenReaderOnly';
import PlusIcon from 'static/images/icons/plus.svg';
import styles from './CloseButton.module.css';

CloseButton.propTypes = {
disabled: bool,
onClick: func.isRequired,
theme: oneOf(['primary', 'secondary', 'white']),
};
export type CloseButtonProps = {
/**
* Sets the button color theme.
*/
theme?: 'primary' | 'secondary' | 'white';
} & React.ButtonHTMLAttributes<HTMLButtonElement>;

CloseButton.defaultProps = {
disabled: false,
theme: 'primary',
};

export default function CloseButton({ disabled, onClick, theme }) {
export default function CloseButton({
disabled = false,
onClick,
theme = 'primary',
}: CloseButtonProps) {
return (
<button
className={styles.CloseButton}
Expand Down
11 changes: 0 additions & 11 deletions components/Buttons/CloseButton/__stories__/CloseButton.stories.js

This file was deleted.

18 changes: 18 additions & 0 deletions components/Buttons/CloseButton/__stories__/CloseButton.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Meta, StoryObj } from '@storybook/react';
import CloseButton from '../CloseButton';

type CloseButtonStoryType = StoryObj<typeof CloseButton>;

const meta: Meta<typeof CloseButton> = {
title: 'Buttons/Closebutton',
component: CloseButton,
};

export default meta;

export const Default: CloseButtonStoryType = {
render: args => <CloseButton {...args} />,
args: {
theme: 'primary',
},
};
Loading

0 comments on commit ec58180

Please sign in to comment.