diff --git a/src/components/Identifier/Identifier/Identifier.stories.tsx b/src/components/Identifier/Identifier/Identifier.stories.tsx
new file mode 100644
index 0000000000..78e2efd723
--- /dev/null
+++ b/src/components/Identifier/Identifier/Identifier.stories.tsx
@@ -0,0 +1,416 @@
+/* eslint-disable jsx-a11y/anchor-is-valid */
+import React from 'react'
+
+import { Identifier } from './Identifier'
+import { IdentifierMasthead } from '../IdentifierMasthead/IdentifierMasthead'
+import { IdentifierLinks } from '../IdentifierLinks/IdentifierLinks'
+import { IdentifierGov } from '../IdentifierGov/IdentifierGov'
+import { IdentifierLinkItem } from '../IdentifierLinkItem/IdentifierLinkItem'
+import { IdentifierLink } from '../IdentifierLink/IdentifierLink'
+import { IdentifierLogo } from '../IdentifierLogo/IdentifierLogo'
+
+import dotGovIcon from 'uswds/src/img/icon-dot-gov.svg'
+
+export default {
+ title: 'Components/Identifier',
+ component: Identifier,
+ parameters: {
+ docs: {
+ description: {
+ component: `
+### USWDS 2.0 Identifier component
+
+Source: https://designsystem.digital.gov/components/identifier/
+`,
+ },
+ },
+ },
+}
+
+const testIdentifierLogo = (
+
+)
+
+const testIdentifierLogoSpanish = (
+
+)
+
+const testLinks = [
+
+ About <Parent shortname>
+ ,
+
+ Accessibility support
+ ,
+
+ FOIA requests
+ ,
+
+ No FEAR Act data
+ ,
+
+ Office of the Inspector General
+ ,
+
+ Performance reports
+ ,
+
+ Privacy policy
+ ,
+]
+
+const testLinksSpanish = [
+
+ Acerca de <Parent shortname>
+ ,
+
+ Soporte de accesibilidad
+ ,
+
+ Solicitud a través de FOIA
+ ,
+
+ Datos de la ley No FEAR
+ ,
+
+ Oficina del Inspector General
+ ,
+
+ Informes de desempeño
+ ,
+
+ Política de privacidad
+ ,
+]
+
+const testIdentifierGovContent = [
+
,
+]
+
+const testIdentifierGovContentSpanish = [
+ ,
+]
+
+export const identifierDefault = (): React.ReactElement => (
+
+
+
+
+ {testIdentifierLogo}
+
+
+
+
+
+ {testLinks}
+
+
+ {testIdentifierGovContent}
+
+
+)
+
+export const identifierSpanish = (): React.ReactElement => (
+
+
+
+
+ {testIdentifierLogoSpanish}
+
+
+
+
+
+ {testLinksSpanish}
+
+
+ {testIdentifierGovContentSpanish}
+
+
+)
+
+export const multipleParentsAndLogos = (): React.ReactElement => (
+
+
+
+
+ {testIdentifierLogo}
+ {testIdentifierLogo}
+
+
+
+
+
+ {testLinks}
+
+
+ {testIdentifierGovContent}
+
+
+)
+
+export const multipleParentsAndLogosSpanish = (): React.ReactElement => (
+
+
+
+
+ {testIdentifierLogoSpanish}
+ {testIdentifierLogoSpanish}
+
+
+
+
+ {testLinksSpanish}
+
+ {testIdentifierGovContentSpanish}
+
+
+)
+
+export const moreThanTwoParentsAndLogos = (): React.ReactElement => (
+
+
+
+
+ {testIdentifierLogo}
+ {testIdentifierLogo}
+ {testIdentifierLogo}
+
+
+
+
+
+ {testLinks}
+
+
+ {testIdentifierGovContent}
+
+
+)
+
+export const noLogosEnglish = (): React.ReactElement => (
+
+
+
+
+
+ {testLinks}
+
+
+ {testIdentifierGovContent}
+
+
+)
+
+export const noLogosSpanish = (): React.ReactElement => (
+
+
+
+
+
+ {testLinksSpanish}
+
+
+ {testIdentifierGovContentSpanish}
+
+
+)
+
+export const taxDisclaimerEnglish = (): React.ReactElement => (
+
+
+
+
+ {testIdentifierLogo}
+
+
+
domain.edu.mil.gov
+
+ {`An official website of the `}
+ Test Agency Name
+ {`. Produced and published at taxpayer expense.`}
+
+
+
+
+
+ {testLinks}
+
+
+ {testIdentifierGovContent}
+
+
+)
+
+export const taxDisclaimerSpanish = (): React.ReactElement => (
+
+
+
+
+ {testIdentifierLogoSpanish}
+
+
+
domain.edu.mil.gov
+
+ {`Un sitio web oficial de `}
+ Test Agency Name Spanish
+ {`. Producido y publicado con dinero de los contribuyentes de impuestos.`}
+
+
+
+
+
+ {testLinksSpanish}
+
+
+ {testIdentifierGovContentSpanish}
+
+
+)
+
+export const taxDisclaimerAndMultipleParentsAndLogos = (): React.ReactElement => (
+
+
+
+
+ {testIdentifierLogo}
+ {testIdentifierLogo}
+
+
+
+
+
+ {testLinks}
+
+
+ {testIdentifierGovContent}
+
+
+)
diff --git a/src/components/Identifier/Identifier/Identifier.test.tsx b/src/components/Identifier/Identifier/Identifier.test.tsx
new file mode 100644
index 0000000000..55e21c6a74
--- /dev/null
+++ b/src/components/Identifier/Identifier/Identifier.test.tsx
@@ -0,0 +1,304 @@
+import React from 'react'
+import { render } from '@testing-library/react'
+
+import { Identifier } from './Identifier'
+import { IdentifierMasthead } from '../IdentifierMasthead/IdentifierMasthead'
+import { IdentifierLogo } from '../IdentifierLogo/IdentifierLogo'
+import { IdentifierLinks } from '../IdentifierLinks/IdentifierLinks'
+import { IdentifierLink } from '../IdentifierLink/IdentifierLink'
+import { IdentifierLinkItem } from '../IdentifierLinkItem/IdentifierLinkItem'
+import { IdentifierGov } from '../IdentifierGov/IdentifierGov'
+
+import dotGovIcon from 'uswds/src/img/icon-dot-gov.svg'
+
+const testIdentifierLogo = (
+
+)
+
+const testIdentifierLogoSpanish = (
+
+)
+
+const testLinks = [
+
+ About <Parent shortname>
+ ,
+
+ Accessibility support
+ ,
+
+ FOIA requests
+ ,
+
+ No FEAR Act data
+ ,
+
+ Office of the Inspector General
+ ,
+
+ Performance reports
+ ,
+
+ Privacy policy
+ ,
+]
+
+const testLinksSpanish = [
+
+ Acerca de <Parent shortname>
+ ,
+
+ Soporte de accesibilidad
+ ,
+
+ Solicitud a través de FOIA
+ ,
+
+ Datos de la ley No FEAR
+ ,
+
+ Oficina del Inspector General
+ ,
+
+ Informes de desempeño
+ ,
+
+ Política de privacidad
+ ,
+]
+
+const testIdentifierGovContent = [
+ ,
+]
+
+const testIdentifierGovContentSpanish = [
+ ,
+]
+
+describe('Identifier component', () => {
+ it('renders without errors', () => {
+ const { getByRole, getAllByRole, queryByTestId } = render(
+
+
+
+
+
+ {testIdentifierLogo}
+
+
+
+
+ domain.edu.mil.gov
+
+
+ {`An official website of the `}
+ Test Agency Name
+
+
+
+
+
+ {testLinks}
+
+
+ {testIdentifierGovContent}
+
+
+ )
+
+ expect(queryByTestId('identifier')).toBeInTheDocument()
+ expect(queryByTestId('identifierMasthead')).toBeInTheDocument()
+ expect(queryByTestId('identifierGov')).toBeInTheDocument()
+ expect(getAllByRole('link')).toHaveLength(10)
+ expect(getByRole('navigation')).toBeInTheDocument()
+ })
+
+ it('renders in Spanish', () => {
+ const { getAllByRole, queryByText } = render(
+
+
+
+
+
+ {testIdentifierLogoSpanish}
+
+
+
+
+
+
+ {testLinksSpanish}
+
+
+ {testIdentifierGovContentSpanish}
+
+
+ )
+
+ expect(queryByText('Un sitio web oficial de')).toBeInTheDocument()
+ expect(queryByText('Visite USAGov en Español')).toBeInTheDocument()
+ expect(getAllByRole('link')).toHaveLength(10)
+ })
+
+ it('renders without logos', () => {
+ const { getAllByRole, getByTestId, queryByText } = render(
+
+
+
+
+
+ domain.edu.mil.gov
+
+
+ {`An official website of the `}
+ Test Agency Name
+
+
+
+
+
+ {testLinks}
+
+
+ {testIdentifierGovContent}
+
+
+ )
+
+ expect(getByTestId('identifierMasthead-agency-description')).not.toContain(
+ 'img'
+ )
+ expect(getAllByRole('link')).toHaveLength(9)
+ expect(queryByText('Privacy policy')).toBeInTheDocument()
+ })
+
+ it('renders more than two parent agencies', () => {
+ const { getAllByRole, queryByText } = render(
+
+
+
+
+ {testIdentifierLogo}
+ {testIdentifierLogo}
+ {testIdentifierLogo}
+
+
+
+
+
+ {testLinks}
+
+
+ {testIdentifierGovContent}
+
+
+ )
+
+ expect(getAllByRole('img')).toHaveLength(3)
+ expect(getAllByRole('link')).toHaveLength(14)
+ expect(queryByText('Third Test Agency Name')).toBeInTheDocument()
+ })
+
+ it('renders tax disclaimer', () => {
+ const { getByTestId } = render(
+
+
+
+
+ {testIdentifierLogo}
+
+
+
+ domain.edu.mil.gov
+
+
+ {`An official website of the `}
+ Test Agency Name
+ {`. Produced and published at taxpayer expense.`}
+
+
+
+
+
+ {testLinks}
+
+
+ {testIdentifierGovContent}
+
+
+ )
+
+ expect(
+ getByTestId('identifierMasthead-agency-description')
+ ).toHaveTextContent('Produced and published at taxpayer expense.')
+ })
+})
diff --git a/src/components/Identifier/Identifier/Identifier.tsx b/src/components/Identifier/Identifier/Identifier.tsx
new file mode 100644
index 0000000000..4593abe62f
--- /dev/null
+++ b/src/components/Identifier/Identifier/Identifier.tsx
@@ -0,0 +1,22 @@
+import React from 'react'
+import classnames from 'classnames'
+
+interface IdentifierProps {
+ className?: string
+ children: React.ReactNode
+}
+
+export const Identifier = ({
+ className,
+ children,
+ ...divProps
+}: IdentifierProps & JSX.IntrinsicElements['div']): React.ReactElement => {
+ const classes = classnames('usa-identifier', className)
+ return (
+
+ {children}
+
+ )
+}
+
+export default Identifier
diff --git a/src/components/Identifier/IdentifierGov/IdentifierGov.test.tsx b/src/components/Identifier/IdentifierGov/IdentifierGov.test.tsx
new file mode 100644
index 0000000000..797b8eaec8
--- /dev/null
+++ b/src/components/Identifier/IdentifierGov/IdentifierGov.test.tsx
@@ -0,0 +1,47 @@
+import React from 'react'
+import { render } from '@testing-library/react'
+import renderer from 'react-test-renderer'
+
+import { IdentifierGov } from './IdentifierGov'
+
+describe('IdentifierGov component', () => {
+ it('renders without errors', () => {
+ const { queryByTestId } = render()
+ expect(queryByTestId('identifierGov')).toBeInTheDocument()
+ })
+
+ it('renders section attributes passed in through props', () => {
+ const { queryByTestId } = render(
+
+ )
+
+ expect(queryByTestId('identifierGov')).toHaveAttribute(
+ 'aria-label',
+ 'custom aria-label value'
+ )
+ })
+
+ it('renders consistently in Spanish', () => {
+ const tree = renderer
+ .create(
+
+
+
+ )
+ .toJSON()
+ expect(tree).toMatchSnapshot()
+ })
+})
diff --git a/src/components/Identifier/IdentifierGov/IdentifierGov.tsx b/src/components/Identifier/IdentifierGov/IdentifierGov.tsx
new file mode 100644
index 0000000000..27798945f1
--- /dev/null
+++ b/src/components/Identifier/IdentifierGov/IdentifierGov.tsx
@@ -0,0 +1,27 @@
+import React from 'react'
+import classnames from 'classnames'
+
+interface IdentifierGovProps {
+ children?: React.ReactNode
+ className?: string
+}
+
+export const IdentifierGov = ({
+ children,
+ className,
+ ...sectionProps
+}: IdentifierGovProps &
+ JSX.IntrinsicElements['section']): React.ReactElement => {
+ const classes = classnames(
+ 'usa-identifier__section usa-identifier__section--usagov',
+ className
+ )
+
+ return (
+
+ )
+}
+
+export default IdentifierGov
diff --git a/src/components/Identifier/IdentifierGov/__snapshots__/IdentifierGov.test.tsx.snap b/src/components/Identifier/IdentifierGov/__snapshots__/IdentifierGov.test.tsx.snap
new file mode 100644
index 0000000000..faba90b55e
--- /dev/null
+++ b/src/components/Identifier/IdentifierGov/__snapshots__/IdentifierGov.test.tsx.snap
@@ -0,0 +1,27 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`IdentifierGov component renders consistently in Spanish 1`] = `
+
+`;
diff --git a/src/components/Identifier/IdentifierLink/IdentifierLink.test.tsx b/src/components/Identifier/IdentifierLink/IdentifierLink.test.tsx
new file mode 100644
index 0000000000..d923926963
--- /dev/null
+++ b/src/components/Identifier/IdentifierLink/IdentifierLink.test.tsx
@@ -0,0 +1,48 @@
+import React from 'react'
+import { render } from '@testing-library/react'
+import { IdentifierLink } from './IdentifierLink'
+
+const testPageName = 'Test Page'
+
+describe('IdentifierLink component', () => {
+ it('renders without errors', () => {
+ const { getByRole, queryByText } = render(
+ {testPageName}
+ )
+ expect(queryByText(testPageName)).toBeInTheDocument()
+ expect(getByRole('link')).toHaveClass(
+ 'usa-identifier__required-link usa-link'
+ )
+ })
+ it('renders with a custom component', () => {
+ type CustomLinkProps = React.PropsWithChildren<{
+ to: string
+ className?: string
+ }> &
+ JSX.IntrinsicElements['a']
+
+ const CustomLink: React.FunctionComponent = ({
+ to,
+ children,
+ className,
+ ...linkProps
+ }: CustomLinkProps): React.ReactElement => (
+
+ {children}
+
+ )
+
+ const { getByRole, queryByText } = render(
+
+ to="#"
+ className="custom-class"
+ asCustom={CustomLink}>
+ {testPageName}
+
+ )
+ expect(queryByText(testPageName)).toBeInTheDocument()
+ expect(getByRole('link')).toHaveClass(
+ 'custom-class usa-identifier__required-link usa-link'
+ )
+ })
+})
diff --git a/src/components/Identifier/IdentifierLink/IdentifierLink.tsx b/src/components/Identifier/IdentifierLink/IdentifierLink.tsx
new file mode 100644
index 0000000000..ac935ad0ba
--- /dev/null
+++ b/src/components/Identifier/IdentifierLink/IdentifierLink.tsx
@@ -0,0 +1,28 @@
+import React from 'react'
+import classnames from 'classnames'
+
+import {
+ CustomLinkProps,
+ DefaultLinkProps,
+ isCustomProps,
+ Link,
+} from '../../Link/Link'
+
+export function IdentifierLink(props: DefaultLinkProps): React.ReactElement
+export function IdentifierLink(props: CustomLinkProps): React.ReactElement
+export function IdentifierLink({
+ className,
+ ...passThroughProps
+}: DefaultLinkProps | CustomLinkProps): React.ReactElement {
+ const classes = classnames(className, 'usa-identifier__required-link')
+ const linkProps = {
+ ...passThroughProps,
+ className: classes,
+ } as DefaultLinkProps | CustomLinkProps
+
+ if (isCustomProps(linkProps)) {
+ return {...linkProps} />
+ }
+
+ return
+}
diff --git a/src/components/Identifier/IdentifierLinkItem/IdentifierLinkItem.test.tsx b/src/components/Identifier/IdentifierLinkItem/IdentifierLinkItem.test.tsx
new file mode 100644
index 0000000000..42c1ea89b9
--- /dev/null
+++ b/src/components/Identifier/IdentifierLinkItem/IdentifierLinkItem.test.tsx
@@ -0,0 +1,29 @@
+import React from 'react'
+import { render } from '@testing-library/react'
+
+import { IdentifierLink } from '../IdentifierLink/IdentifierLink'
+import { IdentifierLinkItem } from '../IdentifierLinkItem/IdentifierLinkItem'
+
+describe('IdentifierLinkItem component', () => {
+ it('renders without errors', () => {
+ const { getByRole, queryByText } = render(
+ Test Page
+ )
+ expect(queryByText('Test Page')).toBeInTheDocument()
+ expect(getByRole('listitem')).toHaveClass(
+ 'usa-identifier__required-links-item'
+ )
+ })
+
+ it('renders properly with IdentifierLink', () => {
+ const { getByRole, queryByText } = render(
+
+ Test Page
+
+ )
+ expect(queryByText('Test Page')).toBeInTheDocument()
+ expect(getByRole('listitem')).toHaveClass(
+ 'usa-identifier__required-links-item'
+ )
+ })
+})
diff --git a/src/components/Identifier/IdentifierLinkItem/IdentifierLinkItem.tsx b/src/components/Identifier/IdentifierLinkItem/IdentifierLinkItem.tsx
new file mode 100644
index 0000000000..c91e623f93
--- /dev/null
+++ b/src/components/Identifier/IdentifierLinkItem/IdentifierLinkItem.tsx
@@ -0,0 +1,21 @@
+import React from 'react'
+import classnames from 'classnames'
+
+export interface IdentifierLinkItemProps {
+ children: React.ReactNode
+ className?: string
+}
+
+export const IdentifierLinkItem = ({
+ children,
+ className,
+ ...listItemProps
+}: IdentifierLinkItemProps &
+ JSX.IntrinsicElements['li']): React.ReactElement => {
+ const classes = classnames('usa-identifier__required-links-item', className)
+ return (
+
+ {children}
+
+ )
+}
diff --git a/src/components/Identifier/IdentifierLinks/IdentifierLinks.test.tsx b/src/components/Identifier/IdentifierLinks/IdentifierLinks.test.tsx
new file mode 100644
index 0000000000..4b03c8c1dd
--- /dev/null
+++ b/src/components/Identifier/IdentifierLinks/IdentifierLinks.test.tsx
@@ -0,0 +1,72 @@
+import React from 'react'
+import { render } from '@testing-library/react'
+
+import { IdentifierLinks } from './IdentifierLinks'
+import { IdentifierLinkItem } from '../IdentifierLinkItem/IdentifierLinkItem'
+import { IdentifierLink } from '../IdentifierLink/IdentifierLink'
+
+const testPageName = 'Test Page'
+
+describe('IdentifierLinks component', () => {
+ it('renders without errors', () => {
+ const { getByRole, queryByText } = render(
+
+ {testPageName}
+
+ )
+ expect(getByRole('listitem')).toHaveClass(
+ 'usa-identifier__required-links-item'
+ )
+ expect(queryByText('Test Page')).toBeInTheDocument()
+ })
+
+ it('renders properly with IdentifierLinkItem and IdentifierLink components', () => {
+ const { getAllByRole, queryByText } = render(
+
+
+ {testPageName}
+
+
+ Second Test Page
+
+
+ Third Test Page
+
+
+ )
+ expect(getAllByRole('link')).toHaveLength(3)
+ expect(queryByText('Test Page')).toBeInTheDocument()
+ })
+
+ it('renders properly with subcomponents using custom elements', () => {
+ type CustomLinkProps = React.PropsWithChildren<{
+ to: string
+ className?: string
+ }> &
+ JSX.IntrinsicElements['a']
+
+ const CustomLink: React.FunctionComponent = ({
+ to,
+ children,
+ className,
+ ...linkProps
+ }: CustomLinkProps): React.ReactElement => (
+
+ {children}
+
+ )
+
+ const { getByRole, queryByText } = render(
+
+
+ to="#" asCustom={CustomLink}>
+ {testPageName}
+
+
+
+ )
+ expect(queryByText('Test Page')).toBeInTheDocument()
+ expect(getByRole('link')).toBeInTheDocument()
+ expect(getByRole('list')).toBeInTheDocument()
+ })
+})
diff --git a/src/components/Identifier/IdentifierLinks/IdentifierLinks.tsx b/src/components/Identifier/IdentifierLinks/IdentifierLinks.tsx
new file mode 100644
index 0000000000..14d45f04f1
--- /dev/null
+++ b/src/components/Identifier/IdentifierLinks/IdentifierLinks.tsx
@@ -0,0 +1,36 @@
+import React, { ReactElement } from 'react'
+import classnames from 'classnames'
+import { IdentifierLinkItemProps } from '../IdentifierLinkItem/IdentifierLinkItem'
+
+interface IdentifierLinksProps {
+ children:
+ | ReactElement
+ | ReactElement[]
+ className?: string
+ navProps?: JSX.IntrinsicElements['nav']
+ listProps?: JSX.IntrinsicElements['ul']
+}
+
+export const IdentifierLinks = ({
+ children,
+ className,
+ navProps,
+ listProps,
+}: IdentifierLinksProps): React.ReactElement => {
+ const classes = classnames(
+ 'usa-identifier__section usa-identifier__section--required-links',
+ className
+ )
+
+ return (
+
+ )
+}
+
+export default IdentifierLinks
diff --git a/src/components/Identifier/IdentifierLogo/IdentifierLogo.test.tsx b/src/components/Identifier/IdentifierLogo/IdentifierLogo.test.tsx
new file mode 100644
index 0000000000..275318f58c
--- /dev/null
+++ b/src/components/Identifier/IdentifierLogo/IdentifierLogo.test.tsx
@@ -0,0 +1,57 @@
+import React from 'react'
+import { render } from '@testing-library/react'
+
+import dotGovIcon from 'uswds/src/img/icon-dot-gov.svg'
+
+import { IdentifierLogo } from './IdentifierLogo'
+
+describe('IdentifierLogo component', () => {
+ it('renders without errors', () => {
+ const { getByRole } = render(
+
+
+
+ )
+
+ expect(getByRole('link')).toHaveClass('usa-identifier__logo')
+ expect(getByRole('img')).toHaveClass('usa-identifier__logo-img')
+ })
+
+ it('renders with a custom className', () => {
+ const { getByRole } = render(
+
+
+
+ )
+
+ expect(getByRole('img')).toHaveProperty('alt', 'Test Agency Name logo')
+ expect(getByRole('link')).toHaveClass(
+ 'usa-identifier__logo-custom-class-name'
+ )
+ expect(getByRole('link')).toHaveProperty('href')
+ })
+
+ it('renders a logo in Spanish', () => {
+ const { getByRole } = render(
+
+
+
+ )
+
+ expect(getByRole('img')).toHaveProperty('alt', 'Logo de Test Agency Name')
+ })
+})
diff --git a/src/components/Identifier/IdentifierLogo/IdentifierLogo.tsx b/src/components/Identifier/IdentifierLogo/IdentifierLogo.tsx
new file mode 100644
index 0000000000..c687935579
--- /dev/null
+++ b/src/components/Identifier/IdentifierLogo/IdentifierLogo.tsx
@@ -0,0 +1,20 @@
+import React from 'react'
+import classnames from 'classnames'
+
+export interface IdentifierLogoProps {
+ children: React.ReactNode
+ className?: string
+}
+
+export const IdentifierLogo = ({
+ children,
+ className,
+ ...anchorProps
+}: IdentifierLogoProps & JSX.IntrinsicElements['a']): React.ReactElement => {
+ const classes = classnames('usa-identifier__logo', className)
+ return (
+
+ {children}
+
+ )
+}
diff --git a/src/components/Identifier/IdentifierMasthead/IdentifierMasthead.test.tsx b/src/components/Identifier/IdentifierMasthead/IdentifierMasthead.test.tsx
new file mode 100644
index 0000000000..126d1146c3
--- /dev/null
+++ b/src/components/Identifier/IdentifierMasthead/IdentifierMasthead.test.tsx
@@ -0,0 +1,107 @@
+import React from 'react'
+import { render } from '@testing-library/react'
+
+import dotGovIcon from 'uswds/src/img/icon-dot-gov.svg'
+
+import { IdentifierMasthead } from './IdentifierMasthead'
+import { IdentifierLogo } from '../IdentifierLogo/IdentifierLogo'
+
+const testIdentifierLogo = [
+ ,
+]
+
+const testIdentifierLogoSpanish = [
+ ,
+]
+
+describe('IdentifierMasthead component', () => {
+ it('renders without errors', () => {
+ const { getAllByRole, queryByTestId } = render(
+
+
+
+
+ {testIdentifierLogo}
+
+
+
+
+ domain.edu.mil.gov
+
+
+ {`An official website of the `}
+ Test Agency Name
+
+
+
+
+ )
+
+ expect(queryByTestId('identifierMasthead-logo')).toBeInTheDocument
+ expect(getAllByRole('link')).toHaveLength(2)
+ expect(queryByTestId('identifierMasthead')).toBeInTheDocument()
+ expect(queryByTestId('identifierMasthead')).toHaveClass(
+ 'usa-identifier__section usa-identifier__section--masthead usa-identifier__custom-class-name'
+ )
+ })
+
+ it('renders in Spanish', () => {
+ const { queryByAltText } = render(
+ {testIdentifierLogoSpanish}
+ )
+ expect(queryByAltText('Logo de Test Agency Name')).toBeInTheDocument()
+ })
+
+ it('renders without a logo passed in', () => {
+ const { queryByTestId } = render()
+ expect(queryByTestId('identifierMasthead-logo')).not.toBeInTheDocument()
+ })
+
+ it('renders with more than two logos passed in', () => {
+ const { getAllByRole, queryByText } = render(
+
+
+
+ {testIdentifierLogo}
+ {testIdentifierLogo}
+ {testIdentifierLogo}
+
+
+
+
+ )
+ expect(getAllByRole('img')).toHaveLength(3)
+ expect(getAllByRole('link')).toHaveLength(6)
+ expect(queryByText('Third Test Agency Name')).toBeInTheDocument()
+ })
+})
diff --git a/src/components/Identifier/IdentifierMasthead/IdentifierMasthead.tsx b/src/components/Identifier/IdentifierMasthead/IdentifierMasthead.tsx
new file mode 100644
index 0000000000..b974631a17
--- /dev/null
+++ b/src/components/Identifier/IdentifierMasthead/IdentifierMasthead.tsx
@@ -0,0 +1,30 @@
+import React, { ReactElement } from 'react'
+import classnames from 'classnames'
+
+interface IdentifierMastheadProps {
+ className?: string
+ children?: React.ReactNode
+}
+
+export const IdentifierMasthead = ({
+ className,
+ children,
+ ...sectionProps
+}: IdentifierMastheadProps &
+ JSX.IntrinsicElements['section']): React.ReactElement => {
+ const classes = classnames(
+ 'usa-identifier__section usa-identifier__section--masthead',
+ className
+ )
+
+ return (
+
+ )
+}
+
+export default IdentifierMasthead
diff --git a/src/index.ts b/src/index.ts
index 554808078b..d5df850252 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -51,6 +51,15 @@ export { NavDropDownButton } from './components/header/NavDropDownButton/NavDrop
export { PrimaryNav } from './components/header/PrimaryNav/PrimaryNav'
export { Title } from './components/header/Title/Title'
+/** Identifier Components */
+export { Identifier } from './components/Identifier/Identifier/Identifier'
+export { IdentifierGov } from './components/Identifier/IdentifierGov/IdentifierGov'
+export { IdentifierLink } from './components/Identifier/IdentifierLink/IdentifierLink'
+export { IdentifierLinkItem } from './components/Identifier/IdentifierLinkItem/IdentifierLinkItem'
+export { IdentifierLinks } from './components/Identifier/IdentifierLinks/IdentifierLinks'
+export { IdentifierLogo } from './components/Identifier/IdentifierLogo/IdentifierLogo'
+export { IdentifierMasthead } from './components/Identifier/IdentifierMasthead/IdentifierMasthead'
+
/** Footer components */
export { Address } from './components/Footer/Address/Address'
export { Footer } from './components/Footer/Footer/Footer'
diff --git a/yarn.lock b/yarn.lock
index 015e6b2210..8074f735ed 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4239,15 +4239,10 @@ camelcase@^6.0.0, camelcase@^6.2.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
-caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001173:
- version "1.0.30001179"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001179.tgz#b0803883b4471a6c62066fb1752756f8afc699c8"
- integrity sha512-blMmO0QQujuUWZKyVrD1msR4WNDAqb/UPO1Sw2WWsQ7deoM5bJiicKnWJ1Y0NS/aGINSnKPIWBMw5luX+NDUCA==
-
-caniuse-lite@^1.0.30001125:
- version "1.0.30001199"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001199.tgz#062afccaad21023e2e647d767bac4274b8b8fd7f"
- integrity sha512-ifbK2eChUCFUwGhlEzIoVwzFt1+iriSjyKKFYNfv6hN34483wyWpLLavYQXhnR036LhkdUYaSDpHg1El++VgHQ==
+caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001173:
+ version "1.0.30001202"
+ resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001202.tgz"
+ integrity sha512-ZcijQNqrcF8JNLjzvEiXqX4JUYxoZa7Pvcsd9UD8Kz4TvhTonOSNRsK+qtvpVL4l6+T1Rh4LFtLfnNWg6BGWCQ==
capture-exit@^2.0.0:
version "2.0.0"