# react-paperboard-ui **Repository Path**: wangkai000/react-paperboard-ui ## Basic Information - **Project Name**: react-paperboard-ui - **Description**: 一款面向React的纸皮风格UI库 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-03 - **Last Updated**: 2026-07-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 📦 Paperboard UI **瓦楞纸板质感 React 组件库 · Corrugated Cardboard Textured React Component Library** [English](#english) · [中文](#中文) > 6 种纸主题 · 5 种边缘模式 · 65 个组件 · SSR 安全 · 运行时主题切换 --- ## English A React component library with authentic corrugated cardboard texture. Built on Radix UI headless primitives + SCSS-crafted textures + CSS custom properties. Runtime theme switching with zero FOUC, full TypeScript support, SSR-safe. > **Distribution model**: shadcn/ui-style atomic CLI distribution. Components are copied as source code into your project — fully customizable, no black-box dist files. ### ✨ Features - **Runtime multi-theme** — 6 paper themes via `data-theme` + CSS variables, no reload needed - **Corrugation toggle** — `data-corrugated` controls flute texture visibility - **5 edge modes** — clean / torn / scissor / rough / zigzag, seeded PRNG generates stable `clip-path` - **65 components** — full coverage: primitives, forms, layouts, navigation, feedback, data display, paper-style decorations - **Radix headless + SCSS** — interaction logic by Radix UI, visual texture by SCSS Modules - **TypeScript friendly** — full type exports, every component uses `forwardRef` + `displayName` - **Source-first distribution** — no dist package; components live in your `src/` as editable source --- ### 📦 Quick Start (CLI) ```bash # 1. Initialize paperboard in your React project npx react-paperboard-ui init # 2. Add components you need npx react-paperboard-ui add Button npx react-paperboard-ui add Card npx react-paperboard-ui add Select # 3. Import and use ``` ```tsx import { Button } from '@/components/paperboard-ui/Button'; import { Card } from '@/components/paperboard-ui/Card'; ``` > **How it works**: `init` copies shared dependencies (ThemeProvider, tokens, edge hooks). `add ` resolves component dependencies, copies source files into your project, and installs required npm peer deps. All code is yours to modify. > > **Path alias**: The import path `@/components/paperboard-ui/` depends on your `tsconfig.json` path aliases. Make sure `@/*` → `./src/*` (or equivalent) is configured in `compilerOptions.paths`. --- ### 🚀 Usage Example ```tsx import React, { useState } from 'react'; import { ThemeProvider, useTheme } from '@/theme'; import { Button } from '@/components/paperboard-ui/Button'; import { Card } from '@/components/paperboard-ui/Card'; import { Input } from '@/components/paperboard-ui/Input'; import { Tag } from '@/components/paperboard-ui/Tag'; import { Surface } from '@/components/paperboard-ui/Surface'; function App() { const [name, setName] = useState(''); const { theme, setTheme, corrugated, setCorrugated } = useTheme(); return (

Shipping Label

setName(e.target.value)} />
Fragile Handle with care

