@patternfly/react-core
Version:
This library provides a set of common React components for use with the PatternFly reference implementation.
317 lines • 16.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Wizard = void 0;
const tslib_1 = require("tslib");
const react_1 = require("react");
const jsx_runtime_1 = require("react/jsx-runtime");
const react_2 = require("react");
const constants_1 = require("../../../helpers/constants");
const react_styles_1 = require("@patternfly/react-styles");
const wizard_1 = tslib_1.__importDefault(require("@patternfly/react-styles/css/components/Wizard/wizard"));
const Modal_1 = require("../Modal");
const WizardFooterInternal_1 = require("./WizardFooterInternal");
const WizardToggle_1 = require("./WizardToggle");
const WizardNav_1 = require("./WizardNav");
const WizardNavItem_1 = require("./WizardNavItem");
const WizardContext_1 = require("./WizardContext");
const WizardHeader_1 = require("./WizardHeader");
class Wizard extends react_2.Component {
constructor(props) {
super(props);
this.handleKeyClicks = (event) => {
if (event.key === constants_1.KeyTypes.Escape) {
if (this.state.isNavOpen) {
this.setState({ isNavOpen: !this.state.isNavOpen });
}
else if (this.props.isOpen) {
this.props.onClose();
}
}
};
this.onNext = () => {
const { onNext, onClose, onSave } = this.props;
const { currentStep } = this.state;
const flattenedSteps = this.getFlattenedSteps();
const maxSteps = flattenedSteps.length;
if (currentStep >= maxSteps) {
// Hit the save button at the end of the wizard
if (onSave) {
return onSave();
}
return onClose();
}
else {
let newStep = currentStep;
for (let nextStep = currentStep; nextStep <= maxSteps; nextStep++) {
if (!flattenedSteps[nextStep]) {
return;
}
if (!flattenedSteps[nextStep].isDisabled) {
newStep = nextStep + 1;
break;
}
}
this.setCurrentStep(newStep, flattenedSteps[newStep - 1]);
const { id: prevId, name: prevName } = flattenedSteps[currentStep - 1];
const { id, name } = flattenedSteps[newStep - 1];
return onNext && onNext({ id, name }, { prevId, prevName });
}
};
this.onBack = () => {
const { onBack } = this.props;
const { currentStep } = this.state;
const flattenedSteps = this.getFlattenedSteps();
if (flattenedSteps.length < currentStep) {
// Previous step was removed, just update the currentStep state
const adjustedStep = flattenedSteps.length;
this.setCurrentStep(adjustedStep, flattenedSteps[adjustedStep - 1]);
}
else {
let newStep = currentStep;
for (let prevStep = currentStep; prevStep >= 0; prevStep--) {
if (!flattenedSteps[prevStep - 2]) {
return;
}
if (!flattenedSteps[prevStep - 2].isDisabled) {
newStep = prevStep - 1 <= 1 ? 1 : prevStep - 1;
break;
}
}
this.setCurrentStep(newStep, flattenedSteps[newStep - 1]);
const { id: prevId, name: prevName } = flattenedSteps[newStep];
const { id, name } = flattenedSteps[newStep - 1];
return onBack && onBack({ id, name }, { prevId, prevName });
}
};
this.goToStep = (step) => {
const flattenedSteps = this.getFlattenedSteps();
if (flattenedSteps[step - 1].isDisabled) {
return;
}
const { onGoToStep } = this.props;
const { currentStep } = this.state;
const maxSteps = flattenedSteps.length;
if (step < 1) {
step = 1;
}
else if (step > maxSteps) {
step = maxSteps;
}
this.setCurrentStep(step, flattenedSteps[step - 1]);
this.setState({ isNavOpen: false });
const { id: prevId, name: prevName } = flattenedSteps[currentStep - 1];
const { id, name } = flattenedSteps[step - 1];
return onGoToStep && onGoToStep({ id, name }, { prevId, prevName });
};
this.goToStepById = (stepId) => {
const flattenedSteps = this.getFlattenedSteps();
let step;
for (let i = 0; i < flattenedSteps.length; i++) {
if (flattenedSteps[i].id === stepId) {
step = i + 1;
break;
}
}
if (step) {
this.setCurrentStep(step, flattenedSteps[step - 1]);
}
};
this.goToStepByName = (stepName) => {
const flattenedSteps = this.getFlattenedSteps();
let step;
for (let i = 0; i < flattenedSteps.length; i++) {
if (flattenedSteps[i].name === stepName) {
step = i + 1;
break;
}
}
if (step) {
this.setCurrentStep(step, flattenedSteps[step - 1]);
}
};
this.getFlattenedSteps = () => {
const { steps } = this.props;
const flattenedSteps = [];
for (const step of steps) {
if (step.steps) {
for (const childStep of step.steps) {
flattenedSteps.push(childStep);
}
}
else {
flattenedSteps.push(step);
}
}
return flattenedSteps;
};
this.getFlattenedStepsIndex = (flattenedSteps, stepName) => {
for (let i = 0; i < flattenedSteps.length; i++) {
if (flattenedSteps[i].name === stepName) {
return i + 1;
}
}
return 0;
};
this.initSteps = (steps) => {
// Set default Step values
for (let i = 0; i < steps.length; i++) {
if (steps[i].steps) {
for (let j = 0; j < steps[i].steps.length; j++) {
steps[i].steps[j] = Object.assign({ canJumpTo: true }, steps[i].steps[j]);
}
}
steps[i] = Object.assign({ canJumpTo: true }, steps[i]);
}
return steps;
};
this.getElement = (appendTo) => {
if (typeof appendTo === 'function') {
return appendTo();
}
return appendTo || document.body;
};
const newId = Wizard.currentId++;
this.titleId = props.titleId || `pf-wizard-title-${newId}`;
this.descriptionId = props.descriptionId || `pf-wizard-description-${newId}`;
this.state = {
currentStep: this.props.startAtStep && Number.isInteger(this.props.startAtStep) ? this.props.startAtStep : 1,
isNavOpen: false
};
if (props.onCurrentStepChanged) {
const flattenedSteps = this.getFlattenedSteps();
if (flattenedSteps.length >= this.state.currentStep) {
const currentStep = flattenedSteps[this.state.currentStep - 1];
props.onCurrentStepChanged(currentStep);
}
}
this.drawerRef = (0, react_2.createRef)();
}
setCurrentStep(currentStep, currentStepObject) {
this.setState({
currentStep
});
if (this.props.onCurrentStepChanged) {
this.props.onCurrentStepChanged(currentStepObject);
}
}
componentDidMount() {
const target = typeof document !== 'undefined' ? document.body : null;
if (target) {
target.addEventListener('keydown', this.handleKeyClicks, false);
}
}
componentWillUnmount() {
const target = (typeof document !== 'undefined' && document.body) || null;
if (target) {
target.removeEventListener('keydown', this.handleKeyClicks, false);
}
}
componentDidUpdate(prevProps) {
if (prevProps.startAtStep !== this.props.startAtStep) {
this.setState({ currentStep: this.props.startAtStep });
}
}
render() {
const _a = this.props, {
/* eslint-disable @typescript-eslint/no-unused-vars */
width, height, title, description, descriptionComponent, onClose, onSave, onBack, onNext, onGoToStep, className, steps, startAtStep, nextButtonText = 'Next', backButtonText = 'Back', cancelButtonText = 'Cancel', hideClose, closeButtonAriaLabel = 'Close', navAriaLabel, navAriaLabelledBy, mainAriaLabel, mainAriaLabelledBy, hasNoBodyPadding, footer, appendTo, isOpen, titleId, descriptionId, isNavExpandable, onCurrentStepChanged, hasDrawer, isDrawerExpanded, onExpandDrawer } = _a, rest = tslib_1.__rest(_a, ["width", "height", "title", "description", "descriptionComponent", "onClose", "onSave", "onBack", "onNext", "onGoToStep", "className", "steps", "startAtStep", "nextButtonText", "backButtonText", "cancelButtonText", "hideClose", "closeButtonAriaLabel", "navAriaLabel", "navAriaLabelledBy", "mainAriaLabel", "mainAriaLabelledBy", "hasNoBodyPadding", "footer", "appendTo", "isOpen", "titleId", "descriptionId", "isNavExpandable", "onCurrentStepChanged", "hasDrawer", "isDrawerExpanded", "onExpandDrawer"])
/* eslint-enable @typescript-eslint/no-unused-vars */
;
const { currentStep } = this.state;
const flattenedSteps = this.getFlattenedSteps();
const adjustedStep = flattenedSteps.length < currentStep ? flattenedSteps.length : currentStep;
const activeStep = flattenedSteps[adjustedStep - 1];
const computedSteps = this.initSteps(steps);
const firstStep = activeStep === flattenedSteps[0];
const isValid = activeStep && activeStep.enableNext !== undefined ? activeStep.enableNext : true;
const nav = (isWizardNavOpen) => {
const wizNavAProps = {
isOpen: isWizardNavOpen,
'aria-label': navAriaLabel,
'aria-labelledby': (title || navAriaLabelledBy) && (navAriaLabelledBy || this.titleId)
};
return ((0, jsx_runtime_1.jsx)(WizardNav_1.WizardNav, Object.assign({}, wizNavAProps, { children: computedSteps.map((step, index) => {
if (step.isFinishedStep) {
// Don't show finished step in the side nav
return;
}
let enabled;
let navItemStep;
if (step.steps) {
let hasActiveChild = false;
let canJumpToParent = false;
for (const subStep of step.steps) {
if (activeStep.name === subStep.name) {
// one of the children matches
hasActiveChild = true;
}
if (subStep.canJumpTo) {
canJumpToParent = true;
}
}
navItemStep = this.getFlattenedStepsIndex(flattenedSteps, step.steps[0].name);
return ((0, jsx_runtime_1.jsx)(WizardNavItem_1.WizardNavItem, { id: step.id, content: step.name, isExpandable: isNavExpandable, isCurrent: hasActiveChild, isDisabled: !canJumpToParent, step: navItemStep, onNavItemClick: this.goToStep, children: (0, jsx_runtime_1.jsx)(WizardNav_1.WizardNav, Object.assign({}, wizNavAProps, { returnList: true, children: step.steps.map((childStep, indexChild) => {
if (childStep.isFinishedStep) {
// Don't show finished step in the side nav
return;
}
navItemStep = this.getFlattenedStepsIndex(flattenedSteps, childStep.name);
enabled = childStep.canJumpTo && !childStep.isDisabled;
return ((0, jsx_runtime_1.jsx)(WizardNavItem_1.WizardNavItem, { id: childStep.id, content: childStep.name, isCurrent: activeStep.name === childStep.name, isDisabled: !enabled, step: navItemStep, onNavItemClick: this.goToStep }, `child_${indexChild}`));
}) })) }, index));
}
navItemStep = this.getFlattenedStepsIndex(flattenedSteps, step.name);
enabled = step.canJumpTo && !step.isDisabled;
return ((0, react_1.createElement)(WizardNavItem_1.WizardNavItem, Object.assign({}, step.stepNavItemProps, { key: index, id: step.id, content: step.name, isCurrent: activeStep.name === step.name, isDisabled: !enabled, step: navItemStep, onNavItemClick: this.goToStep })));
}) })));
};
const context = {
goToStepById: this.goToStepById,
goToStepByName: this.goToStepByName,
onNext: this.onNext,
onBack: this.onBack,
onClose,
activeStep
};
const divStyles = Object.assign(Object.assign({}, (height ? { height } : {})), (width ? { width } : {}));
const wizard = ((0, jsx_runtime_1.jsx)(WizardContext_1.WizardContextProvider, { value: context, children: (0, jsx_runtime_1.jsxs)("div", Object.assign({}, rest, { className: (0, react_styles_1.css)(wizard_1.default.wizard, activeStep && activeStep.isFinishedStep && 'pf-m-finished', className), style: Object.keys(divStyles).length ? divStyles : undefined, children: [title && ((0, jsx_runtime_1.jsx)(WizardHeader_1.WizardHeader, { titleId: this.titleId, descriptionId: this.descriptionId, onClose: onClose, title: title, description: description, descriptionComponent: descriptionComponent, closeButtonAriaLabel: closeButtonAriaLabel, hideClose: hideClose })), (0, jsx_runtime_1.jsx)(WizardToggle_1.WizardToggle, { hasDrawer: hasDrawer, isDrawerExpanded: isDrawerExpanded, onExpandDrawer: onExpandDrawer, mainAriaLabel: mainAriaLabel, isInPage: isOpen === undefined, mainAriaLabelledBy: (title || mainAriaLabelledBy) && (mainAriaLabelledBy || this.titleId), isNavOpen: this.state.isNavOpen, onNavToggle: (isNavOpen) => this.setState({ isNavOpen }), nav: nav, steps: steps, activeStep: activeStep, hasNoBodyPadding: hasNoBodyPadding, children: footer || ((0, jsx_runtime_1.jsx)(WizardFooterInternal_1.WizardFooterInternal, { onNext: this.onNext, onBack: this.onBack, onClose: onClose, isValid: isValid, firstStep: firstStep, activeStep: activeStep, nextButtonText: (activeStep && activeStep.nextButtonText) || nextButtonText, backButtonText: backButtonText, cancelButtonText: cancelButtonText })) })] })) }));
if (isOpen !== undefined) {
return ((0, jsx_runtime_1.jsx)(Modal_1.Modal, { width: width !== null ? width : undefined, isOpen: isOpen, variant: Modal_1.ModalVariant.large, "aria-labelledby": this.titleId, "aria-describedby": this.descriptionId, showClose: false, hasNoBodyWrapper: true, children: wizard }));
}
return wizard;
}
}
exports.Wizard = Wizard;
Wizard.displayName = 'Wizard';
Wizard.currentId = 0;
Wizard.defaultProps = {
title: null,
description: '',
descriptionComponent: 'p',
className: '',
startAtStep: 1,
nextButtonText: 'Next',
backButtonText: 'Back',
cancelButtonText: 'Cancel',
hideClose: false,
closeButtonAriaLabel: 'Close',
navAriaLabel: null,
navAriaLabelledBy: null,
mainAriaLabel: null,
mainAriaLabelledBy: null,
hasNoBodyPadding: false,
onBack: null,
onNext: null,
onGoToStep: null,
width: null,
height: null,
footer: null,
onClose: () => undefined,
appendTo: null,
isOpen: undefined,
isNavExpandable: false,
hasDrawer: false,
isDrawerExpanded: false,
onExpandDrawer: () => undefined
};
//# sourceMappingURL=Wizard.js.map