UNPKG

@atlassian/aui

Version:

Atlassian User Interface library

94 lines (76 loc) 3.5 kB
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; };