tango-ui-cw
Version:
A lightweight ui library with ClayW
1,794 lines • 120 kB
JavaScript
'use client';
import { jsx as s, jsxs as P, Fragment as Ne } from "react/jsx-runtime";
import te, { useState as Z, useRef as ke, useEffect as se, useContext as Ue, createContext as He, forwardRef as Lt, useCallback as oe, useMemo as Se, useId as Wt } from "react";
import { createPortal as Ut } from "react-dom";
import t from "prop-types";
import { twMerge as Ht } from "tailwind-merge";
const et = "tango:theme", tt = "tango:themeTokens", De = "light", Zt = [
"primary",
"input-accent",
"modal-ok-bg",
"drawer-ok-bg",
"datepicker-confirm-bg"
], Pt = He(null), Ot = () => typeof window < "u", ot = (e, o) => {
if (!Ot())
return o;
try {
const r = window.localStorage.getItem(e);
return r ? JSON.parse(r) : o;
} catch {
return o;
}
}, rt = (e, o) => {
if (Ot())
try {
window.localStorage.setItem(e, JSON.stringify(o));
} catch {
}
};
function Jr({ children: e }) {
const [o, r] = Z(De), n = ke(!1);
se(() => {
const d = ot(et, De);
d !== De && r(d === "dark" ? "dark" : "light"), n.current = !0;
}, []);
const [c, l] = Z(
() => ot(tt, {})
), a = ke(/* @__PURE__ */ new Set());
se(() => {
typeof document > "u" || (document.documentElement.dataset.theme = o);
}, [o]), se(() => {
n.current && rt(et, o);
}, [o]), se(() => {
if (typeof document > "u")
return;
const d = document.documentElement, g = new Set(Object.keys(c));
a.current.forEach((v) => {
g.has(v) || d.style.removeProperty(`--${v}`);
}), Object.entries(c).forEach(([v, w]) => {
w == null || w === "" ? d.style.removeProperty(`--${v}`) : d.style.setProperty(`--${v}`, String(w));
}), a.current = g, rt(tt, c);
}, [c]);
const i = (d) => {
l((g) => {
const v = typeof d == "function" ? d(g) : d;
return {
...g,
...v || {}
};
});
}, u = (d, g = Zt) => {
i((v) => {
const w = { ...v };
return g.forEach((C) => {
w[C] = d;
}), w;
});
}, h = () => {
l({});
}, m = () => {
r((d) => d === "dark" ? "light" : "dark");
};
return /* @__PURE__ */ s(
Pt.Provider,
{
value: {
theme: o,
setTheme: r,
toggleTheme: m,
themeTokens: c,
setThemeTokens: i,
setThemeColor: u,
resetThemeTokens: h
},
children: e
}
);
}
function Qr() {
return Ue(Pt);
}
const Gt = /* @__PURE__ */ new Set([
"root",
"slots",
"tw",
"className",
"css",
"style"
]), $e = {
tw: "",
css: {}
}, ye = (e) => typeof e == "object" && e !== null && !Array.isArray(e), Y = (e, o = "px") => typeof e == "number" ? `${e}${o}` : e, he = (e) => typeof e == "string" && e.startsWith("$") ? `var(--${e.slice(1)})` : e, Xt = (e) => e.includes("-") ? e.replace(/-([a-z])/g, (o, r) => r.toUpperCase()) : e, qt = (e) => /(color|background|border|fill|stroke|shadow)$/i.test(e), Jt = {
mt: (e, o) => {
e.marginTop = Y(o);
},
mr: (e, o) => {
e.marginRight = Y(o);
},
mb: (e, o) => {
e.marginBottom = Y(o);
},
ml: (e, o) => {
e.marginLeft = Y(o);
},
mx: (e, o) => {
e.marginLeft = Y(o), e.marginRight = Y(o);
},
my: (e, o) => {
e.marginTop = Y(o), e.marginBottom = Y(o);
},
m: (e, o) => {
e.margin = Y(o);
},
pt: (e, o) => {
e.paddingTop = Y(o);
},
pr: (e, o) => {
e.paddingRight = Y(o);
},
pb: (e, o) => {
e.paddingBottom = Y(o);
},
pl: (e, o) => {
e.paddingLeft = Y(o);
},
px: (e, o) => {
e.paddingLeft = Y(o), e.paddingRight = Y(o);
},
py: (e, o) => {
e.paddingTop = Y(o), e.paddingBottom = Y(o);
},
p: (e, o) => {
e.padding = Y(o);
},
g: (e, o) => {
e.gap = Y(o);
},
rg: (e, o) => {
e.rowGap = Y(o);
},
cg: (e, o) => {
e.columnGap = Y(o);
},
w: (e, o) => {
e.width = Y(o);
},
h: (e, o) => {
e.height = Y(o);
},
mw: (e, o) => {
e.minWidth = Y(o);
},
mh: (e, o) => {
e.minHeight = Y(o);
},
maxw: (e, o) => {
e.maxWidth = Y(o);
},
maxh: (e, o) => {
e.maxHeight = Y(o);
},
vw: (e, o) => {
e.width = typeof o == "number" ? `${o}vw` : o;
},
vh: (e, o) => {
e.height = typeof o == "number" ? `${o}vh` : o;
},
presentw: (e, o) => {
e.width = typeof o == "number" ? `${o}%` : o;
},
presenth: (e, o) => {
e.height = typeof o == "number" ? `${o}%` : o;
},
size: (e, o) => {
e.fontSize = Y(o);
},
fw: (e, o) => {
e.fontWeight = o;
},
fwb: (e) => {
e.fontWeight = "bold";
},
fwn: (e) => {
e.fontWeight = "normal";
},
tac: (e) => {
e.textAlign = "center";
},
tar: (e) => {
e.textAlign = "right";
},
tal: (e) => {
e.textAlign = "left";
},
lh: (e, o) => {
e.lineHeight = Y(o);
},
ls: (e, o) => {
e.letterSpacing = Y(o);
},
c: (e, o) => {
e.color = he(o);
},
bg: (e, o) => {
e.background = he(o);
},
bgc: (e, o) => {
e.backgroundColor = he(o);
},
b: (e, o) => {
e.border = o === 1 ? "1px solid var(--border)" : he(o);
},
br: (e, o) => {
e.borderRadius = Y(o);
},
bw: (e, o) => {
e.borderWidth = Y(o);
},
bs: (e, o) => {
e.borderStyle = o;
},
bColor: (e, o) => {
e.borderColor = he(o);
},
boxshadow: (e, o) => {
e.boxShadow = he(o);
},
bgSize: (e, o) => {
e.backgroundSize = o;
},
bgPosition: (e, o) => {
e.backgroundPosition = o;
},
bgRepeat: (e, o) => {
e.backgroundRepeat = o;
},
rel: (e) => {
e.position = "relative";
},
ab: (e) => {
e.position = "absolute";
},
fixed: (e) => {
e.position = "fixed";
},
sticky: (e) => {
e.position = "sticky";
},
center: (e) => {
e.position = "absolute", e.inset = 0, e.margin = "auto";
},
inset: (e, o) => {
e.inset = Y(o);
},
top: (e, o) => {
e.top = Y(o);
},
right: (e, o) => {
e.right = Y(o);
},
bottom: (e, o) => {
e.bottom = Y(o);
},
left: (e, o) => {
e.left = Y(o);
},
z: (e, o) => {
e.zIndex = o;
},
flex: (e) => {
e.display = "flex";
},
iflex: (e) => {
e.display = "inline-flex";
},
fd: (e, o) => {
e.flexDirection = o;
},
fwrap: (e, o = "wrap") => {
e.flexWrap = o;
},
aic: (e) => {
e.alignItems = "center";
},
ai: (e, o) => {
e.alignItems = o;
},
jcc: (e) => {
e.justifyContent = "center";
},
jc: (e, o) => {
e.justifyContent = o;
},
ac: (e, o) => {
e.alignContent = o;
},
as: (e, o) => {
e.alignSelf = o;
},
f: (e, o) => {
e.flex = typeof o == "number" ? o : `${o}`;
},
fl: (e) => {
e.float = "left";
},
fr: (e) => {
e.float = "right";
},
ar: (e, o) => {
e.aspectRatio = o;
},
tran: (e, o) => {
e.transition = typeof o == "number" ? `${o}s` : o;
},
op: (e, o) => {
e.opacity = o;
},
oh: (e) => {
e.overflow = "hidden";
},
ohauto: (e) => {
e.overflow = "auto";
},
oxh: (e) => {
e.overflowX = "hidden";
},
oxa: (e) => {
e.overflowX = "auto";
},
oyh: (e) => {
e.overflowY = "hidden";
},
oya: (e) => {
e.overflowY = "auto";
},
cur: (e, o) => {
e.cursor = o;
},
pe: (e, o) => {
e.pointerEvents = o;
},
boxsizing: (e) => {
e.boxSizing = "border-box";
},
none: (e) => {
e.display = "none";
},
block: (e) => {
e.display = "block";
},
inline: (e) => {
e.display = "inline";
},
ib: (e) => {
e.display = "inline-block";
},
hidden: (e) => {
e.visibility = "hidden";
},
shown: (e) => {
e.visibility = "visible";
}
}, ze = (e = {}) => ye(e) ? Object.entries(e).reduce((o, [r, n]) => {
if (Gt.has(r))
return o;
const c = Jt[r];
if (c)
return c(o, n), o;
const l = Xt(r), a = typeof n == "string" && (n.startsWith("$") || qt(l)) ? he(n) : n;
return o[l] = a, o;
}, {}) : {}, I = (...e) => {
const o = e.filter(Boolean).join(" ").trim();
return o ? Ht(o) : "";
}, Oe = (e) => {
if (typeof e == "string")
return { tw: e, css: {} };
if (!ye(e))
return { ...$e };
if (!("tw" in e || "className" in e || "css" in e || "style" in e))
return {
tw: "",
css: ze(e)
};
const r = [e.className, e.tw].filter(Boolean).join(" "), n = ye(e.css) ? ze(e.css) : {}, c = ye(e.style) ? ze(e.style) : {};
return {
tw: r,
css: {
...n,
...c
}
};
}, Qt = (e, o) => ye(e) ? "root" in e || "slots" in e || "tw" in e || "className" in e || "css" in e || "style" in e ? !0 : o.some((r) => r !== "root" && r in e) : !1, eo = (e) => {
const o = {};
return e.forEach((r) => {
o[r] = { ...$e };
}), o.root || (o.root = { ...$e }), o;
}, H = (e, o = ["root"]) => {
const r = eo(o);
if (typeof e == "string")
return r.root.tw = e, r;
if (!ye(e))
return r;
if (!Qt(e, o))
return r.root.css = ze(e), r;
const n = Oe({
tw: [e.className, e.tw].filter(Boolean).join(" "),
css: e.css,
style: e.style
}), c = Oe(e.root);
r.root = {
tw: I(n.tw, c.tw),
css: {
...n.css,
...c.css
}
};
const l = ye(e.slots) ? e.slots : {};
return Object.keys(r).forEach((a) => {
if (a === "root")
return;
const i = Oe(e[a]), u = Oe(l[a]);
r[a] = {
tw: I(i.tw, u.tw),
css: {
...i.css,
...u.css
}
};
}), r;
}, b = ({
baseClassName: e = "",
className: o = "",
baseStyle: r = {},
style: n = {},
sxSlot: c = $e
} = {}) => ({
className: I(e, o, c.tw),
style: {
...r || {},
...c.css || {},
...n || {}
}
}), to = ["root", "icon", "content"], st = {
success: "text-[var(--notice-success-text)]",
fail: "text-[var(--notice-fail-text)]",
caution: "text-[var(--notice-caution-text)]"
}, at = {
default: {
base: "fixed top-5 left-1/2 -translate-x-1/2",
enter: "animate-[noticeSlideDown_0.3s_cubic-bezier(0.22,1,0.36,1)_forwards]"
},
md: {
base: "fixed bottom-5 left-5",
enter: "animate-[noticeSlideFromBottom_0.3s_ease-out_forwards]"
}
};
function oo(e, o) {
const {
type: r = "success",
icon: n,
message: c,
variant: l = "default",
duration: a = 3e3,
onClose: i,
sx: u = {},
style: h = {},
className: m = "",
...d
} = e, [g, v] = Z(!1), w = st[r] ? r : "success", C = at[l] ? l : "default", F = H(u, to), O = oe(() => {
v(!0);
const _ = setTimeout(() => i == null ? void 0 : i(), 300);
return () => clearTimeout(_);
}, [i]);
se(() => {
if (!i || a <= 0) return;
const _ = setTimeout(O, a);
return () => clearTimeout(_);
}, [i, a, O]);
const y = at[C], x = C === "default" ? "animate-[noticeSlideUpFade_0.3s_ease-in_forwards]" : "animate-[noticeSlideToBottom_0.3s_ease-in_forwards]", T = b({
baseClassName: I(
"inline-flex items-center gap-2 px-3 py-2 text-sm z-[999]",
"rounded-[var(--notice-radius)]",
"bg-[var(--notice-bg)] text-[var(--notice-foreground)]",
"shadow-[var(--notice-shadow)]",
y.base,
g ? x : y.enter,
C === "md" && st[w]
),
className: m,
sxSlot: F.root,
baseStyle: { borderRadius: "var(--notice-radius)" },
style: h
}), p = b({
baseClassName: "flex-shrink-0 text-[var(--notice-foreground)]",
sxSlot: F.icon
}), S = b({
baseClassName: "inline-block",
sxSlot: F.content
});
return /* @__PURE__ */ P("div", { ref: o, role: "alert", className: T.className, style: T.style, ...d, children: [
C !== "md" && n && /* @__PURE__ */ s("span", { className: p.className, style: p.style, children: n }),
/* @__PURE__ */ s("span", { className: S.className, style: S.style, children: c })
] });
}
const Ze = Lt(oo);
Ze.displayName = "Notice";
Ze.propTypes = {
type: t.oneOf(["success", "fail", "caution"]),
icon: t.node,
message: t.node,
variant: t.oneOf(["default", "md"]),
duration: t.number,
onClose: t.func,
sx: t.oneOfType([t.string, t.object]),
style: t.object,
className: t.string
};
const _t = He(null), ro = /* @__PURE__ */ s("svg", { viewBox: "0 0 1024 1024", width: "1.2em", height: "1.2em", children: /* @__PURE__ */ s(
"path",
{
d: "M874.119618 149.859922A510.816461 510.816461 0 0 0 511.997 0.00208a509.910462 509.910462 0 0 0-362.119618 149.857842c-199.817789 199.679789-199.817789 524.581447 0 724.260236a509.969462 509.969462 0 0 0 362.119618 149.857842A508.872463 508.872463 0 0 0 874.119618 874.120158c199.836789-199.679789 199.836789-524.581447 0-724.260236zM814.94268 378.210681L470.999043 744.132295a15.359984 15.359984 0 0 1-5.887994 4.095996c-1.751998 1.180999-2.913997 2.362998-5.276994 2.913997a34.499964 34.499964 0 0 1-13.469986 2.914997 45.547952 45.547952 0 0 1-12.897986-2.303998l-4.095996-2.363997a45.291952 45.291952 0 0 1-7.009992-4.095996l-196.902793-193.789796a34.126964 34.126964 0 0 1-10.555989-25.186973c0-9.37399 3.583996-18.74698 9.98399-25.186974a36.429962 36.429962 0 0 1 50.372947 0l169.98382 167.423824L763.389735 330.220732a37.059961 37.059961 0 0 1 50.371947-1.732998 33.647965 33.647965 0 0 1 11.165988 25.186973 35.544963 35.544963 0 0 1-9.98399 24.575974v-0.04z m0 0",
fill: "var(--notice-success-text)"
}
) }), so = /* @__PURE__ */ s("svg", { viewBox: "0 0 1024 1024", width: "1.2em", height: "1.2em", children: /* @__PURE__ */ s(
"path",
{
d: "M549.044706 512l166.189176-166.249412a26.383059 26.383059 0 0 0 0-36.98447 26.383059 26.383059 0 0 0-37.044706 0L512 475.015529l-166.249412-166.249411a26.383059 26.383059 0 0 0-36.98447 0 26.383059 26.383059 0 0 0 0 37.044706L475.015529 512l-166.249411 166.249412a26.383059 26.383059 0 0 0 0 36.98447 26.383059 26.383059 0 0 0 37.044706 0L512 548.984471l166.249412 166.249411a26.383059 26.383059 0 0 0 36.98447 0 26.383059 26.383059 0 0 0 0-37.044706L548.984471 512zM512 1024a512 512 0 1 1 0-1024 512 512 0 0 1 0 1024z",
fill: "var(--notice-fail-text)"
}
) }), ao = /* @__PURE__ */ P("svg", { viewBox: "0 0 1024 1024", width: "1.2em", height: "1.2em", children: [
/* @__PURE__ */ s(
"path",
{
d: "M512 909.061224c-218.906122 0-397.061224-178.155102-397.061224-397.061224s178.155102-397.061224 397.061224-397.061224 397.061224 178.155102 397.061224 397.061224-178.155102 397.061224-397.061224 397.061224z",
fill: "var(--notice-caution-text)"
}
),
/* @__PURE__ */ s(
"path",
{
d: "M512 690.677551m-31.346939 0a31.346939 31.346939 0 1 0 62.693878 0 31.346939 31.346939 0 1 0-62.693878 0Z",
fill: "var(--notice-fail-text)"
}
),
/* @__PURE__ */ s(
"path",
{
d: "M512 584.097959c-11.493878 0-20.897959-9.404082-20.897959-20.897959v-261.22449c0-11.493878 9.404082-20.897959 20.897959-20.897959s20.897959 9.404082 20.897959 20.897959v261.22449c0 12.016327-9.404082 20.897959-20.897959 20.897959z",
fill: "var(--notice-fail-text)"
}
)
] }), no = { success: ro, fail: so, caution: ao };
function es({ children: e }) {
const [o, r] = Z([]), [n, c] = Z(!1);
se(() => {
c(!0);
}, []);
const l = oe((i) => {
r((u) => u.filter((h) => h.id !== i));
}, []), a = oe((i, u, h = "default") => {
const m = Date.now() + Math.random();
r((d) => [
...d,
{ id: m, type: i, message: u, variant: h, icon: no[i] }
]);
}, []);
return /* @__PURE__ */ P(_t.Provider, { value: { add: a, remove: l }, children: [
e,
n && Ut(
/* @__PURE__ */ s("div", { id: "notification-container", className: "flex flex-col items-center gap-2", children: o.map((i) => /* @__PURE__ */ s(Ze, { ...i, onClose: () => l(i.id) }, i.id)) }),
document.body
)
] });
}
function lo() {
const e = Ue(_t);
if (!e)
throw new Error("useNotice must be used inside <NoticeProvider />");
return e;
}
function ts() {
const { add: e } = lo();
return {
success: (o) => e("success", o),
fail: (o) => e("fail", o),
caution: (o) => e("caution", o),
md: {
success: (o) => e("success", o, "md"),
fail: (o) => e("fail", o, "md"),
caution: (o) => e("caution", o, "md")
}
};
}
const At = "tango:locale", xe = "zh-CN", co = {
zh: "zh-CN",
ZH: "zh-CN",
"zh-CN": "zh-CN",
"zh-cn": "zh-CN",
cn: "zh-CN",
CN: "zh-CN",
en: "en-US",
EN: "en-US",
"en-US": "en-US",
"en-us": "en-US",
us: "en-US",
US: "en-US"
}, Mt = {
"zh-CN": {
button: {
default: "按钮",
loading: "加载中",
iconAlt: "图标",
toggle: "切换",
light: "浅色",
dark: "暗色",
blue: "蓝色",
green: "绿色",
token: "自定义词条",
reset: "重置",
locale: "语言",
chinese: "中文",
english: "英文",
successDemo: "成功",
outlineDemo: "描边",
submit: "提交",
confirm: "确认",
cancel: "取消",
search: "搜索",
save: "保存",
delete: "删除",
back: "返回",
next: "下一步",
prev: "上一步",
add: "新增"
},
banner: {
cancel: "取消",
action: "操作"
},
colorpicker: {
hex: "HEX",
rgb: "RGB",
hsl: "HSL"
},
date: {
weekdayPrefix: "星期",
weekdayShortPrefix: "周"
},
datepicker: {
placeholder: "YYYY-MM-DD",
placeholderTime: "YYYY-MM-DD HH:mm",
timeLabel: "时间",
confirm: "确定",
cancel: "关闭",
prevMonth: "上一月",
nextMonth: "下一月"
},
drawer: {
title: "基础标题",
okText: "确定",
cancelText: "取消",
closeAriaLabel: "关闭"
},
modal: {
title: "基础标题",
okText: "确定",
cancelText: "取消",
closeAriaLabel: "关闭"
},
search: {
placeholder: "请输入内容",
btnText: "搜索"
},
materialInput: {
label: ""
},
materialButton: {
default: "按钮",
loading: "加载中",
iconAlt: "图标"
},
table: {
empty: "暂无数据",
prev: "上一页",
next: "下一页",
page: "页",
total: "共 {total} 条",
perPage: "条/页"
}
},
"en-US": {
button: {
default: "Button",
loading: "Loading",
iconAlt: "icon",
toggle: "Toggle",
light: "Light",
dark: "Dark",
blue: "Blue",
green: "Green",
token: "Token",
reset: "Reset",
locale: "Locale",
chinese: "Chinese",
english: "English",
successDemo: "Success",
outlineDemo: "Outline",
submit: "Submit",
confirm: "Confirm",
cancel: "Cancel",
search: "Search",
save: "Save",
delete: "Delete",
back: "Back",
next: "Next",
prev: "Previous",
add: "Add"
},
banner: {
cancel: "Cancel",
action: "Action"
},
colorpicker: {
hex: "HEX",
rgb: "RGB",
hsl: "HSL"
},
date: {
weekdayPrefix: "",
weekdayShortPrefix: ""
},
datepicker: {
placeholder: "YYYY-MM-DD",
placeholderTime: "YYYY-MM-DD HH:mm",
timeLabel: "Time",
confirm: "Confirm",
cancel: "Close",
prevMonth: "Previous month",
nextMonth: "Next month"
},
drawer: {
title: "Drawer",
okText: "OK",
cancelText: "Cancel",
closeAriaLabel: "Close"
},
modal: {
title: "Modal",
okText: "OK",
cancelText: "Cancel",
closeAriaLabel: "Close"
},
search: {
placeholder: "Search...",
btnText: "Search"
},
materialInput: {
label: ""
},
materialButton: {
default: "Button",
loading: "Loading",
iconAlt: "icon"
},
table: {
empty: "No data",
prev: "Previous",
next: "Next",
page: "Page",
total: "{total} items",
perPage: "/ page"
}
}
}, We = () => {
}, zt = He({
locale: xe,
setLocale: We,
toggleLocale: We,
messages: Mt,
t: (e, o = "") => o
}), nt = (e) => typeof e == "object" && e !== null && !Array.isArray(e), Et = (e, o) => {
const r = { ...e };
return Object.entries(o || {}).forEach(([n, c]) => {
nt(c) && nt(r[n]) ? r[n] = Et(r[n], c) : r[n] = c;
}), r;
}, io = (e, o) => o.split(".").reduce((r, n) => {
if (r && Object.prototype.hasOwnProperty.call(r, n))
return r[n];
}, e), Ee = (e) => typeof e != "string" || !e.trim() ? xe : co[e] || e, uo = () => {
if (typeof window > "u")
return xe;
try {
const e = window.localStorage.getItem(At);
return Ee(e || xe);
} catch {
return xe;
}
};
function os({
children: e,
locale: o,
defaultLocale: r = xe,
onLocaleChange: n = We,
messages: c = {}
}) {
const l = Ee(r), a = o == null ? null : Ee(o), [i, u] = Z(
() => uo() || l
), h = a || i, m = (w) => {
const C = Ee(w);
a == null && u(C), n(C);
};
se(() => {
if (!(typeof window > "u"))
try {
window.localStorage.setItem(At, h);
} catch {
}
}, [h]);
const d = Se(
() => Et(Mt, c),
[c]
), g = () => {
m(h === "zh-CN" ? "en-US" : "zh-CN");
}, v = (w, C = "") => {
const F = d[h] || d[xe] || {}, O = io(F, w);
return O == null || O === "" ? C : String(O);
};
return /* @__PURE__ */ s(
zt.Provider,
{
value: {
locale: h,
setLocale: m,
toggleLocale: g,
messages: d,
t: v
},
children: e
}
);
}
function de() {
return Ue(zt);
}
const po = "_materialBtn_y97j8_8", mo = "_materialBtnSmall_y97j8_27", bo = "_materialBtnMedium_y97j8_33", go = "_materialBtnLarge_y97j8_39", fo = "_materialBtnHuge_y97j8_45", ho = "_materialBtnDisabled_y97j8_52", yo = "_ripple_y97j8_60", Ce = {
materialBtn: po,
materialBtnSmall: mo,
materialBtnMedium: bo,
materialBtnLarge: go,
materialBtnHuge: fo,
materialBtnDisabled: ho,
ripple: yo
}, lt = ["root", "content", "icon", "loading"], xo = { small: "small", medium: "medium", large: "large", huge: "huge" }, vo = { small: 12, medium: 14, large: 16, huge: 20 }, ct = {
default: {
backgroundColor: "var(--primary)",
color: "var(--primary-foreground)",
borderColor: "var(--border)",
borderWidth: "1px",
borderStyle: "solid"
},
transparent: {
backgroundColor: "var(--transparent)",
color: "var(--primary-foreground)",
borderColor: "var(--button-transparent-border)",
borderWidth: "1px",
borderStyle: "solid"
},
danger: {
backgroundColor: "var(--destructive)",
color: "var(--destructive-foreground)",
borderColor: "transparent",
borderWidth: "1px",
borderStyle: "solid"
},
success: {
backgroundColor: "var(--success)",
color: "var(--success-foreground)",
borderColor: "transparent",
borderWidth: "1px",
borderStyle: "solid"
}
}, So = {
default: {
backgroundColor: "var(--transparent)",
color: "var(--button-outline-foreground)",
borderColor: "var(--border)",
borderWidth: "1px",
borderStyle: "solid"
},
transparent: {
backgroundColor: "var(--transparent)",
color: "var(--button-outline-foreground)",
borderColor: "var(--button-transparent-border)",
borderWidth: "1px",
borderStyle: "solid"
},
danger: {
backgroundColor: "var(--transparent)",
color: "var(--destructive)",
borderColor: "var(--destructive)",
borderWidth: "1px",
borderStyle: "solid"
},
success: {
backgroundColor: "var(--transparent)",
color: "var(--success)",
borderColor: "var(--success)",
borderWidth: "1px",
borderStyle: "solid"
}
}, No = {
backgroundColor: "var(--muted)",
color: "var(--muted-foreground)",
borderColor: "transparent",
borderWidth: "1px",
borderStyle: "solid",
cursor: "not-allowed"
}, Re = {
default: "按钮",
loading: "加载中",
iconAlt: "图标"
}, wo = (e) => e.charAt(0).toUpperCase() + e.slice(1), Co = (e) => e === !0 || e === "light" || e === "dark" ? !0 : Array.isArray(e) && e.length > 0 ? e[0] === !0 || e[0] === "light" || e[0] === "dark" : !1, To = (e) => e === "light" ? "light" : e === "dark" || e === !0 || Array.isArray(e) && e.length >= 2 && e[1] === "dark" ? "dark" : "light", it = (e, o, r) => Object.prototype.hasOwnProperty.call(r, e) ? e : o;
function Ge(e) {
const {
type: o = "default",
size: r = "medium",
sx: n = {},
style: c = {},
className: l = "",
onClick: a = () => {
},
children: i,
disabled: u = !1,
outline: h = !1,
icon: m = null,
iconPosition: d = null,
loading: g = !1,
i18nKey: v = null,
localeText: w = {},
rippleColor: C,
"aria-label": F,
...O
} = e, { t: y } = de(), x = ke(null), T = it(r, "medium", xo), p = it(o, "default", ct), S = Co(g), _ = To(g), M = u || S, B = vo[T], A = d === "right" ? "right" : m || S ? "left" : null, k = C ?? "var(--material-button-ripple)", N = {
default: y("materialButton.default", Re.default),
loading: y("materialButton.loading", Re.loading),
iconAlt: y("materialButton.iconAlt", Re.iconAlt),
...w
}, W = (v && typeof N[v] == "string" ? N[v] : null) || (v ? y(`materialButton.${v}`, N.default) : N.default), D = S ? N.loading : W, E = i ?? D, $ = F || (i == null ? String(E || N.default) : void 0), z = H(n, lt), U = M ? No : h ? So[p] : ct[p], K = Ce[`materialBtn${wo(T)}`], G = z.root.css || {}, R = typeof n == "string" ? n : "", Q = /* @__PURE__ */ new Set([...lt, "root", "slots", "tw", "className", "css", "style"]), ue = typeof n == "object" ? Object.fromEntries(Object.entries(n).filter(([re]) => !Q.has(re))) : {}, be = [
Ce.materialBtn,
K,
M && Ce.materialBtnDisabled,
z.root.tw,
R,
l
].filter(Boolean).join(" "), ge = {
...U,
...ue,
...G,
...c
}, fe = b({
baseClassName: "inline-flex items-center relative z-[1]",
sxSlot: z.content
}), X = b({
baseClassName: "inline-flex items-center justify-center shrink-0 transition-all duration-300 relative z-[1]",
baseStyle: { width: `${B}px`, height: `${B}px` },
sxSlot: z.icon
}), J = b({
baseClassName: "inline-flex items-center justify-center shrink-0 animate-spin relative z-[1]",
baseStyle: {
width: `${B}px`,
height: `${B}px`,
color: _ === "light" ? "var(--button-loading-light)" : "var(--button-loading-dark)"
},
sxSlot: z.loading
}), j = oe(
(re) => {
if (M) return;
const ae = x.current;
if (!ae) return;
const f = document.createElement("span"), V = Math.max(ae.clientWidth, ae.clientHeight), ee = V / 2;
Object.assign(f.style, {
width: `${V}px`,
height: `${V}px`,
left: `${re.clientX - ae.getBoundingClientRect().left - ee}px`,
top: `${re.clientY - ae.getBoundingClientRect().top - ee}px`
}), f.className = Ce.ripple, f.style.background = k;
const ce = ae.querySelector(`.${Ce.ripple}`);
ce && ce.remove(), ae.appendChild(f);
},
[M, k]
), q = () => m ? typeof m == "string" ? /* @__PURE__ */ s(
"img",
{
src: m,
alt: N.iconAlt,
className: X.className,
style: X.style,
"aria-hidden": "true"
}
) : te.isValidElement(m) ? te.cloneElement(m, {
className: I(X.className, m.props.className),
style: { ...X.style, ...m.props.style },
"aria-hidden": !0
}) : typeof m == "function" ? /* @__PURE__ */ s(
m,
{
className: X.className,
style: X.style,
"aria-hidden": "true"
}
) : /* @__PURE__ */ s("span", { className: X.className, style: X.style, "aria-hidden": "true", children: m }) : null, le = () => /* @__PURE__ */ s(
"svg",
{
viewBox: "0 0 1024 1024",
role: "presentation",
className: J.className,
style: J.style,
"aria-hidden": "true",
children: /* @__PURE__ */ s(
"path",
{
d: "M512 1024A512 512 0 0 1 0 512a32 32 0 0 1 64 0 448 448 0 0 0 896 0 32 32 0 0 1 64 0 512 512 0 0 1-512 512z",
fill: "currentColor"
}
)
}
);
return /* @__PURE__ */ P(
"button",
{
ref: x,
className: be,
style: ge,
onClick: (re) => {
j(re), a == null || a(re);
},
disabled: M,
"aria-label": $,
"data-variant": p,
"data-size": T,
"data-icon-position": A || void 0,
...O,
children: [
A === "left" && /* @__PURE__ */ P(Ne, { children: [
S && le(),
!S && m && q()
] }),
/* @__PURE__ */ s("span", { className: fe.className, style: fe.style, children: E }),
A === "right" && /* @__PURE__ */ P(Ne, { children: [
S && le(),
!S && m && q()
] })
]
}
);
}
Ge.propTypes = {
type: t.oneOf(["default", "transparent", "danger", "success"]),
size: t.oneOf(["small", "medium", "large", "huge"]),
sx: t.oneOfType([t.object, t.string]),
style: t.object,
onClick: t.func,
className: t.string,
children: t.node,
disabled: t.bool,
outline: t.bool,
icon: t.oneOfType([
t.elementType,
t.node,
t.string
]),
iconPosition: t.oneOf(["left", "right"]),
loading: t.oneOfType([
t.bool,
t.oneOf(["light", "dark"]),
t.array
]),
i18nKey: t.string,
localeText: t.object,
rippleColor: t.string
};
const ko = ["root", "content", "icon", "loading"], Ve = {
default: "按钮",
loading: "加载中",
iconAlt: "图标"
}, Lo = "inline-flex select-none items-center justify-center whitespace-nowrap rounded-[var(--radius)] border align-middle font-medium tracking-[0.5px] transition-all duration-300 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--input-accent)] focus-visible:ring-offset-2", Ye = {
small: {
iconSize: 12,
className: "text-xs px-2 py-1 gap-1"
},
medium: {
iconSize: 14,
className: "text-sm px-4 py-2 gap-1.5"
},
large: {
iconSize: 16,
className: "text-base px-5 py-3 gap-2"
},
huge: {
iconSize: 20,
className: "text-[25px] px-[45px] py-[18px] gap-3"
}
}, dt = {
default: "bg-[var(--primary)] text-[var(--primary-foreground)] border-[var(--border)] hover:shadow-[0_0_0.4em_0_var(--button-shadow-default)]",
transparent: "bg-[var(--transparent)] text-[var(--primary-foreground)] border-[var(--button-transparent-border)] hover:shadow-[0_0_0.4em_0_var(--button-shadow-default)]",
danger: "bg-[var(--destructive)] text-[var(--destructive-foreground)] border-transparent hover:shadow-[0_0_0.4em_0_var(--destructive)]",
success: "bg-[var(--success)] text-[var(--success-foreground)] border-transparent hover:shadow-[0_0_0.4em_0_var(--success)]"
}, Po = "bg-[var(--transparent)]", Oo = {
default: "text-[var(--button-outline-foreground)] border-[var(--border)]",
transparent: "text-[var(--button-outline-foreground)] border-[var(--button-transparent-border)]",
danger: "text-[var(--destructive)] border-[var(--destructive)]",
success: "text-[var(--success)] border-[var(--success)]"
}, _o = "shadow-[var(--button-enu-shadow)] hover:shadow-[var(--button-enu-hover-shadow)] active:translate-y-px active:shadow-[var(--button-enu-active-shadow)]", Ao = {
default: "bg-[var(--button-enu-bg)] text-[var(--button-enu-fg)] border-transparent",
transparent: "bg-[var(--transparent)] text-[var(--button-enu-fg)] border-[var(--button-transparent-border)]",
danger: "bg-[var(--destructive)] text-[var(--destructive-foreground)] border-transparent",
success: "bg-[var(--success)] text-[var(--success-foreground)] border-transparent"
}, Mo = "bg-[var(--muted)] text-[var(--muted-foreground)] border-transparent cursor-not-allowed shadow-none hover:shadow-none", zo = (e) => e === !0 || e === "light" || e === "dark" ? !0 : Array.isArray(e) && e.length > 0 ? e[0] === !0 || e[0] === "light" || e[0] === "dark" : !1, Eo = (e) => e === "light" ? "light" : e === "dark" || e === !0 || Array.isArray(e) && e.length >= 2 && e[1] === "dark" ? "dark" : "light", ut = (e, o, r) => Object.prototype.hasOwnProperty.call(r, e) ? e : o;
function ie(e) {
const {
type: o = "default",
size: r = "medium",
sx: n = {},
style: c = {},
className: l = "",
onClick: a = () => {
},
children: i,
disabled: u = !1,
outline: h = !1,
enu: m = !1,
icon: d = null,
iconPosition: g = null,
loading: v = !1,
i18nKey: w = null,
localeText: C = {},
"aria-label": F,
...O
} = e, { t: y } = de(), x = ut(r, "medium", Ye), T = ut(o, "default", dt), p = zo(v), S = Eo(v), _ = u || p, M = Ye[x].iconSize, B = g === "right" ? "right" : d || p ? "left" : null, A = H(n, ko), k = {
default: y("button.default", Ve.default),
loading: y("button.loading", Ve.loading),
iconAlt: y("button.iconAlt", Ve.iconAlt),
...C
}, L = (w && typeof k[w] == "string" ? k[w] : null) || (w ? y(`button.${w}`, k.default) : k.default), W = p ? k.loading : L, D = i ?? W, E = F || (i == null ? String(D || k.default) : void 0);
let $ = dt[T];
h && ($ = I(
$,
Po,
Oo[T]
)), m && ($ = I(
$,
_o,
Ao[T]
));
const z = b({
// 顺序固定为:baseTw -> className -> sx.tw,sx 能稳定覆盖普通 Tailwind。
baseClassName: I(
Lo,
Ye[x].className,
$,
_ && Mo,
p && "cursor-wait"
),
className: l,
style: c,
sxSlot: A.root
}), U = b({
baseClassName: "inline-flex items-center",
sxSlot: A.content
}), K = b({
baseClassName: "inline-flex items-center justify-center shrink-0 transition-all duration-300",
baseStyle: {
width: `${M}px`,
height: `${M}px`
},
sxSlot: A.icon
}), G = b({
baseClassName: "inline-flex items-center justify-center shrink-0 animate-spin",
baseStyle: {
width: `${M}px`,
height: `${M}px`,
color: S === "light" ? "var(--button-loading-light)" : "var(--button-loading-dark)"
},
sxSlot: A.loading
}), R = () => d ? typeof d == "string" ? /* @__PURE__ */ s(
"img",
{
src: d,
alt: k.iconAlt,
className: K.className,
style: K.style,
"aria-hidden": "true"
}
) : te.isValidElement(d) ? te.cloneElement(d, {
className: I(K.className, d.props.className),
style: {
...K.style,
...d.props.style
},
"aria-hidden": !0
}) : typeof d == "function" ? /* @__PURE__ */ s(
d,
{
className: K.className,
style: K.style,
"aria-hidden": "true"
}
) : /* @__PURE__ */ s("span", { className: K.className, style: K.style, "aria-hidden": "true", children: d }) : null, Q = () => /* @__PURE__ */ s(
"svg",
{
viewBox: "0 0 1024 1024",
role: "presentation",
className: G.className,
style: G.style,
"aria-hidden": "true",
children: /* @__PURE__ */ s(
"path",
{
d: "M512 1024A512 512 0 0 1 0 512a32 32 0 0 1 64 0 448 448 0 0 0 896 0 32 32 0 0 1 64 0 512 512 0 0 1-512 512z",
fill: "currentColor"
}
)
}
);
return /* @__PURE__ */ P(
"button",
{
className: z.className,
style: z.style,
onClick: a,
disabled: _,
"aria-label": E,
"data-variant": T,
"data-size": x,
"data-icon-position": B || void 0,
...O,
children: [
B === "left" && /* @__PURE__ */ P(Ne, { children: [
p && Q(),
!p && d && R()
] }),
/* @__PURE__ */ s("span", { className: U.className, style: U.style, children: D }),
B === "right" && /* @__PURE__ */ P(Ne, { children: [
p && Q(),
!p && d && R()
] })
]
}
);
}
ie.propTypes = {
type: t.oneOf(["default", "transparent", "danger", "success"]),
size: t.oneOf(["small", "medium", "large", "huge"]),
sx: t.oneOfType([t.object, t.string]),
style: t.object,
onClick: t.func,
className: t.string,
children: t.node,
disabled: t.bool,
outline: t.bool,
enu: t.bool,
icon: t.oneOfType([
t.elementType,
t.node,
t.string
]),
iconPosition: t.oneOf(["left", "right"]),
loading: t.oneOfType([
t.bool,
t.oneOf(["light", "dark"]),
t.array
]),
i18nKey: t.string,
localeText: t.object
};
ie.MaterialButton = Ge;
const $o = ["root", "input", "label"], Bo = {
small: "small",
medium: "medium",
large: "large",
huge: "huge"
}, Io = {
small: { wrapper: "h-10 text-sm", label: "text-sm", labelFloat: "text-[10px]", pt: "pt-5" },
medium: { wrapper: "h-12 text-base", label: "text-base", labelFloat: "text-xs", pt: "pt-6" },
large: { wrapper: "h-14 text-lg", label: "text-lg", labelFloat: "text-sm", pt: "pt-7" },
huge: { wrapper: "h-16 text-xl", label: "text-xl", labelFloat: "text-base", pt: "pt-8" }
}, jo = {
label: ""
}, Fo = (e, o, r) => Object.prototype.hasOwnProperty.call(r, e) ? e : o;
function Xe(e) {
const {
size: o = "medium",
sx: r = {},
style: n = {},
className: c = "",
onChange: l,
value: a,
defaultValue: i,
disabled: u = !1,
label: h,
localeText: m,
type: d = "text",
...g
} = e, { t: v } = de(), w = Fo(o, "medium", Bo), C = a !== void 0, [F, O] = Z(i ?? ""), [y, x] = Z(!1), T = C ? a : F, p = y || String(T).length > 0, S = h ?? (m == null ? void 0 : m.label) ?? v("materialInput.label", jo.label), _ = H(r, $o), M = {
tw: I(_.root.tw, _.input.tw),
css: { ..._.root.css, ..._.input.css }
}, B = I("relative inline-flex", _.root.tw), A = Io[w], k = I(
"w-[300px] bg-transparent text-[var(--foreground)] outline-none transition-all duration-200 ease-in-out",
"border-b border-b-[var(--border)]",
"hover:border-b-[var(--input-accent)]",
"focus:border-b-[var(--input-accent)]",
u && "text-[var(--muted-foreground)] border-b-[var(--muted)] cursor-not-allowed hover:border-b-[var(--muted)]",
A.wrapper,
A.pt
), N = b({
baseClassName: k,
className: c,
style: n,
sxSlot: M
}), L = I(
"absolute left-0 transition-all duration-200 ease-in-out pointer-events-none",
p ? `top-1 ${A.labelFloat} text-[var(--input-accent)]` : `top-1/2 -translate-y-1/2 ${A.label} text-[var(--muted-foreground)]`,
y && p && "text-[var(--input-accent)]",
u && "text-[var(--muted-foreground)]",
_.label.tw
), W = b({
baseClassName: L,
sxSlot: { tw: "", css: _.label.css }
}), D = oe((G) => {
const R = G.target.value;
C || O(R), l == null || l(R);
}, [C, l]), E = oe((G) => {
var R;
x(!0), (R = g.onFocus) == null || R.call(g, G);
}, [g.onFocus]), $ = oe((G) => {
var R;
x(!1), (R = g.onBlur) == null || R.call(g, G);
}, [g.onBlur]), { onFocus: z, onBlur: U, ...K } = g;
return /* @__PURE__ */ P("div", { className: B, children: [
/* @__PURE__ */ s(
"input",
{
...K,
type: d,
className: N.className,
style: N.style,
value: T,
disabled: u || void 0,
onChange: D,
onFocus: E,
onBlur: $,
"aria-label": S || void 0
}
),
S && /* @__PURE__ */ s("label", { className: W.className, style: W.style, children: S })
] });
}
Xe.propTypes = {
size: t.oneOf(["small", "medium", "large", "huge"]),
sx: t.oneOfType([t.object, t.string]),
style: t.object,
className: t.string,
onChange: t.func,
value: t.string,
defaultValue: t.string,
disabled: t.bool,
label: t.string,
localeText: t.shape({
label: t.string
}),
type: t.string
};
const Do = ["root", "input"], Ro = {
small: "small",
medium: "medium",
large: "large",
huge: "huge"
}, Vo = {
small: "h-8 text-xs px-2.5",
medium: "h-10 text-sm px-3",
large: "h-12 text-base px-3.5",
huge: "h-14 text-lg px-4"
}, Yo = (e, o, r) => Object.prototype.hasOwnProperty.call(r, e) ? e : o;
function qe(e) {
const {
type: o = "default",
size: r = "medium",
sx: n = {},
style: c = {},
className: l = "",
onClick: a,
onChange: i,
value: u,
defaultValue: h,
disabled: m = !1,
placeholder: d = "",
maxlength: g = 524288,
status: v,
...w
} = e, C = Yo(r, "medium", Ro), F = o === "textarea", O = o === "password", y = v === "error", x = H(n, Do), T = {
tw: I(x.root.tw, x.input.tw),
css: { ...x.root.css, ...x.input.css }
}, p = I("inline-flex", x.root.tw), S = I(
"w-[300px] rounded-[var(--radius)] border bg-[var(--input-bg)] text-[var(--foreground)] outline-none transition-all duration-200 ease-in-out",
"border-[var(--border)] shadow-[var(--input-shadow)]",
"hover:border-[var(--input-accent)]",
"focus:border-[var(--input-accent)] focus:shadow-[var(--input-focus-shadow)]",
y && "border-[var(--input-error-border)] bg-[var(--input-error-bg)] text-[var(--input-error-fg)] hover:border-[var(--input-error-border)] focus:shadow-[var(--input-error-focus-shadow)]",
m && "bg-[var(--muted)] text-[var(--muted-foreground)] border-[var(--muted)] cursor-not-allowed shadow-none hover:border-[var(--muted)] focus:shadow-none",
Vo[C]
), _ = b({
baseClassName: S,
className: l,
style: c,
sxSlot: T
}), M = u !== void 0, B = {
className: _.className,
style: _.style,
onClick: a,
onChange: i ? (A) => i(A.target.value) : void 0,
value: M ? u : void 0,
defaultValue: M ? void 0 : h ?? "",
disabled: m || void 0,
placeholder: d,
maxLength: g,
"aria-invalid": y || void 0,
...w
};
return (
// 原因:password input 不在 form 内,浏览器会发出 [DOM] Password field is not contained in a form 警告
// 导致的问题:控制台持续出现 DOM 警告,autoComplete 属性无法完全抑制
// 解决办法:password 类型用 <form> 包裹 input,阻止默认提交行为,满足浏览器规范
// fixed by clayw on 20260523 night
/* @__PURE__ */ s("div", { className: p, children: O ? /* @__PURE__ */ s(
"form",
{
onSubmit: (A) => A.preventDefault(),
style: { display: "inline-flex" },
autoComplete: "off",
children: /* @__PURE__ */ s(
"input",
{
...B,
type: "password"
}
)
}
) : F ? /* @__PURE__ */ s(
"textarea",
{
...B,
className: `${B.className} min-h-[80px] py-2 resize-y`
}
) : /* @__PURE__ */ s(
"input",
{
...B,
type: "text"
}
) })
);
}
qe.propTypes = {
type: t.oneOf(["default", "textarea", "password"]),
size: t.oneOf(["small", "medium", "large", "huge"]),
sx: t.oneOfType([t.object, t.string]),
style: t.object,
className: t.string,
onClick: t.func,
onChange: t.func,
value: t.string,
defaultValue: t.string,
disabled: t.bool,
placeholder: t.string,
maxlength: t.number,
status: t.oneOf(["default", "error"])
};
qe.MaterialInput = Xe;
const we = ["root"];
function Ko(e, o) {
const {
sx: r = {},
style: n = {},
className: c = "",
children: l,
...a
} = e, i = H(r, we), u = b({
baseClassName: "flex items-center px-4 bg-[var(--layout-header-bg)] text-[var(--layout-header-color)]",
className: c,
sxSlot: i.root,
baseStyle: {
height: "var(--layout-header-height)",
borderBottom: "1px solid var(--layout-border)"
},
style: n
});
return /* @__PURE__ */ s(
"header",
{
ref: o,
className: u.className,
style: u.style,
...a,
children: l
}
);
}
const Be = te.forwardRef(Ko);
Be.displayName = "LayoutHeader";
Be.propTypes = {
sx: t.oneOfType([t.string, t.object]),
style: t.object,
className: t.string,
children: t.node
};
function Wo(e, o) {
const {
sx: r = {},
style: n = {},
className: c = "",
children: l,
...a
} = e, i = H(r, we), u = b({
baseClassName: "flex items-center px-4 bg-[var(--layout-footer-bg)] text-[var(--layout-footer-color)]",
className: c,
sxSlot: i.root,
baseStyle: {
height: "var(--layout-footer-height)",
borderTop: "1px solid var(--layout-border)"
},
style: n
});
return /* @__PURE__ */ s(
"footer",
{
ref: o,
className: u.className,
style: u.style,
...a,
children: l
}
);
}
const Ie = te.forwardRef(Wo);
Ie.displayName = "LayoutFooter";
Ie.propTypes = {
sx: t.oneOfType([t.string, t.object]),
style: t.object,
className: t.string,
children: t.node
};
function Uo(e, o) {
const {
sx: r = {},
style: n = {},
className: c = "",
width: l,
children: a,
...i
} = e, u = H(r, we), h = l ?? "var(--layout-sider-width)", m = b({
baseClassName: "overflow-auto flex flex-col bg-[var(--layout-sider-bg)] text-[var(--layout-sider-color)]",
className: c,
sxSlot: u.root,
baseStyle: {
width: h,
minWidth: h,
maxWidth: "100%",
borderRight: "1px solid var(--layout-border)"
},
style: n
});
return /* @__PURE__ */ s(
"aside",
{
ref: o,
className: m.className,
style: m.style,
...i,
children: a
}
);
}
const Le = te.forwardRef(Uo);
Le.displayName = "LayoutSider";
Le.propTypes = {
width: t.oneOfType([t.string, t.number]),
sx: t.oneOfType([t.string, t.object]),
style: t.object,
className: t.string,
children: t.node
};
function Ho(e, o) {
const {
sx: r = {},
style: n = {},
className: c = "",
width: l,
children: a,
...i
} = e, u = H(r, we), h = l ?? "var(--layout-toc-width)", m = b({
baseClassName: "overflow-auto flex flex-col bg-[var(--layout-toc-bg)] text-[var(--layout-toc-color)]",
className: c,
sxSlot: u.root,
baseStyle: {
width: h,
minWidth: h,
maxWidth: "100%",
borderLeft: "1px solid var(--layout-border)"
},
style: n
});
return /* @__PURE__ */ s(
"nav",
{
ref: o,
className: m.className,
style: m.style,
...i,
children: a
}
);
}
const Pe = te.forwardRef(Ho);
Pe.displayName = "LayoutToc";
Pe.propTypes = {
width: t.oneOfType([t.string, t.number]),
sx: t.oneOfType([t.string, t.object]),
style: t.object,
className: t.string,
children: t.node
};
function Zo(e, o) {
const {
sx: r = {},
style: n = {},
className: c = "",
children: l,
...a
} = e, i = H(r, we), u = b({
/**
*
* 这里记录了一次问题:backgroundColor、color 等写在 baseStyle(inline style)里,
* CSS 优先级高于任何 Tailwind class,所以 sx="bg-amber-400" 无法覆盖。
* sx.css 和 style 可以覆盖(同层级后展开覆盖前),但 Tailwind class 不行。
*
* 修复方案:将 backgroundColor 和 color 从 baseStyle 移到 baseClassName
* 用 Tailwind 任意值语法,这样默认值和用户覆盖都在 class 层级,tailwind-merge
* 可正确处理冲突。
*
* noted by clayw on 20260523 night
*
*/
baseClassName: (
// 原因:Content 默认 items-center justify-center 会导致内容垂直+水平居中,长页面内容显示异常
// 导致的问题:Content 区域内容始终居中,而非自然流动布局;窄屏时表格文字出现竖排
// 解决办法:移除 items-center justify-center,改为 flex-col 让内容自然从上往下流动
// fixed by clayw on 20260523 night
"flex-1 flex flex-col bg-[var(--layout-content-bg)] text-[var(--layout-content-color)]"
),
className: c,
sxSlot: i.root,
baseStyle: {},
style: n
});
return /* @__PURE__ */ s(
"main",
{
ref: o,
className: u.className,
style: u.style,
...a,
children: l
}
);
}
const je = te.forwardRef(Zo);
je.displayName = "LayoutContent";
je.propTypes = {
sx: t.oneOfType([t.string, t.object]),
style: t.object,
className: t.string,
children: t.node
};
function Go(e, o) {
const {
sx: r = {},
style: n = {},
className: c = "",
hasSider: l,
children: a,
...i
} = e, u = H(r, we), h = l ?? te.Children.toArray(a).some(
(d) => {
var g, v;
return te.isValidElement(d) && (d.type === Le || d.type === Pe || ((g = d.type) == null ? void 0 : g.displayName) === "LayoutSider" || ((v = d.type) == null ? void 0 : v.displayName) === "LayoutToc");
}
), m = b({
baseClassName: I(
"flex flex-1 flex-col min-h-0",
h ? "md:flex-row" : ""
),
className: c,
sxSlot: u.root,
style: n
});
return /* @__PURE__ */ s(
"section",
{
ref: o,
className: m.className,
style: m.style,
...i,
children: a
}
);
}
const ne = te.forwardRef(Go);
ne.displayName = "Layout";
ne.Header = Be;
ne.Footer = Ie;
ne.Sider = Le;
ne.Content = je;
ne.Toc = Pe;
ne.propTypes = {
hasSider: t.bool,
sx: t.oneOfType([t.string, t.object]),
style: t.object,
className: t.string,
children: t.node
};
const Xo = Be, qo = Ie, Jo = Le, Qo = je, er = Pe, tr = ["root", "button", "list", "item"], $t = Symbol("LIST_IGNORE"), pt = /* @__PURE__ */ P("svg", { viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
/* @__PURE__ */ s("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z" }),
/* @__PURE__ */ s("path", { d: "M14 2v6h6" })
] }), mt = /* @__PURE__ */ s("svg", { viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ s("path", { d: "M18 6 6 18M6 6l12 12" }) });
function or(e, o) {
const {
sx: r = {},
style: n = {},
className: c = "",
accept: l = "image/*",
multiple: a = !1,
onChange: i = () => {
},
beforeUpload: u = () => {
},
files: h = [],
showUploadList: m = !0,
maxCount: d = 20,
maxSize: g = 100,
btnText: v = "选择文件",
btnStyle: w,
showSize: C = !0,
disabled: F = !1,
...O
} = e, y = Wt(), x = h || [], T = H(r, tr), p = oe(async (k, N) => {
if (!u) return !0;
try {
const L = await u(k, N);
return L === void 0 ? !0 : L;
} catch {
return !1;
}
}, [u]), S = oe(async (k) => {
const L = Array.from(k.target.files || []).filter((E) => E.size / 1024 / 1024 > g ? (console.warn(`[Tango Upload] ${E.name} 超过 ${g}MB,已被过滤`), !1) : !0), W = a ? L.slice(0, d) : L.slice(0, 1), D = [];
for (const E of W) {
const $ = await p(E, W);
if ($ === !1) {
console.warn(`[Tango Upload] ${E.name} 被 beforeUpload 拦截`);
continue;
}
if ($ === $t) {
console.warn(`[Tango Upload] ${E.name} 被 LIST_IGNORE 忽略`);
continue;
}
if ($ instanceof Blob) {
const z = $ instanceof File ? $ : new File([$], E.name, { type: E.type });
D.push(z);
} else
D.push(E);
}
k.target.value = "", i(D);
}, [a, d, g, p, i]), _ = oe((k, N) => {
const L = x.filter((W, D) => D !== N);
i(L);
}, [x, i]), M = b({