@nanahoshi/mona-ui 0.1.0

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 (134) hide show
  1. package/README.md +25 -0
  2. package/fesm2022/nanahoshi-mona-ui-auto-complete.mjs +590 -0
  3. package/fesm2022/nanahoshi-mona-ui-avatar.mjs +168 -0
  4. package/fesm2022/nanahoshi-mona-ui-breadcrumb.mjs +220 -0
  5. package/fesm2022/nanahoshi-mona-ui-button-group.mjs +225 -0
  6. package/fesm2022/nanahoshi-mona-ui-button.mjs +497 -0
  7. package/fesm2022/nanahoshi-mona-ui-calendar.mjs +1569 -0
  8. package/fesm2022/nanahoshi-mona-ui-check-box.mjs +339 -0
  9. package/fesm2022/nanahoshi-mona-ui-chip.mjs +453 -0
  10. package/fesm2022/nanahoshi-mona-ui-circular-progress-bar.mjs +200 -0
  11. package/fesm2022/nanahoshi-mona-ui-color-gradient.mjs +853 -0
  12. package/fesm2022/nanahoshi-mona-ui-color-palette.mjs +923 -0
  13. package/fesm2022/nanahoshi-mona-ui-color-picker.mjs +495 -0
  14. package/fesm2022/nanahoshi-mona-ui-combo-box.mjs +686 -0
  15. package/fesm2022/nanahoshi-mona-ui-common.mjs +642 -0
  16. package/fesm2022/nanahoshi-mona-ui-contextmenu.mjs +485 -0
  17. package/fesm2022/nanahoshi-mona-ui-date-input.mjs +132 -0
  18. package/fesm2022/nanahoshi-mona-ui-date-picker.mjs +460 -0
  19. package/fesm2022/nanahoshi-mona-ui-datetime-picker.mjs +659 -0
  20. package/fesm2022/nanahoshi-mona-ui-dialog.mjs +828 -0
  21. package/fesm2022/nanahoshi-mona-ui-dropdown-button.mjs +523 -0
  22. package/fesm2022/nanahoshi-mona-ui-dropdown-list.mjs +615 -0
  23. package/fesm2022/nanahoshi-mona-ui-dropdowns.mjs +701 -0
  24. package/fesm2022/nanahoshi-mona-ui-editor.mjs +1400 -0
  25. package/fesm2022/nanahoshi-mona-ui-expansion-panel.mjs +245 -0
  26. package/fesm2022/nanahoshi-mona-ui-fieldset.mjs +170 -0
  27. package/fesm2022/nanahoshi-mona-ui-filter.mjs +680 -0
  28. package/fesm2022/nanahoshi-mona-ui-grid-grid-footer-cell.component-B9SQH5N-.mjs +105 -0
  29. package/fesm2022/nanahoshi-mona-ui-grid-grid-footer-table-cell.directive-DlLwcCFT.mjs +42 -0
  30. package/fesm2022/nanahoshi-mona-ui-grid-grid-list.component-Dgea-O0X.mjs +130 -0
  31. package/fesm2022/nanahoshi-mona-ui-grid-grid-toggle.component-DIUutx9s.mjs +773 -0
  32. package/fesm2022/nanahoshi-mona-ui-grid-grid-virtual-list.component-DRHycGIh.mjs +240 -0
  33. package/fesm2022/nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-C3eZIaJK.mjs +5374 -0
  34. package/fesm2022/nanahoshi-mona-ui-grid.mjs +2 -0
  35. package/fesm2022/nanahoshi-mona-ui-internal-filter-input.mjs +87 -0
  36. package/fesm2022/nanahoshi-mona-ui-internal-indicator-icon.mjs +154 -0
  37. package/fesm2022/nanahoshi-mona-ui-internal-list.mjs +1356 -0
  38. package/fesm2022/nanahoshi-mona-ui-internal-tree.mjs +2263 -0
  39. package/fesm2022/nanahoshi-mona-ui-internal.mjs +379 -0
  40. package/fesm2022/nanahoshi-mona-ui-list-box.mjs +630 -0
  41. package/fesm2022/nanahoshi-mona-ui-list-view.mjs +527 -0
  42. package/fesm2022/nanahoshi-mona-ui-list.mjs +4 -0
  43. package/fesm2022/nanahoshi-mona-ui-menubar.mjs +966 -0
  44. package/fesm2022/nanahoshi-mona-ui-multi-select.mjs +641 -0
  45. package/fesm2022/nanahoshi-mona-ui-notification.mjs +536 -0
  46. package/fesm2022/nanahoshi-mona-ui-numeric-text-box.mjs +597 -0
  47. package/fesm2022/nanahoshi-mona-ui-pager.mjs +790 -0
  48. package/fesm2022/nanahoshi-mona-ui-placeholder.mjs +83 -0
  49. package/fesm2022/nanahoshi-mona-ui-popover.mjs +325 -0
  50. package/fesm2022/nanahoshi-mona-ui-popup-menu.mjs +1559 -0
  51. package/fesm2022/nanahoshi-mona-ui-popup.mjs +1321 -0
  52. package/fesm2022/nanahoshi-mona-ui-progress-bar.mjs +294 -0
  53. package/fesm2022/nanahoshi-mona-ui-query.mjs +175 -0
  54. package/fesm2022/nanahoshi-mona-ui-radio-button.mjs +339 -0
  55. package/fesm2022/nanahoshi-mona-ui-scroll-view.mjs +565 -0
  56. package/fesm2022/nanahoshi-mona-ui-slider.mjs +1049 -0
  57. package/fesm2022/nanahoshi-mona-ui-split-button.mjs +636 -0
  58. package/fesm2022/nanahoshi-mona-ui-splitter.mjs +843 -0
  59. package/fesm2022/nanahoshi-mona-ui-stepper.mjs +537 -0
  60. package/fesm2022/nanahoshi-mona-ui-switch.mjs +308 -0
  61. package/fesm2022/nanahoshi-mona-ui-tabs.mjs +664 -0
  62. package/fesm2022/nanahoshi-mona-ui-text-area.mjs +111 -0
  63. package/fesm2022/nanahoshi-mona-ui-text-box.mjs +369 -0
  64. package/fesm2022/nanahoshi-mona-ui-theme.mjs +314 -0
  65. package/fesm2022/nanahoshi-mona-ui-time-picker.mjs +450 -0
  66. package/fesm2022/nanahoshi-mona-ui-time-selector.mjs +723 -0
  67. package/fesm2022/nanahoshi-mona-ui-tooltip.mjs +716 -0
  68. package/fesm2022/nanahoshi-mona-ui-tree-view.mjs +733 -0
  69. package/fesm2022/nanahoshi-mona-ui-window.mjs +1329 -0
  70. package/fesm2022/nanahoshi-mona-ui.mjs +9 -0
  71. package/package.json +289 -0
  72. package/types/nanahoshi-mona-ui-auto-complete.d.ts +223 -0
  73. package/types/nanahoshi-mona-ui-avatar.d.ts +642 -0
  74. package/types/nanahoshi-mona-ui-breadcrumb.d.ts +70 -0
  75. package/types/nanahoshi-mona-ui-button-group.d.ts +77 -0
  76. package/types/nanahoshi-mona-ui-button.d.ts +111 -0
  77. package/types/nanahoshi-mona-ui-calendar.d.ts +262 -0
  78. package/types/nanahoshi-mona-ui-check-box.d.ts +133 -0
  79. package/types/nanahoshi-mona-ui-chip.d.ts +130 -0
  80. package/types/nanahoshi-mona-ui-circular-progress-bar.d.ts +113 -0
  81. package/types/nanahoshi-mona-ui-color-gradient.d.ts +201 -0
  82. package/types/nanahoshi-mona-ui-color-palette.d.ts +102 -0
  83. package/types/nanahoshi-mona-ui-color-picker.d.ts +156 -0
  84. package/types/nanahoshi-mona-ui-combo-box.d.ts +232 -0
  85. package/types/nanahoshi-mona-ui-common.d.ts +386 -0
  86. package/types/nanahoshi-mona-ui-contextmenu.d.ts +129 -0
  87. package/types/nanahoshi-mona-ui-date-input.d.ts +60 -0
  88. package/types/nanahoshi-mona-ui-date-picker.d.ts +177 -0
  89. package/types/nanahoshi-mona-ui-datetime-picker.d.ts +199 -0
  90. package/types/nanahoshi-mona-ui-dialog.d.ts +261 -0
  91. package/types/nanahoshi-mona-ui-dropdown-button.d.ts +159 -0
  92. package/types/nanahoshi-mona-ui-dropdown-list.d.ts +219 -0
  93. package/types/nanahoshi-mona-ui-dropdowns.d.ts +176 -0
  94. package/types/nanahoshi-mona-ui-editor.d.ts +113 -0
  95. package/types/nanahoshi-mona-ui-expansion-panel.d.ts +87 -0
  96. package/types/nanahoshi-mona-ui-fieldset.d.ts +68 -0
  97. package/types/nanahoshi-mona-ui-filter.d.ts +115 -0
  98. package/types/nanahoshi-mona-ui-grid.d.ts +1114 -0
  99. package/types/nanahoshi-mona-ui-internal-filter-input.d.ts +25 -0
  100. package/types/nanahoshi-mona-ui-internal-indicator-icon.d.ts +28 -0
  101. package/types/nanahoshi-mona-ui-internal-list.d.ts +269 -0
  102. package/types/nanahoshi-mona-ui-internal-tree.d.ts +391 -0
  103. package/types/nanahoshi-mona-ui-internal.d.ts +136 -0
  104. package/types/nanahoshi-mona-ui-list-box.d.ts +225 -0
  105. package/types/nanahoshi-mona-ui-list-view.d.ts +188 -0
  106. package/types/nanahoshi-mona-ui-list.d.ts +1 -0
  107. package/types/nanahoshi-mona-ui-menubar.d.ts +198 -0
  108. package/types/nanahoshi-mona-ui-multi-select.d.ts +247 -0
  109. package/types/nanahoshi-mona-ui-notification.d.ts +106 -0
  110. package/types/nanahoshi-mona-ui-numeric-text-box.d.ts +161 -0
  111. package/types/nanahoshi-mona-ui-pager.d.ts +238 -0
  112. package/types/nanahoshi-mona-ui-placeholder.d.ts +35 -0
  113. package/types/nanahoshi-mona-ui-popover.d.ts +130 -0
  114. package/types/nanahoshi-mona-ui-popup-menu.d.ts +412 -0
  115. package/types/nanahoshi-mona-ui-popup.d.ts +485 -0
  116. package/types/nanahoshi-mona-ui-progress-bar.d.ts +139 -0
  117. package/types/nanahoshi-mona-ui-query.d.ts +89 -0
  118. package/types/nanahoshi-mona-ui-radio-button.d.ts +128 -0
  119. package/types/nanahoshi-mona-ui-scroll-view.d.ts +166 -0
  120. package/types/nanahoshi-mona-ui-slider.d.ts +305 -0
  121. package/types/nanahoshi-mona-ui-split-button.d.ts +182 -0
  122. package/types/nanahoshi-mona-ui-splitter.d.ts +70 -0
  123. package/types/nanahoshi-mona-ui-stepper.d.ts +173 -0
  124. package/types/nanahoshi-mona-ui-switch.d.ts +125 -0
  125. package/types/nanahoshi-mona-ui-tabs.d.ts +158 -0
  126. package/types/nanahoshi-mona-ui-text-area.d.ts +42 -0
  127. package/types/nanahoshi-mona-ui-text-box.d.ts +164 -0
  128. package/types/nanahoshi-mona-ui-theme.d.ts +23 -0
  129. package/types/nanahoshi-mona-ui-time-picker.d.ts +184 -0
  130. package/types/nanahoshi-mona-ui-time-selector.d.ts +143 -0
  131. package/types/nanahoshi-mona-ui-tooltip.d.ts +130 -0
  132. package/types/nanahoshi-mona-ui-tree-view.d.ts +274 -0
  133. package/types/nanahoshi-mona-ui-window.d.ts +295 -0
  134. package/types/nanahoshi-mona-ui.d.ts +2 -0
