From 2dc4fe643de38d51afb4dc66fdfccd9cc6fe232b Mon Sep 17 00:00:00 2001 From: Brian Hague Date: Mon, 27 Apr 2020 21:25:03 -0700 Subject: [PATCH] answers --- package-lock.json | 29 ++++++++++++++ package.json | 3 ++ src/exercise1/Exercise1.js | 5 +++ src/exercise1/Exercise1.test.js | 8 ++++ .../__snapshots__/Exercise1.test.js.snap | 24 +++++++++++ src/exercise2/Exercise2.js | 2 + src/exercise2/Orchid.css | 3 ++ src/exercise2/Orchid.js | 40 ++++++++++++++++++- src/exercise3/Exercise3.js | 4 ++ src/exercise3/InfoCard.css | 9 +++++ src/exercise3/InfoCard.js | 26 ++++++++++++ src/exercise5/Dropdown.js | 30 ++++++++++++-- src/exercise5/Exercise5.js | 4 ++ 13 files changed, 182 insertions(+), 5 deletions(-) create mode 100644 src/exercise1/__snapshots__/Exercise1.test.js.snap create mode 100644 src/exercise2/Orchid.css create mode 100644 src/exercise3/InfoCard.css diff --git a/package-lock.json b/package-lock.json index e29844b..84204d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1078,6 +1078,35 @@ "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz", "integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==" }, + "@fortawesome/fontawesome-common-types": { + "version": "0.2.28", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.28.tgz", + "integrity": "sha512-gtis2/5yLdfI6n0ia0jH7NJs5i/Z/8M/ZbQL6jXQhCthEOe5Cr5NcQPhgTvFxNOtURE03/ZqUcEskdn2M+QaBg==" + }, + "@fortawesome/fontawesome-svg-core": { + "version": "1.2.28", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.28.tgz", + "integrity": "sha512-4LeaNHWvrneoU0i8b5RTOJHKx7E+y7jYejplR7uSVB34+mp3Veg7cbKk7NBCLiI4TyoWS1wh9ZdoyLJR8wSAdg==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.28" + } + }, + "@fortawesome/free-solid-svg-icons": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.13.0.tgz", + "integrity": "sha512-IHUgDJdomv6YtG4p3zl1B5wWf9ffinHIvebqQOmV3U+3SLw4fC+LUCCgwfETkbTtjy5/Qws2VoVf6z/ETQpFpg==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.28" + } + }, + "@fortawesome/react-fontawesome": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.9.tgz", + "integrity": "sha512-49V3WNysLZU5fZ3sqSuys4nGRytsrxJktbv3vuaXkEoxv22C6T7TEG0TW6+nqVjMnkfCQd5xOnmJoZHMF78tOw==", + "requires": { + "prop-types": "^15.7.2" + } + }, "@hapi/address": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", diff --git a/package.json b/package.json index 0034cfd..c8129c5 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,9 @@ "version": "0.1.0", "private": true, "dependencies": { + "@fortawesome/fontawesome-svg-core": "^1.2.28", + "@fortawesome/free-solid-svg-icons": "^5.13.0", + "@fortawesome/react-fontawesome": "^0.1.9", "lodash": "^4.17.15", "prop-types": "^15.7.2", "react": "^16.13.1", diff --git a/src/exercise1/Exercise1.js b/src/exercise1/Exercise1.js index 12bc96a..fd4c301 100644 --- a/src/exercise1/Exercise1.js +++ b/src/exercise1/Exercise1.js @@ -1,4 +1,5 @@ import React from 'react'; +import CoffeeCard from './CoffeeCard'; export default class Exercise1 extends React.Component { render() { @@ -12,6 +13,10 @@ export default class Exercise1 extends React.Component {
  • Render this component four times in Exercise1.js (one for each coffee drink).
  • Pass in the correct props.
  • + + + + ) } diff --git a/src/exercise1/Exercise1.test.js b/src/exercise1/Exercise1.test.js index 66fe6bf..aac2183 100644 --- a/src/exercise1/Exercise1.test.js +++ b/src/exercise1/Exercise1.test.js @@ -1,6 +1,7 @@ import React from 'react'; import {shallow} from 'enzyme'; import Exercise1 from './Exercise1'; +import CoffeeCard from './CoffeeCard'; describe('Exercise1', () => { const wrapper = shallow(); @@ -17,4 +18,11 @@ describe('Exercise1', () => { expect(drinkNames).toEqual(['americano', 'espresso', 'latte', 'mocha']) }); +}); + +describe('CoffeeCard', () => { + it('should render', () => { + const element = shallow(); + expect(element).toMatchSnapshot(); + }); }); \ No newline at end of file diff --git a/src/exercise1/__snapshots__/Exercise1.test.js.snap b/src/exercise1/__snapshots__/Exercise1.test.js.snap new file mode 100644 index 0000000..d2670e2 --- /dev/null +++ b/src/exercise1/__snapshots__/Exercise1.test.js.snap @@ -0,0 +1,24 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`CoffeeCard should render 1`] = ` +
    + mocha +

    + Mocha +

    +

    + Cost: $ + 3.00 +

    +
    +`; diff --git a/src/exercise2/Exercise2.js b/src/exercise2/Exercise2.js index ed855e3..9d1e280 100644 --- a/src/exercise2/Exercise2.js +++ b/src/exercise2/Exercise2.js @@ -1,4 +1,5 @@ import React from 'react'; +import Orchid from './Orchid'; export default class Exercise2 extends React.Component { render() { @@ -13,6 +14,7 @@ export default class Exercise2 extends React.Component {
  • Add the prop borderColor to the Orchid component and give the image a border with the color provided.
  • Import and render the Orchid component in Exercise2.js and provide it a borderColor
  • + ) } diff --git a/src/exercise2/Orchid.css b/src/exercise2/Orchid.css new file mode 100644 index 0000000..b5539d2 --- /dev/null +++ b/src/exercise2/Orchid.css @@ -0,0 +1,3 @@ +.Orchid { + width: 100%; +} \ No newline at end of file diff --git a/src/exercise2/Orchid.js b/src/exercise2/Orchid.js index 60f7264..b092873 100644 --- a/src/exercise2/Orchid.js +++ b/src/exercise2/Orchid.js @@ -1,3 +1,41 @@ -// Here's a URL to get you started +import React from 'react'; +import PropTypes from 'prop-types'; +import './Orchid.css'; +// Here's a URL to get you started const orchidImageUrl = 'https://upload.wikimedia.org/wikipedia/commons/d/df/Orchid_high_resolution.jpg'; + +// Class component +export default class Orchid extends React.Component { + static propTypes = { + borderColor: PropTypes.string + } + + render() { + const { borderColor } = this.props; + return ( + Orchid + ); + } +} + +// // Functional component +// export default function Orchid({ borderColor }) { +// return ( +// Orchid +// ); +// } + +// Orchid.propTypes = { +// borderColor: PropTypes.string +// }; diff --git a/src/exercise3/Exercise3.js b/src/exercise3/Exercise3.js index cd47d13..42ee01b 100644 --- a/src/exercise3/Exercise3.js +++ b/src/exercise3/Exercise3.js @@ -1,4 +1,5 @@ import React from 'react'; +import InfoCard from './InfoCard'; export default class Exercise3 extends React.Component { render() { @@ -26,6 +27,9 @@ export default class Exercise3 extends React.Component {
  • When passing children into the component, the component should display the info icon next to the children.
  • Import and render the InfoCard in Exercise3.js
  • + + Did you know that React has hooks? + ) } diff --git a/src/exercise3/InfoCard.css b/src/exercise3/InfoCard.css new file mode 100644 index 0000000..9b79e86 --- /dev/null +++ b/src/exercise3/InfoCard.css @@ -0,0 +1,9 @@ +.InfoCard { + border: 1px solid lightgray; + padding: 10px; +} + +.InfoCard__icon { + color: rgb(17, 17, 184); + margin-right: 5px; +} \ No newline at end of file diff --git a/src/exercise3/InfoCard.js b/src/exercise3/InfoCard.js index 7b5a5c7..c44907e 100644 --- a/src/exercise3/InfoCard.js +++ b/src/exercise3/InfoCard.js @@ -1 +1,27 @@ // You're on your own +import React from 'react'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faInfoCircle } from '@fortawesome/free-solid-svg-icons' +import './InfoCard.css'; + +// Class component +export default class InfoCard extends React.Component { + render() { + return ( +
    + + {this.props.children} +
    + ) + } +} + +// // Functional component +// export default function InfoCard({ children }) { +// return ( +//
    +// +// {children} +//
    +// ) +// } \ No newline at end of file diff --git a/src/exercise5/Dropdown.js b/src/exercise5/Dropdown.js index ce1e046..23856fc 100644 --- a/src/exercise5/Dropdown.js +++ b/src/exercise5/Dropdown.js @@ -1,20 +1,42 @@ -import React from 'react'; +import React, { useState } from 'react'; import PropTypes from 'prop-types'; import './Dropdown.css'; +// Class component export default class Dropdown extends React.Component { static propTypes = { header: PropTypes.any.isRequired } + state = { isOpen: false }; + + toggleDropdown = () => this.setState(prevState => ({ isOpen: !prevState.isOpen })); + render() { const { header, children } = this.props; return (
    -
    {header}
    -
    {children}
    +
    {header}
    + {this.state.isOpen &&
    {children}
    }
    ) } -} \ No newline at end of file +} + +// Functional component w/hooks +// export default function Dropdown({ header, children }) { +// const [isOpen, toggleDropdown] = useState(false); +// const onClick = () => toggleDropdown(!isOpen); + +// return ( +//
    +//
    {header}
    +// {isOpen &&
    {children}
    } +//
    +// ); +// } + +// Dropdown.propTypes = { +// header: PropTypes.any.isRequired +// }; \ No newline at end of file diff --git a/src/exercise5/Exercise5.js b/src/exercise5/Exercise5.js index 25c5bd9..4a6c7c9 100644 --- a/src/exercise5/Exercise5.js +++ b/src/exercise5/Exercise5.js @@ -1,4 +1,5 @@ import React from 'react'; +import Dropdown from './Dropdown'; export default class Exercise5 extends React.Component { render() { @@ -14,6 +15,9 @@ export default class Exercise5 extends React.Component {
  • Add a click handler called toggleDropdown that makes the content hide/show on click.
  • Ensure that the corresponding tests pass.
  • + + Description + ) }