diff --git a/src/Card/CardSelect.jsx b/src/Card/CardSelect.jsx new file mode 100644 index 00000000000..684b731de7a --- /dev/null +++ b/src/Card/CardSelect.jsx @@ -0,0 +1,77 @@ +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 ( + <> + + { + setCurrentRecord(e.target.value); + onChange(e.target.value); + }} + defaultValue={selectedCardName} + isInline + className="row" + > + {cardsData?.map(data => ( +
+ + + + + +
+
+ + <>{data.text}
+ <>{data.subtext} +
+
+ + {data.footer} + +
+
+ ))} +
+
+ + ); +}; + +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; diff --git a/src/Card/CardSelect.test.jsx b/src/Card/CardSelect.test.jsx new file mode 100644 index 00000000000..db3b374f4e6 --- /dev/null +++ b/src/Card/CardSelect.test.jsx @@ -0,0 +1,35 @@ +import React from 'react'; +import renderer from 'react-test-renderer'; +import CardSelect from './CardSelect'; + +describe('', () => { + describe('First card selected', () => { + it('First card selected', () => { + const tree = renderer.create(( + + )).toJSON(); + expect(tree).toMatchSnapshot(); + }); + }); + + describe('Second card selected', () => { + it('Second card selected', () => { + const tree = renderer.create(( + + )).toJSON(); + expect(tree).toMatchSnapshot(); + }); + }); +}); diff --git a/src/Card/README.md b/src/Card/README.md index 5672a6f9483..7b9d14892fa 100644 --- a/src/Card/README.md +++ b/src/Card/README.md @@ -185,6 +185,21 @@ it is meant to be used as a single horizontal row of Cards, not as a grid. See C ``` +### CardSelect + +This component displays a collection of Cards in a radio selectable form. + +```jsx live + + +``` + ### Theme variables (SCSS) ```scss diff --git a/src/Card/__snapshots__/CardSelect.test.jsx.snap b/src/Card/__snapshots__/CardSelect.test.jsx.snap new file mode 100644 index 00000000000..1f8e8a3da64 --- /dev/null +++ b/src/Card/__snapshots__/CardSelect.test.jsx.snap @@ -0,0 +1,397 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` First card selected First card selected 1`] = ` +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+

+
+

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+

+
+

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+

+
+

+
+
+ +
+
+
+
+
+`; + +exports[` Second card selected Second card selected 1`] = ` +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+

+
+

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+

+
+

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+

+
+

+
+
+ +
+
+
+
+
+`; diff --git a/src/Card/index.jsx b/src/Card/index.jsx index e5afd0a3340..e34c4eed595 100644 --- a/src/Card/index.jsx +++ b/src/Card/index.jsx @@ -5,3 +5,4 @@ export { default as CardImg } from 'react-bootstrap/CardImg'; export { default as CardGroup } from 'react-bootstrap/CardGroup'; export { default as CardGrid } from './CardGrid'; +export { default as CardSelect } from './CardSelect'; diff --git a/src/index.js b/src/index.js index e8720dec2f6..5f4f02e6e20 100644 --- a/src/index.js +++ b/src/index.js @@ -14,6 +14,7 @@ export { CardImg, CardGroup, CardGrid, + CardSelect, } from './Card'; export { default as Carousel, CarouselItem } from './Carousel'; export { default as CheckBox } from './CheckBox';