@ng-nest/ui 20.1.0 → 20.1.1

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 (115) hide show
  1. package/auto-complete/index.d.ts +3 -3
  2. package/avatar/index.d.ts +64 -2
  3. package/bubble/index.d.ts +170 -0
  4. package/calendar/index.d.ts +2 -1
  5. package/cascade/index.d.ts +3 -3
  6. package/checkbox/index.d.ts +1 -1
  7. package/color-picker/index.d.ts +3 -3
  8. package/core/index.d.ts +16 -4
  9. package/date-picker/index.d.ts +4 -4
  10. package/dropdown/index.d.ts +4 -4
  11. package/fesm2022/ng-nest-ui-affix.mjs +10 -10
  12. package/fesm2022/ng-nest-ui-alert.mjs +10 -10
  13. package/fesm2022/ng-nest-ui-anchor.mjs +16 -16
  14. package/fesm2022/ng-nest-ui-api.mjs +7 -7
  15. package/fesm2022/ng-nest-ui-auto-complete.mjs +13 -13
  16. package/fesm2022/ng-nest-ui-avatar.mjs +28 -16
  17. package/fesm2022/ng-nest-ui-avatar.mjs.map +1 -1
  18. package/fesm2022/ng-nest-ui-back-top.mjs +10 -10
  19. package/fesm2022/ng-nest-ui-badge.mjs +10 -10
  20. package/fesm2022/ng-nest-ui-base-form.mjs +7 -7
  21. package/fesm2022/ng-nest-ui-bubble.mjs +350 -0
  22. package/fesm2022/ng-nest-ui-bubble.mjs.map +1 -0
  23. package/fesm2022/ng-nest-ui-button.mjs +16 -16
  24. package/fesm2022/ng-nest-ui-calendar.mjs +10 -10
  25. package/fesm2022/ng-nest-ui-card.mjs +10 -10
  26. package/fesm2022/ng-nest-ui-carousel.mjs +16 -16
  27. package/fesm2022/ng-nest-ui-cascade.mjs +13 -13
  28. package/fesm2022/ng-nest-ui-checkbox.mjs +10 -10
  29. package/fesm2022/ng-nest-ui-collapse.mjs +16 -16
  30. package/fesm2022/ng-nest-ui-color-picker.mjs +16 -16
  31. package/fesm2022/ng-nest-ui-color.mjs +10 -10
  32. package/fesm2022/ng-nest-ui-comment.mjs +16 -16
  33. package/fesm2022/ng-nest-ui-container.mjs +31 -31
  34. package/fesm2022/ng-nest-ui-core.mjs +21 -18
  35. package/fesm2022/ng-nest-ui-core.mjs.map +1 -1
  36. package/fesm2022/ng-nest-ui-crumb.mjs +10 -10
  37. package/fesm2022/ng-nest-ui-date-picker.mjs +49 -49
  38. package/fesm2022/ng-nest-ui-description.mjs +16 -16
  39. package/fesm2022/ng-nest-ui-dialog.mjs +40 -40
  40. package/fesm2022/ng-nest-ui-doc.mjs +7 -7
  41. package/fesm2022/ng-nest-ui-drag.mjs +10 -10
  42. package/fesm2022/ng-nest-ui-drawer.mjs +31 -31
  43. package/fesm2022/ng-nest-ui-dropdown.mjs +13 -13
  44. package/fesm2022/ng-nest-ui-empty.mjs +10 -10
  45. package/fesm2022/ng-nest-ui-examples.mjs +7 -7
  46. package/fesm2022/ng-nest-ui-find.mjs +10 -10
  47. package/fesm2022/ng-nest-ui-form.mjs +16 -16
  48. package/fesm2022/ng-nest-ui-highlight.mjs +13 -13
  49. package/fesm2022/ng-nest-ui-i18n.mjs +13 -13
  50. package/fesm2022/ng-nest-ui-icon.mjs +13 -13
  51. package/fesm2022/ng-nest-ui-image.mjs +19 -19
  52. package/fesm2022/ng-nest-ui-inner.mjs +10 -10
  53. package/fesm2022/ng-nest-ui-input-number.mjs +10 -10
  54. package/fesm2022/ng-nest-ui-input.mjs +18 -18
  55. package/fesm2022/ng-nest-ui-input.mjs.map +1 -1
  56. package/fesm2022/ng-nest-ui-keyword.mjs +10 -10
  57. package/fesm2022/ng-nest-ui-layout.mjs +16 -16
  58. package/fesm2022/ng-nest-ui-link.mjs +10 -10
  59. package/fesm2022/ng-nest-ui-list.mjs +19 -19
  60. package/fesm2022/ng-nest-ui-loading.mjs +16 -11
  61. package/fesm2022/ng-nest-ui-loading.mjs.map +1 -1
  62. package/fesm2022/ng-nest-ui-menu.mjs +16 -16
  63. package/fesm2022/ng-nest-ui-message-box.mjs +10 -10
  64. package/fesm2022/ng-nest-ui-message.mjs +10 -10
  65. package/fesm2022/ng-nest-ui-notification.mjs +10 -10
  66. package/fesm2022/ng-nest-ui-outlet.mjs +7 -7
  67. package/fesm2022/ng-nest-ui-page-header.mjs +10 -10
  68. package/fesm2022/ng-nest-ui-pagination.mjs +10 -10
  69. package/fesm2022/ng-nest-ui-pattern.mjs +7 -7
  70. package/fesm2022/ng-nest-ui-popconfirm.mjs +10 -10
  71. package/fesm2022/ng-nest-ui-popover.mjs +13 -13
  72. package/fesm2022/ng-nest-ui-portal.mjs +7 -7
  73. package/fesm2022/ng-nest-ui-progress.mjs +10 -10
  74. package/fesm2022/ng-nest-ui-radio.mjs +10 -10
  75. package/fesm2022/ng-nest-ui-rate.mjs +10 -10
  76. package/fesm2022/ng-nest-ui-resizable.mjs +10 -10
  77. package/fesm2022/ng-nest-ui-result.mjs +10 -10
  78. package/fesm2022/ng-nest-ui-ripple.mjs +10 -10
  79. package/fesm2022/ng-nest-ui-scrollable.mjs +7 -7
  80. package/fesm2022/ng-nest-ui-select.mjs +13 -13
  81. package/fesm2022/ng-nest-ui-skeleton.mjs +10 -10
  82. package/fesm2022/ng-nest-ui-slider-select.mjs +10 -10
  83. package/fesm2022/ng-nest-ui-slider.mjs +10 -10
  84. package/fesm2022/ng-nest-ui-statistic.mjs +16 -16
  85. package/fesm2022/ng-nest-ui-steps.mjs +10 -10
  86. package/fesm2022/ng-nest-ui-switch.mjs +10 -10
  87. package/fesm2022/ng-nest-ui-table-view.mjs +58 -58
  88. package/fesm2022/ng-nest-ui-table.mjs +34 -34
  89. package/fesm2022/ng-nest-ui-tabs.mjs +25 -25
  90. package/fesm2022/ng-nest-ui-tag.mjs +10 -10
  91. package/fesm2022/ng-nest-ui-text-retract.mjs +10 -10
  92. package/fesm2022/ng-nest-ui-textarea.mjs +10 -10
  93. package/fesm2022/ng-nest-ui-theme.mjs +10 -10
  94. package/fesm2022/ng-nest-ui-time-ago.mjs +7 -7
  95. package/fesm2022/ng-nest-ui-time-picker.mjs +16 -16
  96. package/fesm2022/ng-nest-ui-time-range.mjs +7 -7
  97. package/fesm2022/ng-nest-ui-timeline.mjs +10 -10
  98. package/fesm2022/ng-nest-ui-tooltip.mjs +13 -13
  99. package/fesm2022/ng-nest-ui-transfer.mjs +10 -10
  100. package/fesm2022/ng-nest-ui-tree-file.mjs +10 -10
  101. package/fesm2022/ng-nest-ui-tree-select.mjs +13 -13
  102. package/fesm2022/ng-nest-ui-tree.mjs +19 -19
  103. package/fesm2022/ng-nest-ui-typography.mjs +10 -10
  104. package/fesm2022/ng-nest-ui-upload.mjs +13 -13
  105. package/fesm2022/ng-nest-ui.mjs +1 -0
  106. package/fesm2022/ng-nest-ui.mjs.map +1 -1
  107. package/index.d.ts +1 -0
  108. package/loading/index.d.ts +6 -1
  109. package/message-box/index.d.ts +5 -4
  110. package/package.json +47 -43
  111. package/radio/index.d.ts +1 -1
  112. package/select/index.d.ts +3 -3
  113. package/steps/index.d.ts +2 -1
  114. package/time-picker/index.d.ts +3 -3
  115. package/tree-select/index.d.ts +3 -3
