optimize style sheets, support tabIndex in popup

This commit is contained in:
2023-04-21 10:59:56 +08:00
parent cbdb2c7868
commit c4316e7e52
16 changed files with 235 additions and 199 deletions

View File

@ -110,6 +110,8 @@ class Popup {
mask.classList.add('popup-transparent');
}
const container = createElement('div', 'popup-container');
let tabIndex = Math.max.apply(null, [...document.querySelectorAll('[tabindex]')].map(e => e.tabIndex ?? 0));
container.tabIndex = tabIndex + 1;
const close = () => {
mask.classList.add('popup-active');
mask.style.opacity = 0;
@ -155,7 +157,13 @@ class Popup {
}
if (this.#option.collapsable === true) {
const collapse = createIcon('fa-regular', 'compress-alt');
collapse.tabIndex = tabIndex + 2;
collapse.classList.add('icon-expand');
collapse.addEventListener('keypress', e => {
if (e.key === ' ' || e.key === 'Enter') {
collapse.dispatchEvent(new MouseEvent('click'));
}
});
collapse.addEventListener('click', () => {
if (container.classList.contains('popup-collapse')) {
const bounds = this.#bounds;
@ -176,6 +184,12 @@ class Popup {
header.appendChild(collapse);
}
const cancel = createIcon('fa-regular', 'times');
cancel.tabIndex = tabIndex + 3;
cancel.addEventListener('keypress', e => {
if (e.key === ' ' || e.key === 'Enter') {
close();
}
});
cancel.addEventListener('click', () => close());
header.appendChild(cancel);
}),
@ -184,9 +198,15 @@ class Popup {
))
);
if (Array.isArray(this.#option.buttons)) {
tabIndex = Math.max.apply(null, [...container.querySelectorAll('[tabindex]')].map(e => e.tabIndex ?? 0));
container.appendChild(
createElement('div', 'popup-footer', ...this.#option.buttons.map(b => {
const button = createElement('div', 'popup-button');
createElement('div', 'popup-footer', ...this.#option.buttons.map((b, i) => {
const button = createElement('button', 'popup-button');
if (b.tabindex > 0) {
button.tabIndex = b.tabindex;
} else {
button.tabIndex = tabIndex + i + 1;
}
button.innerText = b.text;
button.addEventListener('click', () => {
if (typeof b.trigger === 'function') {
@ -207,6 +227,19 @@ class Popup {
return button;
}))
);
const tabs = [...container.querySelectorAll('[tabindex]')].map(e => e.tabIndex ?? 0);
const tabMin = Math.min.apply(null, tabs);
const tabMax = Math.max.apply(null, tabs);
const last = container.querySelector(`[tabindex="${tabMax}"]`);
if (last != null) {
last.addEventListener('keydown', e => {
if (e.key === 'Tab') {
const first = container.querySelector(`[tabindex="${tabMin}"]`);
first?.focus();
e.preventDefault();
}
});
}
}
// resizable
if (this.#option.resizable === true) {
@ -264,7 +297,8 @@ class Popup {
}
return new Promise(resolve => {
setTimeout(() => {
mask.style.opacity = 1
mask.style.opacity = 1;
this.container.focus();
resolve(mask);
}, 0);
});
@ -396,7 +430,10 @@ export function showAlert(title, message, iconType = 'info', parent = document.b
{ text: r('ok', 'OK'), trigger: resolve }
]
});
popup.show(parent);
popup.show(parent).then(mask => {
const button = mask.querySelector('.popup-container .popup-footer .popup-button:last-child');
button?.focus();
});
});
}
@ -442,6 +479,9 @@ export function showConfirm(title, content, buttons, iconType = 'question', pare
{ text: r('no', 'No'), trigger: p => resolve({ key: 'no', popup: p }) }
]
});
popup.show(parent);
popup.show(parent).then(mask => {
const button = mask.querySelector('.popup-container .popup-footer .popup-button:last-child');
button?.focus();
});
});
}