Move survey button to footer (#897)

* Move survey button to header

- remove SurveyFab component as it's no longer a FAB
- place button in heading
- add tests
- add pageStyles module

* Add retry and timeout to failing test

* Move survey button to bottom of page

* Fix surveyButton failing a11y

- udpate snapshots

* Align survey button to Contact nav link
This commit is contained in:
Vim 2021-11-19 13:01:47 -05:00 committed by GitHub
parent 474d010bf4
commit fff9b86d7a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 177 additions and 116 deletions

View file

@ -9,7 +9,20 @@ describe('Does the map zoom and adjust to lat/long correctly?', () => {
cy.get('.mapboxgl-ctrl-icon.mapboxgl-ctrl-zoom-in').click(); cy.get('.mapboxgl-ctrl-icon.mapboxgl-ctrl-zoom-in').click();
cy.url().should('include', '#4'); cy.url().should('include', '#4');
}); });
it('should show the correct lat/lng coordinates in the URL', () => { it('should show the correct lat/lng coordinates in the URL',
{
retries: {
runMode: 3,
openMode: 3,
},
defaultCommandTimeout: 4000,
execTimeout: 10000,
taskTimeout: 10000,
pageLoadTimeout: 10000,
requestTimeout: 5000,
responseTimeout: 10000,
},
() => {
cy.getMap().then((map) => { cy.getMap().then((map) => {
cy.panTo(map, [-77.9, 35.04]); cy.panTo(map, [-77.9, 35.04]);
cy.url().should('include', '#4/35.04/-77.9'); cy.url().should('include', '#4/35.04/-77.9');

View file

@ -8,6 +8,7 @@ import {useIntl} from 'gatsby-plugin-intl';
import J40MainGridContainer from './J40MainGridContainer'; import J40MainGridContainer from './J40MainGridContainer';
import {hyphenizeString} from '../../cypress/integration/common/helpers'; import {hyphenizeString} from '../../cypress/integration/common/helpers';
import SurveyButton from './SurveyButton';
// @ts-ignore // @ts-ignore
import whitehouseIcon from '../images/eop-seal.svg'; import whitehouseIcon from '../images/eop-seal.svg';
@ -111,6 +112,7 @@ const J40Footer = () => {
/> />
</J40MainGridContainer> </J40MainGridContainer>
</div> </div>
<SurveyButton />
</footer> </footer>
); );
}; };

View file

@ -0,0 +1,26 @@
@use '../../styles/design-system.scss' as *;
.surveyButtonContainer {
position: relative;
.surveyButton {
position: absolute;
bottom: 0;
right: 2.2rem;
@include at-media-max("desktop") {
right: 0;
}
border-radius: 5px 5px 0 0;
@include u-height(6);
z-index: 2;
@include u-text("gray-90");
@include u-bg("yellow-20v");
&:hover {
@include u-bg("yellow-20");
@include u-text("gray-90");
}
}
}

View file

@ -0,0 +1,13 @@
declare namespace SurveyButtonNamespace {
export interface ISurveyButtonScss {
surveyButton: string;
surveyButtonContainer: string;
}
}
declare const SurveyButtonScssModule: SurveyButtonNamespace.ISurveyButtonScss & {
/** WARNING: Only available when `css-loader` is used without `style-loader` or `mini-css-extract-plugin` */
locals: SurveyButtonNamespace.ISurveyButtonScss;
};
export = SurveyButtonScssModule;

View file

@ -1,13 +1,12 @@
import * as React from 'react'; import * as React from 'react';
import {render} from '@testing-library/react'; import {render} from '@testing-library/react';
import {LocalizedComponent} from '../../test/testHelpers'; import {LocalizedComponent} from '../../test/testHelpers';
import SurveyFab from './SurveyFab'; import SurveyButton from './SurveyButton';
import {onClickHandler} from './SurveyFab'; import {onClickHandler} from './SurveyButton';
describe('rendering of the SurveyButton', () => {
describe('rendering of the SurveyFab', () => {
const {asFragment} = render( const {asFragment} = render(
<LocalizedComponent> <LocalizedComponent>
<SurveyFab /> <SurveyButton />
</LocalizedComponent>, </LocalizedComponent>,
); );
@ -15,7 +14,6 @@ describe('rendering of the SurveyFab', () => {
expect(asFragment()).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
}); });
describe('test clickHandler', () => { describe('test clickHandler', () => {
it('clickHandler should fire successfully', () => { it('clickHandler should fire successfully', () => {
onClickHandler(); onClickHandler();

View file

@ -0,0 +1,27 @@
import React from 'react';
import {useIntl} from 'gatsby-plugin-intl';
import {Button} from '@trussworks/react-uswds';
import * as styles from './SurveyButton.module.scss';
import * as CONTACT_COPY from '../../data/copy/contact';
import J40MainGridContainer from '../J40MainGridContainer';
export const onClickHandler = () => {
Object.assign(document.createElement('a'), {target: '_blank', href: 'https://www.surveymonkey.com/r/cejst-survey'}).click();
};
const SurveyButton = () => {
const intl = useIntl();
return (
<J40MainGridContainer className={styles.surveyButtonContainer}>
<Button
type='button'
className={styles.surveyButton}
onClick={() => onClickHandler()}>
{intl.formatMessage(CONTACT_COPY.PAGE_INTRO.SURVEY_TEXT)}
</Button>
</J40MainGridContainer>
);
};
export default SurveyButton;

View file

@ -0,0 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`rendering of the SurveyButton checks if component renders 1`] = `
<DocumentFragment>
<div
class="grid-container-desktop-lg"
data-testid="gridContainer"
>
<button
class="usa-button"
data-testid="button"
type="button"
>
Tell us how we're doing
</button>
</div>
</DocumentFragment>
`;

View file

@ -0,0 +1,3 @@
import SurveyButton from './SurveyButton';
export default SurveyButton;

View file

@ -1,18 +0,0 @@
@use '../../styles/design-system.scss' as *;
.surveyFabContainer {
position:fixed;
z-index: 1;
@include u-bottom(3);
@include u-right(3);
@include u-radius(1);
box-shadow: 1.2px 2.4px 2.4px hsl(0deg 0% 0% / 0.46);
@include u-text('gray-90');
@include u-bg('yellow-20v');
&:hover {
@include u-bg('yellow-20');
@include u-text('gray-90');
}
}

View file

@ -1,12 +0,0 @@
declare namespace SurveyFabNamespace {
export interface ISurveyFabScss {
surveyFabContainer: string;
}
}
declare const SurveyFabScssModule: SurveyFabNamespace.ISurveyFabScss & {
/** WARNING: Only available when `css-loader` is used without `style-loader` or `mini-css-extract-plugin` */
locals: SurveyFabNamespace.ISurveyFabScss;
};
export = SurveyFabScssModule;

View file

@ -1,24 +0,0 @@
import React from 'react';
import {useIntl} from 'gatsby-plugin-intl';
import {Button} from '@trussworks/react-uswds';
import * as styles from './SurveyFab.module.scss';
import * as CONTACT_COPY from '../../data/copy/contact';
export const onClickHandler = () => {
Object.assign(document.createElement('a'), {target: '_blank', href: 'https://www.surveymonkey.com/r/cejst-survey'}).click();
};
const SurveyFab = () => {
const intl = useIntl();
return (
<Button
type='button'
className={styles.surveyFabContainer}
onClick={() => onClickHandler()}>
{intl.formatMessage(CONTACT_COPY.PAGE_INTRO.SURVEY_TEXT)}
</Button>
);
};
export default SurveyFab;

View file

@ -1,13 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`rendering of the SurveyFab checks if component renders 1`] = `
<DocumentFragment>
<button
class="usa-button"
data-testid="button"
type="button"
>
Take our survey!
</button>
</DocumentFragment>
`;

View file

@ -1,3 +0,0 @@
import SurveyFab from './SurveyFab';
export default SurveyFab;

View file

@ -176,6 +176,18 @@ exports[`J40Footer renders correctly 1`] = `
</div> </div>
</div> </div>
</div> </div>
<div
class="grid-container-desktop-lg"
data-testid="gridContainer"
>
<button
class="usa-button"
data-testid="button"
type="button"
>
Tell us how we're doing
</button>
</div>
</footer> </footer>
</DocumentFragment> </DocumentFragment>
`; `;

View file

@ -1,10 +1,10 @@
import React, {ReactNode} from 'react'; import React, {ReactNode} from 'react';
import {Helmet} from 'react-helmet';
import {URLFlagProvider} from '../contexts/FlagContext';
import J40Header from './J40Header'; import J40Header from './J40Header';
import J40Footer from './J40Footer'; import J40Footer from './J40Footer';
import {URLFlagProvider} from '../contexts/FlagContext';
import {Helmet} from 'react-helmet';
import SurveyFab from './SurveyFab';
interface ILayoutProps { interface ILayoutProps {
children: ReactNode, children: ReactNode,
location: Location, location: Location,
@ -31,7 +31,6 @@ const Layout = ({children, location, title}: ILayoutProps) => {
<J40Header /> <J40Header />
<main id={'main-content'}> <main id={'main-content'}>
{children} {children}
<SurveyFab />
</main> </main>
<J40Footer/> <J40Footer/>
</URLFlagProvider> </URLFlagProvider>

View file

@ -23,7 +23,7 @@ export const PAGE_INTRO = defineMessages({
}, },
SURVEY_TEXT: { SURVEY_TEXT: {
id: 'fab.survey.text', id: 'fab.survey.text',
defaultMessage: 'Take our survey!', defaultMessage: `Tell us how we're doing`,
description: 'text for floating action button', description: 'text for floating action button',
}, },
}); });

View file

@ -309,6 +309,9 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
class="grid-container-desktop-lg" class="grid-container-desktop-lg"
data-testid="gridContainer" data-testid="gridContainer"
> >
<h1>
Contact
</h1>
<div <div
class="grid-row" class="grid-row"
data-testid="grid" data-testid="grid"
@ -317,9 +320,6 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
class="grid-col" class="grid-col"
data-testid="grid" data-testid="grid"
> >
<h1>
Contact
</h1>
<h2> <h2>
Email us Email us
</h2> </h2>
@ -336,13 +336,6 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div> </div>
</div> </div>
</div> </div>
<button
class="usa-button"
data-testid="button"
type="button"
>
Take our survey!
</button>
</main> </main>
<footer <footer
class="j40-footer" class="j40-footer"
@ -518,6 +511,18 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div> </div>
</div> </div>
</div> </div>
<div
class="grid-container-desktop-lg"
data-testid="gridContainer"
>
<button
class="usa-button"
data-testid="button"
type="button"
>
Tell us how we're doing
</button>
</div>
</footer> </footer>
</DocumentFragment> </DocumentFragment>
`; `;

View file

@ -656,13 +656,6 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div> </div>
</div> </div>
</div> </div>
<button
class="usa-button"
data-testid="button"
type="button"
>
Take our survey!
</button>
</main> </main>
<footer <footer
class="j40-footer" class="j40-footer"
@ -838,6 +831,18 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div> </div>
</div> </div>
</div> </div>
<div
class="grid-container-desktop-lg"
data-testid="gridContainer"
>
<button
class="usa-button"
data-testid="button"
type="button"
>
Tell us how we're doing
</button>
</div>
</footer> </footer>
</DocumentFragment> </DocumentFragment>
`; `;

View file

@ -1116,13 +1116,6 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div> </div>
</div> </div>
</div> </div>
<button
class="usa-button"
data-testid="button"
type="button"
>
Take our survey!
</button>
</main> </main>
<footer <footer
class="j40-footer" class="j40-footer"
@ -1298,6 +1291,18 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div> </div>
</div> </div>
</div> </div>
<div
class="grid-container-desktop-lg"
data-testid="gridContainer"
>
<button
class="usa-button"
data-testid="button"
type="button"
>
Tell us how we're doing
</button>
</div>
</footer> </footer>
</DocumentFragment> </DocumentFragment>
`; `;

View file

@ -23,7 +23,9 @@ const CEJSTPage = ({location}: IMapPageProps) => {
return (<Layout location={location} title={intl.formatMessage(EXPLORE_COPY.PAGE_INTRO.PAGE_TILE)}> return (<Layout location={location} title={intl.formatMessage(EXPLORE_COPY.PAGE_INTRO.PAGE_TILE)}>
<J40MainGridContainer> <J40MainGridContainer>
<h1>{intl.formatMessage(EXPLORE_COPY.PAGE_INTRO.PAGE_HEADING)}</h1> <h1>{intl.formatMessage(EXPLORE_COPY.PAGE_INTRO.PAGE_HEADING)}</h1>
<Grid row className={'j40-mb-5'}> <Grid row className={'j40-mb-5'}>
<Grid col={12} tablet={{col: 6}}> <Grid col={12} tablet={{col: 6}}>
<section> <section>

View file

@ -6,7 +6,6 @@ import J40MainGridContainer from '../components/J40MainGridContainer';
import Layout from '../components/layout'; import Layout from '../components/layout';
import * as CONTACT_COPY from '../data/copy/contact'; import * as CONTACT_COPY from '../data/copy/contact';
interface IContactPageProps { interface IContactPageProps {
location: Location; location: Location;
} }
@ -18,11 +17,11 @@ const ContactPage = ({location}: IContactPageProps) => {
<Layout location={location} title={intl.formatMessage(CONTACT_COPY.PAGE_INTRO.PAGE_TILE)}> <Layout location={location} title={intl.formatMessage(CONTACT_COPY.PAGE_INTRO.PAGE_TILE)}>
<J40MainGridContainer> <J40MainGridContainer>
<h1>{intl.formatMessage(CONTACT_COPY.PAGE_INTRO.PAGE_HEADING)}</h1>
<Grid row> <Grid row>
<Grid col> <Grid col>
<h1>
{intl.formatMessage(CONTACT_COPY.PAGE_INTRO.PAGE_HEADING)}
</h1>
<h2> <h2>
{intl.formatMessage(CONTACT_COPY.PAGE_INTRO.PAGE_SUB_HEADING)} {intl.formatMessage(CONTACT_COPY.PAGE_INTRO.PAGE_SUB_HEADING)}
</h2> </h2>

View file

@ -37,7 +37,9 @@ const IndexPage = ({location}: IndexPageProps) => {
<Layout location={location} title={intl.formatMessage(ABOUT_COPY.PAGE.TILE)}> <Layout location={location} title={intl.formatMessage(ABOUT_COPY.PAGE.TILE)}>
<J40MainGridContainer> <J40MainGridContainer>
<h1 data-cy={'about-page-heading'}>{intl.formatMessage(ABOUT_COPY.PAGE.HEADING)}</h1> <h1 data-cy={'about-page-heading'}>{intl.formatMessage(ABOUT_COPY.PAGE.HEADING)}</h1>
<AboutCardsContainer> <AboutCardsContainer>
<AboutCard <AboutCard
size={'large'} size={'large'}

View file

@ -22,7 +22,9 @@ const IndexPage = ({location}: MethodPageProps) => {
<Layout location={location} title={intl.formatMessage(METHODOLOGY_COPY.PAGE.TILE)}> <Layout location={location} title={intl.formatMessage(METHODOLOGY_COPY.PAGE.TILE)}>
<J40MainGridContainer> <J40MainGridContainer>
<h1>{intl.formatMessage(METHODOLOGY_COPY.PAGE.HEADING)}</h1> <h1>{intl.formatMessage(METHODOLOGY_COPY.PAGE.HEADING)}</h1>
<Grid row gap className={'j40-mb-5'}> <Grid row gap className={'j40-mb-5'}>
<Grid col={12} tablet={{col: 6}}> <Grid col={12} tablet={{col: 6}}>
<section> <section>