@acorex/components 22.1.0-next.1 → 22.1.0-next.11

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 (50) hide show
  1. package/combo-box/README.md +5 -1
  2. package/fesm2022/acorex-components-accordion.mjs +2 -2
  3. package/fesm2022/acorex-components-accordion.mjs.map +1 -1
  4. package/fesm2022/acorex-components-button.mjs +2 -2
  5. package/fesm2022/acorex-components-button.mjs.map +1 -1
  6. package/fesm2022/acorex-components-check-box.mjs +2 -2
  7. package/fesm2022/acorex-components-check-box.mjs.map +1 -1
  8. package/fesm2022/acorex-components-combo-box.mjs +270 -57
  9. package/fesm2022/acorex-components-combo-box.mjs.map +1 -1
  10. package/fesm2022/acorex-components-conversation.mjs +222 -101
  11. package/fesm2022/acorex-components-conversation.mjs.map +1 -1
  12. package/fesm2022/acorex-components-form.mjs +21 -5
  13. package/fesm2022/acorex-components-form.mjs.map +1 -1
  14. package/fesm2022/acorex-components-label.mjs +2 -2
  15. package/fesm2022/acorex-components-label.mjs.map +1 -1
  16. package/fesm2022/acorex-components-list.mjs +2 -2
  17. package/fesm2022/acorex-components-list.mjs.map +1 -1
  18. package/fesm2022/acorex-components-loading-dialog.mjs +59 -42
  19. package/fesm2022/acorex-components-loading-dialog.mjs.map +1 -1
  20. package/fesm2022/acorex-components-lookup.mjs +186 -67
  21. package/fesm2022/acorex-components-lookup.mjs.map +1 -1
  22. package/fesm2022/acorex-components-password-box.mjs +2 -2
  23. package/fesm2022/acorex-components-password-box.mjs.map +1 -1
  24. package/fesm2022/acorex-components-radio.mjs +2 -2
  25. package/fesm2022/acorex-components-radio.mjs.map +1 -1
  26. package/fesm2022/acorex-components-range-slider.mjs +2 -2
  27. package/fesm2022/acorex-components-range-slider.mjs.map +1 -1
  28. package/fesm2022/acorex-components-select-box.mjs +6 -7
  29. package/fesm2022/acorex-components-select-box.mjs.map +1 -1
  30. package/fesm2022/acorex-components-selection-list.mjs +2 -2
  31. package/fesm2022/acorex-components-selection-list.mjs.map +1 -1
  32. package/fesm2022/acorex-components-switch.mjs +2 -2
  33. package/fesm2022/acorex-components-switch.mjs.map +1 -1
  34. package/fesm2022/acorex-components-tabs.mjs +2 -2
  35. package/fesm2022/acorex-components-tabs.mjs.map +1 -1
  36. package/fesm2022/acorex-components-tag-box.mjs +2 -2
  37. package/fesm2022/acorex-components-tag-box.mjs.map +1 -1
  38. package/fesm2022/acorex-components-text-area.mjs +2 -2
  39. package/fesm2022/acorex-components-text-area.mjs.map +1 -1
  40. package/lookup/README.md +11 -0
  41. package/package.json +4 -7
  42. package/types/acorex-components-combo-box.d.ts +90 -21
  43. package/types/acorex-components-conversation.d.ts +81 -48
  44. package/types/acorex-components-loading-dialog.d.ts +12 -4
  45. package/types/acorex-components-lookup.d.ts +47 -10
  46. package/types/acorex-components-select-box.d.ts +2 -2
  47. package/fesm2022/acorex-components-selection-list-2.mjs +0 -168
  48. package/fesm2022/acorex-components-selection-list-2.mjs.map +0 -1
  49. package/selection-list-2/README.md +0 -3
  50. package/types/acorex-components-selection-list-2.d.ts +0 -52
@@ -1,7 +1,8 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { TemplateRef } from '@angular/core';
3
- import { NXComponent, AXStyleLookType, AXValueChangedEvent, AXFocusEvent, AXItemClickEvent, AXItemSelectedEvent, AXEvent } from '@acorex/cdk/common';
3
+ import { NXValueComponent, AXStyleLookType, AXValueChangedEvent, AXFocusEvent, AXItemClickEvent, AXItemSelectedEvent, AXEvent } from '@acorex/cdk/common';
4
4
  import { AXPopoverComponent } from '@acorex/components/popover';
