Управление, отмена закрытия и очистка
Откройте панель, запретите закрытие и проверьте hide(), Escape или подложку. Затем снимите запрет, закройте панель, вызовите dispose() и создайте экземпляр снова.
Экземпляр создан.
<div class="sidebar-demo-actions">
<button type="button" class="btn btn-primary btn-sm" id="sidebar-api-show">show()</button>
<button type="button" class="btn btn-surface btn-sm" id="sidebar-api-toggle">toggle()</button>
<button type="button" class="btn btn-surface btn-sm" id="sidebar-api-dispose">dispose()</button>
<button type="button" class="btn btn-surface btn-sm" id="sidebar-api-create">Создать снова</button>
</div>
<pre id="sidebar-api-log" class="sidebar-demo-log" role="log" aria-live="polite">Экземпляр создан.</pre>
<!-- Panels: разместите в конце body -->
<aside id="sidebar-api" class="vg-sidebar right sidebar-demo-panel" aria-labelledby="sidebar-api-title">
<div class="vg-sidebar-header">
<h2 id="sidebar-api-title">Жизненный цикл</h2>
<button type="button" class="vg-btn-close" data-vg-dismiss="sidebar" data-vg-target="#sidebar-api" aria-label="Закрыть"></button>
</div>
<div class="vg-sidebar-body"><label class="sidebar-demo-check"><input type="checkbox" id="sidebar-api-lock"> Запретить закрытие</label>
<p id="sidebar-api-status" role="status">Закрытие разрешено.</p>
<button type="button" class="btn btn-surface btn-sm" id="sidebar-api-hide">hide()</button></div>
<div class="vg-sidebar-footer">
<button type="button" class="btn btn-primary btn-sm" data-vg-dismiss="sidebar" data-vg-target="#sidebar-api">Закрыть панель</button>
</div>
</aside>
/**
* Описание: программное управление и жизненный цикл VGSidebar.
* Возможности: show/hide/toggle, preventDefault, журнал DOM-событий, dispose и повторная инициализация.
*/
import { VGSidebar } from 'vgapp';
function initSidebarDemo() {
const panel = document.querySelector('#sidebar-api');
if (!panel) return;
const log = document.querySelector('#sidebar-api-log');
const lock = document.querySelector('#sidebar-api-lock');
const status = document.querySelector('#sidebar-api-status');
const disposeButton = document.querySelector('#sidebar-api-dispose');
const showButton = document.querySelector('#sidebar-api-show');
const toggleButton = document.querySelector('#sidebar-api-toggle');
const createButton = document.querySelector('#sidebar-api-create');
let instance = VGSidebar.getOrCreateInstance(panel);
let transitioning = false;
const write = (message) => {
log.textContent = (log.textContent + '\n' + message).split('\n').slice(-12).join('\n');
};
const sync = () => {
const unavailable = !instance || transitioning;
showButton.disabled = unavailable;
toggleButton.disabled = unavailable;
disposeButton.disabled = unavailable || panel.classList.contains('show');
createButton.disabled = !!instance;
};
panel.addEventListener('vg.sidebar.hide', (event) => {
if (!lock.checked) return;
event.preventDefault();
status.textContent = 'Закрытие отменено через preventDefault(). Снимите флажок.';
});
lock.addEventListener('change', () => {
status.textContent = lock.checked ? 'Закрытие запрещено.' : 'Закрытие разрешено.';
});
['show', 'shown', 'hide', 'hidden'].forEach((name) => {
panel.addEventListener('vg.sidebar.' + name, (event) => {
write(event.type + (event.defaultPrevented ? ' — отменено' : ''));
if (!event.defaultPrevented) {
transitioning = name === 'show' || name === 'hide';
}
sync();
});
});
showButton.addEventListener('click', () => instance?.show(showButton));
toggleButton.addEventListener('click', () => instance?.toggle(toggleButton));
document.querySelector('#sidebar-api-hide').addEventListener('click', () => instance?.hide());
// Сначала hide(), затем vg.sidebar.hidden; dispose не заменяет закрытие.
disposeButton.addEventListener('click', () => {
instance.dispose();
instance = null;
write('dispose; getInstance: ' + VGSidebar.getInstance(panel));
sync();
});
createButton.addEventListener('click', () => {
instance = VGSidebar.getOrCreateInstance(panel);
write('Создан новый экземпляр.');
sync();
});
sync();
}
initSidebarDemo();
/* Композиция демо; OKAUX на сайте использует префикс токенов vg. */
.sidebar-demo-panel {
--vg-sidebar-horizontal-width: min(26rem, 100vw);
--vg-sidebar-horizontal-height: 100dvh;
--vg-sidebar-vertical-height: min(24rem, 80dvh);
--vg-sidebar-header-height: 72px;
--vg-sidebar-footer-height: 64px;
--vg-sidebar-padding: 1rem;
--vg-sidebar-bg-color: var(--vg-bg-primary);
--vg-sidebar-color: var(--vg-text-primary);
--vg-sidebar-border: 1px solid var(--vg-border-default);
}
.sidebar-demo-panel .vg-sidebar-header {
justify-content: space-between;
gap: 1rem;
}
.sidebar-demo-panel .vg-sidebar-header h2 {
margin: 0;
font-size: 1.125rem;
}
.sidebar-demo-panel .vg-btn-close { flex-shrink: 0; }
.sidebar-demo-panel .vg-sidebar-footer {
display: flex;
align-items: center;
gap: .5rem;
}
.sidebar-demo-actions { display: flex; flex-wrap: wrap; gap: .75rem; }
.sidebar-demo-card, .sidebar-demo-log {
padding: 1rem;
border: 1px solid var(--vg-border-default);
border-radius: var(--vg-radius-lg);
background: var(--vg-bg-secondary);
color: var(--vg-text-primary);
overflow-wrap: anywhere;
}
.sidebar-demo-log {
margin-top: 1rem;
max-height: 14rem;
overflow-y: auto;
white-space: pre-wrap;
}
.sidebar-demo-panel .vg-sidebar-body { overflow-wrap: anywhere; }
.sidebar-demo-check { display: flex; align-items: center; gap: .5rem; margin: 1rem 0; }
/* Не меняем состояние темы: оно остаётся в data-theme / okaux.theme. */