feat: 增加 DCF 等估值工具
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import template from './dcf-help.html?raw';
|
||||
|
||||
// Keep the documentation separate from calculator inputs and per-company storage.
|
||||
// Add future concepts as a section and a matching directory button in the template.
|
||||
export function createDCFHelp(root) {
|
||||
root.insertAdjacentHTML('beforeend', template);
|
||||
const dialog = root.querySelector('.df-help-dialog');
|
||||
const trigger = root.querySelector('[data-help-open]');
|
||||
const body = dialog.querySelector('.df-help-body');
|
||||
let previousOverflow;
|
||||
|
||||
const unlock = () => {
|
||||
if (previousOverflow === undefined) return;
|
||||
document.documentElement.style.overflow = previousOverflow;
|
||||
previousOverflow = undefined;
|
||||
};
|
||||
trigger.addEventListener('click', () => {
|
||||
if (dialog.open) return;
|
||||
dialog.showModal();
|
||||
previousOverflow = document.documentElement.style.overflow;
|
||||
document.documentElement.style.overflow = 'hidden';
|
||||
body.scrollTop = 0;
|
||||
});
|
||||
dialog.querySelector('[data-help-close]').addEventListener('click', () => dialog.close());
|
||||
dialog.addEventListener('close', () => {
|
||||
unlock();
|
||||
if (trigger.isConnected) trigger.focus({preventScroll: true});
|
||||
});
|
||||
dialog.addEventListener('keydown', event => {
|
||||
if (event.key !== 'Tab') return;
|
||||
const items = [...dialog.querySelectorAll('button:not(:disabled), a[href]')];
|
||||
const destination = event.shiftKey && document.activeElement === items[0] ? items.at(-1)
|
||||
: !event.shiftKey && document.activeElement === items.at(-1) ? items[0] : undefined;
|
||||
if (destination) {
|
||||
event.preventDefault();
|
||||
destination.focus();
|
||||
}
|
||||
});
|
||||
let backdropPointer = false;
|
||||
const outside = event => {
|
||||
const rect = dialog.getBoundingClientRect();
|
||||
return event.clientX < rect.left || event.clientX > rect.right || event.clientY < rect.top || event.clientY > rect.bottom;
|
||||
};
|
||||
dialog.addEventListener('pointerdown', event => { backdropPointer = event.target === dialog && outside(event); });
|
||||
dialog.addEventListener('click', event => {
|
||||
if (backdropPointer && event.target === dialog && outside(event)) dialog.close();
|
||||
backdropPointer = false;
|
||||
});
|
||||
dialog.querySelectorAll('[data-help-jump]').forEach(button => button.addEventListener('click', () => {
|
||||
const section = dialog.querySelector(`[data-help-section="${button.dataset.helpJump}"]`);
|
||||
body.scrollTop = section.getBoundingClientRect().top - body.getBoundingClientRect().top + body.scrollTop;
|
||||
section.focus({preventScroll: true});
|
||||
}));
|
||||
return () => {
|
||||
if (dialog.open) dialog.close();
|
||||
unlock();
|
||||
dialog.remove();
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user