@@ -0,0 +1,843 @@
1
+ import { NgTemplateOutlet } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { computed, input, Directive, model, viewChild, TemplateRef, Component, inject, output, DestroyRef, ElementRef, signal, afterNextRender, afterRenderEffect, contentChildren } from '@angular/core';
4
+ import { where, compact, from } from '@mirei/ts-collections';
5
+ import { ThemeService } from '@nanahoshi/mona-ui/theme';
6
+ import { cva } from 'class-variance-authority';
7
+ import { v4 } from 'uuid';
8
+ import { Directionality } from '@angular/cdk/bidi';
9
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
10
+ import { fromEvent, map, merge, filter, tap, skipUntil, takeUntil } from 'rxjs';
11
+ import { LucideChevronLeft, LucideChevronRight, LucideChevronUp, LucideChevronDown } from '@lucide/angular';
12
+ import { ButtonDirective } from '@nanahoshi/mona-ui/button';
13
+
14
+ class SplitterPaneStyleDirective {
15
+ constructor() {
16
+ this.#autoSizedPane = computed(() => {
17
+ const paneList = this.paneList();
18
+ const panes = where(paneList, pane => !(pane.collapsible() && pane.collapsed()));
19
+ if (!panes.any()) {
20
+ return null;
21
+ }
22
+ return panes.firstOrDefault(pane => pane.size() === "") ?? panes.last();
23
+ }, /* @ts-ignore */
24
+ ...(ngDevMode ? [{ debugName: "#autoSizedPane" }] : /* istanbul ignore next */ []));
25
+ this.styles = computed(() => {
26
+ const pane = this.pane();
27
+ const flexBasis = this.getPaneFlexBasis(pane);
28
+ const flexGrow = this.getPaneFlexGrow(pane);
29
+ const flexShrink = this.getPaneFlexShrink(pane);
30
+ const styles = { flexGrow, flexShrink, flexBasis };
31
+ return styles;
32
+ }, /* @ts-ignore */
33
+ ...(ngDevMode ? [{ debugName: "styles" }] : /* istanbul ignore next */ []));
34
+ this.pane = input.required(/* @ts-ignore */
35
+ ...(ngDevMode ? [{ debugName: "pane" }] : /* istanbul ignore next */ []));
36
+ this.paneList = input.required(/* @ts-ignore */
37
+ ...(ngDevMode ? [{ debugName: "paneList" }] : /* istanbul ignore next */ []));
38
+ }
39
+ #autoSizedPane;
40
+ getFractionalWeight(size) {
41
+ if (typeof size !== "string") {
42
+ return null;
43
+ }
44
+ const match = size.trim().match(/^([0-9]*\.?[0-9]+)fr$/i);
45
+ if (match === null) {
46
+ return null;
47
+ }
48
+ const weight = Number(match[1]);
49
+ return Number.isFinite(weight) ? weight : 1;
50
+ }
51
+ getPaneFlexBasis(pane) {
52
+ if (pane.collapsible() && pane.collapsed()) {
53
+ return "0px";
54
+ }
55
+ const size = this.getPaneSize(pane);
56
+ if (size === null || this.isFractionalSize(size)) {
57
+ return "0px";
58
+ }
59
+ return size;
60
+ }
61
+ getPaneFlexGrow(pane) {
62
+ if (pane.collapsible() && pane.collapsed()) {
63
+ return "0";
64
+ }
65
+ const size = this.getPaneSize(pane);
66
+ const fractionalWeight = this.getFractionalWeight(size);
67
+ if (fractionalWeight !== null) {
68
+ return fractionalWeight.toString();
69
+ }
70
+ if (pane.uid === this.#autoSizedPane()?.uid) {
71
+ return "1";
72
+ }
73
+ return size === null ? "1" : "0";
74
+ }
75
+ getPaneFlexShrink(pane) {
76
+ return pane.collapsible() && pane.collapsed() ? "0" : "1";
77
+ }
78
+ getPaneSize(pane) {
79
+ const size = pane.size();
80
+ if (size === "" || size === undefined || size === null) {
81
+ return null;
82
+ }
83
+ if (typeof size === "number") {
84
+ return `${size}px`;
85
+ }
86
+ return size;
87
+ }
88
+ isFractionalSize(size) {
89
+ if (typeof size !== "string") {
90
+ return false;
91
+ }
92
+ return size.trim().toLowerCase().endsWith("fr");
93
+ }
94
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SplitterPaneStyleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
95
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: SplitterPaneStyleDirective, isStandalone: true, selector: "div[monaSplitterPaneStyle]", inputs: { pane: { classPropertyName: "pane", publicName: "pane", isSignal: true, isRequired: true, transformFunction: null }, paneList: { classPropertyName: "paneList", publicName: "paneList", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "style": "styles()", "aria-hidden": "pane().collapsible() && pane().collapsed()" } }, ngImport: i0 }); }
96
+ }
97
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SplitterPaneStyleDirective, decorators: [{
98
+ type: Directive,
99
+ args: [{
100
+ selector: "div[monaSplitterPaneStyle]",
101
+ host: {
102
+ "[style]": "styles()",
103
+ "[aria-hidden]": "pane().collapsible() && pane().collapsed()"
104
+ }
105
+ }]
106
+ }], propDecorators: { pane: [{ type: i0.Input, args: [{ isSignal: true, alias: "pane", required: true }] }], paneList: [{ type: i0.Input, args: [{ isSignal: true, alias: "paneList", required: true }] }] } });
107
+
108
+ const splitterBaseVariants = cva(`
109
+ flex w-full h-full overflow-hidden min-w-0 min-h-0
110
+ `, {
111
+ variants: {
112
+ orientation: {
113
+ horizontal: "flex-row",
114
+ vertical: "flex-col"
115
+ }
116
+ },
117
+ defaultVariants: {
118
+ orientation: "horizontal"
119
+ }
120
+ });
121
+ const splitterResizerVariants = cva(`
122
+ flex items-center justify-center
123
+ relative bg-accent
124
+ hover:bg-accent-hover
125
+ active:bg-primary/40
126
+ shrink-0 outline-none
127
+ focus-visible:bg-primary
128
+ `, {
129
+ variants: {
130
+ orientation: {
131
+ horizontal: "w-0.5 flex-col ",
132
+ vertical: "h-0.5 flex-row"
133
+ },
134
+ resizing: {
135
+ true: "",
136
+ false: ""
137
+ }
138
+ },
139
+ defaultVariants: {
140
+ orientation: "horizontal",
141
+ resizing: false
142
+ }
143
+ });
144
+ const splitterResizerHandleVariants = cva(`
145
+ flex items-center justify-center
146
+ [&_button]:p-0
147
+ `, {
148
+ variants: {
149
+ orientation: {
150
+ horizontal: "flex-row [&_button]:w-3.5 [&_button]:h-6",
151
+ vertical: "flex-col [&_button]:h-3.5 [&_button]:w-6"
152
+ }
153
+ },
154
+ defaultVariants: {
155
+ orientation: "horizontal"
156
+ }
157
+ });
158
+
159
+ const splitterBaseThemeVariants = (theme) => {
160
+ switch (theme) {
161
+ case "mona":
162
+ return splitterBaseVariants;
163
+ default:
164
+ return splitterBaseVariants;
165
+ }
166
+ };
167
+ const splitterResizerThemeVariants = (theme) => {
168
+ switch (theme) {
169
+ case "mona":
170
+ return splitterResizerVariants;
171
+ default:
172
+ return splitterResizerVariants;
173
+ }
174
+ };
175
+ const splitterResizerHandleThemeVariants = (theme) => {
176
+ switch (theme) {
177
+ case "mona":
178
+ return splitterResizerHandleVariants;
179
+ default:
180
+ return splitterResizerHandleVariants;
181
+ }
182
+ };
183
+
184
+ class SplitterPaneComponent {
185
+ constructor() {
186
+ /**
187
+ * @description Whether the pane is collapsible.
188
+ */
189
+ this.collapsible = input(false, /* @ts-ignore */
190
+ ...(ngDevMode ? [{ debugName: "collapsible" }] : /* istanbul ignore next */ []));
191
+ /**
192
+ * @description Whether the pane is collapsed.
193
+ */
194
+ this.collapsed = model(false, /* @ts-ignore */
195
+ ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
196
+ /**
197
+ * @description The maximum size of the pane.
198
+ */
199
+ this.max = input(null, /* @ts-ignore */
200
+ ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
201
+ /**
202
+ * @description The minimum size of the pane.
203
+ */
204
+ this.min = input(null, /* @ts-ignore */
205
+ ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
206
+ /**
207
+ * @description Whether the pane is resizable.
208
+ */
209
+ this.resizable = input(true, /* @ts-ignore */
210
+ ...(ngDevMode ? [{ debugName: "resizable" }] : /* istanbul ignore next */ []));
211
+ /**
212
+ * @description The size of the pane.
213
+ */
214
+ this.size = model("", /* @ts-ignore */
215
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
216
+ this.template = viewChild.required(TemplateRef, /* @ts-ignore */
217
+ ...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
218
+ this.uid = v4();
219
+ }
220
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SplitterPaneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
221
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.6", type: SplitterPaneComponent, isStandalone: true, selector: "mona-splitter-pane", inputs: { collapsible: { classPropertyName: "collapsible", publicName: "collapsible", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsed: "collapsedChange", size: "sizeChange" }, viewQueries: [{ propertyName: "template", first: true, predicate: TemplateRef, descendants: true, isSignal: true }], ngImport: i0, template: `
222
+ <ng-template>
223
+ <ng-content></ng-content>
224
+ </ng-template>
225
+ `, isInline: true }); }
226
+ }
227
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SplitterPaneComponent, decorators: [{
228
+ type: Component,
229
+ args: [{
230
+ selector: "mona-splitter-pane",
231
+ template: `
232
+ <ng-template>
233
+ <ng-content></ng-content>
234
+ </ng-template>
235
+ `
236
+ }]
237
+ }], propDecorators: { collapsible: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsible", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }, { type: i0.Output, args: ["collapsedChange"] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }, { type: i0.Output, args: ["sizeChange"] }], template: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
238
+
239
+ class SplitterResizerHandleComponent {
240
+ constructor() {
241
+ this.#themeService = inject(ThemeService);
242
+ this.baseClass = computed(() => {
243
+ const theme = this.#themeService.theme();
244
+ const orientation = this.orientation();
245
+ return splitterResizerHandleThemeVariants(theme)({ orientation });
246
+ }, /* @ts-ignore */
247
+ ...(ngDevMode ? [{ debugName: "baseClass" }] : /* istanbul ignore next */ []));
248
+ this.collapseNext = output();
249
+ this.collapsePrevious = output();
250
+ this.nextControlsVisible = input.required(/* @ts-ignore */
251
+ ...(ngDevMode ? [{ debugName: "nextControlsVisible" }] : /* istanbul ignore next */ []));
252
+ this.orientation = input.required(/* @ts-ignore */
253
+ ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
254
+ this.previousControlsVisible = input.required(/* @ts-ignore */
255
+ ...(ngDevMode ? [{ debugName: "previousControlsVisible" }] : /* istanbul ignore next */ []));
256
+ this.resizable = input.required(/* @ts-ignore */
257
+ ...(ngDevMode ? [{ debugName: "resizable" }] : /* istanbul ignore next */ []));
258
+ }
259
+ #themeService;
260
+ onPointerDown(event) {
261
+ event.preventDefault();
262
+ event.stopPropagation();
263
+ }
264
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SplitterResizerHandleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
265
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: SplitterResizerHandleComponent, isStandalone: true, selector: "mona-splitter-resizer-handle", inputs: { nextControlsVisible: { classPropertyName: "nextControlsVisible", publicName: "nextControlsVisible", isSignal: true, isRequired: true, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: true, transformFunction: null }, previousControlsVisible: { classPropertyName: "previousControlsVisible", publicName: "previousControlsVisible", isSignal: true, isRequired: true, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { collapseNext: "collapseNext", collapsePrevious: "collapsePrevious" }, host: { properties: { "class": "baseClass()" } }, ngImport: i0, template: "@if (orientation() === \"horizontal\") {\r\n @if (previousControlsVisible()) {\r\n <button\r\n monaButton\r\n look=\"secondary\"\r\n [rounded]=\"'none'\"\r\n aria-label=\"Collapse previous pane\"\r\n (click)=\"collapsePrevious.emit($event)\"\r\n (pointerdown)=\"onPointerDown($event)\">\r\n <svg lucideChevronLeft [size]=\"12\"></svg>\r\n </button>\r\n }\r\n @if (resizable()) {\r\n <div class=\"flex h-6 w-0.5 bg-primary/40\"></div>\r\n }\r\n @if (nextControlsVisible()) {\r\n <button\r\n monaButton\r\n look=\"secondary\"\r\n [rounded]=\"'none'\"\r\n aria-label=\"Collapse next pane\"\r\n (click)=\"collapseNext.emit($event)\"\r\n (pointerdown)=\"onPointerDown($event)\">\r\n <svg lucideChevronRight [size]=\"12\"></svg>\r\n </button>\r\n }\r\n} @else {\r\n @if (previousControlsVisible()) {\r\n <button\r\n monaButton\r\n look=\"secondary\"\r\n [rounded]=\"'none'\"\r\n aria-label=\"Collapse pane above\"\r\n (click)=\"collapsePrevious.emit($event)\"\r\n (pointerdown)=\"onPointerDown($event)\">\r\n <svg lucideChevronUp [size]=\"12\"></svg>\r\n </button>\r\n }\r\n @if (resizable()) {\r\n <div class=\"flex h-0.5 w-6 bg-primary/40\"></div>\r\n }\r\n @if (nextControlsVisible()) {\r\n <button\r\n monaButton\r\n look=\"secondary\"\r\n [rounded]=\"'none'\"\r\n aria-label=\"Collapse pane below\"\r\n (click)=\"collapseNext.emit($event)\"\r\n (pointerdown)=\"onPointerDown($event)\">\r\n <svg lucideChevronDown [size]=\"12\"></svg>\r\n </button>\r\n }\r\n}\r\n", dependencies: [{ kind: "directive", type: ButtonDirective, selector: "button[monaButton]", inputs: ["aria-haspopup", "disabled", "iconOnly", "loading", "look", "rounded", "selected", "size", "tabindex", "toggleable", "class"], outputs: ["disabledChange", "loadingChange", "lookChange", "selectedChange"] }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "component", type: LucideChevronUp, selector: "svg[lucideChevronUp]" }, { kind: "component", type: LucideChevronDown, selector: "svg[lucideChevronDown]" }] }); }
266
+ }
267
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SplitterResizerHandleComponent, decorators: [{
268
+ type: Component,
269
+ args: [{ selector: "mona-splitter-resizer-handle", imports: [ButtonDirective, LucideChevronLeft, LucideChevronRight, LucideChevronUp, LucideChevronDown], host: {
270
+ "[class]": "baseClass()"
271
+ }, template: "@if (orientation() === \"horizontal\") {\r\n @if (previousControlsVisible()) {\r\n <button\r\n monaButton\r\n look=\"secondary\"\r\n [rounded]=\"'none'\"\r\n aria-label=\"Collapse previous pane\"\r\n (click)=\"collapsePrevious.emit($event)\"\r\n (pointerdown)=\"onPointerDown($event)\">\r\n <svg lucideChevronLeft [size]=\"12\"></svg>\r\n </button>\r\n }\r\n @if (resizable()) {\r\n <div class=\"flex h-6 w-0.5 bg-primary/40\"></div>\r\n }\r\n @if (nextControlsVisible()) {\r\n <button\r\n monaButton\r\n look=\"secondary\"\r\n [rounded]=\"'none'\"\r\n aria-label=\"Collapse next pane\"\r\n (click)=\"collapseNext.emit($event)\"\r\n (pointerdown)=\"onPointerDown($event)\">\r\n <svg lucideChevronRight [size]=\"12\"></svg>\r\n </button>\r\n }\r\n} @else {\r\n @if (previousControlsVisible()) {\r\n <button\r\n monaButton\r\n look=\"secondary\"\r\n [rounded]=\"'none'\"\r\n aria-label=\"Collapse pane above\"\r\n (click)=\"collapsePrevious.emit($event)\"\r\n (pointerdown)=\"onPointerDown($event)\">\r\n <svg lucideChevronUp [size]=\"12\"></svg>\r\n </button>\r\n }\r\n @if (resizable()) {\r\n <div class=\"flex h-0.5 w-6 bg-primary/40\"></div>\r\n }\r\n @if (nextControlsVisible()) {\r\n <button\r\n monaButton\r\n look=\"secondary\"\r\n [rounded]=\"'none'\"\r\n aria-label=\"Collapse pane below\"\r\n (click)=\"collapseNext.emit($event)\"\r\n (pointerdown)=\"onPointerDown($event)\">\r\n <svg lucideChevronDown [size]=\"12\"></svg>\r\n </button>\r\n }\r\n}\r\n" }]
272
+ }], propDecorators: { collapseNext: [{ type: i0.Output, args: ["collapseNext"] }], collapsePrevious: [{ type: i0.Output, args: ["collapsePrevious"] }], nextControlsVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextControlsVisible", required: true }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: true }] }], previousControlsVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "previousControlsVisible", required: true }] }], resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: true }] }] } });
273
+
274
+ class SplitterResizerComponent {
275
+ #destroyRef;
276
+ #directionality;
277
+ #hostElementRef;
278
+ #paneSizeMemory;
279
+ #splitter;
280
+ #themeService;
281
+ constructor() {
282
+ this.#destroyRef = inject(DestroyRef);
283
+ this.#directionality = inject(Directionality);
284
+ this.#hostElementRef = inject(ElementRef);
285
+ this.#paneSizeMemory = new WeakMap();
286
+ this.#splitter = inject(SplitterComponent);
287
+ this.#themeService = inject(ThemeService);
288
+ this.ariaValueMax = signal(0, /* @ts-ignore */
289
+ ...(ngDevMode ? [{ debugName: "ariaValueMax" }] : /* istanbul ignore next */ []));
290
+ this.ariaValueMin = signal(0, /* @ts-ignore */
291
+ ...(ngDevMode ? [{ debugName: "ariaValueMin" }] : /* istanbul ignore next */ []));
292
+ this.ariaValueNow = signal(0, /* @ts-ignore */
293
+ ...(ngDevMode ? [{ debugName: "ariaValueNow" }] : /* istanbul ignore next */ []));
294
+ this.baseClass = computed(() => {
295
+ const theme = this.#themeService.theme();
296
+ const orientation = this.orientation();
297
+ const resizing = this.resizing();
298
+ return splitterResizerThemeVariants(theme)({ orientation, resizing });
299
+ }, /* @ts-ignore */
300
+ ...(ngDevMode ? [{ debugName: "baseClass" }] : /* istanbul ignore next */ []));
301
+ this.hovered = signal(false, /* @ts-ignore */
302
+ ...(ngDevMode ? [{ debugName: "hovered" }] : /* istanbul ignore next */ []));
303
+ this.isInert = computed(() => {
304
+ return !this.resizable() && this.getCollapsibleTargetPane() === null;
305
+ }, /* @ts-ignore */
306
+ ...(ngDevMode ? [{ debugName: "isInert" }] : /* istanbul ignore next */ []));
307
+ this.nextCollapseControlsVisible = computed(() => {
308
+ return this.hovered() && this.nextPane().collapsible() && !this.nextPane().collapsed();
309
+ }, /* @ts-ignore */
310
+ ...(ngDevMode ? [{ debugName: "nextCollapseControlsVisible" }] : /* istanbul ignore next */ []));
311
+ this.previousCollapseControlsVisible = computed(() => {
312
+ return this.hovered() && this.previousPane().collapsible() && !this.previousPane().collapsed();
313
+ }, /* @ts-ignore */
314
+ ...(ngDevMode ? [{ debugName: "previousCollapseControlsVisible" }] : /* istanbul ignore next */ []));
315
+ this.resizable = computed(() => {
316
+ return this.previousPane().resizable() && this.nextPane().resizable();
317
+ }, /* @ts-ignore */
318
+ ...(ngDevMode ? [{ debugName: "resizable" }] : /* istanbul ignore next */ []));
319
+ this.resizing = signal(false, /* @ts-ignore */
320
+ ...(ngDevMode ? [{ debugName: "resizing" }] : /* istanbul ignore next */ []));
321
+ this.nextPane = input.required(/* @ts-ignore */
322
+ ...(ngDevMode ? [{ debugName: "nextPane" }] : /* istanbul ignore next */ []));
323
+ this.orientation = input.required(/* @ts-ignore */
324
+ ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
325
+ this.previousPane = input.required(/* @ts-ignore */
326
+ ...(ngDevMode ? [{ debugName: "previousPane" }] : /* istanbul ignore next */ []));
327
+ afterNextRender({
328
+ read: () => {
329
+ this.setHoverEvents();
330
+ this.setPointerEvents();
331
+ this.setKeyboardEvents();
332
+ }
333
+ });
334
+ afterRenderEffect({
335
+ read: () => {
336
+ this.previousPane().size();
337
+ this.previousPane().collapsed();
338
+ this.nextPane().size();
339
+ this.nextPane().collapsed();
340
+ this.updateAriaSeparatorValues();
341
+ }
342
+ });
343
+ }
344
+ collapseNext(event) {
345
+ event.preventDefault();
346
+ event.stopPropagation();
347
+ this.collapsePane("next");
348
+ }
349
+ collapsePrevious(event) {
350
+ event.preventDefault();
351
+ event.stopPropagation();
352
+ this.collapsePane("previous");
353
+ }
354
+ toggleCollapse() {
355
+ const targetPane = this.getCollapsibleTargetPane();
356
+ if (targetPane === null) {
357
+ return;
358
+ }
359
+ const targetElement = targetPane.uid === this.previousPane().uid ? this.getPaneElements()[0] : this.getPaneElements()[1];
360
+ const direction = targetPane.uid === this.previousPane().uid ? "previous" : "next";
361
+ this.togglePane(targetPane, targetElement, direction);
362
+ }
363
+ clamp(value, min, max) {
364
+ if (Number.isFinite(max)) {
365
+ return Math.min(Math.max(value, min), max);
366
+ }
367
+ return Math.max(value, min);
368
+ }
369
+ clampPaneSizes(total, desiredPrev, previousPane, nextPane) {
370
+ const prevMin = this.getMinSize(previousPane);
371
+ const nextMin = this.getMinSize(nextPane);
372
+ const prevMaxRaw = this.getMaxSize(previousPane);
373
+ const nextMaxRaw = this.getMaxSize(nextPane);
374
+ const prevMax = Math.min(prevMaxRaw, total - nextMin);
375
+ const prevMinBound = Math.max(prevMin, total - nextMaxRaw);
376
+ let prevSize = this.clamp(desiredPrev, prevMinBound, prevMax);
377
+ let nextSize = total - prevSize;
378
+ if (nextSize < nextMin) {
379
+ nextSize = nextMin;
380
+ prevSize = total - nextSize;
381
+ }
382
+ else if (nextSize > nextMaxRaw) {
383
+ nextSize = nextMaxRaw;
384
+ prevSize = total - nextSize;
385
+ }
386
+ // final guard for prev bounds
387
+ prevSize = this.clamp(prevSize, prevMin, prevMaxRaw);
388
+ nextSize = total - prevSize;
389
+ return [prevSize, nextSize];
390
+ }
391
+ collapseAndRedistribute(targetPane, targetSize, leading, trailing) {
392
+ if (targetSize <= 0) {
393
+ return;
394
+ }
395
+ const leadingNeighbor = leading !== null && !(leading.pane.collapsible() && leading.pane.collapsed()) ? leading : null;
396
+ const trailingNeighbor = trailing !== null && !(trailing.pane.collapsible() && trailing.pane.collapsed()) ? trailing : null;
397
+ const neighbors = compact([leadingNeighbor, trailingNeighbor]).toArray();
398
+ if (neighbors.length === 0) {
399
+ targetPane.collapsed.set(true);
400
+ return;
401
+ }
402
+ this.distributeSpaceToNeighbors(targetSize, neighbors);
403
+ targetPane.collapsed.set(true);
404
+ }
405
+ collapsePane(direction) {
406
+ const target = this.pickTargetPane(direction);
407
+ if (target === null || !target.pane.collapsible()) {
408
+ return;
409
+ }
410
+ this.togglePane(target.pane, target.element, target.direction);
411
+ }
412
+ distributeSpaceToNeighbors(space, neighbors) {
413
+ let remaining = space;
414
+ const capacities = neighbors.map(neighbor => {
415
+ const max = this.getMaxSize(neighbor.pane);
416
+ const capacity = max === Number.POSITIVE_INFINITY ? Number.POSITIVE_INFINITY : Math.max(0, max - neighbor.size);
417
+ return { neighbor, capacity };
418
+ });
419
+ const infiniteRecipients = capacities.filter(c => !Number.isFinite(c.capacity));
420
+ if (infiniteRecipients.length > 0) {
421
+ const share = remaining / infiniteRecipients.length;
422
+ infiniteRecipients.forEach(c => {
423
+ c.neighbor.pane.size.set(`${c.neighbor.size + share}px`);
424
+ });
425
+ return;
426
+ }
427
+ let available = capacities.reduce((sum, c) => sum + c.capacity, 0);
428
+ if (available <= 0) {
429
+ return;
430
+ }
431
+ capacities.forEach(c => {
432
+ const share = (c.capacity / available) * remaining;
433
+ c.neighbor.pane.size.set(`${c.neighbor.size + share}px`);
434
+ });
435
+ }
436
+ ensureExpandedBeforeResize() {
437
+ if (this.previousPane().collapsed()) {
438
+ this.previousPane().collapsed.set(false);
439
+ }
440
+ if (this.nextPane().collapsed()) {
441
+ this.nextPane().collapsed.set(false);
442
+ }
443
+ }
444
+ expandPane(targetPane, desiredSize, leading, trailing) {
445
+ const targetMin = this.getMinSize(targetPane);
446
+ const targetMax = this.getMaxSize(targetPane);
447
+ if (desiredSize <= 0) {
448
+ targetPane.collapsed.set(false);
449
+ return;
450
+ }
451
+ const currentLeadingSize = leading?.size ?? 0;
452
+ const currentTrailingSize = trailing?.size ?? 0;
453
+ const neighborTotal = currentLeadingSize + currentTrailingSize;
454
+ if (neighborTotal <= 0) {
455
+ const clampedTarget = this.clamp(desiredSize, targetMin, targetMax);
456
+ targetPane.size.set(`${clampedTarget}px`);
457
+ targetPane.collapsed.set(false);
458
+ return;
459
+ }
460
+ const availableFromLeading = leading !== null ? Math.max(0, currentLeadingSize - this.getMinSize(leading.pane)) : 0;
461
+ const availableFromTrailing = trailing !== null ? Math.max(0, currentTrailingSize - this.getMinSize(trailing.pane)) : 0;
462
+ const availableTotal = availableFromLeading + availableFromTrailing;
463
+ if (availableTotal <= 0) {
464
+ targetPane.collapsed.set(false);
465
+ return;
466
+ }
467
+ const desiredClamped = this.clamp(desiredSize, targetMin, targetMax);
468
+ const targetSize = Math.min(desiredClamped, availableTotal);
469
+ if (leading !== null && availableFromLeading > 0) {
470
+ const takeFromLeading = targetSize * (availableFromLeading / availableTotal);
471
+ const newSize = Math.max(this.getMinSize(leading.pane), currentLeadingSize - takeFromLeading);
472
+ leading.pane.size.set(`${newSize}px`);
473
+ }
474
+ if (trailing !== null && availableFromTrailing > 0) {
475
+ const takeFromTrailing = targetSize * (availableFromTrailing / availableTotal);
476
+ const newSize = Math.max(this.getMinSize(trailing.pane), currentTrailingSize - takeFromTrailing);
477
+ trailing.pane.size.set(`${newSize}px`);
478
+ }
479
+ targetPane.size.set(`${targetSize}px`);
480
+ targetPane.collapsed.set(false);
481
+ }
482
+ findPaneToLeft(element) {
483
+ let cursor = element.previousElementSibling;
484
+ while (cursor !== null) {
485
+ if (cursor.dataset["pid"]) {
486
+ const pane = this.#splitter.getPaneByUid(cursor.dataset["pid"]);
487
+ if (pane != null) {
488
+ return { pane, element: cursor };
489
+ }
490
+ }
491
+ cursor = cursor.previousElementSibling;
492
+ }
493
+ return null;
494
+ }
495
+ findPaneToRight(element) {
496
+ let cursor = element.nextElementSibling;
497
+ while (cursor !== null) {
498
+ if (cursor.dataset["pid"]) {
499
+ const pane = this.#splitter.getPaneByUid(cursor.dataset["pid"]);
500
+ if (pane != null) {
501
+ return { pane, element: cursor };
502
+ }
503
+ }
504
+ cursor = cursor.nextElementSibling;
505
+ }
506
+ return null;
507
+ }
508
+ focusAdjacentResizer(forward) {
509
+ let cursor = this.#hostElementRef.nativeElement;
510
+ if (!cursor) {
511
+ return false;
512
+ }
513
+ while (true) {
514
+ cursor = forward ? cursor.nextElementSibling : cursor.previousElementSibling;
515
+ if (cursor === null) {
516
+ return false;
517
+ }
518
+ if (cursor instanceof HTMLElement && cursor.tagName.toLowerCase() === "mona-splitter-resizer") {
519
+ cursor.focus();
520
+ return true;
521
+ }
522
+ }
523
+ }
524
+ getCollapsibleTargetPane() {
525
+ const previousPane = this.previousPane();
526
+ const nextPane = this.nextPane();
527
+ if (previousPane.collapsible() && previousPane.collapsed()) {
528
+ return previousPane;
529
+ }
530
+ if (nextPane.collapsible() && nextPane.collapsed()) {
531
+ return nextPane;
532
+ }
533
+ if (previousPane.collapsible()) {
534
+ return previousPane;
535
+ }
536
+ if (nextPane.collapsible()) {
537
+ return nextPane;
538
+ }
539
+ return null;
540
+ }
541
+ getMaxSize(pane) {
542
+ const max = pane.max();
543
+ const parsed = this.parseSizeInput(max);
544
+ return parsed === null ? Number.POSITIVE_INFINITY : Math.max(0, parsed);
545
+ }
546
+ getMinSize(pane) {
547
+ const min = pane.min();
548
+ const parsed = this.parseSizeInput(min);
549
+ return parsed === null ? 0 : Math.max(0, parsed);
550
+ }
551
+ getNeighborPanes(targetElement, direction) {
552
+ const [previousElement, nextElement] = this.getPaneElements();
553
+ const leadingPane = direction === "previous"
554
+ ? this.findPaneToLeft(targetElement)
555
+ : { pane: this.previousPane(), element: previousElement };
556
+ const trailingPane = direction === "previous"
557
+ ? { pane: this.nextPane(), element: nextElement }
558
+ : this.findPaneToRight(targetElement);
559
+ return {
560
+ leading: leadingPane !== null ? { ...leadingPane, size: this.measurePaneSize(leadingPane.element) } : null,
561
+ trailing: trailingPane !== null ? { ...trailingPane, size: this.measurePaneSize(trailingPane.element) } : null
562
+ };
563
+ }
564
+ getPaneElements() {
565
+ const previousPane = this.#hostElementRef.nativeElement.previousElementSibling;
566
+ const nextPane = this.#hostElementRef.nativeElement.nextElementSibling;
567
+ if (previousPane === null || nextPane === null) {
568
+ throw new Error("The previous or next pane element is not found.");
569
+ }
570
+ return [previousPane, nextPane];
571
+ }
572
+ getPaneRectangles() {
573
+ const [previousPane, nextPane] = this.getPaneElements();
574
+ return [previousPane.getBoundingClientRect(), nextPane.getBoundingClientRect()];
575
+ }
576
+ handleCollapserKeys(key) {
577
+ const orientation = this.orientation();
578
+ if (orientation === "horizontal") {
579
+ const isRtl = this.#directionality.value === "rtl";
580
+ if (key === "ArrowLeft") {
581
+ this.collapsePane(isRtl ? "next" : "previous");
582
+ return true;
583
+ }
584
+ if (key === "ArrowRight") {
585
+ this.collapsePane(isRtl ? "previous" : "next");
586
+ return true;
587
+ }
588
+ }
589
+ else {
590
+ if (key === "ArrowUp") {
591
+ this.collapsePane("previous");
592
+ return true;
593
+ }
594
+ if (key === "ArrowDown") {
595
+ this.collapsePane("next");
596
+ return true;
597
+ }
598
+ }
599
+ return false;
600
+ }
601
+ handleKeydown(event) {
602
+ const key = event.key;
603
+ if (key === "Tab") {
604
+ return this.focusAdjacentResizer(!event.shiftKey);
605
+ }
606
+ if (key === "Enter") {
607
+ this.toggleCollapse();
608
+ return true;
609
+ }
610
+ if (event.altKey) {
611
+ return this.handleCollapserKeys(key);
612
+ }
613
+ return this.handleResizerKeys(key);
614
+ }
615
+ handleResizerKeys(key) {
616
+ const orientation = this.orientation();
617
+ const step = 10;
618
+ const previousPane = this.previousPane();
619
+ const nextPane = this.nextPane();
620
+ if (!previousPane.resizable() && !nextPane.resizable()) {
621
+ return false;
622
+ }
623
+ if (orientation === "horizontal") {
624
+ const isRtl = this.#directionality.value === "rtl";
625
+ if (key === "ArrowLeft") {
626
+ this.nudgeSplitter(isRtl ? step : -step);
627
+ return true;
628
+ }
629
+ if (key === "ArrowRight") {
630
+ this.nudgeSplitter(isRtl ? -step : step);
631
+ return true;
632
+ }
633
+ }
634
+ else {
635
+ if (key === "ArrowUp") {
636
+ this.nudgeSplitter(-step);
637
+ return true;
638
+ }
639
+ if (key === "ArrowDown") {
640
+ this.nudgeSplitter(step);
641
+ return true;
642
+ }
643
+ }
644
+ return false;
645
+ }
646
+ measurePaneSize(paneElement) {
647
+ const rect = paneElement.getBoundingClientRect();
648
+ const orientation = this.orientation();
649
+ return orientation === "horizontal" ? rect.width : rect.height;
650
+ }
651
+ nudgeSplitter(delta) {
652
+ this.ensureExpandedBeforeResize();
653
+ const [previousRect, nextRect] = this.getPaneRectangles();
654
+ const total = this.orientation() === "horizontal"
655
+ ? previousRect.width + nextRect.width
656
+ : previousRect.height + nextRect.height;
657
+ const currentPrev = this.orientation() === "horizontal" ? previousRect.width : previousRect.height;
658
+ const desiredPrev = this.clamp(currentPrev + delta, 0, total);
659
+ const [prevSize, nextSize] = this.clampPaneSizes(total, desiredPrev, this.previousPane(), this.nextPane());
660
+ this.updatePaneSizes(`${prevSize}px`, `${nextSize}px`);
661
+ }
662
+ parseSizeInput(value) {
663
+ if (value === null || value === undefined || value === "") {
664
+ return null;
665
+ }
666
+ if (typeof value === "number") {
667
+ return Number.isFinite(value) ? value : null;
668
+ }
669
+ const trimmed = value.trim().toLowerCase();
670
+ const numeric = parseFloat(trimmed.replace("px", ""));
671
+ return Number.isFinite(numeric) ? numeric : null;
672
+ }
673
+ pickTargetPane(direction) {
674
+ const [previousElement, nextElement] = this.getPaneElements();
675
+ const previousPane = this.previousPane();
676
+ const nextPane = this.nextPane();
677
+ if (direction === "previous") {
678
+ if (nextPane.collapsible() && nextPane.collapsed()) {
679
+ return { pane: nextPane, element: nextElement, direction: "next" };
680
+ }
681
+ return { pane: previousPane, element: previousElement, direction: "previous" };
682
+ }
683
+ else {
684
+ if (previousPane.collapsible() && previousPane.collapsed()) {
685
+ return { pane: previousPane, element: previousElement, direction: "previous" };
686
+ }
687
+ return { pane: nextPane, element: nextElement, direction: "next" };
688
+ }
689
+ }
690
+ setHoverEvents() {
691
+ const host = this.#hostElementRef.nativeElement;
692
+ const pointerEnter$ = fromEvent(host, "pointerenter").pipe(map(() => true));
693
+ const pointerLeave$ = fromEvent(host, "pointerleave").pipe(map(() => false));
694
+ merge(pointerEnter$, pointerLeave$)
695
+ .pipe(takeUntilDestroyed(this.#destroyRef))
696
+ .subscribe(isHovered => {
697
+ this.hovered.set(isHovered);
698
+ });
699
+ }
700
+ setKeyboardEvents() {
701
+ fromEvent(this.#hostElementRef.nativeElement, "keydown")
702
+ .pipe(takeUntilDestroyed(this.#destroyRef))
703
+ .subscribe(event => {
704
+ const handled = this.handleKeydown(event);
705
+ if (handled) {
706
+ event.preventDefault();
707
+ event.stopPropagation();
708
+ }
709
+ });
710
+ }
711
+ setPointerEvents() {
712
+ const pointerDown$ = fromEvent(this.#hostElementRef.nativeElement, "pointerdown").pipe(filter(() => this.resizable()), tap(event => {
713
+ event.preventDefault();
714
+ this.#hostElementRef.nativeElement.setPointerCapture(event.pointerId);
715
+ this.resizing.set(true);
716
+ }));
717
+ const pointerUp$ = fromEvent(this.#hostElementRef.nativeElement, "pointerup").pipe(tap(event => {
718
+ this.#hostElementRef.nativeElement.releasePointerCapture(event.pointerId);
719
+ this.resizing.set(false);
720
+ this.setPointerEvents();
721
+ }));
722
+ fromEvent(document, "pointermove")
723
+ .pipe(skipUntil(pointerDown$), takeUntil(pointerUp$))
724
+ .subscribe(event => {
725
+ this.ensureExpandedBeforeResize();
726
+ const orientation = this.orientation();
727
+ if (orientation === "horizontal") {
728
+ this.updateHorizontalPaneSizes(event);
729
+ }
730
+ else {
731
+ this.updateVerticalPaneSizes(event);
732
+ }
733
+ });
734
+ }
735
+ togglePane(targetPane, targetElement, direction) {
736
+ const neighbors = this.getNeighborPanes(targetElement, direction);
737
+ if (targetPane.collapsed()) {
738
+ const storedSize = this.#paneSizeMemory.get(targetPane) ?? this.measurePaneSize(targetElement);
739
+ this.expandPane(targetPane, storedSize, neighbors.leading, neighbors.trailing);
740
+ }
741
+ else {
742
+ const targetSize = this.measurePaneSize(targetElement);
743
+ this.#paneSizeMemory.set(targetPane, targetSize);
744
+ this.collapseAndRedistribute(targetPane, targetSize, neighbors.leading, neighbors.trailing);
745
+ }
746
+ }
747
+ updateAriaSeparatorValues() {
748
+ const [previousRect, nextRect] = this.getPaneRectangles();
749
+ const orientation = this.orientation();
750
+ const previousSize = orientation === "horizontal" ? previousRect.width : previousRect.height;
751
+ const nextSize = orientation === "horizontal" ? nextRect.width : nextRect.height;
752
+ const total = previousSize + nextSize;
753
+ const previousMin = this.getMinSize(this.previousPane());
754
+ const nextMin = this.getMinSize(this.nextPane());
755
+ const previousMaxRaw = this.getMaxSize(this.previousPane());
756
+ const previousMax = Math.min(previousMaxRaw, total - nextMin);
757
+ this.ariaValueMax.set(Math.round(Number.isFinite(previousMax) ? previousMax : total));
758
+ this.ariaValueMin.set(Math.round(previousMin));
759
+ this.ariaValueNow.set(Math.round(previousSize));
760
+ }
761
+ updateHorizontalPaneSizes(event) {
762
+ const [previousRect, nextRect] = this.getPaneRectangles();
763
+ const maxWidth = previousRect.width + nextRect.width;
764
+ const desiredPrevWidth = Math.min(Math.max(event.clientX - previousRect.left, 0), maxWidth);
765
+ const [previousPaneWidth, nextPaneWidth] = this.clampPaneSizes(maxWidth, desiredPrevWidth, this.previousPane(), this.nextPane());
766
+ this.updatePaneSizes(`${previousPaneWidth}px`, `${nextPaneWidth}px`);
767
+ }
768
+ updatePaneSizes(previousPaneSize, nextPaneSize) {
769
+ this.previousPane().collapsed.set(false);
770
+ this.nextPane().collapsed.set(false);
771
+ this.previousPane().size.set(previousPaneSize);
772
+ this.nextPane().size.set(nextPaneSize);
773
+ }
774
+ updateVerticalPaneSizes(event) {
775
+ const [previousRect, nextRect] = this.getPaneRectangles();
776
+ const maxHeight = previousRect.height + nextRect.height;
777
+ const desiredPrevHeight = Math.min(Math.max(event.clientY - previousRect.top, 0), maxHeight);
778
+ const [previousPaneHeight, nextPaneHeight] = this.clampPaneSizes(maxHeight, desiredPrevHeight, this.previousPane(), this.nextPane());
779
+ this.updatePaneSizes(`${previousPaneHeight}px`, `${nextPaneHeight}px`);
780
+ }
781
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SplitterResizerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
782
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.6", type: SplitterResizerComponent, isStandalone: true, selector: "mona-splitter-resizer", inputs: { nextPane: { classPropertyName: "nextPane", publicName: "nextPane", isSignal: true, isRequired: true, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: true, transformFunction: null }, previousPane: { classPropertyName: "previousPane", publicName: "previousPane", isSignal: true, isRequired: true, transformFunction: null } }, host: { attributes: { "role": "separator" }, listeners: { "dblclick": "toggleCollapse()" }, properties: { "class": "baseClass()", "style.cursor": "resizable() ? (orientation()==='horizontal' ? 'ew-resize' : 'ns-resize') : 'auto'", "attr.aria-orientation": "orientation()", "attr.aria-valuemax": "ariaValueMax()", "attr.aria-valuemin": "ariaValueMin()", "attr.aria-valuenow": "ariaValueNow()", "attr.tabindex": "isInert() ? -1 : 0" } }, ngImport: i0, template: "<mona-splitter-resizer-handle\r\n (collapseNext)=\"collapseNext($event)\"\r\n (collapsePrevious)=\"collapsePrevious($event)\"\r\n [nextControlsVisible]=\"nextCollapseControlsVisible()\"\r\n [orientation]=\"orientation()\"\r\n [previousControlsVisible]=\"previousCollapseControlsVisible()\"\r\n [resizable]=\"resizable()\">\r\n</mona-splitter-resizer-handle>\r\n", dependencies: [{ kind: "component", type: SplitterResizerHandleComponent, selector: "mona-splitter-resizer-handle", inputs: ["nextControlsVisible", "orientation", "previousControlsVisible", "resizable"], outputs: ["collapseNext", "collapsePrevious"] }] }); }
783
+ }
784
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SplitterResizerComponent, decorators: [{
785
+ type: Component,
786
+ args: [{ selector: "mona-splitter-resizer", imports: [SplitterResizerHandleComponent], host: {
787
+ "[class]": "baseClass()",
788
+ "[style.cursor]": "resizable() ? (orientation()==='horizontal' ? 'ew-resize' : 'ns-resize') : 'auto'",
789
+ "(dblclick)": "toggleCollapse()",
790
+ role: "separator",
791
+ "[attr.aria-orientation]": "orientation()",
792
+ "[attr.aria-valuemax]": "ariaValueMax()",
793
+ "[attr.aria-valuemin]": "ariaValueMin()",
794
+ "[attr.aria-valuenow]": "ariaValueNow()",
795
+ "[attr.tabindex]": "isInert() ? -1 : 0"
796
+ }, template: "<mona-splitter-resizer-handle\r\n (collapseNext)=\"collapseNext($event)\"\r\n (collapsePrevious)=\"collapsePrevious($event)\"\r\n [nextControlsVisible]=\"nextCollapseControlsVisible()\"\r\n [orientation]=\"orientation()\"\r\n [previousControlsVisible]=\"previousCollapseControlsVisible()\"\r\n [resizable]=\"resizable()\">\r\n</mona-splitter-resizer-handle>\r\n" }]
797
+ }], ctorParameters: () => [], propDecorators: { nextPane: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextPane", required: true }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: true }] }], previousPane: [{ type: i0.Input, args: [{ isSignal: true, alias: "previousPane", required: true }] }] } });
798
+
799
+ class SplitterComponent {
800
+ constructor() {
801
+ this.#themeService = inject(ThemeService);
802
+ this.baseClass = computed(() => {
803
+ const theme = this.#themeService.theme();
804
+ const orientation = this.orientation();
805
+ return splitterBaseThemeVariants(theme)({ orientation });
806
+ }, /* @ts-ignore */
807
+ ...(ngDevMode ? [{ debugName: "baseClass" }] : /* istanbul ignore next */ []));
808
+ this.paneList = contentChildren(SplitterPaneComponent, /* @ts-ignore */
809
+ ...(ngDevMode ? [{ debugName: "paneList" }] : /* istanbul ignore next */ []));
810
+ /**
811
+ * @description The layout direction of the splitter panes.
812
+ * @default "horizontal"
813
+ */
814
+ this.orientation = input("horizontal", /* @ts-ignore */
815
+ ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
816
+ }
817
+ #themeService;
818
+ /**
819
+ * @internal Used by SplitterResizerComponent to resolve sibling panes by id.
820
+ */
821
+ getPaneByUid(uid) {
822
+ return from(this.paneList()).firstOrDefault(pane => pane.uid === uid);
823
+ }
824
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SplitterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
825
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: SplitterComponent, isStandalone: true, selector: "mona-splitter", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "baseClass()" } }, queries: [{ propertyName: "paneList", predicate: SplitterPaneComponent, isSignal: true }], ngImport: i0, template: "@for (pane of paneList(); track pane.uid) {\n <div\n class=\"overflow-hidden min-w-0 min-h-0\"\n [attr.data-pid]=\"pane.uid\"\n [attr.data-px]=\"$index\"\n monaSplitterPaneStyle\n [pane]=\"pane\"\n [paneList]=\"paneList()\">\n <ng-container [ngTemplateOutlet]=\"pane.template()\"></ng-container>\n </div>\n @if ($index !== $count - 1) {\n <mona-splitter-resizer\n [nextPane]=\"paneList()[$index + 1]\"\n [orientation]=\"orientation()!\"\n [previousPane]=\"paneList()[$index]\">\n </mona-splitter-resizer>\n }\n}\n", dependencies: [{ kind: "component", type: SplitterResizerComponent, selector: "mona-splitter-resizer", inputs: ["nextPane", "orientation", "previousPane"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: SplitterPaneStyleDirective, selector: "div[monaSplitterPaneStyle]", inputs: ["pane", "paneList"] }] }); }
826
+ }
827
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SplitterComponent, decorators: [{
828
+ type: Component,
829
+ args: [{ selector: "mona-splitter", imports: [SplitterResizerComponent, NgTemplateOutlet, SplitterPaneStyleDirective], host: {
830
+ "[class]": "baseClass()"
831
+ }, template: "@for (pane of paneList(); track pane.uid) {\n <div\n class=\"overflow-hidden min-w-0 min-h-0\"\n [attr.data-pid]=\"pane.uid\"\n [attr.data-px]=\"$index\"\n monaSplitterPaneStyle\n [pane]=\"pane\"\n [paneList]=\"paneList()\">\n <ng-container [ngTemplateOutlet]=\"pane.template()\"></ng-container>\n </div>\n @if ($index !== $count - 1) {\n <mona-splitter-resizer\n [nextPane]=\"paneList()[$index + 1]\"\n [orientation]=\"orientation()!\"\n [previousPane]=\"paneList()[$index]\">\n </mona-splitter-resizer>\n }\n}\n" }]
832
+ }], propDecorators: { paneList: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SplitterPaneComponent), { isSignal: true }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }] } });
833
+
834
+ /*
835
+ * Public API Surface of @nanahoshi/mona-ui/splitter
836
+ */
837
+
838
+ /**
839
+ * Generated bundle index. Do not edit.
840
+ */
841
+
842
+ export { SplitterComponent, SplitterPaneComponent };
843
+ //# sourceMappingURL=nanahoshi-mona-ui-splitter.mjs.map