UNPKG

9.14 kBJavaScriptView Raw
1"use strict";
2/*
3 * Copyright 2015 Palantir Technologies, Inc. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17Object.defineProperty(exports, "__esModule", { value: true });
18exports.Collapse = exports.AnimationStates = void 0;
19var tslib_1 = require("tslib");
20var classnames_1 = tslib_1.__importDefault(require("classnames"));
21var React = tslib_1.__importStar(require("react"));
22var common_1 = require("../../common");
23var props_1 = require("../../common/props");
24/**
25 * `Collapse` can be in one of six states, enumerated here.
26 * When changing the `isOpen` prop, the following happens to the states:
27 * isOpen={true} : CLOSED -> OPEN_START -> OPENING -> OPEN
28 * isOpen={false} : OPEN -> CLOSING_START -> CLOSING -> CLOSED
29 */
30var AnimationStates;
31(function (AnimationStates) {
32 /**
33 * The body is re-rendered, height is set to the measured body height and
34 * the body Y is set to 0.
35 */
36 AnimationStates[AnimationStates["OPEN_START"] = 0] = "OPEN_START";
37 /**
38 * Animation begins, height is set to auto. This is all animated, and on
39 * complete, the state changes to OPEN.
40 */
41 AnimationStates[AnimationStates["OPENING"] = 1] = "OPENING";
42 /**
43 * The collapse height is set to auto, and the body Y is set to 0 (so the
44 * element can be seen as normal).
45 */
46 AnimationStates[AnimationStates["OPEN"] = 2] = "OPEN";
47 /**
48 * Height has been changed from auto to the measured height of the body to
49 * prepare for the closing animation in CLOSING.
50 */
51 AnimationStates[AnimationStates["CLOSING_START"] = 3] = "CLOSING_START";
52 /**
53 * Height is set to 0 and the body Y is at -height. Both of these properties
54 * are transformed, and then after the animation is complete, the state
55 * changes to CLOSED.
56 */
57 AnimationStates[AnimationStates["CLOSING"] = 4] = "CLOSING";
58 /**
59 * The contents of the collapse is not rendered, the collapse height is 0,
60 * and the body Y is at -height (so that the bottom of the body is at Y=0).
61 */
62 AnimationStates[AnimationStates["CLOSED"] = 5] = "CLOSED";
63})(AnimationStates = exports.AnimationStates || (exports.AnimationStates = {}));
64/**
65 * Collapse component.
66 *
67 * @see https://blueprintjs.com/docs/#core/components/collapse
68 */
69var Collapse = /** @class */ (function (_super) {
70 tslib_1.__extends(Collapse, _super);
71 function Collapse() {
72 var _this = _super !== null && _super.apply(this, arguments) || this;
73 _this.state = {
74 animationState: _this.props.isOpen ? AnimationStates.OPEN : AnimationStates.CLOSED,
75 height: undefined,
76 heightWhenOpen: undefined,
77 };
78 // The element containing the contents of the collapse.
79 _this.contents = null;
80 _this.contentsRefHandler = function (el) {
81 _this.contents = el;
82 if (_this.contents != null) {
83 var height = _this.contents.clientHeight;
84 _this.setState({
85 animationState: _this.props.isOpen ? AnimationStates.OPEN : AnimationStates.CLOSED,
86 height: height === 0 ? undefined : "".concat(height, "px"),
87 heightWhenOpen: height === 0 ? undefined : height,
88 });
89 }
90 };
91 return _this;
92 }
93 Collapse.getDerivedStateFromProps = function (props, state) {
94 var isOpen = props.isOpen;
95 var animationState = state.animationState;
96 if (isOpen) {
97 switch (animationState) {
98 case AnimationStates.OPEN:
99 // no-op
100 break;
101 case AnimationStates.OPENING:
102 // allow Collapse#onDelayedStateChange() to handle the transition here
103 break;
104 default:
105 return { animationState: AnimationStates.OPEN_START };
106 }
107 }
108 else {
109 switch (animationState) {
110 case AnimationStates.CLOSED:
111 // no-op
112 break;
113 case AnimationStates.CLOSING:
114 // allow Collapse#onDelayedStateChange() to handle the transition here
115 break;
116 default:
117 // need to set an explicit height so that transition can work
118 return {
119 animationState: AnimationStates.CLOSING_START,
120 height: "".concat(state.heightWhenOpen, "px"),
121 };
122 }
123 }
124 return null;
125 };
126 Collapse.prototype.render = function () {
127 var isContentVisible = this.state.animationState !== AnimationStates.CLOSED;
128 var shouldRenderChildren = isContentVisible || this.props.keepChildrenMounted;
129 var displayWithTransform = isContentVisible && this.state.animationState !== AnimationStates.CLOSING;
130 var isAutoHeight = this.state.height === "auto";
131 var containerStyle = {
132 height: isContentVisible ? this.state.height : undefined,
133 overflowY: isAutoHeight ? "visible" : undefined,
134 // transitions don't work with height: auto
135 transition: isAutoHeight ? "none" : undefined,
136 };
137 var contentsStyle = {
138 // only use heightWhenOpen while closing
139 transform: displayWithTransform ? "translateY(0)" : "translateY(-".concat(this.state.heightWhenOpen, "px)"),
140 // transitions don't work with height: auto
141 transition: isAutoHeight ? "none" : undefined,
142 };
143 return React.createElement(this.props.component, {
144 className: (0, classnames_1.default)(common_1.Classes.COLLAPSE, this.props.className),
145 style: containerStyle,
146 }, React.createElement("div", { className: common_1.Classes.COLLAPSE_BODY, ref: this.contentsRefHandler, style: contentsStyle, "aria-hidden": !isContentVisible && this.props.keepChildrenMounted }, shouldRenderChildren ? this.props.children : null));
147 };
148 Collapse.prototype.componentDidMount = function () {
149 this.forceUpdate();
150 // HACKHACK: this should probably be done in getSnapshotBeforeUpdate
151 /* eslint-disable react/no-did-mount-set-state */
152 if (this.props.isOpen) {
153 this.setState({ animationState: AnimationStates.OPEN, height: "auto" });
154 }
155 else {
156 this.setState({ animationState: AnimationStates.CLOSED, height: "0px" });
157 }
158 /* eslint-disable react/no-did-mount-set-state */
159 };
160 Collapse.prototype.componentDidUpdate = function () {
161 var _this = this;
162 if (this.contents == null) {
163 return;
164 }
165 var transitionDuration = this.props.transitionDuration;
166 var animationState = this.state.animationState;
167 if (animationState === AnimationStates.OPEN_START) {
168 var clientHeight = this.contents.clientHeight;
169 this.setState({
170 animationState: AnimationStates.OPENING,
171 height: "".concat(clientHeight, "px"),
172 heightWhenOpen: clientHeight,
173 });
174 this.setTimeout(function () { return _this.onDelayedStateChange(); }, transitionDuration);
175 }
176 else if (animationState === AnimationStates.CLOSING_START) {
177 var clientHeight_1 = this.contents.clientHeight;
178 this.setTimeout(function () {
179 return _this.setState({
180 animationState: AnimationStates.CLOSING,
181 height: "0px",
182 heightWhenOpen: clientHeight_1,
183 });
184 });
185 this.setTimeout(function () { return _this.onDelayedStateChange(); }, transitionDuration);
186 }
187 };
188 Collapse.prototype.onDelayedStateChange = function () {
189 switch (this.state.animationState) {
190 case AnimationStates.OPENING:
191 this.setState({ animationState: AnimationStates.OPEN, height: "auto" });
192 break;
193 case AnimationStates.CLOSING:
194 this.setState({ animationState: AnimationStates.CLOSED });
195 break;
196 default:
197 break;
198 }
199 };
200 Collapse.displayName = "".concat(props_1.DISPLAYNAME_PREFIX, ".Collapse");
201 Collapse.defaultProps = {
202 component: "div",
203 isOpen: false,
204 keepChildrenMounted: false,
205 transitionDuration: 200,
206 };
207 return Collapse;
208}(common_1.AbstractPureComponent2));
209exports.Collapse = Collapse;
210//# sourceMappingURL=collapse.js.map
\No newline at end of file