UNPKG

@carbon/ibm-cloud-cognitive-cdai

Version:
387 lines (382 loc) 15 kB
import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } // // Copyright IBM Corp. 2020, 2020 // // This source code is licensed under the Apache-2.0 license found in the // LICENSE file in the root directory of this source tree. // import React from 'react'; import { settings } from 'carbon-components'; import PropTypes from 'prop-types'; import { Button, Link, ProgressIndicator, ProgressStep } from 'carbon-components-react'; import { Launch24 } from '@carbon/icons-react'; import IdeCreateStep from './ide-create-step'; import { idePrefix } from '../../globals/js/settings'; var prefix = settings.prefix; /** * The Create pattern provides a standard container for creating objects. It handles the page heading * and buttons and can support a two-step or one-step flow. The two-step flow consists of a pre-check * selection page followed by a form entry page. The one-step flow is just the form entry page. */ var IdeCreate = /*#__PURE__*/function (_React$Component) { function IdeCreate(props) { var _this; _classCallCheck(this, IdeCreate); _this = _callSuper(this, IdeCreate, [props]); _this.containerRef = /*#__PURE__*/React.createRef(); _this.headerRef = /*#__PURE__*/React.createRef(); _this._handleBackButton = _this._handleBackButton.bind(_this); _this._handleNextButton = _this._handleNextButton.bind(_this); _this.state = { step: 0, actionDisabled: false, fixedHeader: false }; // add scroll handler to deal with sticky header _this.scrollHandler = function (event) { _this._handlePageScroll(event); }; window.addEventListener('scroll', _this.scrollHandler); return _this; } _inherits(IdeCreate, _React$Component); return _createClass(IdeCreate, [{ key: "componentWillUnmount", value: function componentWillUnmount() { window.removeEventListener('scroll', this.scrollHandler); } /** * Public function to control the disabled state on the primary action button on the page. */ }, { key: "setActionButtonDisabled", value: function setActionButtonDisabled(state) { this.setState({ actionDisabled: state }); } /** * Public function to move the flow onto the next page if using the pre-check flow. */ }, { key: "setNextPage", value: function setNextPage() { this._handleNextButton(); } }, { key: "_handleBackButton", value: function _handleBackButton() { var _this2 = this; var step = this.state.step - 1; this.setState({ step: step }, function () { return _this2.props.onStepChange(step); }); } }, { key: "_handleNextButton", value: function _handleNextButton() { var _this3 = this; if (!this.props.stepNextDisabled) { var step = this.state.step + 1; this.setState({ step: step }, function () { return _this3.props.onStepChange(step); }); } } }, { key: "changeStep", value: function changeStep(step) { var _this4 = this; this.setState({ step: step }, function () { return _this4.props.onStepChange(step); }); } }, { key: "_handlePageScroll", value: function _handlePageScroll() { var rect = this.containerRef.current.getBoundingClientRect(); if (rect.top < 0) { if (!this.state.fixedHeader && this.headerRef.current) { this.setState({ style: { paddingTop: "".concat(this.headerRef.current.clientHeight, "px") } }); } this.setState({ fixedHeader: true }); } else { this.setState({ style: undefined, fixedHeader: false }); } } }, { key: "_validateProps", value: function _validateProps() { if (this.props.usePreCheck && React.Children.count(this.props.children) > 0) { if (React.Children.toArray(this.props.children)[0].props.label) { throw new Error('Error: label should not be set on first step when usePreCheck is set'); } } } }, { key: "_onProgressChange", value: function _onProgressChange(index, stepsDisabled) { var _this5 = this; // We need to count +1 in case usePreCheck is set var actualStep = function actualStep(index) { return _this5.props.usePreCheck ? index + 1 : index; }; return stepsDisabled[actualStep(index)] ? undefined : this.changeStep(actualStep(index)); } }, { key: "render", value: function render() { var _this6 = this; this._validateProps(); var currentStep = this.state.step; var steps = React.Children.toArray(this.props.children).filter(function (c) { return c.type === IdeCreateStep; }); var stepLabels = steps.filter(function (child) { return child.props.label; }); var stepsDisabled = steps.map(function (child) { return child.props.disabled; }); // work out which buttons to show var button1 = null; if (currentStep > 0) { button1 = /*#__PURE__*/React.createElement(Button, { kind: "secondary", disabled: this.props.disableCancelButton, className: "".concat(idePrefix, "-create-cancel-btn"), onClick: this._handleBackButton }, this.props.buttonTextStepBack); } else if (this.props.buttonTextFormCancel) { button1 = /*#__PURE__*/React.createElement(Button, { kind: "secondary", disabled: this.props.disableCancelButton, className: "".concat(idePrefix, "-create-cancel-btn"), onClick: this.props.onCancel }, this.props.buttonTextFormCancel); } var button2 = null; if (currentStep < steps.length - 1) { if (this.props.buttonTextStepNext) { button2 = /*#__PURE__*/React.createElement(Button, { disabled: this.props.stepNextDisabled, onClick: this._handleNextButton, className: "".concat(idePrefix, "-create-next-btn") }, this.props.buttonTextStepNext); } } else { button2 = /*#__PURE__*/React.createElement(Button, { disabled: this.state.actionDisabled, onClick: this.props.onFormAction, className: "".concat(idePrefix, "-create-next-btn"), renderIcon: this.props.externalLink ? Launch24 : null }, this.props.buttonTextFormAction); } var buttonGroup = /*#__PURE__*/React.createElement(React.Fragment, null, button1, button2); var contentClassName = "".concat(idePrefix, "-create-content ").concat(prefix, "--grid ").concat(idePrefix, "--content-alignment"); var headerClassName = "".concat(idePrefix, "-create-header"); if (this.state.fixedHeader) { headerClassName += ' fixed'; } return /*#__PURE__*/React.createElement("div", { ref: this.containerRef, className: "".concat(idePrefix, "-create-container") }, /*#__PURE__*/React.createElement("div", { ref: this.headerRef, className: headerClassName }, /*#__PURE__*/React.createElement("div", { className: "".concat(prefix, "--grid ").concat(idePrefix, "--content-alignment") }, /*#__PURE__*/React.createElement("div", { className: "".concat(prefix, "--row ").concat(idePrefix, "-create-breadcrumb") }, this.props.breadCrumbUrl && /*#__PURE__*/React.createElement(Link, { className: "".concat(prefix, "--col"), href: this.props.breadCrumbUrl, onClick: function onClick(ev) { if (_this6.props.useCancelOnBreadCrumb && _this6.props.onCancel) { _this6.props.onCancel(ev); } } }, this.props.breadCrumbText), !this.props.breadCrumbUrl && this.props.breadCrumbCallback && /*#__PURE__*/React.createElement(Link, { className: "".concat(prefix, "--col"), href: "#", onClick: function onClick(ev) { ev.preventDefault(); _this6.props.breadCrumbCallback(ev); } }, this.props.breadCrumbText), !this.props.breadCrumbUrl && !this.props.breadCrumbCallback && /*#__PURE__*/React.createElement("p", { className: "".concat(prefix, "--col") }, this.props.breadCrumbText)), /*#__PURE__*/React.createElement("div", { className: "".concat(prefix, "--row") }, /*#__PURE__*/React.createElement("div", { className: "".concat(idePrefix, "-create-title ").concat(prefix, "--col") }, /*#__PURE__*/React.createElement("div", { className: "".concat(idePrefix, "-create-title-box") }, /*#__PURE__*/React.createElement("div", { className: "".concat(idePrefix, "-create-heading") }, /*#__PURE__*/React.createElement("h2", { className: "".concat(idePrefix, "-create-heading-heading") }, this.props.pageTitle)), this.props.subTitle && (!this.props.subTitleFixedOnly || this.state.fixedHeader) && /*#__PURE__*/React.createElement("div", { className: "".concat(idePrefix, "-create-form-subtitle") }, /*#__PURE__*/React.createElement("span", { className: "".concat(idePrefix, "-create-form-subtitle-content") }, this.props.subTitle))), /*#__PURE__*/React.createElement("div", { className: "".concat(idePrefix, "-create-buttons") }, /*#__PURE__*/React.createElement("div", { className: "".concat(idePrefix, "-create-button-box") }, buttonGroup)))))), /*#__PURE__*/React.createElement("div", { className: contentClassName, style: this.state.style }, /*#__PURE__*/React.createElement("div", { className: "".concat(prefix, "--grid ").concat(idePrefix, "-create-progress-container") }, stepLabels.length > 1 && (!this.props.usePreCheck || currentStep > 0) && /*#__PURE__*/React.createElement(ProgressIndicator, { currentIndex: this.props.usePreCheck ? currentStep - 1 : currentStep, className: "".concat(prefix, "--row progress-bar"), onChange: this.props.disableProgressOnChange ? undefined : function (index) { return _this6._onProgressChange(index, stepsDisabled); } }, stepLabels.map(function (child, i) { return /*#__PURE__*/React.createElement(ProgressStep, { label: child.props.label, key: i, disabled: child.props.disabled }); }))), steps[currentStep])); } }], [{ key: "getDerivedStateFromProps", value: function getDerivedStateFromProps(props, state) { if (typeof props.formActionDisabled === 'boolean' && props.formActionDisabled !== state.actionDisabled) { return { actionDisabled: props.formActionDisabled }; } return null; } }]); }(React.Component); /* eslint-disable react/sort-prop-types */ _defineProperty(IdeCreate, "propTypes", { /** * The primary page heading (required) */ pageTitle: PropTypes.string.isRequired, /** * The secondary page heading (shows under the primary heading). This can be any JSX fragment */ subTitle: PropTypes.node, /** * Only include the subtitle when in fixed mode */ subTitleFixedOnly: PropTypes.bool, /** * The text to go into the breadcrumb link */ breadCrumbText: PropTypes.string, /** * The URL to navigate to for the breadcrumb. If not specified, the link will be a simple text */ breadCrumbUrl: PropTypes.string, /** * A callback function to be used on breadcrumb instead of a full page navigation. !!! It only works if breadCrumbUrl is not defined to avoid consumer side confusion */ breadCrumbCallback: PropTypes.func, /** * Set this flag to call the onCancel function when using the breadcrumb */ useCancelOnBreadCrumb: PropTypes.bool, /** * Set this flag to put indicate the first step is a pre-check, so that the progress indicator is not * shown. The pre-check flow allows for an initial user selection page before seeing the main input * form for the create. For example, this could be a page where the user chooses a particular template * to base the create on. */ usePreCheck: PropTypes.bool, /** * The text for the form primary action (usually "Create") */ buttonTextFormAction: PropTypes.string, /** * The text for the form cancel action (usually "Cancel"). If not specified the button will be hidden */ buttonTextFormCancel: PropTypes.string, /** * The text for the primary button to move between steps (usually "Next"). Only needed when using * the pre-check flow. Can be left blank to hide the button. */ buttonTextStepNext: PropTypes.string, /** * The text for the secondary button to move back a step (usually "Back"). Only needed when using * the pre-check flow. */ buttonTextStepBack: PropTypes.string, /** * Function that will be called when the user navigates between the steps in the flow. */ onStepChange: PropTypes.func, /** * Function that will be called when the user clicks on the Cancel button */ onCancel: PropTypes.func, /** * Function that will be called when the user clicks on the form primary action button */ onFormAction: PropTypes.func, /** * Set this flag to disable the primary form action */ formActionDisabled: PropTypes.bool, /** * Set this flag to disable the secondary form action */ disableCancelButton: PropTypes.bool, /** * Set this flag to disable the next step action */ stepNextDisabled: PropTypes.bool, /* * Set this flag to true to get a launch out icon of the form action button */ externalLink: PropTypes.bool, /* * Set this flag to true to remove the onClick behaviour for the progress indicator */ disableProgressOnChange: PropTypes.bool, /** * Child components */ children: PropTypes.any }); _defineProperty(IdeCreate, "defaultProps", { onCancel: function onCancel() { return; }, onFormAction: function onFormAction() { return; }, onStepChange: function onStepChange() { return; } }); export default IdeCreate;