mirror of
https://github.com/pocketbase/pocketbase.git
synced 2026-10-24 06:50:25 +02:00
merge newui branch
This commit is contained in:
1 parent
58f605e90c
commit
4c44044c0c
804 files changed
+58660
-56663
No files matched your search
@@ -0,0 +1,170 @@
|
||||
window.app = window.app || {};
|
||||
window.app.components = window.app.components || {};
|
||||
|
||||
const responsiveThreshold = 1000;
|
||||
|
||||
/**
|
||||
* A generic page sidebar component with resizable edge.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* app.components.pageSidebar({},
|
||||
* t.nav({ className: "sidebar-content scrollable" },
|
||||
* t.details({ className: "nav-group"},
|
||||
* t.summary({ tabIndex: -1, onfocusout: () => false, onclick: () => false, onkeyup: () => false },
|
||||
* "Group 1",
|
||||
* ),
|
||||
* t.a({ className: "nav-link", href: "..." }, "Link 1.1"),
|
||||
* t.a({ className: "nav-link", href: "..." }, "Link 1.2"),
|
||||
* ),
|
||||
* t.details({ className: "nav-group"},
|
||||
* t.summary({ tabIndex: -1, onfocusout: () => false, onclick: () => false, onkeyup: () => false },
|
||||
* "Group 2",
|
||||
* ),
|
||||
* t.a({ className: "nav-link", href: "..." }, "Link 2.1"),
|
||||
* t.a({ className: "nav-link", href: "..." }, "Link 2.2"),
|
||||
* ),
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* @param {Object} [propsArg]
|
||||
* @param {Array<Element|Function>} [children]
|
||||
* @return {Element}
|
||||
*/
|
||||
window.app.components.pageSidebar = function(propsArg = {}, ...children) {
|
||||
let sidebarElem;
|
||||
|
||||
const props = store({
|
||||
rid: undefined,
|
||||
id: undefined,
|
||||
hidden: undefined,
|
||||
inert: undefined,
|
||||
className: "",
|
||||
widthHistoryKey: "pbPageSidebarWidth",
|
||||
onmount: undefined,
|
||||
onunmount: undefined,
|
||||
});
|
||||
|
||||
const watchers = app.utils.extendStore(props, propsArg);
|
||||
|
||||
const data = store({
|
||||
responsiveShow: false,
|
||||
});
|
||||
|
||||
let responsiveBtn;
|
||||
function responsivePageSidebar() {
|
||||
if (!sidebarElem) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (window.innerWidth > responsiveThreshold) {
|
||||
data.responsiveShow = false;
|
||||
sidebarElem.dataset.responsive = false;
|
||||
responsiveBtn?.remove();
|
||||
responsiveBtn = null;
|
||||
return;
|
||||
}
|
||||
|
||||
sidebarElem.dataset.responsive = true;
|
||||
|
||||
if (!responsiveBtn) {
|
||||
responsiveBtn = t.button(
|
||||
{
|
||||
type: "button",
|
||||
className: "btn transparent secondary responsive-sidebar-btn",
|
||||
title: "Toggle sidebar",
|
||||
onclick: (e) => {
|
||||
e.stopPropagation();
|
||||
data.responsiveShow = !data.responsiveShow;
|
||||
},
|
||||
},
|
||||
t.i({ className: "ri-menu-2-line", ariaHidden: true }),
|
||||
);
|
||||
|
||||
document.body.querySelector(".page-header .breadcrumbs").before(responsiveBtn);
|
||||
}
|
||||
}
|
||||
|
||||
function onOutsideClick(e) {
|
||||
if (e.target.closest(".responsive-close")) {
|
||||
data.responsiveShow = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
e.target.closest(".page-sidebar")
|
||||
|| e.target.closest(".app-header")
|
||||
|| e.target.closest(".modal")
|
||||
) {
|
||||
return; // inside click -> do nothing
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
e.stopImmediatePropagation();
|
||||
|
||||
data.responsiveShow = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
watchers.push(
|
||||
watch(() => data.responsiveShow, (visible) => {
|
||||
if (visible) {
|
||||
window.addEventListener("click", onOutsideClick, true);
|
||||
} else {
|
||||
window.removeEventListener("click", onOutsideClick, true);
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
sidebarElem = t.aside(
|
||||
{
|
||||
pbEvent: "pageSidebar",
|
||||
rid: props.rid,
|
||||
id: () => props.id,
|
||||
hidden: () => props.hidden,
|
||||
inert: () => props.inert,
|
||||
className: () => `page-sidebar ${props.className} ${data.responsiveShow ? "active" : ""}`,
|
||||
onmount: (el) => {
|
||||
responsivePageSidebar(el);
|
||||
window.addEventListener("resize", responsivePageSidebar);
|
||||
props.onmount?.(el);
|
||||
},
|
||||
onunmount: (el) => {
|
||||
props.onunmount?.(el);
|
||||
|
||||
window.removeEventListener("click", onOutsideClick, true);
|
||||
window.removeEventListener("resize", responsivePageSidebar);
|
||||
responsiveBtn?.remove();
|
||||
watchers.forEach((w) => w?.unwatch());
|
||||
},
|
||||
},
|
||||
(el) => {
|
||||
let sidebarWidth;
|
||||
|
||||
if (props.widthHistoryKey) {
|
||||
sidebarWidth = localStorage.getItem(props.widthHistoryKey);
|
||||
if (sidebarWidth) {
|
||||
el.style.width = sidebarWidth;
|
||||
}
|
||||
}
|
||||
|
||||
return app.components.dragline({
|
||||
ondragstart: (e) => {
|
||||
el._startWidth = el.offsetWidth;
|
||||
},
|
||||
ondragging: (e, diffX, diffY) => {
|
||||
sidebarWidth = el._startWidth + diffX + "px";
|
||||
el.style.width = sidebarWidth;
|
||||
|
||||
if (props.widthHistoryKey) {
|
||||
localStorage.setItem(props.widthHistoryKey, sidebarWidth);
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
...children,
|
||||
);
|
||||
|
||||
return sidebarElem;
|
||||
};
|
||||
Reference in new issue
Block a user