UNPKG

11.4 kBJavaScriptView Raw
1var __extends = (this && this.__extends) || (function () {
2 var extendStatics = Object.setPrototypeOf ||
3 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
4 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
5 return function (d, b) {
6 extendStatics(d, b);
7 function __() { this.constructor = d; }
8 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
9 };
10})();
11import { ContentChildren, Directive, ElementRef, EventEmitter, Input, NgZone, Output, Renderer, forwardRef } from '@angular/core';
12import { Ion } from '../ion';
13import { isTrueProperty } from '../../util/util';
14import { Config } from '../../config/config';
15import { Platform } from '../../platform/platform';
16var QUERY = {
17 xs: '(min-width: 0px)',
18 sm: '(min-width: 576px)',
19 md: '(min-width: 768px)',
20 lg: '(min-width: 992px)',
21 xl: '(min-width: 1200px)',
22 never: ''
23};
24/**
25 * @hidden
26 */
27var RootNode = (function () {
28 function RootNode() {
29 }
30 return RootNode;
31}());
32export { RootNode };
33/**
34 * @name SplitPane
35 *
36 * @description
37 * SplitPane is a component that makes it possible to create multi-view layout.
38 * Similar to iPad apps, SplitPane allows UI elements, like Menus, to be
39 * displayed as the viewport increases.
40 *
41 * If the devices screen size is below a certain size, the SplitPane will
42 * collapse and the menu will become hidden again. This is especially useful when
43 * creating an app that will be served over a browser or deployed through the app
44 * store to phones and tablets.
45 *
46 * @usage
47 * To use SplitPane, simply add the component around your root component.
48 * In this example, we'll be using a sidemenu layout, similar to what is
49 * provided from the sidemenu starter template.
50 *
51 * ```html
52 * <ion-split-pane>
53 * <!-- our side menu -->
54 * <ion-menu [content]="content">
55 * <ion-header>
56 * <ion-toolbar>
57 * <ion-title>Menu</ion-title>
58 * </ion-toolbar>
59 * </ion-header>
60 * </ion-menu>
61 *
62 * <!-- the main content -->
63 * <ion-nav [root]="root" main #content></ion-nav>
64 * </ion-split-pane>
65 * ```
66 *
67 * Here, SplitPane will look for the element with the `main` attribute and make
68 * that the central component on larger screens. The `main` component can be any
69 * Ionic component (`ion-nav` or `ion-tabs`) except `ion-menu`.
70 *
71 * ### Setting breakpoints
72 *
73 * By default, SplitPane will expand when the screen is larger than 768px.
74 * If you want to customize this, use the `when` input. The `when` input can
75 * accept any valid media query, as it uses `matchMedia()` underneath.
76 *
77 * ```
78 * <ion-split-pane when="(min-width: 475px)">
79 *
80 * <!-- our side menu -->
81 * <ion-menu [content]="content">
82 * ....
83 * </ion-menu>
84 *
85 * <!-- the main content -->
86 * <ion-nav [root]="root" main #content></ion-nav>
87 * </ion-split-pane>
88 * ```
89 *
90 * SplitPane also provides some predefined media queries that can be used.
91 *
92 * ```html
93 * <!-- could be "xs", "sm", "md", "lg", or "xl" -->
94 * <ion-split-pane when="lg">
95 * ...
96 * </ion-split-pane>
97 * ```
98 *
99 *
100 * | Size | Value | Description |
101 * |------|-----------------------|-----------------------------------------------------------------------|
102 * | `xs` | `(min-width: 0px)` | Show the split-pane when the min-width is 0px (meaning, always) |
103 * | `sm` | `(min-width: 576px)` | Show the split-pane when the min-width is 576px |
104 * | `md` | `(min-width: 768px)` | Show the split-pane when the min-width is 768px (default break point) |
105 * | `lg` | `(min-width: 992px)` | Show the split-pane when the min-width is 992px |
106 * | `xl` | `(min-width: 1200px)` | Show the split-pane when the min-width is 1200px |
107 *
108 * You can also pass in boolean values that will trigger SplitPane when the value
109 * or expression evaluates to true.
110 *
111 *
112 * ```html
113 * <ion-split-pane [when]="isLarge">
114 * ...
115 * </ion-split-pane>
116 * ```
117 *
118 * ```ts
119 * class MyClass {
120 * public isLarge = false;
121 * constructor(){}
122 * }
123 * ```
124 *
125 * Or
126 *
127 * ```html
128 * <ion-split-pane [when]="shouldShow()">
129 * ...
130 * </ion-split-pane>
131 * ```
132 *
133 * ```ts
134 * class MyClass {
135 * constructor(){}
136 * shouldShow(){
137 * if(conditionA){
138 * return true
139 * } else {
140 * return false
141 * }
142 * }
143 * }
144 * ```
145 *
146 */
147var SplitPane = (function (_super) {
148 __extends(SplitPane, _super);
149 function SplitPane(_zone, _plt, config, elementRef, renderer) {
150 var _this = _super.call(this, config, elementRef, renderer, 'split-pane') || this;
151 _this._zone = _zone;
152 _this._plt = _plt;
153 _this._init = false;
154 _this._visible = false;
155 _this._isEnabled = true;
156 _this._mediaQuery = QUERY['md'];
157 /**
158 * @hidden
159 */
160 _this.sideContent = null;
161 /**
162 * @hidden
163 */
164 _this.mainContent = null;
165 /**
166 * @output {any} Expression to be called when the split-pane visibility has changed
167 */
168 _this.ionChange = new EventEmitter();
169 return _this;
170 }
171 Object.defineProperty(SplitPane.prototype, "_setchildren", {
172 /**
173 * @hidden
174 */
175 set: function (query) {
176 var _this = this;
177 var children = this._children = query.filter((function (child) { return child !== _this; }));
178 children.forEach(function (child) {
179 var isMain = child.initPane();
180 _this._setPaneCSSClass(child.getElementRef(), isMain);
181 });
182 },
183 enumerable: true,
184 configurable: true
185 });
186 Object.defineProperty(SplitPane.prototype, "when", {
187 get: function () {
188 return this._mediaQuery;
189 },
190 /**
191 * @input {string | boolean} When the split-pane should be shown.
192 * Can be a CSS media query expression, or a shortcut expression.
193 * Can also be a boolean expression.
194 */
195 set: function (query) {
196 if (typeof query === 'boolean') {
197 this._mediaQuery = query;
198 }
199 else {
200 var defaultQuery = QUERY[query];
201 this._mediaQuery = (defaultQuery)
202 ? defaultQuery
203 : query;
204 }
205 this._update();
206 },
207 enumerable: true,
208 configurable: true
209 });
210 Object.defineProperty(SplitPane.prototype, "enabled", {
211 get: function () {
212 return this._isEnabled;
213 },
214 /**
215 * @input {boolean} If `false`, the split-pane is disabled, ie. the side pane will
216 * never be displayed. Default `true`.
217 */
218 set: function (val) {
219 this._isEnabled = isTrueProperty(val);
220 this._update();
221 },
222 enumerable: true,
223 configurable: true
224 });
225 /**
226 * @hidden
227 */
228 SplitPane.prototype._register = function (node, isMain, callback) {
229 if (this.getElementRef().nativeElement !== node.getElementRef().nativeElement.parentNode) {
230 return false;
231 }
232 this._setPaneCSSClass(node.getElementRef(), isMain);
233 if (callback) {
234 this.ionChange.subscribe(callback);
235 }
236 if (isMain) {
237 if (this.mainContent) {
238 console.error('split pane: main content was already set');
239 }
240 this.mainContent = node;
241 }
242 return true;
243 };
244 /**
245 * @hidden
246 */
247 SplitPane.prototype.ngAfterViewInit = function () {
248 this._init = true;
249 this._update();
250 };
251 /**
252 * @hidden
253 */
254 SplitPane.prototype._update = function () {
255 var _this = this;
256 if (!this._init) {
257 return;
258 }
259 // Unlisten
260 this._rmListener && this._rmListener();
261 this._rmListener = null;
262 // Check if the split-pane is disabled
263 if (!this._isEnabled) {
264 this._setVisible(false);
265 return;
266 }
267 var query = this._mediaQuery;
268 if (typeof query === 'boolean') {
269 this._setVisible(query);
270 return;
271 }
272 if (query && query.length > 0) {
273 // Listen
274 var callback_1 = function (query) { return _this._setVisible(query.matches); };
275 var mediaList_1 = this._plt.win().matchMedia(query);
276 mediaList_1.addListener(callback_1);
277 this._setVisible(mediaList_1.matches);
278 this._rmListener = function () {
279 mediaList_1.removeListener(callback_1);
280 };
281 }
282 else {
283 this._setVisible(false);
284 }
285 };
286 /**
287 * @hidden
288 */
289 SplitPane.prototype._updateChildren = function () {
290 this.mainContent = null;
291 this.sideContent = null;
292 var visible = this._visible;
293 this._children.forEach(function (child) { return child.paneChanged && child.paneChanged(visible); });
294 };
295 /**
296 * @hidden
297 */
298 SplitPane.prototype._setVisible = function (visible) {
299 var _this = this;
300 if (this._visible === visible) {
301 return;
302 }
303 this._visible = visible;
304 this.setElementClass('split-pane-visible', visible);
305 this._updateChildren();
306 this._zone.run(function () {
307 _this.ionChange.emit(_this);
308 });
309 };
310 /**
311 * @hidden
312 */
313 SplitPane.prototype.isVisible = function () {
314 return this._visible;
315 };
316 /**
317 * @hidden
318 */
319 SplitPane.prototype.setElementClass = function (className, add) {
320 this._renderer.setElementClass(this._elementRef.nativeElement, className, add);
321 };
322 /**
323 * @hidden
324 */
325 SplitPane.prototype._setPaneCSSClass = function (elementRef, isMain) {
326 var ele = elementRef.nativeElement;
327 this._renderer.setElementClass(ele, 'split-pane-main', isMain);
328 this._renderer.setElementClass(ele, 'split-pane-side', !isMain);
329 };
330 /**
331 * @hidden
332 */
333 SplitPane.prototype.ngOnDestroy = function () {
334 (void 0) /* assert */;
335 this._rmListener && this._rmListener();
336 this._rmListener = null;
337 };
338 /**
339 * @hidden
340 */
341 SplitPane.prototype.initPane = function () {
342 return true;
343 };
344 SplitPane.decorators = [
345 { type: Directive, args: [{
346 selector: 'ion-split-pane',
347 providers: [{ provide: RootNode, useExisting: forwardRef(function () { return SplitPane; }) }]
348 },] },
349 ];
350 /** @nocollapse */
351 SplitPane.ctorParameters = function () { return [
352 { type: NgZone, },
353 { type: Platform, },
354 { type: Config, },
355 { type: ElementRef, },
356 { type: Renderer, },
357 ]; };
358 SplitPane.propDecorators = {
359 '_setchildren': [{ type: ContentChildren, args: [RootNode, { descendants: false },] },],
360 'when': [{ type: Input },],
361 'enabled': [{ type: Input },],
362 'ionChange': [{ type: Output },],
363 };
364 return SplitPane;
365}(Ion));
366export { SplitPane };
367//# sourceMappingURL=split-pane.js.map
\No newline at end of file