update Sidebar
All checks were successful
Build and Deploy Next.js + Nginx Docker Image / build-and-deploy (push) Successful in 54s
Build and Deploy Next.js + Nginx Docker Image / deploy (push) Successful in 6s

This commit is contained in:
Mohamadzadeh 2026-10-03 17:11:33 +03:30
parent 1a87e58a6c
commit 52a58e497d
6 changed files with 34 additions and 32 deletions

View File

@ -914,7 +914,8 @@ import { AppSidebar } from "uikit/remote/ui/AppSidebar";
items={[ items={[
{ {
id: "home", id: "home",
label: "عنوان آیتم", title: "عنوان آیتم",
mobileTitle: "عنوان کوتاه",
icon: <YourSvgIcon />, icon: <YourSvgIcon />,
active: true, active: true,
onClick: () => navigate("/home"), onClick: () => navigate("/home"),

View File

@ -2,8 +2,8 @@ import type { ElementType, ReactNode } from "react";
export type AppSidebarItem = { export type AppSidebarItem = {
id?: string | number; id?: string | number;
label: string; title: string;
mobileLabel?: string; mobileTitle?: string;
icon?: ReactNode | ElementType; icon?: ReactNode | ElementType;
iconSvg?: string; iconSvg?: string;
href?: string; href?: string;

View File

@ -524,7 +524,7 @@ class y extends HTMLElement {
} }
} }
getItemLabel(e) { getItemLabel(e) {
return String(e?.mobileLabel || e?.label || ""); return String(e?.mobileTitle || e?.title || "");
} }
hideTooltip() { hideTooltip() {
this._tooltip && (this._tooltip.dataset.open = "false"); this._tooltip && (this._tooltip.dataset.open = "false");
@ -540,23 +540,23 @@ class y extends HTMLElement {
e.addEventListener("mouseenter", o), e.addEventListener("mouseleave", n), i.addEventListener("focus", o), i.addEventListener("blur", n); e.addEventListener("mouseenter", o), e.addEventListener("mouseleave", n), i.addEventListener("focus", o), i.addEventListener("blur", n);
} }
createItemControl(e, i, t, o) { createItemControl(e, i, t, o) {
const n = !!e?.disabled, a = !!e?.active, l = typeof e?.onClick == "function", s = typeof e?.href == "string" && e.href.length > 0, d = r(s && !l ? "a" : "button", t); const n = !!e?.disabled, a = !!e?.active, s = typeof e?.onClick == "function", l = typeof e?.href == "string" && e.href.length > 0, d = r(l && !s ? "a" : "button", t);
return d.tagName === "BUTTON" ? d.type = "button" : (d.href = e.href, e.target && (d.target = e.target), e.rel && (d.rel = e.rel)), d.setAttribute("aria-label", String(e?.label || `آیتم ${i + 1}`)), d.setAttribute("aria-disabled", n ? "true" : "false"), d.dataset.active = a ? "true" : "false", a && d.setAttribute("aria-current", "page"), n && (d.tabIndex = -1), d.addEventListener("click", (p) => { return d.tagName === "BUTTON" ? d.type = "button" : (d.href = e.href, e.target && (d.target = e.target), e.rel && (d.rel = e.rel)), d.setAttribute("aria-label", String(e?.title || `آیتم ${i + 1}`)), d.setAttribute("aria-disabled", n ? "true" : "false"), d.dataset.active = a ? "true" : "false", a && d.setAttribute("aria-current", "page"), n && (d.tabIndex = -1), d.addEventListener("click", (p) => {
if (n) { if (n) {
p.preventDefault(), p.stopPropagation(); p.preventDefault(), p.stopPropagation();
return; return;
} }
l && e.onClick(e, p), typeof o == "function" && o(e, p); s && e.onClick(e, p), typeof o == "function" && o(e, p);
}), d; }), d;
} }
createNavItem(e, i) { createNavItem(e, i) {
const t = r("div", "item-wrap"), n = !!e?.disabled ? "عدم دسترسی" : String(e?.label || ""), a = this.createItemControl(e, i, "item"), l = r("span", "icon"); const t = r("div", "item-wrap"), n = !!e?.disabled ? "عدم دسترسی" : String(e?.title || ""), a = this.createItemControl(e, i, "item"), s = r("span", "icon");
return a.appendChild(l), this.renderIcon(l, e), t.appendChild(a), this.bindTooltip(t, a, n), t; return a.appendChild(s), this.renderIcon(s, e), t.appendChild(a), this.bindTooltip(t, a, n), t;
} }
createExitItem() { createExitItem() {
const { exitLabel: e = "خروج", onExit: i, exitDisabled: t = !1 } = this._props, o = r("div", "item-wrap"), n = r("button", "item"); const { exitLabel: e = "خروج", onExit: i, exitDisabled: t = !1 } = this._props, o = r("div", "item-wrap"), n = r("button", "item");
n.type = "button", n.setAttribute("aria-label", e), n.setAttribute("aria-disabled", t ? "true" : "false"), t && (n.tabIndex = -1), n.addEventListener("click", (l) => { n.type = "button", n.setAttribute("aria-label", e), n.setAttribute("aria-disabled", t ? "true" : "false"), t && (n.tabIndex = -1), n.addEventListener("click", (s) => {
t || typeof i == "function" && i(l); t || typeof i == "function" && i(s);
}); });
const a = r("span", "icon exit-icon"); const a = r("span", "icon exit-icon");
return a.innerHTML = h, n.appendChild(a), o.appendChild(n), this.bindTooltip( return a.innerHTML = h, n.appendChild(a), o.appendChild(n), this.bindTooltip(
@ -583,18 +583,18 @@ class y extends HTMLElement {
createMobileExit({ drawer: e = !1 } = {}) { createMobileExit({ drawer: e = !1 } = {}) {
const { exitLabel: i = "خروج", onExit: t, exitDisabled: o = !1 } = this._props; const { exitLabel: i = "خروج", onExit: t, exitDisabled: o = !1 } = this._props;
if (e) { if (e) {
const l = r("div", "drawer-exit-section"), s = r("button", "drawer-exit"); const s = r("div", "drawer-exit-section"), l = r("button", "drawer-exit");
s.type = "button", s.setAttribute("aria-label", i), s.setAttribute("aria-disabled", o ? "true" : "false"), o && (s.tabIndex = -1); l.type = "button", l.setAttribute("aria-label", i), l.setAttribute("aria-disabled", o ? "true" : "false"), o && (l.tabIndex = -1);
const d = r("span", "mobile-icon exit-icon"); const d = r("span", "mobile-icon exit-icon");
d.innerHTML = h; d.innerHTML = h;
const p = r("span"); const p = r("span");
return p.textContent = i === "خروج" ? "خروج از سامانه" : i, s.appendChild(d), s.appendChild(p), s.addEventListener("click", (u) => { return p.textContent = i === "خروج" ? "خروج از سامانه" : i, l.appendChild(d), l.appendChild(p), l.addEventListener("click", (u) => {
o || (this.setDrawerOpen(!1), typeof t == "function" && t(u)); o || (this.setDrawerOpen(!1), typeof t == "function" && t(u));
}), l.appendChild(s), l; }), s.appendChild(l), s;
} }
const n = r("div", "mobile-slot"), a = r("button", "mobile-control mobile-exit"); const n = r("div", "mobile-slot"), a = r("button", "mobile-control mobile-exit");
return a.type = "button", a.setAttribute("aria-label", i), a.setAttribute("aria-disabled", o ? "true" : "false"), a.dataset.active = "false", o && (a.tabIndex = -1), a.appendChild(this.createMobileContent(null, !0)), a.addEventListener("click", (l) => { return a.type = "button", a.setAttribute("aria-label", i), a.setAttribute("aria-disabled", o ? "true" : "false"), a.dataset.active = "false", o && (a.tabIndex = -1), a.appendChild(this.createMobileContent(null, !0)), a.addEventListener("click", (s) => {
o || typeof t == "function" && t(l); o || typeof t == "function" && t(s);
}), n.appendChild(a), n; }), n.appendChild(a), n;
} }
createMoreButton(e) { createMoreButton(e) {
@ -616,10 +616,10 @@ class y extends HTMLElement {
n.textContent = "سایر بخش‌های سامانه"; n.textContent = "سایر بخش‌های سامانه";
const a = r("button", "drawer-close"); const a = r("button", "drawer-close");
a.type = "button", a.setAttribute("aria-label", "بستن"), a.innerHTML = m, a.addEventListener("click", () => this.setDrawerOpen(!1)), n.appendChild(a); a.type = "button", a.setAttribute("aria-label", "بستن"), a.innerHTML = m, a.addEventListener("click", () => this.setDrawerOpen(!1)), n.appendChild(a);
const l = r("div", "drawer-body"), s = r("div", "drawer-grid"); const s = r("div", "drawer-body"), l = r("div", "drawer-grid");
return e.forEach((d, p) => { return e.forEach((d, p) => {
s.appendChild(this.createMobileItem(d, p + 4, { drawer: !0 })); l.appendChild(this.createMobileItem(d, p + 4, { drawer: !0 }));
}), l.appendChild(s), this._props.showExit && l.appendChild(this.createMobileExit({ drawer: !0 })), o.appendChild(n), o.appendChild(l), i.appendChild(t), i.appendChild(o), this._drawerLayer = i, i; }), s.appendChild(l), this._props.showExit && s.appendChild(this.createMobileExit({ drawer: !0 })), o.appendChild(n), o.appendChild(s), i.appendChild(t), i.appendChild(o), this._drawerLayer = i, i;
} }
setDrawerOpen(e) { setDrawerOpen(e) {
this._drawerOpen = !!e, this._drawerLayer && (this._drawerLayer.dataset.open = this._drawerOpen ? "true" : "false"), this._moreButton && this._moreButton.setAttribute("aria-expanded", this._drawerOpen ? "true" : "false"), !this._drawerOpen && this._moreButton && this._moreButton.focus({ preventScroll: !0 }); this._drawerOpen = !!e, this._drawerLayer && (this._drawerLayer.dataset.open = this._drawerOpen ? "true" : "false"), this._moreButton && this._moreButton.setAttribute("aria-expanded", this._drawerOpen ? "true" : "false"), !this._drawerOpen && this._moreButton && this._moreButton.focus({ preventScroll: !0 });
@ -636,11 +636,11 @@ class y extends HTMLElement {
const i = r("nav", "mobile-nav"); const i = r("nav", "mobile-nav");
i.setAttribute("aria-label", `${this._props.ariaLabel || "ناوبری اصلی"} موبایل`), i.dir = this._props.dir === "ltr" ? "ltr" : "rtl"; i.setAttribute("aria-label", `${this._props.ariaLabel || "ناوبری اصلی"} موبایل`), i.dir = this._props.dir === "ltr" ? "ltr" : "rtl";
const t = r("div", "mobile-bar"), o = e.length > 4, n = o ? e.slice(0, 4) : e, a = o ? e.slice(4) : []; const t = r("div", "mobile-bar"), o = e.length > 4, n = o ? e.slice(0, 4) : e, a = o ? e.slice(4) : [];
if (n.forEach((l, s) => { if (n.forEach((s, l) => {
t.appendChild(this.createMobileItem(l, s)); t.appendChild(this.createMobileItem(s, l));
}), o) { }), o) {
const l = a.some((s) => !!s?.active); const s = a.some((l) => !!l?.active);
t.appendChild(this.createMoreButton(l)); t.appendChild(this.createMoreButton(s));
} else this._props.showExit && t.appendChild(this.createMobileExit()); } else this._props.showExit && t.appendChild(this.createMobileExit());
return i.appendChild(t), { return i.appendChild(t), {
mobileNav: i, mobileNav: i,

View File

@ -115,9 +115,10 @@ export default function RemoteUiPreview() {
["restricted", "بخش محدود"], ["restricted", "بخش محدود"],
]; ];
return definitions.slice(0, 4).map(([id, label], index) => ({ return definitions.slice(0, 4).map(([id, title], index) => ({
id, id,
label, title,
mobileTitle: title,
icon: iconCycle[index % iconCycle.length], icon: iconCycle[index % iconCycle.length],
active: activeId === id, active: activeId === id,
disabled: id === "restricted", disabled: id === "restricted",
@ -126,7 +127,7 @@ export default function RemoteUiPreview() {
? undefined ? undefined
: () => { : () => {
setActiveId(id); setActiveId(id);
setLastAction(`آیتم «${label}» کلیک شد.`); setLastAction(`آیتم «${title}» کلیک شد.`);
}, },
})); }));
}, [activeId]); }, [activeId]);

View File

@ -570,7 +570,7 @@ class AppSidebarElement extends HTMLElement {
} }
getItemLabel(item) { getItemLabel(item) {
return String(item?.mobileLabel || item?.label || ""); return String(item?.mobileTitle || item?.title || "");
} }
hideTooltip() { hideTooltip() {
@ -620,7 +620,7 @@ class AppSidebarElement extends HTMLElement {
if (item.rel) control.rel = item.rel; if (item.rel) control.rel = item.rel;
} }
control.setAttribute("aria-label", String(item?.label || `آیتم ${index + 1}`)); control.setAttribute("aria-label", String(item?.title || `آیتم ${index + 1}`));
control.setAttribute("aria-disabled", disabled ? "true" : "false"); control.setAttribute("aria-disabled", disabled ? "true" : "false");
control.dataset.active = active ? "true" : "false"; control.dataset.active = active ? "true" : "false";
@ -649,7 +649,7 @@ class AppSidebarElement extends HTMLElement {
createNavItem(item, index) { createNavItem(item, index) {
const wrap = createElement("div", "item-wrap"); const wrap = createElement("div", "item-wrap");
const disabled = Boolean(item?.disabled); const disabled = Boolean(item?.disabled);
const label = disabled ? "عدم دسترسی" : String(item?.label || ""); const label = disabled ? "عدم دسترسی" : String(item?.title || "");
const control = this.createItemControl(item, index, "item"); const control = this.createItemControl(item, index, "item");
const icon = createElement("span", "icon"); const icon = createElement("span", "icon");

View File

@ -2,8 +2,8 @@ import type { ElementType, ReactNode } from "react";
export type AppSidebarItem = { export type AppSidebarItem = {
id?: string | number; id?: string | number;
label: string; title: string;
mobileLabel?: string; mobileTitle?: string;
icon?: ReactNode | ElementType; icon?: ReactNode | ElementType;
iconSvg?: string; iconSvg?: string;
href?: string; href?: string;