Tracking #: PB-{Date.now().toString().slice(-6)}

); } export default function Root() { return ( ); } ``` --- ### 🎨 Theme System 6 built-in paper themes, switchable at runtime via `data-theme`: | Theme | `data-theme` | Description | |-------|-------------|-------------| | Kraft paper | `kraft` | Default, standard cardboard brown | | White board | `white` | Warm white tone | | Dark board | `dark` | True dark mode (`color-scheme: dark`) | | Rice paper | `rice` | Off-white, cool tone | | Parchment | `parchment` | Yellowish antique | | Letter paper | `letter` | Light cream | #### ThemeProvider ```tsx import { ThemeProvider } from '@/theme'; ``` | Prop | Type | Default | Description | |------|------|---------|-------------| | `theme` | `PaperTheme` | `'kraft'` | Paper theme key | | `corrugated` | `boolean` | `false` | Corrugation texture toggle | | `defaultEdgeMode` | `EdgeMode` | `'clean'` | Default edge mode (overridable per component) | | `container` | `HTMLElement` | `document.documentElement` | Target element for `data-*` attributes | | `tokens` | `Partial` | — | CSS variable overrides (`--pb-*`) | > **Auto dark mode**: If no `theme` is set and the system prefers `prefers-color-scheme: dark`, it auto-switches to `dark`. Manual `setTheme()` disables auto-following. #### useTheme Hook ```tsx import { useTheme } from '@/theme'; function ThemeSwitcher() { const { theme, setTheme, corrugated, setCorrugated, defaultEdgeMode, setDefaultEdgeMode } = useTheme(); return ( <> ); } ``` #### CSS Variable Names ``` --pb-paper-base / light / dark / cream / darker --pb-flute / flute-dark --pb-tape --pb-accent / accent-hover / accent-deep --pb-ink / ink-faded --pb-success / warning / error / info (+ -deep variants) --pb-white / black / border-color / cardboard ``` --- ### ✂️ Edge Modes 5 edge modes powered by seeded PRNG (`mulberry32`) generating stable `clip-path: polygon(...)` values: | Mode | Key | Description | |------|-----|-------------| | Clean | `clean` | Neat rectangular edge | | Torn | `torn` | Hand-torn paper edge, moderate jitter | | Scissor | `scissor` | Scissor-cut, straight segments with slight offset | | Rough | `rough` | Rough tear, large jitter | | Zigzag | `zigzag` | Natural zigzag pattern | ```tsx Hand-torn edge Scissor cut with custom seed Rough torn card ``` The `seed` prop controls PRNG output for deterministic edge shapes — same seed produces identical results across renders (SSR-safe via `useMemo`). --- ### 📋 Components (65) #### Primitives | Component | Description | Key Props | |-----------|-------------|-----------| | **Surface** | Base paper surface | `variant`, `edgeMode`, `corrugated`, `paper`, `seed`, `asChild` | #### Basics | Component | Description | Key Props | |-----------|-------------|-----------| | **Button** | Paper-style button | `size`, `variant`, `icon`, `loading`, `block`, `asChild` | | **Input** | Text input with label/prefix/suffix | `inputSize`, `error`, `label`, `prefix`, `suffix`, `addonBefore`, `addonAfter` | | **Tag** | Inline tag/label | `variant`, `size`, `removable`, `onRemove` | | **Chip** | Selectable/removable chip | `variant`, `size`, `selected`, `selectable`, `removable`, `icon`, `avatar` | #### Forms | Component | Description | Key Props | |-----------|-------------|-----------| | **Checkbox** | Paper checkbox | `checked`, `disabled`, `label`, `onCheckedChange` | | **Radio** | Radio button | `value`, `checked`, `disabled`, `label` | | **Switch** | Toggle switch | `checked`, `disabled`, `label`, `onCheckedChange` | | **Select** | Dropdown (multi/search) | `value`, `multiple`, `options`, `searchable`, `size` | | **Slider** | Range slider | `min`, `max`, `step`, `value`, `onChange`, `disabled` | | **Form** | Form field wrapper | `label`, `required`, `error`, `helperText`, `name` | #### Layout | Component | Description | Key Props | |-----------|-------------|-----------| | **Card** | Paper card container (+ sub-components) | `variant`, `size`, `interactive`, `edgeMode` | | **Panel** | Collapsible panel | `title`, `defaultOpen`, `onOpenChange` | | **Divider** | Divider line | `orientation`, `variant`, `label`, `align` | | **Descriptions** | Key-value list | `items`, `column`, `bordered`, `title` | #### Navigation | Component | Description | Key Props | |-----------|-------------|-----------| | **Tabs** | Tab navigation (Radix) | `Tabs.List`, `Tabs.Trigger`, `Tabs.Content` | | **Breadcrumb** | Breadcrumb trail | `separator`, `Breadcrumb.Item` | | **Pagination** | Page navigation | `current`, `total`, `pageSize`, `onChange`, `size` | | **Menu** | Vertical/horizontal menu | `items`, `selectedKey`, `onSelect`, `mode` | | **Steps** | Step progress | `Steps.Step` (`title`, `description`) | | **Segmented** | Segmented control | `options`, `value`, `onChange` | #### Feedback | Component | Description | Key Props | |-----------|-------------|-----------| | **Tooltip** | Hover tooltip (Radix) | `content`, `side`, `delayDuration` | | **Popover** | Floating popover (Radix) | `open`, `defaultOpen`, `onOpenChange` | | **Dropdown** | Dropdown menu (Radix) | `Dropdown.Item`, `Dropdown.Trigger` | | **Progress** | Progress bar | `value`, `max`, `indicatorColor` | | **Skeleton** | Loading skeleton | `width`, `height`, `variant` | | **Spinner** | Loading spinner | `size`, `color` | | **Alert** | Alert message | `variant`, `title`, `edgeMode` | | **Badge** | Status badge / count | `variant`, `size`, `dot`, `count`, `overflowCount` | | **Toast** | Toast notification (Radix) | `Toast.Provider`, `Toast.Viewport`, `useToast()` | | **Message** | Inline message | `children`, `defaultDuration` | | **Notification** | Notification stack | `children`, `defaultDuration` | | **EmptyState** | Empty data placeholder | `icon`, `title`, `description`, `action` | | **Result** | Result page | `status`, `icon`, `title`, `subTitle`, `extra` | #### Data Display | Component | Description | Key Props | |-----------|-------------|-----------| | **Avatar** | User avatar | `src`, `alt`, `size`, `shape`, `fallback`, `status` | | **Table** | Data table (+ sub-components) | `bordered`, `striped`, `stickyHeader`, `size` | | **List** | Data list | `items`, `bordered`, `size` | | **Statistic** | Statistic display | `title`, `value`, `prefix`, `suffix`, `precision`, `trend` | | **Accordion** | Collapsible accordion | `title`, `defaultOpen`, `disabled` | #### Overlays | Component | Description | Key Props | |-----------|-------------|-----------| | **Drawer** | Side drawer | `open`, `onOpenChange`, `title`, `side`, `size` | | **Modal** | Modal dialog | `open`, `onOpenChange`, `title`, `description`, `size` | #### Paper-Style (25 decorative) | Component | Description | Key Props | |-----------|-------------|-----------| | **Stamp** | Rubber stamp imprint | `color`, `variant`, `edgeMode`, `size`, `rotate` | | **WaxSeal** | Wax seal with embossed pattern | `color`, `size`, `rotate`, `seal`, `shape` | | **Tape** | Adhesive tape piece | `position`, `color`, `width`, `edgeMode` | | **Ribbon** | Decorative ribbon | `color`, `position`, `edgeMode` | | **Envelope** | Openable letter envelope | `sender`, `recipient`, `edgeMode` | | **StickyNote** | Sticky note paper | `color`, `rotate`, `as` | | **PaperStack** | Stack of paper layers (draggable) | `layers`, `offset`, `maxVisible`, `sortable` | | **Timeline** | Vertical timeline | `items`, `mode`, `edgeMode` | | **BulletinBoard** | Bulletin board with pins | `title`, `backgroundColor` | | **CarbonCopy** | Carbon copy paper | `copies`, `defaultValue` | | **ClippingBoard** | Clipping board | `clips` | | **DeskMat** | Desk mat with grid/ruler | `gridSize`, `showRuler` | | **FileFolder** | File folder tab | `title`, `files`, `expanded` | | **JournalPage** | Journal page layout | `date`, `title` | | **LetterSet** | Complete letter set | `sender`, `recipient`, `content`, `stampType`, `waxColor` | | **NotePad** | Note pad with tear-off pages | `pages`, `currentPage`, `onTear` | | **PageTurn** | Flip page animation | `front`, `back`, `open`, `direction` | | **PaperClip** | Paper clip decoration | `position`, `color`, `size` | | **PaperConfetti** | Confetti paper pieces | `count`, `active` | | **PaperCut** | Papercut layered reveal | `revealed`, `layers` | | **PaperPlane** | Flying paper plane animation | `flying`, `onComplete` | | **PushPin** | Push pin decoration | `position`, `color`, `size` | | **StickyWall** | Sticky notes wall | `notes`, `backgroundColor` | | **WritingPaper** | Lined writing paper | `lineType`, `lineColor` | --- ### 📝 Paper-Style Components In Detail The paper-style components are what make Paperboard UI unique — they simulate real-world paper objects with authentic textures and interactions. **Stamp** — Rubber stamp with 4 ink colors, 3 shapes, rotation. Edge mode for distressed edges. ```tsx APPROVED ``` **WaxSeal** — Wax seal with embossed pattern, 6 colors, 4 sizes. Includes wax bleed, highlight, and crack textures. ```tsx ``` **Tape** — Adhesive tape in 8 positions, 3 colors. Edge mode for torn tape ends. ```tsx FRAGILE ``` **Ribbon** — Decorative ribbon banner at top-left or top-right corner. ```tsx Sale ``` **Envelope** — Letter envelope with sender/recipient, openable flap with torn edge. ```tsx Dear Bob, ... ``` **StickyNote** — Classic sticky note in 5 colors, auto-rotation (seed-based for SSR stability). ```tsx Don't forget to ship! Urgent ``` **PaperStack** — Stack of paper layers with offset visualization, draggable sorting (via @dnd-kit). ```tsx Top sheet

}]} offset={6} sortable /> ``` **Timeline** — Vertical timeline with dot or stamp mode. ```tsx ``` **BulletinBoard** — Cork-board style container for pinning notes. ```tsx Meeting at 3pm ``` **CarbonCopy** — Carbon copy paper effect with multiple copies. ```tsx ``` **ClippingBoard** — Clipping board with clipped items. ```tsx ``` **DeskMat** — Desk mat with optional grid lines, ruler, and crop guide. ```tsx Content on the mat ``` **FileFolder** — File folder tab with expandable file list. ```tsx ``` **JournalPage** — Journal page layout with date and title header. ```tsx

