Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
858add5
Alfa Chat MessageBox: Intagrate Toolbar
Oct 2, 2025
eb7b292
refactor(chat): Move files to new folder && Remove extra scss files
Oct 6, 2025
7a02ade
feat(chat): Intermediate result
Oct 6, 2025
3f04ff1
feat && refactor(chat): Move logic to CTA
Oct 7, 2025
b4a02f9
fix(tests): Update imports
Oct 7, 2025
8b25d6d
resolve conflicts after rebase
Oct 9, 2025
30c78b8
refactor(chat): Rename textarea
Oct 9, 2025
23fed61
feat(chat): Add fileUploaderOptions
Oct 9, 2025
3948bd8
feat(chat scss): Remove button extra style
Oct 9, 2025
dc05c61
feat(chat): Add styles
Oct 9, 2025
326bbe5
feat(chat styles): Add vars
Oct 10, 2025
d75340b
feat(chat styles): Add vars for paddings
Oct 10, 2025
1eca565
feat(chat styles): Improve BR in Fluent
Oct 10, 2025
78f4198
revert && refactor()
Oct 10, 2025
257c7ba
refactor && feat(chat): Provide fileUploaderOptions
Oct 10, 2025
9ef9770
feat(CTA): Add fileUploaderOptions to _optionChanged
Oct 10, 2025
d836295
improve(CTA && MB): Improve types
Oct 10, 2025
2f75384
feat(chat tests): Raise the tests
Oct 10, 2025
f487fbe
revert(pg)
Oct 10, 2025
578fb51
feat(tests && etalons)
Oct 10, 2025
1fe6fc8
fix(ML TC Tests): Increase height for the test
Oct 14, 2025
5c1829b
feat(etalons): Update
Oct 14, 2025
fa42c75
feat(TC Tests, MB): Add new test for attach button
Oct 14, 2025
58ceae8
fix(chat): Update tests after small refactoring
Oct 14, 2025
c8583a0
feat(etalons): Update
Oct 14, 2025
315ab98
feat(etalons): Update (fix conflicts: remove some etalons)
Oct 14, 2025
04ee603
feat(etalons): Update
Oct 15, 2025
9e1ba7c
fix(etalons): Get new ones
Oct 15, 2025
6395ef8
fix(etalons): Add etalons
Oct 15, 2025
d1a9d32
fix(etalons): Remove again (2nd)
Oct 15, 2025
0cf5bb0
fix(etalons): Remove brocken
Oct 16, 2025
42e126e
fix(etalons): Add new one
Oct 16, 2025
7f78bd4
fix(etalons): Add fixed etalon
Oct 16, 2025
7e8ae2b
fix(etalons): Add new ones (3)
Oct 17, 2025
fbf462f
fix(etalons): Update
Oct 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/demos/testing/etalons/Chat-AIAndChatbotIntegration.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/demos/testing/etalons/Chat-Customization.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/demos/testing/etalons/Chat-MessageEditing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/demos/testing/etalons/Chat-Overview (material.blue.light).png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/demos/testing/etalons/Chat-Overview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/demos/testing/widgets/chat/etalons/message_is_deleted.png
Binary file modified apps/demos/testing/widgets/chat/etalons/message_is_edited.png
Binary file modified apps/demos/testing/widgets/chat/etalons/preview_is_shown.png
21 changes: 21 additions & 0 deletions e2e/testcafe-devextreme/tests/editors/chat/messageBox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,24 @@ test('Chat: messagebox with editing preview', async (t) => {
height: 600,
}, '#chat');
});

