把前端组件做成一座小岛:Animal-Island-UI 的自然风 React 组件库拆解

0 阅读5分钟

项目地址:guokaigdg/animal-island-ui

先说结论

Animal-Island-UI 是一套基于 React + TypeScript 的轻量组件库,视觉气质偏自然、圆润、轻松,适合做个人站点、儿童教育、互动页面和带一点游戏感的展示型产品。它不是那种“后台系统一把梭”的严肃组件库,而是更偏主题化:按钮、卡片、弹窗、手机面板、分割线、图标、加载动画等组件都围绕一套统一的设计语言组织起来。

仓库也把边界写得很清楚:项目用于学习、研究和非商业展示;视觉灵感来自游戏界面,但没有直接使用官方美术素材、代码或资源文件。

项目速览

维度内容
技术栈React、TypeScript、Vite、Less、CSS Modules
包名animal-island-ui
组件数量本地快照中 src/components 下 18 个组件目录
样式入口import 'animal-island-ui/style'
构建产物ES Module、CommonJS、类型声明、独立 CSS
许可证MIT,但 README 明确限定学习使用并提示非商业边界

组件库的整体结构

在这里插入图片描述

Animal-Island-UI 的代码结构非常适合学习组件库怎么组织:每个组件单独成目录,组件逻辑写在 *.tsx,样式写在 *.module.less,再通过 index.ts 做局部导出;根入口 src/index.ts 统一导出组件和类型。

flowchart TB
  App["使用方应用"] --> Import["animal-island-ui"]
  Import --> Entry["src/index.ts"]
  Entry --> Components["18 个组件目录"]
  Components --> TSX["React + TypeScript"]
  Components --> Less["CSS Modules + Less"]
  Entry --> Style["全局样式与字体"]
  Style --> Package["dist/index.css"]

目前导出的组件包括 ButtonInputSwitchModalCardFooterCollapseCursorTimePhoneDividerTypewriterIconSelectTabsCheckboxCodeBlockLoading。这个组合很有意思:它既有通用表单控件,也有强主题组件,比如 PhoneCursorFooterLoading,说明项目目标不是复制 Ant Design,而是构建一套带性格的界面素材。

设计 Token:风格不是靠玄学

在这里插入图片描述

项目的视觉基础集中在 src/styles/variables.less。颜色、字号、间距、圆角、阴影、动效时长都被抽成 Less 变量。主色是偏清爽的青绿色,文字色偏棕,背景是柔和米白,整体避免了高饱和工业感。

Token 类型例子
主色@primary-color: #19c8b9
语义色success、warning、error
字体Nunito、Noto Sans SC、Zen Maru Gothic
圆角16px、18px、24px
阴影轻量棕色透明阴影
动效0.15s、0.25s、0.35s

它还内置了字体资源,并在构建阶段处理字体产物。这种做法会让组件在不同机器上的观感更稳定,尤其是中文和日文场景,不完全依赖系统字体。

构建与发布管线

在这里插入图片描述

仓库有两套 Vite 配置:一套用于组件库构建,一套用于 Demo 站点。库构建走 Vite library mode,外部化 reactreact-domreact/jsx-runtime,输出 ES/CJS 两种格式,并配合 TypeScript 生成类型声明。

flowchart LR
  Source["src/index.ts"] --> Vite["Vite library build"]
  Vite --> ES["dist/es/index.js"]
  Vite --> CJS["dist/cjs/index.cjs"]
  Source --> TSC["tsc declarations"]
  TSC --> Types["dist/types"]
  Less["Less / CSS Modules"] --> CSS["dist/index.css"]
  Fonts["fontsource 字体"] --> Assets["dist/files"]

比较细的一点是,vite.config.ts 里有一个 stripWoffFallbackPlugin,会去掉 fontsource CSS 里的 woff 备份,只保留 woff2,并删除未被最终 CSS 引用的 woff 文件。对组件库来说,这属于很实在的体积优化:不改变开发体验,却能减少发布包里的冗余字体文件。

使用方式

安装:

npm install animal-island-ui

基础使用:

import { Button, Card } from 'animal-island-ui';
import 'animal-island-ui/style';

export function Demo() {
  return (
    <Card color="app-blue">
      <Button type="primary">开始冒险</Button>
    </Card>
  );
}

README 特别提醒必须导入样式文件。这个提示很重要:组件逻辑和样式是分离发布的,如果忘了 animal-island-ui/style,组件会存在,但不会呈现预期的字体、色彩和主题细节。

它适合做什么

Animal-Island-UI 最适合三类项目:

场景为什么适合
个人主页 / 博客主题感强,容易做出记忆点
儿童教育 / 轻互动产品圆润、友好,不像传统后台组件
前端组件学习结构清楚,能看到组件、样式、构建完整链路

它不太适合企业后台、金融系统、数据密集型表格平台。不是技术做不到,而是气质不对。组件库的第一价值是统一体验,如果项目需要的是高密度、低装饰、强效率,应该选更偏工作台的设计系统。

二次开发建议

如果想基于它继续做自己的主题库,建议从三处下手:

  1. 先改 variables.less,不要急着改每个组件。
  2. 新组件沿用“组件目录 + TSX + module.less + index.ts”的结构。
  3. 构建前检查导出类型,避免组件能用但类型不可用。

更进一步,可以把色彩、圆角、阴影做成主题变量,给 Demo 增加“主题切换”页面。这样既能保留当前自然风,又能扩展出不同场景的皮肤。

注意边界

项目 README 已明确写到:仅用于个人学习、研究与非商业展示,禁止商业使用、二次售卖或盈利行为,并说明与任天堂没有关联、授权或合作关系。使用时最好保留这个边界,不要把主题风格直接包装成商业模板售卖。

总结

Animal-Island-UI 的可贵之处,是它把“主题化 UI”做成了一个真正可安装、可构建、可学习的组件库。它不追求覆盖所有业务场景,而是把自然、圆润、轻松的视觉语言坚持到底。对想学习 React 组件库工程化的人来说,它比一个静态页面更有参考价值;对想做有温度的小产品的人来说,它也比通用组件库更容易出效果。