@@ -14,7 +14,6 @@ import { Color } from 'vs/base/common/color';
1414import { Emitter , Event as BaseEvent } from 'vs/base/common/event' ;
1515import { KeyCode } from 'vs/base/common/keyCodes' ;
1616import { Disposable , IDisposable } from 'vs/base/common/lifecycle' ;
17- import { mixin } from 'vs/base/common/objects' ;
1817import { localize } from 'vs/nls' ;
1918import 'vs/css!./button' ;
2019
@@ -24,22 +23,28 @@ export interface IButtonOptions extends IButtonStyles {
2423 readonly secondary ?: boolean ;
2524}
2625
26+ export type CSSValueString = string ;
27+
2728export interface IButtonStyles {
28- buttonBackground ?: Color ;
29- buttonHoverBackground ?: Color ;
30- buttonForeground ?: Color ;
31- buttonSeparator ?: Color ;
32- buttonSecondaryBackground ?: Color ;
33- buttonSecondaryHoverBackground ?: Color ;
34- buttonSecondaryForeground ?: Color ;
35- buttonBorder ?: Color ;
29+ readonly buttonBackground ?: CSSValueString ;
30+ readonly buttonHoverBackground ?: CSSValueString ;
31+ readonly buttonForeground ?: CSSValueString ;
32+ readonly buttonSeparator ?: CSSValueString ;
33+ readonly buttonSecondaryBackground ?: CSSValueString ;
34+ readonly buttonSecondaryHoverBackground ?: CSSValueString ;
35+ readonly buttonSecondaryForeground ?: CSSValueString ;
36+ readonly buttonBorder ?: CSSValueString ;
3637}
3738
38- const defaultOptions : IButtonStyles = {
39- buttonBackground : Color . fromHex ( '#0E639C' ) ,
40- buttonHoverBackground : Color . fromHex ( '#006BB3' ) ,
41- buttonSeparator : Color . white ,
42- buttonForeground : Color . white
39+ export const defaultOptions : IButtonStyles = {
40+ buttonBackground : '#0E639C' ,
41+ buttonHoverBackground : '#006BB3' ,
42+ buttonSeparator : Color . white . toString ( ) ,
43+ buttonForeground : Color . white . toString ( ) ,
44+ buttonBorder : undefined ,
45+ buttonSecondaryBackground : undefined ,
46+ buttonSecondaryForeground : undefined ,
47+ buttonSecondaryHoverBackground : undefined
4348} ;
4449
4550export interface IButton extends IDisposable {
@@ -48,7 +53,6 @@ export interface IButton extends IDisposable {
4853 label : string ;
4954 icon : CSSIcon ;
5055 enabled : boolean ;
51- style ( styles : IButtonStyles ) : void ;
5256 focus ( ) : void ;
5357 hasFocus ( ) : boolean ;
5458}
@@ -62,40 +66,31 @@ export class Button extends Disposable implements IButton {
6266 protected _element : HTMLElement ;
6367 protected options : IButtonOptions ;
6468
65- private buttonBackground : Color | undefined ;
66- private buttonHoverBackground : Color | undefined ;
67- private buttonForeground : Color | undefined ;
68- private buttonSecondaryBackground : Color | undefined ;
69- private buttonSecondaryHoverBackground : Color | undefined ;
70- private buttonSecondaryForeground : Color | undefined ;
71- private buttonBorder : Color | undefined ;
72-
7369 private _onDidClick = this . _register ( new Emitter < Event > ( ) ) ;
7470 get onDidClick ( ) : BaseEvent < Event > { return this . _onDidClick . event ; }
7571
7672 private focusTracker : IFocusTracker ;
7773
78- constructor ( container : HTMLElement , options ? : IButtonOptions ) {
74+ constructor ( container : HTMLElement , options : IButtonOptions ) {
7975 super ( ) ;
8076
81- this . options = options || Object . create ( null ) ;
82- mixin ( this . options , defaultOptions , false ) ;
83-
84- this . buttonForeground = this . options . buttonForeground ;
85- this . buttonBackground = this . options . buttonBackground ;
86- this . buttonHoverBackground = this . options . buttonHoverBackground ;
87-
88- this . buttonSecondaryForeground = this . options . buttonSecondaryForeground ;
89- this . buttonSecondaryBackground = this . options . buttonSecondaryBackground ;
90- this . buttonSecondaryHoverBackground = this . options . buttonSecondaryHoverBackground ;
91-
92- this . buttonBorder = this . options . buttonBorder ;
77+ this . options = options ;
9378
9479 this . _element = document . createElement ( 'a' ) ;
9580 this . _element . classList . add ( 'monaco-button' ) ;
9681 this . _element . tabIndex = 0 ;
9782 this . _element . setAttribute ( 'role' , 'button' ) ;
9883
84+ const background = options . secondary ? options . buttonSecondaryBackground : options . buttonBackground ;
85+ const foreground = options . secondary ? options . buttonSecondaryForeground : options . buttonForeground ;
86+ const border = options . buttonBorder ;
87+
88+ this . _element . style . color = foreground || '' ;
89+ this . _element . style . backgroundColor = background || '' ;
90+ if ( border ) {
91+ this . _element . style . border = `1px solid ${ border } ` ;
92+ }
93+
9994 container . appendChild ( this . _element ) ;
10095
10196 this . _register ( Gesture . addTarget ( this . _element ) ) ;
@@ -129,65 +124,29 @@ export class Button extends Disposable implements IButton {
129124
130125 this . _register ( addDisposableListener ( this . _element , EventType . MOUSE_OVER , e => {
131126 if ( ! this . _element . classList . contains ( 'disabled' ) ) {
132- this . setHoverBackground ( ) ;
127+ this . updateBackground ( true ) ;
133128 }
134129 } ) ) ;
135130
136131 this . _register ( addDisposableListener ( this . _element , EventType . MOUSE_OUT , e => {
137- this . applyStyles ( ) ; // restore standard styles
132+ this . updateBackground ( false ) ; // restore standard styles
138133 } ) ) ;
139134
140135 // Also set hover background when button is focused for feedback
141136 this . focusTracker = this . _register ( trackFocus ( this . _element ) ) ;
142- this . _register ( this . focusTracker . onDidFocus ( ( ) => { if ( this . enabled ) { this . setHoverBackground ( ) ; } } ) ) ;
143- this . _register ( this . focusTracker . onDidBlur ( ( ) => { if ( this . enabled ) { this . applyStyles ( ) ; } } ) ) ;
144-
145- this . applyStyles ( ) ;
137+ this . _register ( this . focusTracker . onDidFocus ( ( ) => { if ( this . enabled ) { this . updateBackground ( true ) ; } } ) ) ;
138+ this . _register ( this . focusTracker . onDidBlur ( ( ) => { if ( this . enabled ) { this . updateBackground ( false ) ; } } ) ) ;
146139 }
147140
148- private setHoverBackground ( ) : void {
149- let hoverBackground ;
141+ private updateBackground ( hover : boolean ) : void {
142+ let background ;
150143 if ( this . options . secondary ) {
151- hoverBackground = this . buttonSecondaryHoverBackground ? this . buttonSecondaryHoverBackground . toString ( ) : null ;
144+ background = hover ? this . options . buttonSecondaryHoverBackground : this . options . buttonSecondaryBackground ;
152145 } else {
153- hoverBackground = this . buttonHoverBackground ? this . buttonHoverBackground . toString ( ) : null ;
154- }
155- if ( hoverBackground ) {
156- this . _element . style . backgroundColor = hoverBackground ;
146+ background = hover ? this . options . buttonHoverBackground : this . options . buttonBackground ;
157147 }
158- }
159-
160- style ( styles : IButtonStyles ) : void {
161- this . buttonForeground = styles . buttonForeground ;
162- this . buttonBackground = styles . buttonBackground ;
163- this . buttonHoverBackground = styles . buttonHoverBackground ;
164- this . buttonSecondaryForeground = styles . buttonSecondaryForeground ;
165- this . buttonSecondaryBackground = styles . buttonSecondaryBackground ;
166- this . buttonSecondaryHoverBackground = styles . buttonSecondaryHoverBackground ;
167- this . buttonBorder = styles . buttonBorder ;
168-
169- this . applyStyles ( ) ;
170- }
171-
172- private applyStyles ( ) : void {
173- if ( this . _element ) {
174- let background , foreground ;
175- if ( this . options . secondary ) {
176- foreground = this . buttonSecondaryForeground ? this . buttonSecondaryForeground . toString ( ) : '' ;
177- background = this . buttonSecondaryBackground ? this . buttonSecondaryBackground . toString ( ) : '' ;
178- } else {
179- foreground = this . buttonForeground ? this . buttonForeground . toString ( ) : '' ;
180- background = this . buttonBackground ? this . buttonBackground . toString ( ) : '' ;
181- }
182-
183- const border = this . buttonBorder ? this . buttonBorder . toString ( ) : '' ;
184-
185- this . _element . style . color = foreground ;
148+ if ( background ) {
186149 this . _element . style . backgroundColor = background ;
187-
188- this . _element . style . borderWidth = border ? '1px' : '' ;
189- this . _element . style . borderStyle = border ? 'solid' : '' ;
190- this . _element . style . borderColor = border ;
191150 }
192151 }
193152
@@ -293,6 +252,21 @@ export class ButtonWithDropdown extends Disposable implements IButton {
293252 this . separatorContainer . appendChild ( this . separator ) ;
294253 this . element . appendChild ( this . separatorContainer ) ;
295254
255+ // Separator styles
256+ const border = options . buttonBorder ;
257+ if ( border ) {
258+ this . separatorContainer . style . borderTopWidth = '1px' ;
259+ this . separatorContainer . style . borderTopStyle = 'solid' ;
260+ this . separatorContainer . style . borderTopColor = border ;
261+
262+ this . separatorContainer . style . borderBottomWidth = '1px' ;
263+ this . separatorContainer . style . borderBottomStyle = 'solid' ;
264+ this . separatorContainer . style . borderBottomColor = border ;
265+ }
266+ this . separatorContainer . style . backgroundColor = options . buttonBackground ?. toString ( ) ?? '' ;
267+ this . separator . style . backgroundColor = options . buttonSeparator ?. toString ( ) ?? '' ;
268+
269+
296270 this . dropdownButton = this . _register ( new Button ( this . element , { ...options , title : false , supportIcons : true } ) ) ;
297271 this . dropdownButton . element . title = localize ( "button dropdown more actions" , 'More Actions...' ) ;
298272 this . dropdownButton . element . setAttribute ( 'aria-haspopup' , 'true' ) ;
@@ -330,25 +304,6 @@ export class ButtonWithDropdown extends Disposable implements IButton {
330304 return this . button . enabled ;
331305 }
332306
333- style ( styles : IButtonStyles ) : void {
334- this . button . style ( styles ) ;
335- this . dropdownButton . style ( styles ) ;
336-
337- // Separator
338- const border = styles . buttonBorder ? styles . buttonBorder . toString ( ) : '' ;
339-
340- this . separatorContainer . style . borderTopWidth = border ? '1px' : '' ;
341- this . separatorContainer . style . borderTopStyle = border ? 'solid' : '' ;
342- this . separatorContainer . style . borderTopColor = border ;
343-
344- this . separatorContainer . style . borderBottomWidth = border ? '1px' : '' ;
345- this . separatorContainer . style . borderBottomStyle = border ? 'solid' : '' ;
346- this . separatorContainer . style . borderBottomColor = border ;
347-
348- this . separatorContainer . style . backgroundColor = styles . buttonBackground ?. toString ( ) ?? '' ;
349- this . separator . style . backgroundColor = styles . buttonSeparator ?. toString ( ) ?? '' ;
350- }
351-
352307 focus ( ) : void {
353308 this . button . focus ( ) ;
354309 }
@@ -363,7 +318,7 @@ export class ButtonWithDescription extends Button implements IButtonWithDescript
363318 private _labelElement : HTMLElement ;
364319 private _descriptionElement : HTMLElement ;
365320
366- constructor ( container : HTMLElement , options ? : IButtonOptions ) {
321+ constructor ( container : HTMLElement , options : IButtonOptions ) {
367322 super ( container , options ) ;
368323
369324 this . _element . classList . add ( 'monaco-description-button' ) ;
@@ -412,13 +367,13 @@ export class ButtonBar extends Disposable {
412367 return this . _buttons ;
413368 }
414369
415- addButton ( options ? : IButtonOptions ) : IButton {
370+ addButton ( options : IButtonOptions ) : IButton {
416371 const button = this . _register ( new Button ( this . container , options ) ) ;
417372 this . pushButton ( button ) ;
418373 return button ;
419374 }
420375
421- addButtonWithDescription ( options ? : IButtonOptions ) : IButtonWithDescription {
376+ addButtonWithDescription ( options : IButtonOptions ) : IButtonWithDescription {
422377 const button = this . _register ( new ButtonWithDescription ( this . container , options ) ) ;
423378 this . pushButton ( button ) ;
424379 return button ;
0 commit comments