-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into refactor-decouple-uswds-from-lib-bundle
- Loading branch information
Showing
21 changed files
with
426 additions
and
133 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.usa-banner__button:after { | ||
top: 3px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,78 +1,136 @@ | ||
import React, { useState } from 'react'; | ||
import { Icon } from '@trussworks/react-uswds'; | ||
import { decode } from 'he'; | ||
import { | ||
USWDSBanner, | ||
USWDSBannerContent | ||
USWDSBannerContent, | ||
USWDSBannerButton, | ||
USWDSBannerFlag, | ||
USWDSBannerHeader, | ||
USWDSBannerIcon, | ||
USWDSBannerGuidance, | ||
USWDSMediaBlockBody | ||
} from '$components/common/uswds/banner'; | ||
|
||
const BANNER_KEY = 'dismissedBannerUrl'; | ||
|
||
function hasExpired(expiryDatetime) { | ||
const expiryDate = new Date(expiryDatetime); | ||
const currentDate = new Date(); | ||
return !!(currentDate > expiryDate); | ||
interface Guidance { | ||
left?: GuidanceContent; | ||
right?: GuidanceContent; | ||
} | ||
|
||
enum BannerType { | ||
info = 'info', | ||
warning = 'warning' | ||
interface GuidanceContent { | ||
icon?: string; | ||
iconAlt?: string; | ||
title?: string; | ||
text?: string; | ||
} | ||
|
||
const infoTypeFlag = BannerType.info; | ||
interface BannerProps { | ||
appTitle: string; | ||
expires: Date; | ||
url: string; | ||
text: string; | ||
type?: BannerType; | ||
headerText?: string; | ||
headerActionText?: string; | ||
ariaLabel?: string; | ||
flagImgAlt?: string; | ||
leftGuidance?: GuidanceContent; | ||
rightGuidance?: GuidanceContent; | ||
className?: string; | ||
defaultIsOpen?: boolean; | ||
contentId?: string; | ||
} | ||
|
||
const DEFAULT_HEADER_TEXT = | ||
'An official website of the United States government'; | ||
|
||
const DEFAULT_HEADER_ACTION_TEXT = "Here's how you know"; | ||
|
||
const DEFAULT_GUIDANCE: Guidance = { | ||
left: { | ||
title: 'Official websites use .gov', | ||
text: 'A .gov website belongs to an official government organization in the United States.', | ||
iconAlt: 'Dot gov icon', | ||
icon: '/img/icon-dot-gov.svg' | ||
}, | ||
right: { | ||
title: 'Secure .gov websites use HTTPS', | ||
text: ` | ||
A <strong>lock</strong> or <strong>https://</strong> means you've safely | ||
connected to the .gov website. Share sensitive information only on | ||
official, secure websites. | ||
`, | ||
iconAlt: 'HTTPS icon', | ||
icon: '/img/icon-https.svg' | ||
} | ||
}; | ||
|
||
const GuidanceBlock = ({ | ||
content, | ||
className | ||
}: { | ||
content: GuidanceContent; | ||
className?: string; | ||
}) => ( | ||
<USWDSBannerGuidance className={className}> | ||
<USWDSBannerIcon src={content.icon} alt={content.iconAlt ?? ''} /> | ||
<USWDSMediaBlockBody> | ||
<p> | ||
<strong>{content.title}</strong> | ||
<br /> | ||
<span | ||
dangerouslySetInnerHTML={{ __html: decode(content.text ?? '') }} | ||
/> | ||
</p> | ||
</USWDSMediaBlockBody> | ||
</USWDSBannerGuidance> | ||
); | ||
|
||
export default function Banner({ | ||
appTitle, | ||
expires, | ||
url, | ||
text, | ||
type = infoTypeFlag | ||
headerText, | ||
headerActionText, | ||
ariaLabel, | ||
flagImgAlt = '', | ||
leftGuidance, | ||
rightGuidance, | ||
className = '', | ||
defaultIsOpen = false, | ||
contentId = 'gov-banner-content' | ||
}: BannerProps) { | ||
const [isOpen, setIsOpen] = useState(defaultIsOpen); | ||
|
||
const showBanner = localStorage.getItem(BANNER_KEY) !== url; | ||
const [isOpen, setIsOpen] = useState(showBanner && !hasExpired(expires)); | ||
const leftContent = { | ||
...DEFAULT_GUIDANCE.left, | ||
...leftGuidance | ||
} as GuidanceContent; | ||
|
||
function onClose() { | ||
localStorage.setItem(BANNER_KEY, url); | ||
setIsOpen(false); | ||
} | ||
const rightContent = { | ||
...DEFAULT_GUIDANCE.right, | ||
...rightGuidance | ||
} as GuidanceContent; | ||
|
||
return ( | ||
<div> | ||
{isOpen && ( | ||
<div className='position-relative'> | ||
<USWDSBanner | ||
aria-label={appTitle} | ||
className={type !== infoTypeFlag ? 'bg-secondary-lighter' : ''} | ||
> | ||
<a href={url} target='_blank' rel='noreferrer'> | ||
<USWDSBannerContent | ||
className='padding-top-1 padding-bottom-1' | ||
isOpen={true} | ||
> | ||
<div dangerouslySetInnerHTML={{ __html: text }} /> | ||
<USWDSBanner | ||
aria-label={ariaLabel ?? DEFAULT_HEADER_TEXT} | ||
className={className} | ||
> | ||
<USWDSBannerHeader | ||
isOpen={isOpen} | ||
flagImg={ | ||
<USWDSBannerFlag src='/img/us_flag_small.png' alt={flagImgAlt} /> | ||
} | ||
headerText={headerText ?? DEFAULT_HEADER_TEXT} | ||
headerActionText={headerActionText ?? DEFAULT_HEADER_ACTION_TEXT} | ||
> | ||
<USWDSBannerButton | ||
isOpen={isOpen} | ||
onClick={() => setIsOpen((prev) => !prev)} | ||
aria-controls={contentId} | ||
> | ||
{headerActionText ?? DEFAULT_HEADER_ACTION_TEXT} | ||
</USWDSBannerButton> | ||
</USWDSBannerHeader> | ||
|
||
</USWDSBannerContent> | ||
</a> | ||
</USWDSBanner> | ||
<div className='position-absolute top-0 right-0 margin-right-3 height-full display-flex'> | ||
<button | ||
className='usa-button usa-button--unstyled' | ||
type='button' | ||
aria-label='Close Banner' | ||
onClick={onClose} | ||
> | ||
<Icon.Close /> | ||
</button> | ||
</div> | ||
<USWDSBannerContent id={contentId} isOpen={isOpen}> | ||
<div className='grid-row grid-gap-lg'> | ||
<GuidanceBlock content={leftContent} className='tablet:grid-col-6' /> | ||
<GuidanceBlock content={rightContent} className='tablet:grid-col-6' /> | ||
</div> | ||
)} | ||
</div> | ||
</USWDSBannerContent> | ||
</USWDSBanner> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import React, { useState } from 'react'; | ||
import { Icon } from '@trussworks/react-uswds'; | ||
import { decode } from 'he'; | ||
import { USWDSSiteAlert } from '$components/common/uswds/site-alert'; | ||
|
||
const ALERT_KEY = 'dismissedSiteAlertUrl'; | ||
|
||
function hasExpired(expiryDatetime?: Date): boolean { | ||
if (!expiryDatetime) return false; | ||
const expiryDate = new Date(expiryDatetime); | ||
const currentDate = new Date(); | ||
return !!(currentDate > expiryDate); | ||
} | ||
|
||
enum SiteAlertType { | ||
info = 'info', | ||
emergency = 'emergency' | ||
} | ||
|
||
const infoTypeFlag = SiteAlertType.info; | ||
|
||
interface SiteAlertProps { | ||
appTitle: string; | ||
expires?: Date; | ||
content: string; | ||
type?: SiteAlertType; | ||
heading?: string; | ||
showIcon?: boolean; | ||
slim?: boolean; | ||
className?: string; | ||
} | ||
|
||
export default function SiteAlert({ | ||
appTitle, | ||
expires, | ||
content, | ||
type = infoTypeFlag, | ||
heading, | ||
showIcon = true, | ||
slim = false, | ||
className = '' | ||
}: SiteAlertProps) { | ||
const showAlert = localStorage.getItem(ALERT_KEY) !== content; | ||
const [isOpen, setIsOpen] = useState(showAlert && !hasExpired(expires)); | ||
|
||
function onClose() { | ||
localStorage.setItem(ALERT_KEY, content); | ||
setIsOpen(false); | ||
} | ||
|
||
return ( | ||
<div> | ||
{isOpen && ( | ||
<div className='position-relative'> | ||
<USWDSSiteAlert | ||
aria-label={`${appTitle} site alert`} | ||
variant={type} | ||
heading={heading} | ||
showIcon={showIcon} | ||
slim={slim} | ||
className={`${className} ${ | ||
type !== infoTypeFlag ? 'bg-secondary-lighter' : '' | ||
}`} | ||
> | ||
<div dangerouslySetInnerHTML={{ __html: decode(content) }} /> | ||
</USWDSSiteAlert> | ||
<div className='position-absolute top-0 right-0 margin-right-3 height-full display-flex'> | ||
<button | ||
className='usa-button usa-button--unstyled' | ||
type='button' | ||
aria-label={`Close ${appTitle} site alert`} | ||
onClick={onClose} | ||
> | ||
<Icon.Close /> | ||
</button> | ||
</div> | ||
</div> | ||
)} | ||
</div> | ||
); | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import React from 'react'; | ||
import { | ||
Banner, | ||
BannerContent, | ||
BannerButton, | ||
BannerFlag, | ||
BannerHeader, | ||
BannerIcon, | ||
BannerGuidance, MediaBlockBody | ||
} from '@trussworks/react-uswds'; | ||
|
||
export function USWDSBanner(props) { | ||
return <Banner {...props} />; | ||
} | ||
|
||
export function USWDSBannerContent(props) { | ||
return <BannerContent {...props} />; | ||
} | ||
|
||
export function USWDSBannerButton(props) { | ||
return <BannerButton {...props} />; | ||
} | ||
|
||
export function USWDSBannerFlag(props) { | ||
return <BannerFlag {...props} />; | ||
} | ||
|
||
export function USWDSBannerHeader(props) { | ||
return <BannerHeader {...props} />; | ||
} | ||
|
||
export function USWDSBannerIcon(props) { | ||
return <BannerIcon {...props} />; | ||
} | ||
|
||
export function USWDSBannerGuidance(props) { | ||
return <BannerGuidance {...props} />; | ||
} | ||
|
||
export function USWDSMediaBlockBody(props) { | ||
return <MediaBlockBody {...props} />; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import React from 'react'; | ||
import { SiteAlert } from '@trussworks/react-uswds'; | ||
|
||
export function USWDSSiteAlert(props) { | ||
return <SiteAlert {...props} />; | ||
} |
Oops, something went wrong.