UNPKG

@progress/kendo-angular-layout

Version:

Kendo UI for Angular Layout Package - a collection of components to create professional application layoyts

325 lines (324 loc) 11.3 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { ChangeDetectorRef, Component, ElementRef, EventEmitter, HostBinding, Renderer2, Input, Output } from '@angular/core'; import { SplitterService } from './splitter.service'; import { anyChanged } from '@progress/kendo-angular-common'; import * as i0 from "@angular/core"; import * as i1 from "./splitter.service"; /** * Represents the pane component of the Splitter. * * @example * ```html * <kendo-splitter> * <kendo-splitter-pane size="30%" [collapsible]="true"> * Left pane content * </kendo-splitter-pane> * <kendo-splitter-pane> * Right pane content * </kendo-splitter-pane> * </kendo-splitter> * ``` */ export class SplitterPaneComponent { element; renderer; cdr; splitterService; /** * @hidden */ set order(paneOrder) { this._order = paneOrder; this.setOrderStyles(); } get order() { return this._order; } /** * Defines the initial size of the pane. * Accepts values in pixels and percentages. * The value must be between the `min` and `max` properties. */ set size(newSize) { this._size = newSize; // Only set flex-basis if the pane is not collapsed if (!this._collapsed) { this.renderer.setStyle(this.nativeElement, '-ms-flex-preferred-size', newSize); this.renderer.setStyle(this.nativeElement, 'flex-basis', newSize); } this.setStaticPaneClass(); } get size() { return this._size; } /** * Defines the HTML attributes of the splitter bar. * Accepts string key-value pairs. * You cannot change attributes that are essential for certain functionalities. */ set splitterBarAttributes(attributes) { this._splitterBarAttributes = attributes; const splitterBar = this.splitterService.getPaneSplitterBar(this); if (splitterBar) { splitterBar.htmlAttributes = attributes; } } get splitterBarAttributes() { return this._splitterBarAttributes; } /** * Defines the CSS classes that are rendered on the splitter bar. * Supports the same values as [`ngClass`](link:site.data.urls.angular['ngclassapi']). */ splitterBarClass; /** * Defines the minimum possible size of the pane. * Accepts values in pixels and percentages. */ min; /** * Defines the maximum possible size of the pane. * Accepts values in pixels and percentages. */ max; /** * Determines if you can resize the pane and provide space for other panes. * * @default true */ resizable = true; /** * Determines if you can hide the pane and provide space for other panes. * * @default false */ collapsible = false; /** * Determines if overflowing content is scrollable or hidden. * * @default true */ scrollable = true; /** * Determines if the pane is initially collapsed. * * @default false */ set collapsed(value) { const hasChanged = this._collapsed !== value; this._collapsed = value; if (hasChanged && this.nativeElement) { if (this._collapsed) { // When collapsing, clear the flex-basis to allow other panes to expand this.renderer.setStyle(this.nativeElement, '-ms-flex-preferred-size', '0'); this.renderer.setStyle(this.nativeElement, 'flex-basis', '0'); } else if (this._size) { // When expanding, restore the size if it was set this.renderer.setStyle(this.nativeElement, '-ms-flex-preferred-size', this._size); this.renderer.setStyle(this.nativeElement, 'flex-basis', this._size); } // Trigger the same forceExpand logic that tryToggle does // This ensures remaining panes expand when a pane is collapsed if (this.splitterService?.panes) { const notCollapsed = this.splitterService.panes.filter(p => !p.collapsed); const allHaveFixedSize = notCollapsed.every(p => p.fixedSize); notCollapsed.filter(p => p.fixedSize).forEach(pane => { pane.forceExpand = allHaveFixedSize; }); } } } get collapsed() { return this._collapsed; } /** * @hidden */ orientation = 'horizontal'; /** * @hidden */ set containsSplitter(value) { if (value) { this.renderer.addClass(this.nativeElement, 'k-pane-flex'); } else { this.renderer.removeClass(this.nativeElement, 'k-pane-flex'); } } /** * @hidden */ overlayContent = false; /** * Fires when the Splitter pane size changes. * The event data contains the new pane size. * Enables two-way binding of the pane `size` property. */ sizeChange = new EventEmitter(); /** * Fires when the Splitter pane collapses or expands. * The event data contains the new property state. * Enables two-way binding of the `collapsed` pane property. */ collapsedChange = new EventEmitter(); get isHidden() { return this.collapsed; } ariaRole = 'group'; hostClass = true; get scrollablePaneClass() { return this.scrollable; } get fixedSize() { return this.size && this.size.length > 0; } /** * @hidden */ forceExpand = false; /** * @hidden */ isResized = false; _size; _order; _splitterBarAttributes; _collapsed = false; constructor(element, renderer, cdr, splitterService) { this.element = element; this.renderer = renderer; this.cdr = cdr; this.splitterService = splitterService; } ngAfterViewChecked() { if (this.isHidden) { this.renderer.addClass(this.nativeElement, 'k-hidden'); this.renderer.addClass(this.nativeElement, 'hidden'); } else { this.renderer.removeClass(this.nativeElement, 'k-hidden'); this.renderer.removeClass(this.nativeElement, 'hidden'); } this.setStaticPaneClass(); } ngOnChanges(changes) { if (anyChanged(['resizable', 'collapsible'], changes)) { this.setStaticPaneClass(); } } /** * @hidden */ get computedSize() { if (this.orientation === 'vertical') { return this.nativeElement.offsetHeight; } else { return this.nativeElement.offsetWidth; } } /** * @hidden */ get nativeElement() { return this.element.nativeElement; } /** * @hidden */ toggleOverlay(show) { this.overlayContent = show; this.cdr.detectChanges(); } /** * @hidden */ detectChanges() { this.cdr.detectChanges(); } setOrderStyles() { this.renderer.setStyle(this.nativeElement, '-ms-flex-order', this.order); this.renderer.setStyle(this.nativeElement, 'order', this.order); } setStaticPaneClass() { if (this.forceExpand) { this.renderer.removeClass(this.nativeElement, 'k-pane-static'); return; } if (!this.resizable && !this.collapsible || this.fixedSize) { this.renderer.addClass(this.nativeElement, 'k-pane-static'); } else { this.renderer.removeClass(this.nativeElement, 'k-pane-static'); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SplitterPaneComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i1.SplitterService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SplitterPaneComponent, isStandalone: true, selector: "kendo-splitter-pane", inputs: { order: "order", size: "size", splitterBarAttributes: "splitterBarAttributes", splitterBarClass: "splitterBarClass", min: "min", max: "max", resizable: "resizable", collapsible: "collapsible", scrollable: "scrollable", collapsed: "collapsed", orientation: "orientation", containsSplitter: "containsSplitter", overlayContent: "overlayContent" }, outputs: { sizeChange: "sizeChange", collapsedChange: "collapsedChange" }, host: { properties: { "attr.role": "this.ariaRole", "class.k-pane": "this.hostClass", "class.k-scrollable": "this.scrollablePaneClass" } }, exportAs: ["kendoSplitterPane"], usesOnChanges: true, ngImport: i0, template: ` @if (!collapsed) { <ng-content></ng-content> } @if (overlayContent) { <div class="k-splitter-overlay k-overlay"></div> } `, isInline: true }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SplitterPaneComponent, decorators: [{ type: Component, args: [{ exportAs: 'kendoSplitterPane', selector: 'kendo-splitter-pane', template: ` @if (!collapsed) { <ng-content></ng-content> } @if (overlayContent) { <div class="k-splitter-overlay k-overlay"></div> } `, standalone: true }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i1.SplitterService }], propDecorators: { order: [{ type: Input }], size: [{ type: Input }], splitterBarAttributes: [{ type: Input }], splitterBarClass: [{ type: Input }], min: [{ type: Input }], max: [{ type: Input }], resizable: [{ type: Input }], collapsible: [{ type: Input }], scrollable: [{ type: Input }], collapsed: [{ type: Input }], orientation: [{ type: Input }], containsSplitter: [{ type: Input }], overlayContent: [{ type: Input }], sizeChange: [{ type: Output }], collapsedChange: [{ type: Output }], ariaRole: [{ type: HostBinding, args: ['attr.role'] }], hostClass: [{ type: HostBinding, args: ['class.k-pane'] }], scrollablePaneClass: [{ type: HostBinding, args: ['class.k-scrollable'] }] } });