@@ -14,7 +14,7 @@ import type {
1414 InitializedEvent ,
1515} from '@js/ui/button' ;
1616import type Button from '@js/ui/button' ;
17- import type { Attachment } from '@js/ui/chat' ;
17+ import type { Attachment , SendButtonProperties } from '@js/ui/chat' ;
1818import type {
1919 UploadedEvent ,
2020 UploadStartedEvent ,
@@ -60,6 +60,8 @@ export type Properties = TextAreaProperties & {
6060
6161 speechToTextOptions ?: SpeechToTextProperties ;
6262
63+ sendButtonOptions ?: SendButtonProperties ;
64+
6365 onSend ?: ( e : SendEvent ) => void ;
6466} ;
6567
@@ -104,6 +106,14 @@ export const SEND_BUTTON_READY_TO_SEND_STATE: ButtonState = {
104106 disabled : false ,
105107} ;
106108
109+ export const SEND_BUTTON_CUSTOM_ACTIVE_STATE : ButtonState = {
110+ stylingMode : 'contained' ,
111+ type : 'default' ,
112+ disabled : false ,
113+ } ;
114+
115+ const SEND_BUTTON_DEFAULT_ICON = 'arrowright' ;
116+
107117const isMobile = ( ) : boolean => devices . current ( ) . deviceType !== 'desktop' ;
108118
109119export const DEFAULT_ALLOWED_FILE_EXTENSIONS = [ '.jpg' , '.jpeg' , '.png' , '.gif' , '.webp' , '.bmp' , '.pdf' , '.docx' , '.xlsx' , '.pptx' , '.txt' , '.rtf' , '.csv' , '.md' ] ;
@@ -135,6 +145,8 @@ class ChatTextArea extends TextArea<Properties> {
135145
136146 _sendAction ?: ( e : Partial < SendEvent > ) => void ;
137147
148+ _sendButtonClickAction ?: ( e : Partial < ClickEvent > ) => void ;
149+
138150 getAttachments ( ) : Attachment [ ] | undefined {
139151 if ( ! this . _filesToSend ?. size ) {
140152 return undefined ;
@@ -201,6 +213,7 @@ class ChatTextArea extends TextArea<Properties> {
201213 super . _init ( ) ;
202214
203215 this . _createSendAction ( ) ;
216+ this . _createSendButtonClickAction ( ) ;
204217 }
205218
206219 _createSendAction ( ) : void {
@@ -210,6 +223,15 @@ class ChatTextArea extends TextArea<Properties> {
210223 ) ;
211224 }
212225
226+ _createSendButtonClickAction ( ) : void {
227+ const { sendButtonOptions } = this . option ( ) ;
228+
229+ this . _sendButtonClickAction = this . _createAction (
230+ sendButtonOptions ?. onClick ,
231+ { excludeValidators : [ 'disabled' ] } ,
232+ ) ;
233+ }
234+
213235 _initMarkup ( ) : void {
214236 this . $element ( ) . addClass ( CHAT_TEXTAREA_CLASS ) ;
215237 super . _initMarkup ( ) ;
@@ -378,6 +400,7 @@ class ChatTextArea extends TextArea<Properties> {
378400 activeStateEnabled,
379401 focusStateEnabled,
380402 hoverStateEnabled,
403+ sendButtonOptions,
381404 } = this . option ( ) ;
382405
383406 const configuration = {
@@ -387,13 +410,14 @@ class ChatTextArea extends TextArea<Properties> {
387410 activeStateEnabled,
388411 focusStateEnabled,
389412 hoverStateEnabled,
390- icon : 'arrowright' ,
413+ icon : sendButtonOptions ?. icon ?? SEND_BUTTON_DEFAULT_ICON ,
391414 ...SEND_BUTTON_INITIAL_STATE ,
392415 elementAttr : {
393416 'aria-label' : messageLocalization . format ( 'dxChat-sendButtonAriaLabel' ) ,
394417 } ,
395418 onClick : ( e : ClickEvent ) : void => {
396419 this . _processSendButtonActivation ( e ) ;
420+ this . _sendButtonClickAction ?.( e ) ;
397421 } ,
398422 onInitialized : ( e : InitializedEvent ) : void => {
399423 this . _sendButton = e . component ;
@@ -566,6 +590,12 @@ class ChatTextArea extends TextArea<Properties> {
566590 return ;
567591 }
568592
593+ if ( this . _isCustomBehavior ( ) ) {
594+ this . _speechToTextButton ?. option ( STT_INITIAL_STATE ) ;
595+ this . _sendButton ?. option ( SEND_BUTTON_CUSTOM_ACTIVE_STATE ) ;
596+ return ;
597+ }
598+
569599 this . _speechToTextButton ?. option ( STT_INITIAL_STATE ) ;
570600 this . _sendButton ?. option ( SEND_BUTTON_INITIAL_STATE ) ;
571601 }
@@ -594,7 +624,18 @@ class ChatTextArea extends TextArea<Properties> {
594624 this . _updateButtonsState ( ) ;
595625 }
596626
627+ _isCustomBehavior ( ) : boolean {
628+ const { sendButtonOptions } = this . option ( ) ;
629+
630+ return sendButtonOptions ?. action === 'custom' ;
631+ }
632+
597633 _processSendButtonActivation ( e : Partial < SendEvent > ) : void {
634+ if ( this . _isCustomBehavior ( ) ) {
635+ this . _updateButtonsState ( ) ;
636+ return ;
637+ }
638+
598639 this . _sendAction ?.( e ) ;
599640 this . clear ( ) ;
600641 this . resetFileUploader ( ) ;
@@ -640,6 +681,10 @@ class ChatTextArea extends TextArea<Properties> {
640681 this . _speechToTextButton ?. option ( this . _getSpeechToTextButtonOptions ( ) ) ;
641682 break ;
642683
684+ case 'sendButtonOptions' :
685+ this . _handleSendButtonOptionsChange ( ) ;
686+ break ;
687+
643688 default :
644689 super . _optionChanged ( args ) ;
645690 }
@@ -661,6 +706,22 @@ class ChatTextArea extends TextArea<Properties> {
661706 this . _fileUploader ?. option ( options ) ;
662707 }
663708
709+ _handleSendButtonOptionsChange ( ) : void {
710+ const { sendButtonOptions } = this . option ( ) ;
711+
712+ this . _createSendButtonClickAction ( ) ;
713+
714+ this . _sendButton ?. option ( {
715+ onClick : ( e : ClickEvent ) : void => {
716+ this . _processSendButtonActivation ( e ) ;
717+ this . _sendButtonClickAction ?.( e ) ;
718+ } ,
719+ icon : sendButtonOptions ?. icon ?? SEND_BUTTON_DEFAULT_ICON ,
720+ } ) ;
721+
722+ this . _updateButtonsState ( ) ;
723+ }
724+
664725 _isValuableTextEntered ( ) : boolean {
665726 const { text } = this . option ( ) ;
666727
0 commit comments