完成页面的基础配置

This commit is contained in:
JIANG
2025-09-28 15:51:45 +08:00
parent e34dc99330
commit 6d1cc6c9a1
28 changed files with 9753 additions and 52 deletions

View File

@@ -0,0 +1,57 @@
import clsx from "clsx";
import { useState } from "react";
const ToolbarButton: React.FC<{
icon: React.ReactNode;
name: string;
isActive: boolean;
onClick: () => void;
disabled?: boolean;
}> = ({ icon, name, isActive, onClick, disabled = false }) => {
const [showTooltip, setShowTooltip] = useState(false);
return (
<div className="relative flex items-center justify-center">
<button
className={clsx(
"w-8 h-8 rounded-lg m-1 bg-white border border-gray-300 shadow-sm flex items-center justify-center transition-colors duration-150",
"hover:bg-blue-50 hover:border-blue-400 focus:outline-none focus:ring-2 focus:ring-blue-300",
"active:bg-blue-600 active:border-blue-700",
{
"border-blue-600 bg-blue-50 shadow-md ring-1 ring-blue-300": isActive && !disabled,
"bg-gray-100 border-gray-200 cursor-not-allowed": disabled,
"hover:bg-gray-100 hover:border-gray-200": disabled,
}
)}
onClick={onClick}
onMouseEnter={() => !disabled && setShowTooltip(true)}
onMouseLeave={() => setShowTooltip(false)}
aria-label={name}
type="button"
disabled={disabled}
>
<span
className={clsx(
"flex items-center justify-center w-full h-full text-xl active:scale-95 active:text-white",
{
"text-blue-600": isActive && !disabled,
"text-gray-700": !isActive && !disabled,
"text-gray-400": disabled,
}
)}
>
{icon}
</span>
</button>
{showTooltip && !disabled && (
<div className="absolute left-full top-1/2 -translate-y-1/2 ml-2 px-3 py-2 text-xs text-gray-800 bg-white border border-gray-300 rounded shadow-lg whitespace-nowrap z-20">
{name}
<div className="absolute left-0 top-1/2 -translate-y-1/2 -ml-2 w-0 h-0 border-y-8 border-y-transparent border-r-8 border-r-white"></div>
</div>
)}
</div>
);
};
export default ToolbarButton;

View File

@@ -0,0 +1,18 @@
"use client";
import React from "react";
import { IoIosWater } from "react-icons/io";
import { PROJECT_TITLE } from "@config/config";
interface TitleProps {
collapsed?: boolean;
}
export const Title: React.FC<TitleProps> = ({ collapsed = false }) => {
return (
<div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
<IoIosWater className="w-6 h-6" style={{ color: "#1976d2" }} />
{!collapsed && <span className="select-none"> {PROJECT_TITLE} </span>}
</div>
);
};