@acorex/components 21.0.3-next.39 → 21.0.3-next.40

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 (129) hide show
  1. package/{conversation2 → conversation}/README.md +23 -23
  2. package/fesm2022/acorex-components-button.mjs +4 -4
  3. package/fesm2022/acorex-components-button.mjs.map +1 -1
  4. package/fesm2022/acorex-components-conversation-acorex-components-conversation-YhVa42TC.mjs +13711 -0
  5. package/fesm2022/acorex-components-conversation-acorex-components-conversation-YhVa42TC.mjs.map +1 -0
  6. package/fesm2022/acorex-components-conversation-audio-attachment.component-CLvS3W8F.mjs +119 -0
  7. package/fesm2022/acorex-components-conversation-audio-attachment.component-CLvS3W8F.mjs.map +1 -0
  8. package/fesm2022/acorex-components-conversation-audio-composer.payload-BHQJNyXz.mjs +59 -0
  9. package/fesm2022/acorex-components-conversation-audio-composer.payload-BHQJNyXz.mjs.map +1 -0
  10. package/fesm2022/acorex-components-conversation-audio-picker.component-BD_fN2Ip.mjs +432 -0
  11. package/fesm2022/acorex-components-conversation-audio-picker.component-BD_fN2Ip.mjs.map +1 -0
  12. package/fesm2022/acorex-components-conversation-audio-renderer.component-CcxVVprx.mjs +177 -0
  13. package/fesm2022/acorex-components-conversation-audio-renderer.component-CcxVVprx.mjs.map +1 -0
  14. package/fesm2022/acorex-components-conversation-audio.payload-Bag4aTut.mjs +54 -0
  15. package/fesm2022/acorex-components-conversation-audio.payload-Bag4aTut.mjs.map +1 -0
  16. package/fesm2022/acorex-components-conversation-composer-action-choice-dialog.component-C28hl7iD.mjs +101 -0
  17. package/fesm2022/acorex-components-conversation-composer-action-choice-dialog.component-C28hl7iD.mjs.map +1 -0
  18. package/fesm2022/acorex-components-conversation-conversation-audio.file-type-CfGSVnMA.mjs +100 -0
  19. package/fesm2022/acorex-components-conversation-conversation-audio.file-type-CfGSVnMA.mjs.map +1 -0
  20. package/fesm2022/acorex-components-conversation-conversation-file.file-type-DB-2xhaC.mjs +121 -0
  21. package/fesm2022/acorex-components-conversation-conversation-file.file-type-DB-2xhaC.mjs.map +1 -0
  22. package/fesm2022/acorex-components-conversation-conversation-image.file-type-C02OzZZB.mjs +84 -0
  23. package/fesm2022/acorex-components-conversation-conversation-image.file-type-C02OzZZB.mjs.map +1 -0
  24. package/fesm2022/acorex-components-conversation-conversation-info-media-view.component-Mhk7JE6K.mjs +238 -0
  25. package/fesm2022/acorex-components-conversation-conversation-info-media-view.component-Mhk7JE6K.mjs.map +1 -0
  26. package/fesm2022/acorex-components-conversation-conversation-info-panel.component-CNaM5ajR.mjs +1080 -0
  27. package/fesm2022/acorex-components-conversation-conversation-info-panel.component-CNaM5ajR.mjs.map +1 -0
  28. package/fesm2022/acorex-components-conversation-conversation-video.file-type-Pescv4Vu.mjs +102 -0
  29. package/fesm2022/acorex-components-conversation-conversation-video.file-type-Pescv4Vu.mjs.map +1 -0
  30. package/fesm2022/acorex-components-conversation-conversation-voice.file-type-DDd47o4r.mjs +90 -0
  31. package/fesm2022/acorex-components-conversation-conversation-voice.file-type-DDd47o4r.mjs.map +1 -0
  32. package/fesm2022/acorex-components-conversation-emoji-categories-C7Gm95V0.mjs +1840 -0
  33. package/fesm2022/acorex-components-conversation-emoji-categories-C7Gm95V0.mjs.map +1 -0
  34. package/fesm2022/acorex-components-conversation-fallback-renderer.component-CYh_6O6j.mjs +44 -0
  35. package/fesm2022/acorex-components-conversation-fallback-renderer.component-CYh_6O6j.mjs.map +1 -0
  36. package/fesm2022/acorex-components-conversation-file-composer.payload-Dy7aG-EH.mjs +64 -0
  37. package/fesm2022/acorex-components-conversation-file-composer.payload-Dy7aG-EH.mjs.map +1 -0
  38. package/fesm2022/acorex-components-conversation-file-picker.component-DCVgl33l.mjs +468 -0
  39. package/fesm2022/acorex-components-conversation-file-picker.component-DCVgl33l.mjs.map +1 -0
  40. package/fesm2022/acorex-components-conversation-file-renderer.component-DgCi06Mg.mjs +125 -0
  41. package/fesm2022/acorex-components-conversation-file-renderer.component-DgCi06Mg.mjs.map +1 -0
  42. package/fesm2022/acorex-components-conversation-file.payload-DyFxTQYn.mjs +50 -0
  43. package/fesm2022/acorex-components-conversation-file.payload-DyFxTQYn.mjs.map +1 -0
  44. package/fesm2022/acorex-components-conversation-format-media-DUD4vA6F.mjs +21 -0
  45. package/fesm2022/acorex-components-conversation-format-media-DUD4vA6F.mjs.map +1 -0
  46. package/fesm2022/acorex-components-conversation-image-attachment.component-CLMGxXPl.mjs +77 -0
  47. package/fesm2022/acorex-components-conversation-image-attachment.component-CLMGxXPl.mjs.map +1 -0
  48. package/fesm2022/acorex-components-conversation-image-picker.component-CS343UDa.mjs +407 -0
  49. package/fesm2022/acorex-components-conversation-image-picker.component-CS343UDa.mjs.map +1 -0
  50. package/fesm2022/acorex-components-conversation-image-renderer.component-Cy0TA6cL.mjs +83 -0
  51. package/fesm2022/acorex-components-conversation-image-renderer.component-Cy0TA6cL.mjs.map +1 -0
  52. package/fesm2022/acorex-components-conversation-index-3V2b14I0.mjs +184 -0
  53. package/fesm2022/acorex-components-conversation-index-3V2b14I0.mjs.map +1 -0
  54. package/fesm2022/acorex-components-conversation-index-MCvfr9Zd.mjs +266 -0
  55. package/fesm2022/acorex-components-conversation-index-MCvfr9Zd.mjs.map +1 -0
  56. package/fesm2022/acorex-components-conversation-location-picker.component-DcNQzuoU.mjs +149 -0
  57. package/fesm2022/acorex-components-conversation-location-picker.component-DcNQzuoU.mjs.map +1 -0
  58. package/fesm2022/acorex-components-conversation-location-renderer.component-Cw2PB0LM.mjs +118 -0
  59. package/fesm2022/acorex-components-conversation-location-renderer.component-Cw2PB0LM.mjs.map +1 -0
  60. package/fesm2022/acorex-components-conversation-media-formatters-DV3wEEno.mjs +17 -0
  61. package/fesm2022/acorex-components-conversation-media-formatters-DV3wEEno.mjs.map +1 -0
  62. package/fesm2022/acorex-components-conversation-media-playback-info-bar-banner.component-DbWUl6M2.mjs +140 -0
  63. package/fesm2022/acorex-components-conversation-media-playback-info-bar-banner.component-DbWUl6M2.mjs.map +1 -0
  64. package/fesm2022/acorex-components-conversation-message-renderer-copy-host.component-oXTr_Lfq.mjs +33 -0
  65. package/fesm2022/acorex-components-conversation-message-renderer-copy-host.component-oXTr_Lfq.mjs.map +1 -0
  66. package/fesm2022/acorex-components-conversation-message-renderer-state.component-Dp-JdHWr.mjs +172 -0
  67. package/fesm2022/acorex-components-conversation-message-renderer-state.component-Dp-JdHWr.mjs.map +1 -0
  68. package/fesm2022/acorex-components-conversation-open-composer-picker-for-files-Du8Lj9Sp.mjs +224 -0
  69. package/fesm2022/acorex-components-conversation-open-composer-picker-for-files-Du8Lj9Sp.mjs.map +1 -0
  70. package/fesm2022/acorex-components-conversation-pagination-demo-data-oIT_YJmN.mjs +81 -0
  71. package/fesm2022/acorex-components-conversation-pagination-demo-data-oIT_YJmN.mjs.map +1 -0
  72. package/fesm2022/acorex-components-conversation-picker-header.component-BneIFjXq.mjs +91 -0
  73. package/fesm2022/acorex-components-conversation-picker-header.component-BneIFjXq.mjs.map +1 -0
  74. package/fesm2022/acorex-components-conversation-picker-toolbar.component-BthRvEeE.mjs +537 -0
  75. package/fesm2022/acorex-components-conversation-picker-toolbar.component-BthRvEeE.mjs.map +1 -0
  76. package/fesm2022/acorex-components-conversation-picker-upload-C-PlKPaU.mjs +163 -0
  77. package/fesm2022/acorex-components-conversation-picker-upload-C-PlKPaU.mjs.map +1 -0
  78. package/fesm2022/acorex-components-conversation-playback-banner-sync-D8FFKde6.mjs +68 -0
  79. package/fesm2022/acorex-components-conversation-playback-banner-sync-D8FFKde6.mjs.map +1 -0
  80. package/fesm2022/acorex-components-conversation-renderer-shared.styles-Digah3Zn.mjs +95 -0
  81. package/fesm2022/acorex-components-conversation-renderer-shared.styles-Digah3Zn.mjs.map +1 -0
  82. package/fesm2022/acorex-components-conversation-search.component-B-nc6xiA.mjs +187 -0
  83. package/fesm2022/acorex-components-conversation-search.component-B-nc6xiA.mjs.map +1 -0
  84. package/fesm2022/acorex-components-conversation-send-message-media-BRklgfV7.mjs +170 -0
  85. package/fesm2022/acorex-components-conversation-send-message-media-BRklgfV7.mjs.map +1 -0
  86. package/fesm2022/acorex-components-conversation-shared-storage.seed-J9PA4l3c.mjs +750 -0
  87. package/fesm2022/acorex-components-conversation-shared-storage.seed-J9PA4l3c.mjs.map +1 -0
  88. package/fesm2022/acorex-components-conversation-sticker-renderer.component-BmBwy7Ig.mjs +103 -0
  89. package/fesm2022/acorex-components-conversation-sticker-renderer.component-BmBwy7Ig.mjs.map +1 -0
  90. package/fesm2022/acorex-components-conversation-system-renderer.component-uie3tm5N.mjs +55 -0
  91. package/fesm2022/acorex-components-conversation-system-renderer.component-uie3tm5N.mjs.map +1 -0
  92. package/fesm2022/acorex-components-conversation-text-renderer.component-DNAquHYK.mjs +109 -0
  93. package/fesm2022/acorex-components-conversation-text-renderer.component-DNAquHYK.mjs.map +1 -0
  94. package/fesm2022/acorex-components-conversation-video-attachment.component-CGaUhnSb.mjs +105 -0
  95. package/fesm2022/acorex-components-conversation-video-attachment.component-CGaUhnSb.mjs.map +1 -0
  96. package/fesm2022/acorex-components-conversation-video-composer.payload-DMqRkafr.mjs +62 -0
  97. package/fesm2022/acorex-components-conversation-video-composer.payload-DMqRkafr.mjs.map +1 -0
  98. package/fesm2022/acorex-components-conversation-video-picker.component-DPwSBnoH.mjs +446 -0
  99. package/fesm2022/acorex-components-conversation-video-picker.component-DPwSBnoH.mjs.map +1 -0
  100. package/fesm2022/acorex-components-conversation-video-renderer.component-DKa9mUe2.mjs +181 -0
  101. package/fesm2022/acorex-components-conversation-video-renderer.component-DKa9mUe2.mjs.map +1 -0
  102. package/fesm2022/acorex-components-conversation-video.payload-C8QaqxuX.mjs +54 -0
  103. package/fesm2022/acorex-components-conversation-video.payload-C8QaqxuX.mjs.map +1 -0
  104. package/fesm2022/acorex-components-conversation-voice-composer.payload-DLVow7ex.mjs +17 -0
  105. package/fesm2022/acorex-components-conversation-voice-composer.payload-DLVow7ex.mjs.map +1 -0
  106. package/fesm2022/acorex-components-conversation-voice-recorder.component-D_rdANZN.mjs +344 -0
  107. package/fesm2022/acorex-components-conversation-voice-recorder.component-D_rdANZN.mjs.map +1 -0
  108. package/fesm2022/acorex-components-conversation-voice-renderer.component-BY5FJcT8.mjs +270 -0
  109. package/fesm2022/acorex-components-conversation-voice-renderer.component-BY5FJcT8.mjs.map +1 -0
  110. package/fesm2022/acorex-components-conversation.mjs +2 -0
  111. package/fesm2022/acorex-components-conversation.mjs.map +1 -0
  112. package/fesm2022/acorex-components-kbd.mjs +2 -2
  113. package/fesm2022/acorex-components-kbd.mjs.map +1 -1
  114. package/fesm2022/acorex-components-scheduler-picker.mjs +22 -14
  115. package/fesm2022/acorex-components-scheduler-picker.mjs.map +1 -1
  116. package/fesm2022/acorex-components-side-menu.mjs +4 -13
  117. package/fesm2022/acorex-components-side-menu.mjs.map +1 -1
  118. package/fesm2022/acorex-components-tree-view.mjs +2 -2
  119. package/fesm2022/acorex-components-tree-view.mjs.map +1 -1
  120. package/package.json +6 -10
  121. package/types/{acorex-components-conversation2.d.ts → acorex-components-conversation.d.ts} +1127 -1928
  122. package/types/acorex-components-scheduler-picker.d.ts +2 -0
  123. package/types/acorex-components-side-menu.d.ts +1 -3
  124. package/fesm2022/acorex-components-conversation2.mjs +0 -22347
  125. package/fesm2022/acorex-components-conversation2.mjs.map +0 -1
  126. package/fesm2022/acorex-components-sidebar.mjs +0 -275
  127. package/fesm2022/acorex-components-sidebar.mjs.map +0 -1
  128. package/sidebar/README.md +0 -5
  129. package/types/acorex-components-sidebar.d.ts +0 -132
