/
webru
/
prisma-ui
Обзор
Документация
Войти
/
webru
/
prisma-ui
Код
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
ops-patterns.js
147 строк
5 KB
webru
Add full UI component library, EU date format, and expanded AI designer prompt.
14 июн 2026, 14:01
14 июн 2026, 14:01
a418de3
Код
Авторство
О чём код?
/** * Prisma UI — Tabs, action menus, table selection */ (function () { function initTabs(root) { (root || document).querySelectorAll("[data-ops-tabs]").forEach(function (container) { if (container.dataset.opsTabsInit) return; container.dataset.opsTabsInit = "true"; var tabs = container.querySelectorAll(".ops-tabs__tab"); var panels = container.querySelectorAll(".ops-tabs__panel"); tabs.forEach(function (tab) { tab.addEventListener("click", function () { var id = tab.getAttribute("data-tab"); tabs.forEach(function (t) { t.classList.toggle("is-active", t === tab); }); panels.forEach(function (p) { p.classList.toggle("is-active", p.getAttribute("data-tab-panel") === id); }); }); }); }); } var openMenu = null; function positionMenu(trigger, panel) { var rect = trigger.getBoundingClientRect(); panel.style.top = rect.bottom + 4 + "px"; panel.style.left = Math.max(8, rect.right - panel.offsetWidth) + "px"; } function closeMenu(menu) { if (!menu) return; menu.classList.remove("is-open"); if (openMenu === menu) openMenu = null; } function initMenus(root) { (root || document).querySelectorAll(".ops-menu").forEach(function (menu) { if (menu.dataset.opsMenuInit) return; menu.dataset.opsMenuInit = "true"; var trigger = menu.querySelector("[data-menu-trigger]"); var panel = menu.querySelector(".ops-menu__panel"); if (!trigger || !panel) return; trigger.addEventListener("click", function (e) { e.stopPropagation(); if (menu.classList.contains("is-open")) { closeMenu(menu); } else { if (openMenu) closeMenu(openMenu); menu.classList.add("is-open"); openMenu = menu; positionMenu(trigger, panel); } }); panel.querySelectorAll(".ops-menu__item").forEach(function (item) { item.addEventListener("click", function () { closeMenu(menu); }); }); }); } function initTableSelection(root) { (root || document).querySelectorAll("[data-ops-table-select]").forEach(function (wrap) { if (wrap.dataset.opsTableInit) return; wrap.dataset.opsTableInit = "true"; var bulk = wrap.querySelector(".ops-table-bulk"); var master = wrap.querySelector("[data-select-all]"); var rows = wrap.querySelectorAll("tbody .ops-check input"); function updateBulk() { var n = wrap.querySelectorAll("tbody .ops-check input:checked").length; wrap.querySelectorAll("tbody tr").forEach(function (tr) { var cb = tr.querySelector(".ops-check input"); tr.classList.toggle("is-selected", cb && cb.checked); }); if (bulk) { bulk.classList.toggle("is-visible", n > 0); var countEl = bulk.querySelector("[data-selected-count]"); if (countEl) countEl.textContent = String(n); } if (master) { master.checked = n > 0 && n === rows.length; master.indeterminate = n > 0 && n < rows.length; } } if (master) { master.addEventListener("change", function () { rows.forEach(function (cb) { cb.checked = master.checked; }); updateBulk(); }); } rows.forEach(function (cb) { cb.addEventListener("change", updateBulk); }); }); } function initSortHeaders(root) { (root || document).querySelectorAll(".ops-th-sort").forEach(function (th) { if (th.dataset.opsSortInit) return; th.dataset.opsSortInit = "true"; th.innerHTML += ' <span class="ops-th-sort__icon">↕</span>'; th.addEventListener("click", function () { var isAsc = th.classList.contains("is-sorted-asc"); th.closest("tr").querySelectorAll(".ops-th-sort").forEach(function (h) { h.classList.remove("is-sorted-asc", "is-sorted-desc"); }); th.classList.add(isAsc ? "is-sorted-desc" : "is-sorted-asc"); var icon = th.querySelector(".ops-th-sort__icon"); if (icon) icon.textContent = isAsc ? "↓" : "↑"; }); }); } document.addEventListener("click", function () { if (openMenu) closeMenu(openMenu); }); window.addEventListener("resize", function () { if (!openMenu) return; var trigger = openMenu.querySelector("[data-menu-trigger]"); var panel = openMenu.querySelector(".ops-menu__panel"); if (trigger && panel) positionMenu(trigger, panel); }); document.addEventListener("DOMContentLoaded", function () { initTabs(); initMenus(); initTableSelection(); initSortHeaders(); }); window.initOpsPatterns = function (root) { initTabs(root); initMenus(root); initTableSelection(root); initSortHeaders(root); }; })();