refactor(auth): migrate shell styles to tailwind

This commit is contained in:
2026-07-10 18:56:53 +08:00
parent 37fbcfa68e
commit 65cbdf3f20
11 changed files with 51 additions and 90 deletions
+8 -3
View File
@@ -13,7 +13,6 @@ import { ROUTES } from "@/router/routes";
import { useAppNavigator } from "@/router/use-app-navigator"; import { useAppNavigator } from "@/router/use-app-navigator";
import { AuthBackground, AuthPanel } from "./components"; import { AuthBackground, AuthPanel } from "./components";
import styles from "./components/auth-screen.module.css";
import { Logger } from "@/utils"; import { Logger } from "@/utils";
const log = new Logger("AppAuthAuthScreen"); const log = new Logger("AppAuthAuthScreen");
@@ -51,9 +50,15 @@ export function AuthScreen() {
return ( return (
<MobileShell> <MobileShell>
<div className={styles.wrapper}> <div className="relative flex min-h-[var(--app-viewport-height,100dvh)] w-full flex-1 flex-col overflow-hidden bg-[#fbf1f2]">
<AuthBackground /> <AuthBackground />
<div className={styles.content}> <div
className="relative z-[2] flex flex-auto flex-col justify-center"
style={{
padding:
"calc(var(--page-padding-y, var(--spacing-lg)) + var(--app-safe-top, 0px)) calc(var(--page-padding-x, var(--spacing-lg)) + var(--app-safe-right, 0px)) calc(var(--page-padding-y, var(--spacing-lg)) + var(--app-safe-bottom, 0px)) calc(var(--page-padding-x, var(--spacing-lg)) + var(--app-safe-left, 0px))",
}}
>
<AuthPanel /> <AuthPanel />
</div> </div>
</div> </div>
@@ -1,7 +1,14 @@
import { renderToStaticMarkup } from "react-dom/server"; import { renderToStaticMarkup } from "react-dom/server";
import { describe, expect, it } from "vitest"; import { describe, expect, it, vi } from "vitest";
import { AuthBackground } from "../auth-background";
import { AuthErrorMessage } from "../auth-error-message"; import { AuthErrorMessage } from "../auth-error-message";
import { EmailLoginForm } from "../email-login-form";
import { EmailRegisterForm } from "../email-register-form";
vi.mock("@/stores/auth/auth-context", () => ({
useAuthDispatch: () => vi.fn(),
}));
describe("auth Tailwind components", () => { describe("auth Tailwind components", () => {
it("renders AuthErrorMessage only when a message is present", () => { it("renders AuthErrorMessage only when a message is present", () => {
@@ -12,4 +19,34 @@ describe("auth Tailwind components", () => {
expect(html).toContain("text-error"); expect(html).toContain("text-error");
expect(html).toContain("Invalid email"); expect(html).toContain("Invalid email");
}); });
it("renders EmailLoginForm with Tailwind form layout", () => {
const html = renderToStaticMarkup(<EmailLoginForm />);
expect(html).toContain("<form");
expect(html).toContain("flex");
expect(html).toContain("w-full");
expect(html).toContain("gap-md");
expect(html).toContain("Login");
});
it("renders EmailRegisterForm with Tailwind form layout", () => {
const html = renderToStaticMarkup(<EmailRegisterForm />);
expect(html).toContain("<form");
expect(html).toContain("flex");
expect(html).toContain("w-full");
expect(html).toContain("gap-md");
expect(html).toContain("Register");
});
it("renders AuthBackground with Tailwind layout classes", () => {
const html = renderToStaticMarkup(<AuthBackground />);
expect(html).toContain("absolute");
expect(html).toContain("inset-0");
expect(html).toContain("bg-[#fbf1f2]");
expect(html).toContain("object-cover");
expect(html).toContain("%2Fimages%2Fauth%2Fbg-login.png");
});
}); });
@@ -1,14 +0,0 @@
/* Auth 背景图片容器(与 splash-background.module.css 同款) */
.bg {
position: absolute;
inset: 0;
z-index: 0;
background: #fbf1f2;
overflow: hidden;
}
.image {
object-fit: cover;
object-position: center;
}
+2 -3
View File
@@ -5,18 +5,17 @@
* 资源: /public/images/auth/bg-login.png * 资源: /public/images/auth/bg-login.png
*/ */
import Image from "next/image"; import Image from "next/image";
import styles from "./auth-background.module.css";
export function AuthBackground() { export function AuthBackground() {
return ( return (
<div className={styles.bg}> <div className="absolute inset-0 z-0 overflow-hidden bg-[#fbf1f2]">
<Image <Image
src="/images/auth/bg-login.png" src="/images/auth/bg-login.png"
alt="" alt=""
fill fill
priority priority
sizes="(max-width: 540px) 100vw, 540px" sizes="(max-width: 540px) 100vw, 540px"
className={styles.image} className="object-cover object-center"
/> />
</div> </div>
); );
@@ -1,13 +0,0 @@
/*
*
* 视觉规格(与 Dart 对齐):
* - panelShell 包裹整个面板(position: relative
*/
.panelShell {
position: relative;
flex: 1 1 auto;
display: flex;
flex-direction: column;
width: 100%;
min-height: 0;
}
+1 -2
View File
@@ -8,7 +8,6 @@ import { useAuthDispatch, useAuthState } from "@/stores/auth/auth-context";
import { AuthEmailPanel } from "./auth-email-panel"; import { AuthEmailPanel } from "./auth-email-panel";
import { AuthFacebookPanel } from "./auth-facebook-panel"; import { AuthFacebookPanel } from "./auth-facebook-panel";
import styles from "./auth-panel.module.css";
export function AuthPanel() { export function AuthPanel() {
const state = useAuthState(); const state = useAuthState();
@@ -29,7 +28,7 @@ export function AuthPanel() {
}; };
return ( return (
<div className={styles.panelShell}> <div className="relative flex min-h-0 w-full flex-auto flex-col">
<BackButton onClick={handleBack} /> <BackButton onClick={handleBack} />
{state.authPanelMode === "facebook" ? ( {state.authPanelMode === "facebook" ? (
@@ -1,29 +0,0 @@
/* auth-screen.module.css
* 与 splash-screen.module.css 同款结构(MobileShell 顶层 + .wrapper + .content
* 移动端宽度约束由 ResponsiveMobileShell / MobileShell 统一提供。
*/
.wrapper {
position: relative;
flex: 1;
display: flex;
flex-direction: column;
width: 100%;
min-height: var(--app-viewport-height, 100dvh);
background: #fbf1f2;
overflow: hidden;
}
.content {
position: relative;
z-index: 2;
display: flex;
flex: 1 1 auto;
flex-direction: column;
justify-content: center;
padding:
calc(var(--page-padding-y, var(--spacing-lg)) + var(--app-safe-top, 0px))
calc(var(--page-padding-x, var(--spacing-lg)) + var(--app-safe-right, 0px))
calc(var(--page-padding-y, var(--spacing-lg)) + var(--app-safe-bottom, 0px))
calc(var(--page-padding-x, var(--spacing-lg)) + var(--app-safe-left, 0px));
}
@@ -1,14 +0,0 @@
/* 邮箱登录/注册表单样式
*
*
*
* 视觉规格(与 Dart 对齐):
* - 字段间距 12pxDart AppSpacing.md
* - 错误横幅与主按钮之间 12px
*/
.form {
display: flex;
flex-direction: column;
gap: var(--spacing-md);
width: 100%;
}
+1 -2
View File
@@ -13,7 +13,6 @@ import {
import { AuthTextField } from "./auth-text-field"; import { AuthTextField } from "./auth-text-field";
import { AuthPrimaryButton } from "./auth-primary-button"; import { AuthPrimaryButton } from "./auth-primary-button";
import { AuthErrorMessage } from "./auth-error-message"; import { AuthErrorMessage } from "./auth-error-message";
import styles from "./email-form.module.css";
import { AppEnvUtil, Logger } from "@/utils"; import { AppEnvUtil, Logger } from "@/utils";
const log = new Logger("AppAuthComponentsEmailLoginForm"); const log = new Logger("AppAuthComponentsEmailLoginForm");
@@ -76,7 +75,7 @@ export function EmailLoginForm({
return ( return (
<form <form
className={styles.form} className="flex w-full flex-col gap-md"
onSubmit={(e) => { onSubmit={(e) => {
e.preventDefault(); e.preventDefault();
submit(); submit();
@@ -24,7 +24,6 @@ import {
import { AuthTextField } from "./auth-text-field"; import { AuthTextField } from "./auth-text-field";
import { AuthPrimaryButton } from "./auth-primary-button"; import { AuthPrimaryButton } from "./auth-primary-button";
import { AuthErrorMessage } from "./auth-error-message"; import { AuthErrorMessage } from "./auth-error-message";
import styles from "./email-form.module.css";
import { Logger } from "@/utils"; import { Logger } from "@/utils";
const log = new Logger("AppAuthComponentsEmailRegisterForm"); const log = new Logger("AppAuthComponentsEmailRegisterForm");
@@ -112,7 +111,7 @@ export function EmailRegisterForm({
return ( return (
<form <form
className={styles.form} className="flex w-full flex-col gap-md"
onSubmit={(e) => { onSubmit={(e) => {
e.preventDefault(); e.preventDefault();
submit(); submit();
@@ -1,7 +0,0 @@
.slot {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
min-height: var(--button-height);
}