Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions packages/devextreme/js/__internal/ui/chat/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ class Chat extends Widget<ChatProperties> {
inputFieldText,
speechToTextEnabled,
speechToTextOptions,
mainButtonOptions,
} = this.option();

const $messageBox = $('<div>');
Expand All @@ -485,6 +486,7 @@ class Chat extends Widget<ChatProperties> {
text: inputFieldText,
speechToTextEnabled,
speechToTextOptions,
mainButtonOptions,
onMessageEntered: (e) => {
this._messageEnteredHandler(e);
},
Expand Down Expand Up @@ -743,6 +745,9 @@ class Chat extends Widget<ChatProperties> {
break;
case 'reloadOnChange':
break;
case 'mainButtonOptions':
this._messageBox.option(name, value);
break;
default:
super._optionChanged(args);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type {
InitializedEvent,
} from '@js/ui/button';
import type Button from '@js/ui/button';
import type { Attachment } from '@js/ui/chat';
import type { Attachment, MainButtonOptions } from '@js/ui/chat';
import type {
UploadedEvent,
UploadStartedEvent,
Expand Down Expand Up @@ -60,6 +60,8 @@ export type Properties = TextAreaProperties & {

speechToTextOptions?: SpeechToTextProperties;

mainButtonOptions?: MainButtonOptions;

onSend?: (e: SendEvent) => void;
};

Expand Down Expand Up @@ -104,6 +106,12 @@ export const SEND_BUTTON_READY_TO_SEND_STATE: ButtonState = {
disabled: false,
};

export const MAIN_BUTTON_CUSTOM_ACTIVE_STATE: ButtonState = {
stylingMode: 'contained',
type: 'default',
disabled: false,
};

const isMobile = (): boolean => devices.current().deviceType !== 'desktop';

export const DEFAULT_ALLOWED_FILE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp', '.pdf', '.docx', '.xlsx', '.pptx', '.txt', '.rtf', '.csv', '.md'];
Expand Down Expand Up @@ -378,6 +386,7 @@ class ChatTextArea extends TextArea<Properties> {
activeStateEnabled,
focusStateEnabled,
hoverStateEnabled,
mainButtonOptions,
} = this.option();

const configuration = {
Expand All @@ -387,13 +396,15 @@ class ChatTextArea extends TextArea<Properties> {
activeStateEnabled,
focusStateEnabled,
hoverStateEnabled,
icon: 'arrowright',
icon: mainButtonOptions?.icon ?? 'arrowright',
...SEND_BUTTON_INITIAL_STATE,
elementAttr: {
'aria-label': messageLocalization.format('dxChat-sendButtonAriaLabel'),
},
onClick: (e: ClickEvent): void => {
this._processSendButtonActivation(e);
// @ts-expect-error
mainButtonOptions?.onClick?.(e);
},
onInitialized: (e: InitializedEvent): void => {
this._sendButton = e.component;
Expand Down Expand Up @@ -552,6 +563,11 @@ class ChatTextArea extends TextArea<Properties> {
_updateButtonsState(): void {
const { speechToTextEnabled } = this.option();

if (this._isCustomBehavior()) {
this._sendButton?.option(MAIN_BUTTON_CUSTOM_ACTIVE_STATE);
return;
}

if (this._isSpeechToTextListening === true && speechToTextEnabled) {
this._speechToTextButton?.option(STT_LISTENING_STATE);
this._sendButton?.option(SEND_BUTTON_INITIAL_STATE);
Expand Down Expand Up @@ -594,7 +610,18 @@ class ChatTextArea extends TextArea<Properties> {
this._updateButtonsState();
}

_isCustomBehavior(): boolean {
const { mainButtonOptions } = this.option();

return mainButtonOptions?.behavior === 'custom';
}

_processSendButtonActivation(e: Partial<SendEvent>): void {
if (this._isCustomBehavior()) {
this._updateButtonsState();
return;
}

this._sendAction?.(e);
this.clear();
this.resetFileUploader();
Expand Down Expand Up @@ -640,6 +667,11 @@ class ChatTextArea extends TextArea<Properties> {
this._speechToTextButton?.option(this._getSpeechToTextButtonOptions());
break;

case 'mainButtonOptions':
this._toolbar?.option({ items: this._getToolbarItems() });
this._updateButtonsState();
break;

default:
super._optionChanged(args);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { NativeEventInfo } from '@js/common/core/events';
import $, { type dxElementWrapper } from '@js/core/renderer';
import type { InteractionEvent } from '@js/events';
import type { Attachment, InputFieldTextChangedEvent } from '@js/ui/chat';
import type { Attachment, InputFieldTextChangedEvent, MainButtonOptions } from '@js/ui/chat';
import type { Properties as FileUploaderProperties } from '@js/ui/file_uploader';
import type { Properties as SpeechToTextProperties } from '@js/ui/speech_to_text';
import type { InputEvent } from '@js/ui/text_area';
Expand Down Expand Up @@ -40,6 +40,8 @@ export interface Properties extends DOMComponentProperties<MessageBox> {

text?: string;

mainButtonOptions?: MainButtonOptions;

onMessageEntered?: (e: MessageEnteredEvent) => void;

onTypingStart?: (e: TypingStartEvent) => void;
Expand Down Expand Up @@ -176,6 +178,7 @@ class MessageBox extends DOMComponent<MessageBox, Properties> {
speechToTextEnabled,
speechToTextOptions,
text,
mainButtonOptions,
} = this.option();

const options = {
Expand All @@ -187,6 +190,7 @@ class MessageBox extends DOMComponent<MessageBox, Properties> {
value: previewText || text,
speechToTextEnabled,
speechToTextOptions,
mainButtonOptions,
onInput: (e: InputEvent): void => {
this._triggerTypingStartAction(e);
this._updateTypingEndTimeout();
Expand Down Expand Up @@ -321,6 +325,10 @@ class MessageBox extends DOMComponent<MessageBox, Properties> {
this._textArea.option('value', value);
break;

case 'mainButtonOptions':
this._textArea.option(name, value);
break;

default:
super._optionChanged(args);
}
Expand Down
38 changes: 38 additions & 0 deletions packages/devextreme/js/ui/chat.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,39 @@ export type AttachmentDownloadClickEvent = EventInfo<dxChat> & {
*/
export type InputFieldTextChangedEvent = NativeEventInfo<dxChat, InteractionEvent | Event> & ValueChangedInfo;

/**
* @docid _ui_chat_MainButtonClickEvent
* @public
* @type object
* @inherits NativeEventInfo
*/
export type MainButtonClickEvent = NativeEventInfo<dxChat, InteractionEvent>;

/**
* @docid
* @namespace DevExpress.ui.dxChat
* @public
*/
export type MainButtonOptions = {
/**
* @docid
* @public
*/
icon?: string;
/**
* @docid
* @public
* @default 'default'
*/
behavior?: 'default' | 'custom';
/**
* @docid
* @type_function_param1 e:{ui/chat:MainButtonClickEvent}
* @public
*/
onClick: ((e: MainButtonClickEvent) => void);
};

/**
* @docid
* @namespace DevExpress.ui.dxChat
Expand Down Expand Up @@ -446,6 +479,11 @@ export interface dxChatOptions extends WidgetOptions<dxChat> {
* @public
*/
inputFieldText?: TextAreaProperties['value'];
/**
* @docid
* @public
*/
mainButtonOptions?: MainButtonOptions;
/**
* @docid
* @default null
Expand Down
2 changes: 2 additions & 0 deletions packages/devextreme/js/ui/chat_types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export {
MessageUpdatedEvent,
AttachmentDownloadClickEvent,
InputFieldTextChangedEvent,
MainButtonClickEvent,
MainButton,
User,
Alert,
Attachment,
Expand Down
33 changes: 33 additions & 0 deletions packages/devextreme/ts/dx.all.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11238,6 +11238,14 @@ declare module DevExpress.ui {
DevExpress.events.InteractionEvent | Event
> &
DevExpress.ui.Editor.ValueChangedInfo;
/**
* [descr:_ui_chat_MainButtonClickEvent]
*/
export type MainButtonClickEvent =
DevExpress.common.core.events.NativeEventInfo<
dxChat,
DevExpress.events.InteractionEvent
>;
/**
* [descr:_ui_chat_MessageDeletedEvent]
*/
Expand Down Expand Up @@ -11442,6 +11450,10 @@ declare module DevExpress.ui {
* [descr:dxChatOptions.inputFieldText]
*/
inputFieldText?: DevExpress.ui.dxTextArea.Properties['value'];
/**
* [descr:dxChatOptions.mainButton]
*/
mainButton?: DevExpress.ui.dxChat.MainButton;
/**
* [descr:dxChatOptions.messageTemplate]
*/
Expand Down Expand Up @@ -34134,6 +34146,27 @@ declare module DevExpress.ui.dxChat {
*/
alt?: string;
};
/**
* [descr:MainButton]
*/
export type MainButton = {
/**
* [descr:MainButton.icon]
*/
icon?: string;
/**
* [descr:MainButton.hint]
*/
hint?: string;
/**
* [descr:MainButton.action]
*/
action: 'default' | 'custom';
/**
* [descr:MainButton.onClick]
*/
onClick: (e: MainButtonClickEvent) => void;
};
/**
* [descr:Message]
*/
Expand Down
Loading