UNPKG

@blueprintjs/core

Version:

Core styles & components

208 lines 8.98 kB
"use strict"; /* * Copyright 2015 Palantir Technologies, Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Collapse = exports.AnimationStates = void 0; var tslib_1 = require("tslib"); var classnames_1 = tslib_1.__importDefault(require("classnames")); var React = tslib_1.__importStar(require("react")); var common_1 = require("../../common"); var props_1 = require("../../common/props"); /** * `Collapse` can be in one of six states, enumerated here. * When changing the `isOpen` prop, the following happens to the states: * isOpen={true} : CLOSED -> OPEN_START -> OPENING -> OPEN * isOpen={false} : OPEN -> CLOSING_START -> CLOSING -> CLOSED */ var AnimationStates; (function (AnimationStates) { /** * The body is re-rendered, height is set to the measured body height and * the body Y is set to 0. */ AnimationStates[AnimationStates["OPEN_START"] = 0] = "OPEN_START"; /** * Animation begins, height is set to auto. This is all animated, and on * complete, the state changes to OPEN. */ AnimationStates[AnimationStates["OPENING"] = 1] = "OPENING"; /** * The collapse height is set to auto, and the body Y is set to 0 (so the * element can be seen as normal). */ AnimationStates[AnimationStates["OPEN"] = 2] = "OPEN"; /** * Height has been changed from auto to the measured height of the body to * prepare for the closing animation in CLOSING. */ AnimationStates[AnimationStates["CLOSING_START"] = 3] = "CLOSING_START"; /** * Height is set to 0 and the body Y is at -height. Both of these properties * are transformed, and then after the animation is complete, the state * changes to CLOSED. */ AnimationStates[AnimationStates["CLOSING"] = 4] = "CLOSING"; /** * The contents of the collapse is not rendered, the collapse height is 0, * and the body Y is at -height (so that the bottom of the body is at Y=0). */ AnimationStates[AnimationStates["CLOSED"] = 5] = "CLOSED"; })(AnimationStates || (exports.AnimationStates = AnimationStates = {})); /** * Collapse component. * * @see https://blueprintjs.com/docs/#core/components/collapse */ var Collapse = /** @class */ (function (_super) { tslib_1.__extends(Collapse, _super); function Collapse() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.state = { animationState: _this.props.isOpen ? AnimationStates.OPEN : AnimationStates.CLOSED, height: undefined, heightWhenOpen: undefined, }; // The element containing the contents of the collapse. _this.contents = null; _this.contentsRefHandler = function (el) { _this.contents = el; if (_this.contents != null) { var height = _this.contents.clientHeight; _this.setState({ animationState: _this.props.isOpen ? AnimationStates.OPEN : AnimationStates.CLOSED, height: height === 0 ? undefined : "".concat(height, "px"), heightWhenOpen: height === 0 ? undefined : height, }); } }; return _this; } Collapse.getDerivedStateFromProps = function (props, state) { var isOpen = props.isOpen; var animationState = state.animationState; if (isOpen) { switch (animationState) { case AnimationStates.OPEN: // no-op break; case AnimationStates.OPENING: // allow Collapse#onDelayedStateChange() to handle the transition here break; default: return { animationState: AnimationStates.OPEN_START }; } } else { switch (animationState) { case AnimationStates.CLOSED: // no-op break; case AnimationStates.CLOSING: // allow Collapse#onDelayedStateChange() to handle the transition here break; default: // need to set an explicit height so that transition can work return { animationState: AnimationStates.CLOSING_START, height: "".concat(state.heightWhenOpen, "px"), }; } } return null; }; Collapse.prototype.render = function () { var isContentVisible = this.state.animationState !== AnimationStates.CLOSED; var shouldRenderChildren = isContentVisible || this.props.keepChildrenMounted; var displayWithTransform = isContentVisible && this.state.animationState !== AnimationStates.CLOSING; var isAutoHeight = this.state.height === "auto"; var containerStyle = { height: isContentVisible ? this.state.height : undefined, overflowY: isAutoHeight ? "visible" : undefined, // transitions don't work with height: auto transition: isAutoHeight ? "none" : undefined, }; var contentsStyle = { // only use heightWhenOpen while closing transform: displayWithTransform ? "translateY(0)" : "translateY(-".concat(this.state.heightWhenOpen, "px)"), // transitions don't work with height: auto transition: isAutoHeight ? "none" : undefined, }; return React.createElement(this.props.component, { className: (0, classnames_1.default)(common_1.Classes.COLLAPSE, this.props.className), style: containerStyle, }, React.createElement("div", { className: common_1.Classes.COLLAPSE_BODY, ref: this.contentsRefHandler, style: contentsStyle, "aria-hidden": !isContentVisible }, shouldRenderChildren ? this.props.children : null)); }; Collapse.prototype.componentDidMount = function () { this.forceUpdate(); // HACKHACK: this should probably be done in getSnapshotBeforeUpdate if (this.props.isOpen) { this.setState({ animationState: AnimationStates.OPEN, height: "auto" }); } else { this.setState({ animationState: AnimationStates.CLOSED, height: "0px" }); } }; Collapse.prototype.componentDidUpdate = function () { var _this = this; if (this.contents == null) { return; } var transitionDuration = this.props.transitionDuration; var animationState = this.state.animationState; if (animationState === AnimationStates.OPEN_START) { var clientHeight = this.contents.clientHeight; this.setState({ animationState: AnimationStates.OPENING, height: "".concat(clientHeight, "px"), heightWhenOpen: clientHeight, }); this.setTimeout(function () { return _this.onDelayedStateChange(); }, transitionDuration); } else if (animationState === AnimationStates.CLOSING_START) { var clientHeight_1 = this.contents.clientHeight; this.setTimeout(function () { return _this.setState({ animationState: AnimationStates.CLOSING, height: "0px", heightWhenOpen: clientHeight_1, }); }); this.setTimeout(function () { return _this.onDelayedStateChange(); }, transitionDuration); } }; Collapse.prototype.onDelayedStateChange = function () { switch (this.state.animationState) { case AnimationStates.OPENING: this.setState({ animationState: AnimationStates.OPEN, height: "auto" }); break; case AnimationStates.CLOSING: this.setState({ animationState: AnimationStates.CLOSED }); break; default: break; } }; Collapse.displayName = "".concat(props_1.DISPLAYNAME_PREFIX, ".Collapse"); Collapse.defaultProps = { component: "div", isOpen: false, keepChildrenMounted: false, transitionDuration: 200, }; return Collapse; }(common_1.AbstractPureComponent)); exports.Collapse = Collapse; //# sourceMappingURL=collapse.js.map