feat(back-button): enhance button styles and add variant support; refactor back navigation in sidebar and coins rules screen

This commit is contained in:
2026-06-29 14:54:03 +08:00
parent 096978e703
commit ef18500de3
9 changed files with 104 additions and 119 deletions
+57 -12
View File
@@ -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;
}
+40 -4
View File
@@ -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 = (
<ChevronLeft size={iconSize} strokeWidth={2.5} aria-hidden="true" />
);
if (href) {
return (
<Link href={href} className={buttonClassName} aria-label={ariaLabel}>
{icon}
</Link>
);
}
return (
<button
type="button"
className={[styles.backButton, className].filter(Boolean).join(" ")}
className={buttonClassName}
onClick={onClick}
aria-label={ariaLabel}
>
<ChevronLeft size={20} strokeWidth={2.5} aria-hidden="true" />
{icon}
</button>
);
}