@@ -0,0 +1,350 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, Component, inject, ElementRef, Renderer2, contentChildren, ChangeDetectionStrategy, ViewEncapsulation, viewChild, computed, signal, effect, NgModule } from '@angular/core';
3
+ import { XPropertyFunction, XToBoolean, XToNumber, XIsEmpty } from '@ng-nest/ui/core';
4
+ import { XOutletDirective } from '@ng-nest/ui/outlet';
5
+ import { NgClass } from '@angular/common';
6
+ import { XAvatarComponent } from '@ng-nest/ui/avatar';
7
+ import { XLoadingComponent } from '@ng-nest/ui/loading';
8
+ import { DomSanitizer } from '@angular/platform-browser';
9
+ import { toObservable } from '@angular/core/rxjs-interop';
10
+
11
+ /**
12
+ * Bubble
13
+ * @selector x-bubble
14
+ * @decorator component
15
+ */
16
+ const XBubblePrefix = 'x-bubble';
17
+ const X_BUBBLE_CONFIG_NAME = 'bubble';
18
+ /**
19
+ * Bubble Property
20
+ */
21
+ class XBubbleProperty extends XPropertyFunction(X_BUBBLE_CONFIG_NAME) {
22
+ constructor() {
23
+ super(...arguments);
24
+ /**
25
+ * @zh_CN 气泡内容
26
+ * @en_US Bubble content
27
+ */
28
+ this.content = input(...(ngDevMode ? [undefined, { debugName: "content" }] : []));
29
+ /**
30
+ * @zh_CN 头像
31
+ * @en_US Avatar
32
+ */
33
+ this.avatar = input(...(ngDevMode ? [undefined, { debugName: "avatar" }] : []));
34
+ /**
35
+ * @zh_CN 尺寸
36
+ * @en_US Size
37
+ */
38
+ this.size = input(this.config?.size ?? 'medium', ...(ngDevMode ? [{ debugName: "size" }] : []));
39
+ /**
40
+ * @zh_CN 形态变体
41
+ * @en_US Bubble variant
42
+ */
43
+ this.variant = input(this.config?.variant ?? 'outlined', ...(ngDevMode ? [{ debugName: "variant" }] : []));
44
+ /**
45
+ * @zh_CN 位置
46
+ * @en_US Bubble placement
47
+ */
48
+ this.placement = input('start', ...(ngDevMode ? [{ debugName: "placement" }] : []));
49
+ /**
50
+ * @zh_CN 气泡头部内容
51
+ * @en_US Bubble header content
52
+ */
53
+ this.header = input(...(ngDevMode ? [undefined, { debugName: "header" }] : []));
54
+ /**
55
+ * @zh_CN 气泡底部内容
56
+ * @en_US Bubble header content
57
+ */
58
+ this.footer = input(...(ngDevMode ? [undefined, { debugName: "footer" }] : []));
59
+ /**
60
+ * @zh_CN 加载中
61
+ * @en_US Loading
62
+ */
63
+ this.loading = input(false, ...(ngDevMode ? [{ debugName: "loading", transform: XToBoolean }] : [{ transform: XToBoolean }]));
64
+ /**
65
+ * @zh_CN 内容输出打字机效果
66
+ * @en_US Typing effect
67
+ */
68
+ this.typing = input(false, ...(ngDevMode ? [{ debugName: "typing", transform: XToBoolean }] : [{ transform: XToBoolean }]));
69
+ /**
70
+ * @zh_CN 打字机输出速度
71
+ * @en_US Typing speed
72
+ */
73
+ this.speed = input(30, ...(ngDevMode ? [{ debugName: "speed", transform: XToNumber }] : [{ transform: XToNumber }]));
74
+ /**
75
+ * @zh_CN 内容渲染器,可自定义内容的渲染方式,如 HTML、Markdown
76
+ * @en_US Content renderer, can customize content rendering, such as HTML, Markdown
77
+ */
78
+ this.renderer = input(...(ngDevMode ? [undefined, { debugName: "renderer" }] : []));
79
+ /**
80
+ * @zh_CN 是否显示打字机光标
81
+ * @en_US Whether to show the typing cursor
82
+ */
83
+ this.showCursor = input(false, ...(ngDevMode ? [{ debugName: "showCursor", transform: XToBoolean }] : [{ transform: XToBoolean }]));
84
+ }
85
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: XBubbleProperty, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
86
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.0", type: XBubbleProperty, isStandalone: true, selector: "x-bubble-property", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, avatar: { classPropertyName: "avatar", publicName: "avatar", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, footer: { classPropertyName: "footer", publicName: "footer", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, typing: { classPropertyName: "typing", publicName: "typing", isSignal: true, isRequired: false, transformFunction: null }, speed: { classPropertyName: "speed", publicName: "speed", isSignal: true, isRequired: false, transformFunction: null }, renderer: { classPropertyName: "renderer", publicName: "renderer", isSignal: true, isRequired: false, transformFunction: null }, showCursor: { classPropertyName: "showCursor", publicName: "showCursor", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: '', isInline: true }); }
87
+ }
88
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: XBubbleProperty, decorators: [{
89
+ type: Component,
90
+ args: [{ selector: `${XBubblePrefix}-property`, template: '' }]
91
+ }] });
92
+ /**
93
+ * Bubbles
94
+ * @selector x-bubbles
95
+ * @decorator component
96
+ */
97
+ const XBubblesPrefix = 'x-bubbles';
98
+ const X_BUBBLES_CONFIG_NAME = 'bubbles';
99
+ /**
100
+ * Bubbles Property
101
+ */
102
+ class XBubblesProperty extends XPropertyFunction(X_BUBBLES_CONFIG_NAME) {
103
+ constructor() {
104
+ super(...arguments);
105
+ /**
106
+ * @zh_CN 尺寸
107
+ * @en_US Size
108
+ */
109
+ this.size = input(...(ngDevMode ? [undefined, { debugName: "size" }] : []));
110
+ /**
111
+ * @zh_CN 形态变体
112
+ * @en_US Bubble variant
113
+ */
114
+ this.variant = input(...(ngDevMode ? [undefined, { debugName: "variant" }] : []));
115
+ }
116
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: XBubblesProperty, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
117
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.0", type: XBubblesProperty, isStandalone: true, selector: "x-bubbles-property", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: '', isInline: true }); }
118
+ }
119
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: XBubblesProperty, decorators: [{
120
+ type: Component,
121
+ args: [{ selector: `${XBubblesPrefix}-property`, template: '' }]
122
+ }] });
123
+
124
+ class XBubblesComponent extends XBubblesProperty {
125
+ constructor() {
126
+ super(...arguments);
127
+ this.elementRef = inject(ElementRef);
128
+ this.renderer = inject(Renderer2);
129
+ this.parentScrollElement = null;
130
+ this.isFollowing = true;
131
+ this.removeScrollListener = null;
132
+ this.contentMutationObserver = null;
133
+ this.typingObserver = null;
134
+ this.bubbles = contentChildren(XBubbleComponent, ...(ngDevMode ? [{ debugName: "bubbles" }] : []));
135
+ }
136
+ ngAfterViewInit() {
137
+ this.parentScrollElement = this.getParentScrollElement(this.elementRef.nativeElement);
138
+ if (this.parentScrollElement) {
139
+ this.removeScrollListener = this.renderer.listen(this.parentScrollElement, 'scroll', () => {
140
+ const atBottom = this.parentScrollElement.scrollHeight - this.parentScrollElement.scrollTop ===
141
+ this.parentScrollElement.clientHeight;
142
+ if (!atBottom) {
143
+ this.isFollowing = false;
144
+ }
145
+ else {
146
+ this.isFollowing = true;
147
+ }
148
+ });
149
+ this.observeContentChanges();
150
+ }
151
+ }
152
+ ngDoCheck() {
153
+ const bubbles = this.bubbles();
154
+ if (bubbles.length <= 0)
155
+ return;
156
+ const lastBubble = bubbles[bubbles.length - 1];
157
+ if (lastBubble && lastBubble.typing() && lastBubble.pendingContent().length > 0) {
158
+ if (!this.typingObserver) {
159
+ this.startTypingObserver(lastBubble);
160
+ }
161
+ }
162
+ else {
163
+ if (this.typingObserver) {
164
+ this.stopTypingObserver();
165
+ }
166
+ }
167
+ }
168
+ ngOnDestroy() {
169
+ if (this.removeScrollListener) {
170
+ this.removeScrollListener();
171
+ }
172
+ if (this.contentMutationObserver) {
173
+ this.contentMutationObserver.disconnect();
174
+ }
175
+ this.stopTypingObserver();
176
+ }
177
+ getParentScrollElement(element) {
178
+ let parent = this.renderer.parentNode(element);
179
+ while (parent && parent.nodeType === 1) {
180
+ const overflowY = getComputedStyle(parent).overflowY;
181
+ if (overflowY === 'auto' || overflowY === 'scroll') {
182
+ return parent;
183
+ }
184
+ parent = this.renderer.parentNode(parent);
185
+ }
186
+ return null;
187
+ }
188
+ observeContentChanges() {
189
+ this.contentMutationObserver = new MutationObserver(() => {
190
+ this.isFollowing = true;
191
+ this.scrollToBottom();
192
+ });
193
+ this.contentMutationObserver.observe(this.elementRef.nativeElement, { childList: true });
194
+ }
195
+ startTypingObserver(bubble) {
196
+ const bubbleContent = bubble.contentRef()?.nativeElement;
197
+ if (bubbleContent) {
198
+ this.typingObserver = new MutationObserver(() => {
199
+ if (this.isFollowing) {
200
+ this.scrollToBottom();
201
+ }
202
+ });
203
+ this.typingObserver.observe(bubbleContent, {
204
+ childList: true,
205
+ subtree: true,
206
+ characterData: true
207
+ });
208
+ }
209
+ }
210
+ stopTypingObserver() {
211
+ if (this.typingObserver) {
212
+ this.typingObserver.disconnect();
213
+ this.typingObserver = null;
214
+ }
215
+ }
216
+ scrollToBottom() {
217
+ if (this.parentScrollElement) {
218
+ this.parentScrollElement.scrollTop = this.parentScrollElement.scrollHeight;
219
+ }
220
+ }
221
+ scrollToTop() {
222
+ if (this.parentScrollElement) {
223
+ this.parentScrollElement.scrollTop = 0;
224
+ }
225
+ }
226
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: XBubblesComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
227
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.0", type: XBubblesComponent, isStandalone: true, selector: "x-bubbles", queries: [{ propertyName: "bubbles", predicate: XBubbleComponent, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ng-content></ng-content>\r\n", styles: ["x-bubbles{margin:0;padding:0}x-bubbles{display:flex;flex-direction:column;gap:1rem}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
228
+ }
229
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: XBubblesComponent, decorators: [{
230
+ type: Component,
231
+ args: [{ selector: 'x-bubbles', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [], template: "<ng-content></ng-content>\r\n", styles: ["x-bubbles{margin:0;padding:0}x-bubbles{display:flex;flex-direction:column;gap:1rem}\n"] }]
232
+ }] });
233
+
234
+ class XBubbleComponent extends XBubbleProperty {
235
+ constructor() {
236
+ super();
237
+ this.sanitizer = inject(DomSanitizer);
238
+ this.renderer2 = inject(Renderer2);
239
+ this.bubbles = inject(XBubblesComponent, { optional: true, host: true });
240
+ this.contentRef = viewChild('contentRef', ...(ngDevMode ? [{ debugName: "contentRef" }] : []));
241
+ this.classMap = computed(() => ({
242
+ [`${XBubblePrefix}-${this.variantSignal()}`]: !XIsEmpty(this.variantSignal()),
243
+ [`${XBubblePrefix}-${this.placement()}`]: !XIsEmpty(this.placement()),
244
+ [`${XBubblePrefix}-cursor`]: this.showCursor() && this.typing(),
245
+ [`${XBubblePrefix}-typing`]: this.typing() && this.pendingContent().length > 0,
246
+ [`x-size-${this.sizeSignal()}`]: !XIsEmpty(this.sizeSignal())
247
+ }), ...(ngDevMode ? [{ debugName: "classMap" }] : []));
248
+ this.typedContent = signal('', ...(ngDevMode ? [{ debugName: "typedContent" }] : []));
249
+ this.pendingContent = signal('', ...(ngDevMode ? [{ debugName: "pendingContent" }] : []));
250
+ this.pendingContentObserver = toObservable(this.pendingContent);
251
+ this.typingInterval = null;
252
+ this.sizeSignal = computed(() => {
253
+ return this.bubbles?.size() || this.size();
254
+ }, ...(ngDevMode ? [{ debugName: "sizeSignal" }] : []));
255
+ this.variantSignal = computed(() => {
256
+ return this.bubbles?.variant() || this.variant();
257
+ }, ...(ngDevMode ? [{ debugName: "variantSignal" }] : []));
258
+ effect(() => {
259
+ if (!this.typing()) {
260
+ this.stopTyping();
261
+ this.typedContent.set(this.typedContent() + this.pendingContent());
262
+ this.pendingContent.set('');
263
+ }
264
+ });
265
+ }
266
+ ngOnChanges(changes) {
267
+ if (changes['content']) {
268
+ const newFullContent = changes['content'].currentValue || '';
269
+ const currentTypedContent = this.typedContent();
270
+ if (!this.typing()) {
271
+ this.typedContent.set(newFullContent);
272
+ return;
273
+ }
274
+ if (newFullContent.startsWith(currentTypedContent)) {
275
+ this.pendingContent.set(newFullContent.substring(currentTypedContent.length));
276
+ this.startTyping();
277
+ }
278
+ else {
279
+ this.stopTyping();
280
+ this.typedContent.set('');
281
+ this.pendingContent.set(newFullContent);
282
+ this.startTyping();
283
+ }
284
+ }
285
+ }
286
+ get renderedContent() {
287
+ const finalContent = this.typing() ? this.typedContent() : this.content() || '';
288
+ let renderedString;
289
+ if (this.renderer()) {
290
+ renderedString = this.renderer()(finalContent) || '';
291
+ }
292
+ else {
293
+ renderedString = finalContent;
294
+ }
295
+ return this.sanitizer.bypassSecurityTrustHtml(renderedString);
296
+ }
297
+ startTyping() {
298
+ if (this.typingInterval) {
299
+ return;
300
+ }
301
+ if (this.pendingContent().length === 0) {
302
+ return;
303
+ }
304
+ this.typingInterval = setInterval(() => {
305
+ if (this.pendingContent().length > 0) {
306
+ const nextChar = this.pendingContent().charAt(0);
307
+ this.typedContent.update((current) => current + nextChar);
308
+ this.pendingContent.update((current) => current.substring(1));
309
+ }
310
+ else {
311
+ this.stopTyping();
312
+ }
313
+ }, this.speed());
314
+ }
315
+ stopTyping() {
316
+ if (this.typingInterval) {
317
+ clearInterval(this.typingInterval);
318
+ this.typingInterval = null;
319
+ }
320
+ }
321
+ ngOnDestroy() {
322
+ this.stopTyping();
323
+ }
324
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: XBubbleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
325
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.0", type: XBubbleComponent, isStandalone: true, selector: "x-bubble", viewQueries: [{ propertyName: "contentRef", first: true, predicate: ["contentRef"], descendants: true, isSignal: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"x-bubble\" [ngClass]=\"classMap()\">\r\n @if (!!avatar()) {\r\n <div class=\"x-bubble-avatar\">\r\n <x-avatar\r\n [icon]=\"avatar()?.icon!\"\r\n [label]=\"avatar()?.label!\"\r\n [src]=\"avatar()?.src!\"\r\n [size]=\"avatar()?.size ?? size()\"\r\n [gap]=\"avatar()?.gap ?? '0.25rem'\"\r\n [fit]=\"avatar()?.fit ?? 'cover'\"\r\n [backgroundColor]=\"avatar()?.backgroundColor ?? '#999999'\"\r\n [color]=\"avatar()?.color ?? '#FFFFFF'\"\r\n [shape]=\"avatar()?.shape ?? 'circle'\"\r\n ></x-avatar>\r\n </div>\r\n }\r\n <div class=\"x-bubble-warp\">\r\n @if (loading()) {\r\n <div class=\"x-bubble-content\" [x-loading]=\"true\" [size]=\"'small'\" inline></div>\r\n } @else {\r\n @if (header()) {\r\n <div class=\"x-bubble-header\">\r\n <ng-container *xOutlet=\"header()\">{{ header() }}</ng-container>\r\n </div>\r\n }\r\n <div class=\"x-bubble-content\" #contentRef [innerHTML]=\"renderedContent\"></div>\r\n @if (footer()) {\r\n <div class=\"x-bubble-footer\">\r\n <ng-container *xOutlet=\"footer()\">{{ footer() }}</ng-container>\r\n </div>\r\n }\r\n }\r\n </div>\r\n</div>\r\n", styles: [".x-bubble{margin:0;padding:0}.x-bubble{display:flex}.x-bubble-content{position:relative;box-sizing:border-box;min-width:0;max-width:100%;color:var(--x-text);font-size:var(--x-font-size);border-radius:var(--x-border-radius);word-break:break-word}.x-bubble-outlined .x-bubble-content{border:var(--x-border-width) var(--x-border-style) var(--x-border)}.x-bubble-filled .x-bubble-content{background-color:var(--x-background-a200)}.x-bubble-shadow .x-bubble-content{box-shadow:var(--x-box-shadow)}.x-bubble-end{flex-direction:row-reverse}.x-bubble-header{margin-bottom:.25rem}.x-bubble-footer{margin-top:.5rem}.x-bubble-cursor.x-bubble-typing .x-bubble-content:after{content:\"\";display:inline-block;width:.0625rem;height:1.1em;margin-left:.0625rem;background-color:currentColor;vertical-align:middle;animation:x-bubble-blink 1s infinite}.x-bubble-cursor:not(.x-bubble-typing) .x-bubble-content:after{display:none}@keyframes x-bubble-blink{0%{opacity:1}50%{opacity:0}to{opacity:1}}.x-bubble.x-size-big{column-gap:var(--x-padding-big)}.x-bubble.x-size-big .x-bubble-content{padding:calc(var(--x-padding-big) - .25rem) var(--x-padding-big);line-height:calc(var(--x-height-big) - 1rem);min-height:calc(var(--x-padding-big) * 2 + var(--x-height-big) - 1.5rem)}.x-bubble.x-size-large{column-gap:var(--x-padding-large)}.x-bubble.x-size-large .x-bubble-content{padding:calc(var(--x-padding-large) - .25rem) var(--x-padding-large);line-height:calc(var(--x-height-large) - 1rem);min-height:calc(var(--x-padding-large) * 2 + var(--x-height-large) - 1.5rem)}.x-bubble.x-size-medium{column-gap:var(--x-padding-medium)}.x-bubble.x-size-medium .x-bubble-content{padding:calc(var(--x-padding-medium) - .25rem) var(--x-padding-medium);line-height:calc(var(--x-height-medium) - 1rem);min-height:calc(var(--x-padding-medium) * 2 + var(--x-height-medium) - 1.5rem)}.x-bubble.x-size-small{column-gap:var(--x-padding-small)}.x-bubble.x-size-small .x-bubble-content{padding:calc(var(--x-padding-small) - .25rem) var(--x-padding-small);line-height:calc(var(--x-height-small) - 1rem);min-height:calc(var(--x-padding-small) * 2 + var(--x-height-small) - 1.5rem)}.x-bubble.x-size-mini{column-gap:var(--x-padding-mini)}.x-bubble.x-size-mini .x-bubble-content{padding:calc(var(--x-padding-mini) - .25rem) var(--x-padding-mini);line-height:calc(var(--x-height-mini) - 1rem);min-height:calc(var(--x-padding-mini) * 2 + var(--x-height-mini) - 1.5rem)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: XOutletDirective, selector: "[xOutlet]", inputs: ["xOutletContext", "xOutlet"] }, { kind: "component", type: XAvatarComponent, selector: "x-avatar" }, { kind: "component", type: XLoadingComponent, selector: "x-loading, [x-loading]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
326
+ }
327
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: XBubbleComponent, decorators: [{
328
+ type: Component,
329
+ args: [{ selector: 'x-bubble', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgClass, XOutletDirective, XAvatarComponent, XLoadingComponent], template: "<div class=\"x-bubble\" [ngClass]=\"classMap()\">\r\n @if (!!avatar()) {\r\n <div class=\"x-bubble-avatar\">\r\n <x-avatar\r\n [icon]=\"avatar()?.icon!\"\r\n [label]=\"avatar()?.label!\"\r\n [src]=\"avatar()?.src!\"\r\n [size]=\"avatar()?.size ?? size()\"\r\n [gap]=\"avatar()?.gap ?? '0.25rem'\"\r\n [fit]=\"avatar()?.fit ?? 'cover'\"\r\n [backgroundColor]=\"avatar()?.backgroundColor ?? '#999999'\"\r\n [color]=\"avatar()?.color ?? '#FFFFFF'\"\r\n [shape]=\"avatar()?.shape ?? 'circle'\"\r\n ></x-avatar>\r\n </div>\r\n }\r\n <div class=\"x-bubble-warp\">\r\n @if (loading()) {\r\n <div class=\"x-bubble-content\" [x-loading]=\"true\" [size]=\"'small'\" inline></div>\r\n } @else {\r\n @if (header()) {\r\n <div class=\"x-bubble-header\">\r\n <ng-container *xOutlet=\"header()\">{{ header() }}</ng-container>\r\n </div>\r\n }\r\n <div class=\"x-bubble-content\" #contentRef [innerHTML]=\"renderedContent\"></div>\r\n @if (footer()) {\r\n <div class=\"x-bubble-footer\">\r\n <ng-container *xOutlet=\"footer()\">{{ footer() }}</ng-container>\r\n </div>\r\n }\r\n }\r\n </div>\r\n</div>\r\n", styles: [".x-bubble{margin:0;padding:0}.x-bubble{display:flex}.x-bubble-content{position:relative;box-sizing:border-box;min-width:0;max-width:100%;color:var(--x-text);font-size:var(--x-font-size);border-radius:var(--x-border-radius);word-break:break-word}.x-bubble-outlined .x-bubble-content{border:var(--x-border-width) var(--x-border-style) var(--x-border)}.x-bubble-filled .x-bubble-content{background-color:var(--x-background-a200)}.x-bubble-shadow .x-bubble-content{box-shadow:var(--x-box-shadow)}.x-bubble-end{flex-direction:row-reverse}.x-bubble-header{margin-bottom:.25rem}.x-bubble-footer{margin-top:.5rem}.x-bubble-cursor.x-bubble-typing .x-bubble-content:after{content:\"\";display:inline-block;width:.0625rem;height:1.1em;margin-left:.0625rem;background-color:currentColor;vertical-align:middle;animation:x-bubble-blink 1s infinite}.x-bubble-cursor:not(.x-bubble-typing) .x-bubble-content:after{display:none}@keyframes x-bubble-blink{0%{opacity:1}50%{opacity:0}to{opacity:1}}.x-bubble.x-size-big{column-gap:var(--x-padding-big)}.x-bubble.x-size-big .x-bubble-content{padding:calc(var(--x-padding-big) - .25rem) var(--x-padding-big);line-height:calc(var(--x-height-big) - 1rem);min-height:calc(var(--x-padding-big) * 2 + var(--x-height-big) - 1.5rem)}.x-bubble.x-size-large{column-gap:var(--x-padding-large)}.x-bubble.x-size-large .x-bubble-content{padding:calc(var(--x-padding-large) - .25rem) var(--x-padding-large);line-height:calc(var(--x-height-large) - 1rem);min-height:calc(var(--x-padding-large) * 2 + var(--x-height-large) - 1.5rem)}.x-bubble.x-size-medium{column-gap:var(--x-padding-medium)}.x-bubble.x-size-medium .x-bubble-content{padding:calc(var(--x-padding-medium) - .25rem) var(--x-padding-medium);line-height:calc(var(--x-height-medium) - 1rem);min-height:calc(var(--x-padding-medium) * 2 + var(--x-height-medium) - 1.5rem)}.x-bubble.x-size-small{column-gap:var(--x-padding-small)}.x-bubble.x-size-small .x-bubble-content{padding:calc(var(--x-padding-small) - .25rem) var(--x-padding-small);line-height:calc(var(--x-height-small) - 1rem);min-height:calc(var(--x-padding-small) * 2 + var(--x-height-small) - 1.5rem)}.x-bubble.x-size-mini{column-gap:var(--x-padding-mini)}.x-bubble.x-size-mini .x-bubble-content{padding:calc(var(--x-padding-mini) - .25rem) var(--x-padding-mini);line-height:calc(var(--x-height-mini) - 1rem);min-height:calc(var(--x-padding-mini) * 2 + var(--x-height-mini) - 1.5rem)}\n"] }]
330
+ }], ctorParameters: () => [] });
331
+
332
+ class XBubbleModule {
333
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: XBubbleModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
334
+ /** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.0", ngImport: i0, type: XBubbleModule, imports: [XBubbleComponent, XBubblesComponent], exports: [XBubbleComponent, XBubblesComponent] }); }
335
+ /** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: XBubbleModule, imports: [XBubbleComponent] }); }
336
+ }
337
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: XBubbleModule, decorators: [{
338
+ type: NgModule,
339
+ args: [{
340
+ exports: [XBubbleComponent, XBubblesComponent],
341
+ imports: [XBubbleComponent, XBubblesComponent]
342
+ }]
343
+ }] });
344
+
345
+ /**
346
+ * Generated bundle index. Do not edit.
347
+ */
348
+
349
+ export { XBubbleComponent, XBubbleModule, XBubblesComponent };
350
+ //# sourceMappingURL=ng-nest-ui-bubble.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ng-nest-ui-bubble.mjs","sources":["../../../../lib/ng-nest/ui/bubble/bubble.property.ts","../../../../lib/ng-nest/ui/bubble/bubbles.component.ts","../../../../lib/ng-nest/ui/bubble/bubbles.component.html","../../../../lib/ng-nest/ui/bubble/bubble.component.ts","../../../../lib/ng-nest/ui/bubble/bubble.component.html","../../../../lib/ng-nest/ui/bubble/bubble.module.ts","../../../../lib/ng-nest/ui/bubble/ng-nest-ui-bubble.ts"],"sourcesContent":["import { Component, input } from '@angular/core';\r\nimport { XBoolean, XNumber, XPropertyFunction, XSize, XTemplate, XToBoolean, XToNumber } from '@ng-nest/ui/core';\r\nimport { XAvatarOption } from '@ng-nest/ui/avatar';\r\n\r\n/**\r\n * Bubble\r\n * @selector x-bubble\r\n * @decorator component\r\n */\r\nexport const XBubblePrefix = 'x-bubble';\r\nconst X_BUBBLE_CONFIG_NAME = 'bubble';\r\n\r\n/**\r\n * Bubble Property\r\n */\r\n@Component({ selector: `${XBubblePrefix}-property`, template: '' })\r\nexport class XBubbleProperty extends XPropertyFunction(X_BUBBLE_CONFIG_NAME) {\r\n /**\r\n * @zh_CN 气泡内容\r\n * @en_US Bubble content\r\n */\r\n readonly content = input<string>();\r\n /**\r\n * @zh_CN 头像\r\n * @en_US Avatar\r\n */\r\n readonly avatar = input<XAvatarOption>();\r\n /**\r\n * @zh_CN 尺寸\r\n * @en_US Size\r\n */\r\n readonly size = input<XSize>(this.config?.size ?? 'medium');\r\n /**\r\n * @zh_CN 形态变体\r\n * @en_US Bubble variant\r\n */\r\n readonly variant = input<XBubbleVariant>(this.config?.variant ?? 'outlined');\r\n /**\r\n * @zh_CN 位置\r\n * @en_US Bubble placement\r\n */\r\n readonly placement = input<XBubblePlacement>('start');\r\n /**\r\n * @zh_CN 气泡头部内容\r\n * @en_US Bubble header content\r\n */\r\n readonly header = input<XTemplate>();\r\n /**\r\n * @zh_CN 气泡底部内容\r\n * @en_US Bubble header content\r\n */\r\n readonly footer = input<XTemplate>();\r\n /**\r\n * @zh_CN 加载中\r\n * @en_US Loading\r\n */\r\n readonly loading = input<boolean, XBoolean>(false, { transform: XToBoolean });\r\n /**\r\n * @zh_CN 内容输出打字机效果\r\n * @en_US Typing effect\r\n */\r\n readonly typing = input<boolean, XBoolean>(false, { transform: XToBoolean });\r\n /**\r\n * @zh_CN 打字机输出速度\r\n * @en_US Typing speed\r\n */\r\n readonly speed = input<number, XNumber>(30, { transform: XToNumber });\r\n /**\r\n * @zh_CN 内容渲染器,可自定义内容的渲染方式,如 HTML、Markdown\r\n * @en_US Content renderer, can customize content rendering, such as HTML, Markdown\r\n */\r\n readonly renderer = input<XBubbleContentRenderer>();\r\n /**\r\n * @zh_CN 是否显示打字机光标\r\n * @en_US Whether to show the typing cursor\r\n */\r\n readonly showCursor = input<boolean, XBoolean>(false, { transform: XToBoolean });\r\n}\r\n\r\n/**\r\n * Bubbles\r\n * @selector x-bubbles\r\n * @decorator component\r\n */\r\nexport const XBubblesPrefix = 'x-bubbles';\r\nconst X_BUBBLES_CONFIG_NAME = 'bubbles';\r\n\r\n/**\r\n * Bubbles Property\r\n */\r\n@Component({ selector: `${XBubblesPrefix}-property`, template: '' })\r\nexport class XBubblesProperty extends XPropertyFunction(X_BUBBLES_CONFIG_NAME) {\r\n /**\r\n * @zh_CN 尺寸\r\n * @en_US Size\r\n */\r\n readonly size = input<XSize>();\r\n /**\r\n * @zh_CN 形态变体\r\n * @en_US Bubble variant\r\n */\r\n readonly variant = input<XBubbleVariant>();\r\n}\r\n\r\n/**\r\n * @zh_CN 形态变体\r\n * @en_US Bubble variant\r\n */\r\nexport type XBubbleVariant = 'outlined' | 'filled' | 'shadow' | 'borderless';\r\n\r\n/**\r\n * @zh_CN 位置\r\n * @en_US Bubble placement\r\n */\r\nexport type XBubblePlacement = 'start' | 'end';\r\n\r\n/**\r\n * @zh_CN 内容渲染函数\r\n * @en_US Bubble content renderer\r\n */\r\nexport type XBubbleContentRenderer = (content: string) => string | undefined;\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n contentChildren,\r\n ElementRef,\r\n inject,\r\n Renderer2,\r\n ViewEncapsulation\r\n} from '@angular/core';\r\nimport { XBubblesProperty } from './bubble.property';\r\nimport { XBubbleComponent } from './bubble.component';\r\n\r\n@Component({\r\n selector: 'x-bubbles',\r\n templateUrl: './bubbles.component.html',\r\n styleUrls: ['./bubbles.component.scss'],\r\n encapsulation: ViewEncapsulation.None,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n imports: []\r\n})\r\nexport class XBubblesComponent extends XBubblesProperty {\r\n elementRef = inject(ElementRef);\r\n renderer = inject(Renderer2);\r\n\r\n private parentScrollElement: HTMLElement | null = null;\r\n private isFollowing = true;\r\n private removeScrollListener: (() => void) | null = null;\r\n private contentMutationObserver: MutationObserver | null = null;\r\n private typingObserver: MutationObserver | null = null;\r\n\r\n bubbles = contentChildren(XBubbleComponent);\r\n\r\n ngAfterViewInit(): void {\r\n this.parentScrollElement = this.getParentScrollElement(this.elementRef.nativeElement);\r\n\r\n if (this.parentScrollElement) {\r\n this.removeScrollListener = this.renderer.listen(this.parentScrollElement, 'scroll', () => {\r\n const atBottom =\r\n this.parentScrollElement!.scrollHeight - this.parentScrollElement!.scrollTop ===\r\n this.parentScrollElement!.clientHeight;\r\n if (!atBottom) {\r\n this.isFollowing = false;\r\n } else {\r\n this.isFollowing = true;\r\n }\r\n });\r\n this.observeContentChanges();\r\n }\r\n }\r\n\r\n ngDoCheck(): void {\r\n const bubbles = this.bubbles();\r\n if (bubbles.length <= 0) return;\r\n const lastBubble = bubbles[bubbles.length - 1];\r\n if (lastBubble && lastBubble.typing() && lastBubble.pendingContent().length > 0) {\r\n if (!this.typingObserver) {\r\n this.startTypingObserver(lastBubble);\r\n }\r\n } else {\r\n if (this.typingObserver) {\r\n this.stopTypingObserver();\r\n }\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n if (this.removeScrollListener) {\r\n this.removeScrollListener();\r\n }\r\n if (this.contentMutationObserver) {\r\n this.contentMutationObserver.disconnect();\r\n }\r\n this.stopTypingObserver();\r\n }\r\n\r\n private getParentScrollElement(element: HTMLElement): HTMLElement | null {\r\n let parent = this.renderer.parentNode(element) as HTMLElement;\r\n while (parent && parent.nodeType === 1) {\r\n const overflowY = getComputedStyle(parent).overflowY;\r\n if (overflowY === 'auto' || overflowY === 'scroll') {\r\n return parent;\r\n }\r\n parent = this.renderer.parentNode(parent);\r\n }\r\n return null;\r\n }\r\n private observeContentChanges(): void {\r\n this.contentMutationObserver = new MutationObserver(() => {\r\n this.isFollowing = true;\r\n this.scrollToBottom();\r\n });\r\n\r\n this.contentMutationObserver.observe(this.elementRef.nativeElement, { childList: true });\r\n }\r\n\r\n private startTypingObserver(bubble: XBubbleComponent): void {\r\n const bubbleContent = bubble.contentRef()?.nativeElement;\r\n if (bubbleContent) {\r\n this.typingObserver = new MutationObserver(() => {\r\n if (this.isFollowing) {\r\n this.scrollToBottom();\r\n }\r\n });\r\n\r\n this.typingObserver.observe(bubbleContent, {\r\n childList: true,\r\n subtree: true,\r\n characterData: true\r\n });\r\n }\r\n }\r\n\r\n private stopTypingObserver(): void {\r\n if (this.typingObserver) {\r\n this.typingObserver.disconnect();\r\n this.typingObserver = null;\r\n }\r\n }\r\n\r\n scrollToBottom(): void {\r\n if (this.parentScrollElement) {\r\n this.parentScrollElement.scrollTop = this.parentScrollElement.scrollHeight;\r\n }\r\n }\r\n\r\n scrollToTop(): void {\r\n if (this.parentScrollElement) {\r\n this.parentScrollElement.scrollTop = 0;\r\n }\r\n }\r\n}\r\n","<ng-content></ng-content>\r\n","import {\r\n Component,\r\n ViewEncapsulation,\r\n ChangeDetectionStrategy,\r\n computed,\r\n viewChild,\r\n ElementRef,\r\n signal,\r\n effect,\r\n SimpleChanges,\r\n inject,\r\n Renderer2\r\n} from '@angular/core';\r\nimport { XBubblePrefix, XBubbleProperty } from './bubble.property';\r\nimport { XOutletDirective } from '@ng-nest/ui/outlet';\r\nimport { XIsEmpty } from '@ng-nest/ui/core';\r\nimport { NgClass } from '@angular/common';\r\nimport { XAvatarComponent } from '@ng-nest/ui/avatar';\r\nimport { XLoadingComponent } from '@ng-nest/ui/loading';\r\nimport { DomSanitizer } from '@angular/platform-browser';\r\nimport { XBubblesComponent } from './bubbles.component';\r\nimport { toObservable } from '@angular/core/rxjs-interop';\r\n\r\n@Component({\r\n selector: 'x-bubble',\r\n templateUrl: './bubble.component.html',\r\n styleUrls: ['./bubble.component.scss'],\r\n encapsulation: ViewEncapsulation.None,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n imports: [NgClass, XOutletDirective, XAvatarComponent, XLoadingComponent]\r\n})\r\nexport class XBubbleComponent extends XBubbleProperty {\r\n sanitizer = inject(DomSanitizer);\r\n renderer2 = inject(Renderer2);\r\n private bubbles = inject(XBubblesComponent, { optional: true, host: true });\r\n\r\n contentRef = viewChild<ElementRef<HTMLElement>>('contentRef');\r\n\r\n classMap = computed(() => ({\r\n [`${XBubblePrefix}-${this.variantSignal()}`]: !XIsEmpty(this.variantSignal()),\r\n [`${XBubblePrefix}-${this.placement()}`]: !XIsEmpty(this.placement()),\r\n [`${XBubblePrefix}-cursor`]: this.showCursor() && this.typing(),\r\n [`${XBubblePrefix}-typing`]: this.typing() && this.pendingContent().length > 0,\r\n [`x-size-${this.sizeSignal()}`]: !XIsEmpty(this.sizeSignal())\r\n }));\r\n\r\n typedContent = signal('');\r\n pendingContent = signal('');\r\n pendingContentObserver = toObservable(this.pendingContent);\r\n private typingInterval: any = null;\r\n\r\n sizeSignal = computed(() => {\r\n return this.bubbles?.size() || this.size();\r\n });\r\n\r\n variantSignal = computed(() => {\r\n return this.bubbles?.variant() || this.variant();\r\n });\r\n\r\n constructor() {\r\n super();\r\n effect(() => {\r\n if (!this.typing()) {\r\n this.stopTyping();\r\n this.typedContent.set(this.typedContent() + this.pendingContent());\r\n this.pendingContent.set('');\r\n }\r\n });\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges): void {\r\n if (changes['content']) {\r\n const newFullContent = changes['content'].currentValue || '';\r\n const currentTypedContent = this.typedContent();\r\n\r\n if (!this.typing()) {\r\n this.typedContent.set(newFullContent);\r\n return;\r\n }\r\n\r\n if (newFullContent.startsWith(currentTypedContent)) {\r\n this.pendingContent.set(newFullContent.substring(currentTypedContent.length));\r\n this.startTyping();\r\n } else {\r\n this.stopTyping();\r\n this.typedContent.set('');\r\n this.pendingContent.set(newFullContent);\r\n this.startTyping();\r\n }\r\n }\r\n }\r\n\r\n get renderedContent() {\r\n const finalContent = this.typing() ? this.typedContent() : this.content() || '';\r\n let renderedString: string;\r\n\r\n if (this.renderer()) {\r\n renderedString = this.renderer()!(finalContent) || '';\r\n } else {\r\n renderedString = finalContent;\r\n }\r\n\r\n return this.sanitizer.bypassSecurityTrustHtml(renderedString);\r\n }\r\n\r\n private startTyping(): void {\r\n if (this.typingInterval) {\r\n return;\r\n }\r\n\r\n if (this.pendingContent().length === 0) {\r\n return;\r\n }\r\n\r\n this.typingInterval = setInterval(() => {\r\n if (this.pendingContent().length > 0) {\r\n const nextChar = this.pendingContent().charAt(0);\r\n this.typedContent.update((current) => current + nextChar);\r\n this.pendingContent.update((current) => current.substring(1));\r\n } else {\r\n this.stopTyping();\r\n }\r\n }, this.speed());\r\n }\r\n\r\n private stopTyping(): void {\r\n if (this.typingInterval) {\r\n clearInterval(this.typingInterval);\r\n this.typingInterval = null;\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.stopTyping();\r\n }\r\n}\r\n","<div class=\"x-bubble\" [ngClass]=\"classMap()\">\r\n @if (!!avatar()) {\r\n <div class=\"x-bubble-avatar\">\r\n <x-avatar\r\n [icon]=\"avatar()?.icon!\"\r\n [label]=\"avatar()?.label!\"\r\n [src]=\"avatar()?.src!\"\r\n [size]=\"avatar()?.size ?? size()\"\r\n [gap]=\"avatar()?.gap ?? '0.25rem'\"\r\n [fit]=\"avatar()?.fit ?? 'cover'\"\r\n [backgroundColor]=\"avatar()?.backgroundColor ?? '#999999'\"\r\n [color]=\"avatar()?.color ?? '#FFFFFF'\"\r\n [shape]=\"avatar()?.shape ?? 'circle'\"\r\n ></x-avatar>\r\n </div>\r\n }\r\n <div class=\"x-bubble-warp\">\r\n @if (loading()) {\r\n <div class=\"x-bubble-content\" [x-loading]=\"true\" [size]=\"'small'\" inline></div>\r\n } @else {\r\n @if (header()) {\r\n <div class=\"x-bubble-header\">\r\n <ng-container *xOutlet=\"header()\">{{ header() }}</ng-container>\r\n </div>\r\n }\r\n <div class=\"x-bubble-content\" #contentRef [innerHTML]=\"renderedContent\"></div>\r\n @if (footer()) {\r\n <div class=\"x-bubble-footer\">\r\n <ng-container *xOutlet=\"footer()\">{{ footer() }}</ng-container>\r\n </div>\r\n }\r\n }\r\n </div>\r\n</div>\r\n","import { NgModule } from '@angular/core';\r\nimport { XBubbleComponent } from './bubble.component';\r\nimport { XBubblesComponent } from './bubbles.component';\r\n\r\n@NgModule({\r\n exports: [XBubbleComponent, XBubblesComponent],\r\n imports: [XBubbleComponent, XBubblesComponent]\r\n})\r\nexport class XBubbleModule {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}