Skip to content

Commit 9c540f4

Browse files
committed
fix(chat): Run adoptPageStyles on theme swap
1 parent 16fb192 commit 9c540f4

File tree

3 files changed

+64
-41
lines changed

3 files changed

+64
-41
lines changed

src/components/chat/chat-input.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,10 @@ export default class IgcChatInputComponent extends LitElement {
102102
private readonly _userInputState!: ChatState;
103103

104104
@query(IgcTextareaComponent.tagName)
105-
private readonly _textInputElement!: IgcTextareaComponent;
105+
private readonly _textInputElement?: IgcTextareaComponent;
106106

107107
@query('#input_attachments')
108-
protected readonly _fileInput!: HTMLInputElement;
108+
protected readonly _fileInput?: HTMLInputElement;
109109

110110
@state()
111111
private _parts = { 'input-container': true, dragging: false };
@@ -116,20 +116,20 @@ export default class IgcChatInputComponent extends LitElement {
116116

117117
constructor() {
118118
super();
119-
addThemingController(this, all);
119+
addThemingController(this, all, { themeChange: this._adoptPageStyles });
120120
}
121121

122-
protected override firstUpdated(): void {
122+
/** @internal */
123+
public focusInput(): void {
124+
this._textInputElement?.focus();
125+
}
126+
127+
private _adoptPageStyles(): void {
123128
if (this._state.options?.adoptRootStyles) {
124129
adoptPageStyles(this);
125130
}
126131
}
127132

128-
/** @internal */
129-
public focusInput(): void {
130-
this._textInputElement.focus();
131-
}
132-
133133
private _getRenderer<U extends keyof DefaultInputRenderers>(
134134
name: U
135135
): DefaultInputRenderers[U] {
@@ -210,7 +210,7 @@ export default class IgcChatInputComponent extends LitElement {
210210
}
211211

212212
private _handleFileInputClick(): void {
213-
this._fileInput.showPicker();
213+
this._fileInput?.showPicker();
214214
}
215215

216216
private _handleFocusState(event: FocusEvent): void {

src/components/chat/chat-message.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ export default class IgcChatMessageComponent extends LitElement {
8484

8585
constructor() {
8686
super();
87-
addThemingController(this, all);
87+
addThemingController(this, all, { themeChange: this._adoptPageStyles });
8888
}
8989

90-
protected override firstUpdated(): void {
90+
private _adoptPageStyles(): void {
9191
if (this._state.options?.adoptRootStyles) {
9292
adoptPageStyles(this);
9393
}

src/components/chat/chat.spec.ts

Lines changed: 52 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { elementUpdated, expect, fixture } from '@open-wc/testing';
22
import { html, nothing } from 'lit';
33
import { spy, stub, useFakeTimers } from 'sinon';
4+
import { configureTheme } from '../../theming/config.js';
45
import type IgcIconButtonComponent from '../button/icon-button.js';
56
import IgcChipComponent from '../chip/chip.js';
67
import { enterKey, tabKey } from '../common/controllers/key-bindings.js';
@@ -22,7 +23,11 @@ import IgcChatComponent from './chat.js';
2223
import IgcChatInputComponent from './chat-input.js';
2324
import IgcChatMessageComponent from './chat-message.js';
2425
import IgcMessageAttachmentsComponent from './message-attachments.js';
25-
import type { IgcChatMessage, IgcChatMessageAttachment } from './types.js';
26+
import type {
27+
ChatMessageRenderContext,
28+
IgcChatMessage,
29+
IgcChatMessageAttachment,
30+
} from './types.js';
2631

2732
describe('Chat', () => {
2833
before(() => {
@@ -1026,7 +1031,22 @@ describe('Chat', () => {
10261031
});
10271032

10281033
describe('adoptRootStyles behavior', () => {
1029-
const customStyles = 'custom-background';
1034+
const messages: IgcChatMessage[] = [
1035+
{ id: 'id', sender: 'bot', text: 'Hello' },
1036+
];
1037+
const renderer = ({ message }: ChatMessageRenderContext) =>
1038+
html`<div class="custom-background">${message.text}</div>`;
1039+
1040+
function verifyCustomStyles(state: boolean) {
1041+
const { messages } = getChatDOM(chat);
1042+
const { backgroundColor } = getComputedStyle(
1043+
getChatMessageDOM(first(messages)).content.querySelector(
1044+
'.custom-background'
1045+
)!
1046+
);
1047+
1048+
expect(backgroundColor === 'rgb(255, 0, 0)').to.equal(state);
1049+
}
10301050

10311051
beforeEach(async () => {
10321052
const styles = document.createElement('style');
@@ -1039,48 +1059,51 @@ describe('Chat', () => {
10391059
document.head.append(styles);
10401060
});
10411061

1062+
afterEach(() => {
1063+
// Reset the theme and clean the style tag
1064+
configureTheme('bootstrap');
1065+
document.head.querySelector('#adopt-styles-test')?.remove();
1066+
});
1067+
10421068
it('correctly applies `adoptRootStyles` when set', async () => {
10431069
chat.options = {
10441070
adoptRootStyles: true,
1045-
renderers: {
1046-
messageContent: ({ message }) =>
1047-
html`<div class=${customStyles}>${message.text}</div>`,
1048-
},
1071+
renderers: { messageContent: renderer },
10491072
};
1050-
chat.messages = [{ id: 'id', sender: 'bot', text: 'Hello' }];
10511073

1052-
await elementUpdated(chat);
1074+
chat.messages = messages;
10531075

1054-
const { messages } = getChatDOM(chat);
1055-
expect(
1056-
getComputedStyle(
1057-
getChatMessageDOM(first(messages)).content.querySelector(
1058-
`.${customStyles}`
1059-
)!
1060-
).backgroundColor
1061-
).equal('rgb(255, 0, 0)');
1076+
await elementUpdated(chat);
1077+
verifyCustomStyles(true);
10621078
});
10631079

10641080
it('skips `adoptRootStyles` when not set', async () => {
10651081
chat.options = {
1066-
renderers: {
1067-
messageContent: ({ message }) =>
1068-
html`<div class=${customStyles}>${message.text}</div>`,
1069-
},
1082+
renderers: { messageContent: renderer },
10701083
};
10711084

1072-
chat.messages = [{ id: 'id', sender: 'bot', text: 'Hello' }];
1085+
chat.messages = messages;
10731086

10741087
await elementUpdated(chat);
1088+
verifyCustomStyles(false);
1089+
});
10751090

1076-
const { messages } = getChatDOM(chat);
1077-
expect(
1078-
getComputedStyle(
1079-
getChatMessageDOM(first(messages)).content.querySelector(
1080-
`.${customStyles}`
1081-
)!
1082-
).backgroundColor
1083-
).not.equal('rgb(255, 0, 0)');
1091+
it('correctly reapplies `adoptRootStyles` when set and the theme is changed', async () => {
1092+
chat.options = {
1093+
adoptRootStyles: true,
1094+
renderers: { messageContent: renderer },
1095+
};
1096+
1097+
chat.messages = messages;
1098+
1099+
await elementUpdated(chat);
1100+
verifyCustomStyles(true);
1101+
1102+
// Change the theme
1103+
configureTheme('material');
1104+
1105+
await elementUpdated(chat);
1106+
verifyCustomStyles(true);
10841107
});
10851108
});
10861109
});

0 commit comments

Comments
 (0)