@acorex/components 22.1.0-next.2 → 22.1.0-next.21

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 (60) hide show
  1. package/fesm2022/acorex-components-accordion.mjs +2 -2
  2. package/fesm2022/acorex-components-accordion.mjs.map +1 -1
  3. package/fesm2022/acorex-components-button.mjs +2 -2
  4. package/fesm2022/acorex-components-button.mjs.map +1 -1
  5. package/fesm2022/acorex-components-check-box.mjs +2 -2
  6. package/fesm2022/acorex-components-check-box.mjs.map +1 -1
  7. package/fesm2022/acorex-components-combo-box.mjs +114 -20
  8. package/fesm2022/acorex-components-combo-box.mjs.map +1 -1
  9. package/fesm2022/{acorex-components-conversation-open-composer-picker-for-files-BuNEjswI.mjs → acorex-components-conversation-open-composer-picker-for-files-DnSW908R.mjs} +6 -19
  10. package/fesm2022/acorex-components-conversation-open-composer-picker-for-files-DnSW908R.mjs.map +1 -0
  11. package/fesm2022/acorex-components-conversation.mjs +7299 -9510
  12. package/fesm2022/acorex-components-conversation.mjs.map +1 -1
  13. package/fesm2022/acorex-components-data-table.mjs +33 -18
  14. package/fesm2022/acorex-components-data-table.mjs.map +1 -1
  15. package/fesm2022/acorex-components-dropdown.mjs +2 -2
  16. package/fesm2022/acorex-components-dropdown.mjs.map +1 -1
  17. package/fesm2022/acorex-components-form.mjs +21 -5
  18. package/fesm2022/acorex-components-form.mjs.map +1 -1
  19. package/fesm2022/acorex-components-label.mjs +2 -2
  20. package/fesm2022/acorex-components-label.mjs.map +1 -1
  21. package/fesm2022/acorex-components-list.mjs +2 -2
  22. package/fesm2022/acorex-components-list.mjs.map +1 -1
  23. package/fesm2022/acorex-components-loading-dialog.mjs +59 -42
  24. package/fesm2022/acorex-components-loading-dialog.mjs.map +1 -1
  25. package/fesm2022/acorex-components-lookup.mjs +765 -98
  26. package/fesm2022/acorex-components-lookup.mjs.map +1 -1
  27. package/fesm2022/acorex-components-notification.mjs +4 -6
  28. package/fesm2022/acorex-components-notification.mjs.map +1 -1
  29. package/fesm2022/acorex-components-password-box.mjs +2 -2
  30. package/fesm2022/acorex-components-password-box.mjs.map +1 -1
  31. package/fesm2022/acorex-components-popover.mjs +22 -0
  32. package/fesm2022/acorex-components-popover.mjs.map +1 -1
  33. package/fesm2022/acorex-components-radio.mjs +2 -2
  34. package/fesm2022/acorex-components-radio.mjs.map +1 -1
  35. package/fesm2022/acorex-components-range-slider.mjs +2 -2
  36. package/fesm2022/acorex-components-range-slider.mjs.map +1 -1
  37. package/fesm2022/acorex-components-select-box.mjs +38 -11
  38. package/fesm2022/acorex-components-select-box.mjs.map +1 -1
  39. package/fesm2022/acorex-components-selection-list.mjs +2 -2
  40. package/fesm2022/acorex-components-selection-list.mjs.map +1 -1
  41. package/fesm2022/acorex-components-switch.mjs +2 -2
  42. package/fesm2022/acorex-components-switch.mjs.map +1 -1
  43. package/fesm2022/acorex-components-tabs.mjs +2 -2
  44. package/fesm2022/acorex-components-tabs.mjs.map +1 -1
  45. package/fesm2022/acorex-components-tag-box.mjs +2 -2
  46. package/fesm2022/acorex-components-tag-box.mjs.map +1 -1
  47. package/lookup/README.md +29 -7
  48. package/package.json +4 -7
  49. package/types/acorex-components-combo-box.d.ts +38 -8
  50. package/types/acorex-components-conversation.d.ts +543 -1019
  51. package/types/acorex-components-data-table.d.ts +3 -2
  52. package/types/acorex-components-loading-dialog.d.ts +12 -4
  53. package/types/acorex-components-lookup.d.ts +181 -21
  54. package/types/acorex-components-popover.d.ts +6 -0
  55. package/types/acorex-components-select-box.d.ts +11 -0
  56. package/fesm2022/acorex-components-conversation-open-composer-picker-for-files-BuNEjswI.mjs.map +0 -1
  57. package/fesm2022/acorex-components-selection-list-2.mjs +0 -168
  58. package/fesm2022/acorex-components-selection-list-2.mjs.map +0 -1
  59. package/selection-list-2/README.md +0 -3
  60. package/types/acorex-components-selection-list-2.d.ts +0 -52
@@ -428,7 +428,7 @@ declare class AXDataTableTextColumnComponent extends AXDataTableColumnComponent
428
428
  /**
429
429
  * @ignore
430
430
  */
431
- protected handleExpandRow(row: any): Promise<void>;
431
+ protected handleExpandRow(row: any, event?: Event): Promise<void>;
432
432
  /**
433
433
  * Generates a unique name based on the `dataField` value.
434
434
  */
