diff --git a/src/app/_components/back-button.module.css b/src/app/_components/back-button.module.css
index 839eea03..e5ef4425 100644
--- a/src/app/_components/back-button.module.css
+++ b/src/app/_components/back-button.module.css
@@ -1,29 +1,74 @@
.backButton {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0;
+ color: var(--color-auth-text-primary);
+ cursor: pointer;
+ border: 0;
+ border-radius: 999px;
+ text-decoration: none;
+ transition:
+ background 0.15s ease,
+ box-shadow 0.18s ease,
+ transform 0.05s ease;
+}
+
+.floating {
position: absolute;
top: var(--spacing-xl);
left: var(--spacing-xl);
z-index: 2;
- display: inline-flex;
- align-items: center;
- justify-content: center;
width: var(--back-button-size);
height: var(--back-button-size);
padding: 0 2px 0 0;
- color: var(--color-auth-text-primary);
- cursor: pointer;
background: var(--color-auth-surface);
- border: none;
- border-radius: 50%;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- transition:
- background 0.15s ease,
- transform 0.05s ease;
}
-.backButton:hover {
+.soft {
+ width: 42px;
+ height: 42px;
+ color: #21191d;
+ border: 1px solid rgba(25, 19, 22, 0.08);
+ background: rgba(255, 255, 255, 0.82);
+ box-shadow: 0 10px 22px rgba(50, 30, 40, 0.08);
+}
+
+.ghost {
+ width: 32px;
+ height: 32px;
+ color: #000000;
+ background: transparent;
+}
+
+.floating:hover {
background: rgba(0, 0, 0, 0.04);
}
-.backButton:active {
+.soft:hover {
+ background: #ffffff;
+ box-shadow: 0 14px 26px rgba(50, 30, 40, 0.12);
+ transform: translateY(-1px);
+}
+
+.ghost:hover {
+ opacity: 0.7;
+}
+
+.floating:active {
transform: scale(0.96);
}
+
+.soft:active {
+ transform: translateY(1px);
+}
+
+.ghost:active {
+ transform: scale(0.96);
+}
+
+.backButton:focus-visible {
+ outline: 2px solid #f657a0;
+ outline-offset: 3px;
+}
diff --git a/src/app/_components/back-button.tsx b/src/app/_components/back-button.tsx
index 1870a416..66382989 100644
--- a/src/app/_components/back-button.tsx
+++ b/src/app/_components/back-button.tsx
@@ -1,28 +1,64 @@
"use client";
import { ChevronLeft } from "lucide-react";
+import Link, { type LinkProps } from "next/link";
import styles from "./back-button.module.css";
-export interface BackButtonProps {
- onClick: () => void;
+interface BackButtonBaseProps {
className?: string;
ariaLabel?: string;
+ iconSize?: number;
+ variant?: "floating" | "soft" | "ghost";
}
+type BackButtonLinkProps = BackButtonBaseProps & {
+ href: LinkProps["href"];
+ onClick?: never;
+};
+
+type BackButtonActionProps = BackButtonBaseProps & {
+ href?: never;
+ onClick: () => void;
+};
+
+export type BackButtonProps = BackButtonLinkProps | BackButtonActionProps;
+
export function BackButton({
+ href,
onClick,
className,
ariaLabel = "Back",
+ iconSize = 24,
+ variant = "floating",
}: BackButtonProps) {
+ const buttonClassName = [
+ styles.backButton,
+ styles[variant],
+ className,
+ ]
+ .filter(Boolean)
+ .join(" ");
+ const icon = (
+
+ );
+
+ if (href) {
+ return (
+
+ {icon}
+
+ );
+ }
+
return (
);
}
diff --git a/src/app/coins-rules/coins-rules-screen.module.css b/src/app/coins-rules/coins-rules-screen.module.css
index eb8dc166..a6f37433 100644
--- a/src/app/coins-rules/coins-rules-screen.module.css
+++ b/src/app/coins-rules/coins-rules-screen.module.css
@@ -15,36 +15,6 @@
gap: 18px;
}
-.backLink {
- display: inline-flex;
- width: 42px;
- height: 42px;
- align-items: center;
- justify-content: center;
- color: #21191d;
- text-decoration: none;
- border: 1px solid rgba(25, 19, 22, 0.08);
- border-radius: 999px;
- background: rgba(255, 255, 255, 0.82);
- box-shadow: 0 10px 22px rgba(50, 30, 40, 0.08);
- transition: background 0.18s ease, box-shadow 0.18s ease, transform 0.16s ease;
-}
-
-.backLink:hover {
- background: #ffffff;
- box-shadow: 0 14px 26px rgba(50, 30, 40, 0.12);
- transform: translateY(-1px);
-}
-
-.backLink:active {
- transform: translateY(1px);
-}
-
-.backLink:focus-visible {
- outline: 2px solid #f657a0;
- outline-offset: 3px;
-}
-
.hero {
position: relative;
overflow: hidden;
diff --git a/src/app/coins-rules/coins-rules-screen.tsx b/src/app/coins-rules/coins-rules-screen.tsx
index a6db6679..bdc0a31e 100644
--- a/src/app/coins-rules/coins-rules-screen.tsx
+++ b/src/app/coins-rules/coins-rules-screen.tsx
@@ -1,7 +1,6 @@
"use client";
import {
- ArrowLeft,
Coins,
Gift,
ImageIcon,
@@ -10,8 +9,8 @@ import {
Phone,
Sparkles,
} from "lucide-react";
-import Link from "next/link";
+import { BackButton } from "@/app/_components";
import { MobileShell } from "@/app/_components/core";
import { ROUTES } from "@/router/routes";
@@ -69,13 +68,11 @@ export function CoinsRulesScreen() {
-
-
-
+ />
diff --git a/src/app/sidebar/components/back-bar.module.css b/src/app/sidebar/components/back-bar.module.css
deleted file mode 100644
index e27325e2..00000000
--- a/src/app/sidebar/components/back-bar.module.css
+++ /dev/null
@@ -1,28 +0,0 @@
-.bar {
- padding: var(--spacing-md, 12px) 0;
- display: flex;
- align-items: center;
-}
-
-.link {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- width: 32px;
- height: 32px;
- color: #000000;
- text-decoration: none;
- background: none;
- border: 0;
- padding: 0;
- cursor: pointer;
-}
-
-.link:hover {
- opacity: 0.7;
-}
-
-.icon {
- color: currentColor;
- flex-shrink: 0;
-}
diff --git a/src/app/sidebar/components/back-bar.tsx b/src/app/sidebar/components/back-bar.tsx
deleted file mode 100644
index e6590b46..00000000
--- a/src/app/sidebar/components/back-bar.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-"use client";
-
-import { ChevronLeft } from "lucide-react";
-import Link from "next/link";
-
-import { ROUTES } from "@/router/routes";
-
-import styles from "./back-bar.module.css";
-
-/**
- * 顶部返回栏:图标按钮,链接至聊天页。
- *
- * 视觉规格(与设计稿对齐):
- * - 黑色文本(浅色主题下)
- * - 居左对齐,顶部留白
- */
-export function BackBar() {
- return (
-
- );
-}
diff --git a/src/app/sidebar/components/index.ts b/src/app/sidebar/components/index.ts
index 2851c683..fb685f6c 100644
--- a/src/app/sidebar/components/index.ts
+++ b/src/app/sidebar/components/index.ts
@@ -2,7 +2,6 @@
* @file Automatically generated by barrelsby.
*/
-export * from "./back-bar";
export * from "./sidebar-wallet-card";
export * from "./user-header";
export * from "./vip-benefits-card";
diff --git a/src/app/sidebar/components/sidebar-screen.module.css b/src/app/sidebar/components/sidebar-screen.module.css
index 91bac7a9..c3440cfb 100644
--- a/src/app/sidebar/components/sidebar-screen.module.css
+++ b/src/app/sidebar/components/sidebar-screen.module.css
@@ -49,7 +49,7 @@
}
.topBar {
- margin: 4px 0 -2px;
+ margin: 10px 0 -2px;
}
.hero {
diff --git a/src/app/sidebar/sidebar-screen.tsx b/src/app/sidebar/sidebar-screen.tsx
index 2097db7e..702faae7 100644
--- a/src/app/sidebar/sidebar-screen.tsx
+++ b/src/app/sidebar/sidebar-screen.tsx
@@ -4,13 +4,13 @@ import { LogOut } from "lucide-react";
import { signOut } from "next-auth/react";
import { useRouter } from "next/navigation";
+import { BackButton } from "@/app/_components";
import { MobileShell } from "@/app/_components/core";
import { ROUTES } from "@/router/routes";
import { useAuthDispatch, useAuthState } from "@/stores/auth/auth-context";
import { useUserDispatch, useUserState } from "@/stores/user/user-context";
import {
- BackBar,
SidebarWalletCard,
UserHeader,
type SidebarUserState,
@@ -56,7 +56,7 @@ export function SidebarScreen() {
-
+