react19【系列实用教程】实用组件封装

必要的全局样式

src/index.css

c 复制代码
@import "tailwindcss";
/* 当根元素有 class="dark" 时 → 激活 dark: 样式,用于在页面上切换主题为暗黑模式 */
@custom-variant dark (&:where(.dark, .dark *));

@theme {
  /* 主配色 */
  --color-apple-light: #f5f5f7;
  --color-apple-dark: #1d1d1f;
  /* 标准色 */
  --color-apple-black: #000000;
  --color-apple-white: #ffffff;
  /* 品牌配色 */
  --color-apple-blue: #0071e3;
  --color-apple-red: #b64400;
  /* 灰阶系统(Gray Scale) */
  --color-apple-gray-100: #f5f5f7;
  --color-apple-gray-200: #d2d2d7;
  --color-apple-gray-300: #86868b;
  --color-apple-gray-800: #424245;
  --color-apple-gray-900: #1d1d1f;
  /* 字体 */
  --font-sans: "Inter", "Roboto", "Open Sans", "Helvetica Neue", sans-serif;
  --font-display: "Poppins", "Inter", "sans-serif";
  --font-text: "Source Sans Pro", "Open Sans", "sans-serif";
  /* 文字颜色*/
  --color-apple-text-light: #1d1d1f;
  --color-apple-text-dark: #f5f5f7;
  /* 阴影 */
  --shadow-apple-sm: 0 1px 3px rgba(0, 0, 0, 0.1);
  --shadow-apple-md: 0 4px 12px rgba(0, 0, 0, 0.08);
  --shadow-apple-lg: 0 8px 24px rgba(0, 0, 0, 0.06);
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: 0.01em;
  color: var(--color-apple-text-light);
  background-color: var(--color-apple-light);
}

按钮

src/components/Button.tsx

c 复制代码
export interface ButtonProps {
  title?: React.ReactNode;
  variant?: "primary" | "outline";
  disabled?: boolean;
  onClick?: () => void;
}

const Button = ({
  title,
  variant = "primary",
  disabled = false,
  onClick,
}: ButtonProps) => {
  let className = `px-5 py-2 rounded-md border
                   transition-colors duration-200
                   inline-flex items-center justify-center gap-2`;
  if (variant === "primary") {
    className +=
      " bg-apple-blue text-white border-apple-blue hover:bg-apple-blue/90";
  } else if (variant === "outline") {
    className +=
      " bg-transparent text-apple-blue border-apple-blue hover:bg-apple-blue hover:text-white";
  }

  if (disabled) {
    className += " opacity-50 cursor-not-allowed pointer-events-none";
  }

  return (
    <button className={className} disabled={disabled} onClick={onClick}>
      {title}
    </button>
  );
};

export default Button;

使用

c 复制代码
<Button title="购买" variant="outline" />

图标按钮

src/components/IconButton.tsx

c 复制代码
import Button, { type ButtonProps } from "./Button.tsx";

export interface IconButtonProps extends ButtonProps {
  icon: React.ReactNode;
  ioconPosition?: "left" | "right";
}

const IconButton = ({
  icon,
  ioconPosition = "left",
  title,
  ...rest
}: IconButtonProps) => {
  return (
    <Button
      title={
        <span className="flex items-center gap-2">
          {ioconPosition === "left" && icon}
          <span>{title}</span>
          {ioconPosition === "right" && icon}
        </span>
      }
      {...rest}
    />
  );
};

export default IconButton;

使用

c 复制代码
import IconButton from "./IconButton.tsx";
import { MdOutlineNavigateNext } from "react-icons/md";
c 复制代码
          <IconButton
            icon={<MdOutlineNavigateNext />}
            ioconPosition="right"
            title="进一步了解"
            variant="primary"
          />
相关推荐
Setsuna_F_Seiei8 小时前
前端转型 Agent 开发 04 之 MCP 与 Skill(赋予 Agent 更广工作能力)
前端·agent
刘发财10 小时前
前端2秒生成500页矢量PDF,rust真的强到没朋友
前端·javascript·rust
lsswear10 小时前
Python 并发 线程
开发语言·python
郑州光合科技余经理10 小时前
国际版外卖系统:税率字段怎么和订单主流程解耦
android·java·开发语言·前端·后端·php·ai编程
软件课代表CiCi11 小时前
运行库是什么?电脑缺运行库怎么办?c++运行库缺失修复全攻略
开发语言·c++·windows·电脑·dll修复·dll丢失·运行库
梦想平凡11 小时前
百游棋牌源代码开发搭建教程(十):隔离部署、备份恢复与双端验收
java·前端·javascript·数据库·源代码管理
Ivanqhz11 小时前
MLIR OpBuilder
开发语言·python·mlir
yume_sibai12 小时前
06-Rust Web 开发实战(Axum 框架 + 数据库 + JWT 认证 + 中间件 + 部署)
前端·数据库·rust
红宝村村长12 小时前
windows笔记本双系统ubuntu设置
开发语言
计算机魔术师13 小时前
特朗普上台打给黄仁勋:AI末日论是骗局,我们绝不让它发生
前端