@@ -641,7 +641,7 @@ declare class AXRowExpandColumnComponent extends AXDataTableColumnComponent {
641
641
  /**
642
642
  * @ignore
643
643
  */
644
- protected handleExpandRow(row: any): Promise<void>;
644
+ protected handleExpandRow(row: any, event?: Event): Promise<void>;
645
645
  /**
646
646
  * Indicates whether loading is enabled for the column.
647
647
  */
@@ -1051,6 +1051,7 @@ declare class AXDataTableComponent extends AXBaseDataTable implements OnInit, Af
1051
1051
  * @ignore
1052
1052
  */
1053
1053
  ngOnInit(): void;
1054
+ private applyLoadedRows;
1054
1055
  /**
1055
1056
  * @ignore
1056
1057
  */
@@ -1,6 +1,7 @@
1
1
  import { AXStyleColorType, AXStyleLookType, AXHotKeyAction, MXBaseComponent } from '@acorex/cdk/common';
2
2
  import { AXOverlayRef } from '@acorex/cdk/overlay';
3
3
  import { AXDialogButtonItem } from '@acorex/components/dialog';
4
+ import { AXPopupSizeType, AXPopupRef } from '@acorex/components/popup';
4
5
  import { AXProgressMode } from '@acorex/components/progress-bar';
5
6
  import * as _angular_core from '@angular/core';
6
7
  import { OnInit } from '@angular/core';
@@ -13,6 +14,8 @@ interface AXLoadingDialogConfig {
13
14
  progressValue?: number;
14
15
  progressColor?: AXStyleColorType;
15
16
  progressHeight?: number;
17
+ /** Popup size token. Uses the same responsive sizes as `AXPopupService`. @default 'sm' */
18
+ size?: AXPopupSizeType;
16
19
  buttons?: AXLoadingDialogButtonItem[];
17
20
  }
18
21
  interface AXLoadingDialogButtonItem {
@@ -43,7 +46,7 @@ interface AXLoadingDialogRef {
43
46
  type AXDialogRef = AXLoadingDialogRef;
44
47
  /**
45
48
  * @internal
46
- * Internal reference used by loading dialog service to manage overlay instances
49
+ * Internal reference used by loading dialog service to manage overlay instances.
47
50
  */
48
51
  interface AXLoadingDialogInternalRef {
49
52
  overlayRef: AXOverlayRef<unknown>;
@@ -57,8 +60,13 @@ interface AXLoadingDialogInternalRef {
57
60
  declare class AXLoadingDialogComponent extends MXBaseComponent implements OnInit {
58
61
  /** Loading dialog configuration data */
59
62
  data: _angular_core.InputSignal<AXLoadingDialogConfig>;
60
- /** @internal Callback function to close the dialog */
63
+ /** Callback function to close the dialog */
61
64
  onClose: _angular_core.InputSignal<() => void>;
65
+ /**
66
+ * Injected by {@link AXPopupComponent} when this dialog is opened via {@link AXPopupService}.
67
+ * @internal
68
+ */
69
+ readonly __popup__: _angular_core.InputSignal<AXPopupRef<any>>;
62
70
  /** @ignore */
63
71
  protected progressText: _angular_core.WritableSignal<string>;
64
72
  /** @ignore */
@@ -116,7 +124,7 @@ declare class AXLoadingDialogComponent extends MXBaseComponent implements OnInit
116
124
  /** @ignore */
117
125
  protected _hasAutoFocus(button: AXLoadingDialogButtonItem): boolean;
118
126
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXLoadingDialogComponent, never>;
119
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXLoadingDialogComponent, "ax-loading-dialog", never, { "data": { "alias": "data"; "required": true; "isSignal": true; }; "onClose": { "alias": "onClose"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
127
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXLoadingDialogComponent, "ax-loading-dialog", never, { "data": { "alias": "data"; "required": true; "isSignal": true; }; "onClose": { "alias": "onClose"; "required": false; "isSignal": true; }; "__popup__": { "alias": "__popup__"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
120
128
  }
121
129
 
122
130
  declare class AXLoadingDialogModule {
@@ -126,7 +134,7 @@ declare class AXLoadingDialogModule {
126
134
  }
127
135
 
128
136
  declare class AXLoadingDialogService {
129
- private overlayService;
137
+ private popupService;
130
138
  /**
131
139
  * Opens a loading dialog with the specified configuration.
132
140
  *
@@ -1,7 +1,8 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { TemplateRef, ElementRef } from '@angular/core';
3
- import { AXEvent, AXDataSource, AXListDataSource, AXHtmlEvent, NXComponent, AXStyleLookType, AXValueChangedEvent, AXFocusEvent, AXItemClickEvent, AXItemSelectedEvent } from '@acorex/cdk/common';
3
+ import { AXEvent, AXDataSource, AXListDataSource, AXHtmlEvent, NXValueComponent, AXStyleLookType, AXValueChangedEvent, AXFocusEvent, AXItemClickEvent, AXItemSelectedEvent } from '@acorex/cdk/common';
4
4
  import { AXPopoverComponent } from '@acorex/components/popover';
5
+ import { AXSearchBoxComponent } from '@acorex/components/search-box';
5
6
  import { AXTreeViewNode, AXTreeViewDataSource, AXTreeViewSelectionBehavior, AXTreeViewItemTemplateContext, AXTreeViewSelectionChangeEvent } from '@acorex/components/tree-view';
6
7
  import { FormValueControl } from '@angular/forms/signals';
7
8
  import { AXListNavigationDirective, AXListNavigationItemDirective } from '@acorex/cdk/list-navigation';
@@ -16,19 +17,25 @@ import { AXDataTableComponent, AXDataTableRowClick } from '@acorex/components/da
16
17
  * - `drop-down-tree` — a tree-like structure for single item selection.
17
18
  * - `multi-select-tree` — a tree-like structure for multiple item selection.
18
19
  * - `multi-column` — a table-structured list for single selection.
20
+ * - `multi-column-tree` — a multi-column table with a drop-down tree inside it (expandable rows).
19
21
  */
20
- type AXLookupMode = 'drop-down-list' | 'multi-select' | 'drop-down-tree' | 'multi-select-tree' | 'multi-column';
22
+ type AXLookupMode = 'drop-down-list' | 'multi-select' | 'drop-down-tree' | 'multi-select-tree' | 'multi-column' | 'multi-column-tree';
21
23
  /**
22
- * A column definition for the `multi-column` lookup mode (rendered via `ax-data-table`).
24
+ * A column definition for the `multi-column` and `multi-column-tree` lookup modes
25
+ * (rendered via `ax-data-table`).
23
26
  *
24
27
  * - `field` — the item property rendered in this column (`ax-text-column` `dataField`).
25
28
  * - `title` — the header text of the column (`ax-text-column` `caption`).
26
29
  * - `width` — optional column width (`120px`, `20%`, or `auto`). Defaults to `auto`.
30
+ * - `expandHandler` — when `true`, this column shows the tree expand/collapse control
31
+ * (`multi-column-tree` only). If omitted, the column matching `textField` (or the first
32
+ * column) is used.
27
33
  */
28
34
  interface AXLookupColumn {
29
35
  field: string;
30
36
  title: string;
31
37
  width?: string;
38
+ expandHandler?: boolean;
32
39
  }
33
40
  /**
34
41
  * A lookup item. Items are plain records; the lookup reads them through
@@ -113,7 +120,13 @@ declare abstract class AXLookupListViewBase {
113
120
  protected listDataSource: _angular_core.WritableSignal<AXListDataSource<AXLookupItem>>;
114
121
  protected totalCount: _angular_core.WritableSignal<number>;
115
122
  protected isLoading: _angular_core.WritableSignal<boolean>;
123
+ protected readonly loadingPlaceholderIndexes: number[];
116
124
  protected isEmpty: _angular_core.Signal<boolean>;
125
+ /**
126
+ * Overlay popovers often measure as 0px on first open, so CDK virtual scroll
127
+ * renders no rows. Paint these placeholders outside the viewport until data arrives.
128
+ */
129
+ protected showLoadingPlaceholder: _angular_core.Signal<boolean>;
117
130
  /** Viewport height so the popup grows with the items up to `maxVisibleItems`. */
118
131
  protected viewportHeight: _angular_core.Signal<number>;
119
132
  protected viewportRef: _angular_core.Signal<CdkVirtualScrollViewport>;
@@ -127,6 +140,11 @@ declare abstract class AXLookupListViewBase {
127
140
  protected isSelected(item: AXLookupItem): boolean;
128
141
  protected isDisabled(item: AXLookupItem): boolean;
129
142
  protected handleItemClick(item: AXLookupItem | null | undefined): void;
143
+ /**
144
+ * Commit on mousedown (not click) so a searchable trigger blur cannot destroy the
145
+ * list before the pick is applied.
146
+ */
147
+ protected handleItemMouseDown(event: Event, item: AXLookupItem | null | undefined): void;
130
148
  protected handleItemKeypress(e: AXHtmlEvent<KeyboardEvent>, item: AXLookupItem | null | undefined): void;
131
149
  protected handleListKeypress(e: AXHtmlEvent<KeyboardEvent>): void;
132
150
  protected activateNavItem(nav: AXListNavigationDirective, item: AXListNavigationItemDirective): void;
@@ -188,14 +206,17 @@ declare class AXLookupMultiSelectTreeComponent {
188
206
  }
189
207
 
190
208
  /**
191
- * An advanced drop-down (lookup) editor with five modes, `AXDataSource` support, and virtual scrolling.
209
+ * An advanced drop-down (lookup) editor with six modes, `AXDataSource` support, and virtual scrolling.
192
210
  *
193
211
  * Modes (each rendered by its own internal mini component):
194
212
  * - `drop-down-list` — a predefined list of options for picking single values.
195
213
  * - `multi-select` — a predefined list of options for multiple item selection (chips in the trigger).
196
214
  * - `drop-down-tree` — a predefined list rendered in a tree-like structure for single item selection.
197
215
  * - `multi-select-tree` — a tree-like structure for multiple item selection.
198
- * - `multi-column` — an `ax-data-table` grid; when searchable, the trigger input filters as you type.
216
+ * - `multi-column` — an `ax-data-table` grid; when searchable, the trigger input filters as you type
217
+ * (on small screens the search field is inside the actionsheet).
218
+ * - `multi-column-tree` — a multi-column `ax-data-table` with a drop-down tree inside it
219
+ * (expandable hierarchical rows). Uses `treeDataSource` + `columns`, or a hierarchical `dataSource`.
199
220
  *
200
221
  * With `adaptivityEnabled` (default `true`), the list opens as a bottom actionsheet on small
201
222
  * screens instead of an anchored dropdown — the same alternate presentation as `ax-select-box`.
@@ -205,19 +226,24 @@ declare class AXLookupMultiSelectTreeComponent {
205
226
  *
206
227
  * @category Components
207
228
  */
208
- declare class AXLookupComponent extends NXComponent implements FormValueControl<unknown | unknown[] | null> {
229
+ declare class AXLookupComponent extends NXValueComponent implements FormValueControl<unknown | unknown[] | null> {
209
230
  #private;
231
+ /**
232
+ * The name of the form field, used by validation rules and `ax-form.validate(names)`.
233
+ */
234
+ name: _angular_core.InputSignal<string>;
210
235
  /**
211
236
  * The lookup rendering mode. Selects which mini component renders in the popup.
212
237
  */
213
238
  mode: _angular_core.InputSignal<AXLookupMode>;
214
239
  /**
215
- * The items source for list-based modes (`drop-down-list`, `multi-select`, `multi-column`).
240
+ * The items source for list-based modes (`drop-down-list`, `multi-select`, `multi-column`)
241
+ * and for `multi-column-tree` when `treeDataSource` is not set.
216
242
  * Accepts an `AXDataSource` (remote paging, `byKey`, server-side filter) or a plain array.
217
243
  */
218
244
  dataSource: _angular_core.InputSignal<AXLookupItem[] | AXDataSource<AXLookupItem>>;
219
245
  /**
220
- * The nodes source for tree modes (`drop-down-tree`, `multi-select-tree`):
246
+ * The nodes source for tree modes (`drop-down-tree`, `multi-select-tree`, `multi-column-tree`):
221
247
  * an array of nodes or a lazy children callback.
222
248
  */
223
249
  treeDataSource: _angular_core.InputSignal<AXTreeViewDataSource>;
@@ -235,18 +261,33 @@ declare class AXLookupComponent extends NXComponent implements FormValueControl<
235
261
  */
236
262
  disabledField: _angular_core.InputSignal<string>;
237
263
  /**
238
- * Column definitions for the `multi-column` mode (rendered as `ax-text-column` in `ax-data-table`).
264
+ * Column definitions for the `multi-column` and `multi-column-tree` modes
265
+ * (rendered as `ax-text-column` in `ax-data-table`).
239
266
  */
240
267
  columns: _angular_core.InputSignal<AXLookupColumn[]>;
268
+ /**
269
+ * Field used by `multi-column-tree` to fetch children when a row is expanded
270
+ * (`AXDataSource` filter). Defaults to `parentId`. Nested `children` arrays are also supported.
271
+ */
272
+ treeParentField: _angular_core.InputSignal<string>;
273
+ /**
274
+ * Field used by `multi-column-tree` to decide whether a row shows an expand control.
275
+ * Defaults to `hasChild`. Nodes with `children` / `childrenCount` are mapped automatically
276
+ * when using `treeDataSource`.
277
+ */
278
+ hasChildrenField: _angular_core.InputSignal<string>;
241
279
  /**
242
280
  * Whether the trigger accepts typing and filters the datasource (`true`),
243
281
  * or is select-only with no writable input (`false`).
244
- * Applies to `drop-down-list`, `multi-select`, and `multi-column`. Tree modes ignore this.
282
+ * Applies to `drop-down-list`, `multi-select`, `multi-column`, and `multi-column-tree`.
283
+ * Tree-only modes (`drop-down-tree`, `multi-select-tree`) ignore this.
284
+ * On small screens with `adaptivityEnabled`, search is typed in the actionsheet instead of the trigger.
245
285
  */
246
286
  searchable: _angular_core.InputSignal<boolean>;
247
287
  /**
248
288
  * When `true` (default), the popup list uses the alternate actionsheet presentation on small
249
- * screens (`SM`). When `false`, the list always opens as an anchored dropdown.
289
+ * screens (`SM`). Searchable list modes then show a search field inside the sheet. When `false`,
290
+ * the list always opens as an anchored dropdown.
250
291
  */
251
292
  adaptivityEnabled: _angular_core.InputSignal<boolean>;
252
293
  /**
@@ -255,12 +296,13 @@ declare class AXLookupComponent extends NXComponent implements FormValueControl<
255
296
  caption: _angular_core.InputSignal<string>;
256
297
  /**
257
298
  * When `true`, list rows use alternating background colors for easier scanning
258
- * (`drop-down-list`, `multi-select`, and `multi-column` modes).
299
+ * (`drop-down-list`, `multi-select`, `multi-column`, and `multi-column-tree` modes).
259
300
  */
260
301
  alternate: _angular_core.InputSignal<boolean>;
261
302
  /**
262
303
  * Placeholder for the trigger search input when items are already selected
263
- * (mainly useful in `multi-select`). Falls back to `placeholder` when the selection is empty.
304
+ * (mainly useful in `multi-select`), and for the in-sheet search field on small screens.
305
+ * Falls back to `placeholder` when the selection is empty on desktop.
264
306
  */
265
307
  searchPlaceholder: _angular_core.InputSignal<string>;
266
308
  /**
@@ -313,6 +355,12 @@ declare class AXLookupComponent extends NXComponent implements FormValueControl<
313
355
  * via {@link FormValueControl}.
314
356
  */
315
357
  readonly value: _angular_core.ModelSignal<unknown>;
358
+ /**
359
+ * Full items that resolve the current `value` key(s) without calling datasource `byKey`.
360
+ * Use when the parent already has the selected entity (e.g. edit forms). Seeds the internal
361
+ * item cache; missing keys still fall through to `find` / `byKey`.
362
+ */
363
+ valueItems: _angular_core.InputSignal<AXLookupItem[]>;
316
364
  /**
317
365
  * Emitted when the selected value changes.
318
366
  */
@@ -353,10 +401,17 @@ declare class AXLookupComponent extends NXComponent implements FormValueControl<
353
401
  protected isMultiple: _angular_core.Signal<boolean>;
354
402
  /** Whether the current mode renders a tree. */
355
403
  protected isTreeMode: _angular_core.Signal<boolean>;
356
- /** Whether the trigger input is writable and filters as you type. */
404
+ /** Whether the current mode can filter a list/table as you type. */
405
+ protected isListSearchMode: _angular_core.Signal<boolean>;
406
+ /** Whether the trigger input is writable and filters as you type (desktop only). */
357
407
  protected isEditableTrigger: _angular_core.Signal<boolean>;
408
+ /** Whether search is typed in the actionsheet instead of the trigger. */
409
+ protected isSheetSearchEnabled: _angular_core.Signal<boolean>;
410
+ /** Query typed in the actionsheet search field (independent of the trigger display text). */
411
+ protected sheetSearchText: _angular_core.WritableSignal<string>;
358
412
  /** The datasource for list-based modes; plain arrays are converted. */
359
413
  protected resolvedDataSource: _angular_core.Signal<AXDataSource<AXLookupItem>>;
414
+ protected resolvedTreeDataSource: _angular_core.Signal<AXTreeViewDataSource>;
360
415
  /** The current selection normalized to an array. */
361
416
  protected selectedValues: _angular_core.Signal<unknown[]>;
362
417
  /** The resolved selected items (via cache, datasource `find`/`byKey`, or tree node lookup). */
@@ -374,9 +429,12 @@ declare class AXLookupComponent extends NXComponent implements FormValueControl<
374
429
  * the selected display text (same pattern as combo-box).
375
430
  */
376
431
  protected showSelectedTemplate: _angular_core.Signal<boolean>;
432
+ /** Placeholder for the editable trigger search input. */
433
+ protected triggerSearchPlaceholder: _angular_core.Signal<string>;
377
434
  protected popoverRef: _angular_core.Signal<AXPopoverComponent>;
378
435
  protected triggerSearchInput: _angular_core.Signal<ElementRef<HTMLInputElement>>;
379
436
  protected listView: _angular_core.Signal<AXLookupListViewBase>;
437
+ protected sheetSearchRef: _angular_core.Signal<AXSearchBoxComponent>;
380
438
  constructor();
381
439
  /** Returns the display text of an item using the `textField` mapping. */
382
440
  protected getItemText(item: AXLookupItem): string;
@@ -397,7 +455,7 @@ declare class AXLookupComponent extends NXComponent implements FormValueControl<
397
455
  /** Blocks typing when the trigger is not editable (keeps Tab / keyboard open working). */
398
456
  protected onBeforeInput(event: Event): void;
399
457
  /**
400
- * Returns focus to the trigger input when list navigation requests it.
458
+ * Returns focus to the search field when list navigation requests it.
401
459
  */
402
460
  protected onListNavigateOut(_reason: 'up' | 'typeahead'): void;
403
461
  protected focusListFirst(): void;
@@ -422,10 +480,10 @@ declare class AXLookupComponent extends NXComponent implements FormValueControl<
422
480
  * Handles typing in the editable trigger input.
423
481
  */
424
482
  protected onTriggerSearchInput(text: string): void;
425
- /** Placeholder for the editable trigger search input. */
426
- protected triggerSearchPlaceholder: _angular_core.Signal<string>;
483
+ /** Filters the datasource from the actionsheet search field (reads the input so delayed ngModel cannot block typing). */
484
+ protected onSheetSearchInput(): void;
427
485
  /**
428
- * Commits a single pick (drop-down-list, drop-down-tree, multi-column) and closes the popup.
486
+ * Commits a single pick (drop-down-list, drop-down-tree, multi-column, multi-column-tree) and closes the popup.
429
487
  */
430
488
  protected handleSinglePick(e: AXLookupItemClickEvent): void;
431
489
  /**
@@ -445,6 +503,13 @@ declare class AXLookupComponent extends NXComponent implements FormValueControl<
445
503
  * Removes a single chip from the multi selection.
446
504
  */
447
505
  protected removeChip(event: Event, item: AXLookupItem): void;
506
+ /**
507
+ * Seeds the item cache with known items so matching `value` keys resolve without `byKey`.
508
+ * Useful after an async parent-entity load when `valueItems` is not bound.
509
+ *
510
+ * @param items - Full items that include `valueField` (and ideally `textField`) properties.
511
+ */
512
+ seedItems(items: AXLookupItem[]): void;
448
513
  /**
449
514
  * Clears the whole selection.
450
515
  * Sets `null` in single modes and `[]` in multi modes. Used by projected `ax-clear-button`.
@@ -453,7 +518,7 @@ declare class AXLookupComponent extends NXComponent implements FormValueControl<
453
518
  */
454
519
  reset(isUserInteraction?: boolean): void;
455
520
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXLookupComponent, never>;
456
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXLookupComponent, "ax-lookup", never, { "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "dataSource": { "alias": "dataSource"; "required": false; "isSignal": true; }; "treeDataSource": { "alias": "treeDataSource"; "required": false; "isSignal": true; }; "valueField": { "alias": "valueField"; "required": false; "isSignal": true; }; "textField": { "alias": "textField"; "required": false; "isSignal": true; }; "disabledField": { "alias": "disabledField"; "required": false; "isSignal": true; }; "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "adaptivityEnabled": { "alias": "adaptivityEnabled"; "required": false; "isSignal": true; }; "caption": { "alias": "caption"; "required": false; "isSignal": true; }; "alternate": { "alias": "alternate"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "look": { "alias": "look"; "required": false; "isSignal": true; }; "itemHeight": { "alias": "itemHeight"; "required": false; "isSignal": true; }; "maxVisibleItems": { "alias": "maxVisibleItems"; "required": false; "isSignal": true; }; "treeSelectionBehavior": { "alias": "treeSelectionBehavior"; "required": false; "isSignal": true; }; "itemTemplate": { "alias": "itemTemplate"; "required": false; "isSignal": true; }; "selectedTemplate": { "alias": "selectedTemplate"; "required": false; "isSignal": true; }; "emptyTemplate": { "alias": "emptyTemplate"; "required": false; "isSignal": true; }; "loadingTemplate": { "alias": "loadingTemplate"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "look": "lookChange"; "value": "valueChange"; "onValueChanged": "onValueChanged"; "onSelectionChanged": "onSelectionChanged"; "onFocus": "onFocus"; "onBlur": "onBlur"; "onItemClick": "onItemClick"; "onItemSelected": "onItemSelected"; "onOpened": "onOpened"; "onClosed": "onClosed"; }, never, ["ax-prefix", "ax-clear-button", "ax-suffix", "ax-header", "ax-footer"], true, never>;
521
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXLookupComponent, "ax-lookup", never, { "name": { "alias": "name"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "dataSource": { "alias": "dataSource"; "required": false; "isSignal": true; }; "treeDataSource": { "alias": "treeDataSource"; "required": false; "isSignal": true; }; "valueField": { "alias": "valueField"; "required": false; "isSignal": true; }; "textField": { "alias": "textField"; "required": false; "isSignal": true; }; "disabledField": { "alias": "disabledField"; "required": false; "isSignal": true; }; "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "treeParentField": { "alias": "treeParentField"; "required": false; "isSignal": true; }; "hasChildrenField": { "alias": "hasChildrenField"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "adaptivityEnabled": { "alias": "adaptivityEnabled"; "required": false; "isSignal": true; }; "caption": { "alias": "caption"; "required": false; "isSignal": true; }; "alternate": { "alias": "alternate"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "look": { "alias": "look"; "required": false; "isSignal": true; }; "itemHeight": { "alias": "itemHeight"; "required": false; "isSignal": true; }; "maxVisibleItems": { "alias": "maxVisibleItems"; "required": false; "isSignal": true; }; "treeSelectionBehavior": { "alias": "treeSelectionBehavior"; "required": false; "isSignal": true; }; "itemTemplate": { "alias": "itemTemplate"; "required": false; "isSignal": true; }; "selectedTemplate": { "alias": "selectedTemplate"; "required": false; "isSignal": true; }; "emptyTemplate": { "alias": "emptyTemplate"; "required": false; "isSignal": true; }; "loadingTemplate": { "alias": "loadingTemplate"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "valueItems": { "alias": "valueItems"; "required": false; "isSignal": true; }; }, { "look": "lookChange"; "value": "valueChange"; "onValueChanged": "onValueChanged"; "onSelectionChanged": "onSelectionChanged"; "onFocus": "onFocus"; "onBlur": "onBlur"; "onItemClick": "onItemClick"; "onItemSelected": "onItemSelected"; "onOpened": "onOpened"; "onClosed": "onClosed"; }, never, ["ax-prefix", "ax-clear-button", "ax-suffix", "ax-header", "ax-footer", "ax-validation-rule"], true, never>;
457
522
  }
458
523
 
459
524
  /**
@@ -607,6 +672,7 @@ declare class AXLookupMultiColumnComponent {
607
672
  protected resolveRowCssClass: (row: unknown) => string;
608
673
  protected handleRowClick(event: AXDataTableRowClick): void;
609
674
  protected handleItemClick(item: AXLookupItem | null | undefined): void;
675
+ protected handleItemMouseDown(event: Event, item: AXLookupItem | null | undefined): void;
610
676
  protected isSelected(item: AXLookupItem): boolean;
611
677
  protected isDisabled(item: AXLookupItem): boolean;
612
678
  private getValue;
@@ -614,11 +680,105 @@ declare class AXLookupMultiColumnComponent {
614
680
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXLookupMultiColumnComponent, "ax-lookup-multi-column", never, { "dataSource": { "alias": "dataSource"; "required": true; "isSignal": true; }; "valueField": { "alias": "valueField"; "required": false; "isSignal": true; }; "textField": { "alias": "textField"; "required": false; "isSignal": true; }; "disabledField": { "alias": "disabledField"; "required": false; "isSignal": true; }; "selectedValues": { "alias": "selectedValues"; "required": false; "isSignal": true; }; "itemHeight": { "alias": "itemHeight"; "required": false; "isSignal": true; }; "maxVisibleItems": { "alias": "maxVisibleItems"; "required": false; "isSignal": true; }; "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "itemTemplate": { "alias": "itemTemplate"; "required": false; "isSignal": true; }; "emptyTemplate": { "alias": "emptyTemplate"; "required": false; "isSignal": true; }; "loadingTemplate": { "alias": "loadingTemplate"; "required": false; "isSignal": true; }; "alternate": { "alias": "alternate"; "required": false; "isSignal": true; }; }, { "itemClick": "itemClick"; }, never, never, true, never>;
615
681
  }
616
682
 
683
+ /**
684
+ * Internal mini component for the `multi-column-tree` lookup mode:
685
+ * a multi-column `ax-data-table` with a drop-down tree inside it.
686
+ * Rows expand/collapse via the data-table hierarchy (`parentField` / nested `children`).
687
+ *
688
+ * @category Components
689
+ */
690
+ declare class AXLookupMultiColumnTreeComponent {
691
+ /**
692
+ * The datasource providing hierarchical rows (roots on load, children via `parentField`).
693
+ */
694
+ dataSource: _angular_core.InputSignal<AXDataSource<AXLookupItem>>;
695
+ /**
696
+ * The item property used as the selection value (also the data-table row key).
697
+ */
698
+ valueField: _angular_core.InputSignal<string>;
699
+ /**
700
+ * The item property used as the display text. The matching column shows the expand control
701
+ * unless another column sets `expandHandler`.
702
+ */
703
+ textField: _angular_core.InputSignal<string>;
704
+ /**
705
+ * The item property marking an item as disabled.
706
+ */
707
+ disabledField: _angular_core.InputSignal<string>;
708
+ /**
709
+ * Field used by the data table to fetch children (`AXDataSource` filter on expand).
710
+ */
711
+ parentField: _angular_core.InputSignal<string>;
712
+ /**
713
+ * Field used by the data table to decide whether a row can expand.
714
+ */
715
+ hasChildrenField: _angular_core.InputSignal<string>;
716
+ /**
717
+ * Currently selected values (always an array, even for single selection).
718
+ */
719
+ selectedValues: _angular_core.InputSignal<unknown[]>;
720
+ /**
721
+ * The fixed row height in pixels passed to the data table.
722
+ */
723
+ itemHeight: _angular_core.InputSignal<number>;
724
+ /**
725
+ * The maximum number of body rows visible before the table scrolls.
726
+ */
727
+ maxVisibleItems: _angular_core.InputSignal<number>;
728
+ /**
729
+ * Column definitions rendered as `ax-text-column` instances.
730
+ */
731
+ columns: _angular_core.InputSignal<AXLookupColumn[]>;
732
+ /**
733
+ * Optional custom row content. Context: `$implicit` is the row item.
734
+ * When set, replaces the default multi-column cell layout.
735
+ */
736
+ itemTemplate: _angular_core.InputSignal<TemplateRef<unknown>>;
737
+ /**
738
+ * Custom template rendered when the datasource has no items.
739
+ */
740
+ emptyTemplate: _angular_core.InputSignal<TemplateRef<unknown>>;
741
+ /**
742
+ * Custom template rendered while the table is loading.
743
+ */
744
+ loadingTemplate: _angular_core.InputSignal<TemplateRef<unknown>>;
745
+ /**
746
+ * When `true`, table rows use alternating background colors for easier scanning.
747
+ */
748
+ alternate: _angular_core.InputSignal<boolean>;
749
+ /**
750
+ * Emitted when the user picks a row (not when expanding/collapsing).
751
+ */
752
+ itemClick: _angular_core.OutputEmitterRef<AXLookupItemClickEvent>;
753
+ /**
754
+ * Header (~40px) + up to `maxVisibleItems` body rows. Expanded children scroll inside.
755
+ */
756
+ protected tableHeight: _angular_core.Signal<number>;
757
+ protected loadingConfig: _angular_core.Signal<{
758
+ enabled: boolean;
759
+ animation: boolean;
760
+ loadingTemplate: TemplateRef<unknown>;
761
+ }>;
762
+ /** Stable unique key for `@for` — avoids NG0955 when `field` is missing or duplicated. */
763
+ protected trackColumnKey(index: number, column: AXLookupColumn): string;
764
+ protected resolveColumnWidth(column: AXLookupColumn): string | number | 'auto';
765
+ protected isExpandColumn(index: number, column: AXLookupColumn): boolean;
766
+ protected resolveRowCssClass: (row: unknown) => string;
767
+ protected handleRowClick(event: AXDataTableRowClick): void;
768
+ protected handleItemClick(item: AXLookupItem | null | undefined): void;
769
+ protected handleItemMouseDown(event: Event, item: AXLookupItem | null | undefined): void;
770
+ protected isSelected(item: AXLookupItem): boolean;
771
+ protected isDisabled(item: AXLookupItem): boolean;
772
+ private getValue;
773
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXLookupMultiColumnTreeComponent, never>;
774
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXLookupMultiColumnTreeComponent, "ax-lookup-multi-column-tree", never, { "dataSource": { "alias": "dataSource"; "required": true; "isSignal": true; }; "valueField": { "alias": "valueField"; "required": false; "isSignal": true; }; "textField": { "alias": "textField"; "required": false; "isSignal": true; }; "disabledField": { "alias": "disabledField"; "required": false; "isSignal": true; }; "parentField": { "alias": "parentField"; "required": false; "isSignal": true; }; "hasChildrenField": { "alias": "hasChildrenField"; "required": false; "isSignal": true; }; "selectedValues": { "alias": "selectedValues"; "required": false; "isSignal": true; }; "itemHeight": { "alias": "itemHeight"; "required": false; "isSignal": true; }; "maxVisibleItems": { "alias": "maxVisibleItems"; "required": false; "isSignal": true; }; "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "itemTemplate": { "alias": "itemTemplate"; "required": false; "isSignal": true; }; "emptyTemplate": { "alias": "emptyTemplate"; "required": false; "isSignal": true; }; "loadingTemplate": { "alias": "loadingTemplate"; "required": false; "isSignal": true; }; "alternate": { "alias": "alternate"; "required": false; "isSignal": true; }; }, { "itemClick": "itemClick"; }, never, never, true, never>;
775
+ }
776
+
617
777
  declare class AXLookupModule {
618
778
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXLookupModule, never>;
619
- static ɵmod: _angular_core.ɵɵNgModuleDeclaration<AXLookupModule, never, [typeof AXLookupComponent, typeof AXLookupDropDownListComponent, typeof AXLookupMultiSelectComponent, typeof AXLookupDropDownTreeComponent, typeof AXLookupMultiSelectTreeComponent, typeof AXLookupMultiColumnComponent], [typeof AXLookupComponent, typeof AXLookupDropDownListComponent, typeof AXLookupMultiSelectComponent, typeof AXLookupDropDownTreeComponent, typeof AXLookupMultiSelectTreeComponent, typeof AXLookupMultiColumnComponent]>;
779
+ static ɵmod: _angular_core.ɵɵNgModuleDeclaration<AXLookupModule, never, [typeof AXLookupComponent, typeof AXLookupDropDownListComponent, typeof AXLookupMultiSelectComponent, typeof AXLookupDropDownTreeComponent, typeof AXLookupMultiSelectTreeComponent, typeof AXLookupMultiColumnComponent, typeof AXLookupMultiColumnTreeComponent], [typeof AXLookupComponent, typeof AXLookupDropDownListComponent, typeof AXLookupMultiSelectComponent, typeof AXLookupDropDownTreeComponent, typeof AXLookupMultiSelectTreeComponent, typeof AXLookupMultiColumnComponent, typeof AXLookupMultiColumnTreeComponent]>;
620
780
  static ɵinj: _angular_core.ɵɵInjectorDeclaration<AXLookupModule>;
621
781
  }
622
782
 
623
- export { AXLookupComponent, AXLookupDropDownListComponent, AXLookupDropDownTreeComponent, AXLookupModule, AXLookupMultiColumnComponent, AXLookupMultiSelectComponent, AXLookupMultiSelectTreeComponent };
783
+ export { AXLookupComponent, AXLookupDropDownListComponent, AXLookupDropDownTreeComponent, AXLookupModule, AXLookupMultiColumnComponent, AXLookupMultiColumnTreeComponent, AXLookupMultiSelectComponent, AXLookupMultiSelectTreeComponent };
624
784
  export type { AXLookupColumn, AXLookupItem, AXLookupItemClickEvent, AXLookupMode, AXLookupSelectionChangedEvent, AXLookupTreeSelectionEvent };
@@ -186,6 +186,12 @@ declare class AXPopoverComponent extends MXBaseComponent implements OnDestroy {
186
186
  private setupScrollListener;
187
187
  /** @ignore */
188
188
  private removeScrollListener;
189
+ /**
190
+ * True when scroll is a side-effect of focusing an editable control inside the overlay
191
+ * (soft keyboard / visual viewport adjustment), mainly on iOS Safari.
192
+ * @ignore
193
+ */
194
+ private isKeyboardInducedScroll;
189
195
  /**
190
196
  * Checks whether the given element lives inside a child overlay
191
197
  * (an overlay stacked on top of this popover, e.g. a selectbox dropdown).
@@ -58,6 +58,13 @@ declare class AXSelectBoxComponent extends AXSelectBoxComponent_base implements
58
58
  protected _dropdownWidth: _angular_core.WritableSignal<string>;
59
59
  /** @ignore */
60
60
  protected _dropdownHeight: _angular_core.WritableSignal<string>;
61
+ /**
62
+ * Pixel height for the popover list and CDK viewport. Uses the sized height
63
+ * when known, otherwise the standard `maxVisibleItems × itemHeight` viewport.
64
+ * Always a pixel value so virtual scroll has a definite size on first open.
65
+ * @ignore
66
+ */
67
+ protected _panelMinHeight: _angular_core.Signal<string>;
61
68
  /** @ignore */
62
69
  protected _listDataSource: AXDataSource<any>;
63
70
  /** @ignore */
@@ -161,6 +168,10 @@ declare class AXSelectBoxComponent extends AXSelectBoxComponent_base implements
161
168
  /** @ignore */
162
169
  protected _handleItemSelected(e: AXItemSelectedEvent): void;
163
170
  private resetSearchAfterSelection;
171
+ private _getListItemPx;
172
+ private _getMaxVisibleItems;
173
+ /** Standard popover list height: `maxVisibleItems` rows (default 5). */
174
+ private _getStandardListHeightPx;
164
175
  /** @ignore */
165
176
  private setDropdownSize;
166
177
  /**
@@ -1 +0,0 @@
1
- {"version":3,"file":"acorex-components-conversation-open-composer-picker-for-files-BuNEjswI.mjs","sources":["../../../../packages/components/conversation/src/lib/components/message-list/open-composer-picker-popup.ts","../../../../packages/components/conversation/src/lib/components/message-list/open-composer-picker-for-files.ts"],"sourcesContent":["import type { AXPopupService } from '@acorex/components/popup';\nimport type { AXConversationComposerService } from '../composer/composer.service';\nimport type { AXConversationComposerAction, AXConversationComposerActionRegistry } from '../../registries/composer-action.registry';\nimport type { AXConversation } from '../../models';\nimport { resolveComposerMaxFiles } from '../../plugins/composer/composer-upload.config';\nimport type { AXConversationConfig } from '../../tokens/conversation-config.interface';\n\nexport async function openComposerPickerPopup(\n popupService: AXPopupService,\n composerService: AXConversationComposerService,\n registry: AXConversationComposerActionRegistry,\n action: AXConversationComposerAction,\n conversation: AXConversation,\n files: File[],\n config: Pick<Required<AXConversationConfig>, 'maxFilesPerMessage'>,\n): Promise<void> {\n const component = action.component ?? (action.componentLoader ? await action.componentLoader() : undefined);\n if (!component || files.length === 0) {\n return;\n }\n\n await popupService.open(component, {\n title: registry.getActionLabel(action),\n size: 'md',\n closeButton: true,\n header: false,\n panelClass: ['ax-conversation-composer-picker-popup'],\n inputs: {\n conversation,\n maxFiles: resolveComposerMaxFiles(action, config),\n initialFiles: files,\n service: composerService,\n },\n });\n}\n","import type { AXPopupService } from '@acorex/components/popup';\nimport type { AXToastService } from '@acorex/components/toast';\nimport { AXTranslationService } from '@acorex/core/translation';\nimport type { AXFileService } from '@acorex/core/file';\nimport type { AXValidationRuleResult } from '@acorex/core/validation';\nimport type { AXConversationComposerService } from '../composer/composer.service';\nimport type { AXConversation } from '../../models';\nimport type { AXConversationComposerAction, AXConversationComposerActionRegistry } from '../../registries/composer-action.registry';\nimport { notifyPickerValidationErrors } from '../../plugins/composer/components/shared/picker-upload';\nimport type { AXConversationConfig } from '../../tokens/conversation-config.interface';\nimport { openComposerPickerPopup } from './open-composer-picker-popup';\n\nexport interface AXConversationOpenComposerPickerForFilesDeps {\n fileService: AXFileService;\n composerService: AXConversationComposerService;\n composerActionRegistry: AXConversationComposerActionRegistry;\n popupService: AXPopupService;\n toast: AXToastService;\n translation: AXTranslationService;\n conversation: AXConversation | null | undefined;\n config: Pick<Required<AXConversationConfig>, 'maxFilesPerMessage'>;\n}\n\n/** Catalogs registered on picker actions (conversation-image, conversation-file, …). */\nfunction pickerCatalogNames(registry: AXConversationComposerActionRegistry): string[] {\n const names = new Set<string>();\n for (const action of registry.actions()) {\n if ((action.component || action.componentLoader) && action.fileType) {\n names.add(action.fileType);\n }\n }\n return [...names];\n}\n\ninterface AXConversationInboundFilesAnalysis {\n matchingCatalogs: string[];\n actions: AXConversationComposerAction[];\n supportedFiles: File[];\n unsupportedFiles: { file: File; errors: AXValidationRuleResult[] }[];\n}\n\n/** Files that are not accepted by any registered picker catalog. */\nasync function collectUnsupportedInboundFiles(\n deps: Pick<AXConversationOpenComposerPickerForFilesDeps, 'fileService' | 'composerActionRegistry'>,\n files: File[],\n catalogs: string[],\n): Promise<{ file: File; errors: AXValidationRuleResult[] }[]> {\n const unsupported: { file: File; errors: AXValidationRuleResult[] }[] = [];\n\n for (const file of files) {\n let acceptedByAny = false;\n let lastErrors: AXValidationRuleResult[] = [];\n\n for (const catalog of catalogs) {\n const errors = await deps.fileService.validate(file, catalog);\n if (errors.length === 0) {\n acceptedByAny = true;\n break;\n }\n lastErrors = errors;\n }\n\n if (!acceptedByAny) {\n unsupported.push({ file, errors: lastErrors });\n }\n }\n\n return unsupported;\n}\n\nasync function analyzeInboundFiles(\n deps: Pick<\n AXConversationOpenComposerPickerForFilesDeps,\n 'fileService' | 'composerService' | 'composerActionRegistry'\n >,\n files: File[],\n): Promise<AXConversationInboundFilesAnalysis> {\n if (!files.length) {\n return { matchingCatalogs: [], actions: [], supportedFiles: [], unsupportedFiles: [] };\n }\n\n const catalogs = pickerCatalogNames(deps.composerActionRegistry);\n const unsupportedFiles = await collectUnsupportedInboundFiles(deps, files, catalogs);\n const unsupportedSet = new Set(unsupportedFiles.map((entry) => entry.file));\n const supportedFiles = files.filter((file) => !unsupportedSet.has(file));\n\n if (supportedFiles.length === 0) {\n return { matchingCatalogs: [], actions: [], supportedFiles: [], unsupportedFiles };\n }\n\n const context = deps.composerService.actionContext();\n const matchingCatalogs: string[] = [];\n\n for (const catalog of catalogs) {\n const { rejected } = await deps.fileService.validateMany(supportedFiles, catalog);\n if (rejected.length === 0) {\n matchingCatalogs.push(catalog);\n }\n }\n\n const seen = new Set<string>();\n const actions: AXConversationComposerAction[] = [];\n\n for (const catalog of matchingCatalogs) {\n for (const action of deps.composerActionRegistry.findPickerActionsForFileType(catalog, context)) {\n if (!seen.has(action.id)) {\n seen.add(action.id);\n actions.push(action);\n }\n }\n }\n\n return {\n matchingCatalogs,\n actions: actions.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0)),\n supportedFiles,\n unsupportedFiles,\n };\n}\n\nfunction notifyInboundFilesValidationFailures(\n deps: Pick<AXConversationOpenComposerPickerForFilesDeps, 'toast' | 'translation'>,\n analysis: AXConversationInboundFilesAnalysis,\n): void {\n if (analysis.supportedFiles.length === 0) {\n if (analysis.unsupportedFiles.length === 0) {\n deps.toast.warning(deps.translation.translateSync('@acorex:chat.errors.inbound-files-none-supported'));\n }\n return;\n }\n\n if (analysis.actions.length === 0) {\n const key =\n analysis.matchingCatalogs.length === 0\n ? '@acorex:chat.errors.inbound-files-none-supported'\n : '@acorex:chat.errors.inbound-files-no-send-option';\n deps.toast.warning(deps.translation.translateSync(key));\n }\n}\n\n/**\n * File catalogs that accept every supported file in the batch, then matching visible picker actions.\n */\nexport async function resolvePickerActionsForAllFiles(\n deps: Pick<AXConversationOpenComposerPickerForFilesDeps, 'fileService' | 'composerService' | 'composerActionRegistry'>,\n files: File[],\n): Promise<AXConversationComposerAction[]> {\n const analysis = await analyzeInboundFiles(deps, files);\n return analysis.actions;\n}\n\nasync function promptComposerActionChoice(\n deps: AXConversationOpenComposerPickerForFilesDeps,\n actions: AXConversationComposerAction[],\n fileCount: number,\n): Promise<AXConversationComposerAction | undefined> {\n const { AXConversationComposerActionChoiceDialogComponent } = await import('./composer-action-choice-dialog.component');\n const result = await deps.popupService.open(AXConversationComposerActionChoiceDialogComponent, {\n title: deps.translation.translateSync('@acorex:chat.dialog.choose-send-option.title'),\n size: 'sm',\n closeButton: true,\n header: true,\n inputs: {\n actions,\n fileCount,\n composerActionRegistry: deps.composerActionRegistry,\n },\n });\n\n const action = result?.data as AXConversationComposerAction | undefined;\n if (!action?.component && !action?.componentLoader) {\n return undefined;\n }\n return action;\n}\n\n/**\n * Match dropped/pasted files to composer picker action(s) and open the popup.\n * Unsupported files are skipped after a warning toast; supported files continue.\n * @returns true when a picker popup was opened\n */\nexport async function openComposerPickerForFiles(\n deps: AXConversationOpenComposerPickerForFilesDeps,\n files: File[],\n): Promise<boolean> {\n if (!files.length) {\n return false;\n }\n\n const conversation = deps.conversation;\n if (!conversation) {\n return false;\n }\n\n const analysis = await analyzeInboundFiles(deps, files);\n\n if (analysis.unsupportedFiles.length > 0) {\n notifyPickerValidationErrors(deps.toast, deps.translation, analysis.unsupportedFiles);\n }\n\n if (!analysis.supportedFiles.length || !analysis.actions.length) {\n notifyInboundFilesValidationFailures(deps, analysis);\n return false;\n }\n\n let action = analysis.actions[0];\n if (analysis.actions.length > 1) {\n const chosen = await promptComposerActionChoice(deps, analysis.actions, analysis.supportedFiles.length);\n if (!chosen) {\n return false;\n }\n action = chosen;\n }\n\n const catalog = action.fileType;\n if (!catalog) {\n deps.toast.warning(deps.translation.translateSync('@acorex:chat.errors.inbound-files-none-supported'));\n return false;\n }\n\n const { accepted, rejected } = await deps.fileService.validateMany(analysis.supportedFiles, catalog);\n if (rejected.length > 0) {\n notifyPickerValidationErrors(deps.toast, deps.translation, rejected);\n }\n if (accepted.length === 0) {\n return false;\n }\n\n await openComposerPickerPopup(\n deps.popupService,\n deps.composerService,\n deps.composerActionRegistry,\n action,\n conversation,\n accepted,\n deps.config,\n );\n return true;\n}\n\n/** Extract OS-copied files from a paste event (e.g. Ctrl+V after copying a file in Explorer). */\nexport function filesFromClipboardEvent(event: ClipboardEvent): File[] {\n const items = event.clipboardData?.items;\n if (!items?.length) {\n return [];\n }\n\n const files: File[] = [];\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n if (item.kind === 'file') {\n const file = item.getAsFile();\n if (file) {\n files.push(file);\n }\n }\n }\n return files;\n}\n\n/** Whether a paste event target lies in the chat panel (not sidebar). */\nexport function isPasteTargetInChatPanel(host: HTMLElement, target: EventTarget | null): boolean {\n if (!(target instanceof Node) || !host.contains(target)) {\n return false;\n }\n\n const excluded = host.querySelector('.conversation-sidebar-container, .sidebar-container');\n if (excluded?.contains(target)) {\n return false;\n }\n\n const chatMain = host.querySelector('.conversation-main-container, .main-area, .conversation-view');\n if (chatMain) {\n return chatMain.contains(target);\n }\n\n return true;\n}\n\n/** Handle Ctrl+V / paste when the clipboard holds files copied from the OS. */\nexport async function handleConversationFilePaste(\n event: ClipboardEvent,\n host: HTMLElement,\n deps: AXConversationOpenComposerPickerForFilesDeps,\n): Promise<void> {\n if (!isPasteTargetInChatPanel(host, event.target)) {\n return;\n }\n\n const files = filesFromClipboardEvent(event);\n if (!files.length) {\n return;\n }\n\n const handled = await openComposerPickerForFiles(deps, files);\n if (handled) {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n}\n"],"names":[],"mappings":"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"}