@ngneers/controls 0.0.1-pre5 → 0.0.1-pre7

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.
Files changed (168) hide show
  1. package/fesm2022/ngneers-controls-accordion.mjs +33 -33
  2. package/fesm2022/ngneers-controls-accordion.mjs.map +1 -1
  3. package/fesm2022/ngneers-controls-api-ng.mjs +22 -19
  4. package/fesm2022/ngneers-controls-api-ng.mjs.map +1 -1
  5. package/fesm2022/ngneers-controls-api-resize.mjs +706 -0
  6. package/fesm2022/ngneers-controls-api-resize.mjs.map +1 -0
  7. package/fesm2022/ngneers-controls-avatar.mjs +13 -13
  8. package/fesm2022/ngneers-controls-avatar.mjs.map +1 -1
  9. package/fesm2022/ngneers-controls-base.mjs +89 -64
  10. package/fesm2022/ngneers-controls-base.mjs.map +1 -1
  11. package/fesm2022/ngneers-controls-breadcrumb.mjs +19 -19
  12. package/fesm2022/ngneers-controls-breadcrumb.mjs.map +1 -1
  13. package/fesm2022/ngneers-controls-button-group.mjs +8 -8
  14. package/fesm2022/ngneers-controls-button-group.mjs.map +1 -1
  15. package/fesm2022/ngneers-controls-button.mjs +15 -10
  16. package/fesm2022/ngneers-controls-button.mjs.map +1 -1
  17. package/fesm2022/{ngneers-controls-calendar-time-BEeJIqIX.mjs → ngneers-controls-calendar-time-CKAqRgOP.mjs} +9 -9
  18. package/fesm2022/{ngneers-controls-calendar-time-BEeJIqIX.mjs.map → ngneers-controls-calendar-time-CKAqRgOP.mjs.map} +1 -1
  19. package/fesm2022/ngneers-controls-calendar.mjs +56 -56
  20. package/fesm2022/ngneers-controls-calendar.mjs.map +1 -1
  21. package/fesm2022/ngneers-controls-checkbox.mjs +9 -9
  22. package/fesm2022/ngneers-controls-checkbox.mjs.map +1 -1
  23. package/fesm2022/ngneers-controls-chip.mjs +7 -7
  24. package/fesm2022/ngneers-controls-chip.mjs.map +1 -1
  25. package/fesm2022/ngneers-controls-default-icons.mjs +61 -0
  26. package/fesm2022/ngneers-controls-default-icons.mjs.map +1 -0
  27. package/fesm2022/ngneers-controls-defer.mjs +10 -10
  28. package/fesm2022/ngneers-controls-defer.mjs.map +1 -1
  29. package/fesm2022/ngneers-controls-dialog.mjs +38 -40
  30. package/fesm2022/ngneers-controls-dialog.mjs.map +1 -1
  31. package/fesm2022/ngneers-controls-directives.mjs +45 -39
  32. package/fesm2022/ngneers-controls-directives.mjs.map +1 -1
  33. package/fesm2022/ngneers-controls-drawer.mjs +29 -29
  34. package/fesm2022/ngneers-controls-drawer.mjs.map +1 -1
  35. package/fesm2022/ngneers-controls-edit-inplace.mjs +16 -16
  36. package/fesm2022/ngneers-controls-edit-inplace.mjs.map +1 -1
  37. package/fesm2022/ngneers-controls-filter.mjs +192 -44
  38. package/fesm2022/ngneers-controls-filter.mjs.map +1 -1
  39. package/fesm2022/{ngneers-controls-i18n-de-CdTPeBiR.mjs → ngneers-controls-i18n-de-CF0xTWEX.mjs} +9 -5
  40. package/fesm2022/ngneers-controls-i18n-de-CF0xTWEX.mjs.map +1 -0
  41. package/fesm2022/{ngneers-controls-i18n-en-Cfp2pOLY.mjs → ngneers-controls-i18n-en-8B7xAjH2.mjs} +9 -5
  42. package/fesm2022/ngneers-controls-i18n-en-8B7xAjH2.mjs.map +1 -0
  43. package/fesm2022/ngneers-controls-i18n.mjs +5 -5
  44. package/fesm2022/ngneers-controls-i18n.mjs.map +1 -1
  45. package/fesm2022/ngneers-controls-icon.mjs +111 -47
  46. package/fesm2022/ngneers-controls-icon.mjs.map +1 -1
  47. package/fesm2022/ngneers-controls-inplace.mjs +18 -18
  48. package/fesm2022/ngneers-controls-inplace.mjs.map +1 -1
  49. package/fesm2022/ngneers-controls-input-field.mjs +16 -16
  50. package/fesm2022/ngneers-controls-input-field.mjs.map +1 -1
  51. package/fesm2022/ngneers-controls-input-mask.mjs +8 -8
  52. package/fesm2022/ngneers-controls-input-mask.mjs.map +1 -1
  53. package/fesm2022/ngneers-controls-input.mjs +6 -6
  54. package/fesm2022/ngneers-controls-input.mjs.map +1 -1
  55. package/fesm2022/ngneers-controls-item-view.mjs +33 -33
  56. package/fesm2022/ngneers-controls-item-view.mjs.map +1 -1
  57. package/fesm2022/ngneers-controls-list-box.mjs +31 -31
  58. package/fesm2022/ngneers-controls-list-box.mjs.map +1 -1
  59. package/fesm2022/ngneers-controls-menu.mjs +33 -33
  60. package/fesm2022/ngneers-controls-menu.mjs.map +1 -1
  61. package/fesm2022/ngneers-controls-message.mjs +4 -4
  62. package/fesm2022/ngneers-controls-message.mjs.map +1 -1
  63. package/fesm2022/ngneers-controls-paginator.mjs +13 -13
  64. package/fesm2022/ngneers-controls-paginator.mjs.map +1 -1
  65. package/fesm2022/ngneers-controls-popover.mjs +21 -16
  66. package/fesm2022/ngneers-controls-popover.mjs.map +1 -1
  67. package/fesm2022/ngneers-controls-progress.mjs +16 -16
  68. package/fesm2022/ngneers-controls-progress.mjs.map +1 -1
  69. package/fesm2022/ngneers-controls-scroll-shadow.mjs +54 -0
  70. package/fesm2022/ngneers-controls-scroll-shadow.mjs.map +1 -0
  71. package/fesm2022/ngneers-controls-scroller.mjs +74 -39
  72. package/fesm2022/ngneers-controls-scroller.mjs.map +1 -1
  73. package/fesm2022/ngneers-controls-select-button.mjs +7 -7
  74. package/fesm2022/ngneers-controls-select-button.mjs.map +1 -1
  75. package/fesm2022/ngneers-controls-select.mjs +48 -47
  76. package/fesm2022/ngneers-controls-select.mjs.map +1 -1
  77. package/fesm2022/ngneers-controls-slider.mjs +11 -11
  78. package/fesm2022/ngneers-controls-slider.mjs.map +1 -1
  79. package/fesm2022/ngneers-controls-spinner.mjs +7 -7
  80. package/fesm2022/ngneers-controls-spinner.mjs.map +1 -1
  81. package/fesm2022/ngneers-controls-splitter.mjs +141 -328
  82. package/fesm2022/ngneers-controls-splitter.mjs.map +1 -1
  83. package/fesm2022/ngneers-controls-switch.mjs +3 -3
  84. package/fesm2022/ngneers-controls-switch.mjs.map +1 -1
  85. package/fesm2022/ngneers-controls-table.mjs +1456 -82
  86. package/fesm2022/ngneers-controls-table.mjs.map +1 -1
  87. package/fesm2022/ngneers-controls-tabs.mjs +41 -40
  88. package/fesm2022/ngneers-controls-tabs.mjs.map +1 -1
  89. package/fesm2022/ngneers-controls-tag.mjs +4 -4
  90. package/fesm2022/ngneers-controls-tag.mjs.map +1 -1
  91. package/fesm2022/ngneers-controls-toast.mjs +19 -19
  92. package/fesm2022/ngneers-controls-toast.mjs.map +1 -1
  93. package/fesm2022/ngneers-controls-toggle-button.mjs +10 -10
  94. package/fesm2022/ngneers-controls-toggle-button.mjs.map +1 -1
  95. package/fesm2022/ngneers-controls-tooltip.mjs +74 -38
  96. package/fesm2022/ngneers-controls-tooltip.mjs.map +1 -1
  97. package/fesm2022/ngneers-controls-utils-ng.mjs +9 -9
  98. package/fesm2022/ngneers-controls-utils-ng.mjs.map +1 -1
  99. package/fesm2022/ngneers-controls-utils.mjs +1 -1
  100. package/fesm2022/ngneers-controls-utils.mjs.map +1 -1
  101. package/package.json +34 -12
  102. package/types/ngneers-controls-accordion.d.ts +6 -4
  103. package/types/ngneers-controls-api-ng.d.ts +7 -2
  104. package/types/ngneers-controls-api-resize.d.ts +318 -0
  105. package/types/ngneers-controls-api.d.ts +2 -2
  106. package/types/ngneers-controls-base.d.ts +8 -0
  107. package/types/ngneers-controls-breadcrumb.d.ts +6 -4
  108. package/types/ngneers-controls-button.d.ts +13 -8
  109. package/types/ngneers-controls-calendar.d.ts +5 -1
  110. package/types/ngneers-controls-checkbox.d.ts +6 -4
  111. package/types/ngneers-controls-chip.d.ts +3 -1
  112. package/types/ngneers-controls-default-icons.d.ts +5 -0
  113. package/types/ngneers-controls-directives.d.ts +7 -1
  114. package/types/ngneers-controls-drawer.d.ts +7 -1
  115. package/types/ngneers-controls-edit-inplace.d.ts +4 -0
  116. package/types/ngneers-controls-filter.d.ts +52 -3
  117. package/types/ngneers-controls-i18n.d.ts +4 -0
  118. package/types/ngneers-controls-icon.d.ts +23 -40
  119. package/types/ngneers-controls-input-field.d.ts +7 -1
  120. package/types/ngneers-controls-item-view.d.ts +4 -2
  121. package/types/ngneers-controls-list-box.d.ts +5 -1
  122. package/types/ngneers-controls-menu.d.ts +4 -2
  123. package/types/ngneers-controls-message.d.ts +3 -1
  124. package/types/ngneers-controls-paginator.d.ts +4 -0
  125. package/types/ngneers-controls-popover.d.ts +2 -1
  126. package/types/ngneers-controls-scroll-shadow.d.ts +16 -0
  127. package/types/ngneers-controls-scroller.d.ts +12 -2
  128. package/types/ngneers-controls-select.d.ts +11 -12
  129. package/types/ngneers-controls-spinner.d.ts +1 -1
  130. package/types/ngneers-controls-splitter.d.ts +29 -59
  131. package/types/ngneers-controls-table.d.ts +380 -24
  132. package/types/ngneers-controls-tabs.d.ts +4 -2
  133. package/types/ngneers-controls-tag.d.ts +3 -1
  134. package/types/ngneers-controls-toast.d.ts +5 -3
  135. package/types/ngneers-controls-toggle-button.d.ts +5 -3
  136. package/types/ngneers-controls-tooltip.d.ts +7 -1
  137. package/fesm2022/ngneers-controls-i18n-de-CdTPeBiR.mjs.map +0 -1
  138. package/fesm2022/ngneers-controls-i18n-en-Cfp2pOLY.mjs.map +0 -1
  139. package/fesm2022/ngneers-controls-icon-calendar-z5xA9wTT.mjs +0 -4
  140. package/fesm2022/ngneers-controls-icon-calendar-z5xA9wTT.mjs.map +0 -1
  141. package/fesm2022/ngneers-controls-icon-check-DdAQ9k-T.mjs +0 -4
  142. package/fesm2022/ngneers-controls-icon-check-DdAQ9k-T.mjs.map +0 -1
  143. package/fesm2022/ngneers-controls-icon-chevron_down-HO-z-xOr.mjs +0 -4
  144. package/fesm2022/ngneers-controls-icon-chevron_down-HO-z-xOr.mjs.map +0 -1
  145. package/fesm2022/ngneers-controls-icon-chevron_left-CC5psi16.mjs +0 -4
  146. package/fesm2022/ngneers-controls-icon-chevron_left-CC5psi16.mjs.map +0 -1
  147. package/fesm2022/ngneers-controls-icon-chevron_right-BRxlzx4G.mjs +0 -4
  148. package/fesm2022/ngneers-controls-icon-chevron_right-BRxlzx4G.mjs.map +0 -1
  149. package/fesm2022/ngneers-controls-icon-chevron_up-cqhPO7g2.mjs +0 -4
  150. package/fesm2022/ngneers-controls-icon-chevron_up-cqhPO7g2.mjs.map +0 -1
  151. package/fesm2022/ngneers-controls-icon-ellipsis-DXIGA1sk.mjs +0 -4
  152. package/fesm2022/ngneers-controls-icon-ellipsis-DXIGA1sk.mjs.map +0 -1
  153. package/fesm2022/ngneers-controls-icon-filter-oU7E6Xgr.mjs +0 -4
  154. package/fesm2022/ngneers-controls-icon-filter-oU7E6Xgr.mjs.map +0 -1
  155. package/fesm2022/ngneers-controls-icon-filter_solid-CqIKuR4N.mjs +0 -4
  156. package/fesm2022/ngneers-controls-icon-filter_solid-CqIKuR4N.mjs.map +0 -1
  157. package/fesm2022/ngneers-controls-icon-magnifying_glass-T4Hzbkig.mjs +0 -4
  158. package/fesm2022/ngneers-controls-icon-magnifying_glass-T4Hzbkig.mjs.map +0 -1
  159. package/fesm2022/ngneers-controls-icon-minus-oGDEFO4E.mjs +0 -4
  160. package/fesm2022/ngneers-controls-icon-minus-oGDEFO4E.mjs.map +0 -1
  161. package/fesm2022/ngneers-controls-icon-sort-CRD4tafz.mjs +0 -4
  162. package/fesm2022/ngneers-controls-icon-sort-CRD4tafz.mjs.map +0 -1
  163. package/fesm2022/ngneers-controls-icon-sort_down-DiFB1P6R.mjs +0 -4
  164. package/fesm2022/ngneers-controls-icon-sort_down-DiFB1P6R.mjs.map +0 -1
  165. package/fesm2022/ngneers-controls-icon-sort_up-Bq_q3hIi.mjs +0 -4
  166. package/fesm2022/ngneers-controls-icon-sort_up-Bq_q3hIi.mjs.map +0 -1
  167. package/fesm2022/ngneers-controls-icon-xmark-BZKZORiu.mjs +0 -4
  168. package/fesm2022/ngneers-controls-icon-xmark-BZKZORiu.mjs.map +0 -1
