Skip to content

Commit

Permalink
feat: Added CardSelect component (#808)
Browse files Browse the repository at this point in the history
  • Loading branch information
irfanuddinahmad committed Sep 8, 2021
1 parent 7c13754 commit d8dec97
Show file tree
Hide file tree
Showing 6 changed files with 515 additions and 0 deletions.
78 changes: 78 additions & 0 deletions src/Card/CardSelect.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import Card from 'react-bootstrap/Card';
import Form from '../Form';

const CardSelect = ({
className,
cardsData,
onChange,
selectedCardName,
}) => {
const [currentRecord, setCurrentRecord] = useState(null);
useEffect(() => {
setCurrentRecord(selectedCardName);
}, []);

return (
<>
<Form.Group>
<Form.RadioSet
name="radio-select-card"
onChange={(e) => {
setCurrentRecord(e.target.value);
onChange(e.target.value);
}}
defaultValue={selectedCardName}
isInline
className="row"
>
{cardsData?.map(data => (
<div
key={data.name}
className={className}
role="group"
aria-label={data.title}
>
<Card className={currentRecord === data.name ? 'border border-dark' : null}>
<Card.Img variant="top" src={data.img} />
<Card.Body>
<Card.Title as="h5" className="card-title mb-1">
<label htmlFor={data.name}>{data.title}</label>
<div className="float-right"><Form.Radio id={data.name} value={data.name} /></div>
</Card.Title>
<Card.Text>
{data.textElements?.map(ele => (
<p className={ele.className}>{ele.text}</p>
))}
</Card.Text>
</Card.Body>
<Card.Footer>
<small className="text-muted">{data.footer}</small>
</Card.Footer>
</Card>
</div>
))}
</Form.RadioSet>
</Form.Group>
</>
);
};

CardSelect.defaultProps = {
className: 'mb-3 col-md-3 offset-md-1',
onChange: () => {},
};

CardSelect.propTypes = {
/** The class name for the CardSelect component */
className: PropTypes.string,
/** The Card components data to organize into a radio selectable form */
cardsData: PropTypes.node.isRequired,
/** specifies the callback for the onChange event. The default value is a no-op function. */
onChange: PropTypes.func,
/** The selected card */
selectedCardName: PropTypes.string.isRequired,
};

export default CardSelect;
35 changes: 35 additions & 0 deletions src/Card/CardSelect.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import renderer from 'react-test-renderer';
import CardSelect from './CardSelect';

describe('<CardSelect />', () => {
describe('First card selected', () => {
it('First card selected', () => {
const tree = renderer.create((
<CardSelect
cardsData={[
{ name: 'card1', title: 'Lorem Ipsum 1' },
{ name: 'card2', title: 'Lorem Ipsum 2', img: 'https://source.unsplash.com/360x200/?nature' },
{ name: 'card3', title: 'Lorem Ipsum 3', img: 'https://source.unsplash.com/360x200' }]}
selectedCardName="card1"
/>
)).toJSON();
expect(tree).toMatchSnapshot();
});
});

describe('Second card selected', () => {
it('Second card selected', () => {
const tree = renderer.create((
<CardSelect
cardsData={[
{ name: 'card1', title: 'Lorem Ipsum 1' },
{ name: 'card2', title: 'Lorem Ipsum 2', img: 'https://source.unsplash.com/360x200/?nature' },
{ name: 'card3', title: 'Lorem Ipsum 3', img: 'https://source.unsplash.com/360x200' }]}
selectedCardName="card2"
/>
)).toJSON();
expect(tree).toMatchSnapshot();
});
});
});
15 changes: 15 additions & 0 deletions src/Card/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,21 @@ it is meant to be used as a single horizontal row of Cards, not as a grid. See C
</CardDeck>
```
### CardSelect
This component displays a collection of Cards in a radio selectable form.
```jsx live
<CardSelect
cardsData={[
{name: "card1", title: "Lorem Ipsum 1", textElements: [{className: "", text: "Card Text1"}, {className: "", text: "Card SubText1"}], footer: "Card Footer1", img: "https://source.unsplash.com/360x200/?nature,flower"},
{name: "card2", title: "Lorem Ipsum 2", textElements: [{className: "", text: "Card Text2"}, {className: "", text: "Card SubText2"}], footer: "Card Footer2", img: "https://source.unsplash.com/360x200/?nature"},
{name: "card3", title: "Lorem Ipsum 3", textElements: [{className: "", text: "Card Text3"}, {className: "", text: "Card SubText3"}], footer: "Card Footer3", img: "https://source.unsplash.com/360x200"}]}
selectedCardName="card3"
>
</CardSelect>
```
### Theme variables (SCSS)
```scss
Expand Down

0 comments on commit d8dec97

Please sign in to comment.