Skip to content

Commit

Permalink
Merge pull request #1079 from ustaxcourt/test
Browse files Browse the repository at this point in the history
Merge Test into Staging
  • Loading branch information
mmarcotte authored Apr 16, 2021
2 parents d3d3280 + 81dc40f commit c3a620f
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 74 deletions.
6 changes: 3 additions & 3 deletions web-client/src/styles/custom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1669,7 +1669,7 @@ button.change-scanner-button {
max-width: 1440px;
}

h3.usa-footer__logo-heading {
.usa-footer__logo-heading {
font-family: $font-serif;
font-size: 18px;
font-weight: 700;
Expand Down Expand Up @@ -1704,7 +1704,7 @@ button.change-scanner-button {

@media only screen and (max-width: $large-screen - 1) {
.usa-footer__secondary-section {
h3.usa-footer__logo-heading {
.usa-footer__logo-heading {
font-size: 16px;
}
}
Expand All @@ -1722,7 +1722,7 @@ button.change-scanner-button {
margin-bottom: 10px;
}

h3.usa-footer__logo-heading {
.usa-footer__logo-heading {
font-size: 18px;
}
}
Expand Down
42 changes: 25 additions & 17 deletions web-client/src/styles/tabs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,14 @@
background: none;
color: color($theme-color-primary);
cursor: pointer;
font-family: $font-serif;
font-size: 32px;
font-weight: bold;
text-align: left;

.button-text {
display: inline;
font-family: $font-serif;
font-size: 32px;
font-weight: bold;
text-align: left;
}

&:hover {
border-bottom: 3px solid color($theme-color-primary-darker);
Expand Down Expand Up @@ -95,16 +99,19 @@
display: inline-block;
padding: 10px 27px 15px;
margin-right: 0;
font-size: 17px;
text-align: center;

.button-text {
font-size: 17px;
text-align: center;
}

&:hover,
&:focus {
border-bottom: none;
background-color: none;
color: color($theme-color-primary-darker);

span {
.button-text {
padding-bottom: 0;
border-bottom: 1px solid color($theme-color-primary-darker);
}
Expand All @@ -121,12 +128,12 @@
cursor: default;

&:hover {
span {
.button-text {
border-bottom: 3px solid color($theme-color-primary);
}
}

span {
.button-text {
border-bottom: 3px solid color($theme-color-primary);
}
}
Expand Down Expand Up @@ -159,16 +166,18 @@
padding: 10px 27px 15px;
margin-right: 0;
color: $color-white;
font-size: 17px;
text-align: center;
.button-text {
font-size: 17px;
text-align: center;
}

&:hover,
&:focus {
border-bottom: none;
background-color: none;
color: $color-white;

span {
.button-text {
padding-bottom: 0;
border-bottom: 3px solid $color-white;
}
Expand All @@ -187,16 +196,15 @@
&:hover {
color: color($theme-color-primary-darker);

span {
.button-text {
padding-bottom: 0;
border-bottom: 3px solid color($theme-color-primary-darker);
}

}

span {
.button-text {
border-bottom: 3px solid color($theme-color-primary);

}
}
}
Expand All @@ -208,14 +216,14 @@
&.tab-button-h2 {
> nav ul {
margin-bottom: 20px;
li button {
li button .button-text {
font-size: 24px;
}
}
}

&.tab-button-h3 {
nav ul li button {
nav ul li button .button-text {
font-size: 17px;
}
}
Expand Down
33 changes: 23 additions & 10 deletions web-client/src/ustc-ui/FocusLock/FocusLock.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,41 @@ const appRoot =
window.document.getElementById('app') ||
window.document.getElementById('app-public');
const tabbableSelector =
'a:enabled,button:enabled,input:enabled,select:enabled,textarea:enabled';
'a:enabled,button:enabled,input:enabled,select:enabled,textarea:enabled,h1[tabindex],h2[tabindex],h3[tabindex],h4[tabindex],.focusable[tabindex]';

export const FocusLock = ({ children }) => {
const el = useRef(null);

const previousElementWithFocus =
(window.document.hasFocus() &&
window.document.activeElement !== window.document.body &&
window.document.activeElement !== window.document.documentElement &&
window.document.activeElement) ||
{};

const getLockedTabbables = () => {
const lockedElements = el.current.querySelectorAll(tabbableSelector);
return {
first: lockedElements.item(0),
last: lockedElements.item(lockedElements.length - 1),
};
};

const onKey = event => {
if (event.keyCode != 9 || !el.current.contains(event.target)) {
// not tab key on element within this component
return;
}
const lockedElements = el.current.querySelectorAll(tabbableSelector);
const [firstTabbable, lastTabbable] = [
lockedElements.item(0),
lockedElements.item(lockedElements.length - 1),
];
if (event.target == firstTabbable && event.shiftKey) {
const tabbables = getLockedTabbables();
if (event.target == tabbables.first && event.shiftKey) {
// shift-tab when on firstTabbable: move focus to lastTabbable
lastTabbable.focus();
tabbables.last.focus();
event.preventDefault();
return false;
}
if (event.target == lastTabbable && !event.shiftKey) {
if (event.target == tabbables.last && !event.shiftKey) {
// tab (without shift) when on lastTabbable: move focus to firstTabbable
firstTabbable.focus();
tabbables.first.focus();
event.preventDefault();
return false;
}
Expand All @@ -39,11 +50,13 @@ export const FocusLock = ({ children }) => {
appRoot.inert = true; // leverages wicg-inert polyfill
appRoot.setAttribute('aria-hidden', 'true');
window.document.addEventListener('keydown', onKey);
getLockedTabbables().first.focus();

return () => {
appRoot.inert = false;
appRoot.setAttribute('aria-hidden', 'false');
window.document.removeEventListener('keydown', onKey);
previousElementWithFocus.focus && previousElementWithFocus.focus();
};
}, []);

Expand Down
100 changes: 58 additions & 42 deletions web-client/src/ustc-ui/Tabs/Tabs.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,48 +20,14 @@ if (process.env.NODE_ENV === 'test') {
({ FontAwesomeIcon } = require('@fortawesome/react-fontawesome'));
}

/**
* Tab
*/
export function Tab() {}

/**
* TabsComponent
*
* @param {*} properties the props
* @returns {*} the rendered component
*/
export function TabsComponent({
const renderTabFactory = ({
activeKey,
asSwitch,
bind,
boxed,
children,
className,
defaultActiveTab,
id,
onSelect,
simpleSetter,
value,
}) {
// TODO - Refactor how tab selection sets documentSelectedForScan
let activeKey, setTab;

defaultActiveTab =
defaultActiveTab || getDefaultAttribute(children, 'tabName');

if (bind) {
const useCerebralState = useCerebralStateFactory(
simpleSetter,
value || defaultActiveTab,
);
[activeKey, setTab] = useCerebralState(bind, defaultActiveTab);
} else {
[activeKey, setTab] = useState(defaultActiveTab);
}

setTab = decorateWithPostCallback(setTab, onSelect);

const renderTab = child => {
headingLevel,
setTab,
}) =>
function TabComponent(child) {
const {
children: tabChildren,
className: childClassName,
Expand Down Expand Up @@ -89,6 +55,7 @@ export function TabsComponent({
return null;
}

const HeadingElement = headingLevel ? `h${headingLevel}` : 'span';
const tabProps = {
'aria-controls': tabContentId,
'aria-selected': isActiveTab,
Expand All @@ -107,7 +74,7 @@ export function TabsComponent({
return (
<li {...tabProps}>
<button {...buttonProps}>
<span>{title}</span>{' '}
<HeadingElement className="button-text">{title}</HeadingElement>{' '}
{showIcon && (
<FontAwesomeIcon color={iconColor || null} icon={icon} />
)}
Expand All @@ -120,6 +87,47 @@ export function TabsComponent({
</li>
);
};
/**
* Tab
*/
export function Tab() {}

/**
* TabsComponent
*
* @param {*} properties the props
* @returns {*} the rendered component
*/
export function TabsComponent({
asSwitch,
bind,
boxed,
children,
className,
defaultActiveTab,
headingLevel,
id,
onSelect,
simpleSetter,
value,
}) {
// TODO - Refactor how tab selection sets documentSelectedForScan
let activeKey, setTab;

defaultActiveTab =
defaultActiveTab || getDefaultAttribute(children, 'tabName');

if (bind) {
const useCerebralState = useCerebralStateFactory(
simpleSetter,
value || defaultActiveTab,
);
[activeKey, setTab] = useCerebralState(bind, defaultActiveTab);
} else {
[activeKey, setTab] = useState(defaultActiveTab);
}

setTab = decorateWithPostCallback(setTab, onSelect);

const renderTabContent = child => {
const { children: tabChildren, tabName } = child.props;
Expand Down Expand Up @@ -171,6 +179,14 @@ export function TabsComponent({
baseProps = {};
}

const TabComponent = renderTabFactory({
activeKey,
asSwitch,
boxed,
headingLevel,
setTab,
});

return (
<div {...baseProps}>
{hasNav && (
Expand All @@ -179,7 +195,7 @@ export function TabsComponent({
className={classNames('ustc-ui-tabs', { 'grid-row': boxed })}
role="tablist"
>
{map(children, renderTab)}
{map(children, TabComponent)}
</ul>
</nav>
)}
Expand Down
30 changes: 30 additions & 0 deletions web-client/src/ustc-ui/Tabs/Tabs.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,36 @@ describe('TabsComponent', () => {
);
});

it('should use a span tag for tab label if no headingLevel parameter is provided', () => {
let testRenderer;
act(() => {
testRenderer = TestRenderer.create(
<TabsComponent>
<Tab tabName="myTabName" title="No Heading Level" />
</TabsComponent>,
);
});

const testInstance = testRenderer.root;

expect(testInstance.findByType('span')).toBeDefined();
});

it('should render tab label within the proper heading tag if headingLevel parameter is present', () => {
let testRenderer;
act(() => {
testRenderer = TestRenderer.create(
<TabsComponent headingLevel="2">
<Tab tabName="myTabName" title="Heading Level Two" />
</TabsComponent>,
);
});

const testInstance = testRenderer.root;

expect(testInstance.findByType('h2')).toBeDefined();
});

it('should create a default tab element id if one is not provided', () => {
let testRenderer;
act(() => {
Expand Down
1 change: 1 addition & 0 deletions web-client/src/views/AdvancedSearch/AdvancedSearch.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const AdvancedSearch = connect(
bind="advancedSearchTab"
className="classic-horizontal-header3 tab-border"
defaultActiveTab={searchTabs.CASE}
headingLevel="2"
onSelect={() => {
advancedSearchTabChangeSequence();
}}
Expand Down
Loading

0 comments on commit c3a620f

Please sign in to comment.