From 9d26d663d45a37587520c8a2fb32d1a046074ab5 Mon Sep 17 00:00:00 2001 From: Bernard Date: Thu, 28 Jan 2021 06:02:55 -0600 Subject: [PATCH] Add usa banner component (#874) * [WNMGDS-480] Add usa banner component (#869) * move scss to design system * add doc site page * Update doc page * Add examples * Add component * Add e2e test * PR feedback * Add USA flag as SVG * remove PNG version of flag and update SVG * Add USA banner to export list * Update examples * Doc page feedback * Add banner icons * Update styles and remove utilities * Adding React Icons * Add lock SVG * Export icons * Update styles * Update component * Rename icons * Remove icons from export * Remove component from doc site * Update doc site header * Add color variables for banner bg and text * Add babel-plugin-inline-react-svg dep * Remove JSX SVG icons * Add classes to SVGs * Update SVG references * Update example * Remove props from Doc * Remove props and update toggle * Add and update tests * Remove classes from SVGs in images folder * Add class names to SVGs * Move theme variables to component SCSS * Delete doc site banner images that are not needed * Update HTML example to use SVGs * Remove old banner props from doc site header * Update banner * Test updates * Update packages/design-system/src/components/UsaBanner/UsaBanner.e2e.test.js Co-authored-by: Ni Chia * Style updates for IE11 * Add Draft status Co-authored-by: bernardwang Co-authored-by: Ni Chia * [WNMGDS-698] Add Spanish translation prop to US banner component (#888) * Add prop for rendering USA banner in Spanish * Add testing for localeSpanish prop * Update to check for localeSpanish prop only once * Update to use locale prop instead of localeSpanish * Update test and snapshot * Add typescript definition file * Add the react prop info to the doc page * Add Spanish version of usa banner to js examples * Move banner text to .json file * Revert back to svg path references in HTML example * Update test * Rename variables * Update SVG references in HTML example * Wrap multipl svg elements by elements * Update html example and snapshots from test * Add Spanish banner to html example * Update html example Co-authored-by: Scott Weber * [WNMGDS-718] Add responsive styling to USA banner component (#904) * Add responsiveness to small viewport * Fix banner-content padding * Show close-alt.svg on background * Fix flag from squishing on small view * Fix banner header from wrapping incorrectly * Update html example * Update snapshots * Tidy scss code variables * Replace background property with individual background-image properties and expand banner by default for HTML example * [WMNGDS-722] Update Banner scss (#916) * Update banner scss * Update svg file for accessibility * Update banner examples and test * Fix svgmin options to keep accessiblity flags * Update docs site examples * Add loadash to generate uniqueID * Update svgmin option to keep Role attribute * Replace rem unit with px * Fix -x * Fix accessiblity issue with inline svg file * Update html example and test file * Add role prop to inline SVG file * Add className prop and update as per feedback * Update test * Add lang attribute for Spanish language and update aria-label to Spanish * Add Spanish version for the Flag and Lock SVG icons * Update tes snapshots * Update packages/design-system-docs/src/pages/components/UsaBanner/_UsaBanner.docs.scss Co-authored-by: Scott Weber * Update packages/design-system/src/components/UsaBanner/UsaBanner.jsx Co-authored-by: Scott Weber * Update packages/design-system/src/types/UsaBanner/UsaBanner.d.ts Co-authored-by: Scott Weber Co-authored-by: Scott Weber Co-authored-by: Ni Chia --- lerna.json | 4 +- .../src/images/icon-dot-gov.svg | 1 - .../src/images/icon-https.svg | 1 - .../src/images/icon-lock.svg | 1 - .../src/images/us_flag_small.png | Bin 176 -> 0 bytes .../UsaBanner/UsaBanner.example.jsx | 13 + .../components/UsaBanner/_UsaBanner.docs.scss | 45 ++ .../UsaBanner/usabanner.example.html | 172 ++++++ .../src/scripts/components/Header.jsx | 81 ++- .../src/scripts/components/UsaBanner.jsx | 81 --- .../design-system-docs/src/styles/_index.scss | 1 - .../src/styles/components/_UsaBanner.scss | 97 ---- .../gulp/common/copyFontsImages.js | 11 + .../UsaBanner/UsaBanner.e2e.test.js | 20 + .../src/components/UsaBanner/UsaBanner.jsx | 119 ++++ .../components/UsaBanner/UsaBanner.test.jsx | 53 ++ .../__snapshots__/UsaBanner.test.jsx.snap | 520 ++++++++++++++++++ .../design-system/src/components/index.js | 1 + .../design-system/src/images/close-alt.svg | 3 + .../src/images/usa-banner-dot-gov.svg | 6 + .../src/images/usa-banner-flag-es.svg | 11 + .../src/images/usa-banner-flag.svg | 11 + .../src/images/usa-banner-https.svg | 6 + .../src/images/usa-banner-lock-es.svg | 5 + .../src/images/usa-banner-lock.svg | 5 + packages/design-system/src/locale/en.json | 17 + packages/design-system/src/locale/es.json | 17 + .../src/styles/components/_UsaBanner.scss | 236 ++++++++ .../src/styles/components/index.scss | 1 + .../src/types/UsaBanner/UsaBanner.d.ts | 22 + packages/design-system/src/types/index.d.ts | 1 + 31 files changed, 1329 insertions(+), 233 deletions(-) delete mode 100644 packages/design-system-docs/src/images/icon-dot-gov.svg delete mode 100644 packages/design-system-docs/src/images/icon-https.svg delete mode 100644 packages/design-system-docs/src/images/icon-lock.svg delete mode 100644 packages/design-system-docs/src/images/us_flag_small.png create mode 100644 packages/design-system-docs/src/pages/components/UsaBanner/UsaBanner.example.jsx create mode 100644 packages/design-system-docs/src/pages/components/UsaBanner/_UsaBanner.docs.scss create mode 100644 packages/design-system-docs/src/pages/components/UsaBanner/usabanner.example.html delete mode 100644 packages/design-system-docs/src/scripts/components/UsaBanner.jsx delete mode 100644 packages/design-system-docs/src/styles/components/_UsaBanner.scss create mode 100644 packages/design-system/src/components/UsaBanner/UsaBanner.e2e.test.js create mode 100644 packages/design-system/src/components/UsaBanner/UsaBanner.jsx create mode 100644 packages/design-system/src/components/UsaBanner/UsaBanner.test.jsx create mode 100644 packages/design-system/src/components/UsaBanner/__snapshots__/UsaBanner.test.jsx.snap create mode 100644 packages/design-system/src/images/close-alt.svg create mode 100644 packages/design-system/src/images/usa-banner-dot-gov.svg create mode 100644 packages/design-system/src/images/usa-banner-flag-es.svg create mode 100644 packages/design-system/src/images/usa-banner-flag.svg create mode 100644 packages/design-system/src/images/usa-banner-https.svg create mode 100644 packages/design-system/src/images/usa-banner-lock-es.svg create mode 100644 packages/design-system/src/images/usa-banner-lock.svg create mode 100644 packages/design-system/src/locale/en.json create mode 100644 packages/design-system/src/locale/es.json create mode 100644 packages/design-system/src/styles/components/_UsaBanner.scss create mode 100644 packages/design-system/src/types/UsaBanner/UsaBanner.d.ts diff --git a/lerna.json b/lerna.json index 2799e64b9c..4a6325fdda 100644 --- a/lerna.json +++ b/lerna.json @@ -5,9 +5,7 @@ } }, "npmClient": "yarn", - "packages": [ - "packages/*" - ], + "packages": ["packages/*"], "ignoreChanges": [ "packages/stylelint-config-design-system/**", "packages/eslint-config-design-system/**" diff --git a/packages/design-system-docs/src/images/icon-dot-gov.svg b/packages/design-system-docs/src/images/icon-dot-gov.svg deleted file mode 100644 index 27182dceba..0000000000 --- a/packages/design-system-docs/src/images/icon-dot-gov.svg +++ /dev/null @@ -1 +0,0 @@ -dot gov icon \ No newline at end of file diff --git a/packages/design-system-docs/src/images/icon-https.svg b/packages/design-system-docs/src/images/icon-https.svg deleted file mode 100644 index 3f98a93f50..0000000000 --- a/packages/design-system-docs/src/images/icon-https.svg +++ /dev/null @@ -1 +0,0 @@ -https icon \ No newline at end of file diff --git a/packages/design-system-docs/src/images/icon-lock.svg b/packages/design-system-docs/src/images/icon-lock.svg deleted file mode 100644 index 8dd2e1d8ad..0000000000 --- a/packages/design-system-docs/src/images/icon-lock.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/packages/design-system-docs/src/images/us_flag_small.png b/packages/design-system-docs/src/images/us_flag_small.png deleted file mode 100644 index 34b927b42c144bc86c9595a4ad0b1974fc650f5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~o!3-oFZT@ltDd_;85La2_jdCWNsdZs>Dtz1Xx9)?eB8ySqs+;o{-CNPO__O<#$EE)BU;Sj^ Xf5dDja +
English banner
+ +
Spanish banner
+ + , + document.getElementById('js-example') +); diff --git a/packages/design-system-docs/src/pages/components/UsaBanner/_UsaBanner.docs.scss b/packages/design-system-docs/src/pages/components/UsaBanner/_UsaBanner.docs.scss new file mode 100644 index 0000000000..e6d858ab47 --- /dev/null +++ b/packages/design-system-docs/src/pages/components/UsaBanner/_UsaBanner.docs.scss @@ -0,0 +1,45 @@ +/* +USA banner + +@status Draft + +The USA banner identifies official websites of government organizations in the United States. It also helps visitors understand how to tell that a website is both official and secure. + +@uswds https://designsystem.digital.gov/components/banner/ + +Markup: usabanner.example.html + +Style guide: components.usa-banner +*/ + +/* +`` + +@react-example UsaBanner.example.jsx + +@react-props UsaBanner.jsx + +Style guide: components.usa-banner.react +*/ + +/* +--- + +### When to use + +- To identify as an official government site. Most government sites should use the banner. + +### When to consider alternatives + +- If you don't use a .gov domain and HTTPS. The banner text identifies .gov domains and HTTPS as indicators that a website is an official government website. Use the banner only if your site uses both the proper TLD and HTTPS. +- Any time it would be misleading. The banner should be used to reduce confusion. Avoid using the banner on any site meant only for testing or otherwise not meant to be identified as an official government website. + +### Usage + +- Use the provided text without customization. The banner is most effective as an identifier and a learning tool when its message is consistent across government websites. +- Show the banner on every page. Use the banner at the top of every page of a site. It can be confusing or misleading if it appears on some pages and not others. +- Avoid distraction. The banner appears on every page of your site. Choose background colors that fit with your site theme and avoid color combinations that draw excessive attention to the banner. +- Keep the text up-to-date. Use the most current version of the banner. + +Style guide: components.usa-banner.guidance +*/ diff --git a/packages/design-system-docs/src/pages/components/UsaBanner/usabanner.example.html b/packages/design-system-docs/src/pages/components/UsaBanner/usabanner.example.html new file mode 100644 index 0000000000..0fee9bb998 --- /dev/null +++ b/packages/design-system-docs/src/pages/components/UsaBanner/usabanner.example.html @@ -0,0 +1,172 @@ +
English banner
+
+
+

