Skip to content

Commit

Permalink
chore(webpack): tune webpack config (patternfly#60)
Browse files Browse the repository at this point in the history
* chore(webpack): tune webpack config

only focus new content when user navigates in-app
add small delay before sending focus for JAWS

* [cleanup] clear timer so they do not queue when switching routes often

* [cleanup] fix active state for nav items
  • Loading branch information
seanforyou23 authored and Bhanvi Menghani committed Mar 18, 2022
1 parent 7d9fb47 commit f6c7759
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 42 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"@patternfly/react-icons": "^3.10.10",
"@patternfly/react-styles": "^3.4.6",
"react-document-title": "^2.0.3",
"react-router-dom": "^5.0.1"
"react-router-dom": "^5.0.1",
"react-router-last-location": "^2.0.1"
}
}
2 changes: 1 addition & 1 deletion src/app/AppLayout/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const AppLayout: React.FunctionComponent<IAppLayout> = ({children}) => {
{routes.map((route, idx) => {
return (
<NavItem key={`${route.label}-${idx}`} id={`${route.label}-${idx}`}>
<NavLink to={route.path} activeClassName="pf-m-current">{route.label}</NavLink>
<NavLink exact={true} to={route.path} activeClassName="pf-m-current">{route.label}</NavLink>
</NavItem>
);
})}
Expand Down
17 changes: 14 additions & 3 deletions src/app/DynamicImport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,21 @@ import { accessibleRouteChangeHandler } from '@app/utils/utils';
interface IDynamicImport {
load: () => Promise<any>;
children: any;
focusContentAfterMount: boolean;
}

class DynamicImport extends React.Component<IDynamicImport> {
public state = {
component: null
};
private routeFocusTimer: number;
constructor(props: IDynamicImport) {
super(props);
this.routeFocusTimer = 0;
}
public componentWillUnmount() {
window.clearTimeout(this.routeFocusTimer);
}
public componentDidMount() {
this.props.load().then(component => {
if (component) {
Expand All @@ -18,9 +27,11 @@ class DynamicImport extends React.Component<IDynamicImport> {
});
}
})
.then(() => {
accessibleRouteChangeHandler();
});
.then(() => {
if (this.props.focusContentAfterMount) {
this.routeFocusTimer = accessibleRouteChangeHandler();
}
});
}
public render() {
return this.props.children(this.state.component);
Expand Down
2 changes: 1 addition & 1 deletion src/app/NotFound/NotFound.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const NotFound: React.FunctionComponent = () => {
return (
<PageSection>
<Alert variant="danger" title="404! This view hasn't been created yet." /><br />
<NavLink to="/dashboard" className="pf-c-nav__link">Back to Dashboard</NavLink>
<NavLink to="/" className="pf-c-nav__link">Take me home</NavLink>
</PageSection>
);
}
Expand Down
72 changes: 40 additions & 32 deletions src/app/routes.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
import * as React from 'react';
import { Redirect, Route, RouteComponentProps, Switch } from 'react-router-dom';
import { Route, RouteComponentProps, Switch } from 'react-router-dom';
import { Alert, PageSection } from '@patternfly/react-core';
import { DynamicImport } from '@app/DynamicImport';
import { accessibleRouteChangeHandler } from '@app/utils/utils';
import { Dashboard } from '@app/Dashboard/Dashboard';
import { NotFound } from '@app/NotFound/NotFound';
import DocumentTitle from 'react-document-title';

import { LastLocationProvider, useLastLocation } from 'react-router-last-location';
let routeFocusTimer: number;
const getSupportModuleAsync = () => {
return () => import(/* webpackChunkName: 'support' */ '@app/Support/Support');
};

const Support = (routeProps: RouteComponentProps) => {
const lastNavigation = useLastLocation();
return (
<DynamicImport load={getSupportModuleAsync()}>
<DynamicImport load={getSupportModuleAsync()} focusContentAfterMount={lastNavigation !== null}>
{(Component: any) => {
let loadedComponent: any;
if (Component === null) {
loadedComponent = (
<PageSection aria-label="Loading Content Container">
<div className="pf-l-bullseye">
<Alert title="Loading" className="pf-l-bullseye__item" />
</div>
</PageSection>
);
} else {
loadedComponent = <Component.Support {...routeProps} />;
}
return loadedComponent
let loadedComponent: any;
if (Component === null) {
loadedComponent = (
<PageSection aria-label="Loading Content Container">
<div className="pf-l-bullseye">
<Alert title="Loading" className="pf-l-bullseye__item" />
</div>
</PageSection>
);
} else {
loadedComponent = <Component.Support {...routeProps} />;
}
return loadedComponent
}}
</DynamicImport>
);
Expand All @@ -39,6 +41,8 @@ const RouteWithTitleUpdates = ({
title,
...rest
}) => {
const lastNavigation = useLastLocation();

function routeWithTitle(routeProps: RouteComponentProps) {
return (
<DocumentTitle title={title}>
Expand All @@ -48,9 +52,12 @@ const RouteWithTitleUpdates = ({
}

React.useEffect(() => {
if (!isAsync) {
accessibleRouteChangeHandler()
if (!isAsync && lastNavigation !== null) {
routeFocusTimer = accessibleRouteChangeHandler()
}
return () => {
clearTimeout(routeFocusTimer);
};
}, []);

return (
Expand All @@ -74,7 +81,7 @@ const routes: IAppRoute[] = [
exact: true,
icon: null,
label: 'Dashboard',
path: '/dashboard',
path: '/',
title: 'Main Dashboard Title'
},
{
Expand All @@ -89,19 +96,20 @@ const routes: IAppRoute[] = [
];

const AppRoutes = () => (
<Switch>
{routes.map(({ path, exact, component, title, isAsync }, idx) => (
<RouteWithTitleUpdates
path={path}
exact={exact}
component={component}
key={idx}
title={title}
isAsync={isAsync} />
))}
<Redirect exact={true} from="/" to="/dashboard" />
<RouteWithTitleUpdates component={NotFound} title={'404 Page Not Found'} />
</Switch>
<LastLocationProvider>
<Switch>
{routes.map(({ path, exact, component, title, isAsync }, idx) => (
<RouteWithTitleUpdates
path={path}
exact={exact}
component={component}
key={idx}
title={title}
isAsync={isAsync} />
))}
<RouteWithTitleUpdates component={NotFound} title={'404 Page Not Found'} />
</Switch>
</LastLocationProvider>
);

export { AppRoutes, routes };
10 changes: 6 additions & 4 deletions src/app/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export function accessibleRouteChangeHandler() {
const mainContainer = document.getElementById('primary-app-container');
if (mainContainer) {
mainContainer.focus();
}
return window.setTimeout(() => {
const mainContainer = document.getElementById('primary-app-container');
if (mainContainer) {
mainContainer.focus();
}
}, 50);
}
2 changes: 2 additions & 0 deletions webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ module.exports = {
path.resolve(__dirname, 'node_modules/patternfly/dist/fonts'),
path.resolve(__dirname, 'node_modules/@patternfly/react-core/dist/styles/assets/fonts'),
path.resolve(__dirname, 'node_modules/@patternfly/react-core/dist/styles/assets/pficon'),
path.resolve(__dirname, 'node_modules/@patternfly/patternfly/assets/fonts'),
path.resolve(__dirname, 'node_modules/@patternfly/patternfly/assets/pficon')
],
use: {
loader: 'file-loader',
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7183,6 +7183,11 @@ react-router-dom@^5.0.1:
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"

react-router-last-location@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/react-router-last-location/-/react-router-last-location-2.0.1.tgz#54d625876dd1448594fa1114aa02e7e21db12970"
integrity sha512-3FbFIWwUr2qN28vN9DNdFp6RhUH/yif6ILVff1zT+hLdyGmlNPh3GuPhveb7bHQLgB744QW8L0qtWjX58ESuZQ==

[email protected]:
version "5.0.1"
resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.0.1.tgz#04ee77df1d1ab6cb8939f9f01ad5702dbadb8b0f"
Expand Down

0 comments on commit f6c7759

Please sign in to comment.