Refactoring focus in color buttons

This commit is contained in:
Julia Radzhabova 2021-09-17 18:16:00 +03:00
parent b50bff460e
commit 2f868c9780
3 changed files with 99 additions and 47 deletions

View file

@ -59,8 +59,7 @@ define([
el: this.cmpEl.find('#' + this.menu.id + '-color-menu'),
transparent: this.options.transparent,
value: color,
colors: colors,
parentButton: this
colors: colors
});
this.colorPicker.on('select', _.bind(this.onColorSelect, this));
this.cmpEl.find('#' + this.menu.id + '-color-new').on('click', _.bind(this.addNewColor, this));
@ -69,6 +68,7 @@ define([
this.colorAuto = this.cmpEl.find('#' + this.menu.id + '-color-auto > a');
(color == 'auto') && this.setAutoColor(true);
}
this.initInnerMenu();
}
return this.colorPicker;
},
@ -105,7 +105,7 @@ define([
}
])
});
this.colorPicker && (this.colorPicker.parentButton = menu);
this.initInnerMenu();
var me = this;
menu.on('keydown:before', _.bind(this.onBeforeKeyDown, this));
menu.on('show:after', function(menu) {
@ -123,6 +123,14 @@ define([
return this.menu;
},
initInnerMenu: function() {
if (!this.colorPicker || typeof this.menu !== 'object') return;
var index = (this.options.additionalItems || []).length + (this.options.auto ? 2 : 0);
this.colorPicker.outerMenu = {menu: this.menu, index: index};
this.menu.setInnerMenu([{menu: this.colorPicker, index: index}]);
},
setMenu: function (m) {
m = m || this.getMenu();
Common.UI.Button.prototype.setMenu.call(this, m);
@ -174,49 +182,12 @@ define([
$('button', this.cmpEl).click();
return false;
}
if (e.keyCode == Common.UI.Keys.RETURN) {
var li = $(e.target).closest('li');
if (li.length>0) {
e.preventDefault();
e.stopPropagation();
li.click();
}
Common.UI.Menu.Manager.hideAll();
} else if (e.namespace!=="after.bs.dropdown" && (e.keyCode == Common.UI.Keys.DOWN || e.keyCode == Common.UI.Keys.UP)) {
var $items = $('> [role=menu] > li:not(.divider):not(.disabled):visible', menu.$el).find('> a');
if (!$items.length) return;
var index = $items.index($items.filter(':focus')),
me = this,
pickerIndex = $items.length-1 ;
if (e.keyCode == Common.UI.Keys.DOWN && (index==pickerIndex-1 || pickerIndex==0) || e.keyCode == Common.UI.Keys.UP && index==pickerIndex) {
e.preventDefault();
e.stopPropagation();
_.delay(function() {
me.focusInner(e);
}, 10);
}
}
},
isMenuOpen: function() {
return this.cmpEl.hasClass('open');
},
focusInner: function(e) {
if (!this.colorPicker) return;
this.colorPicker.focus(e.keyCode == Common.UI.Keys.DOWN ? 'first' : 'last');
},
focusOuter: function(e) {
if (!this.menu) return;
var $items = $('> [role=menu] > li:not(.divider):not(.disabled):visible', this.menu.$el).find('> a');
if (!$items.length) return;
$items.eq(e.keyCode == Common.UI.Keys.UP ? $items.length-2 : $items.length-1).focus();
},
textNewColor: 'Add New Custom Color',
textAutoColor: 'Automatic'

View file

@ -267,6 +267,7 @@ define([
this.parentEl.on('hide.bs.dropdown', _.bind(me.onBeforeHideMenu, me));
this.parentEl.on('hidden.bs.dropdown', _.bind(me.onAfterHideMenu, me));
this.parentEl.on('keydown.after.bs.dropdown', _.bind(me.onAfterKeydownMenu, me));
this.options.innerMenus && this.on('keydown:before', _.bind(me.onBeforeKeyDown, me));
menuRoot.hover(
function(e) { me.isOver = true;},
@ -491,6 +492,83 @@ define([
}
},
onBeforeKeyDown: function(menu, e) {
if (e.keyCode == Common.UI.Keys.RETURN) {
var li = $(e.target).closest('li');
if (li.length>0) {
e.preventDefault();
e.stopPropagation();
li.click();
}
Common.UI.Menu.Manager.hideAll();
} else if (e.namespace!=="after.bs.dropdown" && (e.keyCode == Common.UI.Keys.DOWN || e.keyCode == Common.UI.Keys.UP)) {
var innerMenu = this.findInnerMenu(e.keyCode);
if (innerMenu && innerMenu.focusInner) {
e.preventDefault();
e.stopPropagation();
_.delay(function() {
innerMenu.focusInner(e);
}, 10);
}
}
},
setInnerMenu: function(menus) {
if (this.options.innerMenus || !menus) return;
this.options.innerMenus = menus;
this.options.innerMenus && this.on('keydown:before', _.bind(this.onBeforeKeyDown, this));
},
findInnerMenu: function(direction, index, findOuter) {
if (!this.options.innerMenus) return;
var $allItems = $('> li', this.menuRoot),
$liItems = $('> li:not(.divider):not(.disabled):visible', this.menuRoot),
length = $liItems.length;
if (!length) return;
var step = 0;
while (step<length) {
var focusedIndex = (index!==undefined) ? $liItems.index($allItems.eq(index)) : $liItems.index($liItems.find('> a').filter(':focus').parent());
var checkedIndex = (direction == Common.UI.Keys.DOWN) ? (focusedIndex<length-1 ? focusedIndex+1 : 0) : (focusedIndex>0 ? focusedIndex-1 : length-1),
checkedItem = $liItems.eq(checkedIndex);
index = $allItems.index(checkedItem);
for (var i=0; i<this.options.innerMenus.length; i++) {
var item = this.options.innerMenus[i];
if (item && item.menu && item.index==index) {
return item.menu;
}
}
if (checkedItem.find('> a').length>0)
return findOuter ? checkedItem : undefined;
step++;
}
},
focusInner: function(e) {
if (e.keyCode == Common.UI.Keys.UP)
this.items[this.items.length-1].cmpEl.find('> a').focus();
else
this.items[0].cmpEl.find('> a').focus();
},
focusOuter: function(e, index) {
var innerMenu = this.findInnerMenu(e.keyCode, index, true);
if (innerMenu && innerMenu.focusInner) {
_.delay(function() {
innerMenu.focusInner(e);
}, 10);
} else if (innerMenu) {
innerMenu.find('> a').focus();
} else {
var $items = $('> li:not(.divider):not(.disabled):visible', this.menuRoot).find('> a'),
length = $items.length;
length && $items.eq(e.keyCode == Common.UI.Keys.UP ? (index<0 ? length-1 : index) : (index>=length-1 ? 0 : index+1)).focus();
}
},
onItemClick: function(item, e) {
if (!item.menu) this.isOver = false;
if (item.options.stopPropagation) {

View file

@ -105,7 +105,6 @@ define([
this.colors = me.options.colors || this.generateColorData(me.options.themecolors, me.options.effects, me.options.standardcolors, me.options.transparent);
this.enableKeyEvents= me.options.enableKeyEvents;
this.tabindex = me.options.tabindex || 0;
this.parentButton = me.options.parentButton;
this.lastSelectedIdx = -1;
me.colorItems = [];
@ -516,8 +515,8 @@ define([
var rec = this.getSelectedColor();
if (data.keyCode==Common.UI.Keys.RETURN) {
rec && this.selectByIndex(rec.index);
if (this.parentButton && this.parentButton.menu)
this.parentButton.menu.hide();
if (this.outerMenu && this.outerMenu.menu)
this.outerMenu.menu.hide();
} else {
var idx = rec ? rec.index : -1;
if (idx<0) {
@ -544,9 +543,9 @@ define([
idx = this._layoutParams.itemsIndexes[topIdx][leftIdx];
}
} else if (data.keyCode==Common.UI.Keys.UP) {
if (topIdx==0 && this.parentButton) {
if (topIdx==0 && this.outerMenu && this.outerMenu.menu) {
this.clearSelection(true);
this.parentButton.focusOuter(data);
this.outerMenu.menu.focusOuter(data, this.outerMenu.index);
} else
while (idx===undefined) {
topIdx--;
@ -554,9 +553,9 @@ define([
idx = this._layoutParams.itemsIndexes[topIdx][leftIdx];
}
} else {
if (topIdx==this._layoutParams.rows-1 && this.parentButton) {
if (topIdx==this._layoutParams.rows-1 && this.outerMenu && this.outerMenu.menu) {
this.clearSelection(true);
this.parentButton.focusOuter(data);
this.outerMenu.menu.focusOuter(data, this.outerMenu.index);
} else
while (idx===undefined) {
topIdx++;
@ -635,6 +634,10 @@ define([
this.selectByIndex(index, true);
},
focusInner: function(e) {
this.focus(e.keyCode == Common.UI.Keys.DOWN ? 'first' : 'last');
},
textThemeColors : 'Theme Colors',
textStandartColors : 'Standart Colors'
}, Common.UI.ThemeColorPalette || {}));