It was a good day.

``` **LetterSet** — Complete letter set: sender, recipient, stamp, wax seal. ```tsx Dear Bob...

} stampType="vintage" waxColor="red" /> ``` **NotePad** — Note pad with tear-off pages and page navigation. ```tsx console.log('Torn:', id)} /> ``` **PageTurn** — Flip page animation with front/back content. ```tsx Front} back={
Back
} open={isOpen} direction="right" /> ``` **PaperClip** / **PaperConfetti** / **PaperCut** / **PaperPlane** / **PushPin** — Decorative paper elements with animations. ```tsx

Hidden content

console.log('Sent!')} /> ``` **StickyWall** — Sticky notes wall with multiple notes and background color. ```tsx ``` **WritingPaper** — Lined writing paper with ruled/grid/blank line types. ```tsx

Handwritten content here...

``` --- ### 🔧 Local Development ```bash git clone https://gitee.com/wangkai000/react-paperboard-ui.git cd react-paperboard-ui npm install npm run dev # start demo site (Vite) npm run build # build CLI tool (tsup, output to dist/cli/) npm run test # run tests (Vitest + React Testing Library) npm run storybook # start Storybook (port 6006) npm run build-storybook # build Storybook static site npm run type-check # TypeScript type check npm run lint # ESLint check ``` --- ### 🛠️ Tech Stack | Category | Technology | |----------|-----------| | Framework | React 18 / 19 | | Headless interaction | Radix UI (12 packages) | | Styling | SCSS Modules + CSS Custom Properties | | Icons | lucide-react | | Bundling | Vite (library mode) + tsup (CLI) | | Type system | TypeScript ~5.6 | | Testing | Vitest + React Testing Library + jsdom | | Docs | Storybook 8 | | Drag & drop | @dnd-kit/core + @dnd-kit/sortable | --- ### 📄 License MIT © [wangkai000](https://gitee.com/wangkai000) Repository: [https://gitee.com/wangkai000/react-paperboard-ui](https://gitee.com/wangkai000/react-paperboard-ui) --- ## 中文 瓦楞纸板质感 React 组件库。基于 Radix UI 无头原语 + SCSS 拟物质感 + CSS 自定义属性构建。运行时主题切换无 FOUC,完整 TypeScript 类型支持,SSR 安全。 > **分发模式**:shadcn/ui 风格原子化 CLI 源码分发。组件以源码形式复制到你的项目中 — 完全可定制,无黑盒 dist 产物。 ### ✨ 特性 - **运行时多主题** — 6 种纸主题通过 `data-theme` + CSS 变量切换,无需重新加载 - **瓦楞质感切换** — `data-corrugated` 控制瓦楞波纹纹理显隐 - **5 种边缘模式** — 整齐 / 手撕 / 剪刀 / 粗撕 / 自然锯齿 - **65 个组件** — 全量覆盖:原语、表单、布局、导航、反馈、数据展示、纸风格装饰 - **Radix 无头 + SCSS 拟物** — 交互逻辑由 Radix UI 负责,视觉质感由 SCSS 叠上纸皮纹理 - **TypeScript 友好** — 全组件 `forwardRef` + `displayName` + 完整类型导出 - **源码级分发** — 非传统 npm 包,组件源码直接存在于你的 `src/` 目录,随时可修改 --- ### 📦 快速开始(CLI) ```bash # 1. 在 React 项目中初始化 paperboard npx react-paperboard-ui init # 2. 按需添加组件 npx react-paperboard-ui add Button npx react-paperboard-ui add Card npx react-paperboard-ui add Select # 3. 导入使用 ``` ```tsx import { Button } from '@/components/paperboard-ui/Button'; import { Card } from '@/components/paperboard-ui/Card'; ``` > **原理**:`init` 复制共享依赖(ThemeProvider、tokens、edge hooks)。`add <组件名>` 自动解析组件依赖树、复制源码到项目中、安装所需 npm peer 依赖。所有代码归你所有,自由修改。 > > **路径别名说明**:导入路径 `@/components/paperboard-ui/` 取决于你的 `tsconfig.json` 路径别名配置。请确保 `compilerOptions.paths` 中已配置 `@/*` → `./src/*`(或等效映射)。 --- ### 🚀 使用示例 --- ### 🎨 主题系统 6 套内置纸主题,运行时通过 `data-theme` 切换: | 主题 | `data-theme` | 说明 | |------|-------------|------| | 牛皮纸 | `kraft` | 默认,标准纸板棕色 | | 白纸板 | `white` | 暖白色调 | | 黑纸板 | `dark` | 真暗色模式 | | 宣纸 | `rice` | 米白偏冷 | | 羊皮纸 | `parchment` | 黄色仿旧 | | 信纸 | `letter` | 浅米色 | #### ThemeProvider ```tsx ``` | Prop | 类型 | 默认值 | 说明 | |------|------|--------|------| | `theme` | `PaperTheme` | `'kraft'` | 纸主题标识 | | `corrugated` | `boolean` | `false` | 瓦楞纹理开关 | | `defaultEdgeMode` | `EdgeMode` | `'clean'` | 默认边缘模式 | | `container` | `HTMLElement` | `document.documentElement` | `data-*` 属性注入目标 | | `tokens` | `Partial` | — | CSS 变量覆盖 | > **自动暗色模式**:未显式设置 `theme` 且系统偏好暗色时,自动切换到 `dark` 主题。手动调用 `setTheme()` 后不再跟随系统。 #### useTheme Hook ```tsx import { useTheme } from '@/theme'; function ThemeSwitcher() { const { theme, setTheme, corrugated, setCorrugated } = useTheme(); return ( <> ); } ``` #### CSS 变量命名 ``` --pb-paper-base / light / dark / cream / darker --pb-flute / flute-dark --pb-tape --pb-accent / accent-hover / accent-deep --pb-ink / ink-faded --pb-success / warning / error / info(+ -deep 变体) --pb-white / black / border-color / cardboard ``` --- ### ✂️ 边缘模式 5 种边缘模式,基于 seeded PRNG(`mulberry32`)生成稳定的 `clip-path`: | 模式 | 标识 | 说明 | |------|------|------| | 整齐 | `clean` | 规则矩形边缘 | | 手撕 | `torn` | 手撕纸边,中等抖动 | | 剪刀 | `scissor` | 剪刀剪裁,直线段带轻微偏移 | | 粗撕 | `rough` | 粗暴撕裂,大抖动 | | 锯齿 | `zigzag` | 自然锯齿纹路 | ```tsx 手撕边缘 剪刀边缘 粗撕卡片 ``` `seed` 属性控制 PRNG 输出,相同 seed 始终产生相同边缘形状,SSR 安全。 --- ### 📋 组件列表(65 个) #### 原语 | 组件 | 说明 | 关键 Props | |------|------|-----------| | **Surface** | 纸面基础原语 | `variant`, `edgeMode`, `corrugated`, `seed` | #### 基础 | 组件 | 说明 | 关键 Props | |------|------|-----------| | **Button** | 纸风格按钮 | `size`, `variant`, `icon`, `loading`, `block`, `asChild` | | **Input** | 文本输入框 | `inputSize`, `error`, `label`, `prefix`, `suffix` | | **Tag** | 行内标签 | `variant`, `size`, `removable` | | **Chip** | 可选/可删除芯片 | `variant`, `size`, `selected`, `selectable`, `removable` | #### 表单 | 组件 | 说明 | 关键 Props | |------|------|-----------| | **Checkbox** | 纸风格复选框 | `checked`, `disabled`, `label` | | **Radio** | 单选按钮 | `value`, `checked`, `disabled` | | **Switch** | 开关切换 | `checked`, `disabled`, `label` | | **Select** | 下拉选择器(多选/搜索) | `value`, `multiple`, `options`, `searchable` | | **Slider** | 滑块 | `min`, `max`, `step`, `value` | | **Form** | 表单字段包裹器 | `label`, `required`, `error` | #### 布局 | 组件 | 说明 | 关键 Props | |------|------|-----------| | **Card** | 纸卡片容器(含子组件) | `variant`, `size`, `edgeMode` | | **Panel** | 可折叠面板 | `title`, `defaultOpen` | | **Divider** | 分割线 | `orientation`, `variant`, `label` | | **Descriptions** | 键值对描述列表 | `items`, `column`, `bordered` | #### 导航 | 组件 | 说明 | 关键 Props | |------|------|-----------| | **Tabs** | 标签页导航(Radix) | `Tabs.List`, `Tabs.Trigger`, `Tabs.Content` | | **Breadcrumb** | 面包屑 | `separator`, `Breadcrumb.Item` | | **Pagination** | 分页 | `current`, `total`, `pageSize`, `onChange` | | **Menu** | 垂直/水平菜单 | `items`, `selectedKey`, `onSelect` | | **Steps** | 步骤条 | `Steps.Step` (`title`, `description`) | | **Segmented** | 分段控制器 | `options`, `value`, `onChange` | #### 反馈 | 组件 | 说明 | 关键 Props | |------|------|-----------| | **Tooltip** | 悬浮提示(Radix) | `content`, `side`, `delayDuration` | | **Popover** | 浮层弹出(Radix) | `open`, `defaultOpen` | | **Dropdown** | 下拉菜单(Radix) | `Dropdown.Item`, `Dropdown.Trigger` | | **Progress** | 进度条 | `value`, `max`, `indicatorColor` | | **Skeleton** | 骨架屏 | `width`, `height`, `variant` | | **Spinner** | 加载旋转 | `size`, `color` | | **Alert** | 警告提示 | `variant`, `title`, `edgeMode` | | **Badge** | 状态徽标/计数 | `variant`, `size`, `dot`, `count` | | **Toast** | 轻提示(Radix) | `Toast.Provider`, `Toast.Viewport`, `useToast()` | | **Message** | 行内消息 | `children`, `defaultDuration` | | **Notification** | 通知堆叠 | `children`, `defaultDuration` | | **EmptyState** | 空数据占位 | `icon`, `title`, `description` | | **Result** | 结果页 | `status`, `icon`, `title`, `subTitle` | #### 数据展示 | 组件 | 说明 | 关键 Props | |------|------|-----------| | **Avatar** | 用户头像 | `src`, `alt`, `size`, `shape`, `fallback` | | **Table** | 数据表格(含子组件) | `bordered`, `striped`, `stickyHeader` | | **List** | 数据列表 | `items`, `bordered`, `size` | | **Statistic** | 统计数值 | `title`, `value`, `prefix`, `suffix` | | **Accordion** | 折叠手风琴 | `title`, `defaultOpen` | #### 弹层 | 组件 | 说明 | 关键 Props | |------|------|-----------| | **Drawer** | 侧边抽屉 | `open`, `onOpenChange`, `title`, `side` | | **Modal** | 模态弹窗 | `open`, `onOpenChange`, `title`, `description` | #### 纸风格装饰(25 个) | 组件 | 说明 | 关键 Props | |------|------|-----------| | **Stamp** | 橡胶印章 | `color`, `variant`, `edgeMode`, `rotate` | | **WaxSeal** | 蜡封印章 | `color`, `size`, `rotate`, `seal` | | **Tape** | 胶带 | `position`, `color`, `edgeMode` | | **Ribbon** | 装饰缎带 | `color`, `position` | | **Envelope** | 信封(可翻开) | `sender`, `recipient` | | **StickyNote** | 便利贴 | `color`, `rotate`, `as` | | **PaperStack** | 纸层堆叠(可拖拽排序) | `layers`, `offset`, `sortable` | | **Timeline** | 垂直时间线 | `items`, `mode` | | **BulletinBoard** | 公告板 | `title`, `backgroundColor` | | **CarbonCopy** | 复写纸 | `copies`, `defaultValue` | | **ClippingBoard** | 剪报板 | `clips` | | **DeskMat** | 桌垫(网格/标尺) | `gridSize`, `showRuler` | | **FileFolder** | 文件夹标签 | `title`, `files`, `expanded` | | **JournalPage** | 日记页面 | `date`, `title` | | **LetterSet** | 完整信件套装 | `sender`, `recipient`, `content` | | **NotePad** | 记事本(可撕页) | `pages`, `currentPage`, `onTear` | | **PageTurn** | 翻页动画 | `front`, `back`, `open` | | **PaperClip** | 回形针装饰 | `position`, `color`, `size` | | **PaperConfetti** | 纸屑飞溅 | `count`, `active` | | **PaperCut** | 剪纸分层揭示 | `revealed`, `layers` | | **PaperPlane** | 飞翔纸飞机 | `flying`, `onComplete` | | **PushPin** | 图钉装饰 | `position`, `color`, `size` | | **StickyWall** | 便签墙 | `notes`, `backgroundColor` | | **WritingPaper** | 横线信纸 | `lineType`, `lineColor` | --- ### 🔧 本地开发 ```bash git clone https://gitee.com/wangkai000/react-paperboard-ui.git cd react-paperboard-ui npm install npm run dev # 启动 demo 站(Vite) npm run build # 构建 CLI 工具(tsup,输出到 dist/cli/) npm run test # 运行测试(Vitest) npm run storybook # 启动 Storybook(端口 6006) npm run type-check # TypeScript 类型检查 npm run lint # ESLint 检查 ``` --- ### 🛠️ 技术栈 | 类别 | 技术 | |------|------| | 框架 | React 18 / 19 | | 无头交互 | Radix UI(12 个包) | | 样式 | SCSS Modules + CSS 自定义属性 | | 图标 | lucide-react | | 打包 | Vite(库模式) | | 类型 | TypeScript ~5.6 | | 测试 | Vitest + React Testing Library | | 文档 | Storybook 8 | | 拖拽 | @dnd-kit/core + @dnd-kit/sortable | --- ### 📄 License MIT © [wangkai000](https://gitee.com/wangkai000) 仓库地址:[https://gitee.com/wangkai000/react-paperboard-ui](https://gitee.com/wangkai000/react-paperboard-ui)