From 0731299ec45086c2d35676d10ae0933c89f7680c Mon Sep 17 00:00:00 2001 From: Ricardo Mestre Date: Wed, 31 Mar 2021 22:00:56 +0100 Subject: [PATCH 01/29] Improve layers panel group appearance --- src/styles/panel.js | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/styles/panel.js b/src/styles/panel.js index bcef719..243d18d 100644 --- a/src/styles/panel.js +++ b/src/styles/panel.js @@ -44,20 +44,10 @@ export const PanelSection = styled.section` `; export const PanelSectionHeader = styled.header` - padding: ${glsp( - 0.5, - themeVal('layout.gap.xsmall'), - 0, - themeVal('layout.gap.xsmall') - )}; + padding: ${glsp(0.5, themeVal('layout.gap.xsmall'))}; ${media.mediumUp` - padding: ${glsp( - 1, - themeVal('layout.gap.medium'), - 0, - themeVal('layout.gap.medium') - )}; + padding: ${glsp(0.75, themeVal('layout.gap.medium'))}; `} `; @@ -79,7 +69,7 @@ export const PanelGroup = styled.section` display: flex; flex-flow: column nowrap; flex: 1; - box-shadow: 0 1px 0 0 ${themeVal('color.baseAlphaC')}; + box-shadow: 0 -1px 0 0 ${themeVal('color.baseAlphaC')}; padding: ${glsp(0.5, 0, 0, 0)}; `; From e434b6b1201f1a15fb116845a9e7ccaa4f6a4621 Mon Sep 17 00:00:00 2001 From: Ricardo Mestre Date: Thu, 1 Apr 2021 00:45:26 +0100 Subject: [PATCH 02/29] Tweak layers panel overall appearance --- src/styles/panel.js | 21 ++++++++++++++++--- src/templates/study-single/panel-layer.js | 10 +++++++++ .../study-single/panel-layers-group.js | 2 ++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/styles/panel.js b/src/styles/panel.js index 243d18d..a4eb44f 100644 --- a/src/styles/panel.js +++ b/src/styles/panel.js @@ -47,7 +47,7 @@ export const PanelSectionHeader = styled.header` padding: ${glsp(0.5, themeVal('layout.gap.xsmall'))}; ${media.mediumUp` - padding: ${glsp(0.75, themeVal('layout.gap.medium'))}; + padding: ${glsp(1, themeVal('layout.gap.medium'))}; `} `; @@ -55,7 +55,7 @@ export const PanelSectionHeadline = styled.div``; export const PanelSectionTitle = styled(Heading)` font-size: 1rem; - line-height: 1.5rem; + line-height: 1.25rem; margin: 0; `; @@ -66,11 +66,26 @@ export const PanelSectionBody = styled.div` `; export const PanelGroup = styled.section` + position: relative; display: flex; flex-flow: column nowrap; flex: 1; - box-shadow: 0 -1px 0 0 ${themeVal('color.baseAlphaC')}; padding: ${glsp(0.5, 0, 0, 0)}; + + &::before { + position: absolute; + top: 0; + left: ${glsp(themeVal('layout.gap.xsmall'))}; + right: 0; + content: ''; + pointer-events: none; + height: 1px; + background: ${themeVal('color.baseAlphaC')}; + + ${media.mediumUp` + left: ${glsp(themeVal('layout.gap.medium'))}; + `} + } `; export const PanelGroupHeader = styled.header` diff --git a/src/templates/study-single/panel-layer.js b/src/templates/study-single/panel-layer.js index b558e20..c7caa7e 100644 --- a/src/templates/study-single/panel-layer.js +++ b/src/templates/study-single/panel-layer.js @@ -68,9 +68,19 @@ const LayerBodyInner = styled(Prose)` line-height: 1.25rem; backdrop-filter: saturate(48%); padding: ${glsp(1, themeVal('layout.gap.xsmall'))}; + mask-image: linear-gradient( + to right, + transparent 0, + black ${glsp(themeVal('layout.gap.xsmall'))} + ); ${media.mediumUp` padding: ${glsp(1, themeVal('layout.gap.medium'))}; + mask-image: linear-gradient( + to right, + transparent 0, + black ${glsp(themeVal('layout.gap.medium'))} + ); `} /* stylelint-disable-next-line no-descending-specificity */ diff --git a/src/templates/study-single/panel-layers-group.js b/src/templates/study-single/panel-layers-group.js index 67e49dd..9710cae 100644 --- a/src/templates/study-single/panel-layers-group.js +++ b/src/templates/study-single/panel-layers-group.js @@ -2,6 +2,7 @@ import React from 'react'; import T from 'prop-types'; import styled from 'styled-components'; import { Accordion } from '@devseed-ui/accordion'; +import { glsp } from '@devseed-ui/theme-provider'; import ShadowScrollbar from '@devseed-ui/shadow-scrollbar'; import { @@ -13,6 +14,7 @@ import PanelLayer from './panel-layer'; export const PanelGroupBodyScroll = styled(ShadowScrollbar)` flex: 1; + padding-bottom: ${glsp(1)}; `; function PanelLayersGroup(props) { From e27aca3185fede2fabbe3926297eceb049a0f89e Mon Sep 17 00:00:00 2001 From: Ricardo Mestre Date: Thu, 1 Apr 2021 01:17:16 +0100 Subject: [PATCH 03/29] Improve panel appearance --- src/components/layout.js | 2 -- src/components/page-header.js | 3 +++ src/styles/inpage.js | 3 +++ src/styles/panel.js | 2 +- src/templates/study-single/index.js | 1 - 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/layout.js b/src/components/layout.js index ddb8466..f866468 100644 --- a/src/components/layout.js +++ b/src/components/layout.js @@ -3,7 +3,6 @@ import styled from 'styled-components'; import T from 'prop-types'; import { DevseedUiThemeProvider } from '@devseed-ui/theme-provider'; import { CollecticonsGlobalStyle } from '@devseed-ui/collecticons'; -import { reveal } from '@devseed-ui/animation'; import theme from '../styles/theme'; @@ -23,7 +22,6 @@ const Page = styled.div` const PageBody = styled.main` padding: 0; margin: 0; - animation: ${reveal} 0.32s ease 0s 1; `; const Layout = ({ children, title, metaImage, description }) => { diff --git a/src/components/page-header.js b/src/components/page-header.js index ff73891..ac3a6e8 100644 --- a/src/components/page-header.js +++ b/src/components/page-header.js @@ -12,6 +12,8 @@ import ShareOptions from './share-options'; import { graphql, Link, useStaticQuery } from 'gatsby'; const PageHeaderSelf = styled.header` + position: relative; + z-index: 10; display: grid; grid-template-columns: max-content 1fr; grid-gap: ${glsp(themeVal('layout.gap.xsmall'))}; @@ -20,6 +22,7 @@ const PageHeaderSelf = styled.header` color: #fff; animation: ${reveal} 0.32s ease 0s 1; padding: ${glsp(0.5, themeVal('layout.gap.xsmall'))}; + box-shadow: ${themeVal('boxShadow.elevationD')}; ${media.mediumUp` grid-gap: ${glsp(themeVal('layout.gap.medium'))}; diff --git a/src/styles/inpage.js b/src/styles/inpage.js index e0cf5b0..120bb0e 100644 --- a/src/styles/inpage.js +++ b/src/styles/inpage.js @@ -20,12 +20,15 @@ export const InpageHeader = styled.header` align-items: center; background-color: ${themeVal('color.primary')}; color: #fff; + box-shadow: ${themeVal('boxShadow.elevationD')}; + clip-path: polygon(0 0, 100% 0, 100% 200%, 0% 200%); padding: ${glsp( 0, themeVal('layout.gap.xsmall'), 0.75, themeVal('layout.gap.xsmall') )}; + animation: ${reveal} 0.32s ease 0s 1; ${media.mediumUp` grid-gap: ${glsp(0, themeVal('layout.gap.medium'))}; diff --git a/src/styles/panel.js b/src/styles/panel.js index a4eb44f..7bb978f 100644 --- a/src/styles/panel.js +++ b/src/styles/panel.js @@ -6,7 +6,7 @@ import { headingAlt } from '@devseed-ui/typography'; export const Panel = styled.section` position: relative; - z-index: 20; + z-index: 30; display: flex; flex-flow: column nowrap; width: 18rem; diff --git a/src/templates/study-single/index.js b/src/templates/study-single/index.js index 2ff7c27..9cfedd1 100644 --- a/src/templates/study-single/index.js +++ b/src/templates/study-single/index.js @@ -91,7 +91,6 @@ const ViewMenuLink = styled(StyledLink)` active && css` opacity: 1; - box-shadow: ${themeVal('boxShadow.elevationD')}; &::after { width: 100%; From 7c8b327651a76fb277c7b959c9cad2255dd08530 Mon Sep 17 00:00:00 2001 From: Ricardo Mestre Date: Thu, 1 Apr 2021 10:22:16 +0100 Subject: [PATCH 04/29] Update layer info button color on active state --- src/templates/study-single/panel-layer.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/templates/study-single/panel-layer.js b/src/templates/study-single/panel-layer.js index c7caa7e..37c4d54 100644 --- a/src/templates/study-single/panel-layer.js +++ b/src/templates/study-single/panel-layer.js @@ -129,13 +129,12 @@ function PanelLayer(props) { +
  • - +
  • From 5d72cccec9ded18b2c526e9d195def0fb95c9a1a Mon Sep 17 00:00:00 2001 From: Ricardo Mestre Date: Mon, 5 Apr 2021 17:27:32 +0100 Subject: [PATCH 11/29] Scaffold burger menu --- src/components/burger-options.js | 59 ++++++++++++++++++++++++++++++++ src/components/page-header.js | 14 +++++--- 2 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 src/components/burger-options.js diff --git a/src/components/burger-options.js b/src/components/burger-options.js new file mode 100644 index 0000000..d5f70f2 --- /dev/null +++ b/src/components/burger-options.js @@ -0,0 +1,59 @@ +import React from 'react'; + +import { Button } from '@devseed-ui/button'; +import Dropdown, { + DropTitle, + DropMenu, + DropMenuItem +} from '@devseed-ui/dropdown'; + +function BurgerOptions() { + return ( + ( + + )} + > + Menu + +
  • + + Item A + +
  • +
  • + + Item B + +
  • +
  • + + Item C + +
  • +
  • + + Item D + +
  • +
  • + + Item E + +
  • +
    +
    + ); +} + +export default BurgerOptions; diff --git a/src/components/page-header.js b/src/components/page-header.js index ac3a6e8..ee5f8de 100644 --- a/src/components/page-header.js +++ b/src/components/page-header.js @@ -2,12 +2,12 @@ import React from 'react'; import styled from 'styled-components'; import { glsp, media, themeVal } from '@devseed-ui/theme-provider'; import { reveal } from '@devseed-ui/animation'; -import { VerticalDivider } from '@devseed-ui/toolbar'; import { Heading } from '@devseed-ui/typography'; import { Button } from '../styles/button'; import { filterComponentProps } from '../styles/utils/general'; +import BurgerOptions from './burger-options'; import ShareOptions from './share-options'; import { graphql, Link, useStaticQuery } from 'gatsby'; @@ -67,7 +67,11 @@ const PageNav = styled.nav` const GlobalMenu = styled.ul` display: inline-grid; - grid-gap: ${glsp(0.5)}; + grid-gap: ${glsp(0.25)}; + + ${media.mediumUp` + grid-gap: ${glsp(0.5)}; + `} > * { grid-row: 1; @@ -170,12 +174,12 @@ function PageHeader() { About - - -
  • +
  • + +
  • From ddf8e8c633066e3a8e535bc4bd40ce5fd772327e Mon Sep 17 00:00:00 2001 From: Ricardo Mestre Date: Mon, 5 Apr 2021 18:58:21 +0100 Subject: [PATCH 12/29] Tweak layers panel inner spacing --- src/styles/panel.js | 15 ++++++++++++--- src/templates/study-single/panel-layers-group.js | 1 - 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/styles/panel.js b/src/styles/panel.js index 7bb978f..2bd5b81 100644 --- a/src/styles/panel.js +++ b/src/styles/panel.js @@ -70,7 +70,6 @@ export const PanelGroup = styled.section` display: flex; flex-flow: column nowrap; flex: 1; - padding: ${glsp(0.5, 0, 0, 0)}; &::before { position: absolute; @@ -89,10 +88,20 @@ export const PanelGroup = styled.section` `; export const PanelGroupHeader = styled.header` - padding: ${glsp(0.25, themeVal('layout.gap.xsmall'))}; + padding: ${glsp( + 0.75, + themeVal('layout.gap.xsmall'), + 0.25, + themeVal('layout.gap.xsmall') + )}; ${media.mediumUp` - padding: ${glsp(0.5, themeVal('layout.gap.medium'))}; + padding: ${glsp( + 1, + themeVal('layout.gap.medium'), + 0.5, + themeVal('layout.gap.medium') + )}; `} `; diff --git a/src/templates/study-single/panel-layers-group.js b/src/templates/study-single/panel-layers-group.js index 021df66..2040afa 100644 --- a/src/templates/study-single/panel-layers-group.js +++ b/src/templates/study-single/panel-layers-group.js @@ -14,7 +14,6 @@ import PanelLayer from './panel-layer'; export const PanelGroupBodyScroll = styled(ShadowScrollbar)` flex: 1; - padding-bottom: ${glsp(1)}; `; function PanelLayersGroup(props) { From 5827fc7bd7efd17b952a79d9695f15864fd238bf Mon Sep 17 00:00:00 2001 From: Ricardo Mestre Date: Mon, 5 Apr 2021 19:23:39 +0100 Subject: [PATCH 13/29] Lint --- src/templates/study-single/panel-layers-group.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/templates/study-single/panel-layers-group.js b/src/templates/study-single/panel-layers-group.js index 2040afa..d6186c4 100644 --- a/src/templates/study-single/panel-layers-group.js +++ b/src/templates/study-single/panel-layers-group.js @@ -2,7 +2,6 @@ import React from 'react'; import T from 'prop-types'; import styled from 'styled-components'; import { Accordion } from '@devseed-ui/accordion'; -import { glsp } from '@devseed-ui/theme-provider'; import ShadowScrollbar from '@devseed-ui/shadow-scrollbar'; import { From c27720100ca2db836891c7bd7023c67bc38ee812 Mon Sep 17 00:00:00 2001 From: Ricardo Mestre Date: Mon, 5 Apr 2021 19:33:19 +0100 Subject: [PATCH 14/29] Tidy layer body styles --- src/templates/study-single/panel-layer.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/templates/study-single/panel-layer.js b/src/templates/study-single/panel-layer.js index ff35943..562da33 100644 --- a/src/templates/study-single/panel-layer.js +++ b/src/templates/study-single/panel-layer.js @@ -66,14 +66,13 @@ const LayerBodyInner = styled(Prose)` z-index: 8; display: grid; grid-template-columns: 1fr; - grid-gap: ${glsp()}; + grid-gap: ${glsp(0.75)}; box-shadow: inset 0 1px 0 0 ${themeVal('color.baseAlphaB')}, inset 0 -1px 0 0 ${themeVal('color.baseAlphaB')}; background: ${themeVal('color.baseAlphaA')}; font-size: 0.875rem; line-height: 1.25rem; - backdrop-filter: saturate(48%); - padding: ${glsp(1, themeVal('layout.gap.xsmall'))}; + padding: ${glsp(0.75, themeVal('layout.gap.xsmall'))}; mask-image: linear-gradient( to right, transparent 0, @@ -81,7 +80,7 @@ const LayerBodyInner = styled(Prose)` ); ${media.mediumUp` - padding: ${glsp(1, themeVal('layout.gap.medium'))}; + padding: ${glsp(0.75, themeVal('layout.gap.medium'))}; mask-image: linear-gradient( to right, transparent 0, @@ -90,7 +89,7 @@ const LayerBodyInner = styled(Prose)` `} ${media.largeUp` - padding: ${glsp(1, themeVal('layout.gap.large'))}; + padding: ${glsp(0.75, themeVal('layout.gap.large'))}; mask-image: linear-gradient( to right, transparent 0, @@ -99,7 +98,7 @@ const LayerBodyInner = styled(Prose)` `} ${media.xlargeUp` - padding: ${glsp(1, themeVal('layout.gap.xlarge'))}; + padding: ${glsp(0.75, themeVal('layout.gap.xlarge'))}; mask-image: linear-gradient( to right, transparent 0, @@ -116,7 +115,7 @@ const LayerBodyInner = styled(Prose)` const LayerDetailsList = styled.dl` display: grid; grid-template-columns: minmax(min-content, max-content) 1fr; - grid-gap: ${glsp(0.25, 1)}; + grid-gap: ${glsp(0.125, 0.5)}; dt { ${headingAlt()} From 148362ff97cd25f48cb1ba0f2b666ed9def7c19d Mon Sep 17 00:00:00 2001 From: Ricardo Mestre Date: Mon, 5 Apr 2021 19:52:51 +0100 Subject: [PATCH 15/29] Tweak burger menu copy --- src/components/burger-options.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/burger-options.js b/src/components/burger-options.js index d5f70f2..f2043d3 100644 --- a/src/components/burger-options.js +++ b/src/components/burger-options.js @@ -20,11 +20,11 @@ function BurgerOptions() { useIcon='hamburger-menu' {...props} > - Menu + Browse )} > - Menu + Browse
  • From 5829ae6f21252186a40e9ca6a2217b27a098c6b5 Mon Sep 17 00:00:00 2001 From: Ricardo Mestre Date: Mon, 5 Apr 2021 21:22:47 +0100 Subject: [PATCH 16/29] Tweak layer header inner spacing --- src/templates/study-single/panel-layer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/templates/study-single/panel-layer.js b/src/templates/study-single/panel-layer.js index 562da33..8207318 100644 --- a/src/templates/study-single/panel-layer.js +++ b/src/templates/study-single/panel-layer.js @@ -17,7 +17,7 @@ const LayerSelf = styled(AccordionFold)` const LayerHeader = styled.header` display: grid; grid-auto-columns: 1fr min-content; - grid-gap: ${glsp(0.5)}; + grid-gap: ${glsp(0.5, 1)}; padding: ${glsp(0.5, themeVal('layout.gap.xsmall'))}; align-items: center; From bec83c5f95b95e96b42d29d2840db34b1f657345 Mon Sep 17 00:00:00 2001 From: Daniel da Silva Date: Tue, 6 Apr 2021 09:42:10 +0100 Subject: [PATCH 17/29] Implement responsive menu --- src/components/burger-options.js | 51 ++++++----- src/components/page-header.js | 140 ++++++++++++------------------- src/styles/clean/README.md | 20 +++++ src/styles/clean/link.js | 15 ++++ src/utils/use-breakpoints.js | 49 +++++++++++ 5 files changed, 160 insertions(+), 115 deletions(-) create mode 100644 src/styles/clean/README.md create mode 100644 src/styles/clean/link.js create mode 100644 src/utils/use-breakpoints.js diff --git a/src/components/burger-options.js b/src/components/burger-options.js index f2043d3..c1d87fc 100644 --- a/src/components/burger-options.js +++ b/src/components/burger-options.js @@ -1,5 +1,5 @@ import React from 'react'; - +import T from 'prop-types'; import { Button } from '@devseed-ui/button'; import Dropdown, { DropTitle, @@ -7,7 +7,11 @@ import Dropdown, { DropMenuItem } from '@devseed-ui/dropdown'; -function BurgerOptions() { +import { Link } from '../styles/clean/link'; + +function BurgerOptions(props) { + const { items } = props; + return ( Browse -
  • - - Item A - -
  • -
  • - - Item B - -
  • -
  • - - Item C - -
  • -
  • - - Item D - -
  • -
  • - - Item E - -
  • + {items.map((l) => ( +
  • + + {l.label} + +
  • + ))}
    ); } +BurgerOptions.propTypes = { + items: T.array +}; + export default BurgerOptions; diff --git a/src/components/page-header.js b/src/components/page-header.js index ee5f8de..8592d15 100644 --- a/src/components/page-header.js +++ b/src/components/page-header.js @@ -5,11 +5,11 @@ import { reveal } from '@devseed-ui/animation'; import { Heading } from '@devseed-ui/typography'; import { Button } from '../styles/button'; -import { filterComponentProps } from '../styles/utils/general'; - +import { Link } from '../styles/clean/link'; import BurgerOptions from './burger-options'; import ShareOptions from './share-options'; -import { graphql, Link, useStaticQuery } from 'gatsby'; + +import useBreakpoints from '../utils/use-breakpoints'; const PageHeaderSelf = styled.header` position: relative; @@ -78,108 +78,72 @@ const GlobalMenu = styled.ul` } `; -// See documentation of filterComponentProp as to why this is -const propsToFilter = [ - 'variation', - 'size', - 'hideText', - 'useIcon', - 'active', - 'visuallyDisabled' +const pageMainNavLinks = [ + { + url: '/', + title: 'Visit the home page', + label: 'Welcome' + }, + { + url: '/studies', + partiallyActive: true, + title: 'View Studies page', + label: 'Studies' + }, + { + url: '/support', + title: 'View Project Support page', + label: 'Support' + }, + { + url: '/toolkit', + title: 'View Agricultural Toolkit page', + label: 'Toolkit' + }, + { + url: '/about', + title: 'View About page', + label: 'About' + } ]; -const StyledNavLink = filterComponentProps(Link, propsToFilter); function PageHeader() { - const data = useStaticQuery(graphql` - query { - site { - siteMetadata { - title - } - } - } - `); - - const { title } = data.site.siteMetadata; + const { mediumUp } = useBreakpoints(); return ( - + AEP -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • + {mediumUp && + pageMainNavLinks.map((l) => ( +
  • + +
  • + ))}
  • -
  • - -
  • + {!mediumUp && ( +
  • + +
  • + )}
    diff --git a/src/styles/clean/README.md b/src/styles/clean/README.md new file mode 100644 index 0000000..e56bad1 --- /dev/null +++ b/src/styles/clean/README.md @@ -0,0 +1,20 @@ +# Elements clean of props + +This folder contains element which were filtered for unwanted props. + +This is used to circumvent a bug with styled-component where unwanted props are passed to the dom causing react to display an error: + +``` + `Warning: React does not recognize the hideText prop on a DOM element. + If you intentionally want it to appear in the DOM as a custom attribute, + spell it as lowercase hideText instead. If you accidentally passed it from + a parent component, remove it from the DOM element.` +``` + +This commonly happens when an element is impersonating another with the `as` or `forwardedAs` prop: +``` + +``` + +Because of a bug, all the props passed to `Button` are passed to `Link` without being filtered before rendering, causing the aforementioned error. +Issue tracking the bug: https://github.com/styled-components/styled-components/issues/2131 \ No newline at end of file diff --git a/src/styles/clean/link.js b/src/styles/clean/link.js new file mode 100644 index 0000000..95a4d9a --- /dev/null +++ b/src/styles/clean/link.js @@ -0,0 +1,15 @@ +import { Link as Link$ } from 'gatsby'; + +import { filterComponentProps } from '../utils/general'; + +// See documentation of filterComponentProp as to why this is +const propsToFilter = [ + 'variation', + 'size', + 'hideText', + 'useIcon', + 'active', + 'visuallyDisabled' +]; + +export const Link = filterComponentProps(Link$, propsToFilter); diff --git a/src/utils/use-breakpoints.js b/src/utils/use-breakpoints.js new file mode 100644 index 0000000..45cf4e5 --- /dev/null +++ b/src/utils/use-breakpoints.js @@ -0,0 +1,49 @@ +import { useContext, useEffect, useState } from 'react'; +import { ThemeContext } from 'styled-components'; + +const calculateBreakpoints = (ranges) => { + const w = window.innerWidth; + const mediaKeys = Object.keys(ranges); + return mediaKeys.reduce((acc, k) => { + const [lower, upper] = ranges[k]; + + if (lower) { + acc[`${k}Up`] = w >= lower; + } + if (upper) { + acc[`${k}Down`] = w <= upper; + } + if (lower && upper) { + acc[`${k}Only`] = w >= lower && w <= upper; + } + + return acc; + }, {}); +}; + +export default function useBreakpoints() { + const theme = useContext(ThemeContext); + const [breakpoints, setBreakpoints] = useState( + calculateBreakpoints(theme.mediaRanges) + ); + + useEffect(() => { + const listener = () => { + const newBreak = calculateBreakpoints(theme.mediaRanges); + // Quick compare check to see if properties changed. + for (const r in newBreak) { + if (newBreak[r] !== breakpoints[r]) { + setBreakpoints(newBreak); + return; + } + } + }; + + window.addEventListener('resize', listener); + return () => { + window.removeEventListener('resize', listener); + }; + }, [breakpoints, theme.mediaRanges]); + + return breakpoints; +} From bbf0d3ca613a71d7d5c959d533eb306b8e9783a5 Mon Sep 17 00:00:00 2001 From: Daniel da Silva Date: Tue, 6 Apr 2021 10:07:57 +0100 Subject: [PATCH 18/29] Fix useBreakpoints SSR --- src/utils/use-breakpoints.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/use-breakpoints.js b/src/utils/use-breakpoints.js index 45cf4e5..facaad4 100644 --- a/src/utils/use-breakpoints.js +++ b/src/utils/use-breakpoints.js @@ -2,7 +2,7 @@ import { useContext, useEffect, useState } from 'react'; import { ThemeContext } from 'styled-components'; const calculateBreakpoints = (ranges) => { - const w = window.innerWidth; + const w = typeof window === 'undefined' ? 0 : window.innerWidth; const mediaKeys = Object.keys(ranges); return mediaKeys.reduce((acc, k) => { const [lower, upper] = ranges[k]; From 579b0543675b94be22ff7a293e8c1b01dfe54e58 Mon Sep 17 00:00:00 2001 From: Ricardo Mestre Date: Tue, 6 Apr 2021 10:50:31 +0100 Subject: [PATCH 19/29] Truncate inpage title on small screens --- src/styles/inpage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/styles/inpage.js b/src/styles/inpage.js index 120bb0e..c1c8f3a 100644 --- a/src/styles/inpage.js +++ b/src/styles/inpage.js @@ -15,7 +15,7 @@ export const InpageHeader = styled.header` position: relative; z-index: 20; display: grid; - grid-template-columns: max-content 1fr; + grid-template-columns: auto 1fr; grid-gap: ${glsp(0, themeVal('layout.gap.xsmall'))}; align-items: center; background-color: ${themeVal('color.primary')}; From 32b78ab0b507070c90462386b051fcaeb0d6a1a2 Mon Sep 17 00:00:00 2001 From: Ricardo Mestre Date: Tue, 6 Apr 2021 10:54:35 +0100 Subject: [PATCH 20/29] Tweak global menu appearance --- src/components/page-header.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/page-header.js b/src/components/page-header.js index 8592d15..40f880f 100644 --- a/src/components/page-header.js +++ b/src/components/page-header.js @@ -68,6 +68,7 @@ const PageNav = styled.nav` const GlobalMenu = styled.ul` display: inline-grid; grid-gap: ${glsp(0.25)}; + margin-right: -0.5rem; ${media.mediumUp` grid-gap: ${glsp(0.5)}; From 609e7dc43a4b9f4dda2c3c9e9824879fd99dec8f Mon Sep 17 00:00:00 2001 From: Daniel da Silva Date: Tue, 6 Apr 2021 11:16:21 +0100 Subject: [PATCH 21/29] Fix active state on responsive dropdown menu --- src/components/burger-options.js | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/components/burger-options.js b/src/components/burger-options.js index c1d87fc..30fc07e 100644 --- a/src/components/burger-options.js +++ b/src/components/burger-options.js @@ -1,14 +1,36 @@ import React from 'react'; import T from 'prop-types'; +import styled from 'styled-components'; import { Button } from '@devseed-ui/button'; import Dropdown, { DropTitle, DropMenu, DropMenuItem } from '@devseed-ui/dropdown'; +import { themeVal, glsp } from '@devseed-ui/theme-provider'; +import collecticon from '@devseed-ui/collecticons'; import { Link } from '../styles/clean/link'; +// TODO: Remove once ui library is updated. +const DropMenuItemLink = styled(DropMenuItem)` + &.active { + color: ${themeVal('color.primary')}; + + &::after { + ${collecticon('tick--small')} + position: absolute; + z-index: 1; + top: ${glsp(1 / 4)}; + right: ${glsp(1 / 2)}; + font-size: 1rem; + line-height: 1.5rem; + width: 1.5rem; + text-align: center; + } + } +`; + function BurgerOptions(props) { const { items } = props; @@ -29,10 +51,10 @@ function BurgerOptions(props) { )} > Browse - + {items.map((l) => (
  • - {l.label} - +
  • ))}
    From 0d76cfb6882fda0251f810e0aa54d366850d44c1 Mon Sep 17 00:00:00 2001 From: Olaf Veerman Date: Tue, 6 Apr 2021 12:41:35 +0100 Subject: [PATCH 22/29] Add docs about the legends --- docs/README.md | 46 +++++++++++++++++++++++++++++++++++++ docs/media/line-legend.png | Bin 0 -> 4795 bytes docs/media/wind-legend.png | Bin 0 -> 14212 bytes 3 files changed, 46 insertions(+) create mode 100644 docs/media/line-legend.png create mode 100644 docs/media/wind-legend.png diff --git a/docs/README.md b/docs/README.md index 84ce341..81a466c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -50,6 +50,13 @@ The main information and metadata of each study is managed through a `yml` file, | layers[].source | `object` | Link to the data source | | layers[].source.name | `string` | Name of the source link | | layers[].source.url | `string` | URL of the data source | +| layers[].legendData | `object` | Custom legend | +| layers[].legendData.type | `enum` one of [`gradient`, `line`, `circle`, `symbol`] | Type of legend | +| layers[].legendData.color | `string` | The color of the feature. Applies to `circle` and `line` | +| layers[].legendData.dashed | `boolean` | The color of the feature. Applies to `line` | +| layers[].legendData.min | `string` | Minimum value printed on the x-axis. Applies to `gradient` | +| layers[].legendData.max | `string` | Maximum value printed on the x-axis. Applies to `gradient` +| layers[].legendData.stops | `array` | An array with RGB colors that indicate the stops. Applies to `gradient` ## Map configuration The map of each study is configured using a `json` file that follows the Mapbox Style specification. For a full example, please see [`kenya-mb.json`](/content/study/posts/kenya-mb.json). @@ -166,6 +173,45 @@ New icons can be added to [`/content/icons`](/content/icons). They should be in [To top](#managing-studies) + +# Legends +Broadly speaking, AEP supports two types of legends: symbology for features on the map like circles and lines and gradient legends for raster data like the Global Wind Atlas. + +## Vector layers +The platform will automatically determine the legend for vector layers. It's possible to override these defaults by specifying a `legendData` object on the layer configuration. For example: + +![](media/line-legend.png) + +``` yml +legendData: + type: line + color: '#00FF00' + dashed: true +``` + +## Raster layers +The legend for external data layers can't be automatically determined by AEP and always have to be defined through configuration. The platform currently supports linear gradients, below is an example with 7 color stops. + +![](media/wind-legend.png) + + +``` yml +legendData: + type: gradient + min: '< 2.5' + max: '> 9.75 m/s' + stops: + - '#BEE6FA' + - '#488FC6' + - '#7BC34C' + - '#F9E65B' + - '#F56E2B' + - '#C82333' + - '#A3305C' +``` + +[To top](#managing-studies) + # Troubleshooting ## Map shows an unexpected layer If the map loads with a layer that can't be managed through the layer switcher, it's likely that you added a layer in the Mapbox Style that isn't referenced in the layer configuration of the `yml`. This is by design. It allows you to overlay a contextual layer on the map that the user don't have control over. A use case could be a layer that adds a disputed border. diff --git a/docs/media/line-legend.png b/docs/media/line-legend.png new file mode 100644 index 0000000000000000000000000000000000000000..581d9d2112f4aa7bf19906d17bd40f45bc4f3a6a GIT binary patch literal 4795 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

    pBjH`QsW$l!(xZo+AR>g$5-He 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 Date: Tue, 6 Apr 2021 12:41:46 +0100 Subject: [PATCH 23/29] Update Wind Atlas legend --- content/study/posts/kenya.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/study/posts/kenya.yml b/content/study/posts/kenya.yml index c265483..ad52e65 100644 --- a/content/study/posts/kenya.yml +++ b/content/study/posts/kenya.yml @@ -169,8 +169,8 @@ layers: url: https://globalwindatlas.info/ legendData: type: gradient - min: 10 - max: 1000 + min: '< 2.5' + max: '> 9.75 m/s' stops: - '#BEE6FA' - '#488FC6' From 5a3434f57b8e72dcc5c3bcebd1f94b9293a76b29 Mon Sep 17 00:00:00 2001 From: Olaf Veerman Date: Tue, 6 Apr 2021 13:10:01 +0100 Subject: [PATCH 24/29] Clarify symbol legends --- docs/README.md | 15 +++++++++++++-- docs/media/symbol-legend.png | Bin 0 -> 4877 bytes 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 docs/media/symbol-legend.png diff --git a/docs/README.md b/docs/README.md index 81a466c..a3b98ae 100644 --- a/docs/README.md +++ b/docs/README.md @@ -54,6 +54,7 @@ The main information and metadata of each study is managed through a `yml` file, | layers[].legendData.type | `enum` one of [`gradient`, `line`, `circle`, `symbol`] | Type of legend | | layers[].legendData.color | `string` | The color of the feature. Applies to `circle` and `line` | | layers[].legendData.dashed | `boolean` | The color of the feature. Applies to `line` | +| layers[].legendData.icon | `string` | The basename of the icon, without file extension. Applies to `symbol` | | layers[].legendData.min | `string` | Minimum value printed on the x-axis. Applies to `gradient` | | layers[].legendData.max | `string` | Maximum value printed on the x-axis. Applies to `gradient` | layers[].legendData.stops | `array` | An array with RGB colors that indicate the stops. Applies to `gradient` @@ -177,9 +178,10 @@ New icons can be added to [`/content/icons`](/content/icons). They should be in # Legends Broadly speaking, AEP supports two types of legends: symbology for features on the map like circles and lines and gradient legends for raster data like the Global Wind Atlas. -## Vector layers +## Customizing vector legends The platform will automatically determine the legend for vector layers. It's possible to override these defaults by specifying a `legendData` object on the layer configuration. For example: +### Line ![](media/line-legend.png) ``` yml @@ -189,7 +191,16 @@ legendData: dashed: true ``` -## Raster layers +### Symbol +![](media/symbol-legend.png) + +``` yml +legendData: + type: symbol + color: 'electricity' +``` + +## Defining raster legends The legend for external data layers can't be automatically determined by AEP and always have to be defined through configuration. The platform currently supports linear gradients, below is an example with 7 color stops. ![](media/wind-legend.png) diff --git a/docs/media/symbol-legend.png b/docs/media/symbol-legend.png new file mode 100644 index 0000000000000000000000000000000000000000..89dc60174131a4d31b1ad3aee3a87550617ce336 GIT binary patch literal 4877 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 Date: Tue, 6 Apr 2021 13:10:42 +0100 Subject: [PATCH 25/29] Add validation for custom legends --- schema/validate.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/schema/validate.js b/schema/validate.js index 5bda386..89fd9fa 100644 --- a/schema/validate.js +++ b/schema/validate.js @@ -7,9 +7,8 @@ const mbValidator = require('@mapbox/mapbox-gl-style-spec'); const Schema = require('validate'); const yml = require('js-yaml'); -const fileExists = (val) => { - return fs.existsSync(path.join(__dirname, '../content/study/posts/', val)); -}; +const studyFileExists = (val) => + fs.existsSync(path.join(__dirname, '../content/study/posts/', val)); const studySchema = new Schema({ title: { type: String, required: true }, @@ -24,7 +23,7 @@ const studySchema = new Schema({ ] ], zoomExtent: [{ type: Number }, { type: Number }], - mapConfig: { type: String, use: { fileExists }, required: true }, + mapConfig: { type: String, use: { studyFileExists }, required: true }, study: { consultant: { type: String, required: true }, period: { required: true }, @@ -51,6 +50,18 @@ const studySchema = new Schema({ source: { name: { type: String, required: true }, url: { type: String, required: true } + }, + legendData: { + type: { + type: String, + enum: ['gradient', 'line', 'circle', 'symbol'] + }, + color: { type: String, match: /^#[0-9a-fA-F]{6}$/ }, + dashed: { type: Boolean }, + icon: { type: String }, + min: { type: String }, + max: { type: String }, + stops: [{ type: String, match: /^#[0-9a-fA-F]{6}$/ }] } } ] From 8755afd565384474a43d1e55ce9c006f2a7bc8a8 Mon Sep 17 00:00:00 2001 From: Olaf Veerman Date: Tue, 6 Apr 2021 15:21:18 +0100 Subject: [PATCH 26/29] Add dashed to schema Co-authored-by: Daniel da Silva --- gatsby-node.js | 1 + 1 file changed, 1 insertion(+) diff --git a/gatsby-node.js b/gatsby-node.js index 1e78a9e..1ef52da 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -13,6 +13,7 @@ exports.createSchemaCustomization = ({ actions, schema }) => { stops: [String] color: String icon: String + dashed: Boolean } type PanelLayerSource { From d639654627db8495b1b0dfbb9de391ff9cc64d59 Mon Sep 17 00:00:00 2001 From: Olaf Veerman Date: Tue, 6 Apr 2021 15:22:19 +0100 Subject: [PATCH 27/29] Fix doc error --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index a3b98ae..b0d9491 100644 --- a/docs/README.md +++ b/docs/README.md @@ -53,7 +53,7 @@ The main information and metadata of each study is managed through a `yml` file, | layers[].legendData | `object` | Custom legend | | layers[].legendData.type | `enum` one of [`gradient`, `line`, `circle`, `symbol`] | Type of legend | | layers[].legendData.color | `string` | The color of the feature. Applies to `circle` and `line` | -| layers[].legendData.dashed | `boolean` | The color of the feature. Applies to `line` | +| layers[].legendData.dashed | `boolean` | Use a dashed line. Applies to `line` | | layers[].legendData.icon | `string` | The basename of the icon, without file extension. Applies to `symbol` | | layers[].legendData.min | `string` | Minimum value printed on the x-axis. Applies to `gradient` | | layers[].legendData.max | `string` | Maximum value printed on the x-axis. Applies to `gradient` From 11f3bf63427fe02fe21aa543aacc14f791b87f26 Mon Sep 17 00:00:00 2001 From: Olaf Veerman Date: Tue, 6 Apr 2021 15:45:37 +0100 Subject: [PATCH 28/29] Remove legend override used for testing purposes --- content/study/posts/kenya.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/content/study/posts/kenya.yml b/content/study/posts/kenya.yml index ad52e65..009d7a4 100644 --- a/content/study/posts/kenya.yml +++ b/content/study/posts/kenya.yml @@ -155,10 +155,6 @@ layers: source: name: energydata.info url: https://energydata.info/dataset/kenya-potential-new-mini-grid-sites - legendData: - type: line - color: '#00FF00' - dashed: true - id: wind name: Mean wind speed category: contextual From 3c00618262c45945db43d91b3f0dda46717f9f3f Mon Sep 17 00:00:00 2001 From: Olaf Veerman Date: Tue, 6 Apr 2021 15:55:42 +0100 Subject: [PATCH 29/29] Rename layer categories --- content/study/posts/kenya.yml | 36 ++++++++++++++--------------- schema/validate.js | 2 +- src/templates/study-single/carto.js | 12 +++++----- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/content/study/posts/kenya.yml b/content/study/posts/kenya.yml index 009d7a4..bd67534 100644 --- a/content/study/posts/kenya.yml +++ b/content/study/posts/kenya.yml @@ -14,7 +14,7 @@ platform: layers: - id: 11kv name: Existing grid 11kv - category: contextual + category: input mbLayer: 11kv info: This dataset contains electricity transmission lines with different voltage levels as well as unidentified voltage in Kenya. The dataset was provided by Kenya Power and Lighting Company (KPLC). source: @@ -22,7 +22,7 @@ layers: url: https://energydata.info/dataset/kenya-kenya-electricity-network - id: 33kv name: Existing grid 33kv - category: contextual + category: input mbLayer: 33kv info: This dataset contains electricity transmission lines with different voltage levels as well as unidentified voltage in Kenya. The dataset was provided by Kenya Power and Lighting Company (KPLC). source: @@ -30,7 +30,7 @@ layers: url: https://energydata.info/dataset/kenya-kenya-electricity-network - id: 66kv name: Existing grid 66kv - category: contextual + category: input mbLayer: 66kv info: This dataset contains electricity transmission lines with different voltage levels as well as unidentified voltage in Kenya. The dataset was provided by Kenya Power and Lighting Company (KPLC). source: @@ -38,7 +38,7 @@ layers: url: https://energydata.info/dataset/kenya-kenya-electricity-network - id: 132kv name: Existing grid 132kv - category: contextual + category: input mbLayer: 132kv info: This dataset contains electricity transmission lines with different voltage levels as well as unidentified voltage in Kenya. The dataset was provided by Kenya Power and Lighting Company (KPLC). source: @@ -46,7 +46,7 @@ layers: url: https://energydata.info/dataset/kenya-kenya-electricity-network - id: 220kv name: Existing grid 220kv - category: contextual + category: input mbLayer: 220kv info: This dataset contains electricity transmission lines with different voltage levels as well as unidentified voltage in Kenya. The dataset was provided by Kenya Power and Lighting Company (KPLC). source: @@ -54,7 +54,7 @@ layers: url: https://energydata.info/dataset/kenya-kenya-electricity-network - id: transformers name: Distribution Transformers - category: contextual + category: input mbLayer: transformers info: The dataset contains Distribution Transformers in Kenya.The dataset was provided by Kenya Power and Lighting Company (KPLC). source: @@ -62,7 +62,7 @@ layers: url: https://energydata.info/dataset/kenya-distribution-transformers - id: substations name: Primary Substations - category: contextual + category: input mbLayer: substation info: The dataset contains primary substations in Kenya. The dataset was provided by Kenya Power and Lighting Company (KPLC). source: @@ -70,7 +70,7 @@ layers: url: https://energydata.info/dataset/kenya-primary-substations - id: transmission name: Transmission Stations - category: contextual + category: input mbLayer: transmission-stations info: The data contains transmission station locations in Kenya. The dataset was provided by Kenya Power and Lighting Company (KPLC). source: @@ -78,7 +78,7 @@ layers: url: https://energydata.info/dataset/kenya-transmission-stations - id: power name: Power Stations - category: contextual + category: input disabled: true mbLayer: 11kv info: The dataset contains location of Power Stations in Kenya. It was provided by Kenya Power and Lighting Company (KPLC). @@ -87,7 +87,7 @@ layers: url: https://energydata.info/dataset/kenya-power-stations - id: population name: Population and Household Dataset (2009 & 2016) - category: contextual + category: input disabled: true mbLayer: 11kv info: Population and Household statistics for the years 2009 and 2016 as well as the enumeration areas.The dataset was provided by Kenya National Bureau of Statistics (KNBS). @@ -96,7 +96,7 @@ layers: url: https://energydata.info/dataset/kenya-population-and-household-dataset - id: roads name: Roads - category: contextual + category: input mbLayer: roads info: Road network in Kenya. The dataset was provided by Kenya Roads Board (KRB). source: @@ -104,7 +104,7 @@ layers: url: https://energydata.info/dataset/kenya-roads-1 - id: health name: Healthcare Facilities - category: contextual + category: input disabled: true mbLayer: 11kv info: Data on healthcare facility locations in Kenya. The dataset was provided by the Government of Kenya. @@ -113,7 +113,7 @@ layers: url: https://energydata.info/dataset/kenya-healthcare-facilities - id: education name: Schools - category: contextual + category: input mbLayer: education info: School locations in Kenya. It comprises Primary and Secondary Schools. The dataset was provided by Kenya Ministry of Education. source: @@ -121,7 +121,7 @@ layers: url: https://energydata.info/dataset/kenya-schools - id: minigrid name: Overview of Off-Grid Electricity Service Areas - category: result + category: outcome mbLayer: minigrid visible: true info: This dataset represents the locations of existing mini-grids, mini-grids under development, proposed KOSAP mini-grids, and potential SHS markets in Kenya. This is the output of preliminary GIS analysis funded by the World Bank and undertaken in 2017. @@ -130,7 +130,7 @@ layers: url: https://energydata.info/dataset/kenya-overview-of-off-grid-electricity-service-areas - id: grid-expansion name: Grid Expansion Projects - category: result + category: outcome disabled: true mbLayer: 11kv info: This dataset represents potential grid expansion projects identified through a least-cost geospatial analysis undertaken over the period 2017-2018. @@ -139,7 +139,7 @@ layers: url: https://energydata.info/dataset/kenya-grid-expansion - id: minigrid-expansion name: Existing Mini-Grid Expansion Projects - category: result + category: outcome mbLayer: minigrid-existing visible: true info: Potential expansion projects for existing mini-grids; the expansion projects were identified through a least-cost geospatial analysis undertaken over the period 2017-2018. @@ -148,7 +148,7 @@ layers: url: https://energydata.info/dataset/kenya-potential-expansion-of-existing-mini-grids - id: minigrid-new name: New Mini-Grid Projects - category: result + category: outcome mbLayer: minigrid-proposed visible: true info: Potential mini-grid projects; these projects were identified through a least-cost geospatial analysis undertaken over the period 2017-2018. @@ -157,7 +157,7 @@ layers: url: https://energydata.info/dataset/kenya-potential-new-mini-grid-sites - id: wind name: Mean wind speed - category: contextual + category: input mbLayer: wind info: The mean wind speed is a measure of the wind resource. Higher mean wind speeds normally indicate better wind resources, but mean wind power density gives a more accurate indication of the available wind resource. source: diff --git a/schema/validate.js b/schema/validate.js index 89fd9fa..9e9b0e4 100644 --- a/schema/validate.js +++ b/schema/validate.js @@ -40,7 +40,7 @@ const studySchema = new Schema({ name: { type: String, required: true }, category: { type: String, - enum: ['contextual', 'result'], + enum: ['input', 'outcome'], required: true }, visible: { type: Boolean }, diff --git a/src/templates/study-single/carto.js b/src/templates/study-single/carto.js index 5e00a05..aa47a32 100644 --- a/src/templates/study-single/carto.js +++ b/src/templates/study-single/carto.js @@ -92,8 +92,8 @@ function StudySingleCarto(props) { // Group panel layers by their category and get the config for each map layer // being controlled. This is needed to construct the legend. const { - result: panelResultLayers, - contextual: panelContextualLayers + outcome: panelOutcomeLayers, + input: panelInputLayers } = useMemo(() => { const mapLayers = applyMapLayersDefaults(mapConfig?.layers); @@ -143,13 +143,13 @@ function StudySingleCarto(props) {