@@ -1,11 +1,12 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, model, computed, ChangeDetectionStrategy, Component, afterRenderEffect, untracked, signal, inject, ViewContainerRef, output, viewChild, contentChildren, runInInjectionContext, NgModule } from '@angular/core';
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.1.0", ngImport: i0, type: NgnSplitterPanel, deps: null, target: i0.ɵɵFactoryTarget.Component });
24
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.0", 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 });
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.10", ngImport: i0, type: NgnSplitterPanel, deps: null, target: i0.ɵɵFactoryTarget.Component });
25
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.10", 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.1.0", ngImport: i0, type: NgnSplitterPanel, decorators: [{
27
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", 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
- // Signal fires when any panel size is not calculated
109
- const hasUncalculatedSizesSig = computed(() => this.panels().some(panel => !this.isPanelSizeCalculated(panel)), { equal: (_, b) => b === false });
110
- // Ensure that min and max limits are handled correctly
111
- afterRenderEffect(() => {
112
- // Recalculate on outside changes (e.g. panel size input changes, state restore, etc.)
113
- hasUncalculatedSizesSig();
114
- // Recalculate on splitter size changes
115
- this.splitterSize();
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; // a is not in order, put it at the end
74
+ return 1;
130
75
  if (bIndex === -1)
131
- return -1; // b is not in order, put it at the end
132
- return aIndex - bIndex; // sort by index in panelOrder
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
- const { px, '%': pc } = this.panels().reduce((acc, panel) => {
168
- const size = panel.size();
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: this.layout() === 'horizontal' ? event.clientX : event.clientY,
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 { startPosition } = ctx;
222
- let pxDelta;
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
- if (isCancel) {
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
- // If the size is not calculated, we cannot move the divider
250
- if (!this.isPanelSizeCalculated(leftPanel) || !this.isPanelSizeCalculated(rightPanel)) {
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.applyDividerDelta(index, pxDelta, panels.map(panel => this.createContextPanel(panel)), this.getCurrentFractionFactors());
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
- const panels = this.orderedPanels();
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
- panel.size.set(size);
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.forEach((panel, i) => {
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.1.0", ngImport: i0, type: NgnSplitter, deps: [], target: i0.ɵɵFactoryTarget.Component });
681
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.1.0", 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 }, 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 });
493
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: NgnSplitter, deps: [], target: i0.ɵɵFactoryTarget.Component });
494
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.10", 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.1.0", ngImport: i0, type: NgnSplitter, decorators: [{
496
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", 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.1.0", ngImport: i0, type: NgnSplitterModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
701
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.0", ngImport: i0, type: NgnSplitterModule, imports: [NgnSplitter, NgnSplitterPanel], exports: [NgnSplitter, NgnSplitterPanel] });
702
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: NgnSplitterModule });
513
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: NgnSplitterModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
514
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.10", ngImport: i0, type: NgnSplitterModule, imports: [NgnSplitter, NgnSplitterPanel], exports: [NgnSplitter, NgnSplitterPanel] });
515
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: NgnSplitterModule });
703
516
  }
704
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: NgnSplitterModule, decorators: [{
517
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: NgnSplitterModule, decorators: [{
705
518
  type: NgModule,
706
519
  args: [{
707
520
  imports: [NgnSplitter, NgnSplitterPanel],