@copilotkitnext/angular 0.0.1 → 0.0.4

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 (171) hide show
  1. package/README.md +248 -0
  2. package/dist/README.md +248 -0
  3. package/dist/components/chat/copilot-chat-assistant-message.component.d.ts +10 -10
  4. package/dist/components/chat/copilot-chat-message-view.component.d.ts +42 -42
  5. package/dist/components/chat/copilot-chat-view.component.d.ts +14 -14
  6. package/dist/esm2022/components/chat/copilot-chat-assistant-message-buttons.component.mjs +384 -0
  7. package/dist/esm2022/components/chat/copilot-chat-assistant-message-renderer.component.mjs +286 -0
  8. package/dist/esm2022/components/chat/copilot-chat-assistant-message-toolbar.component.mjs +27 -0
  9. package/dist/esm2022/components/chat/copilot-chat-assistant-message.component.mjs +433 -0
  10. package/dist/esm2022/components/chat/copilot-chat-assistant-message.types.mjs +2 -0
  11. package/dist/esm2022/components/chat/copilot-chat-audio-recorder.component.mjs +202 -0
  12. package/dist/esm2022/components/chat/copilot-chat-buttons.component.mjs +321 -0
  13. package/dist/esm2022/components/chat/copilot-chat-input-defaults.mjs +38 -0
  14. package/dist/esm2022/components/chat/copilot-chat-input.component.mjs +666 -0
  15. package/dist/esm2022/components/chat/copilot-chat-input.types.mjs +10 -0
  16. package/dist/esm2022/components/chat/copilot-chat-message-view-cursor.component.mjs +45 -0
  17. package/dist/esm2022/components/chat/copilot-chat-message-view.component.mjs +296 -0
  18. package/dist/esm2022/components/chat/copilot-chat-message-view.types.mjs +2 -0
  19. package/dist/esm2022/components/chat/copilot-chat-textarea.component.mjs +188 -0
  20. package/dist/esm2022/components/chat/copilot-chat-tool-calls-view.component.mjs +216 -0
  21. package/dist/esm2022/components/chat/copilot-chat-toolbar.component.mjs +25 -0
  22. package/dist/esm2022/components/chat/copilot-chat-tools-menu.component.mjs +199 -0
  23. package/dist/esm2022/components/chat/copilot-chat-user-message-branch-navigation.component.mjs +137 -0
  24. package/dist/esm2022/components/chat/copilot-chat-user-message-buttons.component.mjs +207 -0
  25. package/dist/esm2022/components/chat/copilot-chat-user-message-renderer.component.mjs +35 -0
  26. package/dist/esm2022/components/chat/copilot-chat-user-message-toolbar.component.mjs +34 -0
  27. package/dist/esm2022/components/chat/copilot-chat-user-message.component.mjs +341 -0
  28. package/dist/esm2022/components/chat/copilot-chat-user-message.types.mjs +2 -0
  29. package/dist/esm2022/components/chat/copilot-chat-view-disclaimer.component.mjs +52 -0
  30. package/dist/esm2022/components/chat/copilot-chat-view-feather.component.mjs +55 -0
  31. package/dist/esm2022/components/chat/copilot-chat-view-handlers.service.mjs +19 -0
  32. package/dist/esm2022/components/chat/copilot-chat-view-input-container.component.mjs +110 -0
  33. package/dist/esm2022/components/chat/copilot-chat-view-scroll-to-bottom-button.component.mjs +93 -0
  34. package/dist/esm2022/components/chat/copilot-chat-view-scroll-view.component.mjs +443 -0
  35. package/dist/esm2022/components/chat/copilot-chat-view.component.mjs +479 -0
  36. package/dist/esm2022/components/chat/copilot-chat-view.types.mjs +2 -0
  37. package/dist/esm2022/components/chat/copilot-chat.component.mjs +214 -0
  38. package/dist/esm2022/components/copilotkit-tool-render.component.mjs +153 -0
  39. package/dist/esm2022/copilotkitnext-angular.mjs +5 -0
  40. package/dist/esm2022/core/chat-configuration/chat-configuration.providers.mjs +65 -0
  41. package/dist/esm2022/core/chat-configuration/chat-configuration.service.mjs +145 -0
  42. package/dist/esm2022/core/chat-configuration/chat-configuration.types.mjs +26 -0
  43. package/dist/esm2022/core/copilotkit.providers.mjs +34 -0
  44. package/dist/esm2022/core/copilotkit.service.mjs +430 -0
  45. package/dist/esm2022/core/copilotkit.types.mjs +12 -0
  46. package/dist/esm2022/directives/copilotkit-agent-context.directive.mjs +130 -0
  47. package/dist/esm2022/directives/copilotkit-agent.directive.mjs +217 -0
  48. package/dist/esm2022/directives/copilotkit-chat-config.directive.mjs +218 -0
  49. package/dist/esm2022/directives/copilotkit-config.directive.mjs +94 -0
  50. package/dist/esm2022/directives/copilotkit-frontend-tool.directive.mjs +130 -0
  51. package/dist/esm2022/directives/copilotkit-human-in-the-loop.directive.mjs +266 -0
  52. package/dist/esm2022/directives/stick-to-bottom.directive.mjs +181 -0
  53. package/dist/esm2022/index.mjs +70 -0
  54. package/dist/esm2022/lib/directives/tooltip.directive.mjs +211 -0
  55. package/dist/esm2022/lib/slots/copilot-slot.component.mjs +144 -0
  56. package/dist/esm2022/lib/slots/slot.types.mjs +6 -0
  57. package/dist/esm2022/lib/slots/slot.utils.mjs +222 -0
  58. package/dist/esm2022/lib/utils.mjs +10 -0
  59. package/dist/esm2022/services/resize-observer.service.mjs +152 -0
  60. package/dist/esm2022/services/scroll-position.service.mjs +124 -0
  61. package/dist/esm2022/types/frontend-tool.mjs +2 -0
  62. package/dist/esm2022/types/human-in-the-loop.mjs +2 -0
  63. package/dist/esm2022/utils/agent-context.utils.mjs +114 -0
  64. package/dist/esm2022/utils/agent.utils.mjs +204 -0
  65. package/dist/esm2022/utils/chat-config.utils.mjs +186 -0
  66. package/dist/esm2022/utils/copilotkit.utils.mjs +20 -0
  67. package/dist/esm2022/utils/frontend-tool.utils.mjs +228 -0
  68. package/dist/esm2022/utils/human-in-the-loop.utils.mjs +296 -0
  69. package/dist/fesm2022/copilotkitnext-angular.mjs +163 -164
  70. package/dist/fesm2022/copilotkitnext-angular.mjs.map +1 -1
  71. package/dist/styles.css +0 -27
  72. package/package.json +23 -20
  73. package/vitest.config.mts +32 -21
  74. package/.turbo/turbo-build.log +0 -39
  75. package/.turbo/turbo-check-types.log +0 -0
  76. package/.turbo/turbo-test.log +0 -71
  77. package/README-agent-context.md +0 -310
  78. package/ng-package.json +0 -19
  79. package/slots.md +0 -331
  80. package/src/components/chat/__tests__/copilot-chat-assistant-message.component.spec.ts +0 -282
  81. package/src/components/chat/__tests__/copilot-chat-input.component.spec.ts +0 -419
  82. package/src/components/chat/__tests__/copilot-chat-message-view.component.spec.ts +0 -372
  83. package/src/components/chat/__tests__/copilot-chat-user-message.component.spec.ts +0 -249
  84. package/src/components/chat/copilot-chat-assistant-message-buttons.component.ts +0 -292
  85. package/src/components/chat/copilot-chat-assistant-message-renderer.component.ts +0 -472
  86. package/src/components/chat/copilot-chat-assistant-message-toolbar.component.ts +0 -29
  87. package/src/components/chat/copilot-chat-assistant-message.component.ts +0 -463
  88. package/src/components/chat/copilot-chat-assistant-message.types.ts +0 -50
  89. package/src/components/chat/copilot-chat-audio-recorder.component.ts +0 -241
  90. package/src/components/chat/copilot-chat-buttons.component.ts +0 -308
  91. package/src/components/chat/copilot-chat-buttons.component.ts.bak +0 -471
  92. package/src/components/chat/copilot-chat-input-defaults.ts +0 -47
  93. package/src/components/chat/copilot-chat-input.component.ts +0 -512
  94. package/src/components/chat/copilot-chat-input.types.ts +0 -148
  95. package/src/components/chat/copilot-chat-message-view-cursor.component.ts +0 -51
  96. package/src/components/chat/copilot-chat-message-view.component.ts +0 -233
  97. package/src/components/chat/copilot-chat-message-view.types.ts +0 -39
  98. package/src/components/chat/copilot-chat-textarea.component.ts +0 -220
  99. package/src/components/chat/copilot-chat-tool-calls-view.component.ts +0 -261
  100. package/src/components/chat/copilot-chat-toolbar.component.ts +0 -35
  101. package/src/components/chat/copilot-chat-tools-menu.component.ts +0 -185
  102. package/src/components/chat/copilot-chat-user-message-branch-navigation.component.ts +0 -121
  103. package/src/components/chat/copilot-chat-user-message-buttons.component.ts +0 -170
  104. package/src/components/chat/copilot-chat-user-message-renderer.component.ts +0 -37
  105. package/src/components/chat/copilot-chat-user-message-toolbar.component.ts +0 -37
  106. package/src/components/chat/copilot-chat-user-message.component.ts +0 -247
  107. package/src/components/chat/copilot-chat-user-message.types.ts +0 -42
  108. package/src/components/chat/copilot-chat-view-disclaimer.component.ts +0 -51
  109. package/src/components/chat/copilot-chat-view-feather.component.ts +0 -47
  110. package/src/components/chat/copilot-chat-view-handlers.service.ts +0 -14
  111. package/src/components/chat/copilot-chat-view-input-container.component.ts +0 -87
  112. package/src/components/chat/copilot-chat-view-scroll-to-bottom-button.component.ts +0 -79
  113. package/src/components/chat/copilot-chat-view-scroll-view.component.ts +0 -322
  114. package/src/components/chat/copilot-chat-view.component.ts +0 -420
  115. package/src/components/chat/copilot-chat-view.types.ts +0 -52
  116. package/src/components/chat/copilot-chat.component.ts +0 -232
  117. package/src/components/copilotkit-tool-render.component.ts +0 -169
  118. package/src/core/__tests__/copilotkit.service.spec.ts +0 -1051
  119. package/src/core/__tests__/copilotkit.service.wildcard.spec.ts +0 -316
  120. package/src/core/chat-configuration/__tests__/chat-configuration.service.spec.ts +0 -287
  121. package/src/core/chat-configuration/chat-configuration.providers.ts +0 -71
  122. package/src/core/chat-configuration/chat-configuration.service.ts +0 -162
  123. package/src/core/chat-configuration/chat-configuration.types.ts +0 -57
  124. package/src/core/copilotkit.providers.ts +0 -59
  125. package/src/core/copilotkit.service.ts +0 -542
  126. package/src/core/copilotkit.types.ts +0 -132
  127. package/src/directives/__tests__/copilotkit-agent-context.directive.spec.ts +0 -384
  128. package/src/directives/__tests__/copilotkit-agent.directive.spec.ts +0 -253
  129. package/src/directives/__tests__/copilotkit-chat-config.directive.spec.ts +0 -385
  130. package/src/directives/__tests__/copilotkit-config.directive.spec.ts +0 -69
  131. package/src/directives/__tests__/copilotkit-frontend-tool-simple.directive.spec.ts +0 -60
  132. package/src/directives/__tests__/copilotkit-frontend-tool.directive.spec.ts +0 -108
  133. package/src/directives/__tests__/copilotkit-human-in-the-loop.directive.spec.ts +0 -452
  134. package/src/directives/copilotkit-agent-context.directive.ts +0 -138
  135. package/src/directives/copilotkit-agent.directive.ts +0 -225
  136. package/src/directives/copilotkit-chat-config.directive.ts +0 -241
  137. package/src/directives/copilotkit-config.directive.ts +0 -81
  138. package/src/directives/copilotkit-frontend-tool.directive.ts +0 -145
  139. package/src/directives/copilotkit-human-in-the-loop.directive.ts +0 -281
  140. package/src/directives/stick-to-bottom.directive.ts +0 -204
  141. package/src/index.ts +0 -105
  142. package/src/lib/directives/tooltip.directive.ts +0 -292
  143. package/src/lib/slots/__tests__/slot.utils.spec.ts +0 -377
  144. package/src/lib/slots/copilot-slot.component.ts +0 -135
  145. package/src/lib/slots/index.ts +0 -3
  146. package/src/lib/slots/slot.types.ts +0 -64
  147. package/src/lib/slots/slot.utils.ts +0 -289
  148. package/src/lib/utils.ts +0 -10
  149. package/src/public-api.ts +0 -1
  150. package/src/services/resize-observer.service.ts +0 -181
  151. package/src/services/scroll-position.service.ts +0 -169
  152. package/src/styles/globals.css +0 -266
  153. package/src/styles/index.css +0 -3
  154. package/src/test-setup.ts +0 -15
  155. package/src/testing/index.ts +0 -3
  156. package/src/testing/testing.utils.ts +0 -248
  157. package/src/types/frontend-tool.ts +0 -44
  158. package/src/types/human-in-the-loop.ts +0 -52
  159. package/src/utils/__tests__/agent.utils.spec.ts +0 -234
  160. package/src/utils/__tests__/chat-config.utils.spec.ts +0 -306
  161. package/src/utils/__tests__/frontend-tool-inject.spec.ts +0 -350
  162. package/src/utils/__tests__/frontend-tool-integration.spec.ts +0 -199
  163. package/src/utils/__tests__/frontend-tool.utils.spec.ts +0 -272
  164. package/src/utils/__tests__/human-in-the-loop.utils.spec.ts +0 -365
  165. package/src/utils/agent-context.utils.ts +0 -133
  166. package/src/utils/agent.utils.ts +0 -239
  167. package/src/utils/chat-config.utils.ts +0 -221
  168. package/src/utils/copilotkit.utils.ts +0 -20
  169. package/src/utils/frontend-tool.utils.ts +0 -266
  170. package/src/utils/human-in-the-loop.utils.ts +0 -359
  171. package/tsconfig.spec.json +0 -12
