@turinhub/atomix-common-ui 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -2
- package/dist/AuthPanel-CTKx618F.cjs +2 -0
- package/dist/AuthPanel-CTKx618F.cjs.map +1 -0
- package/dist/AuthPanel-Cn_WwmjX.js +703 -0
- package/dist/AuthPanel-Cn_WwmjX.js.map +1 -0
- package/dist/PDFSidebar-4DtXqqzN.cjs +2 -0
- package/dist/PDFSidebar-4DtXqqzN.cjs.map +1 -0
- package/dist/PDFSidebar-ClnrF4Br.js +239 -0
- package/dist/PDFSidebar-ClnrF4Br.js.map +1 -0
- package/dist/auth.cjs +2 -0
- package/dist/auth.cjs.map +1 -0
- package/dist/auth.d.ts +11 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +9 -0
- package/dist/auth.js.map +1 -0
- package/dist/components/AuthLoginPanel.d.ts +55 -0
- package/dist/components/AuthLoginPanel.d.ts.map +1 -0
- package/dist/components/AuthPageShell.d.ts +11 -0
- package/dist/components/AuthPageShell.d.ts.map +1 -0
- package/dist/components/AuthPanel.d.ts +20 -0
- package/dist/components/AuthPanel.d.ts.map +1 -0
- package/dist/components/AuthRegisterPanel.d.ts +34 -0
- package/dist/components/AuthRegisterPanel.d.ts.map +1 -0
- package/dist/components/AuthVisualCarousel.d.ts +22 -0
- package/dist/components/AuthVisualCarousel.d.ts.map +1 -0
- package/dist/components/DataTable.d.ts +2 -2
- package/dist/components/DataTable.d.ts.map +1 -1
- package/dist/components/ImageReader.d.ts +44 -0
- package/dist/components/ImageReader.d.ts.map +1 -0
- package/dist/components/MarkdownReader.d.ts.map +1 -1
- package/dist/components/PDFReader.d.ts.map +1 -1
- package/dist/components/PDFSidebar.d.ts.map +1 -1
- package/dist/components/SimplePDFReader.d.ts.map +1 -1
- package/dist/components/TableHeader.d.ts.map +1 -1
- package/dist/components/TablePagination.d.ts +2 -1
- package/dist/components/TablePagination.d.ts.map +1 -1
- package/dist/components/VideoReader.d.ts +39 -0
- package/dist/components/VideoReader.d.ts.map +1 -0
- package/dist/components/media-utils.d.ts +9 -0
- package/dist/components/media-utils.d.ts.map +1 -0
- package/dist/components/ui/switch.d.ts +5 -0
- package/dist/components/ui/switch.d.ts.map +1 -0
- package/dist/data-table.cjs +1 -1
- package/dist/data-table.cjs.map +1 -1
- package/dist/data-table.js +83 -73
- package/dist/data-table.js.map +1 -1
- package/dist/file-upload.cjs +1 -1
- package/dist/file-upload.cjs.map +1 -1
- package/dist/file-upload.js +36 -36
- package/dist/file-upload.js.map +1 -1
- package/dist/image-reader.cjs +2 -0
- package/dist/image-reader.cjs.map +1 -0
- package/dist/image-reader.d.ts +3 -0
- package/dist/image-reader.d.ts.map +1 -0
- package/dist/image-reader.js +215 -0
- package/dist/image-reader.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/markdown-reader.cjs +1 -1
- package/dist/markdown-reader.cjs.map +1 -1
- package/dist/markdown-reader.js +28 -24
- package/dist/markdown-reader.js.map +1 -1
- package/dist/media-utils-5UPuocc1.js +23 -0
- package/dist/media-utils-5UPuocc1.js.map +1 -0
- package/dist/media-utils-X1dDYP9W.cjs +2 -0
- package/dist/media-utils-X1dDYP9W.cjs.map +1 -0
- package/dist/pdf-reader.cjs +1 -1
- package/dist/pdf-reader.cjs.map +1 -1
- package/dist/pdf-reader.js +170 -121
- package/dist/pdf-reader.js.map +1 -1
- package/dist/pdf-sidebar.cjs +1 -1
- package/dist/pdf-sidebar.js +1 -1
- package/dist/simple-pdf-reader.cjs +1 -1
- package/dist/simple-pdf-reader.cjs.map +1 -1
- package/dist/simple-pdf-reader.js +138 -105
- package/dist/simple-pdf-reader.js.map +1 -1
- package/dist/table-header.cjs +1 -1
- package/dist/table-header.cjs.map +1 -1
- package/dist/table-header.js +42 -34
- package/dist/table-header.js.map +1 -1
- package/dist/table-pagination.cjs +1 -1
- package/dist/table-pagination.cjs.map +1 -1
- package/dist/table-pagination.js +49 -43
- package/dist/table-pagination.js.map +1 -1
- package/dist/types/component-types.d.ts +2 -0
- package/dist/types/component-types.d.ts.map +1 -1
- package/dist/video-reader.cjs +2 -0
- package/dist/video-reader.cjs.map +1 -0
- package/dist/video-reader.d.ts +3 -0
- package/dist/video-reader.d.ts.map +1 -0
- package/dist/video-reader.js +158 -0
- package/dist/video-reader.js.map +1 -0
- package/package.json +32 -1
- package/dist/PDFSidebar-BBtucLK6.js +0 -232
- package/dist/PDFSidebar-BBtucLK6.js.map +0 -1
- package/dist/PDFSidebar-Di0D-yPS.cjs +0 -2
- package/dist/PDFSidebar-Di0D-yPS.cjs.map +0 -1
- package/dist/index-BiA_tnaq.cjs +0 -13
- package/dist/index-BiA_tnaq.cjs.map +0 -1
- package/dist/index-BypbGNpR.js +0 -18821
- package/dist/index-BypbGNpR.js.map +0 -1
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ pnpm add @turinhub/atomix-common-ui
|
|
|
52
52
|
npx shadcn-ui@latest init
|
|
53
53
|
|
|
54
54
|
# 安装需要的 UI 组件
|
|
55
|
-
npx shadcn-ui@latest add button card dialog input label select table skeleton dropdown-menu
|
|
55
|
+
npx shadcn-ui@latest add button card dialog input label select table skeleton dropdown-menu tabs
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
## 🚀 快速开始
|
|
@@ -91,9 +91,23 @@ import { dataTableUI } from '@/lib/ui-adapter';
|
|
|
91
91
|
data={users}
|
|
92
92
|
columns={columns}
|
|
93
93
|
rowKey="id"
|
|
94
|
+
onRow={(record) => ({
|
|
95
|
+
onClick: () => navigate(`/users/${record.id}`),
|
|
96
|
+
})}
|
|
97
|
+
actions={{
|
|
98
|
+
mode: 'collapsed',
|
|
99
|
+
items: [
|
|
100
|
+
{
|
|
101
|
+
label: '详情',
|
|
102
|
+
onClick: (record) => navigate(`/users/${record.id}`),
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
}}
|
|
94
106
|
/>
|
|
95
107
|
```
|
|
96
108
|
|
|
109
|
+
详情页跳转由业务侧路由处理,组件不会绑定特定 router。可以用 `onRow` 做整行点击跳转,也可以在 `actions.items` 的 `onClick` 中跳转;操作列会阻止点击事件冒泡,避免点击“详情”等操作时同时触发行点击。
|
|
110
|
+
|
|
97
111
|
## 📚 组件列表
|
|
98
112
|
|
|
99
113
|
- **DataTable** - 功能强大的数据表格组件
|
|
@@ -103,11 +117,15 @@ import { dataTableUI } from '@/lib/ui-adapter';
|
|
|
103
117
|
- **ThemeSwitcher** - 主题切换组件(完整版,支持下拉菜单)
|
|
104
118
|
- **ThemeSwitcherContent** - 主题切换内容组件(轻量版,可嵌入)
|
|
105
119
|
- **FileUpload** - 标准文件上传界面(支持拖拽、校验、进度、失败重试,可接入 Tale SDK 上传流程)
|
|
120
|
+
- **ImageReader** - 图片在线预览组件(支持常见图片格式、缩放、旋转)
|
|
121
|
+
- **VideoReader** - 视频在线预览组件(支持常见视频格式、原生播放控件、字幕轨道)
|
|
106
122
|
- **SimplePDFReader** - 轻量级 PDF 阅读器组件
|
|
107
123
|
- **PDFReader** - 功能完整的 PDF 阅读器组件(默认单页阅读,包含侧边栏导航、页面旋转等高级功能)
|
|
108
124
|
- **PDFSidebar** - PDF 侧边栏导航组件(当前页附近和滚动可见缩略图懒加载、书签)
|
|
125
|
+
- **MarkdownReader** - Markdown 在线阅读组件(支持 GFM 表格、任务列表、图片、代码块)
|
|
126
|
+
- **AuthPageShell / AuthVisualCarousel / AuthPanel / AuthLoginPanel / AuthRegisterPanel** - 认证页面壳、视觉轮播与登录注册面板(支持账号密码、手机号验证码和扩展插槽)
|
|
109
127
|
|
|
110
|
-
>
|
|
128
|
+
> 当前内置预览能力覆盖 PDF、Markdown、常见图片和常见视频;Word、Excel、PPT 等其他文件类型需要由业务侧自行预览或另行扩展。
|
|
111
129
|
|
|
112
130
|
## 📁 项目结构
|
|
113
131
|
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const e=require("./jsx-runtime-BB_1_6y_.cjs"),N=require("./utils-IjLH3w2e.cjs"),r=require("react"),x=require("lucide-react"),me=s=>/^1[3-9]\d{9}$/.test(s)?void 0:"请输入正确的手机号",se=(s,l)=>s instanceof Error&&s.message?s.message:typeof s=="string"&&s?s:l,de=s=>s.replace(/\D/g,"").slice(0,11),pe=s=>s.length<=3?s:s.length<=7?`${s.slice(0,3)} ${s.slice(3)}`:`${s.slice(0,3)} ${s.slice(3,7)} ${s.slice(7)}`;function ae({components:s,title:l="欢迎登录",description:h="使用账号密码或手机号验证码进入系统",brandIcon:g,defaultMethod:m="password",enabledMethods:d=["password","sms"],error:I,extraActions:y,footer:o,socialProviders:f,className:E,smsCountdownSeconds:R=60,validatePhone:j=me,validatePassword:p,onPasswordLogin:w,onSendSmsCode:k,onSmsLogin:S}){const[L,t]=r.useState(d.includes(m)?m:d[0]),[a,J]=r.useState(""),[Q,W]=r.useState(),[X,K]=r.useState(),[Y,b]=r.useState(),[C,U]=r.useState(!1),[B,V]=r.useState(!1),[P,F]=r.useState(!1),[T,H]=r.useState(0),A=r.useMemo(()=>d.filter((n,c,$)=>$.indexOf(n)===c),[d]),q=A.length>1,D=Y||I;if(r.useEffect(()=>{if(T<=0)return;const n=setTimeout(()=>H(c=>c-1),1e3);return()=>clearTimeout(n)},[T]),!s)return e.jsxRuntimeExports.jsx("div",{className:"p-4 text-center text-destructive",children:"错误:请通过 components prop 注入 UI 组件"});const{Button:z,Input:_,Label:M,Tabs:i,TabsList:u,TabsTrigger:v,TabsContent:O}=s,Z=async n=>{n.preventDefault();const c=new FormData(n.currentTarget),$={username:String(c.get("username")||"").trim(),password:String(c.get("password")||"")},G=!$.username||!$.password?"请输入账号和密码":p==null?void 0:p($);if(G){b(G);return}try{U(!0),b(void 0),await(w==null?void 0:w($))}catch(ee){b(se(ee,"登录失败,请稍后重试"))}finally{U(!1)}},le=async()=>{const n=j(a);if(n){b(n);return}try{F(!0),b(void 0);const c=await(k==null?void 0:k(a));W(c==null?void 0:c.smsId),K(c==null?void 0:c.smsType),H(R)}catch(c){b(se(c,"发送验证码失败,请稍后重试"))}finally{F(!1)}},oe=async n=>{n.preventDefault();const c=new FormData(n.currentTarget),$=String(c.get("code")||"").trim(),G=j(a);if(G){b(G);return}if(!$){b("请输入验证码");return}try{V(!0),b(void 0),await(S==null?void 0:S({phone:a,code:$,smsId:Q,smsType:X}))}catch(ee){b(se(ee,"验证码错误或已过期"))}finally{V(!1)}},ue=()=>e.jsxRuntimeExports.jsxs("div",{className:"mb-7",children:[e.jsxRuntimeExports.jsx("div",{className:"mb-4 flex h-11 w-11 items-center justify-center rounded-lg bg-primary text-primary-foreground shadow-sm ring-1 ring-primary/10",children:g||e.jsxRuntimeExports.jsx(x.Layers3,{className:"h-5 w-5"})}),e.jsxRuntimeExports.jsx("h1",{className:"text-balance text-2xl font-semibold leading-tight",children:l}),h&&e.jsxRuntimeExports.jsx("p",{className:"mt-2 text-pretty text-sm leading-6 text-muted-foreground",children:h})]}),ce=()=>f!=null&&f.length?e.jsxRuntimeExports.jsx("div",{className:"mb-6 grid gap-2",children:f.map(n=>e.jsxRuntimeExports.jsxs(z,{type:"button",variant:"outline",className:"h-10 w-full",disabled:n.disabled,onClick:n.onClick,children:[n.icon&&e.jsxRuntimeExports.jsx("span",{className:"mr-2 inline-flex h-4 w-4 items-center justify-center",children:n.icon}),n.label]},n.id))}):null,te=()=>e.jsxRuntimeExports.jsx("form",{className:"flex flex-col",onSubmit:Z,children:e.jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxRuntimeExports.jsxs("div",{className:"space-y-2",children:[e.jsxRuntimeExports.jsx(M,{htmlFor:"auth-username",children:"用户名"}),e.jsxRuntimeExports.jsxs("div",{className:"relative",children:[e.jsxRuntimeExports.jsx(x.UserRound,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),e.jsxRuntimeExports.jsx(_,{id:"auth-username",name:"username",className:"bg-background/80 pl-9 backdrop-blur",placeholder:"请输入用户名",autoComplete:"username",spellCheck:!1,required:!0})]})]}),e.jsxRuntimeExports.jsxs("div",{className:"space-y-2",children:[e.jsxRuntimeExports.jsx(M,{htmlFor:"auth-password",children:"密码"}),e.jsxRuntimeExports.jsxs("div",{className:"relative",children:[e.jsxRuntimeExports.jsx(x.LockKeyhole,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),e.jsxRuntimeExports.jsx(_,{id:"auth-password",name:"password",className:"bg-background/80 pl-9 backdrop-blur",type:"password",placeholder:"请输入密码",autoComplete:"current-password",required:!0})]})]}),e.jsxRuntimeExports.jsx(z,{type:"submit",className:"mt-4 h-11 w-full",disabled:C,children:C?e.jsxRuntimeExports.jsxs(e.jsxRuntimeExports.Fragment,{children:[e.jsxRuntimeExports.jsx(x.Loader2,{className:"mr-2 h-4 w-4 animate-spin"}),"登录中..."]}):e.jsxRuntimeExports.jsxs(e.jsxRuntimeExports.Fragment,{children:["登录",e.jsxRuntimeExports.jsx(x.ArrowRight,{className:"ml-2 h-4 w-4"})]})})]})}),re=()=>e.jsxRuntimeExports.jsx("form",{className:"flex flex-col",onSubmit:oe,children:e.jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxRuntimeExports.jsxs("div",{className:"space-y-2",children:[e.jsxRuntimeExports.jsx(M,{htmlFor:"auth-phone",children:"手机号"}),e.jsxRuntimeExports.jsxs("div",{className:"flex gap-2",children:[e.jsxRuntimeExports.jsxs("div",{className:"relative w-full",children:[e.jsxRuntimeExports.jsx(x.MessageCircle,{className:"pointer-events-none absolute left-3 top-1/2 z-10 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),e.jsxRuntimeExports.jsx(_,{id:"auth-phone",name:"phone",className:"bg-background/80 pl-9 backdrop-blur",placeholder:"请输入手机号",value:pe(a),onChange:n=>J(de(n.target.value)),required:!0,maxLength:13,inputMode:"numeric",autoComplete:"tel",spellCheck:!1})]}),e.jsxRuntimeExports.jsx(z,{type:"button",variant:"outline",className:"h-10 w-28 shrink-0 bg-background/70 backdrop-blur hover:bg-background/90",onClick:le,disabled:!a||P||T>0,children:P?e.jsxRuntimeExports.jsx(x.Loader2,{className:"h-4 w-4 animate-spin"}):T>0?`${T}秒`:"发送验证码"})]})]}),e.jsxRuntimeExports.jsxs("div",{className:"space-y-2",children:[e.jsxRuntimeExports.jsx(M,{htmlFor:"auth-code",children:"验证码"}),e.jsxRuntimeExports.jsx(_,{id:"auth-code",name:"code",className:"bg-background/80 backdrop-blur",placeholder:"请输入验证码",inputMode:"numeric",autoComplete:"one-time-code",required:!0})]}),e.jsxRuntimeExports.jsx(z,{type:"submit",className:"mt-4 h-11 w-full",disabled:B,children:B?e.jsxRuntimeExports.jsxs(e.jsxRuntimeExports.Fragment,{children:[e.jsxRuntimeExports.jsx(x.Loader2,{className:"mr-2 h-4 w-4 animate-spin"}),"验证中..."]}):e.jsxRuntimeExports.jsxs(e.jsxRuntimeExports.Fragment,{children:["验证并登录",e.jsxRuntimeExports.jsx(x.ArrowRight,{className:"ml-2 h-4 w-4"})]})})]})}),xe=()=>q?e.jsxRuntimeExports.jsxs(i,{value:L,onValueChange:n=>t(n),className:"w-full",children:[e.jsxRuntimeExports.jsxs(u,{className:"mb-6 grid h-11 w-full grid-cols-2 bg-background/60 backdrop-blur",children:[A.includes("password")&&e.jsxRuntimeExports.jsx(v,{value:"password",children:"账号密码登录"}),A.includes("sms")&&e.jsxRuntimeExports.jsx(v,{value:"sms",children:"手机号登录"})]}),e.jsxRuntimeExports.jsx(O,{value:"password",children:te()}),e.jsxRuntimeExports.jsx(O,{value:"sms",children:re()})]}):A[0]==="sms"?re():te();return e.jsxRuntimeExports.jsxs("div",{className:N.cn("w-full max-w-[calc(100vw-2rem)] rounded-lg border border-white/45 bg-background/70 p-5 shadow-2xl shadow-slate-950/25 backdrop-blur-md supports-[backdrop-filter]:bg-background/55 md:p-8",E),children:[ue(),ce(),xe(),y&&e.jsxRuntimeExports.jsx("div",{className:"mt-5",children:y}),D&&e.jsxRuntimeExports.jsx("div",{className:"mt-4 border-l-2 border-destructive bg-destructive/5 px-4 py-3 text-sm text-destructive","aria-live":"polite",children:D}),o&&e.jsxRuntimeExports.jsx("div",{className:"mt-6 text-sm text-muted-foreground",children:o})]})}const je=s=>/^1[3-9]\d{9}$/.test(s)?void 0:"请输入正确的手机号",ne=(s,l)=>s instanceof Error&&s.message?s.message:typeof s=="string"&&s?s:l,he=s=>s.replace(/\D/g,"").slice(0,11),ge=s=>s.length<=3?s:s.length<=7?`${s.slice(0,3)} ${s.slice(3)}`:`${s.slice(0,3)} ${s.slice(3,7)} ${s.slice(7)}`;function ie({components:s,title:l="创建账号",description:h="填写账号信息并完成手机号验证",brandIcon:g,requirePhoneVerification:m=!0,requireTermsAccepted:d=!1,termsLabel:I="我已阅读并同意服务条款",error:y,extraActions:o,footer:f,socialProviders:E,className:R,smsCountdownSeconds:j=60,validatePhone:p=je,validatePassword:w,validateRegister:k,onSendSmsCode:S,onRegister:L}){const[t,a]=r.useState(""),[J,Q]=r.useState(),[W,X]=r.useState(),[K,Y]=r.useState(!1),[b,C]=r.useState(),[U,B]=r.useState(!1),[V,P]=r.useState(!1),[F,T]=r.useState(0),H=b||y;if(r.useEffect(()=>{if(F<=0)return;const i=setTimeout(()=>T(u=>u-1),1e3);return()=>clearTimeout(i)},[F]),!s)return e.jsxRuntimeExports.jsx("div",{className:"p-4 text-center text-destructive",children:"错误:请通过 components prop 注入 UI 组件"});const{Button:A,Input:q,Label:D}=s,z=async()=>{const i=p(t);if(i){C(i);return}try{P(!0),C(void 0);const u=await(S==null?void 0:S(t));Q(u==null?void 0:u.smsId),X(u==null?void 0:u.smsType),T(j)}catch(u){C(ne(u,"发送验证码失败,请稍后重试"))}finally{P(!1)}},_=async i=>{i.preventDefault();const u=new FormData(i.currentTarget),v={username:String(u.get("username")||"").trim(),password:String(u.get("password")||""),confirmPassword:String(u.get("confirmPassword")||""),phone:t,code:String(u.get("code")||"").trim(),smsId:J,smsType:W,termsAccepted:K},O=!v.username&&"请输入用户名"||!v.password&&"请输入密码"||v.password!==v.confirmPassword&&"两次输入的密码不一致"||m&&p(t)||m&&!v.code&&"请输入验证码"||d&&!K&&"请先同意服务条款"||(w==null?void 0:w(v))||(k==null?void 0:k(v));if(O){C(O);return}try{B(!0),C(void 0),await(L==null?void 0:L(v))}catch(Z){C(ne(Z,"注册失败,请稍后重试"))}finally{B(!1)}},M=()=>E!=null&&E.length?e.jsxRuntimeExports.jsx("div",{className:"mb-6 grid gap-2",children:E.map(i=>e.jsxRuntimeExports.jsxs(A,{type:"button",variant:"outline",className:"h-10 w-full",disabled:i.disabled,onClick:i.onClick,children:[i.icon&&e.jsxRuntimeExports.jsx("span",{className:"mr-2 inline-flex h-4 w-4 items-center justify-center",children:i.icon}),i.label]},i.id))}):null;return e.jsxRuntimeExports.jsxs("div",{className:N.cn("w-full max-w-[calc(100vw-2rem)] rounded-lg border border-white/45 bg-background/70 p-5 shadow-2xl shadow-slate-950/25 backdrop-blur-md supports-[backdrop-filter]:bg-background/55 md:p-8",R),children:[e.jsxRuntimeExports.jsxs("div",{className:"mb-7",children:[e.jsxRuntimeExports.jsx("div",{className:"mb-4 flex h-11 w-11 items-center justify-center rounded-lg bg-primary text-primary-foreground shadow-sm ring-1 ring-primary/10",children:g||e.jsxRuntimeExports.jsx(x.Layers3,{className:"h-5 w-5"})}),e.jsxRuntimeExports.jsx("h1",{className:"text-balance text-2xl font-semibold leading-tight",children:l}),h&&e.jsxRuntimeExports.jsx("p",{className:"mt-2 text-pretty text-sm leading-6 text-muted-foreground",children:h})]}),M(),e.jsxRuntimeExports.jsx("form",{className:"flex flex-col",onSubmit:_,children:e.jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxRuntimeExports.jsxs("div",{className:"space-y-2",children:[e.jsxRuntimeExports.jsx(D,{htmlFor:"auth-register-username",children:"用户名"}),e.jsxRuntimeExports.jsxs("div",{className:"relative",children:[e.jsxRuntimeExports.jsx(x.UserRound,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),e.jsxRuntimeExports.jsx(q,{id:"auth-register-username",name:"username",className:"bg-background/80 pl-9 backdrop-blur",placeholder:"请输入用户名",autoComplete:"username",spellCheck:!1,required:!0})]})]}),e.jsxRuntimeExports.jsxs("div",{className:"space-y-2",children:[e.jsxRuntimeExports.jsx(D,{htmlFor:"auth-register-password",children:"密码"}),e.jsxRuntimeExports.jsxs("div",{className:"relative",children:[e.jsxRuntimeExports.jsx(x.LockKeyhole,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),e.jsxRuntimeExports.jsx(q,{id:"auth-register-password",name:"password",className:"bg-background/80 pl-9 backdrop-blur",type:"password",placeholder:"请输入密码",autoComplete:"new-password",required:!0})]})]}),e.jsxRuntimeExports.jsxs("div",{className:"space-y-2",children:[e.jsxRuntimeExports.jsx(D,{htmlFor:"auth-register-confirm-password",children:"确认密码"}),e.jsxRuntimeExports.jsxs("div",{className:"relative",children:[e.jsxRuntimeExports.jsx(x.LockKeyhole,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),e.jsxRuntimeExports.jsx(q,{id:"auth-register-confirm-password",name:"confirmPassword",className:"bg-background/80 pl-9 backdrop-blur",type:"password",placeholder:"请再次输入密码",autoComplete:"new-password",required:!0})]})]}),m&&e.jsxRuntimeExports.jsxs(e.jsxRuntimeExports.Fragment,{children:[e.jsxRuntimeExports.jsxs("div",{className:"space-y-2",children:[e.jsxRuntimeExports.jsx(D,{htmlFor:"auth-register-phone",children:"手机号"}),e.jsxRuntimeExports.jsxs("div",{className:"flex gap-2",children:[e.jsxRuntimeExports.jsxs("div",{className:"relative w-full",children:[e.jsxRuntimeExports.jsx(x.MessageCircle,{className:"pointer-events-none absolute left-3 top-1/2 z-10 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),e.jsxRuntimeExports.jsx(q,{id:"auth-register-phone",name:"phone",className:"bg-background/80 pl-9 backdrop-blur",placeholder:"请输入手机号",value:ge(t),onChange:i=>a(he(i.target.value)),required:!0,maxLength:13,inputMode:"numeric",autoComplete:"tel",spellCheck:!1})]}),e.jsxRuntimeExports.jsx(A,{type:"button",variant:"outline",className:"h-10 w-28 shrink-0 bg-background/70 backdrop-blur hover:bg-background/90",onClick:z,disabled:!t||V||F>0,children:V?e.jsxRuntimeExports.jsx(x.Loader2,{className:"h-4 w-4 animate-spin"}):F>0?`${F}秒`:"发送验证码"})]})]}),e.jsxRuntimeExports.jsxs("div",{className:"space-y-2",children:[e.jsxRuntimeExports.jsx(D,{htmlFor:"auth-register-code",children:"验证码"}),e.jsxRuntimeExports.jsx(q,{id:"auth-register-code",name:"code",className:"bg-background/80 backdrop-blur",placeholder:"请输入验证码",inputMode:"numeric",autoComplete:"one-time-code",required:!0})]})]}),d&&e.jsxRuntimeExports.jsxs("label",{className:"flex items-start gap-2 text-sm text-muted-foreground",children:[e.jsxRuntimeExports.jsx("input",{type:"checkbox",className:"mt-0.5 h-4 w-4 rounded border-input focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",checked:K,onChange:i=>Y(i.target.checked)}),e.jsxRuntimeExports.jsx("span",{children:I})]}),e.jsxRuntimeExports.jsx(A,{type:"submit",className:"mt-4 h-11 w-full",disabled:U,children:U?e.jsxRuntimeExports.jsxs(e.jsxRuntimeExports.Fragment,{children:[e.jsxRuntimeExports.jsx(x.Loader2,{className:"mr-2 h-4 w-4 animate-spin"}),"注册中..."]}):e.jsxRuntimeExports.jsxs(e.jsxRuntimeExports.Fragment,{children:["创建账号",e.jsxRuntimeExports.jsx(x.ArrowRight,{className:"ml-2 h-4 w-4"})]})})]})}),o&&e.jsxRuntimeExports.jsx("div",{className:"mt-5",children:o}),H&&e.jsxRuntimeExports.jsx("div",{className:"mt-4 border-l-2 border-destructive bg-destructive/5 px-4 py-3 text-sm text-destructive","aria-live":"polite",children:H}),f&&e.jsxRuntimeExports.jsx("div",{className:"mt-6 text-sm text-muted-foreground",children:f})]})}function fe({children:s,visual:l,overlay:h,className:g,contentClassName:m,panelClassName:d}){return e.jsxRuntimeExports.jsx("div",{className:N.cn("min-h-screen",g),children:e.jsxRuntimeExports.jsxs("main",{className:"relative flex min-h-screen w-full overflow-hidden",children:[l&&e.jsxRuntimeExports.jsx("div",{className:"absolute inset-0",children:l}),h??e.jsxRuntimeExports.jsx("div",{className:"absolute inset-0 z-10 bg-black/35"}),e.jsxRuntimeExports.jsx("div",{className:N.cn("relative z-20 flex min-h-screen w-full items-center justify-center px-4 py-6 sm:px-6 lg:p-12 xl:p-16",m),children:e.jsxRuntimeExports.jsx("div",{className:N.cn("w-full min-w-0 max-w-[420px]",d),children:s})})]})})}function be({items:s,intervalMs:l=5e3,showIndicators:h=!0,showText:g=!0,className:m,imageClassName:d,contentClassName:I,ariaLabel:y="认证页视觉轮播"}){const[o,f]=r.useState(0),[E,R]=r.useState(!1),j=s.length>0,p=j?s[o]:void 0,w=t=>{j&&f((t+s.length)%s.length)},k=()=>w(o+1),S=()=>w(o-1);r.useEffect(()=>{if(!j||E||l<=0||s.length<2)return;const t=setTimeout(()=>{f(a=>(a+1)%s.length)},l);return()=>clearTimeout(t)},[j,l,E,s.length,o]);const L=t=>{t.key==="ArrowLeft"&&(t.preventDefault(),S()),t.key==="ArrowRight"&&(t.preventDefault(),k())};return j?e.jsxRuntimeExports.jsxs("div",{className:N.cn("relative h-full min-h-[360px] w-full overflow-hidden bg-slate-950 outline-none focus-visible:ring-2 focus-visible:ring-white/80 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-950",m),tabIndex:0,"aria-label":y,role:"region",onKeyDown:L,onMouseEnter:()=>R(!0),onMouseLeave:()=>R(!1),onFocus:()=>R(!0),onBlur:()=>R(!1),children:[s.map((t,a)=>e.jsxRuntimeExports.jsx("img",{src:t.image,alt:t.alt,width:t.width??1600,height:t.height??900,fetchPriority:a===o?"high":"auto",loading:a===0?"eager":"lazy",decoding:"async",className:N.cn("absolute inset-0 h-full w-full object-cover transition-opacity duration-700 ease-out motion-reduce:transition-none",a===o?"opacity-100":"opacity-0",d),"aria-hidden":a!==o},`${t.image}-${a}`)),e.jsxRuntimeExports.jsx("div",{className:"absolute inset-0 bg-gradient-to-r from-slate-950/80 via-slate-950/30 to-slate-950/10"}),e.jsxRuntimeExports.jsx("div",{className:"absolute inset-x-0 bottom-0 bg-gradient-to-t from-slate-950/80 via-slate-950/30 to-transparent pb-16 pt-24"}),e.jsxRuntimeExports.jsx("div",{className:"pointer-events-none absolute inset-0 opacity-[0.18] [background-image:linear-gradient(to_right,rgba(255,255,255,0.32)_1px,transparent_1px),linear-gradient(to_bottom,rgba(255,255,255,0.26)_1px,transparent_1px)] [background-size:44px_44px]","aria-hidden":"true"}),e.jsxRuntimeExports.jsx("div",{className:"pointer-events-none absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-white/60 to-transparent","aria-hidden":"true"}),(g||h)&&e.jsxRuntimeExports.jsxs("div",{className:N.cn("absolute inset-x-5 bottom-6 text-white sm:inset-x-8 sm:bottom-8 lg:inset-x-12 lg:bottom-10",I),children:[g&&p&&e.jsxRuntimeExports.jsxs("div",{className:"max-w-[min(28rem,calc(100vw-2.5rem))]",children:[p.eyebrow&&e.jsxRuntimeExports.jsx("p",{className:"mb-2 text-[0.68rem] font-medium uppercase tracking-normal text-cyan-100/80 sm:text-xs",children:p.eyebrow}),p.title&&e.jsxRuntimeExports.jsx("h2",{className:"text-balance text-xl font-semibold leading-tight sm:text-2xl lg:text-3xl",children:p.title}),p.description&&e.jsxRuntimeExports.jsx("p",{className:"mt-2 line-clamp-3 text-sm leading-6 text-slate-100/80 sm:text-base",children:p.description})]}),h&&s.length>1&&e.jsxRuntimeExports.jsx("div",{className:"mt-5 flex items-center gap-2",children:s.map((t,a)=>e.jsxRuntimeExports.jsx("button",{type:"button",className:N.cn("h-1.5 rounded-full transition-[background-color,width] duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-slate-950 motion-reduce:transition-none",a===o?"w-8 bg-white":"w-3 bg-white/40 hover:bg-white/70"),"aria-label":`切换到第 ${a+1} 张轮播图`,"aria-current":a===o,onClick:()=>w(a)},`${t.image}-indicator-${a}`))})]})]}):e.jsxRuntimeExports.jsx("div",{className:N.cn("relative h-full min-h-[360px] w-full overflow-hidden bg-slate-950",m),"aria-label":y,role:"region"})}function Ee({components:s,mode:l,defaultMode:h="login",onModeChange:g,loginProps:m,registerProps:d,loginLabel:I="已有账号?登录",registerLabel:y="没有账号?注册"}){const[o,f]=r.useState(h),E=l??o,R=j=>{l||f(j),g==null||g(j)};return E==="register"?e.jsxRuntimeExports.jsx(ie,{...d,components:s,footer:(d==null?void 0:d.footer)??e.jsxRuntimeExports.jsx("button",{type:"button",className:"text-primary underline-offset-4 hover:underline",onClick:()=>R("login"),children:I})}):e.jsxRuntimeExports.jsx(ae,{...m,components:s,footer:(m==null?void 0:m.footer)??e.jsxRuntimeExports.jsx("button",{type:"button",className:"text-primary underline-offset-4 hover:underline",onClick:()=>R("register"),children:y})})}exports.AuthLoginPanel=ae;exports.AuthPageShell=fe;exports.AuthPanel=Ee;exports.AuthRegisterPanel=ie;exports.AuthVisualCarousel=be;
|
|
2
|
+
//# sourceMappingURL=AuthPanel-CTKx618F.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthPanel-CTKx618F.cjs","sources":["../src/components/AuthLoginPanel.tsx","../src/components/AuthRegisterPanel.tsx","../src/components/AuthPageShell.tsx","../src/components/AuthVisualCarousel.tsx","../src/components/AuthPanel.tsx"],"sourcesContent":["import {\n ArrowRight,\n Layers3,\n Loader2,\n LockKeyhole,\n MessageCircle,\n UserRound,\n} from 'lucide-react';\nimport { useEffect, useMemo, useState } from 'react';\nimport type { FormEvent, ReactNode } from 'react';\n\nimport { cn } from '../lib/utils';\nimport type {\n ButtonComponent,\n InputComponent,\n LabelComponent,\n TabsComponent,\n TabsContentComponent,\n TabsListComponent,\n TabsTriggerComponent,\n} from '../types/component-types';\n\nexport type AuthLoginMethod = 'password' | 'sms';\nexport type AuthValidationResult = string | undefined | null;\n\nexport interface AuthUIComponents {\n Button: ButtonComponent;\n Input: InputComponent;\n Label: LabelComponent;\n Tabs: TabsComponent;\n TabsList: TabsListComponent;\n TabsTrigger: TabsTriggerComponent;\n TabsContent: TabsContentComponent;\n}\n\nexport interface AuthSocialProvider {\n id: string;\n label: ReactNode;\n icon?: ReactNode;\n disabled?: boolean;\n onClick?: () => Promise<void> | void;\n}\n\nexport interface AuthSmsCodeResult {\n smsId?: string;\n smsType?: string;\n}\n\nexport interface AuthPasswordLoginPayload {\n username: string;\n password: string;\n}\n\nexport interface AuthSmsLoginPayload {\n phone: string;\n code: string;\n smsId?: string;\n smsType?: string;\n}\n\nexport interface AuthLoginPanelProps {\n components?: AuthUIComponents;\n title?: ReactNode;\n description?: ReactNode;\n brandIcon?: ReactNode;\n defaultMethod?: AuthLoginMethod;\n enabledMethods?: AuthLoginMethod[];\n error?: ReactNode;\n extraActions?: ReactNode;\n footer?: ReactNode;\n socialProviders?: AuthSocialProvider[];\n className?: string;\n smsCountdownSeconds?: number;\n validatePhone?: (phone: string) => AuthValidationResult;\n validatePassword?: (\n payload: AuthPasswordLoginPayload\n ) => AuthValidationResult;\n onPasswordLogin?: (payload: AuthPasswordLoginPayload) => Promise<void> | void;\n onSendSmsCode?: (\n phone: string\n ) => Promise<AuthSmsCodeResult | void> | AuthSmsCodeResult | void;\n onSmsLogin?: (payload: AuthSmsLoginPayload) => Promise<void> | void;\n}\n\nconst defaultValidatePhone = (phone: string) =>\n /^1[3-9]\\d{9}$/.test(phone) ? undefined : '请输入正确的手机号';\n\nconst getErrorMessage = (error: unknown, fallback: string) => {\n if (error instanceof Error && error.message) return error.message;\n if (typeof error === 'string' && error) return error;\n return fallback;\n};\n\nconst normalizePhone = (value: string) => value.replace(/\\D/g, '').slice(0, 11);\n\nconst formatPhone = (phone: string) => {\n if (phone.length <= 3) return phone;\n if (phone.length <= 7) return `${phone.slice(0, 3)} ${phone.slice(3)}`;\n return `${phone.slice(0, 3)} ${phone.slice(3, 7)} ${phone.slice(7)}`;\n};\n\nexport function AuthLoginPanel({\n components,\n title = '欢迎登录',\n description = '使用账号密码或手机号验证码进入系统',\n brandIcon,\n defaultMethod = 'password',\n enabledMethods = ['password', 'sms'],\n error,\n extraActions,\n footer,\n socialProviders,\n className,\n smsCountdownSeconds = 60,\n validatePhone = defaultValidatePhone,\n validatePassword,\n onPasswordLogin,\n onSendSmsCode,\n onSmsLogin,\n}: AuthLoginPanelProps) {\n const [activeMethod, setActiveMethod] = useState<AuthLoginMethod>(\n enabledMethods.includes(defaultMethod) ? defaultMethod : enabledMethods[0]\n );\n const [phone, setPhone] = useState('');\n const [smsId, setSmsId] = useState<string | undefined>();\n const [smsType, setSmsType] = useState<string | undefined>();\n const [localError, setLocalError] = useState<ReactNode>();\n const [passwordPending, setPasswordPending] = useState(false);\n const [smsPending, setSmsPending] = useState(false);\n const [codePending, setCodePending] = useState(false);\n const [countdown, setCountdown] = useState(0);\n\n const methods = useMemo(\n () =>\n enabledMethods.filter(\n (method, index, array) => array.indexOf(method) === index\n ),\n [enabledMethods]\n );\n const shouldShowTabs = methods.length > 1;\n const displayedError = localError || error;\n\n useEffect(() => {\n if (countdown <= 0) return;\n const timer = setTimeout(() => setCountdown((value) => value - 1), 1000);\n return () => clearTimeout(timer);\n }, [countdown]);\n\n if (!components) {\n return (\n <div className=\"p-4 text-center text-destructive\">\n 错误:请通过 components prop 注入 UI 组件\n </div>\n );\n }\n\n const { Button, Input, Label, Tabs, TabsList, TabsTrigger, TabsContent } =\n components;\n\n const handlePasswordSubmit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const formData = new FormData(event.currentTarget);\n const payload = {\n username: String(formData.get('username') || '').trim(),\n password: String(formData.get('password') || ''),\n };\n\n const validationError =\n !payload.username || !payload.password\n ? '请输入账号和密码'\n : validatePassword?.(payload);\n if (validationError) {\n setLocalError(validationError);\n return;\n }\n\n try {\n setPasswordPending(true);\n setLocalError(undefined);\n await onPasswordLogin?.(payload);\n } catch (err) {\n setLocalError(getErrorMessage(err, '登录失败,请稍后重试'));\n } finally {\n setPasswordPending(false);\n }\n };\n\n const handleSendCode = async () => {\n const validationError = validatePhone(phone);\n if (validationError) {\n setLocalError(validationError);\n return;\n }\n\n try {\n setCodePending(true);\n setLocalError(undefined);\n const result = await onSendSmsCode?.(phone);\n setSmsId(result?.smsId);\n setSmsType(result?.smsType);\n setCountdown(smsCountdownSeconds);\n } catch (err) {\n setLocalError(getErrorMessage(err, '发送验证码失败,请稍后重试'));\n } finally {\n setCodePending(false);\n }\n };\n\n const handleSmsSubmit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const formData = new FormData(event.currentTarget);\n const code = String(formData.get('code') || '').trim();\n const validationError = validatePhone(phone);\n\n if (validationError) {\n setLocalError(validationError);\n return;\n }\n if (!code) {\n setLocalError('请输入验证码');\n return;\n }\n\n try {\n setSmsPending(true);\n setLocalError(undefined);\n await onSmsLogin?.({ phone, code, smsId, smsType });\n } catch (err) {\n setLocalError(getErrorMessage(err, '验证码错误或已过期'));\n } finally {\n setSmsPending(false);\n }\n };\n\n const renderHeader = () => (\n <div className=\"mb-7\">\n <div className=\"mb-4 flex h-11 w-11 items-center justify-center rounded-lg bg-primary text-primary-foreground shadow-sm ring-1 ring-primary/10\">\n {brandIcon || <Layers3 className=\"h-5 w-5\" />}\n </div>\n <h1 className=\"text-balance text-2xl font-semibold leading-tight\">\n {title}\n </h1>\n {description && (\n <p className=\"mt-2 text-pretty text-sm leading-6 text-muted-foreground\">\n {description}\n </p>\n )}\n </div>\n );\n\n const renderSocialProviders = () =>\n socialProviders?.length ? (\n <div className=\"mb-6 grid gap-2\">\n {socialProviders.map((provider) => (\n <Button\n key={provider.id}\n type=\"button\"\n variant=\"outline\"\n className=\"h-10 w-full\"\n disabled={provider.disabled}\n onClick={provider.onClick}\n >\n {provider.icon && (\n <span className=\"mr-2 inline-flex h-4 w-4 items-center justify-center\">\n {provider.icon}\n </span>\n )}\n {provider.label}\n </Button>\n ))}\n </div>\n ) : null;\n\n const renderPasswordForm = () => (\n <form className=\"flex flex-col\" onSubmit={handlePasswordSubmit}>\n <div className=\"flex flex-col gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"auth-username\">用户名</Label>\n <div className=\"relative\">\n <UserRound className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n id=\"auth-username\"\n name=\"username\"\n className=\"bg-background/80 pl-9 backdrop-blur\"\n placeholder=\"请输入用户名\"\n autoComplete=\"username\"\n spellCheck={false}\n required\n />\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"auth-password\">密码</Label>\n <div className=\"relative\">\n <LockKeyhole className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n id=\"auth-password\"\n name=\"password\"\n className=\"bg-background/80 pl-9 backdrop-blur\"\n type=\"password\"\n placeholder=\"请输入密码\"\n autoComplete=\"current-password\"\n required\n />\n </div>\n </div>\n <Button\n type=\"submit\"\n className=\"mt-4 h-11 w-full\"\n disabled={passwordPending}\n >\n {passwordPending ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n 登录中...\n </>\n ) : (\n <>\n 登录\n <ArrowRight className=\"ml-2 h-4 w-4\" />\n </>\n )}\n </Button>\n </div>\n </form>\n );\n\n const renderSmsForm = () => (\n <form className=\"flex flex-col\" onSubmit={handleSmsSubmit}>\n <div className=\"flex flex-col gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"auth-phone\">手机号</Label>\n <div className=\"flex gap-2\">\n <div className=\"relative w-full\">\n <MessageCircle className=\"pointer-events-none absolute left-3 top-1/2 z-10 h-4 w-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n id=\"auth-phone\"\n name=\"phone\"\n className=\"bg-background/80 pl-9 backdrop-blur\"\n placeholder=\"请输入手机号\"\n value={formatPhone(phone)}\n onChange={(event) =>\n setPhone(normalizePhone(event.target.value))\n }\n required\n maxLength={13}\n inputMode=\"numeric\"\n autoComplete=\"tel\"\n spellCheck={false}\n />\n </div>\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"h-10 w-28 shrink-0 bg-background/70 backdrop-blur hover:bg-background/90\"\n onClick={handleSendCode}\n disabled={!phone || codePending || countdown > 0}\n >\n {codePending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : countdown > 0 ? (\n `${countdown}秒`\n ) : (\n '发送验证码'\n )}\n </Button>\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"auth-code\">验证码</Label>\n <Input\n id=\"auth-code\"\n name=\"code\"\n className=\"bg-background/80 backdrop-blur\"\n placeholder=\"请输入验证码\"\n inputMode=\"numeric\"\n autoComplete=\"one-time-code\"\n required\n />\n </div>\n <Button\n type=\"submit\"\n className=\"mt-4 h-11 w-full\"\n disabled={smsPending}\n >\n {smsPending ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n 验证中...\n </>\n ) : (\n <>\n 验证并登录\n <ArrowRight className=\"ml-2 h-4 w-4\" />\n </>\n )}\n </Button>\n </div>\n </form>\n );\n\n const renderForms = () => {\n if (!shouldShowTabs) {\n return methods[0] === 'sms' ? renderSmsForm() : renderPasswordForm();\n }\n\n return (\n <Tabs\n value={activeMethod}\n onValueChange={(value) => setActiveMethod(value as AuthLoginMethod)}\n className=\"w-full\"\n >\n <TabsList className=\"mb-6 grid h-11 w-full grid-cols-2 bg-background/60 backdrop-blur\">\n {methods.includes('password') && (\n <TabsTrigger value=\"password\">账号密码登录</TabsTrigger>\n )}\n {methods.includes('sms') && (\n <TabsTrigger value=\"sms\">手机号登录</TabsTrigger>\n )}\n </TabsList>\n <TabsContent value=\"password\">{renderPasswordForm()}</TabsContent>\n <TabsContent value=\"sms\">{renderSmsForm()}</TabsContent>\n </Tabs>\n );\n };\n\n return (\n <div\n className={cn(\n 'w-full max-w-[calc(100vw-2rem)] rounded-lg border border-white/45 bg-background/70 p-5 shadow-2xl shadow-slate-950/25 backdrop-blur-md supports-[backdrop-filter]:bg-background/55 md:p-8',\n className\n )}\n >\n {renderHeader()}\n {renderSocialProviders()}\n {renderForms()}\n {extraActions && <div className=\"mt-5\">{extraActions}</div>}\n {displayedError && (\n <div\n className=\"mt-4 border-l-2 border-destructive bg-destructive/5 px-4 py-3 text-sm text-destructive\"\n aria-live=\"polite\"\n >\n {displayedError}\n </div>\n )}\n {footer && (\n <div className=\"mt-6 text-sm text-muted-foreground\">{footer}</div>\n )}\n </div>\n );\n}\n","import {\n ArrowRight,\n Layers3,\n Loader2,\n LockKeyhole,\n MessageCircle,\n UserRound,\n} from 'lucide-react';\nimport { useEffect, useState } from 'react';\nimport type { FormEvent, ReactNode } from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport type {\n AuthSmsCodeResult,\n AuthSocialProvider,\n AuthUIComponents,\n AuthValidationResult,\n} from './AuthLoginPanel';\n\nexport interface AuthRegisterPayload {\n username: string;\n password: string;\n confirmPassword: string;\n phone: string;\n code: string;\n smsId?: string;\n smsType?: string;\n termsAccepted: boolean;\n}\n\nexport interface AuthRegisterPanelProps {\n components?: AuthUIComponents;\n title?: ReactNode;\n description?: ReactNode;\n brandIcon?: ReactNode;\n requirePhoneVerification?: boolean;\n requireTermsAccepted?: boolean;\n termsLabel?: ReactNode;\n error?: ReactNode;\n extraActions?: ReactNode;\n footer?: ReactNode;\n socialProviders?: AuthSocialProvider[];\n className?: string;\n smsCountdownSeconds?: number;\n validatePhone?: (phone: string) => AuthValidationResult;\n validatePassword?: (payload: AuthRegisterPayload) => AuthValidationResult;\n validateRegister?: (payload: AuthRegisterPayload) => AuthValidationResult;\n onSendSmsCode?: (\n phone: string\n ) => Promise<AuthSmsCodeResult | void> | AuthSmsCodeResult | void;\n onRegister?: (payload: AuthRegisterPayload) => Promise<void> | void;\n}\n\nconst defaultValidatePhone = (phone: string) =>\n /^1[3-9]\\d{9}$/.test(phone) ? undefined : '请输入正确的手机号';\n\nconst getErrorMessage = (error: unknown, fallback: string) => {\n if (error instanceof Error && error.message) return error.message;\n if (typeof error === 'string' && error) return error;\n return fallback;\n};\n\nconst normalizePhone = (value: string) => value.replace(/\\D/g, '').slice(0, 11);\n\nconst formatPhone = (phone: string) => {\n if (phone.length <= 3) return phone;\n if (phone.length <= 7) return `${phone.slice(0, 3)} ${phone.slice(3)}`;\n return `${phone.slice(0, 3)} ${phone.slice(3, 7)} ${phone.slice(7)}`;\n};\n\nexport function AuthRegisterPanel({\n components,\n title = '创建账号',\n description = '填写账号信息并完成手机号验证',\n brandIcon,\n requirePhoneVerification = true,\n requireTermsAccepted = false,\n termsLabel = '我已阅读并同意服务条款',\n error,\n extraActions,\n footer,\n socialProviders,\n className,\n smsCountdownSeconds = 60,\n validatePhone = defaultValidatePhone,\n validatePassword,\n validateRegister,\n onSendSmsCode,\n onRegister,\n}: AuthRegisterPanelProps) {\n const [phone, setPhone] = useState('');\n const [smsId, setSmsId] = useState<string | undefined>();\n const [smsType, setSmsType] = useState<string | undefined>();\n const [termsAccepted, setTermsAccepted] = useState(false);\n const [localError, setLocalError] = useState<ReactNode>();\n const [registerPending, setRegisterPending] = useState(false);\n const [codePending, setCodePending] = useState(false);\n const [countdown, setCountdown] = useState(0);\n const displayedError = localError || error;\n\n useEffect(() => {\n if (countdown <= 0) return;\n const timer = setTimeout(() => setCountdown((value) => value - 1), 1000);\n return () => clearTimeout(timer);\n }, [countdown]);\n\n if (!components) {\n return (\n <div className=\"p-4 text-center text-destructive\">\n 错误:请通过 components prop 注入 UI 组件\n </div>\n );\n }\n\n const { Button, Input, Label } = components;\n\n const handleSendCode = async () => {\n const validationError = validatePhone(phone);\n if (validationError) {\n setLocalError(validationError);\n return;\n }\n\n try {\n setCodePending(true);\n setLocalError(undefined);\n const result = await onSendSmsCode?.(phone);\n setSmsId(result?.smsId);\n setSmsType(result?.smsType);\n setCountdown(smsCountdownSeconds);\n } catch (err) {\n setLocalError(getErrorMessage(err, '发送验证码失败,请稍后重试'));\n } finally {\n setCodePending(false);\n }\n };\n\n const handleRegister = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const formData = new FormData(event.currentTarget);\n const payload: AuthRegisterPayload = {\n username: String(formData.get('username') || '').trim(),\n password: String(formData.get('password') || ''),\n confirmPassword: String(formData.get('confirmPassword') || ''),\n phone,\n code: String(formData.get('code') || '').trim(),\n smsId,\n smsType,\n termsAccepted,\n };\n\n const validationError =\n (!payload.username && '请输入用户名') ||\n (!payload.password && '请输入密码') ||\n (payload.password !== payload.confirmPassword &&\n '两次输入的密码不一致') ||\n (requirePhoneVerification && validatePhone(phone)) ||\n (requirePhoneVerification && !payload.code && '请输入验证码') ||\n (requireTermsAccepted && !termsAccepted && '请先同意服务条款') ||\n validatePassword?.(payload) ||\n validateRegister?.(payload);\n\n if (validationError) {\n setLocalError(validationError);\n return;\n }\n\n try {\n setRegisterPending(true);\n setLocalError(undefined);\n await onRegister?.(payload);\n } catch (err) {\n setLocalError(getErrorMessage(err, '注册失败,请稍后重试'));\n } finally {\n setRegisterPending(false);\n }\n };\n\n const renderSocialProviders = () =>\n socialProviders?.length ? (\n <div className=\"mb-6 grid gap-2\">\n {socialProviders.map((provider) => (\n <Button\n key={provider.id}\n type=\"button\"\n variant=\"outline\"\n className=\"h-10 w-full\"\n disabled={provider.disabled}\n onClick={provider.onClick}\n >\n {provider.icon && (\n <span className=\"mr-2 inline-flex h-4 w-4 items-center justify-center\">\n {provider.icon}\n </span>\n )}\n {provider.label}\n </Button>\n ))}\n </div>\n ) : null;\n\n return (\n <div\n className={cn(\n 'w-full max-w-[calc(100vw-2rem)] rounded-lg border border-white/45 bg-background/70 p-5 shadow-2xl shadow-slate-950/25 backdrop-blur-md supports-[backdrop-filter]:bg-background/55 md:p-8',\n className\n )}\n >\n <div className=\"mb-7\">\n <div className=\"mb-4 flex h-11 w-11 items-center justify-center rounded-lg bg-primary text-primary-foreground shadow-sm ring-1 ring-primary/10\">\n {brandIcon || <Layers3 className=\"h-5 w-5\" />}\n </div>\n <h1 className=\"text-balance text-2xl font-semibold leading-tight\">\n {title}\n </h1>\n {description && (\n <p className=\"mt-2 text-pretty text-sm leading-6 text-muted-foreground\">\n {description}\n </p>\n )}\n </div>\n\n {renderSocialProviders()}\n\n <form className=\"flex flex-col\" onSubmit={handleRegister}>\n <div className=\"flex flex-col gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"auth-register-username\">用户名</Label>\n <div className=\"relative\">\n <UserRound className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n id=\"auth-register-username\"\n name=\"username\"\n className=\"bg-background/80 pl-9 backdrop-blur\"\n placeholder=\"请输入用户名\"\n autoComplete=\"username\"\n spellCheck={false}\n required\n />\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"auth-register-password\">密码</Label>\n <div className=\"relative\">\n <LockKeyhole className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n id=\"auth-register-password\"\n name=\"password\"\n className=\"bg-background/80 pl-9 backdrop-blur\"\n type=\"password\"\n placeholder=\"请输入密码\"\n autoComplete=\"new-password\"\n required\n />\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"auth-register-confirm-password\">确认密码</Label>\n <div className=\"relative\">\n <LockKeyhole className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n id=\"auth-register-confirm-password\"\n name=\"confirmPassword\"\n className=\"bg-background/80 pl-9 backdrop-blur\"\n type=\"password\"\n placeholder=\"请再次输入密码\"\n autoComplete=\"new-password\"\n required\n />\n </div>\n </div>\n\n {requirePhoneVerification && (\n <>\n <div className=\"space-y-2\">\n <Label htmlFor=\"auth-register-phone\">手机号</Label>\n <div className=\"flex gap-2\">\n <div className=\"relative w-full\">\n <MessageCircle className=\"pointer-events-none absolute left-3 top-1/2 z-10 h-4 w-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n id=\"auth-register-phone\"\n name=\"phone\"\n className=\"bg-background/80 pl-9 backdrop-blur\"\n placeholder=\"请输入手机号\"\n value={formatPhone(phone)}\n onChange={(event) =>\n setPhone(normalizePhone(event.target.value))\n }\n required\n maxLength={13}\n inputMode=\"numeric\"\n autoComplete=\"tel\"\n spellCheck={false}\n />\n </div>\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"h-10 w-28 shrink-0 bg-background/70 backdrop-blur hover:bg-background/90\"\n onClick={handleSendCode}\n disabled={!phone || codePending || countdown > 0}\n >\n {codePending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : countdown > 0 ? (\n `${countdown}秒`\n ) : (\n '发送验证码'\n )}\n </Button>\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"auth-register-code\">验证码</Label>\n <Input\n id=\"auth-register-code\"\n name=\"code\"\n className=\"bg-background/80 backdrop-blur\"\n placeholder=\"请输入验证码\"\n inputMode=\"numeric\"\n autoComplete=\"one-time-code\"\n required\n />\n </div>\n </>\n )}\n\n {requireTermsAccepted && (\n <label className=\"flex items-start gap-2 text-sm text-muted-foreground\">\n <input\n type=\"checkbox\"\n className=\"mt-0.5 h-4 w-4 rounded border-input focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n checked={termsAccepted}\n onChange={(event) => setTermsAccepted(event.target.checked)}\n />\n <span>{termsLabel}</span>\n </label>\n )}\n\n <Button\n type=\"submit\"\n className=\"mt-4 h-11 w-full\"\n disabled={registerPending}\n >\n {registerPending ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n 注册中...\n </>\n ) : (\n <>\n 创建账号\n <ArrowRight className=\"ml-2 h-4 w-4\" />\n </>\n )}\n </Button>\n </div>\n </form>\n\n {extraActions && <div className=\"mt-5\">{extraActions}</div>}\n {displayedError && (\n <div\n className=\"mt-4 border-l-2 border-destructive bg-destructive/5 px-4 py-3 text-sm text-destructive\"\n aria-live=\"polite\"\n >\n {displayedError}\n </div>\n )}\n {footer && (\n <div className=\"mt-6 text-sm text-muted-foreground\">{footer}</div>\n )}\n </div>\n );\n}\n","import type { ReactNode } from 'react';\n\nimport { cn } from '../lib/utils';\n\nexport interface AuthPageShellProps {\n children: ReactNode;\n visual?: ReactNode;\n overlay?: ReactNode;\n className?: string;\n contentClassName?: string;\n panelClassName?: string;\n}\n\nexport function AuthPageShell({\n children,\n visual,\n overlay,\n className,\n contentClassName,\n panelClassName,\n}: AuthPageShellProps) {\n return (\n <div className={cn('min-h-screen', className)}>\n <main className=\"relative flex min-h-screen w-full overflow-hidden\">\n {visual && <div className=\"absolute inset-0\">{visual}</div>}\n {overlay ?? <div className=\"absolute inset-0 z-10 bg-black/35\" />}\n <div\n className={cn(\n 'relative z-20 flex min-h-screen w-full items-center justify-center px-4 py-6 sm:px-6 lg:p-12 xl:p-16',\n contentClassName\n )}\n >\n <div className={cn('w-full min-w-0 max-w-[420px]', panelClassName)}>\n {children}\n </div>\n </div>\n </main>\n </div>\n );\n}\n","import { useEffect, useState } from 'react';\nimport type { KeyboardEvent, ReactNode } from 'react';\n\nimport { cn } from '../lib/utils';\n\nexport interface AuthVisualCarouselItem {\n image: string;\n alt: string;\n width?: number;\n height?: number;\n title?: ReactNode;\n description?: ReactNode;\n eyebrow?: ReactNode;\n}\n\nexport interface AuthVisualCarouselProps {\n items: AuthVisualCarouselItem[];\n intervalMs?: number;\n showIndicators?: boolean;\n showText?: boolean;\n className?: string;\n imageClassName?: string;\n contentClassName?: string;\n ariaLabel?: string;\n}\n\nexport function AuthVisualCarousel({\n items,\n intervalMs = 5000,\n showIndicators = true,\n showText = true,\n className,\n imageClassName,\n contentClassName,\n ariaLabel = '认证页视觉轮播',\n}: AuthVisualCarouselProps) {\n const [currentSlide, setCurrentSlide] = useState(0);\n const [isPaused, setIsPaused] = useState(false);\n const hasItems = items.length > 0;\n const currentItem = hasItems ? items[currentSlide] : undefined;\n\n const goToSlide = (index: number) => {\n if (!hasItems) return;\n setCurrentSlide((index + items.length) % items.length);\n };\n\n const nextSlide = () => goToSlide(currentSlide + 1);\n const previousSlide = () => goToSlide(currentSlide - 1);\n\n useEffect(() => {\n if (!hasItems || isPaused || intervalMs <= 0 || items.length < 2) return;\n const timer = setTimeout(() => {\n setCurrentSlide((slide) => (slide + 1) % items.length);\n }, intervalMs);\n return () => clearTimeout(timer);\n }, [hasItems, intervalMs, isPaused, items.length, currentSlide]);\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'ArrowLeft') {\n event.preventDefault();\n previousSlide();\n }\n if (event.key === 'ArrowRight') {\n event.preventDefault();\n nextSlide();\n }\n };\n\n if (!hasItems) {\n return (\n <div\n className={cn(\n 'relative h-full min-h-[360px] w-full overflow-hidden bg-slate-950',\n className\n )}\n aria-label={ariaLabel}\n role=\"region\"\n />\n );\n }\n\n return (\n <div\n className={cn(\n 'relative h-full min-h-[360px] w-full overflow-hidden bg-slate-950 outline-none focus-visible:ring-2 focus-visible:ring-white/80 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-950',\n className\n )}\n tabIndex={0}\n aria-label={ariaLabel}\n role=\"region\"\n onKeyDown={handleKeyDown}\n onMouseEnter={() => setIsPaused(true)}\n onMouseLeave={() => setIsPaused(false)}\n onFocus={() => setIsPaused(true)}\n onBlur={() => setIsPaused(false)}\n >\n {items.map((item, index) => (\n <img\n key={`${item.image}-${index}`}\n src={item.image}\n alt={item.alt}\n width={item.width ?? 1600}\n height={item.height ?? 900}\n fetchPriority={index === currentSlide ? 'high' : 'auto'}\n loading={index === 0 ? 'eager' : 'lazy'}\n decoding=\"async\"\n className={cn(\n 'absolute inset-0 h-full w-full object-cover transition-opacity duration-700 ease-out motion-reduce:transition-none',\n index === currentSlide ? 'opacity-100' : 'opacity-0',\n imageClassName\n )}\n aria-hidden={index !== currentSlide}\n />\n ))}\n\n <div className=\"absolute inset-0 bg-gradient-to-r from-slate-950/80 via-slate-950/30 to-slate-950/10\" />\n <div className=\"absolute inset-x-0 bottom-0 bg-gradient-to-t from-slate-950/80 via-slate-950/30 to-transparent pb-16 pt-24\" />\n <div\n className=\"pointer-events-none absolute inset-0 opacity-[0.18] [background-image:linear-gradient(to_right,rgba(255,255,255,0.32)_1px,transparent_1px),linear-gradient(to_bottom,rgba(255,255,255,0.26)_1px,transparent_1px)] [background-size:44px_44px]\"\n aria-hidden=\"true\"\n />\n <div\n className=\"pointer-events-none absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-white/60 to-transparent\"\n aria-hidden=\"true\"\n />\n\n {(showText || showIndicators) && (\n <div\n className={cn(\n 'absolute inset-x-5 bottom-6 text-white sm:inset-x-8 sm:bottom-8 lg:inset-x-12 lg:bottom-10',\n contentClassName\n )}\n >\n {showText && currentItem && (\n <div className=\"max-w-[min(28rem,calc(100vw-2.5rem))]\">\n {currentItem.eyebrow && (\n <p className=\"mb-2 text-[0.68rem] font-medium uppercase tracking-normal text-cyan-100/80 sm:text-xs\">\n {currentItem.eyebrow}\n </p>\n )}\n {currentItem.title && (\n <h2 className=\"text-balance text-xl font-semibold leading-tight sm:text-2xl lg:text-3xl\">\n {currentItem.title}\n </h2>\n )}\n {currentItem.description && (\n <p className=\"mt-2 line-clamp-3 text-sm leading-6 text-slate-100/80 sm:text-base\">\n {currentItem.description}\n </p>\n )}\n </div>\n )}\n\n {showIndicators && items.length > 1 && (\n <div className=\"mt-5 flex items-center gap-2\">\n {items.map((item, index) => (\n <button\n key={`${item.image}-indicator-${index}`}\n type=\"button\"\n className={cn(\n 'h-1.5 rounded-full transition-[background-color,width] duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-slate-950 motion-reduce:transition-none',\n index === currentSlide\n ? 'w-8 bg-white'\n : 'w-3 bg-white/40 hover:bg-white/70'\n )}\n aria-label={`切换到第 ${index + 1} 张轮播图`}\n aria-current={index === currentSlide}\n onClick={() => goToSlide(index)}\n />\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n","import { useState } from 'react';\nimport type { ReactNode } from 'react';\n\nimport type { AuthLoginPanelProps, AuthUIComponents } from './AuthLoginPanel';\nimport { AuthLoginPanel } from './AuthLoginPanel';\nimport type { AuthRegisterPanelProps } from './AuthRegisterPanel';\nimport { AuthRegisterPanel } from './AuthRegisterPanel';\n\nexport type AuthPanelMode = 'login' | 'register';\n\nexport interface AuthPanelProps {\n components?: AuthUIComponents;\n mode?: AuthPanelMode;\n defaultMode?: AuthPanelMode;\n onModeChange?: (mode: AuthPanelMode) => void;\n loginProps?: Omit<AuthLoginPanelProps, 'components' | 'footer'> & {\n footer?: ReactNode;\n };\n registerProps?: Omit<AuthRegisterPanelProps, 'components' | 'footer'> & {\n footer?: ReactNode;\n };\n loginLabel?: ReactNode;\n registerLabel?: ReactNode;\n}\n\nexport function AuthPanel({\n components,\n mode,\n defaultMode = 'login',\n onModeChange,\n loginProps,\n registerProps,\n loginLabel = '已有账号?登录',\n registerLabel = '没有账号?注册',\n}: AuthPanelProps) {\n const [internalMode, setInternalMode] = useState<AuthPanelMode>(defaultMode);\n const currentMode = mode ?? internalMode;\n\n const setMode = (nextMode: AuthPanelMode) => {\n if (!mode) {\n setInternalMode(nextMode);\n }\n onModeChange?.(nextMode);\n };\n\n if (currentMode === 'register') {\n return (\n <AuthRegisterPanel\n {...registerProps}\n components={components}\n footer={\n registerProps?.footer ?? (\n <button\n type=\"button\"\n className=\"text-primary underline-offset-4 hover:underline\"\n onClick={() => setMode('login')}\n >\n {loginLabel}\n </button>\n )\n }\n />\n );\n }\n\n return (\n <AuthLoginPanel\n {...loginProps}\n components={components}\n footer={\n loginProps?.footer ?? (\n <button\n type=\"button\"\n className=\"text-primary underline-offset-4 hover:underline\"\n onClick={() => setMode('register')}\n >\n {registerLabel}\n </button>\n )\n }\n />\n );\n}\n"],"names":["defaultValidatePhone","phone","getErrorMessage","error","fallback","normalizePhone","value","formatPhone","AuthLoginPanel","components","title","description","brandIcon","defaultMethod","enabledMethods","extraActions","footer","socialProviders","className","smsCountdownSeconds","validatePhone","validatePassword","onPasswordLogin","onSendSmsCode","onSmsLogin","activeMethod","setActiveMethod","useState","setPhone","smsId","setSmsId","smsType","setSmsType","localError","setLocalError","passwordPending","setPasswordPending","smsPending","setSmsPending","codePending","setCodePending","countdown","setCountdown","methods","useMemo","method","index","array","shouldShowTabs","displayedError","useEffect","timer","jsx","Button","Input","Label","Tabs","TabsList","TabsTrigger","TabsContent","handlePasswordSubmit","event","formData","payload","validationError","err","handleSendCode","result","handleSmsSubmit","code","renderHeader","jsxs","Layers3","renderSocialProviders","provider","renderPasswordForm","UserRound","LockKeyhole","Fragment","Loader2","ArrowRight","renderSmsForm","MessageCircle","renderForms","cn","AuthRegisterPanel","requirePhoneVerification","requireTermsAccepted","termsLabel","validateRegister","onRegister","termsAccepted","setTermsAccepted","registerPending","setRegisterPending","handleRegister","AuthPageShell","children","visual","overlay","contentClassName","panelClassName","AuthVisualCarousel","items","intervalMs","showIndicators","showText","imageClassName","ariaLabel","currentSlide","setCurrentSlide","isPaused","setIsPaused","hasItems","currentItem","goToSlide","nextSlide","previousSlide","slide","handleKeyDown","item","AuthPanel","mode","defaultMode","onModeChange","loginProps","registerProps","loginLabel","registerLabel","internalMode","setInternalMode","currentMode","setMode","nextMode"],"mappings":"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"}
|