Modals: lock background scroll; comment dropdown keeps row on one line, full tone labels, flip up near bottom
This commit is contained in:
@@ -235,6 +235,9 @@ dialog.modal {
|
|||||||
box-shadow: 0 20px 60px rgba(0,0,0,0.35);
|
box-shadow: 0 20px 60px rgba(0,0,0,0.35);
|
||||||
}
|
}
|
||||||
dialog.modal::backdrop { background: rgba(0,0,0,0.55); }
|
dialog.modal::backdrop { background: rgba(0,0,0,0.55); }
|
||||||
|
/* Пока открыта модалка — страница не прокручивается; прокрутка остаётся внутри .modal-body */
|
||||||
|
html.modal-open, html.modal-open body { overflow: hidden; }
|
||||||
|
html.modal-open body { padding-right: var(--modal-scrollbar, 0); }
|
||||||
.modal-header { display: flex; align-items: center; justify-content: space-between; padding: 1rem 1.5rem; border-bottom: 1px solid var(--c-border); }
|
.modal-header { display: flex; align-items: center; justify-content: space-between; padding: 1rem 1.5rem; border-bottom: 1px solid var(--c-border); }
|
||||||
.modal-title { margin: 0; font-size: 1.0625rem; font-weight: 600; }
|
.modal-title { margin: 0; font-size: 1.0625rem; font-weight: 600; }
|
||||||
.modal-close { border: none; background: none; cursor: pointer; font-size: 1.25rem; color: var(--c-text-muted); padding: 0 0.25rem; }
|
.modal-close { border: none; background: none; cursor: pointer; font-size: 1.25rem; color: var(--c-text-muted); padding: 0 0.25rem; }
|
||||||
@@ -304,17 +307,17 @@ code.code { padding: 0.125rem 0.5rem; border-radius: 0.25rem; font-family: monos
|
|||||||
.chip-neu { background: #5d6570; color: #fff; }
|
.chip-neu { background: #5d6570; color: #fff; }
|
||||||
.chip-neg { background: #b3283b; color: #fff; }
|
.chip-neg { background: #b3283b; color: #fff; }
|
||||||
/* Слоты комментариев в диалоге */
|
/* Слоты комментариев в диалоге */
|
||||||
.cs-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
|
.cs-row { display: flex; gap: 6px; align-items: center; }
|
||||||
.cs-text-wrap { position: relative; flex: 1 1 12rem; min-width: 0; }
|
.cs-text-wrap { position: relative; flex: 1 1 auto; min-width: 0; }
|
||||||
.cs-text-wrap .cs-text { width: 100%; }
|
.cs-text-wrap .cs-text { width: 100%; }
|
||||||
.cs-row .cs-tone, .cs-row .btn { flex: 0 0 auto; }
|
.cs-row .cs-tone, .cs-row .btn { flex: 0 0 auto; }
|
||||||
.cs-tone { max-width: 9rem; }
|
|
||||||
.ac-list {
|
.ac-list {
|
||||||
position: absolute; left: 0; right: 0; top: 100%; margin-top: 2px; z-index: 20;
|
position: absolute; left: 0; right: 0; top: 100%; margin-top: 2px; z-index: 20;
|
||||||
max-height: 14rem; overflow-y: auto;
|
max-height: 14rem; overflow-y: auto;
|
||||||
background: var(--c-surface); border: 1px solid var(--c-border);
|
background: var(--c-surface); border: 1px solid var(--c-border);
|
||||||
border-radius: 0.4rem; box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
|
border-radius: 0.4rem; box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
|
||||||
}
|
}
|
||||||
|
.ac-list.drop-up { top: auto; bottom: 100%; margin-top: 0; margin-bottom: 2px; }
|
||||||
.ac-item { display: flex; align-items: center; gap: 0.5rem; padding: 0.4rem 0.6rem; cursor: pointer; font-size: 0.875rem; }
|
.ac-item { display: flex; align-items: center; gap: 0.5rem; padding: 0.4rem 0.6rem; cursor: pointer; font-size: 0.875rem; }
|
||||||
.ac-item:hover, .ac-item.active { background: var(--c-bg); }
|
.ac-item:hover, .ac-item.active { background: var(--c-bg); }
|
||||||
.ac-text { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
.ac-text { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ function csRow(text, tone) {
|
|||||||
var sel = document.createElement('select');
|
var sel = document.createElement('select');
|
||||||
sel.className = 'input cs-tone';
|
sel.className = 'input cs-tone';
|
||||||
sel.title = 'Тональность комментария';
|
sel.title = 'Тональность комментария';
|
||||||
[['positive', '+ позитив'], ['negative', '— негатив'], ['neutral', '○ нейтрал']].forEach(function (o) {
|
[['positive', '+ позитивный'], ['negative', '— негативный'], ['neutral', '○ нейтральный']].forEach(function (o) {
|
||||||
var op = document.createElement('option');
|
var op = document.createElement('option');
|
||||||
op.value = o[0];
|
op.value = o[0];
|
||||||
op.textContent = o[1];
|
op.textContent = o[1];
|
||||||
@@ -152,8 +152,22 @@ function attachCommentAutocomplete(input) {
|
|||||||
});
|
});
|
||||||
list.hidden = false;
|
list.hidden = false;
|
||||||
active = -1;
|
active = -1;
|
||||||
|
positionList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Если снизу внутри модалки мало места — раскрываем список вверх, чтобы он не обрезался. */
|
||||||
|
function positionList() {
|
||||||
|
var wrap = input.parentNode;
|
||||||
|
var scrollParent = input.closest('.modal-body') || document.documentElement;
|
||||||
|
var wr = wrap.getBoundingClientRect();
|
||||||
|
var sr = scrollParent.getBoundingClientRect();
|
||||||
|
var below = sr.bottom - wr.bottom;
|
||||||
|
var above = wr.top - sr.top;
|
||||||
|
list.classList.toggle('drop-up', below < 220 && above > below);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('resize', function () { if (!list.hidden) positionList(); });
|
||||||
|
|
||||||
function load() {
|
function load() {
|
||||||
clearTimeout(AC_TIMER);
|
clearTimeout(AC_TIMER);
|
||||||
AC_TIMER = setTimeout(function () {
|
AC_TIMER = setTimeout(function () {
|
||||||
|
|||||||
@@ -27,15 +27,30 @@
|
|||||||
document.querySelectorAll('pre code').forEach(function(el){ window.hljs.highlightElement(el); });
|
document.querySelectorAll('pre code').forEach(function(el){ window.hljs.highlightElement(el); });
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
document.addEventListener('DOMContentLoaded', function(){ window.__hljsSet(document.documentElement.getAttribute('data-theme')); window.__hljsAll(); });
|
document.addEventListener('DOMContentLoaded', function(){ window.__hljsSet(document.documentElement.getAttribute('data-theme')); window.__hljsAll(); syncModalScrollLock(); });
|
||||||
function toggleTheme(){
|
function toggleTheme(){
|
||||||
var e=document.documentElement; var t=e.getAttribute('data-theme')==='dark'?'light':'dark';
|
var e=document.documentElement; var t=e.getAttribute('data-theme')==='dark'?'light':'dark';
|
||||||
e.setAttribute('data-theme',t); localStorage.setItem('lms-theme',t); window.__hljsSet(t);
|
e.setAttribute('data-theme',t); localStorage.setItem('lms-theme',t); window.__hljsSet(t);
|
||||||
}
|
}
|
||||||
function openModal(id){ var d=document.getElementById(id); if(d) d.showModal(); }
|
function openModal(id){ var d=document.getElementById(id); if(d) d.showModal(); syncModalScrollLock(); }
|
||||||
function closeModal(id){ var d=document.getElementById(id); if(d) d.close(); }
|
function closeModal(id){ var d=document.getElementById(id); if(d) d.close(); syncModalScrollLock(); }
|
||||||
function openModalData(btn){ openModal(btn.dataset.modal); }
|
function openModalData(btn){ openModal(btn.dataset.modal); }
|
||||||
function closeModalData(btn){ closeModal(btn.dataset.modal); }
|
function closeModalData(btn){ closeModal(btn.dataset.modal); }
|
||||||
|
/* Пока открыта хоть одна модалка — блокируем прокрутку страницы (внутри .modal-body прокрутка остаётся). */
|
||||||
|
function syncModalScrollLock(){
|
||||||
|
var root = document.documentElement;
|
||||||
|
if (document.querySelector('dialog[open]')) {
|
||||||
|
var sw = window.innerWidth - root.clientWidth;
|
||||||
|
root.style.setProperty('--modal-scrollbar', (sw > 0 ? sw : 0) + 'px');
|
||||||
|
root.classList.add('modal-open');
|
||||||
|
} else {
|
||||||
|
root.classList.remove('modal-open');
|
||||||
|
root.style.removeProperty('--modal-scrollbar');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.addEventListener('toggle', function (e) {
|
||||||
|
if (e.target && e.target.tagName === 'DIALOG') syncModalScrollLock();
|
||||||
|
}, true);
|
||||||
function sectionStateKey(id){ return 'lms-section-open:' + id; }
|
function sectionStateKey(id){ return 'lms-section-open:' + id; }
|
||||||
function applySectionState(acc){
|
function applySectionState(acc){
|
||||||
var id = acc.getAttribute('data-section-id');
|
var id = acc.getAttribute('data-section-id');
|
||||||
|
|||||||
Reference in New Issue
Block a user