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 34b927b42c..0000000000 Binary files a/packages/design-system-docs/src/images/us_flag_small.png and /dev/null differ diff --git a/packages/design-system-docs/src/pages/components/UsaBanner/UsaBanner.example.jsx b/packages/design-system-docs/src/pages/components/UsaBanner/UsaBanner.example.jsx new file mode 100644 index 0000000000..c31dd67f9e --- /dev/null +++ b/packages/design-system-docs/src/pages/components/UsaBanner/UsaBanner.example.jsx @@ -0,0 +1,13 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import { UsaBanner } from '@cmsgov/design-system'; + +ReactDOM.render( +
+
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';