+ + + + + +

+

+ An official website of the United States government + + +

+
+
+
+
+ +

+ Official websites use .gov +
+ A + .gov + website belongs to an official government organization in the United States. +

+
+
+ +

+ Secure .gov websites use HTTPS +
+ A + + lock + + ( + + + + + + ) or + https:// + means you’ve safely connected to the .gov website. Share sensitive information only on + official, secure websites. +

+
+
+
+
+
Spanish banner
+
+
+

+ + + + + +

+

+ Un sitio oficial del Gobierno de Estados Unidos + + +

+
+
+
+
+ +

+ Los sitios web oficiales usan .gov +
+ Un sitio web + .gov + pertenece a una organización oficial del Gobierno de Estados Unidos. +

+
+
+ +

+ Los sitios web seguros .gov usan HTTPS +
+ Un + + candado + + ( + + + + + + ) o + https:// + significa que usted se conectó de forma segura a un sitio web .gov. Comparta información + sensible sólo en sitios web oficiales y seguros. +

+
+
+
+
diff --git a/packages/design-system-docs/src/scripts/components/Header.jsx b/packages/design-system-docs/src/scripts/components/Header.jsx index 5d6775bc81..4fe90abb41 100644 --- a/packages/design-system-docs/src/scripts/components/Header.jsx +++ b/packages/design-system-docs/src/scripts/components/Header.jsx @@ -1,55 +1,40 @@ import GitHubLinks from './GitHubLinks'; import React from 'react'; -import UsaBanner from './UsaBanner'; +import { UsaBanner } from '@cmsgov/design-system'; import path from 'path'; -class Header extends React.PureComponent { - constructor(props) { - super(props); - this.state = { isBannerOpen: false }; - this.handleToggleBanner = this.handleToggleBanner.bind(this); - } - - handleToggleBanner() { - this.setState({ isBannerOpen: !this.state.isBannerOpen }); - } - - render() { - return ( -
- -
-

- - {process.env.name} - -

- -
- {process.env.core && ( -
-
-

- CMS Design System v2 is released! -   See our{' '} - - migration guide - - . -

-
+const Header = () => { + return ( +
+ +
+

+ + {process.env.name} + +

+ +
+ {process.env.core && ( +
+
+

+ CMS Design System v2 is released! +   See our{' '} + + migration guide + + . +

- )} -
- ); - } -} +
+ )} +
+ ); +}; export default Header; diff --git a/packages/design-system-docs/src/scripts/components/UsaBanner.jsx b/packages/design-system-docs/src/scripts/components/UsaBanner.jsx deleted file mode 100644 index a9d072aa1f..0000000000 --- a/packages/design-system-docs/src/scripts/components/UsaBanner.jsx +++ /dev/null @@ -1,81 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import path from 'path'; - -const UsaBanner = function (props) { - const bannerHeader = props.isBannerOpen - ? 'c-usa-banner__header c-usa-banner__header--expanded' - : 'c-usa-banner__header'; - - return ( -
-
-
- U.S. flag -

- An official website of the United States government - -

-
-
- -
- ); -}; - -UsaBanner.propTypes = { - isBannerOpen: PropTypes.bool.isRequired, - onToggleBanner: PropTypes.func.isRequired, -}; - -export default UsaBanner; diff --git a/packages/design-system-docs/src/styles/_index.scss b/packages/design-system-docs/src/styles/_index.scss index 189e1347f9..c0fe0e76e7 100644 --- a/packages/design-system-docs/src/styles/_index.scss +++ b/packages/design-system-docs/src/styles/_index.scss @@ -10,4 +10,3 @@ @import 'components/Docs'; @import 'components/Frame'; @import 'components/Header'; -@import 'components/UsaBanner'; diff --git a/packages/design-system-docs/src/styles/components/_UsaBanner.scss b/packages/design-system-docs/src/styles/components/_UsaBanner.scss deleted file mode 100644 index 7897e959ee..0000000000 --- a/packages/design-system-docs/src/styles/components/_UsaBanner.scss +++ /dev/null @@ -1,97 +0,0 @@ -.c-usa-banner { - background-color: #f0f0f0; - color: #1b1b1b; - font-family: 'Source Sans Pro Web', 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; - font-size: 1.06471rem; - line-height: 1.52155; -} - -.c-usa-banner__header { - font-size: 0.79853rem; - font-weight: 400; - line-height: 1.12707; - min-height: 0; - padding-bottom: 0.25rem; - padding-top: 0.25rem; - position: relative; -} - -.c-usa-banner__header-flag { - margin-right: 0.5rem; - width: 1rem; -} - -.c-usa-banner__header-text { - margin: 0; - span { - margin-right: 0.5rem; - } -} - -.c-usa-banner__content { - font-size: 0.99816rem; - overflow: hidden; - width: 100%; -} - -.c-usa-banner__button { - /* stylelint-disable scss/at-extend-no-missing-placeholder */ - @extend .ds-c-link; - /* stylelint-enable scss/at-extend-no-missing-placeholder */ - background-color: transparent; - border: 0; - box-shadow: none; - font-size: inherit; - line-height: inherit; - margin: 0; - padding: 0; - - &::after { - background-image: url('#{$image-path}/arrow-down.svg'), - linear-gradient(transparent, transparent); - background-position: 50%; - background-repeat: no-repeat; - background-size: 0.5rem; - content: ''; - display: inline-block; - height: 0.5rem; - margin-left: 2px; - width: 0.5rem; - } -} - -.c-usa-banner__guidance { - @media (min-width: $width-sm) { - width: 50%; - } -} - -.c-usa-banner__icon { - width: 2.5rem; -} - -.c-usa-banner__lock-image { - height: 1.5ex; - width: 1.5 * 52 / 64; - path { - fill: currentColor; - } -} - -.c-usa-banner__media-img { - float: left; - margin-right: 0.5rem; -} - -.c-usa-banner__media-body { - margin: 0; - overflow: hidden; -} - -// stylelint-disable no-duplicate-selectors -.c-usa-banner__header--expanded { - .c-usa-banner__button::after { - transform: rotate(180deg); - } -} -// stylelint-enable no-duplicate-selectors diff --git a/packages/design-system-scripts/gulp/common/copyFontsImages.js b/packages/design-system-scripts/gulp/common/copyFontsImages.js index 74496f1918..72e0ae4eaf 100644 --- a/packages/design-system-scripts/gulp/common/copyFontsImages.js +++ b/packages/design-system-scripts/gulp/common/copyFontsImages.js @@ -15,10 +15,21 @@ function minimizeSvg(srcGlob, dest) { plugins: [ { cleanupIDs: false, + }, + { removeTitle: false, + }, + { removeDesc: false, + }, + { removeHiddenElems: false, }, + { + removeUnknownsAndDefaults: { + keepRoleAttr: true, + }, + }, ], }) ) diff --git a/packages/design-system/src/components/UsaBanner/UsaBanner.e2e.test.js b/packages/design-system/src/components/UsaBanner/UsaBanner.e2e.test.js new file mode 100644 index 0000000000..d5168d85eb --- /dev/null +++ b/packages/design-system/src/components/UsaBanner/UsaBanner.e2e.test.js @@ -0,0 +1,20 @@ +/* global driver */ +import { ROOT_URL } from '../helpers/e2e/constants'; + +import assertNoAxeViolations from '../helpers/e2e/assertNoAxeViolations'; +import { getElementByClassName } from '../helpers/e2e'; + +const rootURL = `${ROOT_URL}/example/components.usa-banner.react/`; + +describe('Usa banner component', () => { + it('Usa banner should render', async () => { + await driver.get(rootURL); + + const el = await getElementByClassName('ds-c-usa-banner'); + expect(el).toBeTruthy(); + }); + + it('Usa banner should have no accessibility violations', async () => { + await assertNoAxeViolations(rootURL); + }); +}); diff --git a/packages/design-system/src/components/UsaBanner/UsaBanner.jsx b/packages/design-system/src/components/UsaBanner/UsaBanner.jsx new file mode 100644 index 0000000000..4944122229 --- /dev/null +++ b/packages/design-system/src/components/UsaBanner/UsaBanner.jsx @@ -0,0 +1,119 @@ +import EnglishTranslations from '../../locale/en.json'; +import IconDotGov from '../../images/usa-banner-dot-gov.svg'; +import IconFlag from '../../images/usa-banner-flag.svg'; +import IconFlagSpanish from '../../images/usa-banner-flag-es.svg'; +import IconHttps from '../../images/usa-banner-https.svg'; +import IconLock from '../../images/usa-banner-lock.svg'; +import IconLockSpanish from '../../images/usa-banner-lock-es.svg'; +import PropTypes from 'prop-types'; +import React from 'react'; +import SpanishTranslations from '../../locale/es.json'; +import classNames from 'classnames'; +import uniqueId from 'lodash.uniqueid'; + +export class UsaBanner extends React.PureComponent { + constructor(props) { + super(props); + this.id = props.id || uniqueId('gov-banner_'); + this.state = { isBannerOpen: false }; + this.handleToggleBanner = this.handleToggleBanner.bind(this); + } + + handleToggleBanner() { + this.setState({ isBannerOpen: !this.state.isBannerOpen }); + } + + render() { + const t = + this.props.locale === 'es' ? SpanishTranslations.usaBanner : EnglishTranslations.usaBanner; + const langProp = this.props.locale === 'es' ? 'es' : null; + const IconFlagComponent = this.props.locale === 'es' ? IconFlagSpanish : IconFlag; + const IconLockComponent = this.props.locale === 'es' ? IconLockSpanish : IconLock; + const classes = classNames('ds-c-usa-banner', this.props.className); + + return ( +
+
+

+ +

+

+ {t.bannerText} + + +

+
+ +
+ ); + } +} + +UsaBanner.defaultProps = { + locale: 'en', +}; + +UsaBanner.propTypes = { + /** + * Additional classes to be added to the root `section` element + */ + className: PropTypes.string, + /** + * A unique ID to be applied to the banner content. A unique ID will be generated if one isn't provided. + */ + id: PropTypes.string, + /** + * + * The language the USA Banner will be presented in. + */ + locale: PropTypes.oneOf(['en', 'es']), +}; + +export default UsaBanner; diff --git a/packages/design-system/src/components/UsaBanner/UsaBanner.test.jsx b/packages/design-system/src/components/UsaBanner/UsaBanner.test.jsx new file mode 100644 index 0000000000..24baf22de6 --- /dev/null +++ b/packages/design-system/src/components/UsaBanner/UsaBanner.test.jsx @@ -0,0 +1,53 @@ +import React from 'react'; +import UsaBanner from './UsaBanner'; +import renderer from 'react-test-renderer'; +import { shallow } from 'enzyme'; + +function render(customProps = {}) { + const props = Object.assign({}, customProps); + + return { + props: props, + wrapper: shallow(), + }; +} + +describe('UsaBanner', function () { + it('renders correctly', () => { + const tree = renderer.create().toJSON(); + + expect(tree).toMatchSnapshot(); + }); + + it('applies Spanish translation', () => { + const tree = renderer.create().toJSON(); + + expect(tree).toMatchSnapshot(); + }); + + it('applies additional class names to expanded banner', () => { + const { wrapper } = render(); + const openButton = wrapper.find('.ds-c-usa-banner__button'); + openButton.simulate('click'); + const banner = wrapper.find('header'); + expect(banner.hasClass('ds-c-usa-banner__header--expanded')).toBe(true); + expect(wrapper).toMatchSnapshot(); + }); + + it('adds className to root element', () => { + const data = render({ className: 'bar' }); + + expect(data.wrapper.hasClass('bar')).toBe(true); + }); + + it('has a unique id', () => { + const banner1 = render({ id: 'banner_unique' }); + const banner2 = render(); + const button1 = banner1.wrapper.find('.ds-c-usa-banner__button').first(); + const content1 = banner1.wrapper.find('.ds-c-usa-banner__content').first(); + const content2 = banner2.wrapper.find('.ds-c-usa-banner__content').first(); + + expect(button1.prop('aria-controls')).toBe(content1.prop('id')); + expect(content1.prop('id')).not.toBe(content2.prop('id')); + }); +}); diff --git a/packages/design-system/src/components/UsaBanner/__snapshots__/UsaBanner.test.jsx.snap b/packages/design-system/src/components/UsaBanner/__snapshots__/UsaBanner.test.jsx.snap new file mode 100644 index 0000000000..084e0d5a27 --- /dev/null +++ b/packages/design-system/src/components/UsaBanner/__snapshots__/UsaBanner.test.jsx.snap @@ -0,0 +1,520 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`UsaBanner applies Spanish translation 1`] = ` +
+
+

+ + + U.S. Bandera + + + U.S. Bandera + + + + + + + + + +

+

+ + Un sitio oficial del Gobierno de Estados Unidos + + + +

+
+ +
+`; + +exports[`UsaBanner applies additional class names to expanded banner 1`] = ` +
+
+

+ +

+

+ + An official website of the United States government + + + +

+
+ +
+`; + +exports[`UsaBanner renders correctly 1`] = ` +
+
+

+ + + U.S. flag + + + U.S. flag + + + + + + + + + +

+

+ + An official website of the United States government + + + +

+
+ +
+`; diff --git a/packages/design-system/src/components/index.js b/packages/design-system/src/components/index.js index df63c41afd..dc7ba58778 100644 --- a/packages/design-system/src/components/index.js +++ b/packages/design-system/src/components/index.js @@ -30,4 +30,5 @@ export { default as TabPanel } from './Tabs/TabPanel'; export { default as TextField, unmaskValue } from './TextField/TextField'; export { default as Tooltip } from './Tooltip/Tooltip'; export { default as TooltipIcon } from './Tooltip/TooltipIcon'; +export { default as UsaBanner } from './UsaBanner/UsaBanner'; export { default as VerticalNav } from './VerticalNav/VerticalNav'; diff --git a/packages/design-system/src/images/close-alt.svg b/packages/design-system/src/images/close-alt.svg new file mode 100644 index 0000000000..243587f5b0 --- /dev/null +++ b/packages/design-system/src/images/close-alt.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/design-system/src/images/usa-banner-dot-gov.svg b/packages/design-system/src/images/usa-banner-dot-gov.svg new file mode 100644 index 0000000000..87dd294043 --- /dev/null +++ b/packages/design-system/src/images/usa-banner-dot-gov.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/design-system/src/images/usa-banner-flag-es.svg b/packages/design-system/src/images/usa-banner-flag-es.svg new file mode 100644 index 0000000000..6e32ef5a32 --- /dev/null +++ b/packages/design-system/src/images/usa-banner-flag-es.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/packages/design-system/src/images/usa-banner-flag.svg b/packages/design-system/src/images/usa-banner-flag.svg new file mode 100644 index 0000000000..ed833f02fb --- /dev/null +++ b/packages/design-system/src/images/usa-banner-flag.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/packages/design-system/src/images/usa-banner-https.svg b/packages/design-system/src/images/usa-banner-https.svg new file mode 100644 index 0000000000..a079fab9f1 --- /dev/null +++ b/packages/design-system/src/images/usa-banner-https.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/design-system/src/images/usa-banner-lock-es.svg b/packages/design-system/src/images/usa-banner-lock-es.svg new file mode 100644 index 0000000000..3c98add8fa --- /dev/null +++ b/packages/design-system/src/images/usa-banner-lock-es.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/design-system/src/images/usa-banner-lock.svg b/packages/design-system/src/images/usa-banner-lock.svg new file mode 100644 index 0000000000..21d3c0cdb7 --- /dev/null +++ b/packages/design-system/src/images/usa-banner-lock.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/design-system/src/locale/en.json b/packages/design-system/src/locale/en.json new file mode 100644 index 0000000000..ea582f763a --- /dev/null +++ b/packages/design-system/src/locale/en.json @@ -0,0 +1,17 @@ +{ + "usaBanner": { + "bannerLabel": "Official government website", + "bannerText": "An official website of the United States government", + "bannerActionText": "Here’s how you know", + "domainHeaderText": "Official websites use .gov", + "domainAText": "A", + "domainText": "website belongs to an official government organization in the United States.", + "govText": ".gov", + "httpsHeaderText": "Secure .gov websites use HTTPS", + "httpsOrText": "or", + "httpsText": "https://", + "httpsAText": "A", + "httpsLockText": "lock", + "httpsDetailText": "means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites. " + } +} diff --git a/packages/design-system/src/locale/es.json b/packages/design-system/src/locale/es.json new file mode 100644 index 0000000000..4442ae5996 --- /dev/null +++ b/packages/design-system/src/locale/es.json @@ -0,0 +1,17 @@ +{ + "usaBanner": { + "bannerLabel": "Sitio web oficial del gobierno", + "bannerText": "Un sitio oficial del Gobierno de Estados Unidos", + "bannerActionText": "Así es como usted puede verificarlo", + "domainHeaderText": "Los sitios web oficiales usan .gov", + "domainAText": "Un sitio web", + "domainText": "pertenece a una organización oficial del Gobierno de Estados Unidos.", + "govText": ".gov", + "httpsHeaderText": "Los sitios web seguros .gov usan HTTPS", + "httpsOrText": "o", + "httpsText": "https://", + "httpsAText": "Un", + "httpsLockText": "candado", + "httpsDetailText": "significa que usted se conectó de forma segura a un sitio web .gov. Comparta información sensible sólo en sitios web oficiales y seguros." + } +} diff --git a/packages/design-system/src/styles/components/_UsaBanner.scss b/packages/design-system/src/styles/components/_UsaBanner.scss new file mode 100644 index 0000000000..22af096fcf --- /dev/null +++ b/packages/design-system/src/styles/components/_UsaBanner.scss @@ -0,0 +1,236 @@ +$usa-banner-background-color: #f0f0f0; +$usa-banner-text-color: #1b1b1b; +$usa-banner-close-image-background-color: #e6e6e6; +$usa-banner-header-action-color: #005ea2; +$usa-banner-font-family: $font-sans; + +.ds-c-usa-banner { + background-color: $usa-banner-background-color; + color: $usa-banner-text-color; + font-family: $usa-banner-font-family; + font-size: $base-font-size; + padding: 0; +} + +.ds-c-usa-banner__header { + align-items: flex-start; + display: flex; + flex-direction: row; + font-size: 12px; + font-weight: $font-normal; + min-height: $spacer-4; + padding: $spacer-1 0 $spacer-1 $spacer-2; + position: relative; + + @media (min-width: $width-sm) { + min-height: 0; + padding-bottom: 4px; + padding-top: 4px; + } +} + +.ds-c-usa-banner__header-flag { + margin-right: $spacer-1; + width: $spacer-2; +} + +.ds-c-usa-banner__header-text { + display: table; + margin: 0; + span { + margin-right: $spacer-1; + } +} + +.ds-c-usa-banner__header-action { + color: $usa-banner-header-action-color; + display: block; + line-height: 1.1; + margin-bottom: 0; + margin-top: 2px; + text-decoration: underline; + + &::after { + background-image: url('#{$image-path}/arrow-down.svg'), + linear-gradient(transparent, transparent); + background-position: 50%; + background-repeat: no-repeat; + background-size: $spacer-1; + color: $usa-banner-header-action-color; + content: ''; + display: inline-block; + height: $spacer-1; + margin-left: 2px; + padding-right: 2px; + width: $spacer-1; + } + + // Hide header-action text for large viewport and when expanded + @media (min-width: $width-sm) { + display: none; + } + .ds-c-usa-banner__header--expanded & { + display: none; + } +} + +.ds-c-usa-banner__button { + background-color: transparent; + border: 0; + bottom: 0; + box-shadow: none; + display: block; + font-size: inherit; + left: 0; + line-height: inherit; + margin: 0; + overflow: visible; + padding: 0; + position: absolute; + text-align: left; + top: 0; + width: 100%; + + /* stylelint-disable scss/at-extend-no-missing-placeholder */ + @extend .ds-c-link; + /* stylelint-enable scss/at-extend-no-missing-placeholder */ + + @media (min-width: $width-sm) { + bottom: auto; + display: inline; + left: auto; + position: relative; + right: auto; + top: auto; + width: auto; + } + + // Display close icon on smaller viewport + // stylelint-disable scss/media-feature-value-dollar-variable + @media (max-width: $width-sm - 1px) { + &[aria-expanded='true']::before { + background-color: $usa-banner-close-image-background-color; + bottom: 0; + content: ''; + display: block; + height: $spacer-6; + position: absolute; + right: 0; + top: 0; + width: $spacer-6; + } + // stylelint-enable scss/media-feature-value-dollar-variable + + &[aria-expanded='true']::after { + background-image: url('#{$image-path}/close-alt.svg'); + background-position: center; + background-repeat: no-repeat; + background-size: $spacer-2 $spacer-2; + bottom: 0; + content: ''; + display: inline-block; + height: $spacer-6; + margin-left: 0; + position: absolute; + right: 0; + top: 0; + vertical-align: middle; + width: $spacer-6; + } + } +} + +.ds-c-usa-banner__button-text { + // Hide the button-text on narrow viewport as header-action will display the action text + left: -999em; + position: absolute; + + &::after { + display: none; + } + + @media (min-width: $width-sm) { + display: inline; + position: static; + + &::after { + background-image: url('#{$image-path}/arrow-down.svg'), + linear-gradient(transparent, transparent); + background-position: 50%; + background-repeat: no-repeat; + background-size: $spacer-1; + content: ''; + display: inline-block; + height: $spacer-1; + margin-left: 2px; + padding-right: 2px; + width: $spacer-1; + } + } +} + +.ds-c-usa-banner__content { + margin-left: auto; + margin-right: auto; + overflow: hidden; + padding: 4px $spacer-2 $spacer-2 $spacer-1; + + @media (min-width: $width-sm) { + padding-bottom: $spacer-3; + padding-top: $spacer-3; + } +} + +.ds-c-usa-banner__guidance { + align-items: flex-start; + display: flex; + max-width: 64ex; + padding: $spacer-2 12px 0 12px; + + @media (min-width: $width-sm) { + padding: 0 $spacer-1; + width: 50%; + } +} + +.ds-c-usa-banner__icon { + flex-shrink: 0; + height: $spacer-5; + margin-right: $spacer-1; + width: $spacer-5; +} + +.ds-c-usa-banner__lock-image { + height: 1.5ex; + width: 1.5ex * 52 / 64; + path { + fill: currentColor; + } +} + +.ds-c-usa-banner__media-img { + float: left; + margin-right: $spacer-1; +} + +.ds-c-usa-banner__media-body { + margin: 0; +} + +// stylelint-disable no-duplicate-selectors +.ds-c-usa-banner__header--expanded { + padding-right: $spacer-7; + + @media (min-width: $width-sm) { + background-color: transparent; + padding-right: 0; + .ds-c-usa-banner__button-text::after { + transform: rotate(180deg); + } + } + + .ds-c-usa-banner__header-action { + display: none; + } +} +// stylelint-enable no-duplicate-selectors diff --git a/packages/design-system/src/styles/components/index.scss b/packages/design-system/src/styles/components/index.scss index c5d5ee5520..fee22d6676 100644 --- a/packages/design-system/src/styles/components/index.scss +++ b/packages/design-system/src/styles/components/index.scss @@ -23,4 +23,5 @@ @import 'TooltipIcon.scss'; @import 'Mask.scss'; @import 'DateField.scss'; +@import 'UsaBanner.scss'; @import 'VerticalNav.scss'; diff --git a/packages/design-system/src/types/UsaBanner/UsaBanner.d.ts b/packages/design-system/src/types/UsaBanner/UsaBanner.d.ts new file mode 100644 index 0000000000..71b2dd9b58 --- /dev/null +++ b/packages/design-system/src/types/UsaBanner/UsaBanner.d.ts @@ -0,0 +1,22 @@ +import * as React from 'react'; + +export type LocaleLanguage = 'en' | 'es'; + +export interface UsaBannerProps { + /** + * Additional classes to be added to the root `section` element + */ + className?: string; + /** + * A unique ID to be applied to the banner content. A unique ID will be generated if one isn't provided. + */ + id?: string; + /** + * The language the USA Banner will be presented in. + */ + locale?: LocaleLanguage, +} + +export default class UsaBanner extends React.Component { + render(): JSX.Element; +} diff --git a/packages/design-system/src/types/index.d.ts b/packages/design-system/src/types/index.d.ts index 91a5b92269..436299727b 100644 --- a/packages/design-system/src/types/index.d.ts +++ b/packages/design-system/src/types/index.d.ts @@ -28,4 +28,5 @@ export { default as TableRow } from './Table/TableRow'; export { default as Tabs } from './Tabs/Tabs'; export { default as TabPanel } from './Tabs/TabPanel'; export { default as TextField, unmaskValue } from './TextField/TextField'; +export { default as UsaBanner } from './UsaBanner/UsaBanner'; export { default as VerticalNav } from './VerticalNav/VerticalNav';