1+ import messageLocalization from '@js/common/core/localization/message' ;
12import registerComponent from '@js/core/component_registrator' ;
3+ import devices from '@js/core/devices' ;
4+ import type { DefaultOptionsRule } from '@js/core/options/utils' ;
25import { noop } from '@js/core/utils/common' ;
36import type { DxEvent } from '@js/events' ;
4- import type { ClickEvent , Properties as ButtonProperties } from '@js/ui/button' ;
7+ import type { ClickEvent } from '@js/ui/button' ;
58import Button from '@js/ui/button' ;
69import type {
710 Properties as SpeechToTextProperties ,
811} from '@js/ui/speech_to_text' ;
12+ import { current , isMaterial } from '@js/ui/themes' ;
913import { SpeechRecognitionAdapter } from '@ts/core/speech_recognition_adapter' ;
1014import type { OptionChanged } from '@ts/core/widget/types' ;
1115import Widget from '@ts/core/widget/widget' ;
16+ import type { ButtonProps as ButtonProperties } from '@ts/ui/button/button' ;
1217
1318export const SPEECH_TO_TEXT_CLASS = 'dx-speech-to-text' ;
1419export const SPEECH_TO_TEXT_LISTENING_CLASS = 'dx-speech-to-text-listening' ;
@@ -32,7 +37,11 @@ const ACTIONS: (keyof SpeechToTextActions)[] = [
3237 'onError' ,
3338] ;
3439
35- class SpeechToText extends Widget < SpeechToTextProperties > {
40+ type Properties = SpeechToTextProperties & {
41+ useInkRipple : boolean ;
42+ } ;
43+
44+ class SpeechToText extends Widget < Properties > {
3645 private _button ?: Button ;
3746
3847 private _speechRecognitionAdapter ?: SpeechRecognitionAdapter | null ;
@@ -41,17 +50,20 @@ class SpeechToText extends Widget<SpeechToTextProperties> {
4150
4251 private _actions ! : SpeechToTextActions ;
4352
44- _getDefaultOptions ( ) : SpeechToTextProperties {
53+ _getDefaultOptions ( ) : Properties {
4554 return {
4655 ...super . _getDefaultOptions ( ) ,
47- startIcon : DEFAULT_INITIAL_ICON ,
48- stopIcon : DEFAULT_LISTENING_ICON ,
49- startText : '' ,
50- stopText : '' ,
56+ activeStateEnabled : true ,
5157 customSpeechRecognizer : {
5258 enabled : false ,
5359 isListening : false ,
5460 } ,
61+ hoverStateEnabled : true ,
62+ startIcon : DEFAULT_INITIAL_ICON ,
63+ stopIcon : DEFAULT_LISTENING_ICON ,
64+ startText : '' ,
65+ stopText : '' ,
66+ useInkRipple : false ,
5567 onStartClick : undefined ,
5668 onStopClick : undefined ,
5769 onResult : undefined ,
@@ -106,6 +118,8 @@ class SpeechToText extends Widget<SpeechToTextProperties> {
106118 } ) || noop ;
107119 }
108120
121+ _attachFeedbackEvents ( ) : void { }
122+
109123 private _renderButton ( ) : void {
110124 this . _button = this . _createComponent < Button , ButtonProperties > (
111125 this . $element ( ) ,
@@ -117,26 +131,28 @@ class SpeechToText extends Widget<SpeechToTextProperties> {
117131 private _getButtonOptions ( ) : ButtonProperties {
118132 const {
119133 activeStateEnabled,
134+ disabled,
120135 focusStateEnabled,
136+ height,
137+ hint,
121138 hoverStateEnabled,
122139 stylingMode,
123140 type,
124- disabled ,
141+ useInkRipple ,
125142 width,
126- height,
127- hint,
128143 } = this . option ( ) ;
129144
130145 return {
131- stylingMode,
132- type,
133- disabled,
134- width,
135- height,
136146 activeStateEnabled,
147+ disabled,
137148 focusStateEnabled,
138- hoverStateEnabled ,
149+ height ,
139150 hint,
151+ hoverStateEnabled,
152+ stylingMode,
153+ type,
154+ useInkRipple,
155+ width,
140156 icon : this . _getCurrentIcon ( ) ,
141157 text : this . _getCurrentText ( ) ,
142158 onClick : ( e : ClickEvent ) : void => {
@@ -145,12 +161,41 @@ class SpeechToText extends Widget<SpeechToTextProperties> {
145161 } ;
146162 }
147163
164+ _defaultOptionsRules ( ) : DefaultOptionsRule < Properties > [ ] {
165+ const rules = [
166+ ...super . _defaultOptionsRules ( ) ,
167+ {
168+ device : ( ) : boolean => devices . real ( ) . deviceType === 'desktop' && ! devices . isSimulator ( ) ,
169+ options : {
170+ focusStateEnabled : true ,
171+ } ,
172+ } , {
173+ device : ( ) : boolean => isMaterial ( current ( ) ) ,
174+ options : {
175+ useInkRipple : true ,
176+ } ,
177+ } ,
178+ ] ;
179+
180+ return rules ;
181+ }
182+
148183 private _getCurrentIcon ( ) : string | undefined {
149184 const { startIcon, stopIcon } = this . option ( ) ;
150185
151186 return this . _isListening ( ) ? stopIcon : startIcon ;
152187 }
153188
189+ private _getCurrentAriaLabel ( ) : string {
190+ return this . _isListening ( )
191+ ? messageLocalization . format ( 'dxSpeechToText-ariaLabelStop' )
192+ : messageLocalization . format ( 'dxSpeechToText-ariaLabelStart' ) ;
193+ }
194+
195+ private _getCurrentAriaPressed ( ) : boolean {
196+ return this . _isListening ( ) ;
197+ }
198+
154199 private _getCurrentText ( ) : string {
155200 const { startText, stopText } = this . option ( ) ;
156201
@@ -227,14 +272,18 @@ class SpeechToText extends Widget<SpeechToTextProperties> {
227272 this . _button ?. option ( {
228273 icon : this . _getCurrentIcon ( ) ,
229274 text : this . _getCurrentText ( ) ,
275+ elementAttr : {
276+ 'aria-label' : this . _getCurrentAriaLabel ( ) ,
277+ 'aria-pressed' : this . _getCurrentAriaPressed ( ) ,
278+ } ,
230279 } ) ;
231280 }
232281
233282 private _updateCssClasses ( ) : void {
234283 this . $element ( ) . toggleClass ( SPEECH_TO_TEXT_LISTENING_CLASS , this . _isListening ( ) ) ;
235284 }
236285
237- _optionChanged ( args : OptionChanged < SpeechToTextProperties > ) : void {
286+ _optionChanged ( args : OptionChanged < Properties > ) : void {
238287 const { name, value } = args ;
239288
240289 switch ( name ) {
@@ -246,11 +295,14 @@ class SpeechToText extends Widget<SpeechToTextProperties> {
246295 this . _speechRecognitionAdapter ?. applyConfig ( value ) ;
247296 break ;
248297
298+ case 'activeStateEnabled' :
299+ case 'focusStateEnabled' :
300+ case 'height' :
301+ case 'hint' :
302+ case 'hoverStateEnabled' :
249303 case 'stylingMode' :
250304 case 'type' :
251305 case 'width' :
252- case 'height' :
253- case 'hint' :
254306 this . _button ?. option ( name , value ) ;
255307 break ;
256308
0 commit comments