@@ -0,0 +1,184 @@
1
+ import * as i1 from '@acorex/components/search-box';
2
+ import { AXSearchBoxModule } from '@acorex/components/search-box';
3
+ import * as i3 from '@acorex/core/translation';
4
+ import { AXTranslationModule } from '@acorex/core/translation';
5
+ import * as i2 from '@angular/common';
6
+ import { CommonModule } from '@angular/common';
7
+ import * as i0 from '@angular/core';
8
+ import { output, signal, computed, Component } from '@angular/core';
9
+ import { FormsModule } from '@angular/forms';
10
+
11
+ /**
12
+ * Emoji Tab Component
13
+ * Emoji picker for composer popup
14
+ */
15
+ let emojiCategoriesCache = null;
16
+ async function loadEmojiCategories() {
17
+ if (emojiCategoriesCache) {
18
+ return emojiCategoriesCache;
19
+ }
20
+ const module = await import('./acorex-components-conversation-emoji-categories-C7Gm95V0.mjs');
21
+ emojiCategoriesCache =
22
+ module.default ??
23
+ module;
24
+ return emojiCategoriesCache;
25
+ }
26
+ class AXConversationEmojiTabComponent {
27
+ constructor() {
28
+ /** Emoji selected event */
29
+ this.itemSelected = output();
30
+ /** Search query */
31
+ this.searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : /* istanbul ignore next */ []));
32
+ /** Active category */
33
+ this.activeCategoryId = signal('smileys', ...(ngDevMode ? [{ debugName: "activeCategoryId" }] : /* istanbul ignore next */ []));
34
+ /** Categories */
35
+ this.categories = signal([], ...(ngDevMode ? [{ debugName: "categories" }] : /* istanbul ignore next */ []));
36
+ /** Filtered emojis */
37
+ this.filteredEmojis = computed(() => {
38
+ const query = this.searchQuery().toLowerCase().trim();
39
+ const categoryId = this.activeCategoryId();
40
+ if (query) {
41
+ // Search across all categories by name and keywords
42
+ return this.categories()
43
+ .flatMap((cat) => cat.emojis)
44
+ .filter((emoji) => {
45
+ const searchText = `${emoji.name} ${emoji.keywords.join(' ')}`.toLowerCase();
46
+ return searchText.includes(query);
47
+ });
48
+ }
49
+ else {
50
+ // Show active category
51
+ const category = this.categories().find((c) => c.id === categoryId);
52
+ return category ? category.emojis : [];
53
+ }
54
+ }, ...(ngDevMode ? [{ debugName: "filteredEmojis" }] : /* istanbul ignore next */ []));
55
+ void loadEmojiCategories().then((categories) => this.categories.set(categories));
56
+ }
57
+ /** Select category */
58
+ selectCategory(categoryId) {
59
+ this.activeCategoryId.set(categoryId);
60
+ this.searchQuery.set('');
61
+ }
62
+ /** Get category CSS classes */
63
+ getCategoryClasses(categoryId) {
64
+ const classes = ['category-button'];
65
+ if (this.activeCategoryId() === categoryId) {
66
+ classes.push('category-button-active');
67
+ }
68
+ return classes.join(' ');
69
+ }
70
+ onSearchChange(event) {
71
+ this.searchQuery.set(event?.value || '');
72
+ }
73
+ /** Select emoji */
74
+ selectEmoji(emoji) {
75
+ this.itemSelected.emit(emoji);
76
+ }
77
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXConversationEmojiTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
78
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXConversationEmojiTabComponent, isStandalone: true, selector: "ax-conversation-emoji-tab", outputs: { itemSelected: "itemSelected" }, ngImport: i0, template: `
79
+ <div class="emoji-tab">
80
+ <!-- Search -->
81
+ <div class="emoji-search">
82
+ <ax-search-box
83
+ [value]="searchQuery()"
84
+ [placeholder]="'Search emoji...'"
85
+ (onValueChanged)="onSearchChange($event)"
86
+ ></ax-search-box>
87
+ </div>
88
+
89
+ <!-- Categories -->
90
+ <div class="emoji-categories">
91
+ @for (category of categories(); track category.id) {
92
+ <button
93
+ type="button"
94
+ [class]="getCategoryClasses(category.id)"
95
+ (click)="selectCategory(category.id)"
96
+ [attr.aria-label]="category.name"
97
+ [title]="category.name"
98
+ >
99
+ {{ category.icon }}
100
+ </button>
101
+ }
102
+ </div>
103
+
104
+ <!-- Emoji Grid -->
105
+ <div class="emoji-grid">
106
+ @for (emoji of filteredEmojis(); track emoji.char) {
107
+ <button
108
+ type="button"
109
+ class="emoji-button"
110
+ (click)="selectEmoji(emoji.char)"
111
+ [attr.aria-label]="emoji.name"
112
+ [title]="emoji.name"
113
+ >
114
+ {{ emoji.char }}
115
+ </button>
116
+ }
117
+ </div>
118
+
119
+ @if (filteredEmojis().length === 0) {
120
+ <div class="emoji-empty">
121
+ <p>{{ '@acorex:chat.empty.no-emojis-found' | translate | async }}</p>
122
+ </div>
123
+ }
124
+ </div>
125
+ `, isInline: true, styles: [".emoji-tab{display:flex;flex-direction:column;height:100%}.emoji-search{position:sticky;top:0;z-index:10;padding-block:.75rem}.emoji-categories{display:flex;align-items:center;flex-shrink:0;gap:.25rem;margin-bottom:.75rem;padding-bottom:.75rem;overflow-x:auto;border-bottom:1px solid rgb(var(--ax-sys-color-border-light-surface))}.category-button{height:2rem;width:2rem;display:flex;justify-content:center;align-items:center;padding:.25rem;border:none;background:transparent;border-radius:.375rem;cursor:pointer;font-size:1.25rem;transition:all .15s;font-family:\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\",\"Apple Color Emoji\",Twemoji Mozilla,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.category-button:hover{background:rgb(var(--ax-sys-color-light-surface))}.category-button-active{background:rgb(var(--ax-sys-color-primary-lightest-surface));color:rgb(var(--ax-sys-color-on-primary-lightest-surface))}.emoji-grid{display:grid;grid-template-columns:repeat(auto-fill,32px);gap:.25rem;max-height:240px}.emoji-button{width:2rem;height:2rem;padding:.25rem;border:none;background:transparent;border-radius:.375rem;cursor:pointer;font-size:1.5rem;transition:all .15s;display:flex;align-items:center;justify-content:center;font-family:\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\",\"Apple Color Emoji\",Twemoji Mozilla,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.emoji-button:hover{background:rgb(var(--ax-sys-color-light-surface))}.emoji-empty{padding:2rem;text-align:center;opacity:.6}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i1.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.AXTranslatorPipe, name: "translate" }] }); }
126
+ }
127
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXConversationEmojiTabComponent, decorators: [{
128
+ type: Component,
129
+ args: [{ selector: 'ax-conversation-emoji-tab', imports: [CommonModule, FormsModule, AXSearchBoxModule, AXTranslationModule], template: `
130
+ <div class="emoji-tab">
131
+ <!-- Search -->
132
+ <div class="emoji-search">
133
+ <ax-search-box
134
+ [value]="searchQuery()"
135
+ [placeholder]="'Search emoji...'"
136
+ (onValueChanged)="onSearchChange($event)"
137
+ ></ax-search-box>
138
+ </div>
139
+
140
+ <!-- Categories -->
141
+ <div class="emoji-categories">
142
+ @for (category of categories(); track category.id) {
143
+ <button
144
+ type="button"
145
+ [class]="getCategoryClasses(category.id)"
146
+ (click)="selectCategory(category.id)"
147
+ [attr.aria-label]="category.name"
148
+ [title]="category.name"
149
+ >
150
+ {{ category.icon }}
151
+ </button>
152
+ }
153
+ </div>
154
+
155
+ <!-- Emoji Grid -->
156
+ <div class="emoji-grid">
157
+ @for (emoji of filteredEmojis(); track emoji.char) {
158
+ <button
159
+ type="button"
160
+ class="emoji-button"
161
+ (click)="selectEmoji(emoji.char)"
162
+ [attr.aria-label]="emoji.name"
163
+ [title]="emoji.name"
164
+ >
165
+ {{ emoji.char }}
166
+ </button>
167
+ }
168
+ </div>
169
+
170
+ @if (filteredEmojis().length === 0) {
171
+ <div class="emoji-empty">
172
+ <p>{{ '@acorex:chat.empty.no-emojis-found' | translate | async }}</p>
173
+ </div>
174
+ }
175
+ </div>
176
+ `, styles: [".emoji-tab{display:flex;flex-direction:column;height:100%}.emoji-search{position:sticky;top:0;z-index:10;padding-block:.75rem}.emoji-categories{display:flex;align-items:center;flex-shrink:0;gap:.25rem;margin-bottom:.75rem;padding-bottom:.75rem;overflow-x:auto;border-bottom:1px solid rgb(var(--ax-sys-color-border-light-surface))}.category-button{height:2rem;width:2rem;display:flex;justify-content:center;align-items:center;padding:.25rem;border:none;background:transparent;border-radius:.375rem;cursor:pointer;font-size:1.25rem;transition:all .15s;font-family:\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\",\"Apple Color Emoji\",Twemoji Mozilla,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.category-button:hover{background:rgb(var(--ax-sys-color-light-surface))}.category-button-active{background:rgb(var(--ax-sys-color-primary-lightest-surface));color:rgb(var(--ax-sys-color-on-primary-lightest-surface))}.emoji-grid{display:grid;grid-template-columns:repeat(auto-fill,32px);gap:.25rem;max-height:240px}.emoji-button{width:2rem;height:2rem;padding:.25rem;border:none;background:transparent;border-radius:.375rem;cursor:pointer;font-size:1.5rem;transition:all .15s;display:flex;align-items:center;justify-content:center;font-family:\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\",\"Apple Color Emoji\",Twemoji Mozilla,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.emoji-button:hover{background:rgb(var(--ax-sys-color-light-surface))}.emoji-empty{padding:2rem;text-align:center;opacity:.6}\n"] }]
177
+ }], ctorParameters: () => [], propDecorators: { itemSelected: [{ type: i0.Output, args: ["itemSelected"] }] } });
178
+
179
+ /**
180
+ * Emoji Tab Component
181
+ */
182
+
183
+ export { AXConversationEmojiTabComponent };
184
+ //# sourceMappingURL=acorex-components-conversation-index-3V2b14I0.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-components-conversation-index-3V2b14I0.mjs","sources":["../../../../packages/components/conversation/src/lib/plugins/composer/components/emoji-tab/emoji-tab.component.ts","../../../../packages/components/conversation/src/lib/plugins/composer/components/emoji-tab/index.ts"],"sourcesContent":["/**\n * Emoji Tab Component\n * Emoji picker for composer popup\n */\n\nimport { AXSearchBoxModule } from '@acorex/components/search-box';\nimport { AXTranslationModule } from '@acorex/core/translation';\nimport { CommonModule } from '@angular/common';\nimport { Component, computed, output, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\ninterface AXConversationEmoji {\n char: string;\n name: string;\n keywords: string[];\n}\n\ninterface AXConversationEmojiCategory {\n id: string;\n name: string;\n icon: string;\n emojis: AXConversationEmoji[];\n}\n\nlet emojiCategoriesCache: AXConversationEmojiCategory[] | null = null;\n\nasync function loadEmojiCategories(): Promise<AXConversationEmojiCategory[]> {\n if (emojiCategoriesCache) {\n return emojiCategoriesCache;\n }\n const module = await import('./emoji-categories.json');\n emojiCategoriesCache =\n (module as { default: AXConversationEmojiCategory[] }).default ??\n (module as unknown as AXConversationEmojiCategory[]);\n return emojiCategoriesCache;\n}\n\n@Component({\n selector: 'ax-conversation-emoji-tab',\n imports: [CommonModule, FormsModule, AXSearchBoxModule, AXTranslationModule],\n template: `\n <div class=\"emoji-tab\">\n <!-- Search -->\n <div class=\"emoji-search\">\n <ax-search-box\n [value]=\"searchQuery()\"\n [placeholder]=\"'Search emoji...'\"\n (onValueChanged)=\"onSearchChange($event)\"\n ></ax-search-box>\n </div>\n\n <!-- Categories -->\n <div class=\"emoji-categories\">\n @for (category of categories(); track category.id) {\n <button\n type=\"button\"\n [class]=\"getCategoryClasses(category.id)\"\n (click)=\"selectCategory(category.id)\"\n [attr.aria-label]=\"category.name\"\n [title]=\"category.name\"\n >\n {{ category.icon }}\n </button>\n }\n </div>\n\n <!-- Emoji Grid -->\n <div class=\"emoji-grid\">\n @for (emoji of filteredEmojis(); track emoji.char) {\n <button\n type=\"button\"\n class=\"emoji-button\"\n (click)=\"selectEmoji(emoji.char)\"\n [attr.aria-label]=\"emoji.name\"\n [title]=\"emoji.name\"\n >\n {{ emoji.char }}\n </button>\n }\n </div>\n\n @if (filteredEmojis().length === 0) {\n <div class=\"emoji-empty\">\n <p>{{ '@acorex:chat.empty.no-emojis-found' | translate | async }}</p>\n </div>\n }\n </div>\n `,\n styles: [\n `\n .emoji-tab {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .emoji-search {\n position: sticky;\n top: 0;\n z-index: 10;\n padding-block: 0.75rem;\n }\n\n .emoji-categories {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n gap: 0.25rem;\n margin-bottom: 0.75rem;\n padding-bottom: 0.75rem;\n overflow-x: auto;\n border-bottom: 1px solid rgb(var(--ax-sys-color-border-light-surface));\n }\n\n .category-button {\n height: 2rem;\n width: 2rem;\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 0.25rem;\n border: none;\n background: transparent;\n border-radius: 0.375rem;\n cursor: pointer;\n font-size: 1.25rem;\n transition: all 0.15s;\n font-family:\n 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji', 'Apple Color Emoji', 'Twemoji Mozilla', sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n }\n\n .category-button:hover {\n background: rgb(var(--ax-sys-color-light-surface));\n }\n\n .category-button-active {\n background: rgb(var(--ax-sys-color-primary-lightest-surface));\n color: rgb(var(--ax-sys-color-on-primary-lightest-surface));\n }\n\n .emoji-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, 32px);\n gap: 0.25rem;\n max-height: 240px;\n }\n\n .emoji-button {\n width: 2rem;\n height: 2rem;\n padding: 0.25rem;\n border: none;\n background: transparent;\n border-radius: 0.375rem;\n cursor: pointer;\n font-size: 1.5rem;\n transition: all 0.15s;\n display: flex;\n align-items: center;\n justify-content: center;\n font-family:\n 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji', 'Apple Color Emoji', 'Twemoji Mozilla', sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n }\n\n .emoji-button:hover {\n background: rgb(var(--ax-sys-color-light-surface));\n }\n\n .emoji-empty {\n padding: 2rem;\n text-align: center;\n opacity: 0.6;\n }\n `,\n ],\n})\nexport class AXConversationEmojiTabComponent {\n /** Emoji selected event */\n readonly itemSelected = output<string>();\n\n /** Search query */\n readonly searchQuery = signal('');\n\n /** Active category */\n private readonly activeCategoryId = signal<string>('smileys');\n\n /** Categories */\n readonly categories = signal<AXConversationEmojiCategory[]>([]);\n\n constructor() {\n void loadEmojiCategories().then((categories) => this.categories.set(categories));\n }\n\n /** Filtered emojis */\n readonly filteredEmojis = computed(() => {\n const query = this.searchQuery().toLowerCase().trim();\n const categoryId = this.activeCategoryId();\n\n if (query) {\n // Search across all categories by name and keywords\n return this.categories()\n .flatMap((cat) => cat.emojis)\n .filter((emoji) => {\n const searchText = `${emoji.name} ${emoji.keywords.join(' ')}`.toLowerCase();\n return searchText.includes(query);\n });\n } else {\n // Show active category\n const category = this.categories().find((c) => c.id === categoryId);\n return category ? category.emojis : [];\n }\n });\n\n /** Select category */\n selectCategory(categoryId: string): void {\n this.activeCategoryId.set(categoryId);\n this.searchQuery.set('');\n }\n\n /** Get category CSS classes */\n getCategoryClasses(categoryId: string): string {\n const classes = ['category-button'];\n if (this.activeCategoryId() === categoryId) {\n classes.push('category-button-active');\n }\n return classes.join(' ');\n }\n\n onSearchChange(event: { value?: string }): void {\n this.searchQuery.set(event?.value || '');\n }\n\n /** Select emoji */\n selectEmoji(emoji: string): void {\n this.itemSelected.emit(emoji);\n }\n}\n","/**\n * Emoji Tab Component\n */\n\nexport { AXConversationEmojiTabComponent } from './emoji-tab.component';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,266 @@
1
+ import * as i1$1 from '@acorex/components/search-box';
2
+ import { AXSearchBoxModule } from '@acorex/components/search-box';
3
+ import * as i1 from '@acorex/components/skeleton';
4
+ import { AXSkeletonModule } from '@acorex/components/skeleton';
5
+ import * as i3 from '@acorex/core/translation';
6
+ import { AXTranslationModule } from '@acorex/core/translation';
7
+ import * as i2 from '@angular/common';
8
+ import { CommonModule } from '@angular/common';
9
+ import { HttpClient } from '@angular/common/http';
10
+ import * as i0 from '@angular/core';
11
+ import { InjectionToken, inject, DestroyRef, output, signal, effect, Component } from '@angular/core';
12
+ import { FormsModule } from '@angular/forms';
13
+ import { firstValueFrom } from 'rxjs';
14
+
15
+ /**
16
+ * Sticker Tab Component
17
+ * Sticker picker for composer popup
18
+ */
19
+ const AX_CONVERSATION_STICKER_API_KEY = new InjectionToken('AX_CONVERSATION_STICKER_API_KEY', {
20
+ providedIn: 'root',
21
+ factory: () => 'sXpGFDGZs0Dv1mmNFvYaGUvYwKX0PWIh',
22
+ });
23
+ // Sticker categories using Giphy API
24
+ const AX_CONVERSATION_STICKER_CATEGORIES = [
25
+ { id: 'trending', name: 'Trending', icon: '🔥', searchTerm: 'trending' },
26
+ { id: 'happy', name: 'Happy', icon: '😊', searchTerm: 'happy' },
27
+ { id: 'love', name: 'Love', icon: '❤️', searchTerm: 'love' },
28
+ { id: 'funny', name: 'Funny', icon: '😂', searchTerm: 'funny' },
29
+ { id: 'cool', name: 'Cool', icon: '😎', searchTerm: 'cool' },
30
+ { id: 'party', name: 'Party', icon: '🎉', searchTerm: 'party' },
31
+ ];
32
+ class AXConversationStickerTabComponent {
33
+ constructor() {
34
+ this.http = inject(HttpClient);
35
+ this.destroyRef = inject(DestroyRef);
36
+ this.apiKey = inject(AX_CONVERSATION_STICKER_API_KEY);
37
+ this.itemSelected = output();
38
+ this.searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : /* istanbul ignore next */ []));
39
+ this.activeStickers = signal([], ...(ngDevMode ? [{ debugName: "activeStickers" }] : /* istanbul ignore next */ []));
40
+ this.loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
41
+ this.stickerCategories = AX_CONVERSATION_STICKER_CATEGORIES;
42
+ this.skeletonItems = Array.from({ length: 20 }, (_, i) => i);
43
+ this.activeCategoryId = signal('trending', ...(ngDevMode ? [{ debugName: "activeCategoryId" }] : /* istanbul ignore next */ []));
44
+ effect(() => {
45
+ const categoryId = this.activeCategoryId();
46
+ const query = this.searchQuery();
47
+ if (query.trim()) {
48
+ this.searchStickers(query);
49
+ }
50
+ else {
51
+ this.loadStickers(categoryId);
52
+ }
53
+ });
54
+ this.destroyRef.onDestroy(() => {
55
+ if (this.searchTimeout)
56
+ clearTimeout(this.searchTimeout);
57
+ });
58
+ }
59
+ async loadStickers(categoryId) {
60
+ this.loading.set(true);
61
+ try {
62
+ const category = AX_CONVERSATION_STICKER_CATEGORIES.find((c) => c.id === categoryId);
63
+ if (!category)
64
+ return;
65
+ const endpoint = categoryId === 'trending'
66
+ ? `https://api.giphy.com/v1/stickers/trending?api_key=${this.apiKey}&limit=20`
67
+ : `https://api.giphy.com/v1/stickers/search?api_key=${this.apiKey}&q=${category.searchTerm}&limit=20`;
68
+ const response = await firstValueFrom(this.http.get(endpoint));
69
+ this.activeStickers.set(this.mapGiphyStickers(response, categoryId));
70
+ }
71
+ catch (error) {
72
+ console.error('Failed to load stickers:', error);
73
+ this.activeStickers.set([]);
74
+ }
75
+ finally {
76
+ this.loading.set(false);
77
+ }
78
+ }
79
+ /** Select category */
80
+ selectPack(categoryId) {
81
+ this.activeCategoryId.set(categoryId);
82
+ this.searchQuery.set('');
83
+ }
84
+ async searchStickers(query) {
85
+ if (!query.trim()) {
86
+ this.loadStickers(this.activeCategoryId());
87
+ return;
88
+ }
89
+ this.loading.set(true);
90
+ try {
91
+ const endpoint = `https://api.giphy.com/v1/stickers/search?api_key=${this.apiKey}&q=${encodeURIComponent(query)}&limit=20`;
92
+ const response = await firstValueFrom(this.http.get(endpoint));
93
+ this.activeStickers.set(this.mapGiphyStickers(response, 'search'));
94
+ }
95
+ catch (error) {
96
+ console.error('Failed to search stickers:', error);
97
+ this.activeStickers.set([]);
98
+ }
99
+ finally {
100
+ this.loading.set(false);
101
+ }
102
+ }
103
+ onSearchChange(event) {
104
+ const query = event?.value || '';
105
+ if (this.searchTimeout) {
106
+ clearTimeout(this.searchTimeout);
107
+ }
108
+ this.searchTimeout = setTimeout(() => {
109
+ this.searchQuery.set(query);
110
+ }, 500);
111
+ }
112
+ /** Get category CSS classes */
113
+ getPackClasses(categoryId) {
114
+ const classes = ['pack-button'];
115
+ if (this.activeCategoryId() === categoryId) {
116
+ classes.push('pack-button-active');
117
+ }
118
+ return classes.join(' ');
119
+ }
120
+ mapGiphyStickers(response, packId) {
121
+ if (!response?.data)
122
+ return [];
123
+ return response.data.map((item) => ({
124
+ type: 'sticker',
125
+ id: item.id,
126
+ packId,
127
+ url: item.images.fixed_height.url,
128
+ animated: item.images.fixed_height.url.endsWith('.gif'),
129
+ width: Number(item.images.fixed_height.width),
130
+ height: Number(item.images.fixed_height.height),
131
+ emoji: item.title || 'Sticker',
132
+ }));
133
+ }
134
+ selectSticker(sticker) {
135
+ this.itemSelected.emit(sticker);
136
+ }
137
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXConversationStickerTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
138
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXConversationStickerTabComponent, isStandalone: true, selector: "ax-conversation-sticker-tab", outputs: { itemSelected: "itemSelected" }, ngImport: i0, template: `
139
+ <div class="sticker-tab">
140
+ <!-- Search -->
141
+ <div class="sticker-search">
142
+ <ax-search-box
143
+ [value]="searchQuery()"
144
+ [placeholder]="'Search stickers...'"
145
+ (onValueChanged)="onSearchChange($event)"
146
+ ></ax-search-box>
147
+ </div>
148
+
149
+ <!-- Categories -->
150
+ <div class="sticker-packs">
151
+ @for (category of stickerCategories; track category.id) {
152
+ <button
153
+ type="button"
154
+ [class]="getPackClasses(category.id)"
155
+ (click)="selectPack(category.id)"
156
+ [attr.aria-label]="category.name"
157
+ [title]="category.name"
158
+ >
159
+ {{ category.icon }}
160
+ </button>
161
+ }
162
+ </div>
163
+
164
+ <!-- Loading State -->
165
+ @if (loading()) {
166
+ <div class="sticker-grid">
167
+ @for (i of skeletonItems; track i) {
168
+ <div class="sticker-skeleton">
169
+ <ax-skeleton [animated]="true" class="skeleton-item"></ax-skeleton>
170
+ </div>
171
+ }
172
+ </div>
173
+ }
174
+
175
+ <!-- Stickers Grid -->
176
+ @if (!loading() && activeStickers().length > 0) {
177
+ <div class="sticker-grid">
178
+ @for (sticker of activeStickers(); track sticker.id) {
179
+ <button
180
+ type="button"
181
+ class="sticker-button"
182
+ (click)="selectSticker(sticker)"
183
+ [attr.aria-label]="sticker.emoji"
184
+ >
185
+ <img [src]="sticker.url" [alt]="sticker.emoji || 'Sticker'" class="sticker-image" loading="lazy" />
186
+ </button>
187
+ }
188
+ </div>
189
+ }
190
+
191
+ <!-- Empty State -->
192
+ @if (!loading() && activeStickers().length === 0) {
193
+ <div class="sticker-empty">
194
+ <p>{{ '@acorex:chat.empty.no-stickers-available' | translate | async }}</p>
195
+ </div>
196
+ }
197
+ </div>
198
+ `, isInline: true, styles: [".sticker-tab{display:flex;flex-direction:column;height:100%}.sticker-search{position:sticky;top:0;z-index:10;padding-block:.75rem}.sticker-packs{display:flex;gap:.25rem;padding-top:.75rem;margin-bottom:.75rem;padding-bottom:.75rem;border-bottom:1px solid rgb(var(--ax-sys-color-border-light-surface))}.pack-button{width:3rem;height:3rem;padding:.5rem;border:none;background:transparent;border-radius:.375rem;cursor:pointer;font-size:1.25rem;transition:all .15s;font-family:\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\",\"Apple Color Emoji\",Twemoji Mozilla,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.pack-button:hover{background:rgb(var(--ax-sys-color-light-surface))}.pack-button-active{background:rgb(var(--ax-sys-color-primary-lightest-surface))}.sticker-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:.5rem;overflow-y:auto;max-height:240px}.sticker-button{padding:.5rem;border:none;background:transparent;border-radius:.375rem;cursor:pointer;transition:all .15s;aspect-ratio:1}.sticker-button:hover{background:rgb(var(--ax-sys-color-light-surface))}.sticker-image{width:100%;height:100%;object-fit:contain}.sticker-empty{padding:2rem;text-align:center;opacity:.6}.sticker-skeleton{height:5rem;aspect-ratio:1;border-radius:.375rem;overflow:hidden}.skeleton-item{width:100%;height:100%;border-radius:.375rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i1.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i1$1.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.AXTranslatorPipe, name: "translate" }] }); }
199
+ }
200
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXConversationStickerTabComponent, decorators: [{
201
+ type: Component,
202
+ args: [{ selector: 'ax-conversation-sticker-tab', imports: [CommonModule, FormsModule, AXSkeletonModule, AXSearchBoxModule, AXTranslationModule], template: `
203
+ <div class="sticker-tab">
204
+ <!-- Search -->
205
+ <div class="sticker-search">
206
+ <ax-search-box
207
+ [value]="searchQuery()"
208
+ [placeholder]="'Search stickers...'"
209
+ (onValueChanged)="onSearchChange($event)"
210
+ ></ax-search-box>
211
+ </div>
212
+
213
+ <!-- Categories -->
214
+ <div class="sticker-packs">
215
+ @for (category of stickerCategories; track category.id) {
216
+ <button
217
+ type="button"
218
+ [class]="getPackClasses(category.id)"
219
+ (click)="selectPack(category.id)"
220
+ [attr.aria-label]="category.name"
221
+ [title]="category.name"
222
+ >
223
+ {{ category.icon }}
224
+ </button>
225
+ }
226
+ </div>
227
+
228
+ <!-- Loading State -->
229
+ @if (loading()) {
230
+ <div class="sticker-grid">
231
+ @for (i of skeletonItems; track i) {
232
+ <div class="sticker-skeleton">
233
+ <ax-skeleton [animated]="true" class="skeleton-item"></ax-skeleton>
234
+ </div>
235
+ }
236
+ </div>
237
+ }
238
+
239
+ <!-- Stickers Grid -->
240
+ @if (!loading() && activeStickers().length > 0) {
241
+ <div class="sticker-grid">
242
+ @for (sticker of activeStickers(); track sticker.id) {
243
+ <button
244
+ type="button"
245
+ class="sticker-button"
246
+ (click)="selectSticker(sticker)"
247
+ [attr.aria-label]="sticker.emoji"
248
+ >
249
+ <img [src]="sticker.url" [alt]="sticker.emoji || 'Sticker'" class="sticker-image" loading="lazy" />
250
+ </button>
251
+ }
252
+ </div>
253
+ }
254
+
255
+ <!-- Empty State -->
256
+ @if (!loading() && activeStickers().length === 0) {
257
+ <div class="sticker-empty">
258
+ <p>{{ '@acorex:chat.empty.no-stickers-available' | translate | async }}</p>
259
+ </div>
260
+ }
261
+ </div>
262
+ `, styles: [".sticker-tab{display:flex;flex-direction:column;height:100%}.sticker-search{position:sticky;top:0;z-index:10;padding-block:.75rem}.sticker-packs{display:flex;gap:.25rem;padding-top:.75rem;margin-bottom:.75rem;padding-bottom:.75rem;border-bottom:1px solid rgb(var(--ax-sys-color-border-light-surface))}.pack-button{width:3rem;height:3rem;padding:.5rem;border:none;background:transparent;border-radius:.375rem;cursor:pointer;font-size:1.25rem;transition:all .15s;font-family:\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\",\"Apple Color Emoji\",Twemoji Mozilla,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.pack-button:hover{background:rgb(var(--ax-sys-color-light-surface))}.pack-button-active{background:rgb(var(--ax-sys-color-primary-lightest-surface))}.sticker-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:.5rem;overflow-y:auto;max-height:240px}.sticker-button{padding:.5rem;border:none;background:transparent;border-radius:.375rem;cursor:pointer;transition:all .15s;aspect-ratio:1}.sticker-button:hover{background:rgb(var(--ax-sys-color-light-surface))}.sticker-image{width:100%;height:100%;object-fit:contain}.sticker-empty{padding:2rem;text-align:center;opacity:.6}.sticker-skeleton{height:5rem;aspect-ratio:1;border-radius:.375rem;overflow:hidden}.skeleton-item{width:100%;height:100%;border-radius:.375rem}\n"] }]
263
+ }], ctorParameters: () => [], propDecorators: { itemSelected: [{ type: i0.Output, args: ["itemSelected"] }] } });
264
+
265
+ export { AXConversationStickerTabComponent, AX_CONVERSATION_STICKER_API_KEY };
266
+ //# sourceMappingURL=acorex-components-conversation-index-MCvfr9Zd.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-components-conversation-index-MCvfr9Zd.mjs","sources":["../../../../packages/components/conversation/src/lib/plugins/composer/components/sticker-tab/sticker-tab.component.ts"],"sourcesContent":["/**\n * Sticker Tab Component\n * Sticker picker for composer popup\n */\n\nimport { AXSearchBoxModule } from '@acorex/components/search-box';\nimport { AXSkeletonModule } from '@acorex/components/skeleton';\nimport { AXTranslationModule } from '@acorex/core/translation';\nimport { CommonModule } from '@angular/common';\nimport { HttpClient } from '@angular/common/http';\nimport { Component, DestroyRef, InjectionToken, effect, inject, output, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { firstValueFrom } from 'rxjs';\nimport { AXConversationStickerPayload } from '../../../../models';\n\ninterface AXConversationGiphyImage {\n url: string;\n width: string;\n height: string;\n}\n\ninterface AXConversationGiphySticker {\n id: string;\n title: string;\n images: {\n fixed_height: AXConversationGiphyImage;\n };\n}\n\ninterface AXConversationGiphyResponse {\n data: AXConversationGiphySticker[];\n}\n\nexport const AX_CONVERSATION_STICKER_API_KEY = new InjectionToken<string>('AX_CONVERSATION_STICKER_API_KEY', {\n providedIn: 'root',\n factory: () => 'sXpGFDGZs0Dv1mmNFvYaGUvYwKX0PWIh',\n});\n\ninterface AXConversationStickerCategory {\n id: string;\n name: string;\n icon: string;\n searchTerm: string;\n}\n\n// Sticker categories using Giphy API\nconst AX_CONVERSATION_STICKER_CATEGORIES: AXConversationStickerCategory[] = [\n { id: 'trending', name: 'Trending', icon: '🔥', searchTerm: 'trending' },\n { id: 'happy', name: 'Happy', icon: '😊', searchTerm: 'happy' },\n { id: 'love', name: 'Love', icon: '❤️', searchTerm: 'love' },\n { id: 'funny', name: 'Funny', icon: '😂', searchTerm: 'funny' },\n { id: 'cool', name: 'Cool', icon: '😎', searchTerm: 'cool' },\n { id: 'party', name: 'Party', icon: '🎉', searchTerm: 'party' },\n];\n\n@Component({\n selector: 'ax-conversation-sticker-tab',\n imports: [CommonModule, FormsModule, AXSkeletonModule, AXSearchBoxModule, AXTranslationModule],\n template: `\n <div class=\"sticker-tab\">\n <!-- Search -->\n <div class=\"sticker-search\">\n <ax-search-box\n [value]=\"searchQuery()\"\n [placeholder]=\"'Search stickers...'\"\n (onValueChanged)=\"onSearchChange($event)\"\n ></ax-search-box>\n </div>\n\n <!-- Categories -->\n <div class=\"sticker-packs\">\n @for (category of stickerCategories; track category.id) {\n <button\n type=\"button\"\n [class]=\"getPackClasses(category.id)\"\n (click)=\"selectPack(category.id)\"\n [attr.aria-label]=\"category.name\"\n [title]=\"category.name\"\n >\n {{ category.icon }}\n </button>\n }\n </div>\n\n <!-- Loading State -->\n @if (loading()) {\n <div class=\"sticker-grid\">\n @for (i of skeletonItems; track i) {\n <div class=\"sticker-skeleton\">\n <ax-skeleton [animated]=\"true\" class=\"skeleton-item\"></ax-skeleton>\n </div>\n }\n </div>\n }\n\n <!-- Stickers Grid -->\n @if (!loading() && activeStickers().length > 0) {\n <div class=\"sticker-grid\">\n @for (sticker of activeStickers(); track sticker.id) {\n <button\n type=\"button\"\n class=\"sticker-button\"\n (click)=\"selectSticker(sticker)\"\n [attr.aria-label]=\"sticker.emoji\"\n >\n <img [src]=\"sticker.url\" [alt]=\"sticker.emoji || 'Sticker'\" class=\"sticker-image\" loading=\"lazy\" />\n </button>\n }\n </div>\n }\n\n <!-- Empty State -->\n @if (!loading() && activeStickers().length === 0) {\n <div class=\"sticker-empty\">\n <p>{{ '@acorex:chat.empty.no-stickers-available' | translate | async }}</p>\n </div>\n }\n </div>\n `,\n styles: [\n `\n .sticker-tab {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .sticker-search {\n position: sticky;\n top: 0;\n z-index: 10;\n padding-block: 0.75rem;\n }\n\n .sticker-packs {\n display: flex;\n gap: 0.25rem;\n padding-top: 0.75rem;\n margin-bottom: 0.75rem;\n padding-bottom: 0.75rem;\n border-bottom: 1px solid rgb(var(--ax-sys-color-border-light-surface));\n }\n\n .pack-button {\n width: 3rem;\n height: 3rem;\n padding: 0.5rem;\n border: none;\n background: transparent;\n border-radius: 0.375rem;\n cursor: pointer;\n font-size: 1.25rem;\n transition: all 0.15s;\n font-family:\n 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji', 'Apple Color Emoji', 'Twemoji Mozilla', sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n }\n\n .pack-button:hover {\n background: rgb(var(--ax-sys-color-light-surface));\n }\n\n .pack-button-active {\n background: rgb(var(--ax-sys-color-primary-lightest-surface));\n }\n\n .sticker-grid {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 0.5rem;\n overflow-y: auto;\n max-height: 240px;\n }\n\n .sticker-button {\n padding: 0.5rem;\n border: none;\n background: transparent;\n border-radius: 0.375rem;\n cursor: pointer;\n transition: all 0.15s;\n aspect-ratio: 1;\n }\n\n .sticker-button:hover {\n background: rgb(var(--ax-sys-color-light-surface));\n }\n\n .sticker-image {\n width: 100%;\n height: 100%;\n object-fit: contain;\n }\n\n .sticker-empty {\n padding: 2rem;\n text-align: center;\n opacity: 0.6;\n }\n\n .sticker-skeleton {\n height: 5rem;\n aspect-ratio: 1;\n border-radius: 0.375rem;\n overflow: hidden;\n }\n\n .skeleton-item {\n width: 100%;\n height: 100%;\n border-radius: 0.375rem;\n }\n `,\n ],\n})\nexport class AXConversationStickerTabComponent {\n private readonly http = inject(HttpClient);\n private readonly destroyRef = inject(DestroyRef);\n private readonly apiKey = inject(AX_CONVERSATION_STICKER_API_KEY);\n\n readonly itemSelected = output<AXConversationStickerPayload>();\n readonly searchQuery = signal('');\n readonly activeStickers = signal<AXConversationStickerPayload[]>([]);\n readonly loading = signal(false);\n readonly stickerCategories = AX_CONVERSATION_STICKER_CATEGORIES;\n readonly skeletonItems = Array.from({ length: 20 }, (_, i) => i);\n\n private readonly activeCategoryId = signal<string>('trending');\n private searchTimeout?: ReturnType<typeof setTimeout>;\n\n constructor() {\n effect(() => {\n const categoryId = this.activeCategoryId();\n const query = this.searchQuery();\n\n if (query.trim()) {\n this.searchStickers(query);\n } else {\n this.loadStickers(categoryId);\n }\n });\n\n this.destroyRef.onDestroy(() => {\n if (this.searchTimeout) clearTimeout(this.searchTimeout);\n });\n }\n\n private async loadStickers(categoryId: string): Promise<void> {\n this.loading.set(true);\n try {\n const category = AX_CONVERSATION_STICKER_CATEGORIES.find((c) => c.id === categoryId);\n if (!category) return;\n\n const endpoint =\n categoryId === 'trending'\n ? `https://api.giphy.com/v1/stickers/trending?api_key=${this.apiKey}&limit=20`\n : `https://api.giphy.com/v1/stickers/search?api_key=${this.apiKey}&q=${category.searchTerm}&limit=20`;\n\n const response = await firstValueFrom(this.http.get<AXConversationGiphyResponse>(endpoint));\n this.activeStickers.set(this.mapGiphyStickers(response, categoryId));\n } catch (error) {\n console.error('Failed to load stickers:', error);\n this.activeStickers.set([]);\n } finally {\n this.loading.set(false);\n }\n }\n\n /** Select category */\n selectPack(categoryId: string): void {\n this.activeCategoryId.set(categoryId);\n this.searchQuery.set('');\n }\n\n private async searchStickers(query: string): Promise<void> {\n if (!query.trim()) {\n this.loadStickers(this.activeCategoryId());\n return;\n }\n\n this.loading.set(true);\n try {\n const endpoint = `https://api.giphy.com/v1/stickers/search?api_key=${this.apiKey}&q=${encodeURIComponent(query)}&limit=20`;\n const response = await firstValueFrom(this.http.get<AXConversationGiphyResponse>(endpoint));\n this.activeStickers.set(this.mapGiphyStickers(response, 'search'));\n } catch (error) {\n console.error('Failed to search stickers:', error);\n this.activeStickers.set([]);\n } finally {\n this.loading.set(false);\n }\n }\n\n onSearchChange(event: { value?: string }): void {\n const query = event?.value || '';\n\n if (this.searchTimeout) {\n clearTimeout(this.searchTimeout);\n }\n\n this.searchTimeout = setTimeout(() => {\n this.searchQuery.set(query);\n }, 500);\n }\n\n /** Get category CSS classes */\n getPackClasses(categoryId: string): string {\n const classes = ['pack-button'];\n if (this.activeCategoryId() === categoryId) {\n classes.push('pack-button-active');\n }\n return classes.join(' ');\n }\n\n private mapGiphyStickers(response: AXConversationGiphyResponse, packId: string): AXConversationStickerPayload[] {\n if (!response?.data) return [];\n return response.data.map((item) => ({\n type: 'sticker' as const,\n id: item.id,\n packId,\n url: item.images.fixed_height.url,\n animated: item.images.fixed_height.url.endsWith('.gif'),\n width: Number(item.images.fixed_height.width),\n height: Number(item.images.fixed_height.height),\n emoji: item.title || 'Sticker',\n }));\n }\n\n selectSticker(sticker: AXConversationStickerPayload): void {\n this.itemSelected.emit(sticker);\n }\n}\n"],"names":["i3","i4"],"mappings":"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"}