Skip to content

Commit

Permalink
Merge pull request #617 from HHS/ttahub-345-upgrade-all-packages
Browse files Browse the repository at this point in the history
TTAHUB-345 Upgrade to Trussworks 2.0 Component Library
  • Loading branch information
AdamAdHocTeam authored Nov 15, 2021
2 parents f170803 + 296a1f3 commit 5e61e12
Show file tree
Hide file tree
Showing 21 changed files with 839 additions and 540 deletions.
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"@fortawesome/free-solid-svg-icons": "^5.15.1",
"@fortawesome/react-fontawesome": "^0.1.11",
"@hookform/error-message": "^0.0.5",
"@trussworks/react-uswds": "1.11.0",
"@trussworks/react-uswds": "2.4.1",
"@use-it/interval": "^1.0.0",
"draft-js": "^0.11.7",
"draftjs-to-html": "^0.9.1",
Expand Down
122 changes: 122 additions & 0 deletions frontend/src/components/Accordion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';

export const AccordionItem = ({
title,
id,
content,
expanded,
className,
handleToggle,
headingSize,
}) => {
const headingClasses = `usa-accordion__heading ${className}`;
const contentClasses = `usa-accordion__content usa-prose ${className}`;
const HeadingSizeTag = `h${headingSize}`;
return (
<>
<HeadingSizeTag className={headingClasses}>
<button
type="button"
className="usa-accordion__button"
aria-expanded={expanded}
aria-controls={id}
data-testid={`accordionButton_${id}`}
onClick={handleToggle}
>
{title}
</button>
</HeadingSizeTag>
<div
id={id}
data-testid={`accordionItem_${id}`}
className={contentClasses}
hidden={!expanded}
>
{content}
</div>
</>
);
};

AccordionItem.propTypes = {
title: PropTypes.string.isRequired,
content: PropTypes.string.isRequired,
expanded: PropTypes.bool.isRequired,
id: PropTypes.string.isRequired,
className: PropTypes.string,
handleToggle: PropTypes.func,
headingSize: PropTypes.number.isRequired,
};

AccordionItem.defaultProps = {
className: '',
handleToggle: () => { },
};

export const Accordion = ({
bordered,
items,
multiselectable,
headingSize,
}) => {
const [openItems, setOpenState] = useState(
items.filter((i) => !!i.expanded).map((i) => i.id),
);

const classes = bordered ? 'usa-accordion usa-accordion--bordered' : 'usa-accordion';

const toggleItem = (itemId) => {
const newOpenItems = [...openItems];
const itemIndex = openItems.indexOf(itemId);
const isMultiselectable = multiselectable;

if (itemIndex > -1) {
newOpenItems.splice(itemIndex, 1);
} else if (isMultiselectable) {
newOpenItems.push(itemId);
} else {
newOpenItems.splice(0, newOpenItems.length);
newOpenItems.push(itemId);
}
setOpenState(newOpenItems);
};

return (
<div
className={classes}
data-testid="accordion"
aria-multiselectable={multiselectable || undefined}
>
{items.map((item) => (
<AccordionItem
key={`accordionItem_${item.id}`}
title={item.title}
id={item.id}
content={item.content}
className={item.className}
expanded={openItems.indexOf(item.id) > -1}
handleToggle={() => {
toggleItem(item.id);
}}
headingSize={headingSize}
/>
))}
</div>
);
};

Accordion.propTypes = {
bordered: PropTypes.bool,
multiselectable: PropTypes.bool,
items: PropTypes.arrayOf(PropTypes.shape(AccordionItem)).isRequired,
headingSize: PropTypes.number,
};

Accordion.defaultProps = {
bordered: false,
multiselectable: false,
headingSize: 2,
};

export default Accordion;
26 changes: 0 additions & 26 deletions frontend/src/components/DeleteReportModal.css

This file was deleted.

67 changes: 0 additions & 67 deletions frontend/src/components/DeleteReportModal.js

This file was deleted.

98 changes: 23 additions & 75 deletions frontend/src/components/ExternalResourceModal.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,18 @@
import React, { useCallback, useEffect, useRef } from 'react';
import React, { useRef } from 'react';
import PropTypes from 'prop-types';
import {
Button, Modal, Alert, useModal, connectModal,
} from '@trussworks/react-uswds';

import { Alert } from '@trussworks/react-uswds';
import Modal from './Modal';
import { isValidURL, isInternalGovernmentLink } from '../utils';

const ESCAPE_KEY_CODE = 27;

const ExternalResourceModal = ({ onOpen, onClose }) => (
<Modal
title={<h3>External Resources Disclaimer</h3>}
actions={(
<>
<Button type="button" onClick={onClose}>
Cancel
</Button>

<Button type="button" secondary onClick={onOpen}>
View External Resource
</Button>
</>
)}
>
<Alert role="alert" type="warning">
<b>Note:</b>
{' '}
This link is hosted outside of an OHS-led system.
OHS does not have responsibility for external content or
the privacy policies of non-government websites.
</Alert>
</Modal>
);

ExternalResourceModal.propTypes = {
onOpen: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired,
};

const ExternalLink = ({ to, children }) => {
const modalRef = useRef(null);
const { isOpen, openModal, closeModal } = useModal();

const onEscape = useCallback((event) => {
if (event.keyCode === ESCAPE_KEY_CODE) {
closeModal();
}
}, [closeModal]);

useEffect(() => {
document.addEventListener('keydown', onEscape, false);
return () => {
document.removeEventListener('keydown', onEscape, false);
};
}, [onEscape]);

useEffect(() => {
if (!modalRef.current) return;

const button = modalRef.current.querySelector('button');
if (button) {
button.focus();
}
});

if (!isValidURL(to)) {
return to;
}

const onClick = () => {
closeModal();
const openResource = () => {
modalRef.current.toggleModal(false);
window.open(to, '_blank');
};

Expand All @@ -78,19 +21,28 @@ const ExternalLink = ({ to, children }) => {
if (isInternalGovernmentLink(to)) {
window.open(to, '_blank');
} else {
openModal();
modalRef.current.toggleModal(true);
}
};

const ConnectModal = connectModal(() => (
<ExternalResourceModal onOpen={onClick} onClose={closeModal} />
));

return (
<>
<div ref={modalRef} aria-modal="true" role="dialog">
<ConnectModal isOpen={isOpen} onClose={closeModal} />
</div>
<Modal
modalRef={modalRef}
onOk={openResource}
modalId="ExternalResourceModal"
title="External Resources Disclaimer"
okButtonText="View External Resource"
okButtonAriaLabel="This button will redirect you to content that is outside of any OHS-led system."
>
<Alert role="alert" type="warning">
<b>Note:</b>
{' '}
This link is hosted outside of an OHS-led system.
OHS does not have responsibility for external content or
the privacy policies of non-government websites.
</Alert>
</Modal>
<a href={to} onClick={onLinkClick}>
{children}
{' '}
Expand All @@ -103,8 +55,4 @@ ExternalLink.propTypes = {
to: PropTypes.string.isRequired,
children: PropTypes.node.isRequired,
};

export {
ExternalResourceModal,
ExternalLink,
};
export default ExternalLink;
Loading

0 comments on commit 5e61e12

Please sign in to comment.