@@ -1,419 +0,0 @@
1
- import { TestBed, ComponentFixture } from '@angular/core/testing';
2
- import { Component, DebugElement } from '@angular/core';
3
- import { By } from '@angular/platform-browser';
4
- import { describe, it, expect, beforeEach, vi } from 'vitest';
5
- import { CopilotChatInputComponent } from '../copilot-chat-input.component';
6
- import { CopilotChatTextareaComponent } from '../copilot-chat-textarea.component';
7
- import { CopilotChatConfigurationService } from '../../../core/chat-configuration/chat-configuration.service';
8
- import { provideCopilotChatConfiguration } from '../../../core/chat-configuration/chat-configuration.providers';
9
-
10
- describe('CopilotChatInputComponent', () => {
11
- let component: CopilotChatInputComponent;
12
- let fixture: ComponentFixture<CopilotChatInputComponent>;
13
-
14
- beforeEach(() => {
15
- TestBed.configureTestingModule({
16
- imports: [CopilotChatInputComponent],
17
- providers: [
18
- provideCopilotChatConfiguration({
19
- labels: {
20
- chatInputPlaceholder: 'Test placeholder'
21
- }
22
- })
23
- ]
24
- });
25
-
26
- fixture = TestBed.createComponent(CopilotChatInputComponent);
27
- component = fixture.componentInstance;
28
- fixture.detectChanges();
29
- });
30
-
31
- describe('Basic Rendering', () => {
32
- it('should create', () => {
33
- expect(component).toBeTruthy();
34
- });
35
-
36
- it('should render textarea by default', () => {
37
- const textarea = fixture.nativeElement.querySelector('textarea[copilotChatTextarea]');
38
- expect(textarea).toBeTruthy();
39
- });
40
-
41
- it('should render toolbar', () => {
42
- const toolbar = fixture.nativeElement.querySelector('div[copilotChatToolbar]');
43
- expect(toolbar).toBeTruthy();
44
- });
45
-
46
- it('should apply custom class', () => {
47
- component.inputClass = 'custom-class';
48
- fixture.detectChanges();
49
-
50
- const container = fixture.nativeElement.querySelector('.chat-input-container');
51
- expect(container).toBeFalsy();
52
-
53
- const customContainer = fixture.nativeElement.querySelector('.custom-class');
54
- expect(customContainer).toBeTruthy();
55
- });
56
- });
57
-
58
- describe('Mode Switching', () => {
59
- it('should switch to audio recorder in transcribe mode', () => {
60
- component.mode = 'transcribe';
61
- fixture.detectChanges();
62
-
63
- const audioRecorder = fixture.nativeElement.querySelector('copilot-chat-audio-recorder');
64
- expect(audioRecorder).toBeTruthy();
65
-
66
- const textarea = fixture.nativeElement.querySelector('textarea[copilotChatTextarea]');
67
- expect(textarea).toBeFalsy();
68
- });
69
-
70
- it('should switch back to textarea from transcribe mode', () => {
71
- component.mode = 'transcribe';
72
- fixture.detectChanges();
73
-
74
- component.mode = 'input';
75
- fixture.detectChanges();
76
-
77
- const textarea = fixture.nativeElement.querySelector('textarea[copilotChatTextarea]');
78
- expect(textarea).toBeTruthy();
79
-
80
- const audioRecorder = fixture.nativeElement.querySelector('copilot-chat-audio-recorder');
81
- expect(audioRecorder).toBeFalsy();
82
- });
83
- });
84
-
85
- describe('Value Management', () => {
86
- it('should set initial value', () => {
87
- component.value = 'Initial value';
88
- fixture.detectChanges();
89
-
90
- expect(component.computedValue()).toBe('Initial value');
91
- });
92
-
93
- it('should emit valueChange when value changes', () => {
94
- const spy = vi.fn();
95
- component.valueChange.subscribe(spy);
96
-
97
- component.handleValueChange('New value');
98
-
99
- expect(spy).toHaveBeenCalledWith('New value');
100
- expect(component.computedValue()).toBe('New value');
101
- });
102
-
103
- it('should sync with chat configuration service', () => {
104
- const service = TestBed.inject(CopilotChatConfigurationService);
105
-
106
- component.handleValueChange('Config value');
107
-
108
- expect(service.inputValue()).toBe('Config value');
109
- });
110
- });
111
-
112
- describe('Submit Functionality', () => {
113
- it('should emit submitMessage on send', () => {
114
- const spy = vi.fn();
115
- component.submitMessage.subscribe(spy);
116
-
117
- component.valueSignal.set('Test message');
118
- component.send();
119
-
120
- expect(spy).toHaveBeenCalledWith('Test message');
121
- });
122
-
123
- it('should not submit empty message', () => {
124
- const spy = vi.fn();
125
- component.submitMessage.subscribe(spy);
126
-
127
- component.valueSignal.set(' ');
128
- component.send();
129
-
130
- expect(spy).not.toHaveBeenCalled();
131
- });
132
-
133
- it('should clear input after send', () => {
134
- component.valueSignal.set('Test message');
135
- component.send();
136
-
137
- expect(component.computedValue()).toBe('');
138
- });
139
-
140
- it('should handle Enter key to send', () => {
141
- const spy = vi.fn();
142
- component.submitMessage.subscribe(spy);
143
-
144
- component.valueSignal.set('Test message');
145
-
146
- const event = new KeyboardEvent('keydown', {
147
- key: 'Enter',
148
- shiftKey: false
149
- });
150
-
151
- component.handleKeyDown(event);
152
-
153
- expect(spy).toHaveBeenCalledWith('Test message');
154
- });
155
-
156
- it('should not send on Shift+Enter', () => {
157
- const spy = vi.fn();
158
- component.submitMessage.subscribe(spy);
159
-
160
- const event = new KeyboardEvent('keydown', {
161
- key: 'Enter',
162
- shiftKey: true
163
- });
164
-
165
- component.handleKeyDown(event);
166
-
167
- expect(spy).not.toHaveBeenCalled();
168
- });
169
- });
170
-
171
- describe('Transcribe Events', () => {
172
- it('should emit startTranscribe and switch mode', () => {
173
- const spy = vi.fn();
174
- component.startTranscribe.subscribe(spy);
175
-
176
- component.handleStartTranscribe();
177
-
178
- expect(spy).toHaveBeenCalled();
179
- expect(component.computedMode()).toBe('transcribe');
180
- });
181
-
182
- it('should emit cancelTranscribe and switch mode', () => {
183
- const spy = vi.fn();
184
- component.cancelTranscribe.subscribe(spy);
185
-
186
- component.modeSignal.set('transcribe');
187
- component.handleCancelTranscribe();
188
-
189
- expect(spy).toHaveBeenCalled();
190
- expect(component.computedMode()).toBe('input');
191
- });
192
-
193
- it('should emit finishTranscribe and switch mode', () => {
194
- const spy = vi.fn();
195
- component.finishTranscribe.subscribe(spy);
196
-
197
- component.modeSignal.set('transcribe');
198
- component.handleFinishTranscribe();
199
-
200
- expect(spy).toHaveBeenCalled();
201
- expect(component.computedMode()).toBe('input');
202
- });
203
- });
204
-
205
- describe('Tools Menu', () => {
206
- it('should pass tools menu to toolbar', () => {
207
- const toolsMenu = [
208
- { label: 'Tool 1', action: () => {} },
209
- '-' as const,
210
- { label: 'Tool 2', action: () => {} }
211
- ];
212
-
213
- component.toolsMenu = toolsMenu;
214
- fixture.detectChanges();
215
-
216
- expect(component.computedToolsMenu()).toEqual(toolsMenu);
217
- });
218
- });
219
-
220
- describe('File Operations', () => {
221
- it('should emit addFile event', () => {
222
- const spy = vi.fn();
223
- component.addFile.subscribe(spy);
224
-
225
- component.handleAddFile();
226
-
227
- expect(spy).toHaveBeenCalled();
228
- });
229
- });
230
-
231
- describe('Slot Overrides', () => {
232
- it('should support custom textarea component', () => {
233
- @Component({
234
- selector: 'custom-textarea',
235
- template: '<textarea class="custom"></textarea>',
236
- standalone: true
237
- })
238
- class CustomTextarea {}
239
-
240
- component.textAreaSlot = CustomTextarea;
241
- fixture.detectChanges();
242
-
243
- // The slot should accept the custom component
244
- expect(component.textAreaSlot).toBe(CustomTextarea);
245
- });
246
-
247
- it('should support CSS class override for textarea', () => {
248
- component.textAreaSlot = 'custom-textarea-class';
249
- fixture.detectChanges();
250
-
251
- expect(component.textAreaSlot).toBe('custom-textarea-class');
252
- });
253
- });
254
- });
255
-
256
- // Test host component for CopilotChatTextareaComponent directive
257
- @Component({
258
- template: `
259
- <textarea copilotChatTextarea
260
- [inputValue]="value"
261
- [inputPlaceholder]="placeholder"
262
- [inputMaxRows]="maxRows"
263
- [inputAutoFocus]="autoFocus"
264
- [inputDisabled]="disabled"
265
- (valueChange)="onValueChange($event)"
266
- (keyDown)="onKeyDown($event)">
267
- </textarea>
268
- `,
269
- standalone: true,
270
- imports: [CopilotChatTextareaComponent]
271
- })
272
- class TestHostComponent {
273
- value = '';
274
- placeholder = '';
275
- maxRows = 5;
276
- autoFocus = false;
277
- disabled = false;
278
- onValueChange = vi.fn();
279
- onKeyDown = vi.fn();
280
- }
281
-
282
- describe('CopilotChatTextareaComponent', () => {
283
- let hostComponent: TestHostComponent;
284
- let fixture: ComponentFixture<TestHostComponent>;
285
- let component: CopilotChatTextareaComponent;
286
- let textareaElement: HTMLTextAreaElement;
287
-
288
- beforeEach(() => {
289
- TestBed.configureTestingModule({
290
- imports: [TestHostComponent, CopilotChatTextareaComponent],
291
- providers: [
292
- provideCopilotChatConfiguration({
293
- labels: {
294
- chatInputPlaceholder: 'Test placeholder'
295
- }
296
- })
297
- ]
298
- });
299
-
300
- fixture = TestBed.createComponent(TestHostComponent);
301
- hostComponent = fixture.componentInstance;
302
- fixture.detectChanges();
303
-
304
- // Get the directive instance
305
- const textareaDebugElement = fixture.debugElement.query(By.css('textarea'));
306
- component = textareaDebugElement.injector.get(CopilotChatTextareaComponent);
307
- textareaElement = textareaDebugElement.nativeElement;
308
- });
309
-
310
- describe('Textarea Behavior', () => {
311
- it('should create', () => {
312
- expect(component).toBeTruthy();
313
- });
314
-
315
- it('should set placeholder from configuration', () => {
316
- expect(textareaElement.placeholder).toBe('Test placeholder');
317
- });
318
-
319
- it('should handle input events', () => {
320
- textareaElement.value = 'New text';
321
- textareaElement.dispatchEvent(new Event('input'));
322
-
323
- expect(hostComponent.onValueChange).toHaveBeenCalledWith('New text');
324
- expect(component.value()).toBe('New text');
325
- });
326
-
327
- it('should auto-resize based on content', () => {
328
- // Mock getComputedStyle to return values
329
- const originalGetComputedStyle = window.getComputedStyle;
330
- window.getComputedStyle = vi.fn().mockReturnValue({
331
- paddingTop: '20px',
332
- paddingBottom: '0px'
333
- });
334
-
335
- // Set scrollHeight manually for test
336
- Object.defineProperty(textareaElement, 'scrollHeight', {
337
- configurable: true,
338
- value: 100
339
- });
340
-
341
- // Add multiple lines of text
342
- textareaElement.value = 'Line 1\nLine 2\nLine 3';
343
- textareaElement.dispatchEvent(new Event('input'));
344
- fixture.detectChanges();
345
-
346
- // Height should be set
347
- const newHeight = textareaElement.style.height;
348
- expect(newHeight).toBeTruthy();
349
-
350
- // Restore original getComputedStyle
351
- window.getComputedStyle = originalGetComputedStyle;
352
- });
353
-
354
- it('should respect maxRows limit', () => {
355
- hostComponent.maxRows = 3;
356
- fixture.detectChanges();
357
-
358
- expect(component.maxRows()).toBe(3);
359
- });
360
-
361
- it('should focus when autoFocus is true', async () => {
362
- // Set autoFocus before creating the component
363
- TestBed.resetTestingModule();
364
- TestBed.configureTestingModule({
365
- imports: [TestHostComponent, CopilotChatTextareaComponent],
366
- providers: [
367
- provideCopilotChatConfiguration({
368
- labels: {
369
- chatInputPlaceholder: 'Test placeholder'
370
- }
371
- })
372
- ]
373
- });
374
-
375
- // Create a new fixture with autoFocus set to true
376
- const newFixture = TestBed.createComponent(TestHostComponent);
377
- const newHostComponent = newFixture.componentInstance;
378
- newHostComponent.autoFocus = true;
379
- newFixture.detectChanges();
380
-
381
- // Get the new textarea element
382
- const newTextareaElement = newFixture.nativeElement.querySelector('textarea');
383
-
384
- // Wait for async focus to complete
385
- await newFixture.whenStable();
386
- await new Promise(resolve => setTimeout(resolve, 50));
387
-
388
- expect(document.activeElement).toBe(newTextareaElement);
389
- });
390
-
391
- it('should emit keyDown events', () => {
392
- const event = new KeyboardEvent('keydown', { key: 'Enter' });
393
- textareaElement.dispatchEvent(event);
394
-
395
- expect(hostComponent.onKeyDown).toHaveBeenCalled();
396
- });
397
- });
398
-
399
- describe('Public Methods', () => {
400
- it('should focus textarea programmatically', () => {
401
- component.focus();
402
-
403
- expect(document.activeElement).toBe(textareaElement);
404
- });
405
-
406
- it('should get current value', () => {
407
- component.value.set('Test value');
408
-
409
- expect(component.getValue()).toBe('Test value');
410
- });
411
-
412
- it('should set value programmatically', () => {
413
- component.setValue('New value');
414
-
415
- expect(component.getValue()).toBe('New value');
416
- expect(hostComponent.onValueChange).toHaveBeenCalledWith('New value');
417
- });
418
- });
419
- });