5
+ import { AXSearchBoxComponent } from '@acorex/components/search-box';
5
6
  import { Combobox } from '@angular/aria/combobox';
6
7
  import { Listbox } from '@angular/aria/listbox';
7
8
  import { FormValueControl } from '@angular/forms/signals';
@@ -18,15 +19,24 @@ interface AXComboBoxItem {
18
19
  text: string;
19
20
  value: string | number;
20
21
  }
22
+ /**
23
+ * The combo box model value: a scalar (or `null`) in single-select mode,
24
+ * or an array of scalars in multi-select mode.
25
+ */
26
+ type AXComboBoxValue = string | number | (string | number)[] | null;
21
27
 
22
28
  /**
23
- * A minimal combo box for selecting a single value from a list of items.
29
+ * A minimal combo box for selecting one or more values from a list of items.
24
30
  *
25
31
  * Built on top of the `@angular/aria/combobox` directives, it supports two behaviors:
26
- * - `searchable="true"` (default): an input with typeahead filtering (matches `id`).
32
+ * - `searchable="true"` (default): an input with typeahead filtering (matches `id`). On small
33
+ * screens with `adaptivityEnabled`, the trigger is select-like and search moves into the actionsheet.
27
34
  * - `searchable="false"`: a select-like, non-editable trigger (same input; typing blocked without
28
35
  * Combobox `readonly`, so Tab focus and keyboard open/select keep working).
29
36
  *
37
+ * With `multiple="true"`, selected values are shown as chips in the trigger and the popup stays
38
+ * open while toggling items (same interaction model as `ax-lookup` multi-select).
39
+ *
30
40
  * With `adaptivityEnabled` (default `true`), the list opens as a bottom actionsheet on small
31
41
  * screens instead of an anchored dropdown — the same alternate presentation as `ax-select-box`.
32
42
  *
@@ -36,8 +46,12 @@ interface AXComboBoxItem {
36
46
  *
37
47
  * @category Components
38
48
  */
