UNPKG

@atlassian/aui

Version:

Atlassian User Interface library

178 lines (147 loc) 5.14 kB
import $ from './jquery'; import { defaults } from 'underscore'; import { recomputeStyle } from './internal/animation'; import amdify from './internal/amdify'; import globalize from './internal/globalize'; import keyCode from './key-code'; import CustomEvent from './polyfills/custom-event'; import escapeHtml from './escape-html'; import { CLOSE_BUTTON } from './close-button'; import { FOCUSABLE_QUERY } from './internal/a11y/focusable-query'; import getFocusManager from './focus-manager'; import { I18n } from './i18n'; const AUTO_CLOSE_TIME = 8000; const ID_FLAG_CONTAINER = 'aui-flag-container'; const DEFAULT_OPTIONS = { body: '', close: 'manual', title: '', type: 'info', duration: AUTO_CLOSE_TIME, ariaLive: 'polite', }; function flag(flagOptions) { const options = defaults(flagOptions, DEFAULT_OPTIONS); options.title = (options.title || '').toString().trim(); const $flag = renderFlagElement(options); extendFlagElement($flag); if (options.close === 'auto') { makeCloseable($flag); if ($flag.attr('role') === 'alert') { makeAutoClosable($flag, options.duration); } } else if (options.close === 'manual') { makeCloseable($flag); } handleFlagContainer(); insertFlag($flag); setTimeout(function () { if ($flag.attr('role') === 'alertdialog') { getFocusManager.global.enter($flag); } }, 0); return $flag.get(0); } function extendFlagElement($flag) { const flag = $flag[0]; flag.close = function () { closeFlag($flag); }; } function getDefaultAriaLabelForFlagType(type) { switch (type) { case 'success': return I18n.getText('aui.flag.default-aria-label.success'); case 'warning': return I18n.getText('aui.flag.default-aria-label.warning'); case 'error': return I18n.getText('aui.flag.default-aria-label.error'); default: return I18n.getText('aui.flag.default-aria-label.info'); } } function renderFlagElement({ body, title, close, type, ariaLive, ariaLabel, ariaDescription }) { const titleHtml = title ? `<p class="title"><strong>${escapeHtml(title)}</strong></p>` : ''; const html = `<div class="aui-message">${titleHtml}</div>`; if (!ariaLabel) { ariaLabel = getDefaultAriaLabelForFlagType(type); } if (!ariaDescription) { ariaDescription = ''; } const $message = $(html) .append($.parseHTML(body || '')) .addClass(close === 'never' ? '' : 'closeable') .addClass(`aui-message-${type}`); const isFocusable = $message.find(FOCUSABLE_QUERY).length > 0; const ariaRole = isFocusable ? 'alertdialog' : 'alert'; return $('<div class="aui-flag"></div>') .attr({ 'aria-label': escapeHtml(ariaLabel), 'aria-hidden': 'false', 'aria-live': escapeHtml(ariaLive), 'role': ariaRole, ...(isFocusable ? { 'data-aui-focus-selector': FOCUSABLE_QUERY.split(', ') .map((item) => `.aui-message ${item}`) .join(', '), 'data-aui-focus': 'true', } : {}), ...(!!ariaDescription ? { 'aria-description': escapeHtml(ariaDescription) } : {}), }) .append($message); } function makeCloseable($flag) { const $icon = $(CLOSE_BUTTON); $icon.on('click', function () { closeFlag($flag); }); $icon.on('keypress', function (e) { if (e.which === keyCode.ENTER || e.which === keyCode.SPACE) { closeFlag($flag); e.preventDefault(); } }); return $flag.find('.aui-message').append($icon)[0]; } function makeAutoClosable($flag, duration) { $flag.find('.aui-message').addClass('aui-will-close'); setTimeout(function () { $flag[0].close(); }, duration); } function closeFlag($flagToClose) { const flag = $flagToClose.get(0); if ($flagToClose.attr('role') === 'alertdialog') { getFocusManager.global.exit($flagToClose); } flag.removeAttribute('open'); flag.setAttribute('inert', ''); flag.setAttribute('aria-hidden', true); flag.style.display = 'none'; flag.dispatchEvent(new CustomEvent('aui-flag-close', { bubbles: true })); return flag; } function handleFlagContainer() { const container = findContainer(); if (container) { const closedFlags = container.querySelectorAll('.aui-flag:not([open])'); Array.from(closedFlags).map((flag) => flag.parentNode.removeChild(flag)); } else { $('body').prepend('<div id="' + ID_FLAG_CONTAINER + '"></div>'); } } function findContainer() { return document.getElementById(ID_FLAG_CONTAINER); } function insertFlag($flag) { const flagContainer = findContainer(); $flag.appendTo(flagContainer); recomputeStyle($flag); $flag.removeAttr('hidden').attr('open', ''); } amdify('aui/flag', flag); globalize('flag', flag); export default flag;