@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
781 lines • 104 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { Component, ContentChild, ElementRef, EventEmitter, forwardRef, HostBinding, Inject, Injector, Input, Optional, Output, SkipSelf, ViewChild } from '@angular/core';
import { Debounce } from '@microsoft/windows-admin-center-sdk/core/base/decorators/debounce.decorators';
import { Yield } from '@microsoft/windows-admin-center-sdk/core/base/decorators/yield.decorator';
import { LogLevel } from '@microsoft/windows-admin-center-sdk/core/diagnostics/log-level';
import { Logging } from '@microsoft/windows-admin-center-sdk/core/diagnostics/logging';
import { CoreBaseComponent } from '../common/base.component';
import { SME_LAYOUT_PROVIDER } from '../common/layout';
import { SplitViewResponsiveWindowManager } from './split-view-responsive-window-manager';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "../resizer/resizer.component";
const _c0 = ["*"];
const _c1 = ["paneContainer"];
const _c2 = ["contentContainer"];
function SplitViewComponent_ng_container_0_ng_container_3_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainer(0);
} }
const _c3 = function (a0) { return [a0]; };
function SplitViewComponent_ng_container_0_sme_resizer_6_Template(rf, ctx) { if (rf & 1) {
const _r12 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "sme-resizer", 9);
i0.ɵɵlistener("resized", function SplitViewComponent_ng_container_0_sme_resizer_6_Template_sme_resizer_resized_0_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r11 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r11.onResized($event)); });
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r9 = i0.ɵɵnextContext(2);
i0.ɵɵclassProp("sme-focus-zone", ctx_r9.isExpanded);
i0.ɵɵproperty("tabindex", i0.ɵɵpureFunction1(4, _c3, ctx_r9.isExpanded ? 0 : null))("orientation", ctx_r9.orientationResponsiveWindow);
} }
function SplitViewComponent_ng_container_0_ng_container_7_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainer(0);
} }
function SplitViewComponent_ng_container_0_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainerStart(0);
i0.ɵɵelementStart(1, "section", 3, 4);
i0.ɵɵtemplate(3, SplitViewComponent_ng_container_0_ng_container_3_Template, 1, 0, "ng-container", 5);
i0.ɵɵelementEnd();
i0.ɵɵelementStart(4, "section", 6, 7);
i0.ɵɵtemplate(6, SplitViewComponent_ng_container_0_sme_resizer_6_Template, 1, 6, "sme-resizer", 8);
i0.ɵɵtemplate(7, SplitViewComponent_ng_container_0_ng_container_7_Template, 1, 0, "ng-container", 5);
i0.ɵɵelementEnd();
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
const ctx_r0 = i0.ɵɵnextContext();
const _r2 = i0.ɵɵreference(3);
const _r4 = i0.ɵɵreference(5);
i0.ɵɵadvance(1);
i0.ɵɵclassProp("sme-arrange-overflow-auto", ctx_r0.showScrollbar);
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngTemplateOutlet", _r2);
i0.ɵɵadvance(1);
i0.ɵɵclassProp("sme-layout-none", ctx_r0.hideSplitViewPane)("sme-border-left-sm", ctx_r0.showSplitterBorder && ctx_r0.orientationResponsiveWindow === "right")("sme-border-top-sm", ctx_r0.showSplitterBorder && ctx_r0.orientationResponsiveWindow === "bottom")("sme-arrange-overflow-auto", ctx_r0.showScrollbar);
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngIf", ctx_r0.isExpanded);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngTemplateOutlet", _r4);
} }
function SplitViewComponent_ng_container_1_ng_container_3_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainer(0);
} }
function SplitViewComponent_ng_container_1_sme_resizer_4_Template(rf, ctx) { if (rf & 1) {
const _r19 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "sme-resizer", 9);
i0.ɵɵlistener("resized", function SplitViewComponent_ng_container_1_sme_resizer_4_Template_sme_resizer_resized_0_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r18 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r18.onResized($event)); });
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r15 = i0.ɵɵnextContext(2);
i0.ɵɵclassProp("sme-focus-zone", ctx_r15.isExpanded);
i0.ɵɵproperty("tabindex", i0.ɵɵpureFunction1(5, _c3, ctx_r15.isExpanded ? 0 : null))("orientation", ctx_r15.orientationResponsiveWindow);
i0.ɵɵattribute("aria-valuenow", ctx_r15.getAriaValueNow());
} }
function SplitViewComponent_ng_container_1_ng_container_7_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainer(0);
} }
function SplitViewComponent_ng_container_1_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainerStart(0);
i0.ɵɵelementStart(1, "section", 6, 7);
i0.ɵɵtemplate(3, SplitViewComponent_ng_container_1_ng_container_3_Template, 1, 0, "ng-container", 5);
i0.ɵɵtemplate(4, SplitViewComponent_ng_container_1_sme_resizer_4_Template, 1, 7, "sme-resizer", 8);
i0.ɵɵelementEnd();
i0.ɵɵelementStart(5, "section", 3, 4);
i0.ɵɵtemplate(7, SplitViewComponent_ng_container_1_ng_container_7_Template, 1, 0, "ng-container", 5);
i0.ɵɵelementEnd();
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
const ctx_r1 = i0.ɵɵnextContext();
const _r4 = i0.ɵɵreference(5);
const _r2 = i0.ɵɵreference(3);
i0.ɵɵadvance(1);
i0.ɵɵclassProp("sme-layout-none", ctx_r1.hideSplitViewPane)("sme-border-right-sm", ctx_r1.showSplitterBorder && ctx_r1.orientationResponsiveWindow === "left")("sme-border-bottom-sm", ctx_r1.showSplitterBorder && ctx_r1.orientationResponsiveWindow === "top")("sme-arrange-overflow-auto", ctx_r1.showScrollbar);
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngTemplateOutlet", _r4);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx_r1.isExpanded);
i0.ɵɵadvance(1);
i0.ɵɵclassProp("sme-arrange-overflow-auto", ctx_r1.showScrollbar);
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngTemplateOutlet", _r2);
} }
function SplitViewComponent_ng_template_2_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵprojection(0);
} }
function SplitViewComponent_ng_template_4_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵprojection(0, 1);
} }
const _c4 = [[["sme-split-view-content"]], [["sme-split-view-pane"]]];
const _c5 = ["sme-split-view-content", "sme-split-view-pane"];
/**
* The component definition of the split view content.
*/
export class SplitViewContentComponent {
}
/** @nocollapse */ SplitViewContentComponent.ɵfac = function SplitViewContentComponent_Factory(t) { return new (t || SplitViewContentComponent)(); };
/** @nocollapse */ SplitViewContentComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: SplitViewContentComponent, selectors: [["sme-split-view-content"]], ngContentSelectors: _c0, decls: 1, vars: 0, template: function SplitViewContentComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵprojectionDef();
i0.ɵɵprojection(0);
} }, encapsulation: 2 });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SplitViewContentComponent, [{
type: Component,
args: [{
selector: 'sme-split-view-content',
template: '<ng-content></ng-content>'
}]
}], null, null); })();
/**
* The component definition of the split view pane.
*/
export class SplitViewPaneComponent {
}
/** @nocollapse */ SplitViewPaneComponent.ɵfac = function SplitViewPaneComponent_Factory(t) { return new (t || SplitViewPaneComponent)(); };
/** @nocollapse */ SplitViewPaneComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: SplitViewPaneComponent, selectors: [["sme-split-view-pane"]], ngContentSelectors: _c0, decls: 1, vars: 0, template: function SplitViewPaneComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵprojectionDef();
i0.ɵɵprojection(0);
} }, encapsulation: 2 });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SplitViewPaneComponent, [{
type: Component,
args: [{
selector: 'sme-split-view-pane',
template: '<ng-content></ng-content>'
}]
}], null, null); })();
/**
* The component definition of the split view.
*/
export class SplitViewComponent extends CoreBaseComponent {
constructor(injector, elementReference, layout) {
super(injector);
this.elementReference = elementReference;
/**
* Container for active subscriptions that should be cleaned up in the OnDestroy call.
*/
this.subscriptions = [];
/**
* It defines whether the pane distance value is set.
* It will not set it twice if set because only need to remember the initial value.
*/
this.isPaneDistanceSet = false;
/**
* It defines whether the split view has been expanded.
*/
this.internalIsExpanded = false;
/**
* Defines whether the split view component has been initialized.
*/
this.isComponentInitialized = false;
/**
* The orientation of the pane.
*/
this.internalOrientation = 'bottom';
/**
* It implements the ILayout interface. It's triggered when the layout is changed.
* It's used to tell the child components to coordinate with the layout change.
*/
this.layoutChanged = new EventEmitter();
/**
* Implementation of the Layout interface
*/
this.windowBreakpointChanged = new EventEmitter();
/**
* It indicates whether to show the scrollbar when it's needed.
*/
this.showScrollbar = false;
/**
* It indicates whether to show the border for the splitter.
*/
this.showSplitterBorder = true;
/**
* Set this to true means on smaller window, will respect the original pane value
* It is not suggested to be used other than the shell side nav bar.
*/
this.disablePaneDistanceResponsiveWindow = false;
/**
* Set to true to disable the resize margin to go window responsive.
*/
this.disabledResizeMarginResponsiveWindow = false;
/**
* It indicates the min value of the pane size.
*/
this.resizeLowerMargin = 100;
/**
* It indicates the min value of the content size.
*/
this.resizeUpperMargin = 100;
/**
* Set this to true to disable the orientation change on window size change.
*/
this.disableOrientationResponsiveWindow = false;
/**
* Hides the split view pane
*/
this.hideSplitViewPane = false;
/**
* Remember the previous window responsive value for orientation for the on orientation changed event.
*/
this.previousOrientationResponsiveWindow = 'bottom';
/**
* The event fired when the pane's expanded state is being toggled.
*/
this.paneToggling = new EventEmitter();
/**
* The event fired when the pane's expanded state has been toggled.
*/
this.paneToggled = new EventEmitter();
if (layout) {
this.splitViewResponsiveWindowManager = new SplitViewResponsiveWindowManager(layout);
// on parent layout changes, re-emit the layout change to our event
this.subscriptions.push(layout.layoutChanged.subscribe((() => this.onParentLayoutChanged())));
// on window break point changes, emit the event about critical classes and styling updates signal.
this.subscriptions.push(layout.windowBreakpointChanged.subscribe(() => this.onWindowBreakpointChanged()));
this.deferredOnLayoutChanged();
}
}
/**
* The source name to use for logging
*/
get logSourceName() {
return 'SplitViewComponent';
}
/**
* It indicates the distance between the start and end of the pane.
* It is a hardcoded value, not fully working on window responsive design.
* By design, this value will not be respected on smaller screen, phone down.
*/
get paneDistance() {
return this.internalPaneDistance;
}
set paneDistance(value) {
if (this.internalPaneDistance === value) {
return;
}
this.internalPaneDistance = value;
if (!this.isPaneDistanceSet) {
this.defaultPaneDistance = value;
}
this.isPaneDistanceSet = true;
}
/**
* It defines the orientation of the element which holds the resizer in the resizing layout.
*/
set orientation(input) {
this.internalOrientation = input;
if (!this.splitViewResponsiveWindowManager) {
return;
}
const previousOrientation = this.splitViewResponsiveWindowManager.previousOrientation;
if (previousOrientation !== this.internalOrientation) {
this.splitViewResponsiveWindowManager.previousOrientation = this.internalOrientation;
}
}
/**
* Getter for orientation
*/
get orientation() {
return this.internalOrientation;
}
/**
* Getter for the window responsive value for the orientation
*/
get orientationResponsiveWindow() {
// If opt-out, should use the original orientation
if (this.disableOrientationResponsiveWindow) {
return this.orientation;
}
if (!this.splitViewResponsiveWindowManager) {
return this.orientation;
}
else {
const cur = this.splitViewResponsiveWindowManager.orientation;
if (cur !== this.previousOrientationResponsiveWindow) {
this.onOrientationChanged(cur);
this.previousOrientationResponsiveWindow = cur;
}
return this.splitViewResponsiveWindowManager.orientation;
}
}
/**
* Gets the CSS classes of the component.
*
* TODO: setting the class this way prevent any custom class from being applied.
* Change to setting class in the constructor using Renderer2 and ElementRef
*
* On phone down, the layout for split view can only be top and bottom, in this case, we will allow y scroll.
*/
get hostClass() {
return 'sme-layout-absolute sme-position-inset-none sme-arrange-stack-v sme-arrange-overflow-hide';
}
/**
* Gets the flex direction of the component.
*/
get flexDirection() {
switch (this.orientationResponsiveWindow) {
case 'left':
return 'row';
case 'top':
return 'column';
case 'right':
return 'row';
case 'bottom':
default:
return 'column';
}
}
/**
* Gets whether the pane has been expanded.
*/
get isExpanded() {
return this.internalIsExpanded;
}
/**
* Sets whether the pane has been expanded.
*/
set isExpanded(value) {
if (value === this.internalIsExpanded) {
return;
}
this.internalIsExpanded = value;
this.paneToggling.emit({
isExpanded: this.internalIsExpanded
});
this.refreshUI();
this.paneToggled.emit({
isExpanded: this.internalIsExpanded
});
this.layoutChanged.emit();
}
/**
* The Angular ngOnInit function.
*/
ngOnInit() {
this.isComponentInitialized = true;
this.refreshUI();
}
/**
* The Angular ngOnDestroy function.
*/
ngOnDestroy() {
this.subscriptions.forEach(sub => sub.unsubscribe());
}
/**
* The method called after content is initialized.
*/
ngAfterContentInit() {
if (this.content == null) {
Logging.log({
level: LogLevel.Error,
message: `The value of 'content' is either null or undefined.`,
params: {
content: this.content
},
source: 'SplitViewComponent.ngAfterContentInit'
});
}
if (this.pane == null) {
Logging.log({
level: LogLevel.Error,
message: `The value of 'pane' is either null or undefined.`,
params: {
pane: this.pane
},
source: 'SplitViewComponent.ngAfterContentInit'
});
}
if (!this.isPaneDistanceSet) {
this.resetPaneMaxSize();
}
}
/**
* Gets the window responsive value for the pane distance.
*/
getPaneDistanceResponsiveWindow() {
// If opt-out, should use the original pane distance.
if (this.disablePaneDistanceResponsiveWindow || !this.splitViewResponsiveWindowManager) {
return this.paneDistance;
}
return this.splitViewResponsiveWindowManager.paneDistance(this.paneDistance);
}
/**
* Gets the window responsive value for the resizer margin.
*/
getSplitViewResizerMarginResponsiveWindow() {
// If opt-out, should use the original margin size.
if (this.disabledResizeMarginResponsiveWindow || !this.splitViewResponsiveWindowManager) {
return {
lower: this.resizeLowerMargin,
upper: this.resizeUpperMargin
};
}
return this.splitViewResponsiveWindowManager.splitViewResizerMargin(this.resizeLowerMargin, this.resizeUpperMargin);
}
/**
* The on window breakpoint changed handler.
* Adding yield for component to get ElementRef after initialization.
*/
onWindowBreakpointChanged() {
if (!this.contentContainerElement || !this.paneContainerElement) {
return;
}
this.splitViewResponsiveWindowManager.onWindowSizeChanged(this.contentContainerElement, this.paneContainerElement);
}
/**
* The deferred layout changed handler.
*/
deferredOnLayoutChanged() {
this.onParentLayoutChanged();
}
/**
* Handles the change event coming from parent control from the layout component.
*/
onParentLayoutChanged() {
if (!this.isComponentInitialized) {
return;
}
if (this.isPaneDistanceSet) {
this.resetPaneMaxSize();
const resizeMargin = this.getSplitViewResizerMarginResponsiveWindow();
const orientationResponsiveWindow = this.orientationResponsiveWindow;
const paneContainer = this.paneContainerElement.nativeElement;
if (resizeMargin.lower === undefined && resizeMargin.upper === undefined) {
if (orientationResponsiveWindow === 'bottom' || orientationResponsiveWindow === 'top') {
paneContainer.style.height = '';
paneContainer.style.width = '100%';
}
else if (orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right') {
paneContainer.style.width = '';
paneContainer.style.height = '100%';
}
}
else {
if ((orientationResponsiveWindow === 'bottom' || orientationResponsiveWindow === 'top')
&& this.elementReference.nativeElement.offsetHeight) {
this.paneDistance = Math.min(this.paneDistance, this.elementReference.nativeElement.offsetHeight - resizeMargin.upper);
this.paneDistance = Math.max(this.paneDistance, resizeMargin.lower);
paneContainer.style.height = this.isExpanded && this.paneDistance ? (this.paneDistance + 'px') : '';
paneContainer.style.width = '100%';
}
else if ((orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right')
&& this.elementReference.nativeElement.offsetWidth) {
this.paneDistance = Math.min(this.paneDistance, this.elementReference.nativeElement.offsetWidth - resizeMargin.upper);
this.paneDistance = Math.max(this.paneDistance, resizeMargin.lower);
paneContainer.style.width = this.isExpanded && this.paneDistance ? (this.paneDistance + 'px') : '';
paneContainer.style.height = '100%';
}
}
}
else {
if (this.isExpanded) {
this.setPaneMaxSize();
}
}
this.layoutChanged.emit();
}
/**
* Toggles the expanded state of the pane.
*/
togglePane() {
this.isExpanded = !this.isExpanded;
}
/**
* The implementation for after the control gets signal for confirmation for resize.
* @param $event the event for resizing
*/
onResized($event) {
this.resetPaneMaxSize();
const resizeMargin = this.getSplitViewResizerMarginResponsiveWindow();
const orientationResponsiveWindow = this.orientationResponsiveWindow;
const paneContainer = this.paneContainerElement.nativeElement;
this.isPaneDistanceSet = true;
if (resizeMargin.lower === undefined && resizeMargin.upper === undefined) {
if (orientationResponsiveWindow === 'bottom' || orientationResponsiveWindow === 'top') {
paneContainer.style.height = '';
paneContainer.style.width = '100%';
}
else if (orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right') {
paneContainer.style.width = '';
paneContainer.style.height = '100%';
}
}
else {
if (orientationResponsiveWindow === 'bottom' || orientationResponsiveWindow === 'top') {
const resizedHeight = orientationResponsiveWindow === 'bottom' ?
paneContainer.offsetHeight - $event.y :
paneContainer.offsetHeight + $event.y;
this.paneDistance = Math.max(resizedHeight, resizeMargin.lower);
this.paneDistance = Math.min(this.paneDistance, this.elementReference.nativeElement.offsetHeight - resizeMargin.upper);
paneContainer.style.height = this.paneDistance ? this.paneDistance + 'px' : '';
}
else if (orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right') {
const resizedWidth = orientationResponsiveWindow === 'right' ?
paneContainer.offsetWidth - $event.x :
paneContainer.offsetWidth + $event.x;
this.paneDistance = Math.max(resizedWidth, resizeMargin.lower);
this.paneDistance = Math.min(this.paneDistance, this.elementReference.nativeElement.offsetWidth - resizeMargin.upper);
paneContainer.style.width = this.paneDistance ? this.paneDistance + 'px' : '';
}
}
this.layoutChanged.emit();
}
/**
* Gets the value for the pane's distance for accessibility purposes.
* @returns number that indicates the pane's rendering value.
*/
getAriaValueNow() {
return this.isExpanded && this.paneDistance ? Math.round(this.paneDistance) : null;
}
/**
* Handles the orientation changed events. This usually happens on layout change behavior such as resizing the window.
* This function has to be called with component initialized.
* @param cur the current layout, could be top, bottom, left, right.
* @returns void.
*/
onOrientationChanged(cur) {
// Ignore if the container is not yet initialized.
if (!this.isComponentInitialized || !this.paneContainerElement || !this.paneContainerElement.nativeElement) {
return;
}
const container = this.paneContainerElement.nativeElement;
if (cur === 'top' || cur === 'bottom') {
container.style.width = '100%';
container.style.height = this.getPaneDistanceResponsiveWindow() + 'px';
this.paneDistance = this.defaultPaneDistance;
}
else if (cur === 'left' || cur === 'right') {
container.style.width = this.getPaneDistanceResponsiveWindow() + 'px';
container.style.height = '100%';
}
this.deferredRefreshUI();
}
/**
* It has to be a debounce value in between 0 - 250 to wait for children component.
* Ideally should be promise implemented.
*/
deferredRefreshUI() {
this.refreshUI();
}
/**
* The function to refresh the split view from UI.
* @returns void
*/
refreshUI() {
if (!this.isComponentInitialized || !this.paneContainerElement || !this.paneContainerElement.nativeElement) {
return;
}
const paneDistanceResponsiveWindow = this.getPaneDistanceResponsiveWindow();
const orientationResponsiveWindow = this.orientationResponsiveWindow;
const paneContainer = this.paneContainerElement.nativeElement;
if (this.internalIsExpanded) {
if (this.paneDistance) {
let paneDistance = this.paneDistance > paneDistanceResponsiveWindow
? paneDistanceResponsiveWindow : this.paneDistance;
// On phone-down, get rid of the scrollbar vertically.
if (paneDistanceResponsiveWindow === undefined) {
paneDistance = paneDistanceResponsiveWindow;
}
if (orientationResponsiveWindow === 'top' || orientationResponsiveWindow === 'bottom') {
paneContainer.style.height = paneDistance ? paneDistance + 'px' : '';
paneContainer.style.width = '100%';
}
else if (orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right') {
paneContainer.style.width = paneDistance ? paneDistance + 'px' : '';
paneContainer.style.height = '';
}
}
}
else {
if (orientationResponsiveWindow === 'top' || orientationResponsiveWindow === 'bottom') {
paneContainer.style.height = '';
}
else if (orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right') {
paneContainer.style.width = '';
}
}
this.setInternalPaneDistance();
}
/**
* Sets the pane distance that would be used for rendering the pane.
* pane's height on top, bottom layout.
* pane's width on left, right layout.
* @returns void;
*/
setInternalPaneDistance() {
if (!this.paneContainerElement || !this.paneContainerElement.nativeElement) {
return;
}
if (!this.internalIsExpanded) {
return;
}
const orientationResponsiveWindow = this.orientationResponsiveWindow;
const paneContainer = this.paneContainerElement.nativeElement;
if (orientationResponsiveWindow === 'top' || orientationResponsiveWindow === 'bottom') {
this.paneDistance = paneContainer.offsetHeight;
}
else if (orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right') {
this.paneDistance = paneContainer.offsetWidth;
}
}
/**
* Sets the max value that the pane can grow.
* Sets pane's height value on top, bottom layout.
* Sets pane's width value on left, right layout.
* @returns void.
*/
setPaneMaxSize() {
if (!this.paneContainerElement || !this.paneContainerElement.nativeElement) {
return;
}
const resizeMargin = this.getSplitViewResizerMarginResponsiveWindow();
const orientationResponsiveWindow = this.orientationResponsiveWindow;
const paneContainer = this.paneContainerElement.nativeElement;
if (resizeMargin.lower === undefined && resizeMargin.upper === undefined) {
if (orientationResponsiveWindow === 'bottom' || orientationResponsiveWindow === 'top') {
paneContainer.style.minHeight = '';
paneContainer.style.maxHeight = '100%';
}
else if (orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right') {
paneContainer.style.minWidth = '';
paneContainer.style.maxWidth = '100%';
}
}
else {
if (orientationResponsiveWindow === 'top' || orientationResponsiveWindow === 'bottom') {
if (!this.disabledResizeMarginResponsiveWindow) {
paneContainer.style.minHeight = resizeMargin.lower + 'px';
paneContainer.style.maxHeight = (this.elementReference.nativeElement.offsetHeight - resizeMargin.upper) + 'px';
}
}
else if (orientationResponsiveWindow === 'left' || orientationResponsiveWindow === 'right') {
paneContainer.style.minWidth = resizeMargin.lower + 'px';
paneContainer.style.maxWidth = (this.elementReference.nativeElement.offsetWidth - resizeMargin.upper) + 'px';
}
}
}
/**
* Resets the max value that the pane can grow.
* @returns void.
*/
resetPaneMaxSize() {
if (!this.paneContainerElement || !this.paneContainerElement.nativeElement) {
return;
}
const paneContainer = this.paneContainerElement.nativeElement;
paneContainer.style.maxWidth = '';
paneContainer.style.maxHeight = '';
}
}
/** @nocollapse */ SplitViewComponent.ɵfac = function SplitViewComponent_Factory(t) { return new (t || SplitViewComponent)(i0.ɵɵdirectiveInject(i0.Injector), i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(SME_LAYOUT_PROVIDER, 12)); };
/** @nocollapse */ SplitViewComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: SplitViewComponent, selectors: [["sme-split-view"]], contentQueries: function SplitViewComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) {
i0.ɵɵcontentQuery(dirIndex, SplitViewContentComponent, 5);
i0.ɵɵcontentQuery(dirIndex, SplitViewPaneComponent, 5);
} if (rf & 2) {
let _t;
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.content = _t.first);
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.pane = _t.first);
} }, viewQuery: function SplitViewComponent_Query(rf, ctx) { if (rf & 1) {
i0.ɵɵviewQuery(_c1, 5);
i0.ɵɵviewQuery(_c2, 5);
} if (rf & 2) {
let _t;
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.paneContainerElement = _t.first);
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.contentContainerElement = _t.first);
} }, hostVars: 4, hostBindings: function SplitViewComponent_HostBindings(rf, ctx) { if (rf & 2) {
i0.ɵɵclassMap(ctx.hostClass);
i0.ɵɵstyleProp("flex-direction", ctx.flexDirection);
} }, inputs: { showScrollbar: "showScrollbar", showSplitterBorder: "showSplitterBorder", disablePaneDistanceResponsiveWindow: "disablePaneDistanceResponsiveWindow", paneDistance: "paneDistance", disabledResizeMarginResponsiveWindow: "disabledResizeMarginResponsiveWindow", resizeLowerMargin: "resizeLowerMargin", resizeUpperMargin: "resizeUpperMargin", orientation: "orientation", disableOrientationResponsiveWindow: "disableOrientationResponsiveWindow", hideSplitViewPane: "hideSplitViewPane", isExpanded: "isExpanded" }, outputs: { layoutChanged: "layoutChanged", windowBreakpointChanged: "windowBreakpointChanged", paneToggling: "paneToggling", paneToggled: "paneToggled" }, features: [i0.ɵɵProvidersFeature([
{ provide: SME_LAYOUT_PROVIDER, useExisting: forwardRef((() => SplitViewComponent)) }
]), i0.ɵɵInheritDefinitionFeature], ngContentSelectors: _c5, decls: 6, vars: 2, consts: [[4, "ngIf"], ["content", ""], ["pane", ""], [1, "sme-layout-relative", "sme-position-flex-auto"], ["contentContainer", ""], [4, "ngTemplateOutlet"], [1, "sme-layout-relative", "sme-position-flex-none", "sme-border-color-base-80"], ["paneContainer", ""], ["class", "sme-layout-hide-phone-down", "resizerHostSelector", "sme-split-view", 3, "tabindex", "sme-focus-zone", "orientation", "resized", 4, "ngIf"], ["resizerHostSelector", "sme-split-view", 1, "sme-layout-hide-phone-down", 3, "tabindex", "orientation", "resized"]], template: function SplitViewComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵprojectionDef(_c4);
i0.ɵɵtemplate(0, SplitViewComponent_ng_container_0_Template, 8, 13, "ng-container", 0);
i0.ɵɵtemplate(1, SplitViewComponent_ng_container_1_Template, 8, 13, "ng-container", 0);
i0.ɵɵtemplate(2, SplitViewComponent_ng_template_2_Template, 1, 0, "ng-template", null, 1, i0.ɵɵtemplateRefExtractor);
i0.ɵɵtemplate(4, SplitViewComponent_ng_template_4_Template, 1, 0, "ng-template", null, 2, i0.ɵɵtemplateRefExtractor);
} if (rf & 2) {
i0.ɵɵproperty("ngIf", ctx.orientationResponsiveWindow === "bottom" || ctx.orientationResponsiveWindow === "right");
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx.orientationResponsiveWindow === "top" || ctx.orientationResponsiveWindow === "left");
} }, dependencies: [i1.NgIf, i1.NgTemplateOutlet, i2.ResizerComponent], encapsulation: 2 });
__decorate([
Yield(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], SplitViewComponent.prototype, "onWindowBreakpointChanged", null);
__decorate([
Debounce(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], SplitViewComponent.prototype, "deferredOnLayoutChanged", null);
__decorate([
Debounce(10),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], SplitViewComponent.prototype, "deferredRefreshUI", null);
__decorate([
Debounce(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], SplitViewComponent.prototype, "setInternalPaneDistance", null);
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SplitViewComponent, [{
type: Component,
args: [{ selector: 'sme-split-view', providers: [
{ provide: SME_LAYOUT_PROVIDER, useExisting: forwardRef((() => SplitViewComponent)) }
], template: "<ng-container *ngIf=\"orientationResponsiveWindow==='bottom' || orientationResponsiveWindow==='right'\">\r\n <section #contentContainer class=\"sme-layout-relative sme-position-flex-auto\" [class.sme-arrange-overflow-auto]=\"showScrollbar\">\r\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\r\n </section>\r\n <section #paneContainer [class.sme-layout-none]=\"hideSplitViewPane\"\r\n class=\"sme-layout-relative sme-position-flex-none sme-border-color-base-80\"\r\n [class.sme-border-left-sm]=\"showSplitterBorder && orientationResponsiveWindow === 'right'\"\r\n [class.sme-border-top-sm]=\"showSplitterBorder && orientationResponsiveWindow === 'bottom'\"\r\n [class.sme-arrange-overflow-auto]=\"showScrollbar\">\r\n <!-- TODO: hide resizer on phone down temporarily, needs special design -->\r\n <sme-resizer *ngIf=\"isExpanded\" class=\"sme-layout-hide-phone-down\" [tabindex]=\"[isExpanded?0:null]\"\r\n [class.sme-focus-zone]=\"isExpanded\" resizerHostSelector=\"sme-split-view\"\r\n (resized)=\"onResized($event)\" [orientation]=\"orientationResponsiveWindow\">\r\n </sme-resizer>\r\n <ng-container *ngTemplateOutlet=\"pane\"></ng-container>\r\n </section>\r\n</ng-container>\r\n<ng-container *ngIf=\"orientationResponsiveWindow==='top' || orientationResponsiveWindow==='left'\">\r\n <section #paneContainer [class.sme-layout-none]=\"hideSplitViewPane\"\r\n class=\"sme-layout-relative sme-position-flex-none sme-border-color-base-80\"\r\n [class.sme-border-right-sm]=\"showSplitterBorder && orientationResponsiveWindow === 'left'\"\r\n [class.sme-border-bottom-sm]=\"showSplitterBorder && orientationResponsiveWindow === 'top'\"\r\n [class.sme-arrange-overflow-auto]=\"showScrollbar\">\r\n <ng-container *ngTemplateOutlet=\"pane\"></ng-container>\r\n <!-- TODO: hide resizer on phone down temporarily, needs special design -->\r\n <sme-resizer *ngIf=\"isExpanded\" class=\"sme-layout-hide-phone-down\" [tabindex]=\"[isExpanded?0:null]\"\r\n [class.sme-focus-zone]=\"isExpanded\" resizerHostSelector=\"sme-split-view\"\r\n (resized)=\"onResized($event)\" [orientation]=\"orientationResponsiveWindow\" [attr.aria-valuenow]=\"getAriaValueNow()\">\r\n </sme-resizer>\r\n </section>\r\n <section #contentContainer class=\"sme-layout-relative sme-position-flex-auto\" [class.sme-arrange-overflow-auto]=\"showScrollbar\">\r\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\r\n </section>\r\n</ng-container>\r\n\r\n<ng-template #content>\r\n <ng-content select=\"sme-split-view-content\"></ng-content>\r\n</ng-template>\r\n<ng-template #pane>\r\n <ng-content select=\"sme-split-view-pane\"></ng-content>\r\n</ng-template>\r\n<!-- The reason to use ng-template to wrap the ng-content element instead of directly to use ng-content in both two ng-containers above is:\r\nIf we use ng-content elements directly in both 2 ng-containers, there will be 2 ng-content elements with the same selector. But Angular will only\r\nresolve the first ng-content in multiple ng-content elements with same selector even the first one is in a ngIf false block.\r\nSo when the orientation is \"top\" or \"left\", no ng-content element will be resolved then nothing would render.\r\nIn order to solve this problem, we have to use ng-template to wrap the ng-content to make sure one selector maps to one ng-content.\r\nThen we use ng-container and ngTemplateOutlet to call the ng-template.\r\nThx for reading till here...... -->\r\n" }]
}], function () { return [{ type: i0.Injector }, { type: i0.ElementRef }, { type: undefined, decorators: [{
type: SkipSelf
}, {
type: Optional
}, {
type: Inject,
args: [SME_LAYOUT_PROVIDER]
}] }]; }, { layoutChanged: [{
type: Output
}], windowBreakpointChanged: [{
type: Output
}], content: [{
type: ContentChild,
args: [SplitViewContentComponent]
}], pane: [{
type: ContentChild,
args: [SplitViewPaneComponent]
}], paneContainerElement: [{
type: ViewChild,
args: ['paneContainer']
}], contentContainerElement: [{
type: ViewChild,
args: ['contentContainer']
}], showScrollbar: [{
type: Input
}], showSplitterBorder: [{
type: Input
}], disablePaneDistanceResponsiveWindow: [{
type: Input
}], paneDistance: [{
type: Input
}], disabledResizeMarginResponsiveWindow: [{
type: Input
}], resizeLowerMargin: [{
type: Input
}], resizeUpperMargin: [{
type: Input
}], orientation: [{
type: Input
}], disableOrientationResponsiveWindow: [{
type: Input
}], hideSplitViewPane: [{
type: Input
}], paneToggling: [{
type: Output
}], paneToggled: [{
type: Output
}], hostClass: [{
type: HostBinding,
args: ['class']
}], flexDirection: [{
type: HostBinding,
args: ['style.flex-direction']
}], isExpanded: [{
type: Input
}], onWindowBreakpointChanged: [], deferredOnLayoutChanged: [], deferredRefreshUI: [], setInternalPaneDistance: [] }); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BsaXQtdmlldy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9hbmd1bGFyL3NyYy9jb250cm9scy9zcGxpdC12aWV3L3NwbGl0LXZpZXcuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vYW5ndWxhci9zcmMvY29udHJvbHMvc3BsaXQtdmlldy9zcGxpdC12aWV3LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBRUgsU0FBUyxFQUNULFlBQVksRUFDWixVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFDVixXQUFXLEVBQ1gsTUFBTSxFQUNOLFFBQVEsRUFDUixLQUFLLEVBR0wsUUFBUSxFQUNSLE1BQU0sRUFDTixRQUFRLEVBQ1IsU0FBUyxFQUNaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSw4RUFBOEUsQ0FBQztBQUN4RyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sMEVBQTBFLENBQUM7QUFDakcsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGdFQUFnRSxDQUFDO0FBQzFGLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSw4REFBOEQsQ0FBQztBQUV2RixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM3RCxPQUFPLEVBQVUsbUJBQW1CLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUMvRCxPQUFPLEVBQTBCLGdDQUFnQyxFQUFFLE1BQU0sd0NBQXdDLENBQUM7Ozs7Ozs7O0lDdkI5Ryx3QkFBeUQ7Ozs7O0lBUXpELHNDQUU0RTtJQUExRSx3TUFBVyxlQUFBLHlCQUFpQixDQUFBLElBQUM7SUFDL0IsaUJBQWM7OztJQUZaLG1EQUFtQztJQUQ4QixtRkFBZ0MsbURBQUE7OztJQUluRyx3QkFBc0Q7OztJQWQxRCw2QkFBc0c7SUFDcEcscUNBQWdJO0lBQzlILG9H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