@atlassian/aui
Version:
Atlassian User Interface library
166 lines (130 loc) • 5.84 kB
JavaScript
import skate from './internal/skate';
const DEFAULT_SIZE = 'medium';
const sizes = {xsmall: 16, small: 24, medium: 32, large: 48, xlarge: 64, xxlarge: 96, xxxlarge: 128};
let buttonDropdownIsActive = false;
const setDefaultSizeValue = (value) => {
return Object.keys(sizes).includes(value) ? value : DEFAULT_SIZE;
}
const setAvatarGroupSize = (element, newValue, oldValue) => {
element.classList.remove(`aui-avatar-group-${oldValue}`);
element.classList.add(`aui-avatar-group-${newValue}`);
}
const setLeftPosition = (size, divisionNum, multiplyNum) => {
return `${(sizes[size] - sizes[size] / divisionNum) * multiplyNum}px`;
}
const addAvatarGroupStyle = (element, size, multiplyNum) => {
element.setAttribute('size', size);
element.classList.add('aui-avatar-group-item');
element.style.left = setLeftPosition(size, 4, multiplyNum);
element.style.zIndex = `${5 - multiplyNum}`;
}
const setBadgedDropdownItem = (element) => {
const avatars = element.parentNode.querySelectorAll('aui-avatar');
const badgedDropdown = element.parentNode.querySelector('.aui-avatar-group-dropdown')
const hiddenAvatarsList = [... avatars].slice(4);
if (!buttonDropdownIsActive) {
buttonDropdownIsActive = true;
hiddenAvatarsList.forEach(avatar => {
const avatarItemSrc = avatar.getAttribute('src');
const avatarItemAlt = avatar.getAttribute('alt');
const avatarItemTitle = avatar.getAttribute('title');
const avatarWrapper = document.createElement('span');
avatarWrapper.setAttribute('class', 'aui-avatar-group-dropdown-item');
if (avatarItemSrc) {
avatarWrapper.innerHTML = `<aui-avatar id="avatar-item" src=${avatarItemSrc} alt=${avatarItemAlt} title=${avatarItemTitle}></aui-avatar>`;
} else {
avatarWrapper.innerHTML = '<aui-avatar></aui-avatar>';
}
badgedDropdown.appendChild(avatarWrapper);
});
} else {
buttonDropdownIsActive = false;
hiddenAvatarsList.forEach(()=> {
const dropdownItems = document.querySelector('.aui-avatar-group-dropdown-item');
if (dropdownItems) {dropdownItems.remove();}
});
}
}
const handleClickOnBadged = (element) => {
const badgedDropdown = element.parentNode.querySelector('.aui-avatar-group-dropdown')
badgedDropdown.classList.toggle('aui-avatar-group-dropdown-show');
setBadgedDropdownItem(element);
}
const createAvatarGroupBadged = (element, size, avatars, amount) => {
const oldBadged = element.querySelector('.aui-avatar-group-badged');
if (oldBadged) {oldBadged.remove()};
const oldBadgedDropdown = element.querySelector('.aui-avatar-group-dropdown')
if (oldBadgedDropdown) {oldBadgedDropdown.remove()}
const multiplier = avatars.length - amount;
const groupBadged = document.createElement('button');
groupBadged.classList.add('aui-avatar-group-badged', 'aui-avatar-inner');
groupBadged.style.left = setLeftPosition(size, 4.5, multiplier);
groupBadged.innerText = `+${amount}`;
element.appendChild(groupBadged);
groupBadged.addEventListener('click', () => handleClickOnBadged(groupBadged))
const badgedDropdown = document.createElement('div');
badgedDropdown.classList.add('aui-avatar-group-dropdown');
badgedDropdown.style.left = setLeftPosition(size, 4.5, multiplier);
element.appendChild(badgedDropdown);
}
const tidyUpAvatarGroup = (element, size) => {
const avatars = element.querySelectorAll('aui-avatar');
let amountItems = avatars.length - 4;
avatars.forEach((avatar, index) => {
avatar.classList.toggle('aui-avatar-group-item-hidden', index >= 4);
addAvatarGroupStyle(avatar, size, index);
});
if (amountItems > 0) {
createAvatarGroupBadged(element, size, avatars, amountItems);
} else {
const badged = element.querySelector('.aui-avatar-group-badged');
if (badged) {badged.remove();}
}
}
const AvatarGroupEl = skate('aui-avatar-group', {
attributes: {
size: {
value: DEFAULT_SIZE,
fallback(element, { newValue , oldValue }) {
let value = setDefaultSizeValue(newValue);
skate.init(element);
setAvatarGroupSize(element, value, oldValue);
tidyUpAvatarGroup(element, value);
}
}
},
created(element) {
const avatarGroupSize = element.getAttribute('size')
const value = setDefaultSizeValue(avatarGroupSize);
element.className = 'aui-avatar-group';
setAvatarGroupSize(element, value);
}
});
const wasNodeRemoved = (mutation, target) => {
return mutation.removedNodes.length > 0 && target.classList.contains('aui-avatar-group') && mutation.removedNodes[0].classList.contains('aui-avatar-group-item');
}
const wasNodeAdded = (mutation, target) => {
return mutation.addedNodes.length > 0 && target.classList.contains('aui-avatar-group') && mutation.addedNodes[0].classList.contains('aui-avatar');
}
const mutationObserver = new MutationObserver(function(mutation) {
mutation.forEach(function(mutation) {
const target = mutation.target;
if (wasNodeRemoved(mutation, target)) {
tidyUpAvatarGroup(target, target.getAttribute('size'));
}
if (wasNodeAdded(mutation, target)) {
setTimeout(() => {
tidyUpAvatarGroup(target, target.getAttribute('size'));
}, 0);
}
});
});
mutationObserver.observe(document.documentElement, {
attributes: false,
characterData: true,
childList: true,
subtree: true,
attributeOldValue: false,
characterDataOldValue: false
});
export { AvatarGroupEl };