meganav.jsx 5.01 KB
// Full-viewport "全部导航" mega-menu, modeled after the reference screenshot.
const MegaNav = ({ onClose, onOpen }) => {
  const [activeSection, setActiveSection] = React.useState("sys");
  const cols = XLY.MEGA_COLUMNS[activeSection];

  return (
    <div style={{
      position: "fixed", inset: 0, zIndex: 100,
      background: "#1a2030", color: "var(--text-on-dark)",
      display: "flex", flexDirection: "column",
    }}>
      {/* Header */}
      <div style={{
        height: 36, flex: "none", display: "flex", alignItems: "center",
        padding: "0 10px", background: "#262d3a", borderBottom: "1px solid #1a1f2a",
      }}>
        <button
          onClick={onClose}
          style={{ display: "inline-flex", alignItems: "center", gap: 5, height: 28, padding: "0 10px", background: "rgba(58,142,224,0.18)", color: "#fff", border: "1px solid rgba(58,142,224,0.4)", cursor: "pointer", fontSize: 12 }}
        >
          <Ic.menu size={14} /> 全部导航
        </button>
        <button onClick={onClose} style={{ display: "inline-flex", alignItems: "center", gap: 5, height: 28, padding: "0 10px", background: "transparent", color: "var(--text-on-dark)", border: "none", cursor: "pointer", fontSize: 12, marginLeft: 4 }}>
          <Ic.home size={14} /> 主页
        </button>
        <div style={{ flex: 1 }} />
        <button onClick={onClose} title="关闭" style={{ width: 28, height: 28, background: "transparent", color: "var(--text-on-dark)", border: "none", cursor: "pointer" }}>
          <Ic.close size={14} />
        </button>
      </div>

      {/* Body */}
      <div style={{ flex: 1, display: "flex", overflow: "hidden", minHeight: 0 }}>
        {/* Left rail */}
        <div style={{
          width: 150, flex: "none", borderRight: "1px solid rgba(255,255,255,0.08)",
          overflow: "auto", padding: "8px 0",
        }}>
          {XLY.MEGA_NAV.map((s) => {
            const active = s.id === activeSection;
            return (
              <div
                key={s.id}
                onClick={() => setActiveSection(s.id)}
                style={{
                  display: "flex", alignItems: "center", gap: 8,
                  padding: "8px 14px", cursor: "pointer", fontSize: 12,
                  background: active ? "var(--accent)" : "transparent",
                  color: active ? "#fff" : "var(--text-on-dark)",
                  borderLeft: active ? "3px solid #fff" : "3px solid transparent",
                }}
                onMouseEnter={(e) => { if (!active) e.currentTarget.style.background = "rgba(255,255,255,0.06)"; }}
                onMouseLeave={(e) => { if (!active) e.currentTarget.style.background = "transparent"; }}
              >
                <Ic.folder size={13} />
                <span>{s.label}</span>
              </div>
            );
          })}
        </div>

        {/* Columns */}
        <div style={{ flex: 1, overflow: "auto", padding: "16px 24px" }}>
          {cols ? (
            <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(180px, 1fr))", gap: "0 24px" }}>
              {cols.map((col) => (
                <div key={col.title} style={{ marginBottom: 24 }}>
                  <div style={{ fontSize: 13, fontWeight: 500, color: "#fff", marginBottom: 10, paddingBottom: 6, borderBottom: "1px solid rgba(255,255,255,0.1)" }}>
                    {col.title}
                  </div>
                  <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                    {col.items.map((it, i) => {
                      const clickable = !!it.screen;
                      return (
                        <div
                          key={i}
                          onClick={clickable ? () => { onOpen(it.screen, it.label); onClose(); } : undefined}
                          style={{
                            fontSize: 12,
                            color: it.featured ? "var(--accent)" : "var(--text-on-dark-muted)",
                            cursor: clickable ? "pointer" : "default",
                            display: "inline-flex", alignItems: "center", gap: 4,
                            padding: "1px 0",
                          }}
                          onMouseEnter={(e) => { if (clickable) e.currentTarget.style.color = "#fff"; }}
                          onMouseLeave={(e) => { if (clickable) e.currentTarget.style.color = it.featured ? "var(--accent)" : "var(--text-on-dark-muted)"; }}
                        >
                          {it.label}
                          {it.featured ? <span style={{ color: "var(--warning)", fontSize: 10 }}>★</span> : null}
                        </div>
                      );
                    })}
                  </div>
                </div>
              ))}
            </div>
          ) : (
            <div style={{ color: "var(--text-on-dark-muted)", fontSize: 13, padding: 40 }}>
              {XLY.MEGA_NAV.find((s) => s.id === activeSection)?.label} · 模块开发中
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

window.MegaNav = MegaNav;