diff --git a/client/.env.development b/client/.env.development index 67707973..2ebda307 100644 --- a/client/.env.development +++ b/client/.env.development @@ -8,6 +8,7 @@ GATSBY_LOCAL_TILES_BASE_URL=http://localhost:5000/data/data-pipeline GATSBY_DATA_PIPELINE_SCORE_PATH_LOCAL=data_pipeline/data/score GATSBY_DATA_PIPELINE_SCORE_PATH=data-pipeline/data/score +GATSBY_DATA_PIPELINE_TRIBAL_PATH=data-pipeline/data/tribal GATSBY_FILE_DL_PATH_SCREENING_TOOL_DATA_ZIP=downloadable/Screening_Tool_Data.zip GATSBY_FILE_DL_PATH_SHAPE_FILE_ZIP=shapefile/usa.zip @@ -22,4 +23,4 @@ GATSBY_MAP_TILES_PATH=tiles # If you want the map to render a MapBox base map (as opposed to the # open source one from CartoDB), please create your own API TOKEN from # your MapBox account and add the token here: -# MAPBOX_STYLES_READ_TOKEN='' +MAPBOX_STYLES_READ_TOKEN='' \ No newline at end of file diff --git a/client/src/components/J40Map.module.scss b/client/src/components/J40Map.module.scss index 926f2f58..835d188a 100644 --- a/client/src/components/J40Map.module.scss +++ b/client/src/components/J40Map.module.scss @@ -32,5 +32,7 @@ .j40Map { @include at-media-max("desktop") { height: 55vh; + @include u-margin-top(7); // Allow for tribal toggle to appear above map on screens < 1024 } + } \ No newline at end of file diff --git a/client/src/components/J40Map.tsx b/client/src/components/J40Map.tsx index c0f10ba3..f56c7f6c 100644 --- a/client/src/components/J40Map.tsx +++ b/client/src/components/J40Map.tsx @@ -26,6 +26,7 @@ import {useFlags} from '../contexts/FlagContext'; import AreaDetail from './AreaDetail'; import MapInfoPanel from './mapInfoPanel'; import MapSearch from './MapSearch'; +import LayerSelector from './LayerSelector'; import TerritoryFocusControl from './territoryFocusControl'; import {getOSBaseMap} from '../data/getOSBaseMap'; @@ -350,6 +351,9 @@ const J40Map = ({location}: IJ40Interface) => { + {/* This will allow to select between the census tract layer and the tribal lands layer */} + + {/** * The ReactMapGL component's props are grouped by the API's documentation. The component also has * some children. diff --git a/client/src/components/LayerSelector/LayerSelector.module.scss b/client/src/components/LayerSelector/LayerSelector.module.scss new file mode 100644 index 00000000..bb491638 --- /dev/null +++ b/client/src/components/LayerSelector/LayerSelector.module.scss @@ -0,0 +1,30 @@ +@use '../../styles/design-system.scss' as *; + +.layerSelectorContainer { + background-color: white; + @include u-padding-left(1); + @include u-padding-right(1); + @include u-padding-top(1); + @include u-padding-bottom(1); + width: fit-content; + z-index: 1; + + // styles for mobile-lg (480px) and greater widths, + @include at-media('mobile-lg') { + position: absolute; + top: units(2.5); + left: 62%; + } + + // styles for less than mobile-lg (480px) + position: absolute; + top: -5.2rem; + +} + + + + + + + \ No newline at end of file diff --git a/client/src/components/LayerSelector/LayerSelector.module.scss.d.ts b/client/src/components/LayerSelector/LayerSelector.module.scss.d.ts new file mode 100644 index 00000000..f8c32767 --- /dev/null +++ b/client/src/components/LayerSelector/LayerSelector.module.scss.d.ts @@ -0,0 +1,12 @@ +declare namespace LayerSelectorNamespace { + export interface ILayerSelectorScss { + layerSelectorContainer: string; + } + } + +declare const LayerSelectorScssModule: LayerSelectorNamespace.ILayerSelectorScss & { + /** WARNING: Only available when `css-loader` is used without `style-loader` or `mini-css-extract-plugin` */ + locals: LayerSelectorNamespace.ILayerSelectorScss; + }; + + export = LayerSelectorScssModule; diff --git a/client/src/components/LayerSelector/LayerSelector.test.tsx b/client/src/components/LayerSelector/LayerSelector.test.tsx new file mode 100644 index 00000000..cfd8ccdf --- /dev/null +++ b/client/src/components/LayerSelector/LayerSelector.test.tsx @@ -0,0 +1,16 @@ +import * as React from 'react'; +import {render} from '@testing-library/react'; +import {LocalizedComponent} from '../../test/testHelpers'; +import LayerSelector from './LayerSelector'; + +describe('rendering of the LayerSelector', () => { + const {asFragment} = render( + + + , + ); + + it('checks if component renders', () => { + expect(asFragment()).toMatchSnapshot(); + }); +}); diff --git a/client/src/components/LayerSelector/LayerSelector.tsx b/client/src/components/LayerSelector/LayerSelector.tsx new file mode 100644 index 00000000..92ee25d4 --- /dev/null +++ b/client/src/components/LayerSelector/LayerSelector.tsx @@ -0,0 +1,61 @@ +import React, {useEffect, useState} from 'react'; +import {useIntl} from 'gatsby-plugin-intl'; +import {Button, ButtonGroup} from '@trussworks/react-uswds'; +import {useWindowSize} from 'react-use'; + + +import * as styles from './LayerSelector.module.scss'; +import * as EXPLORE_COPY from '../../data/copy/explore'; + +const LayerSelector = () => { + const intl = useIntl(); + const [censusSelected, setCensusSelected] = useState(true); + + /** + * At compile-time, the width/height returned by useWindowSize will be X. When the client requests the + * app on run-time from CDN, and the app hydrates, reconcilation no longer occurs and the client is forced + * to use X. + * + * To avoid this, we set the text as a state variable. We also create a useEffect that updates + * that state whenenver the width changes. + * + */ + const {width, height} = useWindowSize(); + const [censusText, setCensusText]= useState(EXPLORE_COPY.MAP.CENSUS_TRACT_LONG); + const [tribalText, setTribalText]= useState(EXPLORE_COPY.MAP.TRIBAL_LANDS_LONG); + + useEffect( () => { + if (width > height) { + setCensusText(EXPLORE_COPY.MAP.CENSUS_TRACT_LONG); + setTribalText(EXPLORE_COPY.MAP.TRIBAL_LANDS_LONG); + } else { + setCensusText(EXPLORE_COPY.MAP.CENSUS_TRACT_SHORT); + setTribalText(EXPLORE_COPY.MAP.TRIBAL_LANDS_SHORT); + } + }, [width]); + + // Handles toggle of tracts and tribal layer selection + const buttonClickHandler = (event) => { + if (event.target.id === 'census' && !censusSelected) { + setCensusSelected(true); + } else if (event.target.id === 'tribal' && censusSelected) { + setCensusSelected(false); + } + }; + + return ( +
+ + + + + +
+ ); +}; + +export default LayerSelector; diff --git a/client/src/components/LayerSelector/__snapshots__/LayerSelector.test.tsx.snap b/client/src/components/LayerSelector/__snapshots__/LayerSelector.test.tsx.snap new file mode 100644 index 00000000..c63b3081 --- /dev/null +++ b/client/src/components/LayerSelector/__snapshots__/LayerSelector.test.tsx.snap @@ -0,0 +1,42 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`rendering of the LayerSelector checks if component renders 1`] = ` + +
+ +
    +
  • + +
  • +
  • + +
  • +
+
+
+`; diff --git a/client/src/components/LayerSelector/index.tsx b/client/src/components/LayerSelector/index.tsx new file mode 100644 index 00000000..61f2645c --- /dev/null +++ b/client/src/components/LayerSelector/index.tsx @@ -0,0 +1,3 @@ +import LayerSelector from './LayerSelector'; + +export default LayerSelector; diff --git a/client/src/data/copy/explore.tsx b/client/src/data/copy/explore.tsx index 00c6f52c..52439cf3 100644 --- a/client/src/data/copy/explore.tsx +++ b/client/src/data/copy/explore.tsx @@ -158,6 +158,26 @@ export const MAP = defineMessages({ defaultMessage: 'US Virgin Islands', description: 'On the explore the map page, on the map, the full name indicating the bounds of US Virgin Islands', }, + CENSUS_TRACT_LONG: { + id: 'explore.map.page.map.layer.selector.tracts.long', + defaultMessage: 'Census Tracts', + description: 'On the explore the map page, on the map, the full name indicating Census Tracts', + }, + CENSUS_TRACT_SHORT: { + id: 'explore.map.page.map.layer.selector.tracts.short', + defaultMessage: 'Tracts', + description: 'On the explore the map page, on the map, the short name indicating Census Tracts', + }, + TRIBAL_LANDS_LONG: { + id: 'explore.map.page.map.layer.selector.tribal.long', + defaultMessage: 'Tribal Lands', + description: 'On the explore the map page, on the map, the full name indicating Tribal Lands', + }, + TRIBAL_LANDS_SHORT: { + id: 'explore.map.page.map.layer.selector.tracts.short', + defaultMessage: 'Tribal', + description: 'On the explore the map page, on the map, the short name indicating Tribal Lands', + }, }); diff --git a/client/src/intl/en.json b/client/src/intl/en.json index ebe6156f..7a3d1210 100644 --- a/client/src/intl/en.json +++ b/client/src/intl/en.json @@ -343,6 +343,18 @@ "defaultMessage": "Communities identified as disadvantaged by the map are those that are marginalized, underserved, and overburdened by pollution. These communities are at or above the thresholds in one or more of eight categories of criteria.", "description": "On the explore the map page, the description of the legend" }, + "explore.map.page.map.layer.selector.tracts.long": { + "defaultMessage": "Census Tracts", + "description": "On the explore the map page, on the map, the full name indicating Census Tracts" + }, + "explore.map.page.map.layer.selector.tracts.short": { + "defaultMessage": "Tribal", + "description": "On the explore the map page, on the map, the short name indicating Tribal Lands" + }, + "explore.map.page.map.layer.selector.tribal.long": { + "defaultMessage": "Tribal Lands", + "description": "On the explore the map page, on the map, the full name indicating Tribal Lands" + }, "explore.map.page.map.search.placeholder.mobile.text": { "defaultMessage": "Search locations", "description": "On the explore the map page, on the map, the placeholder text for search"