39
- declare class AXComboBoxComponent extends NXComponent implements FormValueControl<string | number | null> {
49
+ declare class AXComboBoxComponent extends NXValueComponent implements FormValueControl<AXComboBoxValue> {
40
50
  #private;
51
+ /**
52
+ * The name of the form field, used by validation rules and `ax-form.validate(names)`.
53
+ */
54
+ name: _angular_core.InputSignal<string>;
41
55
  /**
42
56
  * The list of items the user can select from.
43
57
  * Each item has `id` (search/identity), `text` (display), and `value` (submitted).
@@ -46,11 +60,18 @@ declare class AXComboBoxComponent extends NXComponent implements FormValueContro
46
60
  /**
47
61
  * Whether the combo box accepts typing and filters the list (`true`),
48
62
  * or is a select-like, non-editable trigger (`false`).
63
+ * On small screens with `adaptivityEnabled`, search is typed in the actionsheet instead of the trigger.
49
64
  */
50
65
  searchable: _angular_core.InputSignal<boolean>;
66
+ /**
67
+ * When `true`, multiple items can be selected. Selected values are shown as chips and the
68
+ * popup stays open while toggling. The model value is an array (`[]` when empty).
69
+ */
70
+ multiple: _angular_core.InputSignal<boolean>;
51
71
  /**
52
72
  * When `true` (default), the popup list uses the alternate actionsheet presentation on small
53
- * screens (`SM`). When `false`, the list always opens as an anchored dropdown.
73
+ * screens (`SM`). Searchable mode then shows a search field inside the sheet. When `false`,
74
+ * the list always opens as an anchored dropdown.
54
75
  */
55
76
  adaptivityEnabled: _angular_core.InputSignal<boolean>;
56
77
  /**
@@ -65,6 +86,12 @@ declare class AXComboBoxComponent extends NXComponent implements FormValueContro
65
86
  * The placeholder text shown when no value is selected.
66
87
  */
67
88
  placeholder: _angular_core.InputSignal<string>;
89
+ /**
90
+ * Placeholder for the trigger search input when items are already selected (multi-select),
91
+ * and for the in-sheet search field on small screens. Falls back to `placeholder` when the
92
+ * selection is empty on desktop.
93
+ */
94
+ searchPlaceholder: _angular_core.InputSignal<string>;
68
95
  /**
69
96
  * Custom template rendered when the filtered list has no items.
70
97
  * When omitted, a default "no result found" message is shown.
@@ -80,6 +107,7 @@ declare class AXComboBoxComponent extends NXComponent implements FormValueContro
80
107
  * Context: `{ $implicit: AXComboBoxItem }`.
81
108
  * When `searchable` is true, the template is shown while the popup is closed and the input
82
109
  * still reflects the selected text; typing/opening falls back to the plain input.
110
+ * In multi-select mode, the template replaces the chip text for each selected item.
83
111
  */
84
112
  selectedTemplate: _angular_core.InputSignal<TemplateRef<unknown>>;
85
113
  /**
@@ -95,14 +123,14 @@ declare class AXComboBoxComponent extends NXComponent implements FormValueContro
95
123
  */
96
124
  look: _angular_core.ModelSignal<AXStyleLookType>;
97
125
  /**
98
- * The selected item's `value`. Supports `[(value)]`, `[(ngModel)]`, and signal forms
99
- * via {@link FormValueControl}.
126
+ * The selected item `value`(s). Scalar (or `null`) in single mode; an array in multi mode.
127
+ * Supports `[(value)]`, `[(ngModel)]`, and signal forms via {@link FormValueControl}.
100
128
  */
101
- readonly value: _angular_core.ModelSignal<string | number>;
129
+ readonly value: _angular_core.ModelSignal<AXComboBoxValue>;
102
130
  /**
103
131
  * Emitted when the selected value changes.
104
132
  */
105
- onValueChanged: _angular_core.OutputEmitterRef<AXValueChangedEvent<string | number>>;
133
+ onValueChanged: _angular_core.OutputEmitterRef<AXValueChangedEvent<AXComboBoxValue>>;
106
134
  /**
107
135
  * Emitted when the trigger receives focus.
108
136
  */
@@ -131,42 +159,77 @@ declare class AXComboBoxComponent extends NXComponent implements FormValueContro
131
159
  protected expanded: _angular_core.WritableSignal<boolean>;
132
160
  /** Whether the list is currently shown as a bottom actionsheet (small screens + adaptivity). */
133
161
  protected isActionsheetStyle: _angular_core.WritableSignal<boolean>;
134
- /** The item whose `value` matches the current model value. */
162
+ /** Whether the trigger input is writable and filters as you type (desktop searchable only). */
163
+ protected isEditableTrigger: _angular_core.Signal<boolean>;
164
+ /** Whether search is typed in the actionsheet instead of the trigger. */
165
+ protected isSheetSearchEnabled: _angular_core.Signal<boolean>;
166
+ /** Query typed in the actionsheet search field (independent of the trigger display text). */
167
+ protected sheetSearchText: _angular_core.WritableSignal<string>;
168
+ /** The current selection normalized to an array of submitted values. */
169
+ protected selectedValues: _angular_core.Signal<(string | number)[]>;
170
+ /** Whether there is at least one selected value. */
171
+ protected hasSelection: _angular_core.Signal<boolean>;
172
+ /** Resolved selected items for the current model value(s). */
173
+ protected selectedItems: _angular_core.Signal<AXComboBoxItem[]>;
174
+ /** The item whose `value` matches the current model value (single-select). */
135
175
  protected selectedItem: _angular_core.Signal<AXComboBoxItem>;
136
- /** Display text shown in the trigger / used as the searchable input baseline. */
176
+ /** Display text shown in the trigger / used as the searchable input baseline (single-select). */
137
177
  protected displayText: _angular_core.Signal<string>;
138
- /** The text typed in the searchable input. Resets to the selected item's text. */
178
+ /**
179
+ * The text typed in the searchable input.
180
+ * Multi-select starts empty; single mode syncs from the selected display text.
181
+ */
139
182
  protected searchText: _angular_core.WritableSignal<string>;
140
183
  /** Whether the trigger should render `selectedTemplate` instead of the plain input text. */
141
184
  protected showSelectedTemplate: _angular_core.Signal<boolean>;
142
- /** The listbox selection (item ids), kept in sync with the selected value. */
185
+ /** Placeholder for the editable trigger search input in multi-select. */
186
+ protected triggerSearchPlaceholder: _angular_core.Signal<string>;
187
+ /** The listbox selection (item ids), kept in sync with the selected value(s). */
143
188
  protected selection: _angular_core.WritableSignal<string[]>;
144
189
  /** Items filtered by typed query against `id` when the combo box is searchable. */
145
190
  protected filteredItems: _angular_core.Signal<AXComboBoxItem[]>;
191
+ /** Whether the filtered list is empty (empty-state vs hidden listbox). */
192
+ protected hasNoMatches: _angular_core.Signal<boolean>;
146
193
  protected comboboxRef: _angular_core.Signal<Combobox>;
147
194
  protected listboxRef: _angular_core.Signal<Listbox<any>>;
148
195
  protected popoverRef: _angular_core.Signal<AXPopoverComponent>;
196
+ protected sheetSearchRef: _angular_core.Signal<AXSearchBoxComponent>;
149
197
  constructor();
150
198
  /** Stable unique key for `@for` — avoids NG0955 when `id` is missing or duplicated. */
151
199
  protected trackItemKey(index: number, item: AXComboBoxItem): string;
200
+ /** Whether the given item is currently selected. */
201
+ protected isItemSelected(item: AXComboBoxItem): boolean;
152
202
  /**
153
203
  * Opens (searchable) or toggles (non-searchable) the popup on trigger click.
154
204
  */
155
205
  protected onTriggerClick(): void;
156
206
  /**
157
- * Non-searchable keyboard: open with Enter/Space when collapsed; commit with Space when expanded.
158
- * (Aria relays Enter for editable inputs, but not Space.)
207
+ * Keyboard handling on the trigger:
208
+ * - Non-searchable: open with Enter/Space when collapsed; commit with Space when expanded.
209
+ * - Multi-select: Backspace removes the last chip when the search input is empty.
159
210
  */
160
211
  protected onTriggerKeydown(event: KeyboardEvent): void;
161
- /** Blocks typing in non-searchable mode without Combobox `readonly` (keeps Tab/keyboard working). */
212
+ /** Blocks typing when the trigger is not editable (keeps Tab / keyboard open working). */
162
213
  protected onBeforeInput(event: Event): void;
214
+ /**
215
+ * Combobox `expanded` two-way binding. On actionsheet with in-sheet search, ignore collapse
216
+ * so focusing the search field (Aria combobox blur) does not close the popup. Dismiss is owned
217
+ * by the popover (`clickOut`, close button), `commit()`, and Escape.
218
+ */
219
+ protected onExpandedChange(open: boolean): void;
220
+ /** Filters the list from the actionsheet search field (reads the input so delayed ngModel cannot block typing). */
221
+ protected onSheetSearchInput(): void;
163
222
  /**
164
223
  * Keeps the combobox expanded state in sync when the popover closes (e.g. click outside).
165
224
  */
166
225
  protected onPopoverClosed(): void;
167
226
  /**
168
- * Clears the selected value (sets it to `null`) and closes the popup.
169
- * Used by projected `ax-clear-button`.
227
+ * Removes a single chip from the multi selection.
228
+ */
229
+ protected removeChip(event: Event, item: AXComboBoxItem): void;
230
+ /**
231
+ * Clears the selected value(s) and closes the popup.
232
+ * Sets `null` in single mode and `[]` in multi mode. Used by projected `ax-clear-button`.
170
233
  *
171
234
  * @param isUserInteraction - Whether the clear was triggered by the user.
172
235
  */
@@ -180,18 +243,24 @@ declare class AXComboBoxComponent extends NXComponent implements FormValueContro
180
243
  */
181
244
  closeAll(): void;
182
245
  /**
183
- * Commits the highlighted (active) or clicked list item as the component value and closes the popup.
246
+ * Commits the highlighted (active) or clicked list item as the component value.
184
247
  *
185
248
  * With `selectionMode="explicit"`, arrow keys only move the active item; Enter/Space must resolve
186
249
  * that option. Clicks resolve from the event target so we do not depend on listener order vs ngListbox.
250
+ *
251
+ * In multi-select mode the item is toggled and the popup stays open.
187
252
  */
188
253
  protected commit(event?: Event): void;
254
+ /**
255
+ * Focuses the combo box trigger input.
256
+ */
257
+ focus(options?: FocusOptions): void;
189
258
  /** Forwards native focus from the trigger input. */
190
259
  protected emitOnFocus(e: FocusEvent): void;
191
260
  /** Forwards native blur from the trigger input. */
192
261
  protected emitOnBlur(e: FocusEvent): void;
193
262
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXComboBoxComponent, never>;
194
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXComboBoxComponent, "ax-combo-box", never, { "items": { "alias": "items"; "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; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "emptyTemplate": { "alias": "emptyTemplate"; "required": false; "isSignal": true; }; "itemTemplate": { "alias": "itemTemplate"; "required": false; "isSignal": true; }; "selectedTemplate": { "alias": "selectedTemplate"; "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; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "look": "lookChange"; "value": "valueChange"; "onValueChanged": "onValueChanged"; "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>;
263
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXComboBoxComponent, "ax-combo-box", never, { "name": { "alias": "name"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "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; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "emptyTemplate": { "alias": "emptyTemplate"; "required": false; "isSignal": true; }; "itemTemplate": { "alias": "itemTemplate"; "required": false; "isSignal": true; }; "selectedTemplate": { "alias": "selectedTemplate"; "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; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "look": "lookChange"; "value": "valueChange"; "onValueChanged": "onValueChanged"; "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>;
195
264
  }
196
265
 
197
266
  declare class AXComboBoxModule {
@@ -201,4 +270,4 @@ declare class AXComboBoxModule {
201
270
  }
202
271
 
203
272
  export { AXComboBoxComponent, AXComboBoxModule };
204
- export type { AXComboBoxItem };
273
+ export type { AXComboBoxItem, AXComboBoxValue };
@@ -1,7 +1,7 @@
1
1
  import * as _acorex_components_conversation from '@acorex/components/conversation';
2
2
  import * as _angular_core from '@angular/core';
3
3
  import { OnDestroy, ViewContainerRef, Type, InputSignal, WritableSignal, Signal, Provider, OnInit, EventEmitter, TemplateRef, InjectionToken, ModuleWithProviders } from '@angular/core';
4
- import { AXComponentCloseEvent, AXHtmlEvent, AXDataSource, AXPlacement, AXClosableComponent } from '@acorex/cdk/common';
4
+ import { AXComponentCloseEvent, AXHtmlEvent, AXClickEvent, AXDataSource, AXPlacement, AXClosableComponent } from '@acorex/cdk/common';
5
5
  import * as _acorex_components_popup from '@acorex/components/popup';
6
6
  import { AXPopupService, AXPopupRef } from '@acorex/components/popup';
7
7
  import { AXFileUploadOptions, AXUploadResult, AXUploadReference, AXUploaderService, AXUploaderFileChangeEvent } from '@acorex/cdk/uploader';
@@ -716,18 +716,20 @@ declare class AXConversationComposerService {
716
716
  readonly canSend: _angular_core.Signal<boolean>;
717
717
  /** Composer action context */
718
718
  readonly actionContext: _angular_core.Signal<AXConversationComposerActionContext>;
719
- /** Left actions from registry */
720
- readonly leftActions: _angular_core.Signal<AXConversationComposerAction[]>;
721
- /** Right actions from registry */
722
- readonly rightActions: _angular_core.Signal<AXConversationComposerAction[]>;
723
- /** Left inline actions (location = 'inline' or undefined) */
724
- readonly leftInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
725
- /** Left menu actions (location = 'menu') */
726
- readonly leftMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
727
- /** Right inline actions (location = 'inline' or undefined) */
728
- readonly rightInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
729
- /** Right menu actions (location = 'menu') */
730
- readonly rightMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
719
+ /** Start actions from registry */
720
+ readonly startActions: _angular_core.Signal<AXConversationComposerAction[]>;
721
+ /** End actions from registry */
722
+ readonly endActions: _angular_core.Signal<AXConversationComposerAction[]>;
723
+ /** Start inline actions (location = 'inline' or undefined) */
724
+ readonly startInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
725
+ /** Start menu actions shown in the attachment popup */
726
+ readonly startMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
727
+ /** End inline actions inside the input pill (excludes default action) */
728
+ readonly endInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
729
+ /** End menu actions (location = 'menu') */
730
+ readonly endMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
731
+ /** Default end action (voice/send morph button) */
732
+ readonly defaultAction: _angular_core.Signal<AXConversationComposerAction>;
731
733
  startReply(message: AXConversationMessage): void;
732
734
  startEdit(message: AXConversationMessage): void;
733
735
  /** Focus the composer text area when the composer component is mounted. */
@@ -758,7 +760,7 @@ declare class AXConversationComposerService {
758
760
  /**
759
761
  * Get actions for the active conversation
760
762
  */
761
- getActionsForPosition(position: 'left' | 'right', context: AXConversationComposerActionContext): AXConversationComposerAction[];
763
+ getActionsForPosition(position: 'start' | 'end', context: AXConversationComposerActionContext): AXConversationComposerAction[];
762
764
  /**
763
765
  * Execute an action
764
766
  */
@@ -822,10 +824,15 @@ interface AXConversationComposerAction extends Omit<AXConversationRegistryItem,
822
824
  label: string;
823
825
  /** Icon name/class */
824
826
  icon: string;
825
- /** Position: left or right */
826
- position: 'left' | 'right';
827
- /** Location: inline (show as button) or menu (show in dropdown menu) */
827
+ /** Position: start or end of the composer */
828
+ position: 'start' | 'end';
829
+ /** Location: inline (show as button) or menu (show in attachment popup menu) */
828
830
  location?: 'inline' | 'menu';
831
+ /**
832
+ * Primary end action (e.g. voice record). Only one action may be default.
833
+ * Renders as the circular send-style button and morphs into send when the draft has content.
834
+ */
835
+ default?: boolean;
829
836
  /** Visibility condition */
830
837
  visible: (context: AXConversationComposerActionContext) => boolean;
831
838
  /** Enabled condition */
@@ -869,18 +876,20 @@ declare class AXConversationComposerActionRegistry {
869
876
  constructor();
870
877
  /** All registered actions */
871
878
  readonly actions: _angular_core.Signal<AXConversationComposerAction[]>;
872
- /** Left-side actions sorted by priority */
873
- readonly leftActions: _angular_core.Signal<AXConversationComposerAction[]>;
874
- /** Right-side actions sorted by priority */
875
- readonly rightActions: _angular_core.Signal<AXConversationComposerAction[]>;
876
- /** Left-side inline actions (location = 'inline' or undefined) */
877
- readonly leftInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
878
- /** Left-side menu actions (location = 'menu') */
879
- readonly leftMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
880
- /** Right-side inline actions (location = 'inline' or undefined) */
881
- readonly rightInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
882
- /** Right-side menu actions (location = 'menu') */
883
- readonly rightMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
879
+ /** Start-side actions sorted by priority */
880
+ readonly startActions: _angular_core.Signal<AXConversationComposerAction[]>;
881
+ /** End-side actions sorted by priority */
882
+ readonly endActions: _angular_core.Signal<AXConversationComposerAction[]>;
883
+ /** Start-side inline actions (location = 'inline' or undefined) */
884
+ readonly startInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
885
+ /** Start-side menu actions (location = 'menu') — shown in the attachment popup */
886
+ readonly startMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
887
+ /** End-side inline actions inside the input pill (excludes default action) */
888
+ readonly endInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
889
+ /** End-side menu actions (location = 'menu') */
890
+ readonly endMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
891
+ /** The single default end action (voice/send morph button) */
892
+ readonly defaultAction: _angular_core.Signal<AXConversationComposerAction>;
884
893
  /**
885
894
  * Register a composer action
886
895
  */
@@ -895,11 +904,11 @@ declare class AXConversationComposerActionRegistry {
895
904
  /**
896
905
  * Get visible actions for a position
897
906
  */
898
- getVisibleActions(position: 'left' | 'right', context: AXConversationComposerActionContext): AXConversationComposerAction[];
907
+ getVisibleActions(position: 'start' | 'end', context: AXConversationComposerActionContext): AXConversationComposerAction[];
899
908
  /**
900
909
  * Get enabled actions for a position
901
910
  */
902
- getEnabledActions(position: 'left' | 'right', context: AXConversationComposerActionContext): AXConversationComposerAction[];
911
+ getEnabledActions(position: 'start' | 'end', context: AXConversationComposerActionContext): AXConversationComposerAction[];
903
912
  isActionEnabled(action: AXConversationComposerAction, context: AXConversationComposerActionContext): boolean;
904
913
  /**
905
914
  * Picker actions for a file catalog (by priority), when visible and enabled.
@@ -1598,7 +1607,7 @@ declare class AXConversationComposerComponent implements OnDestroy {
1598
1607
  private readonly config;
1599
1608
  private readonly translation;
1600
1609
  /** Access registry through conversation service */
1601
- private get registry();
1610
+ protected get composerActionRegistry(): _acorex_components_conversation.AXConversationComposerActionRegistry;
1602
1611
  /** Composer text area reference */
1603
1612
  private readonly textAreaRef;
1604
1613
  /** Draft text - use service */
@@ -1627,6 +1636,9 @@ declare class AXConversationComposerComponent implements OnDestroy {
1627
1636
  /** Emoji popover state */
1628
1637
  private readonly emojiPopoverRef;
1629
1638
  readonly emojiPopoverTarget: _angular_core.WritableSignal<HTMLElement>;
1639
+ /** Attachment menu popover state */
1640
+ private readonly attachPopoverRef;
1641
+ readonly attachPopoverTarget: _angular_core.WritableSignal<HTMLElement>;
1630
1642
  readonly composerPopupLoader: () => Promise<typeof _acorex_components_conversation.AXConversationComposerPopupComponent>;
1631
1643
  /** Input placeholder - use service */
1632
1644
  readonly placeholder: _angular_core.Signal<string>;
@@ -1638,18 +1650,20 @@ declare class AXConversationComposerComponent implements OnDestroy {
1638
1650
  readonly inputRows: _angular_core.Signal<number>;
1639
1651
  /** Can send message - use service */
1640
1652
  readonly canSend: _angular_core.Signal<boolean>;
1641
- /** Left actions from registry - use service */
1642
- readonly leftActions: _angular_core.Signal<AXConversationComposerAction[]>;
1643
- /** Right actions from registry - use service */
1644
- readonly rightActions: _angular_core.Signal<AXConversationComposerAction[]>;
1645
- /** Left inline actions (location = 'inline' or undefined) */
1646
- readonly leftInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
1647
- /** Left menu actions (location = 'menu') */
1648
- readonly leftMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
1649
- /** Right inline actions (location = 'inline' or undefined) */
1650
- readonly rightInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
1651
- /** Right menu actions (location = 'menu') */
1652
- readonly rightMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
1653
+ /** Start actions from registry - use service */
1654
+ readonly startActions: _angular_core.Signal<AXConversationComposerAction[]>;
1655
+ /** End actions from registry - use service */
1656
+ readonly endActions: _angular_core.Signal<AXConversationComposerAction[]>;
1657
+ /** Start inline actions */
1658
+ readonly startInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
1659
+ /** Start menu actions (attachment popup) */
1660
+ readonly startMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
1661
+ /** End inline actions inside input pill */
1662
+ readonly endInlineActions: _angular_core.Signal<AXConversationComposerAction[]>;
1663
+ /** End menu actions */
1664
+ readonly endMenuActions: _angular_core.Signal<AXConversationComposerAction[]>;
1665
+ /** Default end action (voice/send morph) */
1666
+ readonly defaultAction: _angular_core.Signal<AXConversationComposerAction>;
1653
1667
  /** Handle key down */
1654
1668
  onKeyDown(event: AXHtmlEvent<KeyboardEvent>): void;
1655
1669
  /** Handle input */
@@ -1661,7 +1675,7 @@ declare class AXConversationComposerComponent implements OnDestroy {
1661
1675
  /** Handle send click */
1662
1676
  onSendClick(): Promise<void>;
1663
1677
  /** Handle emoji click */
1664
- onEmojiClick(event?: MouseEvent): Promise<void>;
1678
+ onEmojiClick(event?: AXClickEvent | MouseEvent): Promise<void>;
1665
1679
  /** Handle emoji popover closed */
1666
1680
  onEmojiPopoverClosed(): void;
1667
1681
  /** Handle emoji/sticker selection from popup */
@@ -1670,8 +1684,16 @@ declare class AXConversationComposerComponent implements OnDestroy {
1670
1684
  private sendSticker;
1671
1685
  /** Get inputs for emoji popup component */
1672
1686
  getEmojiPopupInputs(): Record<string, unknown>;
1673
- /** Handle attach click */
1674
- onAttachClick(): void;
1687
+ /** Handle attach menu click */
1688
+ onAttachMenuClick(event: AXClickEvent): void;
1689
+ /** Handle attachment popover closed */
1690
+ onAttachPopoverClosed(): void;
1691
+ /** Handle attachment menu action selection */
1692
+ onAttachMenuAction(actionId: string): Promise<void>;
1693
+ /** Handle default action click (voice when empty, send when has content) */
1694
+ onDefaultActionClick(): Promise<void>;
1695
+ /** Icon for the default morph button */
1696
+ getDefaultActionIcon(): string;
1675
1697
  /** Handle voice click */
1676
1698
  onVoiceClick(): void;
1677
1699
  /** Remove attachment */
@@ -1684,8 +1706,9 @@ declare class AXConversationComposerComponent implements OnDestroy {
1684
1706
  startReply(message: AXConversationMessage): void;
1685
1707
  /** Focus the native textarea inside ax-text-area */
1686
1708
  private focusTextArea;
1709
+ private getClickTarget;
1687
1710
  /** Handle action click */
1688
- onActionClick(actionId: string, event?: MouseEvent): Promise<void>;
1711
+ onActionClick(actionId: string, event?: AXClickEvent | MouseEvent): Promise<void>;
1689
1712
  /** Check if action is enabled */
1690
1713
  isActionEnabled(action: any): boolean;
1691
1714
  /** Get replying sender name */
@@ -1693,6 +1716,9 @@ declare class AXConversationComposerComponent implements OnDestroy {
1693
1716
  getActionLabel(action: {
1694
1717
  label: string;
1695
1718
  }): string;
1719
+ getActionButtonClass(action: {
1720
+ className?: string;
1721
+ }): string;
1696
1722
  /** Get replying message text */
1697
1723
  getReplyingMessageText(): string;
1698
1724
  /** Preview object for replying banner (type, icon, value) */
@@ -1788,7 +1814,10 @@ interface AXConversationDropdownMenuItem {
1788
1814
  declare class AXConversationInfoBarComponent {
1789
1815
  private readonly conversationService;
1790
1816
  private readonly infoBar;
1817
+ private readonly customUserAvatarComponent;
1791
1818
  protected get registry(): _acorex_components_conversation.AXConversationRegistryService;
1819
+ /** Whether a custom user avatar component is registered via conversation config. */
1820
+ readonly hasCustomUserAvatar: _angular_core.Signal<boolean>;
1792
1821
  /** Active conversation */
1793
1822
  readonly activeConversation: _angular_core.Signal<AXConversation>;
1794
1823
  /** Active component from service */
@@ -3838,6 +3867,9 @@ declare class AXConversationMessageListComponent implements OnDestroy {
3838
3867
  readonly showScrollButton: _angular_core.WritableSignal<boolean>;
3839
3868
  /** Active conversation */
3840
3869
  readonly activeConversation: _angular_core.Signal<_acorex_components_conversation.AXConversation>;
3870
+ readonly isGroupConversation: _angular_core.Signal<boolean>;
3871
+ /** Placeholder indices for the initial message list skeleton. */
3872
+ protected readonly loadingSkeletonItems: readonly [0, 1, 2, 3, 4, 5];
3841
3873
  /** Whether the active conversation allows message reactions. */
3842
3874
  readonly reactionsEnabled: _angular_core.Signal<boolean>;
3843
3875
  /** Messages */
@@ -6269,6 +6301,7 @@ declare class AXConversationDefaultConversationAvatarComponent {
6269
6301
  displayAvatar: string;
6270
6302
  displayIcon: string;
6271
6303
  }>;
6304
+ readonly filteredUserAvatarInputs: _angular_core.Signal<Record<string, unknown>>;
6272
6305
  readonly fallbackDisplay: _angular_core.Signal<_acorex_components_conversation.AXConversationAvatarDisplay>;
6273
6306
  readonly fallbackInitials: _angular_core.Signal<string>;
6274
6307
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXConversationDefaultConversationAvatarComponent, never>;
@@ -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
  *