diff --git a/.vscode/settings.json b/.vscode/settings.json index eaea662..5bfc7b9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,9 @@ { "eslint.enable": true, - "editor.tabSize": 2 + "editor.tabSize": 2, + "workbench.colorCustomizations": { + "activityBar.background": "#11332B", + "titleBar.activeBackground": "#17483C", + "titleBar.activeForeground": "#F6FCFA" + } } diff --git a/config/client.js b/config/client.js new file mode 100644 index 0000000..b2cb5b9 --- /dev/null +++ b/config/client.js @@ -0,0 +1,6 @@ +module.exports = { + sanity: { + projectId: process.env.SANITY_PROJECT_ID || '<#< sanity.projectId >#>', + dataset: process.env.SANITY_DATASET || '<#< sanity.dataset >#>', + }, +}; diff --git a/package.json b/package.json index 302ed49..89ac7be 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@emotion/babel-preset-css-prop": "^10.0.23", "@emotion/core": "^10.0.22", "@emotion/styled": "^10.0.27", + "@sanity/block-content-to-react": "^2.0.7", "framer-motion": "^1.10.3", "gatsby": "^2.18.4", "gatsby-image": "^2.2.34", diff --git a/plopfile.js b/plopfile.js index 2f45305..9969218 100644 --- a/plopfile.js +++ b/plopfile.js @@ -1,5 +1,7 @@ const componentGenerator = require('./templates/Component'); +const pageGenerator = require('./templates/Page'); module.exports = function(plop) { plop.setGenerator('component', componentGenerator); + plop.setGenerator('page', pageGenerator); }; diff --git a/src/components/constructs/Figure/Figure.js b/src/components/constructs/Figure/Figure.js new file mode 100644 index 0000000..ec7564c --- /dev/null +++ b/src/components/constructs/Figure/Figure.js @@ -0,0 +1,40 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { getFluidGatsbyImage } from 'gatsby-source-sanity'; +import { withSpacing } from '@utilities/styles/spacing'; +import { figcaptionStyles } from './Figure.styles'; +import clientConfig from '../../../../config/client'; + +import Image from '@elements/Image'; + +const Figure = ({ className, node }) => { + console.log('Figure', node); + if (!node || !node.asset || !node.asset._ref) { + return null; + } + const fluid = getFluidGatsbyImage( + node.asset._ref, + { maxWidth: 675 }, + clientConfig.sanity + ); + + return ( +
+ {node.alt} +
{node.caption}
+
+ ); +}; + +Figure.propTypes = { + className: PropTypes.string, + node: PropTypes.shape({ + alt: PropTypes.string, + caption: PropTypes.string, + asset: PropTypes.shape({ + _ref: PropTypes.string, + }), + }), +}; + +export default withSpacing(Figure); diff --git a/src/components/constructs/Figure/Figure.notes.md b/src/components/constructs/Figure/Figure.notes.md new file mode 100644 index 0000000..0f8d0d0 --- /dev/null +++ b/src/components/constructs/Figure/Figure.notes.md @@ -0,0 +1,9 @@ +# Figure + +--- + +(description) + +### Usage +- … +- … \ No newline at end of file diff --git a/src/components/constructs/Figure/Figure.story.js b/src/components/constructs/Figure/Figure.story.js new file mode 100644 index 0000000..d783cf0 --- /dev/null +++ b/src/components/constructs/Figure/Figure.story.js @@ -0,0 +1,12 @@ +import React from 'react'; +import { storiesOf } from '@storybook/react'; +import Figure from '@constructs/Figure'; +import notes from './Figure.notes.md'; + +storiesOf('Constructs', module).add( + 'Figure', + () => ( +
+ ), + { notes } +); \ No newline at end of file diff --git a/src/components/constructs/Figure/Figure.styles.js b/src/components/constructs/Figure/Figure.styles.js new file mode 100644 index 0000000..dfdeb8b --- /dev/null +++ b/src/components/constructs/Figure/Figure.styles.js @@ -0,0 +1 @@ +export const figcaptionStyles = { textAlign: 'right' }; diff --git a/src/components/constructs/Figure/Figure.test.js b/src/components/constructs/Figure/Figure.test.js new file mode 100644 index 0000000..751c4b1 --- /dev/null +++ b/src/components/constructs/Figure/Figure.test.js @@ -0,0 +1,14 @@ +import React from 'react'; +import renderer from 'react-test-renderer'; +import { render } from "@testing-library/react"; + +import Figure from './Figure'; + +describe('Figure', () => { + it('renders correctly', () => { + const tree = renderer + .create(
) + .toJSON() + expect(tree).toMatchSnapshot() + }) +}); \ No newline at end of file diff --git a/src/components/constructs/Figure/index.js b/src/components/constructs/Figure/index.js new file mode 100644 index 0000000..d45c026 --- /dev/null +++ b/src/components/constructs/Figure/index.js @@ -0,0 +1,3 @@ +import Figure from './Figure'; + +export default Figure; diff --git a/src/components/constructs/Layout/Layout.js b/src/components/constructs/Layout/Layout.js index d228383..93708e2 100644 --- a/src/components/constructs/Layout/Layout.js +++ b/src/components/constructs/Layout/Layout.js @@ -1,7 +1,9 @@ import React, { useMemo, useState, useCallback, createContext } from 'react'; import { Global } from '@emotion/core'; import { GLOBAL_STYLES } from '@global'; -import { useSpring, animated } from 'react-spring'; +// import { useSpring, animated } from 'react-spring'; +import { Spring } from 'react-spring/renderprops'; + import { asideStyles, constructChildrenStyles, @@ -41,76 +43,123 @@ const navLinks = [ export const LayoutContext = createContext({}); -const Layout = ({ - // asideLinks, - children, - className, - // navLinks, - withFooter, - withNav, -}) => { - const onGetInvolved = useCallback(() => {}); - const childrenStyles = useMemo( - () => constructChildrenStyles({ withFooter, withNav }), - [withFooter, withNav] - ); - const [isNextEventOpen, setNextEventOpen] = useState(false); - const closeNextEvent = useCallback(() => setNextEventOpen(false), []); +class Layout extends React.Component { + state = { + isNextEventOpen: false, + }; - const animation = useSpring({ - transform: `translate3d(${isNextEventOpen ? 2 : 100}%, 0, 0)`, - config: { mass: 5, tension: 500, friction: 80 }, - }); + // Context =================================================================== + openNextEvent = () => this.setState({ isNextEventOpen: true }); + closeNextEvent = () => this.setState({ isNextEventOpen: false }); - const context = { - isNextEventOpen, - setNextEventOpen, + childContext = { + isNextEventOpen: this.state.isNextEventOpen, + openNextEvent: this.openNextEvent, + closeNextEvent: this.closeNextEvent, }; - return ( - <> - -
- - - - - - - {/* NAV */} -
+ + ); + } +} + +// const Layout = () => { +// const childrenStyles = useMemo( +// () => constructChildrenStyles({ withFooter, withNav: !isCollapsingNav }), +// [withFooter, isCollapsingNav] +// ); +// const [isNextEventOpen, setNextEventOpen] = useState(true); +// Context =================================================================== +// const openNextEvent = useCallback(() => setNextEventOpen(true), []); +// const closeNextEvent = useCallback(() => setNextEventOpen(false), []); + +// const context = { +// isNextEventOpen, +// setNextEventOpen, +// openNextEvent: this.openNextEvent, +// closeNextEvent: this.closeNextEvent, +// }; + +// const animation = useSpring({ +// transform: `translate3d(${isNextEventOpen ? 2 : 100}%, 0, 0)`, +// config: { mass: 5, tension: 500, friction: 80 }, +// }); +// }; Layout.defaultProps = { withFooter: true, - withNav: true, + isCollapsingNav: false, }; Layout.propTypes = { - className: PropTypes.string, - children: PropTypes.node, asideLinks: PropTypes.arrayOf( PropTypes.shape({ brandName: PropTypes.string, @@ -119,6 +168,8 @@ Layout.propTypes = { out: PropTypes.string, }) ), + className: PropTypes.string, + children: PropTypes.node, navLinks: PropTypes.arrayOf( PropTypes.shape({ title: PropTypes.string, @@ -126,12 +177,17 @@ Layout.propTypes = { }) ), withFooter: PropTypes.bool, - withNav: PropTypes.bool, + isCollapsingNav: PropTypes.bool, }; -export const withLayout = (Component, { withNav, withLayout }) => { +export const withLayout = (Component, options = {}) => { + const { isCollapsingNav, withFooter } = options; const WithLayout = (props) => ( - + ); @@ -143,4 +199,4 @@ export const withLayout = (Component, { withNav, withLayout }) => { return WithLayout; }; -export default Layout; +export default React.memo(Layout); diff --git a/src/components/constructs/Layout/Layout.styles.js b/src/components/constructs/Layout/Layout.styles.js index a9e51d5..88d971f 100644 --- a/src/components/constructs/Layout/Layout.styles.js +++ b/src/components/constructs/Layout/Layout.styles.js @@ -43,13 +43,18 @@ export const asideStyles = { }; export const nextEventStyles = { - position: 'fixed', right: 0, width: NEXT_EVENT_WIDTH, height: '100vh', paddingTop: S.calcSpace(4), paddingBottom: S.calcSpace(4), zIndex: 1000, + [`@media (max-width: ${S.LAYOUT_MOBILE_MAX})`]: { + position: 'fixed', + }, + [`@media (min-width: ${S.LAYOUT_TABLET_MIN})`]: { + position: 'absolute', + }, }; export const wrapperStyles = { @@ -62,9 +67,7 @@ export const wrapperStyles = { }; const subtract = (amount) => `- ${amount}`; - export const constructChildrenStyles = ({ withFooter, withNav }) => ({ - minHeight: `calc(100vh ${withFooter ? subtract(FOOTER_HEIGHT) : ''} ${ - withNav ? subtract(NAV_HEIGHT) : '' - })`, + paddingTop: withNav ? NAV_HEIGHT : 0, + minHeight: `calc(100vh ${withFooter ? subtract(FOOTER_HEIGHT) : ''})`, }); diff --git a/src/components/constructs/Layout/partials/Nav/Nav.js b/src/components/constructs/Layout/partials/Nav/Nav.js index b74ecc7..4b6d2b7 100644 --- a/src/components/constructs/Layout/partials/Nav/Nav.js +++ b/src/components/constructs/Layout/partials/Nav/Nav.js @@ -1,8 +1,10 @@ import React, { useState, useCallback } from 'react'; +import PropTypes from 'prop-types'; import { asideStyles, - mobileNavigationStyles, menuButtonStyles, + mobileNavStyles, + navStyles, } from './Nav.styles'; import { useSpring, animated } from 'react-spring'; import S from '@symbols'; @@ -19,7 +21,7 @@ import Text from '@elements/Text'; const MOBILE_BREAKPOINT = `(max-width: ${S.LAYOUT_MOBILE_MAX})`; const SECONDARY_NAV_BREAKPOINT = '>56'; -const LayoutNav = ({ links, background, onButtonClick }) => { +const LayoutNav = ({ links, background, onButtonClick, isCollapsing }) => { const { [MOBILE_BREAKPOINT]: showMobileNav } = useMedia([MOBILE_BREAKPOINT]); const { [SECONDARY_NAV_BREAKPOINT]: isSecondaryNav } = usePageOffset([ SECONDARY_NAV_BREAKPOINT, @@ -35,8 +37,9 @@ const LayoutNav = ({ links, background, onButtonClick }) => { friction: 100, }, }); + const START = isCollapsing ? -100 : 0; const { translateY } = useSpring({ - translateY: isSecondaryNav ? 0 : -100, + translateY: isSecondaryNav ? 0 : START, config: { mass: 5, tension: 500, @@ -47,7 +50,7 @@ const LayoutNav = ({ links, background, onButtonClick }) => { return showMobileNav ? ( <> `translate3d(0,${y}%,0)`), }} @@ -87,8 +90,26 @@ const LayoutNav = ({ links, background, onButtonClick }) => { ) : ( -