FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

feat(Wizard): add support for in page rendering by atiratree · Pull Request #2830 · patternfly/patternfly-react · GitHub

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .md  (1) .tsx  (2) All 2 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
    • Wizard.md
    • Wizard.tsx
    • WizardHeader.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -820,3 +820,32 @@ class SimpleWizard extends React.Component {
}
}
```

### Wizard - in page

```js
import React from 'react';
import { Wizard } from '@patternfly/react-core';

class InPageWizard extends React.Component {
render() {
const steps = [
{ name: 'Step 1', component: <p>Step 1</p> },
{ name: 'Step 2', component: <p>Step 2</p> },
{ name: 'Step 3', component: <p>Step 3</p> },
{ name: 'Step 4', component: <p>Step 4</p> },
{ name: 'Final Step', component: <p>Final Step</p>, hideCancelButton: true, nextButtonText: 'Close' }
];

return (
<div style={{height: '400px'}}>
<Wizard
isInPage
onClose={() => console.log('closed')}
steps={steps}
/>
</div>
);
}
}
```
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ export interface WizardStep {
export type WizardStepFunctionType = (newStep: { id?: string | number; name: string; }, prevStep: { prevId?: string | number; prevName: string; }) => void;

export interface WizardProps extends React.HTMLProps<HTMLDivElement> {
/** True to show the wizard */
/** True to show the wizard (not applicable for isInPage)*/
isOpen?: boolean;
/** True to show the wizard without the modal */
isInPage?: boolean;
/** If true makes the navigation more compact */
isCompactNav?: boolean;
/** True to set full height wizard */
Expand All @@ -55,8 +57,8 @@ export interface WizardProps extends React.HTMLProps<HTMLDivElement> {
width?: number | string;
/** Custom height of the wizard */
height?: number | string;
/** The wizard title */
title: string;
/** The wizard title (required unless isInPage is used) */
title?: string;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

title is now optional, because the header is not rendered in in-page wizard

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

The default wizard requires a title currently, and per conversations with @mcarrano here (patternfly/patternfly#2191) I believe we want to keep it that way. Making it optional creates these 2 scenarios:

Title/description is undefined renders an empty header, and the header is required at a minimum to position the close button.

Title is undefined but a description exists, which seems to work OK, but we haven't really accounted for that in core and I'm not sure we want to allow that per the design:

Can we make this optional if isInPage is true? And technically it isn't optional - the entire header shouldn't render if using an in-page wizard, so title and description shouldn't be allowed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

We can change the title to optional here since it technically is not always required. However, can you generate a warning if the title is not provided AND isModal is true.

/** The wizard description */
description?: string;
/** Callback function to close the wizard */
Expand Down Expand Up @@ -100,9 +102,11 @@ export class Wizard extends React.Component<WizardProps, WizardState> {
private static currentId = 0;
static defaultProps = {
isOpen: false,
isInPage: false,
Comment thread
atiratree marked this conversation as resolved.
isCompactNav: false,
isFullHeight: false,
isFullWidth: false,
title: '',
description: '',
className: '',
startAtStep: 1,
Expand All @@ -122,12 +126,20 @@ export class Wizard extends React.Component<WizardProps, WizardState> {
private container: HTMLDivElement;
private titleId: string;
private descriptionId: string;
private isModal: boolean;

constructor(props: WizardProps) {
super(props);
const newId = Wizard.currentId++;
this.titleId = `pf-wizard-title-${newId}`;
this.descriptionId = `pf-wizard-description-${newId}`;
this.isModal = !props.isInPage;

atiratree Sep 4, 2019
edited
Loading

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

user should not have an ability to change the inpage wizard to modal one after it is constructed

if (this.isModal) {
if (!props.title) {
console.warn('Title is required for modals!');
}
this.titleId = `pf-wizard-title-${newId}`;
this.descriptionId = `pf-wizard-description-${newId}`;
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

not sure if this is needed, but the titleId/descriptionId are not used when in-page


this.state = {
currentStep: this.props.startAtStep && Number.isInteger(this.props.startAtStep) ? this.props.startAtStep : 1,
isNavOpen: false
Expand Down Expand Up @@ -279,30 +291,37 @@ export class Wizard extends React.Component<WizardProps, WizardState> {
}

componentDidMount() {
if (this.container) {
document.body.appendChild(this.container);
if (this.isModal) {
if (this.container) {
document.body.appendChild(this.container);
}
this.toggleSiblingsFromScreenReaders(true);
document.addEventListener('keydown', this.handleKeyClicks, false);
}
this.toggleSiblingsFromScreenReaders(true);
document.addEventListener('keydown', this.handleKeyClicks, false);
}

componentWillUnmount() {
if (this.container) {
document.body.removeChild(this.container);
if (this.isModal) {
if (this.container) {
document.body.removeChild(this.container);
}
this.toggleSiblingsFromScreenReaders(false);
document.removeEventListener('keydown', this.handleKeyClicks, false);
}
this.toggleSiblingsFromScreenReaders(false);
document.removeEventListener('keydown', this.handleKeyClicks, false);
}

render() {
if (!canUseDOM) {
return null;
}
if (!this.container) {
this.container = document.createElement('div');
if (this.isModal) {
if (!canUseDOM) {
return null;
}
if (!this.container) {
this.container = document.createElement('div');
}
}
const {
isOpen,
isInPage,
isFullHeight,
isFullWidth,
width,
Expand Down Expand Up @@ -414,61 +433,77 @@ export class Wizard extends React.Component<WizardProps, WizardState> {
activeStep
};

return (
isOpen && ReactDOM.createPortal(
if (this.isModal && !isOpen) {
return null;
}

const wizard = (
<WizardContextProvider value={context}>
<div {...rest}
className={css(
styles.wizard,
!this.isModal && styles.modifiers.inPage,
isCompactNav && 'pf-m-compact-nav',
activeStep.isFinishedStep && 'pf-m-finished',
setFullWidth && styles.modifiers.fullWidth,
setFullHeight && styles.modifiers.fullHeight,
className)}
{
...(this.isModal && {
role: 'dialog',
'aria-modal': 'true',
'aria-labelledby': this.titleId,
'aria-describedby': description ? this.descriptionId : undefined
})
}
>
{
this.isModal && (
<WizardHeader
titleId={this.titleId}
descriptionId={this.descriptionId}
onClose={onClose}
title={title}
description={description}
ariaLabelCloseButton={ariaLabelCloseButton}
/>
)
}
<WizardToggle
isNavOpen={this.state.isNavOpen}
onNavToggle={(isNavOpen) => this.setState({ isNavOpen })}
nav={nav}
steps={steps}
activeStep={activeStep}
hasBodyPadding={hasBodyPadding}
>
{footer || (
<WizardFooterInternal
onNext={this.onNext}
onBack={this.onBack}
onClose={onClose}
isValid={isValid}
firstStep={firstStep}
activeStep={activeStep}
nextButtonText={activeStep.nextButtonText || nextButtonText}
backButtonText={backButtonText}
cancelButtonText={cancelButtonText}
/>
)}
</WizardToggle>
</div>
</WizardContextProvider>
);

return this.isModal ? ReactDOM.createPortal(
<FocusTrap focusTrapOptions={{ clickOutsideDeactivates: true }}>
<Backdrop>
<Bullseye>
<WizardContextProvider value={context}>
<div {...rest}
className={css(
styles.wizard,
isCompactNav && 'pf-m-compact-nav',
activeStep.isFinishedStep && 'pf-m-finished',
setFullWidth && styles.modifiers.fullWidth,
setFullHeight && styles.modifiers.fullHeight,
className)}
role="dialog"
aria-modal="true"
aria-labelledby={this.titleId}
aria-describedby={description ? this.descriptionId : undefined}
>
<WizardHeader
titleId={this.titleId}
descriptionId={this.descriptionId}
onClose={onClose}
title={title}
description={description}
ariaLabelCloseButton={ariaLabelCloseButton} />
<WizardToggle
isNavOpen={this.state.isNavOpen}
onNavToggle={(isNavOpen) => this.setState({ isNavOpen })}
nav={nav}
steps={steps}
activeStep={activeStep}
hasBodyPadding={hasBodyPadding}
>
{footer || (
<WizardFooterInternal
onNext={this.onNext}
onBack={this.onBack}
onClose={onClose}
isValid={isValid}
firstStep={firstStep}
activeStep={activeStep}
nextButtonText={activeStep.nextButtonText || nextButtonText}
backButtonText={backButtonText}
cancelButtonText={cancelButtonText}
/>
)}
</WizardToggle>
</div>
</WizardContextProvider>
{wizard}
</Bullseye>
</Backdrop>
</FocusTrap>,
this.container
)
);
) : wizard;
}
}
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const WizardHeader: React.FunctionComponent<WizardHeaderProps> = ({
<Button variant="plain" className={css(styles.wizardClose)} aria-label={ariaLabelCloseButton} onClick={onClose}>
<TimesIcon aria-hidden="true" />
</Button>
<Title size="3xl" className={css(styles.wizardTitle)} aria-label={title} id={titleId}>{title}</Title>
<Title size="3xl" className={css(styles.wizardTitle)} aria-label={title} id={titleId}>{title || <>&nbsp;</>}</Title>
{description && <p className={css(styles.wizardDescription)} id={descriptionId}>
{description}
</p>}
Expand Down

Back | FazBrowse Home | New Git URL