@ngneers/controls 0.0.1-pre4 → 0.0.1-pre6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ngneers-controls-accordion.mjs +32 -32
- package/fesm2022/ngneers-controls-accordion.mjs.map +1 -1
- package/fesm2022/ngneers-controls-api-ng.mjs +19 -19
- package/fesm2022/ngneers-controls-api-ng.mjs.map +1 -1
- package/fesm2022/ngneers-controls-api-resize.mjs +706 -0
- package/fesm2022/ngneers-controls-api-resize.mjs.map +1 -0
- package/fesm2022/ngneers-controls-avatar.mjs +13 -13
- package/fesm2022/ngneers-controls-avatar.mjs.map +1 -1
- package/fesm2022/ngneers-controls-base.mjs +89 -64
- package/fesm2022/ngneers-controls-base.mjs.map +1 -1
- package/fesm2022/ngneers-controls-breadcrumb.mjs +18 -18
- package/fesm2022/ngneers-controls-breadcrumb.mjs.map +1 -1
- package/fesm2022/ngneers-controls-button-group.mjs +8 -8
- package/fesm2022/ngneers-controls-button-group.mjs.map +1 -1
- package/fesm2022/ngneers-controls-button.mjs +16 -10
- package/fesm2022/ngneers-controls-button.mjs.map +1 -1
- package/fesm2022/{ngneers-controls-calendar-time-C7UnIFzU.mjs → ngneers-controls-calendar-time-Bzlv9Vkn.mjs} +9 -9
- package/fesm2022/{ngneers-controls-calendar-time-C7UnIFzU.mjs.map → ngneers-controls-calendar-time-Bzlv9Vkn.mjs.map} +1 -1
- package/fesm2022/ngneers-controls-calendar.mjs +54 -54
- package/fesm2022/ngneers-controls-calendar.mjs.map +1 -1
- package/fesm2022/ngneers-controls-checkbox.mjs +9 -9
- package/fesm2022/ngneers-controls-checkbox.mjs.map +1 -1
- package/fesm2022/ngneers-controls-chip.mjs +6 -6
- package/fesm2022/ngneers-controls-chip.mjs.map +1 -1
- package/fesm2022/ngneers-controls-defer.mjs +10 -10
- package/fesm2022/ngneers-controls-defer.mjs.map +1 -1
- package/fesm2022/ngneers-controls-dialog.mjs +37 -39
- package/fesm2022/ngneers-controls-dialog.mjs.map +1 -1
- package/fesm2022/ngneers-controls-directives.mjs +45 -39
- package/fesm2022/ngneers-controls-directives.mjs.map +1 -1
- package/fesm2022/ngneers-controls-drawer.mjs +28 -28
- package/fesm2022/ngneers-controls-drawer.mjs.map +1 -1
- package/fesm2022/ngneers-controls-edit-inplace.mjs +15 -15
- package/fesm2022/ngneers-controls-edit-inplace.mjs.map +1 -1
- package/fesm2022/ngneers-controls-filter.mjs +192 -44
- package/fesm2022/ngneers-controls-filter.mjs.map +1 -1
- package/fesm2022/{ngneers-controls-i18n-de-CdTPeBiR.mjs → ngneers-controls-i18n-de-CF0xTWEX.mjs} +9 -5
- package/fesm2022/ngneers-controls-i18n-de-CF0xTWEX.mjs.map +1 -0
- package/fesm2022/{ngneers-controls-i18n-en-Cfp2pOLY.mjs → ngneers-controls-i18n-en-8B7xAjH2.mjs} +9 -5
- package/fesm2022/ngneers-controls-i18n-en-8B7xAjH2.mjs.map +1 -0
- package/fesm2022/ngneers-controls-i18n.mjs +5 -5
- package/fesm2022/ngneers-controls-i18n.mjs.map +1 -1
- package/fesm2022/ngneers-controls-icon.mjs +10 -10
- package/fesm2022/ngneers-controls-icon.mjs.map +1 -1
- package/fesm2022/ngneers-controls-inplace.mjs +18 -18
- package/fesm2022/ngneers-controls-inplace.mjs.map +1 -1
- package/fesm2022/ngneers-controls-input-field.mjs +15 -15
- package/fesm2022/ngneers-controls-input-field.mjs.map +1 -1
- package/fesm2022/ngneers-controls-input-mask.mjs +8 -8
- package/fesm2022/ngneers-controls-input-mask.mjs.map +1 -1
- package/fesm2022/ngneers-controls-input.mjs +7 -6
- package/fesm2022/ngneers-controls-input.mjs.map +1 -1
- package/fesm2022/ngneers-controls-item-view.mjs +33 -33
- package/fesm2022/ngneers-controls-item-view.mjs.map +1 -1
- package/fesm2022/ngneers-controls-list-box.mjs +31 -31
- package/fesm2022/ngneers-controls-list-box.mjs.map +1 -1
- package/fesm2022/ngneers-controls-menu.mjs +32 -32
- package/fesm2022/ngneers-controls-menu.mjs.map +1 -1
- package/fesm2022/ngneers-controls-message.mjs +4 -4
- package/fesm2022/ngneers-controls-message.mjs.map +1 -1
- package/fesm2022/ngneers-controls-paginator.mjs +12 -12
- package/fesm2022/ngneers-controls-paginator.mjs.map +1 -1
- package/fesm2022/ngneers-controls-popover.mjs +13 -13
- package/fesm2022/ngneers-controls-popover.mjs.map +1 -1
- package/fesm2022/ngneers-controls-progress.mjs +16 -16
- package/fesm2022/ngneers-controls-progress.mjs.map +1 -1
- package/fesm2022/ngneers-controls-scroller.mjs +74 -39
- package/fesm2022/ngneers-controls-scroller.mjs.map +1 -1
- package/fesm2022/ngneers-controls-select-button.mjs +6 -6
- package/fesm2022/ngneers-controls-select-button.mjs.map +1 -1
- package/fesm2022/ngneers-controls-select.mjs +46 -46
- package/fesm2022/ngneers-controls-select.mjs.map +1 -1
- package/fesm2022/ngneers-controls-slider.mjs +12 -12
- package/fesm2022/ngneers-controls-slider.mjs.map +1 -1
- package/fesm2022/ngneers-controls-spinner.mjs +7 -7
- package/fesm2022/ngneers-controls-spinner.mjs.map +1 -1
- package/fesm2022/ngneers-controls-splitter.mjs +141 -328
- package/fesm2022/ngneers-controls-splitter.mjs.map +1 -1
- package/fesm2022/ngneers-controls-switch.mjs +3 -3
- package/fesm2022/ngneers-controls-table.mjs +1520 -80
- package/fesm2022/ngneers-controls-table.mjs.map +1 -1
- package/fesm2022/ngneers-controls-tabs.mjs +40 -39
- package/fesm2022/ngneers-controls-tabs.mjs.map +1 -1
- package/fesm2022/ngneers-controls-tag.mjs +4 -4
- package/fesm2022/ngneers-controls-tag.mjs.map +1 -1
- package/fesm2022/ngneers-controls-toast.mjs +18 -18
- package/fesm2022/ngneers-controls-toast.mjs.map +1 -1
- package/fesm2022/ngneers-controls-toggle-button.mjs +9 -9
- package/fesm2022/ngneers-controls-toggle-button.mjs.map +1 -1
- package/fesm2022/ngneers-controls-tooltip.mjs +37 -45
- package/fesm2022/ngneers-controls-tooltip.mjs.map +1 -1
- package/fesm2022/ngneers-controls-utils-ng.mjs +9 -9
- package/fesm2022/ngneers-controls-utils-ng.mjs.map +1 -1
- package/package.json +14 -10
- package/types/ngneers-controls-api-ng.d.ts +2 -2
- package/types/ngneers-controls-api-resize.d.ts +318 -0
- package/types/ngneers-controls-base.d.ts +8 -0
- package/types/ngneers-controls-breadcrumb.d.ts +1 -1
- package/types/ngneers-controls-button.d.ts +13 -8
- package/types/ngneers-controls-calendar.d.ts +5 -1
- package/types/ngneers-controls-checkbox.d.ts +1 -1
- package/types/ngneers-controls-directives.d.ts +7 -1
- package/types/ngneers-controls-drawer.d.ts +4 -0
- package/types/ngneers-controls-edit-inplace.d.ts +4 -0
- package/types/ngneers-controls-filter.d.ts +53 -4
- package/types/ngneers-controls-i18n.d.ts +4 -0
- package/types/ngneers-controls-icon.d.ts +1 -1
- package/types/ngneers-controls-input-field.d.ts +4 -0
- package/types/ngneers-controls-input.d.ts +1 -1
- package/types/ngneers-controls-list-box.d.ts +5 -1
- package/types/ngneers-controls-menu.d.ts +1 -1
- package/types/ngneers-controls-paginator.d.ts +4 -0
- package/types/ngneers-controls-popover.d.ts +1 -1
- package/types/ngneers-controls-scroller.d.ts +12 -2
- package/types/ngneers-controls-select.d.ts +6 -2
- package/types/ngneers-controls-spinner.d.ts +1 -1
- package/types/ngneers-controls-splitter.d.ts +29 -59
- package/types/ngneers-controls-table.d.ts +392 -24
- package/types/ngneers-controls-toast.d.ts +1 -1
- package/types/ngneers-controls-tooltip.d.ts +1 -7
- package/fesm2022/ngneers-controls-i18n-de-CdTPeBiR.mjs.map +0 -1
- package/fesm2022/ngneers-controls-i18n-en-Cfp2pOLY.mjs.map +0 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, model, computed, ChangeDetectionStrategy, Component,
|
|
2
|
+
import { input, model, computed, ChangeDetectionStrategy, Component, signal, inject, ViewContainerRef, output, viewChild, contentChildren, untracked, runInInjectionContext, afterRenderEffect, NgModule } from '@angular/core';
|
|
3
3
|
import { NgnBase, provideSelf, NgnPt } from '@ngneers/controls/base';
|
|
4
4
|
import { generateElementId, registerState } from '@ngneers/controls/utils-ng';
|
|
5
5
|
import { splitterControlTemplate } from '@ngneers/controls-themes/templates/splitter';
|
|
6
6
|
import { NGN_CONFIG, templateTypeFn, elementSizeSignal, NgnTemplate } from '@ngneers/controls/api/ng';
|
|
7
7
|
import { I18n } from '@ngneers/controls/i18n';
|
|
8
8
|
import { throwExp, Logger, NgnError } from '@ngneers/controls/utils';
|
|
9
|
+
import { ResizeEngine } from '@ngneers/controls/api/resize';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* @category control
|
|
@@ -13,17 +14,17 @@ import { throwExp, Logger, NgnError } from '@ngneers/controls/utils';
|
|
|
13
14
|
class NgnSplitterPanel extends NgnBase {
|
|
14
15
|
theme = this.injectThemeTemplate(splitterControlTemplate, 'panel');
|
|
15
16
|
_fallbackAreaName = generateElementId();
|
|
16
|
-
name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
|
|
17
|
-
size = model('1fr', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
18
|
-
minSize = model('0px', ...(ngDevMode ? [{ debugName: "minSize" }] : []));
|
|
19
|
-
maxSize = model('100%', ...(ngDevMode ? [{ debugName: "maxSize" }] : []));
|
|
20
|
-
ariaLabel = input(...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : []));
|
|
21
|
-
ariaLabelledBy = input(...(ngDevMode ? [undefined, { debugName: "ariaLabelledBy" }] : []));
|
|
22
|
-
gridArea = computed(() => this.name() ?? this._fallbackAreaName, ...(ngDevMode ? [{ debugName: "gridArea" }] : []));
|
|
23
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
24
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.
|
|
17
|
+
name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : /* istanbul ignore next */ []));
|
|
18
|
+
size = model('1fr', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
19
|
+
minSize = model('0px', ...(ngDevMode ? [{ debugName: "minSize" }] : /* istanbul ignore next */ []));
|
|
20
|
+
maxSize = model('100%', ...(ngDevMode ? [{ debugName: "maxSize" }] : /* istanbul ignore next */ []));
|
|
21
|
+
ariaLabel = input(...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
22
|
+
ariaLabelledBy = input(...(ngDevMode ? [undefined, { debugName: "ariaLabelledBy" }] : /* istanbul ignore next */ []));
|
|
23
|
+
gridArea = computed(() => this.name() ?? this._fallbackAreaName, ...(ngDevMode ? [{ debugName: "gridArea" }] : /* istanbul ignore next */ []));
|
|
24
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: NgnSplitterPanel, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
25
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.2", type: NgnSplitterPanel, isStandalone: true, selector: "ngn-splitter-panel", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, minSize: { classPropertyName: "minSize", publicName: "minSize", isSignal: true, isRequired: false, transformFunction: null }, maxSize: { classPropertyName: "maxSize", publicName: "maxSize", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "ariaLabelledBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { size: "sizeChange", minSize: "minSizeChange", maxSize: "maxSizeChange" }, host: { attributes: { "role": "region" }, properties: { "style.grid-area": "gridArea()", "aria-label": "ariaLabel()", "attr.aria-labelledby": "ariaLabelledBy()" } }, providers: [provideSelf(NgnSplitterPanel)], usesInheritance: true, ngImport: i0, template: "<ng-content />\r\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
25
26
|
}
|
|
26
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
27
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: NgnSplitterPanel, decorators: [{
|
|
27
28
|
type: Component,
|
|
28
29
|
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'ngn-splitter-panel', providers: [provideSelf(NgnSplitterPanel)], host: {
|
|
29
30
|
role: 'region',
|
|
@@ -33,65 +34,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
|
|
|
33
34
|
}, template: "<ng-content />\r\n" }]
|
|
34
35
|
}], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }, { type: i0.Output, args: ["sizeChange"] }], minSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "minSize", required: false }] }, { type: i0.Output, args: ["minSizeChange"] }], maxSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSize", required: false }] }, { type: i0.Output, args: ["maxSizeChange"] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaLabelledBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelledBy", required: false }] }] } });
|
|
35
36
|
|
|
36
|
-
function isSplitterPanelSize(value) {
|
|
37
|
-
if (typeof value !== 'string')
|
|
38
|
-
return false;
|
|
39
|
-
const m = value.match(/^(.+)(px|fr)$/);
|
|
40
|
-
if (!m || !m[1])
|
|
41
|
-
return false;
|
|
42
|
-
if (isNaN(parseFloat(m[1])))
|
|
43
|
-
return false;
|
|
44
|
-
return true;
|
|
45
|
-
}
|
|
46
|
-
function getSplitterPanelSizeUnit(value) {
|
|
47
|
-
return value.slice(-2);
|
|
48
|
-
}
|
|
49
|
-
function getSplitterPanelSizeValue(value) {
|
|
50
|
-
return parseFloat(value.slice(0, -2));
|
|
51
|
-
}
|
|
52
|
-
function isSplitterPanelSizeLimit(value) {
|
|
53
|
-
if (typeof value !== 'string')
|
|
54
|
-
return false;
|
|
55
|
-
const m = value.match(/^(.+)(px|%)$/);
|
|
56
|
-
if (!m || !m[1])
|
|
57
|
-
return false;
|
|
58
|
-
if (isNaN(parseFloat(m[1])))
|
|
59
|
-
return false;
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
|
-
function getSplitterPanelSizeLimitUnit(value) {
|
|
63
|
-
return value.endsWith('px') ? 'px' : '%';
|
|
64
|
-
}
|
|
65
|
-
function getSplitterPanelSizeLimitValue(value) {
|
|
66
|
-
return value.endsWith('px') ? parseFloat(value.slice(0, -2)) : parseFloat(value.slice(0, -1));
|
|
67
|
-
}
|
|
68
|
-
function getSplitterPanelSizeLimitInPx(value, totalSize) {
|
|
69
|
-
const unit = getSplitterPanelSizeLimitUnit(value);
|
|
70
|
-
const sizeValue = getSplitterPanelSizeLimitValue(value);
|
|
71
|
-
return unit === 'px' ? sizeValue : (sizeValue / 100) * totalSize;
|
|
72
|
-
}
|
|
73
|
-
function expandSplitterPanelSize(value) {
|
|
74
|
-
return {
|
|
75
|
-
value: getSplitterPanelSizeValue(value),
|
|
76
|
-
unit: getSplitterPanelSizeUnit(value),
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
function expandSplitterPanelSizeLimit(value) {
|
|
80
|
-
return {
|
|
81
|
-
value: getSplitterPanelSizeLimitValue(value),
|
|
82
|
-
unit: getSplitterPanelSizeLimitUnit(value),
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
function collapseSplitterPanelSize(size) {
|
|
86
|
-
return `${size.value}${size.unit}`;
|
|
87
|
-
}
|
|
88
|
-
function collapseSplitterPanelSizeLimit(size) {
|
|
89
|
-
return `${size.value}${size.unit}`;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const LAST_CALC_SIZE_SYMBOL = Symbol('lastCalcSize');
|
|
93
37
|
/**
|
|
94
38
|
* Default implementation of the {@link SplitterCalculator} interface.
|
|
39
|
+
* Delegates all resize math to the generic {@link ResizeEngine}.
|
|
95
40
|
*/
|
|
96
41
|
class DefaultSplitterCalculator {
|
|
97
42
|
panels;
|
|
@@ -99,21 +44,21 @@ class DefaultSplitterCalculator {
|
|
|
99
44
|
panelOrder;
|
|
100
45
|
layout;
|
|
101
46
|
splitterSize;
|
|
47
|
+
_engine;
|
|
102
48
|
constructor(splitter) {
|
|
103
49
|
this.panels = splitter.panels;
|
|
104
50
|
this.dividers = splitter.dividers;
|
|
105
51
|
this.panelOrder = splitter.panelOrder;
|
|
106
52
|
this.layout = splitter.layout;
|
|
107
|
-
this.splitterSize = computed(() => this.layout() === 'vertical' ? splitter.elementSize().height : splitter.elementSize().width, ...(ngDevMode ? [{ debugName: "splitterSize" }] : []));
|
|
108
|
-
//
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
untracked(() => this.ensureMinMaxSizes());
|
|
53
|
+
this.splitterSize = computed(() => this.layout() === 'vertical' ? splitter.elementSize().height : splitter.elementSize().width, ...(ngDevMode ? [{ debugName: "splitterSize" }] : /* istanbul ignore next */ []));
|
|
54
|
+
// Create the resize engine with panels mapped as ResizableItems
|
|
55
|
+
this._engine = new ResizeEngine({
|
|
56
|
+
items: computed(() => this.orderedPanels()),
|
|
57
|
+
containerSize: this.splitterSize,
|
|
58
|
+
gapSizes: this.dividerSizes,
|
|
59
|
+
distributionMode: computed(() => (splitter.resizeMode?.() ?? 'adjacent')),
|
|
60
|
+
containerConstrained: signal(true), // Splitter is always constrained
|
|
61
|
+
lockSizes: computed(() => splitter.lockSizes?.() ?? false),
|
|
117
62
|
});
|
|
118
63
|
}
|
|
119
64
|
orderedPanels = computed(() => {
|
|
@@ -126,29 +71,14 @@ class DefaultSplitterCalculator {
|
|
|
126
71
|
if (aIndex === -1 && bIndex === -1)
|
|
127
72
|
return 0;
|
|
128
73
|
if (aIndex === -1)
|
|
129
|
-
return 1;
|
|
74
|
+
return 1;
|
|
130
75
|
if (bIndex === -1)
|
|
131
|
-
return -1;
|
|
132
|
-
return aIndex - bIndex;
|
|
76
|
+
return -1;
|
|
77
|
+
return aIndex - bIndex;
|
|
133
78
|
})
|
|
134
79
|
: panels;
|
|
135
|
-
}, ...(ngDevMode ? [{ debugName: "orderedPanels" }] : []));
|
|
136
|
-
gridTemplateSizes = computed(() => {
|
|
137
|
-
const panels = this.orderedPanels();
|
|
138
|
-
const dividerSizes = this.dividerSizes();
|
|
139
|
-
if (panels.length === 0)
|
|
140
|
-
return 'none';
|
|
141
|
-
const result = [];
|
|
142
|
-
panels.forEach((panel, i) => {
|
|
143
|
-
const size = panel.size();
|
|
144
|
-
result.push(size);
|
|
145
|
-
if (i < dividerSizes.length) {
|
|
146
|
-
const dividerSize = dividerSizes[i] || 0;
|
|
147
|
-
result.push(`${dividerSize}px`);
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
return result.join(' ');
|
|
151
|
-
}, ...(ngDevMode ? [{ debugName: "gridTemplateSizes" }] : []));
|
|
80
|
+
}, ...(ngDevMode ? [{ debugName: "orderedPanels" }] : /* istanbul ignore next */ []));
|
|
81
|
+
gridTemplateSizes = computed(() => this._engine.gridTemplateSizes(), ...(ngDevMode ? [{ debugName: "gridTemplateSizes" }] : /* istanbul ignore next */ []));
|
|
152
82
|
gridTemplateAreas = computed(() => {
|
|
153
83
|
const panels = this.orderedPanels();
|
|
154
84
|
if (panels.length === 0)
|
|
@@ -162,80 +92,38 @@ class DefaultSplitterCalculator {
|
|
|
162
92
|
result += this.layout() === 'horizontal' ? panel['gridArea']() : `"${panel['gridArea']()}"`;
|
|
163
93
|
});
|
|
164
94
|
return this.layout() === 'horizontal' ? `"${result}"` : result;
|
|
165
|
-
}, ...(ngDevMode ? [{ debugName: "gridTemplateAreas" }] : []));
|
|
166
|
-
minSize = computed(() => {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if (getSplitterPanelSizeUnit(size) === 'px') {
|
|
170
|
-
acc.px += getSplitterPanelSizeValue(size);
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
const minSize = panel.minSize();
|
|
174
|
-
acc[getSplitterPanelSizeLimitUnit(minSize)] += getSplitterPanelSizeLimitValue(minSize);
|
|
175
|
-
}
|
|
176
|
-
return acc;
|
|
177
|
-
}, { px: 0, '%': 0 });
|
|
178
|
-
return `calc(${px + this.totalDividerSize()}px + ${pc}%)`;
|
|
179
|
-
}, ...(ngDevMode ? [{ debugName: "minSize" }] : []));
|
|
180
|
-
maxSize = computed(() => {
|
|
181
|
-
const { px, '%': pc } = this.panels().reduce((acc, panel) => {
|
|
182
|
-
const size = panel.size();
|
|
183
|
-
if (getSplitterPanelSizeUnit(size) === 'px') {
|
|
184
|
-
acc.px += getSplitterPanelSizeValue(size);
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
const maxSize = panel.maxSize();
|
|
188
|
-
acc[getSplitterPanelSizeLimitUnit(maxSize)] += getSplitterPanelSizeLimitValue(maxSize);
|
|
189
|
-
}
|
|
190
|
-
return acc;
|
|
191
|
-
}, { px: 0, '%': 0 });
|
|
192
|
-
return `calc(${px + this.totalDividerSize()}px + ${pc}%)`;
|
|
193
|
-
}, ...(ngDevMode ? [{ debugName: "maxSize" }] : []));
|
|
194
|
-
dragContext = signal(null, ...(ngDevMode ? [{ debugName: "dragContext" }] : []));
|
|
95
|
+
}, ...(ngDevMode ? [{ debugName: "gridTemplateAreas" }] : /* istanbul ignore next */ []));
|
|
96
|
+
minSize = computed(() => this._engine.minTotalSize(), ...(ngDevMode ? [{ debugName: "minSize" }] : /* istanbul ignore next */ []));
|
|
97
|
+
maxSize = computed(() => this._engine.maxTotalSize(), ...(ngDevMode ? [{ debugName: "maxSize" }] : /* istanbul ignore next */ []));
|
|
98
|
+
dragContext = signal(null, ...(ngDevMode ? [{ debugName: "dragContext" }] : /* istanbul ignore next */ []));
|
|
195
99
|
dividerSizes = computed(() => this.dividers().map(d => {
|
|
196
100
|
const el = d.rootNodes.find(x => x instanceof HTMLElement);
|
|
197
101
|
return el ? (this.layout() === 'horizontal' ? el.offsetWidth : el.offsetHeight) : 0;
|
|
198
|
-
}), ...(ngDevMode ? [{ debugName: "dividerSizes" }] : []));
|
|
199
|
-
totalDividerSize = computed(() => this.dividerSizes().reduce((acc, size) => acc + size, 0), ...(ngDevMode ? [{ debugName: "totalDividerSize" }] : []));
|
|
200
|
-
totalPanelSizes = computed(() => this.panels().reduce((acc, panel) => {
|
|
201
|
-
const size = panel.size();
|
|
202
|
-
acc[getSplitterPanelSizeUnit(size)] += getSplitterPanelSizeValue(size);
|
|
203
|
-
return acc;
|
|
204
|
-
}, { px: 0, fr: 0 }), ...(ngDevMode ? [{ debugName: "totalPanelSizes" }] : []));
|
|
102
|
+
}), ...(ngDevMode ? [{ debugName: "dividerSizes" }] : /* istanbul ignore next */ []));
|
|
205
103
|
startDrag(index, event) {
|
|
206
104
|
const panels = this.orderedPanels();
|
|
207
105
|
if (index < 0 || index >= panels.length - 1)
|
|
208
106
|
return;
|
|
107
|
+
const startPosition = this.layout() === 'horizontal' ? event.clientX : event.clientY;
|
|
209
108
|
this.dragContext.set({
|
|
210
109
|
dividerIndex: index,
|
|
211
110
|
pointerId: event.pointerId,
|
|
212
|
-
startPosition
|
|
213
|
-
panels: panels.map(panel => this.createContextPanel(panel)),
|
|
214
|
-
fractionFactors: this.getCurrentFractionFactors(),
|
|
111
|
+
startPosition,
|
|
215
112
|
});
|
|
113
|
+
this._engine.startDrag(index, startPosition);
|
|
216
114
|
}
|
|
217
115
|
drag(index, event) {
|
|
218
116
|
const ctx = this.dragContext();
|
|
219
117
|
if (!ctx || ctx.dividerIndex !== index || ctx.pointerId !== event.pointerId)
|
|
220
118
|
return;
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
if (this.layout() === 'horizontal') {
|
|
224
|
-
pxDelta = event.clientX - startPosition;
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
pxDelta = event.clientY - startPosition;
|
|
228
|
-
}
|
|
229
|
-
this.applyDividerDelta(index, pxDelta, ctx.panels, ctx.fractionFactors);
|
|
119
|
+
const currentPosition = this.layout() === 'horizontal' ? event.clientX : event.clientY;
|
|
120
|
+
this._engine.drag(index, currentPosition);
|
|
230
121
|
}
|
|
231
122
|
endDrag(index, event, isCancel) {
|
|
232
123
|
const ctx = this.dragContext();
|
|
233
124
|
if (!ctx || ctx.dividerIndex !== index || ctx.pointerId !== event.pointerId)
|
|
234
125
|
return;
|
|
235
|
-
|
|
236
|
-
// Reset the panels to their original sizes
|
|
237
|
-
ctx.panels.forEach(p => p.panel.size.set(`${p.startSize.value}${p.startSize.unit}`));
|
|
238
|
-
}
|
|
126
|
+
this._engine.endDrag(index, isCancel);
|
|
239
127
|
this.dragContext.set(null);
|
|
240
128
|
}
|
|
241
129
|
moveDivider(index, pxDelta) {
|
|
@@ -246,171 +134,82 @@ class DefaultSplitterCalculator {
|
|
|
246
134
|
throwExp('NgnSplitterCalculator', `Left panel is missing for divider at index ${index}`);
|
|
247
135
|
const rightPanel = panels[index + 1] ??
|
|
248
136
|
throwExp('NgnSplitterCalculator', `Right panel is missing for divider at index ${index}`);
|
|
249
|
-
|
|
250
|
-
|
|
137
|
+
if (!this._engine.isItemSizeCalculated(leftPanel) ||
|
|
138
|
+
!this._engine.isItemSizeCalculated(rightPanel)) {
|
|
251
139
|
Logger.warn('Cannot move divider, panel sizes are not calculated');
|
|
252
140
|
return;
|
|
253
141
|
}
|
|
254
|
-
this.
|
|
142
|
+
this._engine.moveDivider(index, pxDelta);
|
|
255
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* Ensures all panels respect their min/max size constraints.
|
|
146
|
+
* Delegates to the underlying {@link ResizeEngine}.
|
|
147
|
+
*/
|
|
256
148
|
ensureMinMaxSizes() {
|
|
257
|
-
|
|
258
|
-
if (panels.length === 0)
|
|
259
|
-
return;
|
|
260
|
-
const panelSizes = panels.map(panel => {
|
|
261
|
-
return {
|
|
262
|
-
panel,
|
|
263
|
-
size: {
|
|
264
|
-
unit: getSplitterPanelSizeUnit(panel.size()),
|
|
265
|
-
value: getSplitterPanelSizeValue(panel.size()),
|
|
266
|
-
},
|
|
267
|
-
minSizePx: getSplitterPanelSizeLimitInPx(panel.minSize(), this.splitterSize()),
|
|
268
|
-
maxSizePx: getSplitterPanelSizeLimitInPx(panel.maxSize(), this.splitterSize()),
|
|
269
|
-
};
|
|
270
|
-
});
|
|
271
|
-
// First make sure all px sizes are in the limits
|
|
272
|
-
for (const { size, minSizePx, maxSizePx } of panelSizes) {
|
|
273
|
-
if (size.unit === 'px') {
|
|
274
|
-
if (size.value < minSizePx) {
|
|
275
|
-
size.value = minSizePx;
|
|
276
|
-
}
|
|
277
|
-
else if (size.value > maxSizePx) {
|
|
278
|
-
size.value = maxSizePx;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
// Calculate the fraction factors
|
|
283
|
-
const totalPanelSizes = panelSizes.reduce((acc, { size }) => {
|
|
284
|
-
acc[size.unit] += size.value;
|
|
285
|
-
return acc;
|
|
286
|
-
}, { px: 0, fr: 0 });
|
|
287
|
-
const frArea = this.splitterSize() - this.totalDividerSize() - totalPanelSizes.px;
|
|
288
|
-
const frPerPx = totalPanelSizes.fr / frArea;
|
|
289
|
-
const pxPerFr = frArea / totalPanelSizes.fr;
|
|
290
|
-
// Now make sure all fr sizes are in the limits
|
|
291
|
-
// We need to do this in a loop because we might need to adjust the fr sizes multiple times
|
|
292
|
-
// until all panels are within their limits while distributing the over-/underflow evenly
|
|
293
|
-
let frPanelsWithoutClamping = panelSizes.filter(p => p.size.unit === 'fr');
|
|
294
|
-
let frToDistribute = undefined; // Not needed initially
|
|
295
|
-
while (frPanelsWithoutClamping.length > 0 && frToDistribute !== 0) {
|
|
296
|
-
const frToAddPerPanel = frToDistribute ? frToDistribute / frPanelsWithoutClamping.length : 0;
|
|
297
|
-
const next = []; // Track panels that are still within limits
|
|
298
|
-
let currentTotalFrSize = totalPanelSizes.fr; // Track the total fr size after clamping
|
|
299
|
-
for (const p of frPanelsWithoutClamping) {
|
|
300
|
-
const minSizeFr = p.minSizePx * frPerPx;
|
|
301
|
-
const maxSizeFr = p.maxSizePx * frPerPx;
|
|
302
|
-
p.size.value += frToAddPerPanel;
|
|
303
|
-
if (p.size.value < minSizeFr) {
|
|
304
|
-
currentTotalFrSize = currentTotalFrSize - p.size.value + minSizeFr;
|
|
305
|
-
p.size.value = minSizeFr;
|
|
306
|
-
}
|
|
307
|
-
else if (p.size.value > maxSizeFr) {
|
|
308
|
-
currentTotalFrSize = currentTotalFrSize - p.size.value + maxSizeFr;
|
|
309
|
-
p.size.value = maxSizeFr;
|
|
310
|
-
}
|
|
311
|
-
else {
|
|
312
|
-
next.push(p);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
frToDistribute = totalPanelSizes.fr - currentTotalFrSize;
|
|
316
|
-
if (Math.abs(frToDistribute * pxPerFr) < 1) {
|
|
317
|
-
frToDistribute = 0; // Stop if we are close enough to zero
|
|
318
|
-
}
|
|
319
|
-
frPanelsWithoutClamping = next;
|
|
320
|
-
}
|
|
321
|
-
// Now set all the new sizes to the panels
|
|
322
|
-
for (const { panel, size } of panelSizes) {
|
|
323
|
-
this.setPanelSize(panel, `${size.value}${size.unit}`);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
createContextPanel(panel) {
|
|
327
|
-
return {
|
|
328
|
-
panel,
|
|
329
|
-
startSize: expandSplitterPanelSize(panel.size()),
|
|
330
|
-
minSize: expandSplitterPanelSizeLimit(panel.minSize()),
|
|
331
|
-
maxSize: expandSplitterPanelSizeLimit(panel.maxSize()),
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
|
-
getCurrentFractionFactors() {
|
|
335
|
-
const frArea = this.splitterSize() - this.totalDividerSize() - this.totalPanelSizes().px || 1; // Avoid division by zero
|
|
336
|
-
const totalFr = this.totalPanelSizes().fr || 1; // Avoid division by zero
|
|
337
|
-
return {
|
|
338
|
-
frPerPx: totalFr / frArea,
|
|
339
|
-
pxPerFr: frArea / totalFr,
|
|
340
|
-
};
|
|
149
|
+
this._engine.ensureMinMaxSizes();
|
|
341
150
|
}
|
|
151
|
+
/** @internal — used by tests to seed panel sizes into the engine. */
|
|
342
152
|
setPanelSize(panel, size) {
|
|
343
|
-
|
|
344
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
345
|
-
panel[LAST_CALC_SIZE_SYMBOL] = size;
|
|
346
|
-
}
|
|
347
|
-
isPanelSizeCalculated(panel) {
|
|
348
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
349
|
-
return panel[LAST_CALC_SIZE_SYMBOL] === panel.size();
|
|
350
|
-
}
|
|
351
|
-
applyDividerDelta(dividerIndex, pxDelta, panels, fractionFactors) {
|
|
352
|
-
const appliedPanelDeltas = Array(panels.length).fill(0);
|
|
353
|
-
const recursion = (pxDelta, panelIndex, panelIndexIncrement) => {
|
|
354
|
-
if (panelIndex >= panels.length || panelIndex < 0)
|
|
355
|
-
return 0;
|
|
356
|
-
const panel = panels[panelIndex];
|
|
357
|
-
if (!panel) {
|
|
358
|
-
throw new NgnError('NgnSplitterCalculator', `Panel is missing at index ${panelIndex}`);
|
|
359
|
-
}
|
|
360
|
-
let unappliedDelta = 0;
|
|
361
|
-
const startPx = panel.startSize.unit === 'px'
|
|
362
|
-
? panel.startSize.value
|
|
363
|
-
: fractionFactors.pxPerFr * panel.startSize.value;
|
|
364
|
-
const newPx = startPx + pxDelta;
|
|
365
|
-
if (pxDelta < 0) {
|
|
366
|
-
const min = panel.minSize.unit === 'px'
|
|
367
|
-
? panel.minSize.value
|
|
368
|
-
: (panel.minSize.value / 100) * this.splitterSize();
|
|
369
|
-
if (min > newPx) {
|
|
370
|
-
unappliedDelta = -(min - newPx);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
else if (pxDelta > 0) {
|
|
374
|
-
const max = panel.maxSize.unit === 'px'
|
|
375
|
-
? panel.maxSize.value
|
|
376
|
-
: (panel.maxSize.value / 100) * this.splitterSize();
|
|
377
|
-
if (max < newPx) {
|
|
378
|
-
unappliedDelta = newPx - max;
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
const appliedDelta = pxDelta - unappliedDelta;
|
|
382
|
-
appliedPanelDeltas[panelIndex] = appliedDelta;
|
|
383
|
-
return unappliedDelta === 0
|
|
384
|
-
? pxDelta
|
|
385
|
-
: appliedDelta +
|
|
386
|
-
recursion(unappliedDelta, panelIndex + panelIndexIncrement, panelIndexIncrement);
|
|
387
|
-
};
|
|
388
|
-
let appliedLeft = recursion(pxDelta, dividerIndex, -1);
|
|
389
|
-
let appliedRight = -recursion(-pxDelta, dividerIndex + 1, 1);
|
|
390
|
-
if (appliedLeft !== pxDelta || appliedRight !== pxDelta) {
|
|
391
|
-
pxDelta =
|
|
392
|
-
pxDelta < 0 ? Math.max(appliedLeft, appliedRight) : Math.min(appliedLeft, appliedRight);
|
|
393
|
-
appliedPanelDeltas.fill(0);
|
|
394
|
-
appliedLeft = recursion(pxDelta, dividerIndex, -1);
|
|
395
|
-
appliedRight = -recursion(-pxDelta, dividerIndex + 1, 1);
|
|
396
|
-
if (appliedLeft !== pxDelta || appliedRight !== pxDelta) {
|
|
397
|
-
return;
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
panels.forEach((panel, i) => {
|
|
401
|
-
const pxDelta = appliedPanelDeltas[i] || 0;
|
|
402
|
-
if (panel.startSize.unit === 'px') {
|
|
403
|
-
const size = panel.startSize.value + pxDelta;
|
|
404
|
-
this.setPanelSize(panel.panel, `${Math.max(0, size)}px`);
|
|
405
|
-
}
|
|
406
|
-
else {
|
|
407
|
-
const size = panel.startSize.value + pxDelta * fractionFactors.frPerPx;
|
|
408
|
-
this.setPanelSize(panel.panel, `${Math.max(0, size)}fr`);
|
|
409
|
-
}
|
|
410
|
-
});
|
|
153
|
+
this._engine.setItemSize(panel, size);
|
|
411
154
|
}
|
|
412
155
|
}
|
|
413
156
|
|
|
157
|
+
function isSplitterPanelSize(value) {
|
|
158
|
+
if (typeof value !== 'string')
|
|
159
|
+
return false;
|
|
160
|
+
const m = value.match(/^(.+)(px|fr)$/);
|
|
161
|
+
if (!m || !m[1])
|
|
162
|
+
return false;
|
|
163
|
+
if (isNaN(parseFloat(m[1])))
|
|
164
|
+
return false;
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
function getSplitterPanelSizeUnit(value) {
|
|
168
|
+
return value.slice(-2);
|
|
169
|
+
}
|
|
170
|
+
function getSplitterPanelSizeValue(value) {
|
|
171
|
+
return parseFloat(value.slice(0, -2));
|
|
172
|
+
}
|
|
173
|
+
function isSplitterPanelSizeLimit(value) {
|
|
174
|
+
if (typeof value !== 'string')
|
|
175
|
+
return false;
|
|
176
|
+
const m = value.match(/^(.+)(px|%)$/);
|
|
177
|
+
if (!m || !m[1])
|
|
178
|
+
return false;
|
|
179
|
+
if (isNaN(parseFloat(m[1])))
|
|
180
|
+
return false;
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
function getSplitterPanelSizeLimitUnit(value) {
|
|
184
|
+
return value.endsWith('px') ? 'px' : '%';
|
|
185
|
+
}
|
|
186
|
+
function getSplitterPanelSizeLimitValue(value) {
|
|
187
|
+
return value.endsWith('px') ? parseFloat(value.slice(0, -2)) : parseFloat(value.slice(0, -1));
|
|
188
|
+
}
|
|
189
|
+
function getSplitterPanelSizeLimitInPx(value, totalSize) {
|
|
190
|
+
const unit = getSplitterPanelSizeLimitUnit(value);
|
|
191
|
+
const sizeValue = getSplitterPanelSizeLimitValue(value);
|
|
192
|
+
return unit === 'px' ? sizeValue : (sizeValue / 100) * totalSize;
|
|
193
|
+
}
|
|
194
|
+
function expandSplitterPanelSize(value) {
|
|
195
|
+
return {
|
|
196
|
+
value: getSplitterPanelSizeValue(value),
|
|
197
|
+
unit: getSplitterPanelSizeUnit(value),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
function expandSplitterPanelSizeLimit(value) {
|
|
201
|
+
return {
|
|
202
|
+
value: getSplitterPanelSizeLimitValue(value),
|
|
203
|
+
unit: getSplitterPanelSizeLimitUnit(value),
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
function collapseSplitterPanelSize(size) {
|
|
207
|
+
return `${size.value}${size.unit}`;
|
|
208
|
+
}
|
|
209
|
+
function collapseSplitterPanelSizeLimit(size) {
|
|
210
|
+
return `${size.value}${size.unit}`;
|
|
211
|
+
}
|
|
212
|
+
|
|
414
213
|
/**
|
|
415
214
|
* @category control
|
|
416
215
|
*/
|
|
@@ -427,22 +226,22 @@ class NgnSplitter extends NgnBase {
|
|
|
427
226
|
/**
|
|
428
227
|
* The layout of the splitter.
|
|
429
228
|
*/
|
|
430
|
-
layout = model.required(...(ngDevMode ? [{ debugName: "layout" }] : []));
|
|
229
|
+
layout = model.required(...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
|
|
431
230
|
/**
|
|
432
231
|
* A array of panel names that defines the order of panels.
|
|
433
232
|
* If nullish, the order is determined by the order the panels are defined in the template.
|
|
434
233
|
*/
|
|
435
|
-
panelOrder = model(...(ngDevMode ? [undefined, { debugName: "panelOrder" }] : []));
|
|
234
|
+
panelOrder = model(...(ngDevMode ? [undefined, { debugName: "panelOrder" }] : /* istanbul ignore next */ []));
|
|
436
235
|
/**
|
|
437
236
|
* The storage to use for saving the splitter state.
|
|
438
237
|
* @default `session`
|
|
439
238
|
*/
|
|
440
|
-
stateStorage = input(this._config.defaults.splitter.stateStorage, ...(ngDevMode ? [{ debugName: "stateStorage" }] : []));
|
|
239
|
+
stateStorage = input(this._config.defaults.splitter.stateStorage, ...(ngDevMode ? [{ debugName: "stateStorage" }] : /* istanbul ignore next */ []));
|
|
441
240
|
/**
|
|
442
241
|
* The key to use for saving the splitter state.
|
|
443
242
|
* If nullish, the state will not be saved.
|
|
444
243
|
*/
|
|
445
|
-
stateKey = input(...(ngDevMode ? [undefined, { debugName: "stateKey" }] : []));
|
|
244
|
+
stateKey = input(...(ngDevMode ? [undefined, { debugName: "stateKey" }] : /* istanbul ignore next */ []));
|
|
446
245
|
/**
|
|
447
246
|
* The type of data to save in the splitter state.
|
|
448
247
|
* @default `['layout', 'panelOrder', 'panelSizes']`
|
|
@@ -451,19 +250,32 @@ class NgnSplitter extends NgnBase {
|
|
|
451
250
|
'layout',
|
|
452
251
|
'panelOrder',
|
|
453
252
|
'panelSizes',
|
|
454
|
-
], ...(ngDevMode ? [{ debugName: "stateData" }] : []));
|
|
253
|
+
], ...(ngDevMode ? [{ debugName: "stateData" }] : /* istanbul ignore next */ []));
|
|
455
254
|
/**
|
|
456
255
|
* The type of calculator to use for the splitter.
|
|
457
256
|
* @default `DefaultSplitterCalculator`
|
|
458
257
|
*/
|
|
459
|
-
calculatorType = input(DefaultSplitterCalculator, ...(ngDevMode ? [{ debugName: "calculatorType" }] : []));
|
|
258
|
+
calculatorType = input(DefaultSplitterCalculator, ...(ngDevMode ? [{ debugName: "calculatorType" }] : /* istanbul ignore next */ []));
|
|
259
|
+
/**
|
|
260
|
+
* The resize distribution mode for the splitter.
|
|
261
|
+
* - `'adjacent'` (default): Only the panels adjacent to the divider are resized.
|
|
262
|
+
* - `'proportional'`: The deficit is distributed proportionally across all panels on the other side.
|
|
263
|
+
*/
|
|
264
|
+
resizeMode = input('adjacent', ...(ngDevMode ? [{ debugName: "resizeMode" }] : /* istanbul ignore next */ []));
|
|
265
|
+
/**
|
|
266
|
+
* Whether to lock affected panels to fixed `px` values after a resize completes.
|
|
267
|
+
* When `true`, panels whose size changed are converted from their original unit to `px`.
|
|
268
|
+
* When `false`, panels keep their original units (`fr`, `px`).
|
|
269
|
+
* @default false
|
|
270
|
+
*/
|
|
271
|
+
lockSizes = input(false, ...(ngDevMode ? [{ debugName: "lockSizes" }] : /* istanbul ignore next */ []));
|
|
460
272
|
/**
|
|
461
273
|
* The step size for moving the dividers using the keyboard.
|
|
462
274
|
* This can be a pixel value (e.g., '5px') or a percentage value (e.g., '5%').
|
|
463
275
|
* If a percentage is used, it will be calculated based on the size of the splitter element.
|
|
464
276
|
* @default '5px'
|
|
465
277
|
*/
|
|
466
|
-
step = input('5px', ...(ngDevMode ? [{ debugName: "step" }] : []));
|
|
278
|
+
step = input('5px', ...(ngDevMode ? [{ debugName: "step" }] : /* istanbul ignore next */ []));
|
|
467
279
|
/**
|
|
468
280
|
* Event emitted when the splitter state is being saved.
|
|
469
281
|
* This can be used to modify the state before it is saved.
|
|
@@ -479,11 +291,11 @@ class NgnSplitter extends NgnBase {
|
|
|
479
291
|
/**
|
|
480
292
|
* The current dividers in the splitter.
|
|
481
293
|
*/
|
|
482
|
-
dividers = signal([], ...(ngDevMode ? [{ debugName: "dividers" }] : []));
|
|
294
|
+
dividers = signal([], ...(ngDevMode ? [{ debugName: "dividers" }] : /* istanbul ignore next */ []));
|
|
483
295
|
/**
|
|
484
296
|
* The current panels in the splitter.
|
|
485
297
|
*/
|
|
486
|
-
panels = contentChildren(NgnSplitterPanel, ...(ngDevMode ? [{ debugName: "panels" }] : []));
|
|
298
|
+
panels = contentChildren(NgnSplitterPanel, ...(ngDevMode ? [{ debugName: "panels" }] : /* istanbul ignore next */ []));
|
|
487
299
|
/**
|
|
488
300
|
* The current size of the splitter element.
|
|
489
301
|
*/
|
|
@@ -491,11 +303,11 @@ class NgnSplitter extends NgnBase {
|
|
|
491
303
|
/**
|
|
492
304
|
* A value indicating whether the splitter is currently being dragged.
|
|
493
305
|
*/
|
|
494
|
-
isDragging = computed(() => this.calculator().dragContext() !== null, ...(ngDevMode ? [{ debugName: "isDragging" }] : []));
|
|
306
|
+
isDragging = computed(() => this.calculator().dragContext() !== null, ...(ngDevMode ? [{ debugName: "isDragging" }] : /* istanbul ignore next */ []));
|
|
495
307
|
calculator = computed(() => {
|
|
496
308
|
const calculatorType = this.calculatorType();
|
|
497
309
|
return untracked(() => runInInjectionContext(this.injector, () => new calculatorType(this)));
|
|
498
|
-
}, ...(ngDevMode ? [{ debugName: "calculator" }] : []));
|
|
310
|
+
}, ...(ngDevMode ? [{ debugName: "calculator" }] : /* istanbul ignore next */ []));
|
|
499
311
|
constructor() {
|
|
500
312
|
super();
|
|
501
313
|
afterRenderEffect(() => {
|
|
@@ -579,14 +391,15 @@ class NgnSplitter extends NgnBase {
|
|
|
579
391
|
return divider.slice(0, panels.length - 1);
|
|
580
392
|
}
|
|
581
393
|
});
|
|
582
|
-
// Move dividers to the correct positions
|
|
583
|
-
panels.
|
|
394
|
+
// Move dividers to the correct positions (skip first panel — no divider before it)
|
|
395
|
+
for (let i = 1; i < panels.length; i++) {
|
|
396
|
+
const panel = panels[i];
|
|
584
397
|
const divider = this.dividers()[i - 1];
|
|
585
398
|
if (!divider) {
|
|
586
399
|
throw new NgnError('NgnSplitter', `Divider is missing for panel at index ${i}`);
|
|
587
400
|
}
|
|
588
401
|
this.moveDividerBefore(panel, divider);
|
|
589
|
-
}
|
|
402
|
+
}
|
|
590
403
|
}
|
|
591
404
|
createDivider(index) {
|
|
592
405
|
const viewRef = this._viewContainer.createEmbeddedView(this._dividerTemplate(), { index });
|
|
@@ -677,10 +490,10 @@ class NgnSplitter extends NgnBase {
|
|
|
677
490
|
return 10; // Default step in pixels
|
|
678
491
|
}
|
|
679
492
|
}
|
|
680
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
681
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.
|
|
493
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: NgnSplitter, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
494
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.2", type: NgnSplitter, isStandalone: true, selector: "ngn-splitter", inputs: { layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null }, panelOrder: { classPropertyName: "panelOrder", publicName: "panelOrder", isSignal: true, isRequired: false, transformFunction: null }, stateStorage: { classPropertyName: "stateStorage", publicName: "stateStorage", isSignal: true, isRequired: false, transformFunction: null }, stateKey: { classPropertyName: "stateKey", publicName: "stateKey", isSignal: true, isRequired: false, transformFunction: null }, stateData: { classPropertyName: "stateData", publicName: "stateData", isSignal: true, isRequired: false, transformFunction: null }, calculatorType: { classPropertyName: "calculatorType", publicName: "calculatorType", isSignal: true, isRequired: false, transformFunction: null }, resizeMode: { classPropertyName: "resizeMode", publicName: "resizeMode", isSignal: true, isRequired: false, transformFunction: null }, lockSizes: { classPropertyName: "lockSizes", publicName: "lockSizes", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { layout: "layoutChange", panelOrder: "panelOrderChange", stateSaving: "stateSaving", stateLoading: "stateLoading" }, host: { attributes: { "role": "region" }, properties: { "style.grid-template-columns": "layout() === 'horizontal' ? calculator().gridTemplateSizes() : null", "style.grid-template-rows": "layout() === 'vertical' ? calculator().gridTemplateSizes() : null", "style.grid-template-areas": "calculator().gridTemplateAreas()", "style.max-width": "layout() === 'horizontal' ? calculator().maxSize() : null", "style.max-height": "layout() === 'vertical' ? calculator().maxSize() : null", "style.min-width": "layout() === 'horizontal' ? calculator().minSize() : null", "style.min-height": "layout() === 'vertical' ? calculator().minSize() : null" } }, providers: [provideSelf(NgnSplitter)], queries: [{ propertyName: "panels", predicate: NgnSplitterPanel, isSignal: true }], viewQueries: [{ propertyName: "_dividerTemplate", first: true, predicate: ["defaultDividerTemplate"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ng-content />\r\n\r\n<ng-template #defaultDividerTemplate [ngnTemplate]=\"dividerTemplateType\" let-index=\"index\">\r\n <div\r\n [style.grid-area]=\"`ngn-divider-${index}`\"\r\n [ptInt]=\"this\"\r\n [ptClass]=\"{\r\n divider: true,\r\n 'divider-dragging': calculator().dragContext()?.dividerIndex === index,\r\n }\"\r\n >\r\n <button\r\n role=\"separator\"\r\n [aria-orientation]=\"layout()\"\r\n [aria-label]=\"translations['splitter_handleLabel']()\"\r\n [ptInt]=\"this\"\r\n [ptClass]=\"'divider-handle'\"\r\n (pointerdown)=\"onHandlePointerDown(index, $event)\"\r\n (pointermove)=\"onHandlePointerMove(index, $event)\"\r\n (pointerup)=\"onHandlePointerUp(index, $event)\"\r\n (pointercancel)=\"onHandlePointerCancel(index, $event)\"\r\n (keydown)=\"onHandleKeyDown(index, $event)\"\r\n ></button>\r\n </div>\r\n</ng-template>\r\n", dependencies: [{ kind: "directive", type: NgnPt, selector: "[ptInt]", inputs: ["ptInt", "ptClass"] }, { kind: "directive", type: NgnTemplate, selector: "ng-template[ngnTemplate]", inputs: ["ngnTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
682
495
|
}
|
|
683
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
496
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: NgnSplitter, decorators: [{
|
|
684
497
|
type: Component,
|
|
685
498
|
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'ngn-splitter', imports: [NgnPt, NgnTemplate], providers: [provideSelf(NgnSplitter)], host: {
|
|
686
499
|
role: 'region',
|
|
@@ -692,16 +505,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
|
|
|
692
505
|
'[style.min-width]': `layout() === 'horizontal' ? calculator().minSize() : null`,
|
|
693
506
|
'[style.min-height]': `layout() === 'vertical' ? calculator().minSize() : null`,
|
|
694
507
|
}, template: "<ng-content />\r\n\r\n<ng-template #defaultDividerTemplate [ngnTemplate]=\"dividerTemplateType\" let-index=\"index\">\r\n <div\r\n [style.grid-area]=\"`ngn-divider-${index}`\"\r\n [ptInt]=\"this\"\r\n [ptClass]=\"{\r\n divider: true,\r\n 'divider-dragging': calculator().dragContext()?.dividerIndex === index,\r\n }\"\r\n >\r\n <button\r\n role=\"separator\"\r\n [aria-orientation]=\"layout()\"\r\n [aria-label]=\"translations['splitter_handleLabel']()\"\r\n [ptInt]=\"this\"\r\n [ptClass]=\"'divider-handle'\"\r\n (pointerdown)=\"onHandlePointerDown(index, $event)\"\r\n (pointermove)=\"onHandlePointerMove(index, $event)\"\r\n (pointerup)=\"onHandlePointerUp(index, $event)\"\r\n (pointercancel)=\"onHandlePointerCancel(index, $event)\"\r\n (keydown)=\"onHandleKeyDown(index, $event)\"\r\n ></button>\r\n </div>\r\n</ng-template>\r\n" }]
|
|
695
|
-
}], ctorParameters: () => [], propDecorators: { layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }, { type: i0.Output, args: ["layoutChange"] }], panelOrder: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelOrder", required: false }] }, { type: i0.Output, args: ["panelOrderChange"] }], stateStorage: [{ type: i0.Input, args: [{ isSignal: true, alias: "stateStorage", required: false }] }], stateKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "stateKey", required: false }] }], stateData: [{ type: i0.Input, args: [{ isSignal: true, alias: "stateData", required: false }] }], calculatorType: [{ type: i0.Input, args: [{ isSignal: true, alias: "calculatorType", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], stateSaving: [{ type: i0.Output, args: ["stateSaving"] }], stateLoading: [{ type: i0.Output, args: ["stateLoading"] }], _dividerTemplate: [{ type: i0.ViewChild, args: ['defaultDividerTemplate', { isSignal: true }] }], panels: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => NgnSplitterPanel), { isSignal: true }] }] } });
|
|
508
|
+
}], ctorParameters: () => [], propDecorators: { layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }, { type: i0.Output, args: ["layoutChange"] }], panelOrder: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelOrder", required: false }] }, { type: i0.Output, args: ["panelOrderChange"] }], stateStorage: [{ type: i0.Input, args: [{ isSignal: true, alias: "stateStorage", required: false }] }], stateKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "stateKey", required: false }] }], stateData: [{ type: i0.Input, args: [{ isSignal: true, alias: "stateData", required: false }] }], calculatorType: [{ type: i0.Input, args: [{ isSignal: true, alias: "calculatorType", required: false }] }], resizeMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizeMode", required: false }] }], lockSizes: [{ type: i0.Input, args: [{ isSignal: true, alias: "lockSizes", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], stateSaving: [{ type: i0.Output, args: ["stateSaving"] }], stateLoading: [{ type: i0.Output, args: ["stateLoading"] }], _dividerTemplate: [{ type: i0.ViewChild, args: ['defaultDividerTemplate', { isSignal: true }] }], panels: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => NgnSplitterPanel), { isSignal: true }] }] } });
|
|
696
509
|
|
|
697
510
|
// This module is just for grouping the Splitter and SplitterPanel components for convenience.
|
|
698
511
|
// The components are standalone and can be used without this module.
|
|
699
512
|
class NgnSplitterModule {
|
|
700
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
701
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.
|
|
702
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.
|
|
513
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: NgnSplitterModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
514
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.2", ngImport: i0, type: NgnSplitterModule, imports: [NgnSplitter, NgnSplitterPanel], exports: [NgnSplitter, NgnSplitterPanel] });
|
|
515
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: NgnSplitterModule });
|
|
703
516
|
}
|
|
704
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
517
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: NgnSplitterModule, decorators: [{
|
|
705
518
|
type: NgModule,
|
|
706
519
|
args: [{
|
|
707
520
|
imports: [NgnSplitter, NgnSplitterPanel],
|