Selectmenu: Add classes option

Ref #7053
Ref gh-1411
This commit is contained in:
Alexander Schmitz 2014-12-03 11:26:46 -05:00
parent 2a7873dd57
commit 3483486a15
4 changed files with 68 additions and 40 deletions

View File

@ -9,6 +9,7 @@
<script src="../../../external/qunit/qunit.js"></script>
<script src="../../../external/jquery-simulate/jquery.simulate.js"></script>
<script src="../testsuite.js"></script>
<script src="../../../external/qunit-assert-classes/qunit-assert-classes.js"></script>
<script>
TestHelpers.loadResources({
css: [ "core", "menu" , "selectmenu" ],

View File

@ -1,7 +1,10 @@
TestHelpers.commonWidgetTests( "selectmenu", {
defaults: {
appendTo: null,
classes: {},
classes: {
"ui-selectmenu-button-open": "ui-corner-top",
"ui-selectmenu-button-closed": "ui-corner-all"
},
disabled: null,
icons: {
button: "ui-icon-triangle-1-s"

View File

@ -2,6 +2,21 @@
module( "selectmenu: core" );
test( "markup structure", function( assert ) {
expect( 4 );
var element = $( "#files" ).selectmenu(),
button = element.selectmenu( "widget" ),
menu = element.selectmenu( "menuWidget" ),
menuWrap = menu.parent();
assert.hasClasses( button,
"ui-selectmenu-button ui-selectmenu-button-closed ui-widget" );
assert.lacksClasses( button, "ui-selectmenu-button-open" );
assert.hasClasses( menuWrap, "ui-selectmenu-menu" );
assert.lacksClasses( menuWrap, "ui-selectmenu-menu-open" );
});
asyncTest( "accessibility", function() {
var wrappers, button, menu,
element = $( "#speed" ).attr( "title", "A demo title" );

View File

@ -39,6 +39,10 @@ return $.widget( "ui.selectmenu", {
defaultElement: "<select>",
options: {
appendTo: null,
classes: {
"ui-selectmenu-button-open": "ui-corner-top",
"ui-selectmenu-button-closed": "ui-corner-all"
},
disabled: null,
icons: {
button: "ui-icon-triangle-1-s"
@ -78,7 +82,8 @@ return $.widget( "ui.selectmenu", {
},
_drawButton: function() {
var that = this,
var icon,
that = this,
item = this._parseOption(
this.element.find( "option:selected" ),
this.element[ 0 ].selectedIndex
@ -98,7 +103,6 @@ return $.widget( "ui.selectmenu", {
// Create button
this.button = $( "<span>", {
"class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
tabindex: this.options.disabled ? -1 : 0,
id: this.ids.button,
role: "combobox",
@ -110,10 +114,11 @@ return $.widget( "ui.selectmenu", {
})
.insertAfter( this.element );
$( "<span>", {
"class": "ui-icon " + this.options.icons.button
})
.prependTo( this.button );
this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
"ui-widget ui-state-default" );
icon = $( "<span>" ).prependTo( this.button );
this._addClass( icon, null, "ui-icon " + this.options.icons.button );
this.buttonItem = this._renderButtonItem( item )
.appendTo( this.button );
@ -146,15 +151,16 @@ return $.widget( "ui.selectmenu", {
});
// Wrap menu
this.menuWrap = $( "<div>", {
"class": "ui-selectmenu-menu ui-front"
})
.append( this.menu )
.appendTo( this._appendTo() );
this.menuWrap = $( "<div>" ).append( this.menu );
this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
this.menuWrap.appendTo( this._appendTo() );
// Initialize menu widget
this.menuInstance = this.menu
.menu({
classes: {
"ui-menu": "ui-corner-bottom"
},
role: "listbox",
select: function( event, ui ) {
event.preventDefault();
@ -184,11 +190,6 @@ return $.widget( "ui.selectmenu", {
})
.menu( "instance" );
// Adjust menu styles to dropdown
this.menu
.addClass( "ui-corner-bottom" )
.removeClass( "ui-corner-all" );
// Don't close the menu on mouseleave
this.menuInstance._off( this.menu, "mouseleave" );
@ -258,7 +259,7 @@ return $.widget( "ui.selectmenu", {
} else {
// Menu clears focus on close, reset focus to selected item
this.menu.find( ".ui-state-active" ).removeClass( "ui-state-active" );
this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
this.menuInstance.focus( null, this._getSelectedItem() );
}
@ -304,10 +305,10 @@ return $.widget( "ui.selectmenu", {
},
_renderButtonItem: function( item ) {
var buttonItem = $( "<span>", {
"class": "ui-selectmenu-text"
});
var buttonItem = $( "<span>" );
this._setText( buttonItem, item.label );
this._addClass( buttonItem, "ui-selectmenu-text" );
return buttonItem;
},
@ -317,15 +318,18 @@ return $.widget( "ui.selectmenu", {
currentOptgroup = "";
$.each( items, function( index, item ) {
var li;
if ( item.optgroup !== currentOptgroup ) {
$( "<li>", {
"class": "ui-selectmenu-optgroup ui-menu-divider" +
li = $( "<li>", {
text: item.optgroup
});
that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
( item.element.parent( "optgroup" ).prop( "disabled" ) ?
" ui-state-disabled" :
"" ),
text: item.optgroup
})
.appendTo( ul );
"" ) );
li.appendTo( ul );
currentOptgroup = item.optgroup;
}
@ -345,7 +349,7 @@ return $.widget( "ui.selectmenu", {
});
if ( item.disabled ) {
li.addClass( "ui-state-disabled" );
this._addClass( li, null, "ui-state-disabled" );
}
this._setText( wrapper, item.label );
@ -542,9 +546,9 @@ return $.widget( "ui.selectmenu", {
_setOption: function( key, value ) {
if ( key === "icons" ) {
this.button.find( "span.ui-icon" )
.removeClass( this.options.icons.button )
.addClass( value.button );
var icon = this.button.find( "span.ui-icon" );
this._removeClass( icon, null, this.options.icons.button )
._addClass( icon, null, value.button );
}
this._super( key, value );
@ -555,9 +559,8 @@ return $.widget( "ui.selectmenu", {
if ( key === "disabled" ) {
this.menuInstance.option( "disabled", value );
this.button
.toggleClass( "ui-state-disabled", value )
.attr( "aria-disabled", value );
this.button.attr( "aria-disabled", value );
this._toggleClass( this.button, null, "ui-state-disabled", value );
this.element.prop( "disabled", value );
if ( value ) {
@ -594,11 +597,17 @@ return $.widget( "ui.selectmenu", {
},
_toggleAttr: function() {
this.button
.toggleClass( "ui-corner-top", this.isOpen )
.toggleClass( "ui-corner-all", !this.isOpen )
.attr( "aria-expanded", this.isOpen );
this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
this.button.attr( "aria-expanded", this.isOpen );
// We can't use two _toggleClass() calls here, because we need to make sure
// we always remove classes first and add them second, otherwise if both classes have the
// same theme class, it will be removed after we add it.
this._removeClass( this.button, "ui-selectmenu-button-" +
( this.isOpen ? "closed" : "open" ) )
._addClass( this.button, "ui-selectmenu-button-" +
( this.isOpen ? "open" : "closed" ) )
._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
this.menu.attr( "aria-hidden", !this.isOpen );
},