Skip to content

Commit

Permalink
feat(routing): send focus to new content after routing
Browse files Browse the repository at this point in the history
listen for route changes, send focus to the new content after route changes
add react styles pkg, adjust webpack config
specify main container element id
allow for sending route props to page components
ensure focus is sent after sync and async routing alike
bump pf version to consume changes in react-core
  • Loading branch information
seanforyou23 authored and dgutride committed Jul 30, 2019
1 parent fbfb715 commit 6d4d68d
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 40 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@
"webpack-merge": "^4.1.4"
},
"dependencies": {
"@patternfly/react-core": "^3.58.1",
"@patternfly/react-core": "^3.77.2",
"@patternfly/react-icons": "^3.10.10",
"@patternfly/react-styles": "^3.4.6",
"react-document-title": "^2.0.3",
"react-router-dom": "^5.0.1"
}
Expand Down
3 changes: 2 additions & 1 deletion src/app/AppLayout/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,13 @@ const AppLayout: React.FunctionComponent<IAppLayout> = ({children}) => {
isNavOpen={isMobileView ? isNavOpenMobile : isNavOpen} />
);
const PageSkipToContent = (
<SkipToContent href="#main-content-page-layout-default-nav">
<SkipToContent href="#primary-app-container">
Skip to Content
</SkipToContent>
);
return (
<Page
mainContainerId="primary-app-container"
header={Header}
sidebar={Sidebar}
onPageResize={onPageResize}
Expand Down
4 changes: 2 additions & 2 deletions src/app/Dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as React from 'react';
import { PageSection, Title } from '@patternfly/react-core';

const Dashboard: React.FunctionComponent<{}> = () => {
const Dashboard: React.FunctionComponent<any> = (props) => {
return (
<PageSection>
<Title size="lg">Dashboard</Title>
<Title size="lg">Dashboard Page Title</Title>
</PageSection>
);
}
Expand Down
12 changes: 9 additions & 3 deletions src/app/DynamicImport.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import { accessibleRouteChangeHandler } from '@app/utils/utils';

interface IDynamicImport {
load: () => Promise<any>;
Expand All @@ -11,9 +12,14 @@ class DynamicImport extends React.Component<IDynamicImport> {
};
public componentDidMount() {
this.props.load().then(component => {
this.setState({
component: component.default ? component.default : component
});
if (component) {
this.setState({
component: component.default ? component.default : component
});
}
})
.then(() => {
accessibleRouteChangeHandler();
});
}
public render() {
Expand Down
3 changes: 1 addition & 2 deletions src/app/Support/Support.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import {
EmptyStateSecondaryActions
} from '@patternfly/react-core';

const Support: React.FunctionComponent<{}> = () => {

const Support: React.FunctionComponent<any> = (props) => {
return (
<PageSection>
<EmptyState variant={EmptyStateVariant.full}>
Expand Down
35 changes: 30 additions & 5 deletions src/app/routes.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as React from 'react';
import { Redirect, 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';
Expand All @@ -9,28 +11,48 @@ const getSupportModuleAsync = () => {
return () => import(/* webpackChunkName: 'support' */ '@app/Support/Support');
};

const Support = () => {
const Support = (routeProps: RouteComponentProps) => {
return (
<DynamicImport load={getSupportModuleAsync()}>
{(Component: any) => {
return Component === null ? <p>loading</p> : <Component.Support />;
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>
);
};

const RouteWithTitleUpdates = ({
component: Component,
isAsync = false,
title,
...rest
}) => {
function routeWithTitle(routeProps) {
function routeWithTitle(routeProps: RouteComponentProps) {
return (
<DocumentTitle title={title}>
<Component {...routeProps} />
</DocumentTitle>
)
}

React.useEffect(() => {
if (!isAsync) {
accessibleRouteChangeHandler()
}
}, []);

return (
<Route {...rest} render={routeWithTitle} />
);
Expand All @@ -43,6 +65,7 @@ export interface IAppRoute {
exact?: boolean;
path: string;
title: string;
isAsync?: boolean;
}

const routes: IAppRoute[] = [
Expand All @@ -58,6 +81,7 @@ const routes: IAppRoute[] = [
component: Support,
exact: true,
icon: null,
isAsync: true,
label: 'Support',
path: '/support',
title: 'Support Page Title'
Expand All @@ -66,13 +90,14 @@ const routes: IAppRoute[] = [

const AppRoutes = () => (
<Switch>
{routes.map(({ path, exact, component, title }, idx) => (
{routes.map(({ path, exact, component, title, isAsync }, idx) => (
<RouteWithTitleUpdates
path={path}
exact={exact}
component={component}
key={idx}
title={title} />
title={title}
isAsync={isAsync} />
))}
<Redirect exact={true} from="/" to="/dashboard" />
<RouteWithTitleUpdates component={NotFound} title={'404 Page Not Found'} />
Expand Down
6 changes: 6 additions & 0 deletions src/app/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export function accessibleRouteChangeHandler() {
const mainContainer = document.getElementById('primary-app-container');
if (mainContainer) {
mainContainer.focus();
}
}
3 changes: 2 additions & 1 deletion webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ module.exports = {
path.resolve(__dirname, 'node_modules/patternfly'),
path.resolve(__dirname, 'node_modules/@patternfly/patternfly/assets'),
path.resolve(__dirname, 'node_modules/@patternfly/react-core/dist/styles/assets/images'),
path.resolve(__dirname, 'node_modules/@patternfly/react-styles/css/assets/images')
path.resolve(__dirname, 'node_modules/@patternfly/react-styles/css/assets/images'),
path.resolve(__dirname, 'node_modules/@patternfly/react-core/node_modules/@patternfly/react-styles/css/assets/images')
],
use: [
{
Expand Down
3 changes: 2 additions & 1 deletion webpack.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ module.exports = merge(common, {
path.resolve(__dirname, 'node_modules/@patternfly/patternfly'),
path.resolve(__dirname, 'node_modules/@patternfly/react-styles/css'),
path.resolve(__dirname, 'node_modules/@patternfly/react-core/dist/styles/base.css'),
path.resolve(__dirname, 'node_modules/@patternfly/react-core/dist/esm/@patternfly/patternfly')
path.resolve(__dirname, 'node_modules/@patternfly/react-core/dist/esm/@patternfly/patternfly'),
path.resolve(__dirname, 'node_modules/@patternfly/react-core/node_modules/@patternfly/react-styles/css')
],
use: ["style-loader", "css-loader"]
}
Expand Down
1 change: 1 addition & 0 deletions webpack.prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ module.exports = merge(common, {
path.resolve(__dirname, 'node_modules/@patternfly/patternfly'),
path.resolve(__dirname, 'node_modules/@patternfly/react-core/dist/styles/base.css'),
path.resolve(__dirname, 'node_modules/@patternfly/react-core/dist/esm/@patternfly/patternfly'),
path.resolve(__dirname, 'node_modules/@patternfly/react-core/node_modules/@patternfly/react-styles/css'),
path.resolve(__dirname, 'node_modules/@patternfly/react-styles/css')
],
use: [MiniCssExtractPlugin.loader, 'css-loader']
Expand Down
59 changes: 35 additions & 24 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -386,18 +386,18 @@
"@nodelib/fs.scandir" "2.1.1"
fastq "^1.6.0"

"@patternfly/react-core@^3.58.1":
version "3.58.1"
resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-3.58.1.tgz#3b9ea3a8cabe8c49f1df7f4b5e8ea16938f7a3f1"
integrity sha512-ahb7cbWsLWZu69sHnn3ZdB5tcpXAbgHcUbAttWuG01KVpleK50qkwZMWW0JzuDlUfnelpW3kbaVfNE14HZo+Eg==
dependencies:
"@patternfly/react-icons" "^3.10.6"
"@patternfly/react-styles" "^3.4.6"
"@patternfly/react-tokens" "^2.6.5"
"@tippy.js/react" "^1.1.1"
"@patternfly/react-core@^3.77.2":
version "3.80.2"
resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-3.80.2.tgz#db91e6d49efff211a84975ce01c4c777930066af"
integrity sha512-DAeu1JfZTXjFb9xC7fvc336c6DNRaSKwgYlk1CkdZydXcZGK9CW3MpbqgU92uKhn1o4vgNDyhKJ6AdYTR3txNg==
dependencies:
"@patternfly/react-icons" "^3.10.14"
"@patternfly/react-styles" "^3.5.7"
"@patternfly/react-tokens" "^2.6.13"
emotion "^9.2.9"
exenv "^1.2.2"
focus-trap-react "^4.0.1"
tippy.js "^3.2.0"

"@patternfly/react-icons@^3.10.10":
version "3.10.10"
Expand All @@ -406,10 +406,10 @@
dependencies:
"@fortawesome/free-brands-svg-icons" "^5.8.1"

"@patternfly/react-icons@^3.10.6":
version "3.10.9"
resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-3.10.9.tgz#878b347dd2d4258b79226a7103326bfd95d4c61d"
integrity sha512-RwRa6L/iyitPGrTV8/ST1bcJQhbii+B21nPKFUGNCHzCNymgjGgfruI75l4eMBBrcf7S9vA+iuU+t2tttgu8qA==
"@patternfly/react-icons@^3.10.14":
version "3.10.14"
resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-3.10.14.tgz#537a744dc4aa00ae27e0caafa737a967a930932e"
integrity sha512-LJIeaP6tv54Yr5/h4BMUem//tQADXhKJiV46Qhx2M+/k89Kr5cXYxRpXh7b2KBBqORybX/Wb/6EHixT7KI5ZaA==
dependencies:
"@fortawesome/free-brands-svg-icons" "^5.8.1"

Expand All @@ -432,18 +432,29 @@
resolve-from "^4.0.0"
typescript "3.4.5"

"@patternfly/react-tokens@^2.6.5":
version "2.6.5"
resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-2.6.5.tgz#94907bbf1182855ceb69a44a0e351f7775842f19"
integrity sha512-HZ0LLAOugMmnD9n5T5Hp6vDnZ86ikm+MXu7kbfNqK9dTOVmEroPai0rUN6hnnPP4mCzFrLXmh4rzecDr2273yg==

"@tippy.js/react@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@tippy.js/react/-/react-1.1.1.tgz#91476726529e31d4c9f9074d995d0fa31f3b6e2d"
integrity sha512-TkL1VufxgUvTMouDoBGv2vTdtUxtLUaRpspI4Rv0DsoKe2Ex1E5bl/qISk434mhuAhEnXuemrcgTaPWrfDvmGw==
"@patternfly/react-styles@^3.5.7":
version "3.5.7"
resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-3.5.7.tgz#0bf8e615d09c2ed37235f3bcdb633764469ff499"
integrity sha512-6EzVzSnn3hTnsxeKvB5rZY1f/egkDIJRuSO5VGeXtuQv52KEyb3UDLSIuuZVBR7RZdgXsL0FvQ0lsyIxEPYcFg==
dependencies:
prop-types "^15.6.2"
tippy.js "^3.2.0"
"@babel/helper-plugin-utils" "^7.0.0-beta.48"
camel-case "^3.0.0"
css "^2.2.3"
cssom "^0.3.4"
cssstyle "^0.3.1"
emotion "^9.2.9"
emotion-server "^9.2.9"
fbjs-scripts "^0.8.3"
fs-extra "^6.0.1"
jsdom "^15.1.0"
relative "^3.0.2"
resolve-from "^4.0.0"
typescript "3.4.5"

"@patternfly/react-tokens@^2.6.13":
version "2.6.13"
resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-2.6.13.tgz#68c4c7ba2cde6b5a99ea3a9a85a8cbffce118695"
integrity sha512-rUvXeIIxeod/RrNncSrPFM9VloEKvauiZjDjrFNrXw119JX+DqJy7Di/DQR0LE0HVHY4H5n1tfVu7NrYIsqFPg==

"@types/anymatch@*":
version "1.3.1"
Expand Down

0 comments on commit 6d4d68d

Please sign in to comment.