Skip to content

Commit

Permalink
Adds AddToCart component
Browse files Browse the repository at this point in the history
  • Loading branch information
rabidkitten committed May 9, 2023
1 parent 28dc492 commit 6c9825e
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 4 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,16 @@ internal and are not listed here since they are not exposed. If you don't see a
component that you believe should be here or you would like to see an internal
component made external, submit a request and we will respond promptly.

### Add To Cart

The Add to Cart component displays a button that allows customers to add a
product to their shopping cart.

![Add to Cart component](docs/components/add-to-cart.png)

### Brand Link

Displays the brand name of a product.
The Brand Link component displays the brand name of a product.

![Brand Link component](docs/components/brand-link1.png)

Expand Down
Binary file added docs/components/add-to-cart.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ditus/react-web-retail",
"version": "1.0.24",
"version": "1.0.25",
"description": "A set of reusable React web components based on Material UI for retail applications.",
"private": false,
"main": "dist/index.js",
Expand Down
62 changes: 62 additions & 0 deletions src/components/add-to-cart/add-to-cart.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// Copyright (c) DITUS INC. All rights reserved. See LICENSE file in the project
// root for details.
//
import React from 'react';
import PropTypes from 'prop-types';
import { useTranslationProps } from '@ditus/react-translation';
import { Button } from '@mui/material';

/**
* Represents a button that adds a product to the users shopping cart.
* @param {*} props The properties of the component.
* @returns {HTMLElement} An HTML element representing the component.
*/
function AddToCart(props) {
const {
hidden,
label,
onClick,
} = useTranslationProps({ name: 'AddToCart', props });

if (hidden) {
return null;
}

const handleSelect = () => {
if (onClick) {
onClick();
}
};

return (
<Button onClick={handleSelect}>
{label}
</Button>
);
}

export default AddToCart;

AddToCart.propTypes = {
/**
* Specifies whether the component is visible or hidden.
*/
hidden: PropTypes.bool,

/**
* Specifies the label that appears.
*/
label: PropTypes.string,

/**
* Specifies the event to invoke when the button is clicked.
*/
onClick: PropTypes.func,
};

AddToCart.defaultProps = {
hidden: false,
label: 'Add to Cart',
onClick: null,
};
80 changes: 80 additions & 0 deletions src/components/add-to-cart/add-to-cart.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* @jest-environment jsdom
*/

//
// Copyright (c) DITUS INC. All rights reserved. See LICENSE file in the project
// root for details.
//
import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import AddToCart from './add-to-cart';

describe('AddToCart', () => {
it('is not hidden by default.', async () => {
const { container } = render(
<AddToCart />,
);

expect(container).not.toBeEmptyDOMElement();
expect(screen.queryByRole('button')).not.toBeNull();
});

it('displays when not hidden.', async () => {
const { container } = render(
<AddToCart hidden={false} />,
);

expect(container).not.toBeEmptyDOMElement();
});

it('does not display when hidden.', async () => {
const { container } = render(
<AddToCart hidden />,
);

expect(container).toBeEmptyDOMElement();
});

it('displays a button with a default label.', async () => {
const { container } = render(
<AddToCart />,
);

expect(container).not.toBeEmptyDOMElement();
expect(screen.queryByRole('button', { name: 'Add to Cart' })).not.toBeNull();
});

it('displays a button with the the specified label.', async () => {
const { container } = render(
<AddToCart label="This is new" />,
);

expect(container).not.toBeEmptyDOMElement();
expect(screen.queryByRole('button', { name: 'This is new' })).not.toBeNull();
});

it('can be clicked.', async () => {
const user = userEvent.setup();

const handleClick = jest.fn();

const { container, rerender } = render(
<AddToCart onClick={handleClick} />,
);

expect(container).not.toBeEmptyDOMElement();

await user.click(screen.getByRole('button'));
expect(handleClick).toBeCalled();

// The component should not produce an error if the button is clicked and no
// onClick callback is provided.
rerender(
<AddToCart />,
);

await user.click(screen.getByRole('button'));
});
});
1 change: 1 addition & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint-disable import/prefer-default-export */
export { default as AddToCart } from './add-to-cart/add-to-cart';
export { default as BrandLink } from './brand-link/brand-link';
export { default as CartEmpty } from './cart-empty/cart-empty';
export { default as CartIcon } from './cart-icon/cart-icon';
Expand Down
29 changes: 29 additions & 0 deletions src/stories/AddToCart.stories.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* eslint-disable jsdoc/require-jsdoc */
/* eslint-disable react/jsx-props-no-spreading */
import React from 'react';
import { createTheme, ThemeProvider } from '@mui/material/styles';
import { CssBaseline } from '@mui/material';
import AddToCart from '../components/add-to-cart/add-to-cart';

export default {
title: 'Components/AddToCart',
component: AddToCart,
argTypes: {
},
};

const theme = createTheme({
});

function Template(args) {
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<AddToCart {...args} />
</ThemeProvider>
);
}

export const Primary = Template.bind({});
Primary.args = {
};

0 comments on commit 6c9825e

Please sign in to comment.