test('Chat: messagebox with attach button', async (t) => {
const { takeScreenshot, compareResults } = createScreenshotsComparer(t);

const chat = new Chat('#chat');

await chat.focus();
await testScreenshot(t, takeScreenshot, 'Messagebox with attach button.png', { element: '#chat' });

await t
.expect(compareResults.isValid())
.ok(compareResults.errorMessages());
}).before(async () => {
await appendElementTo('#container', 'div', 'chat');

return createWidget('dxChat', {
width: 400,
height: 600,
fileUploaderOptions: {},
}, '#chat');
});
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ test('Messagelist empty view scenarios', async (t) => {

await chat.option({
width: 200,
height: 200,
height: 400,
disabled: false,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,28 @@
border-top-style: solid;
}

.dx-chat-messagebox-input-container {
.dx-chat-messagebox-textarea-container {
display: flex;
align-items: flex-end;
}

.dx-chat-messagebox-textarea {
.dx-chat-messagebox-textarea.dx-textarea {
display: flex;
flex-direction: column;
flex-grow: 1;

&.dx-texteditor {
> .dx-texteditor-container {
.dx-texteditor-input,
.dx-placeholder::before {
padding: 0;
}
}
}
}

.dx-textarea-toolbar.dx-toolbar {
.dx-toolbar-items-container {
height: auto;
}
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,39 @@
@mixin chat-messagebox(
$padding,
$border-color,
$messagebox-padding,
$messagebox-border-color,
$gap,
$textarea-border-radius,
$button-gap
$textarea-padding,
$toolbar-min-height
) {
.dx-chat-messagebox {
padding: $padding;
border-top-color: $border-color;
gap: $padding;
padding: $messagebox-padding;
border-top-color: $messagebox-border-color;
gap: $messagebox-padding;
}

.dx-chat-messagebox-input-container {
.dx-chat-messagebox-textarea-container {
gap: $gap;
}

.dx-chat-messagebox-textarea {
&.dx-textarea.dx-texteditor {
.dx-chat-messagebox-textarea.dx-textarea {
gap: $gap;
padding: $textarea-padding;

&.dx-texteditor {
border-radius: $textarea-border-radius;

&.dx-editor-outlined::before {
height: $textarea-border-radius;
border-bottom-left-radius: $textarea-border-radius;
border-bottom-right-radius: $textarea-border-radius;
}
}
}

.dx-chat-messagebox-button {
margin-bottom: $button-gap;
.dx-textarea-toolbar.dx-toolbar {
.dx-toolbar-items-container {
min-height: $toolbar-min-height;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
$underlined-top-padding,
) {
.dx-textarea {
.dx-texteditor-input-container {
> .dx-texteditor-container > .dx-texteditor-input-container {
margin: $input-container-margin;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
$chat-messagebox-border-color,
$chat-messagebox-gap,
$chat-messagebox-textarea-border-radius,
$chat-messagebox-buton-gap,
$chat-messagebox-textarea-padding,
$chat-messagebox-toolbar-min-height,
);
@include chat-messagebubble(
$chat-bubble-padding,
Expand Down
11 changes: 9 additions & 2 deletions packages/devextreme-scss/scss/widgets/fluent/chat/_sizes.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ $chat-bubble-container-gap: 4px !default;
$chat-bubble-delete-gap: null !default;
$chat-bubble-delete-icon-size: null !default;
$chat-messagebox-padding: null !default;
$chat-messagebox-textarea-border-radius: $texteditor-input-border-radius !default;
$chat-messagebox-textarea-padding: null !default;
$chat-messagebox-textarea-border-radius: null !default;
$chat-messagebox-toolbar-min-height: null !default;
$chat-messagebox-gap: 8px !default;
$chat-messagebox-buton-gap: 2px !default;
$chat-messagelist-padding: null !default;
$chat-messagegroup-gap: 4px !default;
$chat-messagegroup-padding: null !default;
Expand Down Expand Up @@ -72,6 +73,9 @@ $chat-confirmation-popup-toolbar-gap: null !default;
$chat-bubble-delete-gap: 4px !default;
$chat-bubble-delete-icon-size: 20px !default;
$chat-messagebox-padding: 20px !default;
$chat-messagebox-textarea-border-radius: 8px !default;
$chat-messagebox-textarea-padding: 12px !default;
$chat-messagebox-toolbar-min-height: 32px !default;
$chat-messagelist-padding: 20px !default;
$chat-messagegroup-padding: 24px !default;

Expand Down Expand Up @@ -105,6 +109,9 @@ $chat-confirmation-popup-toolbar-gap: null !default;
$chat-bubble-delete-gap: 2px !default;
$chat-bubble-delete-icon-size: 16px !default;
$chat-messagebox-padding: 16px !default;
$chat-messagebox-textarea-border-radius: 8px !default;
$chat-messagebox-textarea-padding: 8px !default;
$chat-messagebox-toolbar-min-height: 24px !default;
$chat-messagelist-padding: 16px !default;
$chat-messagegroup-padding: 12px !default;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
$chat-messagebox-border-color,
$chat-messagebox-gap,
$chat-messagebox-textarea-border-radius,
$chat-messagebox-buton-gap,
$chat-messagebox-textarea-padding,
$chat-messagebox-toolbar-min-height,
);
@include chat-messagebubble(
$chat-bubble-padding,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ $chat-bubble-delete-gap: null !default;
$chat-bubble-delete-icon-size: null !default;
$chat-messagebox-padding: null !default;
$chat-messagebox-textarea-border-radius: $texteditor-input-border-radius !default;
$chat-messagebox-textarea-padding: null !default;
$chat-messagebox-toolbar-min-height: null !default;
$chat-messagebox-gap: 8px !default;
$chat-messagebox-buton-gap: 0 !default;
$chat-messagelist-padding: null !default;
$chat-messagegroup-gap: 4px !default;
$chat-messagegroup-padding: null !default;
Expand Down Expand Up @@ -70,6 +71,8 @@ $chat-confirmation-popup-toolbar-gap: null !default;
$chat-bubble-delete-gap: 4px !default;
$chat-bubble-delete-icon-size: 18px !default;
$chat-messagebox-padding: 20px !default;
$chat-messagebox-textarea-padding: 9px !default;
$chat-messagebox-toolbar-min-height: 36px !default;
$chat-messagelist-padding: 20px !default;
$chat-messagegroup-padding: 24px !default;

Expand Down Expand Up @@ -102,6 +105,8 @@ $chat-confirmation-popup-toolbar-gap: null !default;
$chat-bubble-delete-gap: 2px !default;
$chat-bubble-delete-icon-size: 14px !default;
$chat-messagebox-padding: 16px !default;
$chat-messagebox-textarea-padding: 5px !default;
$chat-messagebox-toolbar-min-height: 26px !default;
$chat-messagelist-padding: 16px !default;
$chat-messagegroup-padding: 12px !default;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
$chat-messagebox-border-color,
$chat-messagebox-gap,
$chat-messagebox-textarea-border-radius,
$chat-messagebox-buton-gap,
$chat-messagebox-textarea-padding,
$chat-messagebox-toolbar-min-height,
);
@include chat-messagebubble(
$chat-bubble-padding,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ $chat-bubble-delete-gap: null !default;
$chat-bubble-delete-icon-size: null !default;
$chat-messagebox-padding: null !default;
$chat-messagebox-textarea-border-radius: $base-border-radius * 2 !default;
$chat-messagebox-buton-gap: null !default;
$chat-messagebox-textarea-padding: null !default;
$chat-messagebox-toolbar-min-height: null !default;
$chat-messagebox-gap: 8px !default;
$chat-messagelist-padding: null !default;
$chat-messagegroup-gap: 4px !default;
Expand Down Expand Up @@ -64,12 +65,13 @@ $chat-confirmation-popup-toolbar-padding-inline: null !default;
$chat-confirmation-popup-toolbar-gap: null !default;

@if $size == "default" {
$chat-messagebox-buton-gap: 10px !default;
$chat-bubble-border-radius: 8px !default;
$chat-bubble-padding: 8px 16px !default;
$chat-bubble-delete-gap: 4px !default;
$chat-bubble-delete-icon-size: 20px !default;
$chat-messagebox-padding: 20px !default;
$chat-messagebox-textarea-padding: 16px !default;
$chat-messagebox-toolbar-min-height: 36px !default;
$chat-messagelist-padding: 20px !default;
$chat-messagegroup-padding: 24px !default;

Expand Down Expand Up @@ -100,12 +102,13 @@ $chat-confirmation-popup-toolbar-gap: null !default;
}

@else if $size == "compact" {
$chat-messagebox-buton-gap: 7px !default;
$chat-bubble-border-radius: 4px !default;
$chat-bubble-padding: 6px 8px !default;
$chat-bubble-delete-gap: 2px !default;
$chat-bubble-delete-icon-size: 16px !default;
$chat-messagebox-padding: 16px !default;
$chat-messagebox-textarea-padding: 12px !default;
$chat-messagebox-toolbar-min-height: 28px !default;
$chat-messagelist-padding: 16px !default;
$chat-messagegroup-padding: 12px !default;

Expand Down
41 changes: 25 additions & 16 deletions packages/devextreme/js/__internal/ui/chat/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ import type {
MessageEnteredEvent,
MessageUpdatedEvent,
MessageUpdatingEvent,
Properties,
Properties as PublicProperties,
TypingEndEvent,
TypingStartEvent,
} from '@js/ui/chat';
import type { Properties as FileUploaderProperties } from '@js/ui/file_uploader';
import { invokeConditionally } from '@ts/core/utils/conditional_invoke';
import type { OptionChanged } from '@ts/core/widget/types';
import Widget from '@ts/core/widget/widget';
Expand All @@ -28,8 +29,8 @@ import type {
MessageEnteredEvent as MessageBoxMessageEnteredEvent,
Properties as MessageBoxProperties,
TypingStartEvent as MessageBoxTypingStartEvent,
} from '@ts/ui/chat/messagebox';
import MessageBox from '@ts/ui/chat/messagebox';
} from '@ts/ui/chat/message_box/message_box';
import MessageBox from '@ts/ui/chat/message_box/message_box';
import type {
EmptyViewTemplate,
MessageEditingEvent,
Expand All @@ -42,6 +43,10 @@ import type { DataChange } from '@ts/ui/collection/collection_widget.base';
const CHAT_CLASS = 'dx-chat';
const TEXTEDITOR_INPUT_CLASS = 'dx-texteditor-input';

type Properties = PublicProperties & {
fileUploaderOptions?: FileUploaderProperties;
};

class Chat extends Widget<Properties> {
_messageBox!: MessageBox;

Expand Down Expand Up @@ -76,34 +81,35 @@ class Chat extends Widget<Properties> {
_getDefaultOptions(): Properties {
return {
...super._getDefaultOptions(),
showDayHeaders: true,
activeStateEnabled: true,
alerts: [],
dataSource: null,
dayHeaderFormat: 'shortdate',
editing: {
allowUpdating: false,
allowDeleting: false,
},
emptyViewTemplate: null,
fileUploaderOptions: undefined,
focusStateEnabled: true,
hoverStateEnabled: true,
items: [],
dataSource: null,
user: { id: new Guid().toString() },
dayHeaderFormat: 'shortdate',
messageTemplate: null,
messageTimestampFormat: 'shorttime',
emptyViewTemplate: null,
alerts: [],
reloadOnChange: true,
showAvatar: true,
showUserName: true,
showDayHeaders: true,
showMessageTimestamp: true,
showUserName: true,
typingUsers: [],
user: { id: new Guid().toString() },
onMessageDeleted: undefined,
onMessageDeleting: undefined,
onMessageEditCanceled: undefined,
onMessageEditingStart: undefined,
onMessageEntered: undefined,
reloadOnChange: true,
onTypingStart: undefined,
onTypingEnd: undefined,
onMessageEditingStart: undefined,
onMessageEditCanceled: undefined,
onMessageDeleting: undefined,
onMessageDeleted: undefined,
onTypingStart: undefined,
};
}

Expand Down Expand Up @@ -408,6 +414,7 @@ class Chat extends Widget<Properties> {
_renderMessageBox(): void {
const {
activeStateEnabled,
fileUploaderOptions,
focusStateEnabled,
hoverStateEnabled,
} = this.option();
Expand All @@ -418,6 +425,7 @@ class Chat extends Widget<Properties> {

const configuration: MessageBoxProperties = {
activeStateEnabled,
fileUploaderOptions,
focusStateEnabled,
hoverStateEnabled,
onMessageEntered: (e) => {
Expand Down Expand Up @@ -570,6 +578,7 @@ class Chat extends Widget<Properties> {
case 'activeStateEnabled':
case 'focusStateEnabled':
case 'hoverStateEnabled':
case 'fileUploaderOptions':
this._messageBox.option(name, value);
break;
case 'user': {
Expand Down
Loading
Loading