@atlassian/aui
Version:
Atlassian User Interface library
94 lines (76 loc) • 3.5 kB
JavaScript
import $ from './jquery';
import '../../js-vendor/jquery/plugins/jquery.select2';
/**
* Wraps a vanilla Select2 with ADG _style_, as an auiSelect2 method on jQuery objects.
*
* @since 5.2
*/
/**
* We make a copy of the original select2 so that later we might re-specify $.fn.auiSelect2 as $.fn.select2. That
* way, calling code will be able to call $thing.select2() as if they were calling the original library,
* and ADG styling will just magically happen.
*/
const originalSelect2 = $.fn.select2;
// AUI-specific classes
const auiContainer = 'aui-select2-container';
const auiDropdown = 'aui-select2-drop aui-dropdown2';
const auiHasAvatar = 'aui-has-avatar';
$.fn.auiSelect2 = function (first) {
let updatedArgs;
if ($.isPlainObject(first)) {
const auiOpts = $.extend({}, first);
const auiAvatarClass = auiOpts.hasAvatar ? ' ' + auiHasAvatar : '';
//add our classes in addition to those the caller specified
auiOpts.containerCssClass = auiContainer + auiAvatarClass + (auiOpts.containerCssClass ? ' ' + auiOpts.containerCssClass : '');
auiOpts.dropdownCssClass = auiDropdown + auiAvatarClass + (auiOpts.dropdownCssClass ? ' ' + auiOpts.dropdownCssClass : '');
updatedArgs = Array.prototype.slice.call(arguments, 1);
updatedArgs.unshift(auiOpts);
} else if (!arguments.length) {
updatedArgs = [{
containerCssClass: auiContainer,
dropdownCssClass: auiDropdown
}];
} else {
updatedArgs = arguments;
}
const result = originalSelect2.apply(this, updatedArgs);
const select2Instance = this;
const searchLabel = updatedArgs[0].searchLabel;
select2Instance.on('select2-open', function () {
const $selectInput = $(this);
if (updatedArgs[0].multiple || $selectInput.attr('multiple')) {
// This is a multi-select, exiting
return;
}
const $selectDropdown = $selectInput.select2('dropdown')
if (searchLabel) {
$selectDropdown.find('.select2-search label').text(searchLabel);
}
// AUI-5461: when single select dropdown opens up, the first option is
// instantly focused, making SRs announce it, while skipping the search field
$selectDropdown.find('.select2-search .select2-input').attr('aria-activedescendant', '');
});
select2Instance.on('select2-focus', function () {
const $selectInput = $(this);
const $container = $selectInput.parent().find('.select2-container');
if (updatedArgs[0].multiple || $selectInput.attr('multiple')) {
if (searchLabel) {
$container.find('.select2-search-field label').text(searchLabel);
}
return;
}
const $focusserLabel = $container.find('label');
if ($focusserLabel.attr('id')) {
// The id is already assigned, exiting
return;
}
// AUI-5462: when single select is initialized, the selected option container is
// linked to the button via aria-labelledby, preventing SRs from reading its label
const $focusserInput = $container.find('.select2-focusser');
const labelId = $focusserInput.attr('id') + '-label';
const ariaLabelledby = $focusserInput.attr('aria-labelledby');
$focusserLabel.attr('id', labelId);
$focusserInput.attr('aria-labelledby', labelId + ' ' + ariaLabelledby);
});
return result;
};