@leejungkiin/awkit 1.7.1 → 1.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/awk.js +576 -84
- package/core/CLAUDE.md +1 -1
- package/core/GEMINI.md +148 -167
- package/core/GEMINI.md.bak +149 -116
- package/core/skill-runtime-manifest.json +3 -0
- package/docs/Claude Fable 5.md +3826 -0
- package/docs/android_kotlin_system_instruction.md +210 -0
- package/docs/brainstorm_ponytail_integration.md +146 -0
- package/docs/brainstorm_smart_setup.md +113 -0
- package/docs/deep-research-report (1).md +293 -0
- package/docs/history/GEMINI.v1.md +135 -0
- package/docs/history/brainstorm_antigravity_unified_architecture.v1.md +105 -0
- package/docs/history/implementation_plan.v1.md +58 -0
- package/package.json +4 -1
- package/scripts/artifact-storage.js +130 -0
- package/scripts/automation-gate.js +35 -2
- package/scripts/claude-plan.js +76 -0
- package/scripts/dependency-manager.js +210 -0
- package/scripts/exec-rtk.js +11 -5
- package/scripts/i18n-helper.js +381 -0
- package/scripts/multi-model-pipeline.js +144 -0
- package/skill-packs/mobile-ios/pack.json +4 -2
- package/skill-packs/reverse-engineering/pack.json +1 -0
- package/skills/CATALOG.md +20 -0
- package/skills/GEMINI.md +9 -1
- package/skills/TRIGGER_INDEX.md +10 -0
- package/skills/ai-music/SKILL.md +275 -0
- package/skills/android-re-analyzer/SKILL.md +238 -0
- package/skills/android-re-analyzer/references/api-extraction-patterns.md +119 -0
- package/skills/android-re-analyzer/references/call-flow-analysis.md +176 -0
- package/skills/android-re-analyzer/references/fernflower-usage.md +115 -0
- package/skills/android-re-analyzer/references/jadx-usage.md +116 -0
- package/skills/android-re-analyzer/references/setup-guide.md +221 -0
- package/skills/android-re-analyzer/scripts/check-deps.sh +129 -0
- package/skills/android-re-analyzer/scripts/decompile.sh +375 -0
- package/skills/android-re-analyzer/scripts/find-api-calls.sh +118 -0
- package/skills/android-re-analyzer/scripts/install-dep.sh +448 -0
- package/skills/animal-island-ui-style/SKILL.md +1450 -0
- package/skills/app-store-review-agent/SKILL.md +164 -0
- package/skills/app-store-review-agent/references/guidelines/README.md +154 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/ai_apps.md +37 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/all_apps.md +50 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/crypto_finance.md +31 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/games.md +31 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/health_fitness.md +31 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/kids.md +27 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/macos.md +38 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/social_ugc.md +32 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/subscription_iap.md +34 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/vpn.md +18 -0
- package/skills/app-store-review-agent/references/rules/design/minimum_functionality.md +96 -0
- package/skills/app-store-review-agent/references/rules/design/sign_in_with_apple.md +54 -0
- package/skills/app-store-review-agent/references/rules/entitlements/unused_entitlements.md +83 -0
- package/skills/app-store-review-agent/references/rules/metadata/accurate_metadata.md +54 -0
- package/skills/app-store-review-agent/references/rules/metadata/apple_trademark.md +99 -0
- package/skills/app-store-review-agent/references/rules/metadata/china_storefront.md +72 -0
- package/skills/app-store-review-agent/references/rules/metadata/competitor_terms.md +56 -0
- package/skills/app-store-review-agent/references/rules/metadata/subscription_metadata.md +81 -0
- package/skills/app-store-review-agent/references/rules/privacy/privacy_manifest.md +84 -0
- package/skills/app-store-review-agent/references/rules/privacy/unnecessary_data.md +60 -0
- package/skills/app-store-review-agent/references/rules/subscription/misleading_pricing.md +63 -0
- package/skills/app-store-review-agent/references/rules/subscription/missing_tos_pp.md +54 -0
- package/skills/awf-ponytail/SKILL.md +91 -0
- package/skills/awf-ponytail-review/SKILL.md +67 -0
- package/skills/awf-session-restore/SKILL.md +3 -3
- package/skills/brainstorm-agent/SKILL.md +11 -2
- package/skills/brainstorm-agent/templates/brief-template.md +8 -0
- package/skills/claude-planner/SKILL.md +47 -0
- package/skills/code-review/SKILL.md +87 -0
- package/skills/expo-game-development/SKILL.md +163 -0
- package/skills/flutter/LICENSE.txt +202 -0
- package/skills/flutter/SKILL.md +127 -0
- package/skills/flutter-project-creater/LICENSE.txt +202 -0
- package/skills/flutter-project-creater/SKILL.md +106 -0
- package/skills/game-developer/SKILL.md +163 -0
- package/skills/game-developer/references/ecs-patterns.md +501 -0
- package/skills/game-developer/references/multiplayer-networking.md +475 -0
- package/skills/game-developer/references/performance-optimization.md +422 -0
- package/skills/game-developer/references/unity-patterns.md +271 -0
- package/skills/game-developer/references/unreal-cpp.md +352 -0
- package/skills/generate-gui-assets/SKILL.md +305 -0
- package/skills/generate-gui-assets/agents/openai.yaml +4 -0
- package/skills/generate-gui-assets/references/catalog-schema.md +58 -0
- package/skills/generate-gui-assets/references/extraction-techniques.md +21 -0
- package/skills/generate-gui-assets/references/prompt-patterns.md +58 -0
- package/skills/generate-gui-assets/scripts/__pycache__/clean_chroma_edges.cpython-311.pyc +0 -0
- package/skills/generate-gui-assets/scripts/build_gui_contact_sheet.py +51 -0
- package/skills/generate-gui-assets/scripts/clean_chroma_edges.py +262 -0
- package/skills/generate-gui-assets/scripts/copy_approved_icons.py +64 -0
- package/skills/generate-gui-assets/scripts/prepare_gui_asset_run.py +91 -0
- package/skills/generate-gui-assets/scripts/suggest_grid_options.py +63 -0
- package/skills/generate-gui-assets/scripts/validate_gui_catalog.py +50 -0
- package/skills/godot-game-development/SKILL.md +142 -0
- package/skills/hatch-pet/LICENSE.txt +201 -0
- package/skills/hatch-pet/SKILL.md +420 -0
- package/skills/hatch-pet/agents/openai.yaml +4 -0
- package/skills/hatch-pet/references/animation-rows.md +29 -0
- package/skills/hatch-pet/references/codex-pet-contract.md +35 -0
- package/skills/hatch-pet/references/qa-rubric.md +60 -0
- package/skills/hatch-pet/scripts/__pycache__/clean_chroma_edges.cpython-311.pyc +0 -0
- package/skills/hatch-pet/scripts/clean_chroma_edges.py +262 -0
- package/skills/hatch-pet/scripts/compose_atlas.py +150 -0
- package/skills/hatch-pet/scripts/derive_running_left_from_running_right.py +143 -0
- package/skills/hatch-pet/scripts/extract_strip_frames.py +323 -0
- package/skills/hatch-pet/scripts/finalize_pet_run.py +382 -0
- package/skills/hatch-pet/scripts/generate_pet_images.py +287 -0
- package/skills/hatch-pet/scripts/inspect_frames.py +246 -0
- package/skills/hatch-pet/scripts/make_contact_sheet.py +96 -0
- package/skills/hatch-pet/scripts/package_custom_pet.py +108 -0
- package/skills/hatch-pet/scripts/pet_job_status.py +117 -0
- package/skills/hatch-pet/scripts/prepare_pet_run.py +673 -0
- package/skills/hatch-pet/scripts/queue_pet_repairs.py +172 -0
- package/skills/hatch-pet/scripts/record_imagegen_result.py +250 -0
- package/skills/hatch-pet/scripts/render_animation_videos.py +134 -0
- package/skills/hatch-pet/scripts/render_animation_videos.sh +5 -0
- package/skills/hatch-pet/scripts/validate_atlas.py +139 -0
- package/skills/i18n-orchestrator/SKILL.md +37 -0
- package/skills/ios-simulator-skill/SKILL.md +390 -0
- package/skills/ios-simulator-skill/scripts/accessibility_audit.py +300 -0
- package/skills/ios-simulator-skill/scripts/app_launcher.py +326 -0
- package/skills/ios-simulator-skill/scripts/app_state_capture.py +400 -0
- package/skills/ios-simulator-skill/scripts/appearance.py +385 -0
- package/skills/ios-simulator-skill/scripts/build_and_test.py +348 -0
- package/skills/ios-simulator-skill/scripts/clipboard.py +103 -0
- package/skills/ios-simulator-skill/scripts/common/__init__.py +61 -0
- package/skills/ios-simulator-skill/scripts/common/cache_utils.py +289 -0
- package/skills/ios-simulator-skill/scripts/common/device_utils.py +462 -0
- package/skills/ios-simulator-skill/scripts/common/env_config.py +35 -0
- package/skills/ios-simulator-skill/scripts/common/hang_pipeline.py +862 -0
- package/skills/ios-simulator-skill/scripts/common/hang_sessions.py +490 -0
- package/skills/ios-simulator-skill/scripts/common/idb_utils.py +180 -0
- package/skills/ios-simulator-skill/scripts/common/screenshot_utils.py +338 -0
- package/skills/ios-simulator-skill/scripts/container.py +668 -0
- package/skills/ios-simulator-skill/scripts/gesture.py +394 -0
- package/skills/ios-simulator-skill/scripts/hang_watcher.py +1533 -0
- package/skills/ios-simulator-skill/scripts/keyboard.py +391 -0
- package/skills/ios-simulator-skill/scripts/localization_audit.py +483 -0
- package/skills/ios-simulator-skill/scripts/location.py +467 -0
- package/skills/ios-simulator-skill/scripts/log_monitor.py +493 -0
- package/skills/ios-simulator-skill/scripts/model_inspector.py +645 -0
- package/skills/ios-simulator-skill/scripts/navigator.py +461 -0
- package/skills/ios-simulator-skill/scripts/privacy_manager.py +310 -0
- package/skills/ios-simulator-skill/scripts/push_notification.py +240 -0
- package/skills/ios-simulator-skill/scripts/screen_mapper.py +296 -0
- package/skills/ios-simulator-skill/scripts/sim_health_check.sh +245 -0
- package/skills/ios-simulator-skill/scripts/sim_list.py +299 -0
- package/skills/ios-simulator-skill/scripts/simctl_boot.py +312 -0
- package/skills/ios-simulator-skill/scripts/simctl_create.py +316 -0
- package/skills/ios-simulator-skill/scripts/simctl_delete.py +357 -0
- package/skills/ios-simulator-skill/scripts/simctl_erase.py +351 -0
- package/skills/ios-simulator-skill/scripts/simctl_shutdown.py +290 -0
- package/skills/ios-simulator-skill/scripts/simulator_selector.py +375 -0
- package/skills/ios-simulator-skill/scripts/status_bar.py +250 -0
- package/skills/ios-simulator-skill/scripts/test_recorder.py +323 -0
- package/skills/ios-simulator-skill/scripts/visual_diff.py +235 -0
- package/skills/ios-simulator-skill/scripts/xcode/__init__.py +13 -0
- package/skills/ios-simulator-skill/scripts/xcode/builder.py +397 -0
- package/skills/ios-simulator-skill/scripts/xcode/cache.py +204 -0
- package/skills/ios-simulator-skill/scripts/xcode/config.py +178 -0
- package/skills/ios-simulator-skill/scripts/xcode/reporter.py +343 -0
- package/skills/ios-simulator-skill/scripts/xcode/xcresult.py +451 -0
- package/skills/ios-visual-qa-strategist/SKILL.md +111 -0
- package/skills/ios-visual-qa-strategist/agents/openai.yaml +4 -0
- package/skills/ios-visual-qa-strategist/references/ios-tool-selection.md +61 -0
- package/skills/ios-visual-qa-strategist/references/minimal-capture-policy.md +56 -0
- package/skills/ios-visual-qa-strategist/references/visual-reasoning-heuristics.md +53 -0
- package/skills/orchestrator/SKILL.md +0 -20
- package/skills/persistent-storage/SKILL.md +55 -0
- package/skills/short-maker/SKILL.md +23 -0
- package/skills/short-maker/scripts/effects.js +56 -0
- package/skills/short-maker/scripts/shortmaker-bridge.js +332 -0
- package/skills/short-maker/scripts/videomix.js +601 -0
- package/skills/short-maker/templates/hyperframes/cinematic-character.template.html +172 -0
- package/skills/short-maker/templates/hyperframes/index.template.html +194 -0
- package/skills/smali-to-kotlin/SKILL.md +128 -0
- package/skills/smali-to-kotlin/examples/getting-started/tech-stack.md +58 -0
- package/skills/smali-to-kotlin/examples/pipeline/data-ui-parity.md +118 -0
- package/skills/smali-to-kotlin/examples/pipeline/scanner-and-bootstrap.md +106 -0
- package/skills/smali-to-kotlin/library-patterns.md +189 -0
- package/skills/smali-to-kotlin/phase-0-discovery.md +128 -0
- package/skills/smali-to-kotlin/phase-1-architecture.md +166 -0
- package/skills/smali-to-kotlin/phase-2-blueprint-ui.md +347 -0
- package/skills/smali-to-kotlin/phase-2-blueprint.md +228 -0
- package/skills/smali-to-kotlin/phase-3-build.md +248 -0
- package/skills/smali-to-kotlin/phase-3-logic-build.md +268 -0
- package/skills/smali-to-kotlin/smali-reading-guide.md +310 -0
- package/skills/smali-to-kotlin/templates/app-map.md +101 -0
- package/skills/smali-to-kotlin/templates/architecture.md +142 -0
- package/skills/smali-to-kotlin/templates/blueprint.md +145 -0
- package/skills/spec-gate/SKILL.md +6 -2
- package/skills/symphony-enforcer/SKILL.md +8 -0
- package/skills/symphony-enforcer/examples/mindful-stop.md +2 -0
- package/skills/symphony-enforcer/examples/three-phase.md +16 -0
- package/skills/symphony-enforcer/examples/trigger-points.md +7 -1
- package/skills/unity-game-development/SKILL.md +231 -0
- package/skills/video-edit/SKILL.md +36 -0
- package/skills/video-edit/scripts/video_edit.py +324 -0
- package/templates/project-identity/android.json +2 -2
- package/templates/project-identity/backend-nestjs.json +2 -2
- package/templates/project-identity/expo.json +2 -2
- package/templates/project-identity/ios.json +2 -2
- package/templates/project-identity/web-nextjs.json +2 -2
- package/templates/setup-mapping.json +48 -0
- package/templates/specs/design-template.md +161 -71
- package/templates/specs/requirements-template.md +65 -133
- package/templates/specs/task-spec-template.xml +3 -0
- package/workflows/_uncategorized/critic.md +40 -0
- package/workflows/_uncategorized/git-rebase-flow.md +81 -0
- package/workflows/_uncategorized/image-gen.md +118 -0
- package/workflows/_uncategorized/multi-model-pipeline.md +60 -0
- package/workflows/_uncategorized/pixel-gen.md +86 -0
- package/workflows/_uncategorized/pixel-setup.md +90 -0
- package/workflows/_uncategorized/ponytail-review.md +59 -0
- package/workflows/_uncategorized/reverse-android-build.md +222 -0
- package/workflows/_uncategorized/reverse-android-design.md +139 -0
- package/workflows/_uncategorized/reverse-android-discover.md +150 -0
- package/workflows/_uncategorized/reverse-android-scan.md +158 -0
- package/workflows/_uncategorized/reverse-android.md +143 -0
- package/workflows/_uncategorized/reverse-ios-build.md +240 -0
- package/workflows/_uncategorized/reverse-ios-design.md +112 -0
- package/workflows/_uncategorized/reverse-ios-discover.md +120 -0
- package/workflows/_uncategorized/reverse-ios-scan.md +155 -0
- package/workflows/_uncategorized/reverse-ios.md +152 -0
- package/workflows/_uncategorized/safety-router.md +34 -0
- package/workflows/_uncategorized/teach.md +89 -0
- package/workflows/_uncategorized/verify-ui.md +53 -0
- package/workflows/_uncategorized/visualize-screenshots.md +34 -0
- package/workflows/ads/ads-analyst.md +201 -0
- package/workflows/ads/ads-audit.md +106 -0
- package/workflows/ads/ads-optimize.md +97 -0
- package/workflows/ads/ads-targeting.md +241 -0
- package/workflows/ads/adsExpert.md +160 -0
- package/workflows/ads/smali-ads-config.md +400 -0
- package/workflows/ads/smali-ads-flow.md +331 -0
- package/workflows/ads/smali-ads-interstitial.md +377 -0
- package/workflows/ads/smali-ads-native.md +382 -0
- package/workflows/context/teach.md +89 -0
- package/workflows/gitnexus.md +8 -8
- package/workflows/lifecycle/brainstorm.md +43 -0
- package/workflows/lifecycle/code.md +5 -0
- package/workflows/lifecycle/init.md +23 -5
- package/workflows/lifecycle/multi-model-pipeline.md +60 -0
- package/workflows/quality/ponytail-review.md +59 -0
- package/workflows/roles/critic.md +40 -0
- package/workflows/roles/safety-router.md +34 -0
|
@@ -0,0 +1,1450 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: animal-island-ui-style
|
|
3
|
+
description: >
|
|
4
|
+
使用 animal-island-ui 设计风格创建 React UI 界面或组件。当用户需要:
|
|
5
|
+
(1) 用动物森友会风格创建 UI 页面或组件;
|
|
6
|
+
(2) 使用 animal-island-ui 组件库开发界面;
|
|
7
|
+
(3) 构建温馨自然、圆润可爱风格的 React 界面;
|
|
8
|
+
(4) 复现或扩展 animal-island-ui 的视觉语言;
|
|
9
|
+
(5) 提问"动物森友会风格"、"animal island 风格"、"可爱圆润风格"的 UI 时,务必使用此 skill。
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Animal Island UI 设计风格指南
|
|
13
|
+
|
|
14
|
+
> **三文档分工**(生成代码 / 调样式时按需查阅,避免互相翻查):
|
|
15
|
+
> - `AI_USAGE.md` — API 手册:每个组件的 props、类型、默认值、合法取值、禁用用法。**写代码优先查这里**。
|
|
16
|
+
> - `skill/SKILL.md`(本文档)— 像素级样式:设计 token、每组件精确 CSS(hex/px/keyframe)、Demo 布局、新组件开发模板。**要自己实现/扩展样式时查这里**。
|
|
17
|
+
> - `DESIGN_PROMPT.md` — 给外部工具(v0 / Figma AI / Midjourney / DALL-E)的提示词包,含 clip-path、色板速查、禁用清单。**只在喂别的 AI 时用**。
|
|
18
|
+
|
|
19
|
+
## 概述
|
|
20
|
+
|
|
21
|
+
animal-island-ui 是一套受《集合啦!动物森友会》启发的 React + TypeScript UI 组件库。
|
|
22
|
+
设计语言核心:**温暖大地色系 + 大圆角 pill 形 + 游戏按键立体感 + 柔和动效 + 有机不规则形状**。
|
|
23
|
+
|
|
24
|
+
- 源码:`src/components/<ComponentName>/`
|
|
25
|
+
- Demo 站:`demo/`
|
|
26
|
+
- 构建:Vite (library mode) + `vite.config.ts`(库)/ `vite.config.demo.ts`(Demo)
|
|
27
|
+
- 样式系统:Less Modules + `src/styles/variables.less` 设计 token
|
|
28
|
+
|
|
29
|
+
### 全量组件清单(17 个)
|
|
30
|
+
|
|
31
|
+
从 `src/index.ts` 导出:
|
|
32
|
+
|
|
33
|
+
| 组件 | 职责 | 交互 | 装饰 / 纯展示 |
|
|
34
|
+
|---|---|---|---|
|
|
35
|
+
| `Button` | 按钮,5 种类型 × 3 种尺寸 | ✓ | |
|
|
36
|
+
| `Input` | 输入框,3 种尺寸 + clear/prefix/suffix | ✓ | |
|
|
37
|
+
| `Switch` | 开关,默认/小号 | ✓ | |
|
|
38
|
+
| `Modal` | SVG blob 裁切弹窗 | ✓ | |
|
|
39
|
+
| `Card` | 容器,`default`/`title`,13 种 NookPhone 配色 | | ✓ |
|
|
40
|
+
| `Collapse` | 手风琴(CSS Grid,无 JS 过渡) | ✓ | |
|
|
41
|
+
| `Select` | 下拉选择器(受控) | ✓ | |
|
|
42
|
+
| `Checkbox` | 多选框组,水平/垂直,3 种尺寸 | ✓ | |
|
|
43
|
+
| `Icon` | SVG 图标库(10 个) | | ✓ |
|
|
44
|
+
| `Time` | HUD 实时时钟 | | ✓ |
|
|
45
|
+
| `Phone` | NookPhone 3×3 应用网格 | | ✓ |
|
|
46
|
+
| `Footer` | 底部装饰图(`sea`/`tree`) | | ✓ |
|
|
47
|
+
| `Divider` | 装饰分割线,5 种风格 | | ✓ |
|
|
48
|
+
| `Cursor` | 游戏手指光标包裹器 | | ✓ |
|
|
49
|
+
| `Typewriter` | 打字机效果,保留 ReactNode 结构 | | ✓ |
|
|
50
|
+
| `Tabs` | 标签页切换,叶子摆动动画可选 | ✓ | |
|
|
51
|
+
| `CodeBlock` | JSX/TS 语法高亮代码块 | | ✓ |
|
|
52
|
+
|
|
53
|
+
类型导出:`ButtonProps/ButtonType/ButtonSize`、`InputProps/InputSize`、`SwitchProps/SwitchSize`、`ModalProps`、`CardProps/CardType/CardColor`、`FooterProps/FooterType`、`CollapseProps`、`CursorProps`、`TimeProps`、`PhoneProps`、`DividerProps`、`TypewriterProps`、`SelectProps/SelectOption`、`IconProps/IconName`、`TabsProps/TabItem`、`CheckboxProps/CheckboxOption/CheckboxSize`、`CodeBlockProps`。运行时值:`ICON_LIST`。
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 1. Design Tokens
|
|
58
|
+
|
|
59
|
+
### 色彩系统
|
|
60
|
+
|
|
61
|
+
```less
|
|
62
|
+
// 主色(薄荷青绿)
|
|
63
|
+
@primary-color: #19c8b9;
|
|
64
|
+
@primary-color-hover: #3dd4c6;
|
|
65
|
+
@primary-color-active: #11a89b;
|
|
66
|
+
@primary-color-bg: #e6f9f6;
|
|
67
|
+
|
|
68
|
+
// 文字(温暖棕色系)
|
|
69
|
+
@text-color: #794f27; // 主文字(header/sidebar)
|
|
70
|
+
@text-color-body: #725d42; // 正文(组件内文字)
|
|
71
|
+
@text-color-secondary: #9f927d; // 次级文字
|
|
72
|
+
@text-color-muted: #8a7b66; // 浅棕(modal body)
|
|
73
|
+
@text-color-disabled: #c4b89e; // 禁用
|
|
74
|
+
|
|
75
|
+
// 边框
|
|
76
|
+
@border-color: #9f927d;
|
|
77
|
+
@border-color-light: #c4b89e; // 输入框边框
|
|
78
|
+
@border-color-hover: #a89878; // 输入框 hover
|
|
79
|
+
|
|
80
|
+
// 背景(奶油米白)
|
|
81
|
+
@bg-color: #f8f8f0; // 主背景
|
|
82
|
+
@bg-color-content: rgb(247, 243, 223); // 内容区(Modal、Card)
|
|
83
|
+
@bg-color-secondary: #f0e8d8;
|
|
84
|
+
@bg-color-disabled: #f0ece2;
|
|
85
|
+
@bg-color-input: rgb(247, 243, 223); // 输入框背景
|
|
86
|
+
@bg-color-input-dis: #ece8dc; // 输入框禁用
|
|
87
|
+
|
|
88
|
+
// 状态色
|
|
89
|
+
@success-color: #6fba2c;
|
|
90
|
+
@success-color-active: #5a9e1e;
|
|
91
|
+
@warning-color: #f5c31c;
|
|
92
|
+
@warning-color-active: #dba90e;
|
|
93
|
+
@error-color: #e05a5a;
|
|
94
|
+
@error-color-active: #c94444;
|
|
95
|
+
|
|
96
|
+
// 游戏特殊色
|
|
97
|
+
@focus-yellow: #ffcc00; // 焦点高亮(非蓝色)
|
|
98
|
+
@focus-yellow-dark: #e0b800; // 焦点阴影
|
|
99
|
+
@sidebar-active-bg: #B7C6E5; // 侧边栏选中背景
|
|
100
|
+
@sidebar-hover-bg: #d6dff0; // 侧边栏 hover 背景
|
|
101
|
+
|
|
102
|
+
// 3D 阴影色
|
|
103
|
+
@shadow-btn: #bdaea0; // 按钮 3D 阴影
|
|
104
|
+
@shadow-input: #d4c9b4; // 输入框 3D 阴影
|
|
105
|
+
@shadow-switch-on: #5a9e1e; // Switch 开启 3D 阴影
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**NookPhone 应用调色板**(Card `color` prop 可选值):
|
|
109
|
+
|
|
110
|
+
| color 值 | 背景色 | 文字色 |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| default | `rgb(247, 243, 223)` | `#725d42` |
|
|
113
|
+
| app-pink | `#f8a6b2` | `#fff` |
|
|
114
|
+
| purple | `#b77dee` | `#fff` |
|
|
115
|
+
| app-blue | `#889df0` | `#fff` |
|
|
116
|
+
| app-yellow | `#f7cd67` | `#725d42` |
|
|
117
|
+
| app-orange | `#e59266` | `#fff` |
|
|
118
|
+
| app-teal | `#82d5bb` | `#fff` |
|
|
119
|
+
| app-green | `#8ac68a` | `#fff` |
|
|
120
|
+
| app-red | `#fc736d` | `#fff` |
|
|
121
|
+
| lime-green | `#d1da49` | `#3d5a1a` |
|
|
122
|
+
| yellow-green | `#ecdf52` | `#725d42` |
|
|
123
|
+
| brown | `#9a835a` | `#fff` |
|
|
124
|
+
| warm-peach-pink | `#e18c6f` | `#fff` |
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
### 字体
|
|
129
|
+
|
|
130
|
+
项目使用三款 Google Fonts 圆体字,**必须**按以下方式引入,本地未安装时通过在线地址加载:
|
|
131
|
+
|
|
132
|
+
```html
|
|
133
|
+
<!-- 在 index.html <head> 中引入 -->
|
|
134
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
135
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
136
|
+
<link
|
|
137
|
+
href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;500;600;700;800;900&family=Zen+Maru+Gothic:wght@400;500;700&family=M+PLUS+Rounded+1c:wght@400;500;700&display=swap"
|
|
138
|
+
rel="stylesheet"
|
|
139
|
+
/>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
或在 CSS / Less 入口文件顶部:
|
|
143
|
+
|
|
144
|
+
```css
|
|
145
|
+
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;500;600;700;800;900&family=Noto+Sans+SC:wght@400;500;700&family=Zen+Maru+Gothic:wght@400;500;700&display=swap');
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```css
|
|
149
|
+
font-family: Nunito, 'Noto Sans SC', 'Zen Maru Gothic',
|
|
150
|
+
-apple-system, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
| 字体 | 用途 | Google Fonts key |
|
|
154
|
+
|---|---|---|
|
|
155
|
+
| **Nunito** | 主字体,拉丁字符 | `family=Nunito` |
|
|
156
|
+
| **Noto Sans SC** | 中文字体,简体覆盖 | `family=Noto+Sans+SC` |
|
|
157
|
+
| **Zen Maru Gothic** | 日文字体 | `family=Zen+Maru+Gothic` |
|
|
158
|
+
|
|
159
|
+
字重分级:
|
|
160
|
+
- 正文内容:**500**
|
|
161
|
+
- 按钮文字、标题、菜单项:**600–700**
|
|
162
|
+
- 数字强调(时间数字、时钟):**900**
|
|
163
|
+
- placeholder / 说明文字:**400**
|
|
164
|
+
|
|
165
|
+
字间距:`letter-spacing: 0.01em`(正文)/ `0.02em`(按钮/标题)/ `1.5px`(星期大写)
|
|
166
|
+
|
|
167
|
+
禁止使用细体(weight < 400)或等宽字体。
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
### 间距 / 圆角 / 边框
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
间距:xs=4px sm=8px md=12px lg=16px xl=24px
|
|
175
|
+
圆角:sm=12px base=18px lg=24px pill=50px(按钮/输入框)
|
|
176
|
+
边框:默认 2px solid,输入框 2.5px,大尺寸输入框 3px
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
### 阴影
|
|
182
|
+
|
|
183
|
+
```css
|
|
184
|
+
/* 卡片/容器阴影(暖色调,非冷黑)*/
|
|
185
|
+
box-shadow: 0 3px 10px 0 rgba(61, 52, 40, 0.10); /* 基础 */
|
|
186
|
+
box-shadow: 0 8px 24px 0 rgba(61, 52, 40, 0.14); /* 较大 */
|
|
187
|
+
box-shadow: 0 4px 10px rgba(107, 92, 67, 0.42); /* Card */
|
|
188
|
+
|
|
189
|
+
/* 游戏按键立体阴影(最重要特征)*/
|
|
190
|
+
box-shadow: 0 5px 0 0 #bdaea0; /* 按钮默认 */
|
|
191
|
+
box-shadow: 0 6px 0 0 #bdaea0; /* 按钮 hover */
|
|
192
|
+
box-shadow: 0 1px 0 0 #bdaea0; /* 按钮 active */
|
|
193
|
+
box-shadow: 0 3px 0 0 #d4c9b4; /* 输入框 */
|
|
194
|
+
box-shadow: 0 2px 0 0 #d4c9b4; /* 小号输入框 */
|
|
195
|
+
box-shadow: 0 4px 0 0 #d4c9b4; /* 大号输入框 */
|
|
196
|
+
box-shadow: 0 3px 0 0 #5a9e1e; /* Switch 开启态 */
|
|
197
|
+
box-shadow: 0 2px 0 0 #5a9e1e; /* Switch 小号开启态 */
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
### 动效
|
|
203
|
+
|
|
204
|
+
```css
|
|
205
|
+
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); /* 通用 */
|
|
206
|
+
transition: all 0.15s; /* 快速(clear 按钮等)*/
|
|
207
|
+
transition: all 0.3s ease; /* 卡片 */
|
|
208
|
+
transition: grid-template-rows 0.3s cubic-bezier(0.4, 0, 0.2, 1); /* 手风琴 */
|
|
209
|
+
|
|
210
|
+
/* Hover:上浮 */
|
|
211
|
+
transform: translateY(-1px); /* 按钮 / 输入框 */
|
|
212
|
+
transform: translateY(-2px); /* Switch handle */
|
|
213
|
+
transform: translateY(-4px); /* 卡片 */
|
|
214
|
+
|
|
215
|
+
/* Active:下压(游戏按键反馈)*/
|
|
216
|
+
transform: translateY(2px); /* 按钮 active */
|
|
217
|
+
|
|
218
|
+
/* 出现动画 */
|
|
219
|
+
@keyframes animal-zoom-in {
|
|
220
|
+
from { opacity: 0; transform: scale(0.92); }
|
|
221
|
+
to { opacity: 1; transform: scale(1); }
|
|
222
|
+
}
|
|
223
|
+
@keyframes animal-fade-in {
|
|
224
|
+
from { opacity: 0; }
|
|
225
|
+
to { opacity: 1; }
|
|
226
|
+
}
|
|
227
|
+
@keyframes ac-fade-up {
|
|
228
|
+
from { opacity: 0; transform: translateY(8px); }
|
|
229
|
+
to { opacity: 1; transform: translateY(0); }
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## 2. 组件精确样式规范
|
|
236
|
+
|
|
237
|
+
### Button
|
|
238
|
+
|
|
239
|
+
| 属性 | small | middle | large |
|
|
240
|
+
|---|---|---|---|
|
|
241
|
+
| height | 32px | **45px** | 48px |
|
|
242
|
+
| padding | `0 16px` | `0 20px` | `0 32px` |
|
|
243
|
+
| font-size | 12px | 14px | 16px |
|
|
244
|
+
| border-radius | 12px | **50px** | 24px |
|
|
245
|
+
| border-width | 2px | 2px | 2px |
|
|
246
|
+
|
|
247
|
+
**primary 按钮精确值:**
|
|
248
|
+
```css
|
|
249
|
+
color: #794f27;
|
|
250
|
+
background: #f8f8f0;
|
|
251
|
+
border-color: #f8f8f0;
|
|
252
|
+
font-weight: 600;
|
|
253
|
+
letter-spacing: 0.02em;
|
|
254
|
+
line-height: 1;
|
|
255
|
+
box-shadow: 0 5px 0 0 #bdaea0;
|
|
256
|
+
|
|
257
|
+
/* hover */
|
|
258
|
+
transform: translateY(-1px);
|
|
259
|
+
box-shadow: 0 6px 0 0 #bdaea0;
|
|
260
|
+
|
|
261
|
+
/* active */
|
|
262
|
+
transform: translateY(2px);
|
|
263
|
+
box-shadow: 0 1px 0 0 #bdaea0;
|
|
264
|
+
|
|
265
|
+
/* focus-visible */
|
|
266
|
+
outline: 2px solid #19c8b9;
|
|
267
|
+
outline-offset: 2px;
|
|
268
|
+
|
|
269
|
+
/* disabled */
|
|
270
|
+
opacity: 0.5;
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**loading 斜纹动画(精确值):**
|
|
274
|
+
```css
|
|
275
|
+
background: #0ec4b6;
|
|
276
|
+
border: 4px solid #4de2da;
|
|
277
|
+
color: #fff;
|
|
278
|
+
background-image: repeating-linear-gradient(
|
|
279
|
+
-45deg,
|
|
280
|
+
#0ec4b6, #0ec4b6 10px,
|
|
281
|
+
#01b0a7 10px, #01b0a7 20px
|
|
282
|
+
);
|
|
283
|
+
background-size: 28.28px 28.28px;
|
|
284
|
+
animation: animal-btn-loading 1s linear infinite;
|
|
285
|
+
|
|
286
|
+
@keyframes animal-btn-loading {
|
|
287
|
+
0% { background-position: 0 0; }
|
|
288
|
+
100% { background-position: -28.28px 0; }
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**danger primary 按钮:**
|
|
293
|
+
```css
|
|
294
|
+
color: #fff;
|
|
295
|
+
box-shadow: 0 5px 0 0 #c94444; /* error-active */
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
### Input
|
|
301
|
+
|
|
302
|
+
| 属性 | small | middle | large |
|
|
303
|
+
|---|---|---|---|
|
|
304
|
+
| height | 32px | 40px | 48px |
|
|
305
|
+
| padding | `0 14px` | `0 18px` | `0 22px` |
|
|
306
|
+
| font-size | 12px | 14px | 16px |
|
|
307
|
+
| border-radius | 40px | 50px | 50px |
|
|
308
|
+
| border-width | 2.5px | 2.5px | **3px** |
|
|
309
|
+
| box-shadow | `0 2px 0 0 #d4c9b4` | `0 3px 0 0 #d4c9b4` | `0 4px 0 0 #d4c9b4` |
|
|
310
|
+
|
|
311
|
+
**精确颜色值:**
|
|
312
|
+
```css
|
|
313
|
+
background: rgb(247, 243, 223);
|
|
314
|
+
border: 2.5px solid #c4b89e;
|
|
315
|
+
box-shadow: 0 3px 0 0 #d4c9b4;
|
|
316
|
+
|
|
317
|
+
/* 文字 */
|
|
318
|
+
color: #725d42;
|
|
319
|
+
font-weight: 500;
|
|
320
|
+
letter-spacing: 0.01em;
|
|
321
|
+
|
|
322
|
+
/* placeholder */
|
|
323
|
+
color: #c4b89e;
|
|
324
|
+
font-weight: 400;
|
|
325
|
+
|
|
326
|
+
/* prefix/suffix */
|
|
327
|
+
color: #a0936e;
|
|
328
|
+
|
|
329
|
+
/* prefix margin-right */
|
|
330
|
+
margin-right: 6px;
|
|
331
|
+
|
|
332
|
+
/* suffix margin-left */
|
|
333
|
+
margin-left: 6px;
|
|
334
|
+
|
|
335
|
+
/* hover */
|
|
336
|
+
border-color: #a89878;
|
|
337
|
+
box-shadow: 0 3px 0 0 #c4b89e;
|
|
338
|
+
|
|
339
|
+
/* focus */
|
|
340
|
+
border-color: #ffcc00;
|
|
341
|
+
box-shadow: 0 3px 0 0 #e0b800, 0 0 0 3px rgba(255, 204, 0, 0.15);
|
|
342
|
+
|
|
343
|
+
/* disabled */
|
|
344
|
+
background: #ece8dc;
|
|
345
|
+
border-color: #d4c9b4;
|
|
346
|
+
box-shadow: none;
|
|
347
|
+
opacity: 0.6;
|
|
348
|
+
color: #c4b89e;
|
|
349
|
+
|
|
350
|
+
/* error */
|
|
351
|
+
box-shadow: 0 3px 0 0 #c94444;
|
|
352
|
+
|
|
353
|
+
/* warning */
|
|
354
|
+
box-shadow: 0 3px 0 0 #dba90e;
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
**clear 按钮:**
|
|
358
|
+
```css
|
|
359
|
+
width: 20px; height: 20px;
|
|
360
|
+
margin-left: 4px;
|
|
361
|
+
color: #c4b89e;
|
|
362
|
+
font-size: 13px; font-weight: 700;
|
|
363
|
+
border-radius: 50%;
|
|
364
|
+
transition: all 0.15s;
|
|
365
|
+
/* hover */ color: #725d42; background: rgba(114, 93, 66, 0.1);
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
### Switch
|
|
371
|
+
|
|
372
|
+
**默认尺寸:**
|
|
373
|
+
```css
|
|
374
|
+
min-width: 52px;
|
|
375
|
+
height: 28px;
|
|
376
|
+
border: 2.5px solid #c4b89e;
|
|
377
|
+
border-radius: 50px;
|
|
378
|
+
background: #d4c9b4;
|
|
379
|
+
box-shadow: inset 0 2px 4px rgba(114, 93, 66, 0.15);
|
|
380
|
+
|
|
381
|
+
/* handle */
|
|
382
|
+
width: 21px; height: 21px;
|
|
383
|
+
top: 2px; left: 2px;
|
|
384
|
+
background: rgb(247, 243, 223);
|
|
385
|
+
border: 2px solid #c4b89e;
|
|
386
|
+
border-radius: 50%;
|
|
387
|
+
box-shadow: 0 3px 0 0 #bdaea0;
|
|
388
|
+
transform: translateY(-2px); /* 悬浮效果 */
|
|
389
|
+
|
|
390
|
+
/* 开启态 */
|
|
391
|
+
background: #86d67a;
|
|
392
|
+
border-color: #6fba2c;
|
|
393
|
+
box-shadow: inset 0 2px 4px rgba(90, 158, 30, 0.2);
|
|
394
|
+
/* handle 开启后 left */
|
|
395
|
+
left: calc(100% - 24px);
|
|
396
|
+
border-color: #6fba2c;
|
|
397
|
+
box-shadow: 0 3px 0 0 #5a9e1e;
|
|
398
|
+
|
|
399
|
+
/* focus-visible */
|
|
400
|
+
outline: 2px solid #ffcc00;
|
|
401
|
+
outline-offset: 2px;
|
|
402
|
+
|
|
403
|
+
/* disabled */
|
|
404
|
+
opacity: 0.5;
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
**small 尺寸:**
|
|
408
|
+
```css
|
|
409
|
+
min-width: 38px; height: 20px; border-width: 2px;
|
|
410
|
+
/* handle */ width: 14px; height: 14px; top: 1px; left: 1px;
|
|
411
|
+
box-shadow: 0 2px 0 0 #bdaea0;
|
|
412
|
+
/* 开启 handle left */ left: calc(100% - 16px);
|
|
413
|
+
box-shadow: 0 2px 0 0 #5a9e1e;
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
**inner 文字(checkedChildren/unCheckedChildren):**
|
|
417
|
+
```css
|
|
418
|
+
font-size: 11px; font-weight: 700; color: #fff;
|
|
419
|
+
line-height: 1; letter-spacing: 0.02em;
|
|
420
|
+
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
|
|
421
|
+
padding: 0 8px 0 28px; /* 未开启 */
|
|
422
|
+
padding: 0 28px 0 8px; /* 开启 */
|
|
423
|
+
/* small 版 */ padding: 0 6px 0 20px; font-size: 9px;
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
**loading spinner:**
|
|
427
|
+
```css
|
|
428
|
+
width: 11px; height: 11px;
|
|
429
|
+
border: 2px solid #6fba2c;
|
|
430
|
+
border-right-color: transparent;
|
|
431
|
+
border-radius: 50%;
|
|
432
|
+
animation: animal-spin 0.6s linear infinite;
|
|
433
|
+
/* 关闭态 */ border-color: #a89878;
|
|
434
|
+
@keyframes animal-spin { to { transform: rotate(360deg); } }
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
### Card
|
|
440
|
+
|
|
441
|
+
```css
|
|
442
|
+
/* 默认 */
|
|
443
|
+
border-radius: 20px;
|
|
444
|
+
background: rgb(247, 243, 223);
|
|
445
|
+
padding: 16px 24px;
|
|
446
|
+
color: #725d42;
|
|
447
|
+
font-weight: 500;
|
|
448
|
+
box-shadow: 0 4px 10px rgba(107, 92, 67, 0.42);
|
|
449
|
+
transition: all 0.3s ease;
|
|
450
|
+
/* hover */ transform: translateY(-4px);
|
|
451
|
+
|
|
452
|
+
/* title 类型 */
|
|
453
|
+
background: #fdfdf5;
|
|
454
|
+
border-radius: 40px 35px 45px 38px / 38px 45px 35px 40px;
|
|
455
|
+
padding: 12px 32px;
|
|
456
|
+
font-weight: 600;
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
### Collapse
|
|
462
|
+
|
|
463
|
+
```css
|
|
464
|
+
/* 外层卡片 */
|
|
465
|
+
border-radius: 18px;
|
|
466
|
+
border: 2px solid #9f927d;
|
|
467
|
+
margin-bottom: 12px;
|
|
468
|
+
/* disabled */ opacity: 0.6;
|
|
469
|
+
|
|
470
|
+
/* 问题栏 */
|
|
471
|
+
padding: 16px 24px;
|
|
472
|
+
gap: 12px;
|
|
473
|
+
|
|
474
|
+
/* 图标圆圈 */
|
|
475
|
+
width: 28px; height: 28px;
|
|
476
|
+
background: #19c8b9;
|
|
477
|
+
color: #fff;
|
|
478
|
+
border-radius: 50%;
|
|
479
|
+
font-size: 18px; font-weight: 700;
|
|
480
|
+
box-shadow: 0 2px 4px rgba(25, 200, 185, 0.3);
|
|
481
|
+
/* 展开时 */ transform: rotate(180deg);
|
|
482
|
+
|
|
483
|
+
/* 叶子装饰 */
|
|
484
|
+
opacity: 0.5;
|
|
485
|
+
/* 展开时 */ opacity: 1; transform: rotate(45deg);
|
|
486
|
+
|
|
487
|
+
/* 问题文字 */
|
|
488
|
+
font-size: 16px; font-weight: 600; line-height: 1.4;
|
|
489
|
+
|
|
490
|
+
/* 答案展开(CSS Grid trick,无 JS)*/
|
|
491
|
+
display: grid;
|
|
492
|
+
grid-template-rows: 0fr;
|
|
493
|
+
transition: grid-template-rows 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
494
|
+
/* 展开 */ grid-template-rows: 1fr;
|
|
495
|
+
/* 内层 */ overflow: hidden;
|
|
496
|
+
|
|
497
|
+
/* 答案文字 */
|
|
498
|
+
padding: 0 24px;
|
|
499
|
+
font-size: 14px; line-height: 1.7;
|
|
500
|
+
/* 展开后 padding-bottom */ 24px;
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
---
|
|
504
|
+
|
|
505
|
+
### Tabs
|
|
506
|
+
|
|
507
|
+
```css
|
|
508
|
+
/* 外层容器 */
|
|
509
|
+
.tabs {
|
|
510
|
+
background: rgb(247, 243, 223);
|
|
511
|
+
border-radius: 20px;
|
|
512
|
+
border: 2px solid #9f927d;
|
|
513
|
+
overflow: hidden;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/* 标签列表 */
|
|
517
|
+
.tabList {
|
|
518
|
+
display: flex;
|
|
519
|
+
gap: 4px;
|
|
520
|
+
padding: 12px;
|
|
521
|
+
background: rgba(255, 255, 255, 0.6);
|
|
522
|
+
border-bottom: 2px solid #c4b89e;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/* 标签项 */
|
|
526
|
+
.tabItem {
|
|
527
|
+
display: flex;
|
|
528
|
+
align-items: center;
|
|
529
|
+
gap: 6px;
|
|
530
|
+
padding: 6px 14px;
|
|
531
|
+
background: transparent;
|
|
532
|
+
border: none;
|
|
533
|
+
border-radius: 50px;
|
|
534
|
+
cursor: pointer;
|
|
535
|
+
font-size: 14px;
|
|
536
|
+
font-weight: 500;
|
|
537
|
+
color: #8a7b66;
|
|
538
|
+
transition: all 0.2s ease;
|
|
539
|
+
}
|
|
540
|
+
/* hover */
|
|
541
|
+
.tabItem:hover {
|
|
542
|
+
background: rgba(25, 200, 185, 0.1);
|
|
543
|
+
color: #725d42;
|
|
544
|
+
}
|
|
545
|
+
/* 激活状态 */
|
|
546
|
+
.tabItem.active {
|
|
547
|
+
background: rgba(25, 200, 185, 0.15);
|
|
548
|
+
color: #19c8b9;
|
|
549
|
+
font-weight: 600;
|
|
550
|
+
box-shadow: 0 3px 0 0 #d4c9b4;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/* 标签图标 */
|
|
554
|
+
.tabIcon {
|
|
555
|
+
font-size: 10px;
|
|
556
|
+
}
|
|
557
|
+
/* 激活时图标放大 */
|
|
558
|
+
.tabItem.active .tabIcon {
|
|
559
|
+
transform: scale(1.2);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/* 叶子装饰动画 */
|
|
563
|
+
.tabLeaf {
|
|
564
|
+
position: absolute;
|
|
565
|
+
right: -6px;
|
|
566
|
+
top: -3px;
|
|
567
|
+
font-size: 12px;
|
|
568
|
+
animation: leafWiggle 2s ease-in-out infinite;
|
|
569
|
+
}
|
|
570
|
+
/* leafAnimation={false} 时追加 tabLeafStatic 类去除 animation */
|
|
571
|
+
|
|
572
|
+
@keyframes leafWiggle {
|
|
573
|
+
0%, 100% { transform: rotate(0deg); }
|
|
574
|
+
25% { transform: rotate(-10deg); }
|
|
575
|
+
75% { transform: rotate(10deg); }
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/* 内容区 */
|
|
579
|
+
.tabContent {
|
|
580
|
+
padding: 24px;
|
|
581
|
+
animation: fadeIn 0.25s ease;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
@keyframes fadeIn {
|
|
585
|
+
from { opacity: 0; transform: translateY(4px); }
|
|
586
|
+
to { opacity: 1; transform: translateY(0); }
|
|
587
|
+
}
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
---
|
|
591
|
+
|
|
592
|
+
### Modal
|
|
593
|
+
|
|
594
|
+
**SVG clip-path 完整 path d 值(精确还原 blob 轮廓):**
|
|
595
|
+
```jsx
|
|
596
|
+
<svg style={{ position: 'absolute', width: 0, height: 0 }} aria-hidden>
|
|
597
|
+
<defs>
|
|
598
|
+
<clipPath id="animal-modal-clip" clipPathUnits="objectBoundingBox">
|
|
599
|
+
<path d="M0.501,0.005 L0.501,0.005 L0.523,0.005 L0.549,0.006
|
|
600
|
+
C0.704,0.01,0.796,0.017,0.825,0.027
|
|
601
|
+
L0.827,0.028
|
|
602
|
+
C0.872,0.045,0.939,0.044,0.978,0.17
|
|
603
|
+
C1,0.254,1,0.365,0.99,0.505
|
|
604
|
+
L0.988,0.513
|
|
605
|
+
C0.979,0.558,0.971,0.598,0.965,0.633
|
|
606
|
+
C0.956,0.689,0.979,0.77,0.964,0.865
|
|
607
|
+
C0.953,0.928,0.921,0.966,0.869,0.979
|
|
608
|
+
C0.821,0.986,0.773,0.992,0.726,0.995
|
|
609
|
+
L0.712,0.996 L0.694,0.997
|
|
610
|
+
C0.648,1,0.586,1,0.507,1
|
|
611
|
+
L0.501,1 L0.464,1
|
|
612
|
+
C0.385,1,0.325,0.998,0.283,0.995
|
|
613
|
+
C0.234,0.992,0.184,0.987,0.133,0.979
|
|
614
|
+
C0.081,0.966,0.05,0.928,0.039,0.865
|
|
615
|
+
C0.023,0.77,0.047,0.689,0.037,0.633
|
|
616
|
+
C0.031,0.595,0.023,0.552,0.013,0.505
|
|
617
|
+
C-0.006,0.365,-0.002,0.254,0.024,0.17
|
|
618
|
+
C0.064,0.045,0.13,0.045,0.174,0.028
|
|
619
|
+
L0.175,0.028
|
|
620
|
+
C0.204,0.017,0.303,0.009,0.474,0.005
|
|
621
|
+
L0.501,0.005" />
|
|
622
|
+
</clipPath>
|
|
623
|
+
</defs>
|
|
624
|
+
</svg>
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
**Modal 精确样式:**
|
|
628
|
+
```css
|
|
629
|
+
/* 遮罩 */
|
|
630
|
+
background: rgba(0, 0, 0, 0.35);
|
|
631
|
+
animation: animal-fade-in 0.25s ease;
|
|
632
|
+
z-index: 1000;
|
|
633
|
+
|
|
634
|
+
/* 弹窗容器 */
|
|
635
|
+
max-width: calc(100vw - 32px);
|
|
636
|
+
max-height: calc(100vh - 64px);
|
|
637
|
+
animation: animal-zoom-in 0.3s ease;
|
|
638
|
+
|
|
639
|
+
/* 裁切内容区 */
|
|
640
|
+
clip-path: url(#animal-modal-clip);
|
|
641
|
+
background: rgb(247, 243, 223);
|
|
642
|
+
color: rgb(128, 115, 89);
|
|
643
|
+
padding: 48px 48px 32px 48px;
|
|
644
|
+
|
|
645
|
+
/* 标题 */
|
|
646
|
+
font-size: 28px; font-weight: 700;
|
|
647
|
+
color: rgba(114, 93, 66, 1);
|
|
648
|
+
padding-bottom: 15px;
|
|
649
|
+
|
|
650
|
+
/* 关闭按钮 */
|
|
651
|
+
width: 32px; height: 32px;
|
|
652
|
+
font-size: 22px;
|
|
653
|
+
color: rgba(114, 93, 66, 0.6);
|
|
654
|
+
border-radius: 50%;
|
|
655
|
+
transition: all 0.2s;
|
|
656
|
+
/* hover */ background: rgba(114, 93, 66, 0.1); color: rgba(114, 93, 66, 1);
|
|
657
|
+
|
|
658
|
+
/* body */
|
|
659
|
+
font-size: 20px; font-weight: 600; line-height: 1.6;
|
|
660
|
+
color: #8a7b66;
|
|
661
|
+
padding-bottom: 20px;
|
|
662
|
+
|
|
663
|
+
/* footer */
|
|
664
|
+
gap: 12px;
|
|
665
|
+
|
|
666
|
+
/* 普通按钮 */
|
|
667
|
+
height: 40px; padding: 0 24px;
|
|
668
|
+
font-size: 18px;
|
|
669
|
+
border: 2px solid rgba(114, 93, 66, 0.3);
|
|
670
|
+
border-radius: 39.81px;
|
|
671
|
+
transition: all 0.2s; line-height: 1;
|
|
672
|
+
/* hover */ border-color: rgba(114,93,66,0.6); background: rgba(114,93,66,0.08);
|
|
673
|
+
|
|
674
|
+
/* 主按钮(确认)*/
|
|
675
|
+
color: rgba(114, 93, 66, 1);
|
|
676
|
+
background: rgba(255, 204, 0, 1); /* 游戏黄色!*/
|
|
677
|
+
border-color: rgba(255, 204, 0, 1);
|
|
678
|
+
/* hover */ background: rgba(255,204,0,0.85); border-color: rgba(255,204,0,0.85);
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
---
|
|
682
|
+
|
|
683
|
+
### Time
|
|
684
|
+
|
|
685
|
+
```css
|
|
686
|
+
/* 容器 */
|
|
687
|
+
display: flex; align-items: center;
|
|
688
|
+
gap: 20px;
|
|
689
|
+
padding: 16px 36px;
|
|
690
|
+
background: linear-gradient(180deg, #fff 0%, #f8f8f0 100%);
|
|
691
|
+
border: 3px solid #d4cfc3;
|
|
692
|
+
border-radius: 18px;
|
|
693
|
+
animation: ac-fade-up 0.5s ease-out;
|
|
694
|
+
|
|
695
|
+
/* 日期块(右侧分隔线)*/
|
|
696
|
+
padding-right: 24px;
|
|
697
|
+
border-right: 3px solid rgba(159, 146, 125, 0.35);
|
|
698
|
+
|
|
699
|
+
/* 星期 */
|
|
700
|
+
color: #6fba2c;
|
|
701
|
+
font-weight: 900; font-size: 14px;
|
|
702
|
+
letter-spacing: 1.5px;
|
|
703
|
+
|
|
704
|
+
/* 月日 */
|
|
705
|
+
color: #8b7355;
|
|
706
|
+
font-weight: 800; font-size: 22px;
|
|
707
|
+
|
|
708
|
+
/* 时间数字 */
|
|
709
|
+
color: #8b7355;
|
|
710
|
+
font-weight: 900; font-size: 48px;
|
|
711
|
+
letter-spacing: 2px;
|
|
712
|
+
|
|
713
|
+
/* 冒号(闪烁)*/
|
|
714
|
+
font-size: 48px; color: #8b7355;
|
|
715
|
+
position: relative; top: -0.08em;
|
|
716
|
+
margin: 0 1px;
|
|
717
|
+
animation: blink 1s step-end infinite;
|
|
718
|
+
|
|
719
|
+
@keyframes blink { 50% { opacity: 0; } }
|
|
720
|
+
|
|
721
|
+
/* 响应式 768px */
|
|
722
|
+
padding: 12px 20px; gap: 12px;
|
|
723
|
+
.acWeekday → font-size: 11px;
|
|
724
|
+
.acMonthday → font-size: 16px;
|
|
725
|
+
.acTime / .acColon → font-size: 32px;
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
---
|
|
729
|
+
|
|
730
|
+
### Phone(NookPhone)
|
|
731
|
+
|
|
732
|
+
**外壳(固定尺寸,不响应式):**
|
|
733
|
+
```css
|
|
734
|
+
.phone {
|
|
735
|
+
width: 527px; height: 788px;
|
|
736
|
+
background: #F8F4E8; /* 奶油米 */
|
|
737
|
+
border-radius: 136px; /* 超大圆角,近似胶囊 */
|
|
738
|
+
overflow: hidden;
|
|
739
|
+
}
|
|
740
|
+
.homeScreen {
|
|
741
|
+
height: 100%;
|
|
742
|
+
padding-top: 40px;
|
|
743
|
+
background: #F8F4E8;
|
|
744
|
+
background-size: 100% 200%;
|
|
745
|
+
animation: grasswave 8s ease-in-out infinite;
|
|
746
|
+
display: flex; flex-direction: column; align-items: center;
|
|
747
|
+
}
|
|
748
|
+
@keyframes grasswave {
|
|
749
|
+
0%, 100% { background-position: 0% 0%; }
|
|
750
|
+
50% { background-position: 0% 100%; }
|
|
751
|
+
}
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
**顶部时间栏:**
|
|
755
|
+
```css
|
|
756
|
+
.dateDisplay { padding: 0 70px 31px 70px; text-align: center; }
|
|
757
|
+
.dateDisplayHeader { display:flex; justify-content:space-between; align-items:center;
|
|
758
|
+
font-size: 32px; font-weight: 800; letter-spacing: 2px; color: #DDDBCC; }
|
|
759
|
+
.blink { font-size: 32px; font-weight: 800; color: #DDDBCC;
|
|
760
|
+
animation: blink 1s steps(1) infinite; vertical-align: text-bottom; }
|
|
761
|
+
@keyframes blink { 0%,50% { opacity: 1; } 51%,100% { opacity: 0; } }
|
|
762
|
+
.dayText { font-size: 48px; font-weight: 800; color: #725C4E;
|
|
763
|
+
letter-spacing: 2px; height: 56px; margin-top: 20px; }
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
**3×3 应用网格:**
|
|
767
|
+
```css
|
|
768
|
+
.appsGrid { display: grid; grid-template-columns: repeat(3, 1fr);
|
|
769
|
+
gap: 32px; padding: 8px; flex: 1;
|
|
770
|
+
align-content: center; justify-content: center; }
|
|
771
|
+
.appItem { width: 123px; height: 123px;
|
|
772
|
+
border-radius: 45px; /* 圆角正方形 */
|
|
773
|
+
position: relative;
|
|
774
|
+
display: flex; justify-content: center; align-items: center; }
|
|
775
|
+
.appItem:hover .appIcon { animation: iconBounce 0.3s ease-in-out forwards; }
|
|
776
|
+
.appIcon { width: 100%; height: 100%;
|
|
777
|
+
background-repeat: no-repeat; background-position: center;
|
|
778
|
+
background-size: 70% auto; }
|
|
779
|
+
.appItemOffset { overflow: hidden; }
|
|
780
|
+
.appIconOffset { transform: translateY(10px); }
|
|
781
|
+
|
|
782
|
+
@keyframes iconBounce {
|
|
783
|
+
0% { transform: scale(1) rotate(0deg); }
|
|
784
|
+
50% { transform: scale(1.2) rotate(-5deg); }
|
|
785
|
+
100% { transform: scale(1.1) rotate(-4deg); }
|
|
786
|
+
}
|
|
787
|
+
```
|
|
788
|
+
|
|
789
|
+
**应用数据结构(`src/components/Phone/Phone.tsx`):**
|
|
790
|
+
|
|
791
|
+
| id | iconClass | 背景色 | offset | hasNewMessage |
|
|
792
|
+
|---|---|---|---|---|
|
|
793
|
+
| camera | iconCamera | `#B77DEE` | | ✓ |
|
|
794
|
+
| app | iconApp | `#889DF0` | ✓ | |
|
|
795
|
+
| critterpedia | iconCritterpedia | `#F7CD67` | | |
|
|
796
|
+
| diy | iconDiy | `#E59266` | | |
|
|
797
|
+
| shopping | iconDesign | `#F8A6B2` | | |
|
|
798
|
+
| variant | iconMap | `#82D5BB` | | ✓ |
|
|
799
|
+
| design | iconVariant | `#8AC68A` | | |
|
|
800
|
+
| map | iconHelicopter | `#FC736D` | | |
|
|
801
|
+
| chat | iconChat | `#D1DA49` | | |
|
|
802
|
+
|
|
803
|
+
每个 iconClass 都绑定一个 `background-image: url('./img/icon-*.svg')`,`iconApp` 特殊使用 `background-size: 100% auto`(其他是 `70% auto`)。可用图标资源:`icon-miles/camera/chat/critterpedia/design/diy/helicopter/map/shopping/variant.svg`,以及状态图标 `wifi.svg` / `location.svg` / `page.svg`。
|
|
804
|
+
|
|
805
|
+
**小红点(新消息):**
|
|
806
|
+
```css
|
|
807
|
+
.badge {
|
|
808
|
+
position: absolute; top: 0; left: 0;
|
|
809
|
+
width: 28px; height: 28px; border-radius: 50%;
|
|
810
|
+
background: #FF544A;
|
|
811
|
+
border: 5px solid #F8F4E8; /* 奶油米描边,形成游戏风徽章 */
|
|
812
|
+
}
|
|
813
|
+
```
|
|
814
|
+
|
|
815
|
+
**底部状态图标:**
|
|
816
|
+
```css
|
|
817
|
+
.iconWifi { width: 79px; height: 29px; background: url('./img/wifi.svg') center/contain no-repeat; }
|
|
818
|
+
.iconLocation { width: 36px; height: 36px; background: url('./img/location.svg') center/contain no-repeat; }
|
|
819
|
+
.iconPage { width: 65px; height: 32px; background: url('./img/page.svg') center/contain no-repeat; }
|
|
820
|
+
.pageIndicator{ display: flex; justify-content: center; align-items: center;
|
|
821
|
+
margin-top: 74px; }
|
|
822
|
+
```
|
|
823
|
+
|
|
824
|
+
**行为:** 内部 `useEffect + setInterval(1000)` 更新时间,`12 小时制 + AM/PM + 零填充分钟`,冒号闪烁 1s 一个周期。组件无业务回调,纯展示。
|
|
825
|
+
|
|
826
|
+
---
|
|
827
|
+
|
|
828
|
+
### Footer
|
|
829
|
+
|
|
830
|
+
```tsx
|
|
831
|
+
<Footer /> // 默认:森林(tree,高 60px)
|
|
832
|
+
<Footer type="sea" /> // 海浪(高 80px)
|
|
833
|
+
```
|
|
834
|
+
|
|
835
|
+
```less
|
|
836
|
+
.footer { width: 100%; height: 80px;
|
|
837
|
+
background: url('./img/footer-sea.svg') center/contain no-repeat; }
|
|
838
|
+
.tree { background-image: url('./img/footer-tree.webp');
|
|
839
|
+
height: 60px;
|
|
840
|
+
background-size: cover;
|
|
841
|
+
background-position: bottom center; }
|
|
842
|
+
```
|
|
843
|
+
|
|
844
|
+
- `sea`:SVG 海浪插画,`viewBox="0 0 1440 186"`,多色(珊瑚 `#EC7175`、海蓝 `#327A93`、浅蓝 `#98D2E3`、深青 `#008077` 等)。
|
|
845
|
+
- `tree`:webp 森林剪影,置于页面最底部。
|
|
846
|
+
|
|
847
|
+
---
|
|
848
|
+
|
|
849
|
+
### Divider
|
|
850
|
+
|
|
851
|
+
```tsx
|
|
852
|
+
<Divider type="line-brown" /> // 默认
|
|
853
|
+
<Divider type="line-teal" />
|
|
854
|
+
<Divider type="line-white" />
|
|
855
|
+
<Divider type="line-yellow" />
|
|
856
|
+
<Divider type="wave-yellow" />
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
```less
|
|
860
|
+
.divider { width: 100%; height: 12px;
|
|
861
|
+
background: url('./img/divider-line-brown.svg') center/contain no-repeat; }
|
|
862
|
+
.line-teal { background-image: url('./img/divider-line-teal.svg'); }
|
|
863
|
+
.line-white { background-image: url('./img/divider-line-white.png'); }
|
|
864
|
+
.line-yellow { background-image: url('./img/divider-line-yellow.svg'); }
|
|
865
|
+
.wave-yellow { background-image: url('./img/wave-yellow.svg'); }
|
|
866
|
+
```
|
|
867
|
+
|
|
868
|
+
默认 SVG 色值参考:`#D8D0C3`(米褐),`viewBox="0 0 297 14"`。
|
|
869
|
+
|
|
870
|
+
---
|
|
871
|
+
|
|
872
|
+
### Cursor
|
|
873
|
+
|
|
874
|
+
```tsx
|
|
875
|
+
<Cursor>
|
|
876
|
+
<App /> {/* 此范围内所有元素变为游戏手指光标 */}
|
|
877
|
+
</Cursor>
|
|
878
|
+
```
|
|
879
|
+
|
|
880
|
+
样式文件为 **普通 CSS**(非 module):
|
|
881
|
+
```css
|
|
882
|
+
.animal-cursor,
|
|
883
|
+
.animal-cursor * {
|
|
884
|
+
cursor: url('./cursor-icon.png') 4 0, auto !important;
|
|
885
|
+
}
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
- `cursor-icon.png` 热点坐标 `(4, 0)`
|
|
889
|
+
- 使用 `!important` 覆盖默认光标;`className` 直接挂在根 `<div>` 上,类名固定为 `animal-cursor`
|
|
890
|
+
|
|
891
|
+
---
|
|
892
|
+
|
|
893
|
+
### Typewriter
|
|
894
|
+
|
|
895
|
+
```tsx
|
|
896
|
+
<Typewriter speed={90} trigger={openCount} autoPlay onDone={() => ...}>
|
|
897
|
+
<p>第一行 <strong>加粗</strong></p>
|
|
898
|
+
<p>第二行</p>
|
|
899
|
+
</Typewriter>
|
|
900
|
+
```
|
|
901
|
+
|
|
902
|
+
Props:
|
|
903
|
+
|
|
904
|
+
| name | type | default | 说明 |
|
|
905
|
+
|---|---|---|---|
|
|
906
|
+
| `children` | `ReactNode` | — | 要逐字打出的内容,**保留原有元素结构 / 换行 / 样式** |
|
|
907
|
+
| `speed` | `number (ms)` | `90` | 每字间隔 |
|
|
908
|
+
| `trigger` | `unknown` | — | 值变化即重新播放(通常传递弹窗 open 次数或递增 key) |
|
|
909
|
+
| `autoPlay` | `boolean` | `true` | `false` 直接全量显示 |
|
|
910
|
+
| `onDone` | `() => void` | — | 播放完成回调 |
|
|
911
|
+
|
|
912
|
+
**实现要点:**
|
|
913
|
+
- `countText(node)`:递归统计 ReactNode 的纯文本长度
|
|
914
|
+
- `renderTruncated(node, state)`:按剩余字符数递归裁剪,`React.cloneElement` 保留原节点与样式
|
|
915
|
+
- `useEffect` 依赖 `[total, speed, trigger, autoPlay]`,内部 `setInterval` 按步递增 `count`
|
|
916
|
+
- **无样式文件**,不包裹任何额外 DOM(返回 `<>...</>`),对布局零影响
|
|
917
|
+
|
|
918
|
+
---
|
|
919
|
+
|
|
920
|
+
### Checkbox
|
|
921
|
+
|
|
922
|
+
Props:
|
|
923
|
+
|
|
924
|
+
| name | type | default | 说明 |
|
|
925
|
+
|---|---|---|---|
|
|
926
|
+
| `options` | `CheckboxOption[]` | — | **必填**;每项 `{ label, value, disabled? }` |
|
|
927
|
+
| `value` | `Array<string \| number>` | — | 受控选中值 |
|
|
928
|
+
| `defaultValue` | `Array<string \| number>` | `[]` | 非受控默认值 |
|
|
929
|
+
| `size` | `'small' \| 'middle' \| 'large'` | `'middle'` | 尺寸 |
|
|
930
|
+
| `disabled` | `boolean` | `false` | 禁用全部项 |
|
|
931
|
+
| `direction` | `'horizontal' \| 'vertical'` | `'horizontal'` | 排列方向 |
|
|
932
|
+
| `onChange` | `(values) => void` | — | 选中值变化 |
|
|
933
|
+
|
|
934
|
+
**尺寸表(box 方框):**
|
|
935
|
+
|
|
936
|
+
| 属性 | small | middle | large |
|
|
937
|
+
|---|---|---|---|
|
|
938
|
+
| 宽高 | 18×18px | **22×22px** | 28×28px |
|
|
939
|
+
| border-width | 2px | 2.5px | 3px |
|
|
940
|
+
| 标签 font-size | 12px | 14px | 16px |
|
|
941
|
+
| 对勾 font-size | 11px | 13px | 16px |
|
|
942
|
+
|
|
943
|
+
**精确样式:**
|
|
944
|
+
```css
|
|
945
|
+
/* group */
|
|
946
|
+
display: flex; flex-wrap: wrap;
|
|
947
|
+
gap: 12px; /* horizontal */
|
|
948
|
+
/* vertical */ flex-direction: column; gap: 8px;
|
|
949
|
+
|
|
950
|
+
/* item */
|
|
951
|
+
display: inline-flex; align-items: center;
|
|
952
|
+
gap: 8px;
|
|
953
|
+
cursor: pointer;
|
|
954
|
+
transition: all 0.25s cubic-bezier(0.4,0,0.2,1);
|
|
955
|
+
|
|
956
|
+
/* box(未选)*/
|
|
957
|
+
background: rgb(247, 243, 223);
|
|
958
|
+
border: 2.5px solid #c4b89e;
|
|
959
|
+
border-radius: 8px;
|
|
960
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
961
|
+
|
|
962
|
+
/* box hover */
|
|
963
|
+
border-color: #19c8b9;
|
|
964
|
+
transform: translateY(-1px);
|
|
965
|
+
|
|
966
|
+
/* box focus-visible */
|
|
967
|
+
outline: 2px solid #ffcc00; outline-offset: 2px;
|
|
968
|
+
|
|
969
|
+
/* 选中 */
|
|
970
|
+
background: #19c8b9;
|
|
971
|
+
border-color: #11a89b;
|
|
972
|
+
/* 选中 hover */ background: #3dd4c6; border-color: #19c8b9;
|
|
973
|
+
|
|
974
|
+
/* 对勾 ✓ */
|
|
975
|
+
color: #fff; font-weight: 700; line-height: 1;
|
|
976
|
+
animation: animal-checkbox-pop 0.15s cubic-bezier(0.4,0,0.2,1);
|
|
977
|
+
|
|
978
|
+
@keyframes animal-checkbox-pop {
|
|
979
|
+
0% { transform: scale(0.4); opacity: 0; }
|
|
980
|
+
60% { transform: scale(1.2); }
|
|
981
|
+
100% { transform: scale(1); opacity: 1; }
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
/* label */
|
|
985
|
+
color: #725d42; font-weight: 500;
|
|
986
|
+
letter-spacing: 0.01em;
|
|
987
|
+
/* item hover */ label color: #794f27;
|
|
988
|
+
|
|
989
|
+
/* 禁用(单项或整组)*/
|
|
990
|
+
cursor: not-allowed;
|
|
991
|
+
opacity: 0.55;
|
|
992
|
+
/* box */ background: #f0ece2; border-color: #d4c9b4; transform: none !important;
|
|
993
|
+
/* label */ color: #c4b89e;
|
|
994
|
+
```
|
|
995
|
+
|
|
996
|
+
---
|
|
997
|
+
|
|
998
|
+
### CodeBlock
|
|
999
|
+
|
|
1000
|
+
Props:
|
|
1001
|
+
|
|
1002
|
+
| name | type | default | 说明 |
|
|
1003
|
+
|---|---|---|---|
|
|
1004
|
+
| `code` | `string` | — | **必填**;原始源码字符串,内部自动按 JSX/TS 分词高亮 |
|
|
1005
|
+
| `style` | `CSSProperties` | — | 会合并覆盖默认深色主题 |
|
|
1006
|
+
| `className` | `string` | — | 自定义类名 |
|
|
1007
|
+
|
|
1008
|
+
**默认主题(写死在组件,不走 Less):**
|
|
1009
|
+
|
|
1010
|
+
```css
|
|
1011
|
+
padding: 20px 24px;
|
|
1012
|
+
background: #2b2118;
|
|
1013
|
+
border: 1px solid #3d3028;
|
|
1014
|
+
border-radius: 20px;
|
|
1015
|
+
font-size: 14px;
|
|
1016
|
+
line-height: 1.7;
|
|
1017
|
+
font-family: 'SF Mono','Fira Code','Cascadia Code',Consolas,monospace;
|
|
1018
|
+
font-weight: 600;
|
|
1019
|
+
color: #e8d5bc;
|
|
1020
|
+
white-space: pre;
|
|
1021
|
+
overflow: auto;
|
|
1022
|
+
tab-size: 4;
|
|
1023
|
+
```
|
|
1024
|
+
|
|
1025
|
+
**Token 调色板(`COLORS` 常量):**
|
|
1026
|
+
|
|
1027
|
+
| token | 颜色 | 覆盖 |
|
|
1028
|
+
|---|---|---|
|
|
1029
|
+
| comment | `#6b5e50` | `/* */`、`//` |
|
|
1030
|
+
| string | `#a8d4a0` | 反引号 / 单双引号、数字 |
|
|
1031
|
+
| keyword | `#d4a0e0` | `import/export/const/return/async/...`、`true/false/null/undefined` |
|
|
1032
|
+
| react | `#e06c75` | `React/useState/useEffect/FC/ReactNode/CSSProperties/...` |
|
|
1033
|
+
| component| `#80c0e0` | 大写驼峰标识符(JSX 组件名、类型名) |
|
|
1034
|
+
| func | `#61afef` | 小写标识符后跟 `(` |
|
|
1035
|
+
| prop | `#e8c87a` | 标识符后跟 `=`(JSX props / 赋值) |
|
|
1036
|
+
| jsx | `#f0a870` | `<Tag`、`</Tag`、`/>` |
|
|
1037
|
+
| operator | `#d4b896` | `{}[]();,` 和 `+-*/=<>&|^~?:` 等 |
|
|
1038
|
+
| default | `#e8d5bc` | 其余文本 |
|
|
1039
|
+
|
|
1040
|
+
> 不支持 `language` prop;非 JS/TS 代码(Python/Shell/SQL)会按通用规则着色,显示可能不准确。不带 copy 按钮、行号或折行。
|
|
1041
|
+
|
|
1042
|
+
---
|
|
1043
|
+
|
|
1044
|
+
## 3. Demo 布局精确规范
|
|
1045
|
+
|
|
1046
|
+
这是 Demo 站(`demo/App.tsx`)的实际布局数值,用于还原完整页面效果:
|
|
1047
|
+
|
|
1048
|
+
### 整体布局
|
|
1049
|
+
|
|
1050
|
+
```css
|
|
1051
|
+
/* 页面背景 */
|
|
1052
|
+
/* 首页 */ background: url(home_bg.svg) center/cover no-repeat, #7DC395;
|
|
1053
|
+
/* 组件页 */ background: url(content_bg_pc.jpg) center fixed;
|
|
1054
|
+
|
|
1055
|
+
/* Sidebar */
|
|
1056
|
+
width: 220px; min-width: 220px;
|
|
1057
|
+
background: url(menu_bg.svg) center/cover no-repeat;
|
|
1058
|
+
```
|
|
1059
|
+
|
|
1060
|
+
### Sidebar 精确值
|
|
1061
|
+
|
|
1062
|
+
```css
|
|
1063
|
+
/* 顶部 Logo 区 */
|
|
1064
|
+
padding: 20px 16px 12px;
|
|
1065
|
+
border-bottom: 1px solid #e8e2d6;
|
|
1066
|
+
font-weight: 700; font-size: 15px;
|
|
1067
|
+
color: #725d42; letter-spacing: -0.3px;
|
|
1068
|
+
|
|
1069
|
+
/* Logo 图片 */
|
|
1070
|
+
width: 24px; height: 24px; margin-right: 8px;
|
|
1071
|
+
|
|
1072
|
+
/* 菜单列表 */
|
|
1073
|
+
padding: 8px 0;
|
|
1074
|
+
|
|
1075
|
+
/* 分类标题 */
|
|
1076
|
+
padding: 12px 16px 4px;
|
|
1077
|
+
font-size: 11px; color: #a0936e;
|
|
1078
|
+
font-weight: 600; letter-spacing: 0.5px;
|
|
1079
|
+
text-transform: uppercase;
|
|
1080
|
+
|
|
1081
|
+
/* 菜单项 */
|
|
1082
|
+
margin: 1px 5px;
|
|
1083
|
+
height: 40px; padding: 0 16px;
|
|
1084
|
+
padding-left: 26px;
|
|
1085
|
+
font-weight: 600; font-size: 14px;
|
|
1086
|
+
border-radius: 12px;
|
|
1087
|
+
transition: all 0.15s;
|
|
1088
|
+
|
|
1089
|
+
/* inactive */ color: #8a7b66; background: transparent;
|
|
1090
|
+
/* inactive hover */ background: #d6dff0;
|
|
1091
|
+
/* active */ color: #fff; background: #B7C6E5;
|
|
1092
|
+
```
|
|
1093
|
+
|
|
1094
|
+
### 主内容区
|
|
1095
|
+
|
|
1096
|
+
```css
|
|
1097
|
+
/* 桌面 */
|
|
1098
|
+
padding: 32px 40px;
|
|
1099
|
+
|
|
1100
|
+
/* 底部装饰图(桌面端,固定定位)*/
|
|
1101
|
+
left: 220px;
|
|
1102
|
+
width: calc(100% - 220px);
|
|
1103
|
+
z-index: 0; pointer-events: none;
|
|
1104
|
+
```
|
|
1105
|
+
|
|
1106
|
+
### 移动端适配
|
|
1107
|
+
|
|
1108
|
+
```css
|
|
1109
|
+
/* 顶栏 */
|
|
1110
|
+
height: 52px; padding: 0 12px;
|
|
1111
|
+
background: rgba(255, 252, 244, 0.92);
|
|
1112
|
+
backdrop-filter: blur(8px);
|
|
1113
|
+
border-bottom: 1px solid #e8e2d6;
|
|
1114
|
+
z-index: 50;
|
|
1115
|
+
|
|
1116
|
+
/* 按钮 */ font-size: 20px; color: #725d42; padding: 4px 8px; border-radius: 8px;
|
|
1117
|
+
|
|
1118
|
+
/* 主内容区 padding-top */ 68px;
|
|
1119
|
+
|
|
1120
|
+
/* 抽屉 */
|
|
1121
|
+
width: 240px; z-index: 99;
|
|
1122
|
+
box-shadow: 4px 0 24px rgba(0, 0, 0, 0.15);
|
|
1123
|
+
/* 遮罩 */ background: rgba(0, 0, 0, 0.35); z-index: 98;
|
|
1124
|
+
```
|
|
1125
|
+
|
|
1126
|
+
---
|
|
1127
|
+
|
|
1128
|
+
## 4. HomePage 精确规范
|
|
1129
|
+
|
|
1130
|
+
```css
|
|
1131
|
+
/* Hero 区域 */
|
|
1132
|
+
padding: 60px 40px 40px;
|
|
1133
|
+
min-height: 80vh;
|
|
1134
|
+
|
|
1135
|
+
/* 主标题 */
|
|
1136
|
+
font-size: 50px; font-weight: 700;
|
|
1137
|
+
color: #FFF9E6;
|
|
1138
|
+
text-shadow: 0px 4px 1px rgba(0, 0, 0, 0.4);
|
|
1139
|
+
margin: 0 0 12px;
|
|
1140
|
+
|
|
1141
|
+
/* 版本 Badge */
|
|
1142
|
+
font-size: 12px; font-weight: 600;
|
|
1143
|
+
padding: 2px 10px; border-radius: 10px;
|
|
1144
|
+
background: #e6f9f6; color: #19c8b9;
|
|
1145
|
+
margin-left: 8px;
|
|
1146
|
+
|
|
1147
|
+
/* 副标题 */
|
|
1148
|
+
font-size: 17px; color: #7c5734; line-height: 1.7;
|
|
1149
|
+
margin: 0 0 28px; max-width: 520px;
|
|
1150
|
+
|
|
1151
|
+
/* Logo 图片 */
|
|
1152
|
+
width: 172px; height: 172px;
|
|
1153
|
+
|
|
1154
|
+
/* Section */
|
|
1155
|
+
padding: 48px 40px; max-width: 960px; margin: 0 auto;
|
|
1156
|
+
|
|
1157
|
+
/* Section 标题 */
|
|
1158
|
+
font-size: 24px; font-weight: 700; color: #725d42; margin: 0 0 8px;
|
|
1159
|
+
|
|
1160
|
+
/* Section 描述 */
|
|
1161
|
+
font-size: 14px; color: #7c5734; margin-bottom: 32px;
|
|
1162
|
+
|
|
1163
|
+
/* Feature 网格 */
|
|
1164
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
1165
|
+
gap: 16px;
|
|
1166
|
+
|
|
1167
|
+
/* Feature Card hover */
|
|
1168
|
+
transform: translateY(-4px);
|
|
1169
|
+
box-shadow: 0 8px 24px rgba(114, 93, 66, 0.15);
|
|
1170
|
+
|
|
1171
|
+
/* Feature 图标 hover */
|
|
1172
|
+
transform: scale(1.1) rotate(-4deg);
|
|
1173
|
+
|
|
1174
|
+
/* 代码块 */
|
|
1175
|
+
max-width: 600px; margin: 0 auto;
|
|
1176
|
+
padding: 20px 28px;
|
|
1177
|
+
background: #2b2118;
|
|
1178
|
+
border: 1px solid #3d3028;
|
|
1179
|
+
border-radius: 20px;
|
|
1180
|
+
font-size: 13px; font-weight: 600;
|
|
1181
|
+
color: #e8d5bc; line-height: 1.8;
|
|
1182
|
+
```
|
|
1183
|
+
|
|
1184
|
+
**代码高亮配色:**
|
|
1185
|
+
|
|
1186
|
+
| Token 类型 | 颜色 |
|
|
1187
|
+
|---|---|
|
|
1188
|
+
| 注释 | `#6b5e50`(italic, weight 400)|
|
|
1189
|
+
| 字符串 | `#a8d4a0` |
|
|
1190
|
+
| JSX 标签 | `#f0a870` |
|
|
1191
|
+
| 关键字 / npm/pnpm | `#f0a870` |
|
|
1192
|
+
| 命令动词(install/add)| `#a8d4a0` |
|
|
1193
|
+
| 括号 `{}` | `#d4b896` |
|
|
1194
|
+
| 箭头 `=>` | `#d4a0e0` |
|
|
1195
|
+
| CSS 变量名 | `#e8c87a` |
|
|
1196
|
+
| `:root` | `#f0a870` |
|
|
1197
|
+
| 十六进制色值 | `#8ab8e0` |
|
|
1198
|
+
|
|
1199
|
+
---
|
|
1200
|
+
|
|
1201
|
+
## 5. 自实现 CSS 变量完整模板
|
|
1202
|
+
|
|
1203
|
+
不依赖组件库时,在 `:root` 中声明以下变量:
|
|
1204
|
+
|
|
1205
|
+
```css
|
|
1206
|
+
:root {
|
|
1207
|
+
/* 字体 */
|
|
1208
|
+
--animal-font: Nunito, 'Noto Sans SC', 'Zen Maru Gothic',
|
|
1209
|
+
-apple-system, 'PingFang SC', 'Hiragino Sans GB', sans-serif;
|
|
1210
|
+
|
|
1211
|
+
/* 主色 */
|
|
1212
|
+
--animal-primary: #19c8b9;
|
|
1213
|
+
--animal-primary-hover: #3dd4c6;
|
|
1214
|
+
--animal-primary-active: #11a89b;
|
|
1215
|
+
--animal-primary-bg: #e6f9f6;
|
|
1216
|
+
|
|
1217
|
+
/* 文字 */
|
|
1218
|
+
--animal-text: #794f27;
|
|
1219
|
+
--animal-text-body: #725d42;
|
|
1220
|
+
--animal-text-secondary: #9f927d;
|
|
1221
|
+
--animal-text-muted: #8a7b66;
|
|
1222
|
+
--animal-text-disabled: #c4b89e;
|
|
1223
|
+
|
|
1224
|
+
/* 背景 */
|
|
1225
|
+
--animal-bg: #f8f8f0;
|
|
1226
|
+
--animal-bg-content: rgb(247, 243, 223);
|
|
1227
|
+
--animal-bg-disabled: #f0ece2;
|
|
1228
|
+
|
|
1229
|
+
/* 边框 */
|
|
1230
|
+
--animal-border: #c4b89e;
|
|
1231
|
+
--animal-border-hover: #a89878;
|
|
1232
|
+
|
|
1233
|
+
/* 圆角 */
|
|
1234
|
+
--animal-radius-sm: 12px;
|
|
1235
|
+
--animal-radius: 18px;
|
|
1236
|
+
--animal-radius-lg: 24px;
|
|
1237
|
+
--animal-radius-pill: 50px;
|
|
1238
|
+
|
|
1239
|
+
/* 3D 阴影 */
|
|
1240
|
+
--animal-shadow-btn: #bdaea0;
|
|
1241
|
+
--animal-shadow-input: #d4c9b4;
|
|
1242
|
+
--animal-shadow-switch: #5a9e1e;
|
|
1243
|
+
|
|
1244
|
+
/* 游戏特殊色 */
|
|
1245
|
+
--animal-focus-yellow: #ffcc00;
|
|
1246
|
+
--animal-focus-yellow-d: #e0b800;
|
|
1247
|
+
--animal-sidebar-active: #B7C6E5;
|
|
1248
|
+
--animal-sidebar-hover: #d6dff0;
|
|
1249
|
+
|
|
1250
|
+
/* 状态 */
|
|
1251
|
+
--animal-success: #6fba2c;
|
|
1252
|
+
--animal-warning: #f5c31c;
|
|
1253
|
+
--animal-error: #e05a5a;
|
|
1254
|
+
|
|
1255
|
+
/* 动效 */
|
|
1256
|
+
--animal-ease: cubic-bezier(0.4, 0, 0.2, 1);
|
|
1257
|
+
--animal-duration-fast: 0.15s;
|
|
1258
|
+
--animal-duration: 0.25s;
|
|
1259
|
+
--animal-duration-slow: 0.35s;
|
|
1260
|
+
}
|
|
1261
|
+
```
|
|
1262
|
+
|
|
1263
|
+
---
|
|
1264
|
+
|
|
1265
|
+
## 6. 7 条设计铁律
|
|
1266
|
+
|
|
1267
|
+
1. **颜色**:大地棕色系文字 + 薄荷青绿主色 + 奶油米白背景,禁止纯黑 / 冷灰
|
|
1268
|
+
2. **圆角**:最小 12px;按钮、输入框必须 50px pill 形
|
|
1269
|
+
3. **立体感**:所有可点击元素加底部厚阴影 `0 Npx 0 0 [暗色]`,hover 上浮,active 下压
|
|
1270
|
+
4. **字体**:Nunito(Google Fonts)圆体,按钮/标题 weight 600+,从不使用细体
|
|
1271
|
+
5. **动效**:过渡 0.15~0.35s,缓动 `cubic-bezier(0.4, 0, 0.2, 1)`,平滑不生硬
|
|
1272
|
+
6. **焦点**:输入框用黄色 `#ffcc00`,按钮用青绿 `#19c8b9`,绝不用蓝色
|
|
1273
|
+
7. **禁止**:直角矩形交互元素、纯黑文字 `#000`、冷蓝色调、扁平无阴影设计
|
|
1274
|
+
|
|
1275
|
+
---
|
|
1276
|
+
|
|
1277
|
+
## 7. 新组件文件结构模板
|
|
1278
|
+
|
|
1279
|
+
```
|
|
1280
|
+
src/components/MyComponent/
|
|
1281
|
+
├── MyComponent.tsx # 组件逻辑(必须设置 displayName)
|
|
1282
|
+
├── myComponent.module.less # CSS Modules 样式
|
|
1283
|
+
└── index.ts # 统一导出
|
|
1284
|
+
```
|
|
1285
|
+
|
|
1286
|
+
`src/index.ts` 追加:
|
|
1287
|
+
```ts
|
|
1288
|
+
// 方式 A:组件用 default export
|
|
1289
|
+
export { default as MyComponent } from './components/MyComponent'
|
|
1290
|
+
export type { MyComponentProps } from './components/MyComponent/MyComponent'
|
|
1291
|
+
|
|
1292
|
+
// 方式 B:组件用 named export(如 Checkbox / CodeBlock / Select / Icon / Tabs 当前采用)
|
|
1293
|
+
export { MyComponent } from './components/MyComponent'
|
|
1294
|
+
export type { MyComponentProps } from './components/MyComponent'
|
|
1295
|
+
```
|
|
1296
|
+
> 仓库内两种风格并存;新增组件选一种即可,只要 `src/index.ts` 能成功 re-export。
|
|
1297
|
+
|
|
1298
|
+
Less 模板(直接使用设计 token):
|
|
1299
|
+
|
|
1300
|
+
```less
|
|
1301
|
+
@import '../../styles/variables.less';
|
|
1302
|
+
|
|
1303
|
+
.container {
|
|
1304
|
+
background: @bg-color-content; // rgb(247,243,223)
|
|
1305
|
+
color: @text-color-body; // #725d42
|
|
1306
|
+
border: @border-width solid @border-color-light; // 2px solid #c4b89e
|
|
1307
|
+
border-radius: @border-radius-base; // 18px
|
|
1308
|
+
font-family: @font-family;
|
|
1309
|
+
font-weight: 500;
|
|
1310
|
+
letter-spacing: 0.01em;
|
|
1311
|
+
transition: all @motion-duration-base @motion-ease;
|
|
1312
|
+
box-shadow: 0 3px 0 0 @shadow-input; // #d4c9b4
|
|
1313
|
+
|
|
1314
|
+
&:hover:not(.disabled) {
|
|
1315
|
+
border-color: @border-color-hover; // #a89878
|
|
1316
|
+
transform: translateY(-1px);
|
|
1317
|
+
box-shadow: 0 4px 0 0 @shadow-input;
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
&:focus-within {
|
|
1321
|
+
border-color: @focus-yellow; // #ffcc00
|
|
1322
|
+
box-shadow: 0 3px 0 0 @focus-yellow-dark,
|
|
1323
|
+
0 0 0 3px rgba(255, 204, 0, 0.15);
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
&.disabled {
|
|
1327
|
+
opacity: 0.6;
|
|
1328
|
+
cursor: not-allowed;
|
|
1329
|
+
background: @bg-color-disabled;
|
|
1330
|
+
color: @text-color-disabled;
|
|
1331
|
+
border-color: @shadow-input;
|
|
1332
|
+
box-shadow: none;
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
```
|
|
1336
|
+
|
|
1337
|
+
TSX 模板:
|
|
1338
|
+
|
|
1339
|
+
```tsx
|
|
1340
|
+
import React from 'react'
|
|
1341
|
+
import styles from './myComponent.module.less'
|
|
1342
|
+
import classNames from 'classnames'
|
|
1343
|
+
|
|
1344
|
+
export interface MyComponentProps {
|
|
1345
|
+
/** 尺寸 */
|
|
1346
|
+
size?: 'small' | 'middle' | 'large'
|
|
1347
|
+
/** 禁用 */
|
|
1348
|
+
disabled?: boolean
|
|
1349
|
+
/** 子元素 */
|
|
1350
|
+
children?: React.ReactNode
|
|
1351
|
+
/** 自定义类名 */
|
|
1352
|
+
className?: string
|
|
1353
|
+
/** 自定义样式 */
|
|
1354
|
+
style?: React.CSSProperties
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
const MyComponent: React.FC<MyComponentProps> = ({
|
|
1358
|
+
size = 'middle',
|
|
1359
|
+
disabled = false,
|
|
1360
|
+
children,
|
|
1361
|
+
className,
|
|
1362
|
+
style,
|
|
1363
|
+
}) => {
|
|
1364
|
+
const cls = classNames(
|
|
1365
|
+
styles.container,
|
|
1366
|
+
styles[size],
|
|
1367
|
+
{ [styles.disabled]: disabled },
|
|
1368
|
+
className
|
|
1369
|
+
)
|
|
1370
|
+
|
|
1371
|
+
return (
|
|
1372
|
+
<div className={cls} style={style}>
|
|
1373
|
+
{children}
|
|
1374
|
+
</div>
|
|
1375
|
+
)
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
MyComponent.displayName = 'MyComponent'
|
|
1379
|
+
export default MyComponent
|
|
1380
|
+
```
|
|
1381
|
+
|
|
1382
|
+
---
|
|
1383
|
+
|
|
1384
|
+
## 8. Demo 页面规范
|
|
1385
|
+
|
|
1386
|
+
每个组件在 `demo/components/<ComponentName>/index.tsx` 创建演示页:
|
|
1387
|
+
|
|
1388
|
+
```tsx
|
|
1389
|
+
import { CodeBlock, ApiTable } from '../../tools'
|
|
1390
|
+
|
|
1391
|
+
const props = [
|
|
1392
|
+
{ name: 'size', type: "'small' | 'middle' | 'large'", default: "'middle'", description: '尺寸' },
|
|
1393
|
+
]
|
|
1394
|
+
|
|
1395
|
+
export default function MyComponentDemo() {
|
|
1396
|
+
return (
|
|
1397
|
+
<div>
|
|
1398
|
+
<h2>MyComponent</h2>
|
|
1399
|
+
<CodeBlock code={`<MyComponent size="large">内容</MyComponent>`} />
|
|
1400
|
+
<ApiTable data={props} />
|
|
1401
|
+
</div>
|
|
1402
|
+
)
|
|
1403
|
+
}
|
|
1404
|
+
```
|
|
1405
|
+
|
|
1406
|
+
并在 `demo/ComponentPage.tsx` 中注册路由,同时把 `title / desc` 写入 `demo/pageInfo.ts`:
|
|
1407
|
+
|
|
1408
|
+
```ts
|
|
1409
|
+
// demo/pageInfo.ts — 供 App 静态导入的轻量元信息
|
|
1410
|
+
export const PAGE_INFO: Record<string, { title: string; desc: string }> = {
|
|
1411
|
+
button: { title: 'Button 按钮', desc: '...' },
|
|
1412
|
+
input: { title: 'Input 输入框', desc: '...' },
|
|
1413
|
+
switch: { title: 'Switch 开关', desc: '...' },
|
|
1414
|
+
card: { title: 'Card 卡片', desc: '...' },
|
|
1415
|
+
collapse: { title: 'Collapse 折叠面板', desc: '...' },
|
|
1416
|
+
cursor: { title: 'Cursor 光标', desc: '...' },
|
|
1417
|
+
time: { title: 'Time 时间', desc: '...' },
|
|
1418
|
+
phone: { title: 'Phone 手机', desc: '...' },
|
|
1419
|
+
footer: { title: 'Footer 底部装饰', desc: '...' },
|
|
1420
|
+
modal: { title: 'Modal 弹窗', desc: '...' },
|
|
1421
|
+
typewriter: { title: 'Typewriter 打字机', desc: '...' },
|
|
1422
|
+
'divider-comp': { title: 'Divider 分割线', desc: '...' },
|
|
1423
|
+
icon: { title: 'Icon 图标', desc: '...' },
|
|
1424
|
+
select: { title: 'Select 选择器', desc: '...' },
|
|
1425
|
+
checkbox: { title: 'Checkbox 多选框', desc: '...' },
|
|
1426
|
+
codeblock: { title: 'CodeBlock 代码高亮', desc: '...' },
|
|
1427
|
+
}
|
|
1428
|
+
```
|
|
1429
|
+
|
|
1430
|
+
新增组件务必追加对应条目,否则 Demo 侧栏不会展示。
|
|
1431
|
+
|
|
1432
|
+
---
|
|
1433
|
+
|
|
1434
|
+
## 9. 新增组件 Checklist
|
|
1435
|
+
|
|
1436
|
+
- [ ] Google Fonts 已在 `index.html` 或样式入口引入(Nunito + Noto Sans SC + Zen Maru Gothic)
|
|
1437
|
+
- [ ] Props interface 从组件文件导出
|
|
1438
|
+
- [ ] 所有 props 有 JSDoc 注释(中文 OK)
|
|
1439
|
+
- [ ] 有状态组件同时支持受控(`value`)和非受控(`defaultValue`)模式
|
|
1440
|
+
- [ ] `disabled` 状态:cursor: not-allowed + opacity 0.5~0.6 + 移除阴影
|
|
1441
|
+
- [ ] 颜色优先引用 `variables.less` token,避免硬编码 hex
|
|
1442
|
+
- [ ] 阴影使用暖色调(`#bdaea0` / `#d4c9b4` / `rgba(61,52,40,...)`),非冷黑
|
|
1443
|
+
- [ ] hover 时 `translateY(-1px 或 -4px)` + 阴影加深
|
|
1444
|
+
- [ ] active 时 `translateY(2px)` + 阴影减小
|
|
1445
|
+
- [ ] 焦点:输入类用 `#ffcc00`,按钮类用 `#19c8b9`
|
|
1446
|
+
- [ ] 动画使用 `@motion-duration-*` 和 `@motion-ease` token
|
|
1447
|
+
- [ ] 组件从 `src/index.ts` 导出
|
|
1448
|
+
- [ ] Demo 页创建于 `demo/components/`
|
|
1449
|
+
- [ ] Demo 在 `demo/ComponentPage.tsx` 中注册
|
|
1450
|
+
- [ ] `demo/pageInfo.ts` 追加 `{ title, desc }` 元信息
|