You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.6 KiB
94 lines
2.6 KiB
2 years ago
|
const Spacer = require('./Spacer.js');
|
||
|
const theme = require('../theme.js');
|
||
|
|
||
|
/**
|
||
|
* @typedef {Object} RuntimeErrorFooterProps
|
||
|
* @property {string} [initialFocus]
|
||
|
* @property {boolean} multiple
|
||
|
* @property {function(MouseEvent): void} onClickCloseButton
|
||
|
* @property {function(MouseEvent): void} onClickNextButton
|
||
|
* @property {function(MouseEvent): void} onClickPrevButton
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* A fixed footer that handles pagination of runtime errors.
|
||
|
* @param {Document} document
|
||
|
* @param {HTMLElement} root
|
||
|
* @param {RuntimeErrorFooterProps} props
|
||
|
* @returns {void}
|
||
|
*/
|
||
|
function RuntimeErrorFooter(document, root, props) {
|
||
|
const footer = document.createElement('div');
|
||
|
footer.style.backgroundColor = '#' + theme.dimgrey;
|
||
|
footer.style.bottom = '0';
|
||
|
footer.style.boxShadow = '0 -1px 4px rgba(0, 0, 0, 0.3)';
|
||
|
footer.style.height = '2.5rem';
|
||
|
footer.style.left = '0';
|
||
|
footer.style.right = '0';
|
||
|
footer.style.lineHeight = '2.5rem';
|
||
|
footer.style.paddingBottom = '0';
|
||
|
footer.style.paddingBottom = 'env(safe-area-inset-bottom)';
|
||
|
footer.style.position = 'fixed';
|
||
|
footer.style.textAlign = 'center';
|
||
|
footer.style.zIndex = '2';
|
||
|
|
||
|
const BUTTON_CONFIGS = {
|
||
|
prev: {
|
||
|
id: 'prev',
|
||
|
label: '◀ Prev',
|
||
|
onClick: props.onClickPrevButton,
|
||
|
},
|
||
|
close: {
|
||
|
id: 'close',
|
||
|
label: '× Close',
|
||
|
onClick: props.onClickCloseButton,
|
||
|
},
|
||
|
next: {
|
||
|
id: 'next',
|
||
|
label: 'Next ▶',
|
||
|
onClick: props.onClickNextButton,
|
||
|
},
|
||
|
};
|
||
|
|
||
|
let buttons = [BUTTON_CONFIGS.close];
|
||
|
if (props.multiple) {
|
||
|
buttons = [BUTTON_CONFIGS.prev, BUTTON_CONFIGS.close, BUTTON_CONFIGS.next];
|
||
|
}
|
||
|
|
||
|
/** @type {HTMLButtonElement | undefined} */
|
||
|
let initialFocusButton;
|
||
|
for (let i = 0; i < buttons.length; i += 1) {
|
||
|
const buttonConfig = buttons[i];
|
||
|
|
||
|
const button = document.createElement('button');
|
||
|
button.id = buttonConfig.id;
|
||
|
button.innerHTML = buttonConfig.label;
|
||
|
button.tabIndex = 1;
|
||
|
button.style.backgroundColor = '#' + theme.dimgrey;
|
||
|
button.style.border = 'none';
|
||
|
button.style.color = '#' + theme.white;
|
||
|
button.style.cursor = 'pointer';
|
||
|
button.style.fontSize = 'inherit';
|
||
|
button.style.height = '100%';
|
||
|
button.style.padding = '0.5rem 0.75rem';
|
||
|
button.style.width = (100 / buttons.length).toString(10) + '%';
|
||
|
button.addEventListener('click', buttonConfig.onClick);
|
||
|
|
||
|
if (buttonConfig.id === props.initialFocus) {
|
||
|
initialFocusButton = button;
|
||
|
}
|
||
|
|
||
|
footer.appendChild(button);
|
||
|
}
|
||
|
|
||
|
root.appendChild(footer);
|
||
|
|
||
|
Spacer(document, root, { space: '2.5rem' });
|
||
|
|
||
|
if (initialFocusButton) {
|
||
|
initialFocusButton.focus();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = RuntimeErrorFooter;
|