Compare commits
31 Commits
ee719d07cc
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25eb3276f9 | ||
| 9cb1bf5c70 | |||
|
|
d42a4135f8 | ||
| 4bd1f3a2f0 | |||
| f9cabfb7c7 | |||
| 77fc031f4a | |||
| 971e0f0d68 | |||
| 39fd2c2428 | |||
| 6c398add3f | |||
| bd00cbafd0 | |||
| 62763a538f | |||
| a90b5e8c51 | |||
| 7c29d0479e | |||
| 7cdc1eb31b | |||
| ea3e683900 | |||
| fb11a1d365 | |||
| 47dcdabc35 | |||
| 89dacb708f | |||
| 34e05c6dc0 | |||
| a41e12500d | |||
| 20eb9388c3 | |||
| cc9bbd07cc | |||
| a3126d3e7e | |||
| f46cf75aec | |||
| 5a69e68e40 | |||
|
|
3237ef8271 | ||
| be6d4f7b48 | |||
| 54a0ca8058 | |||
| ed5d7f32a5 | |||
| 3e4f4eeb07 | |||
| 8992d360b6 |
@@ -31,13 +31,14 @@
|
||||
└── .memory/
|
||||
```
|
||||
|
||||
## 已写入 Figma Drafts(slim 模式 43 个)
|
||||
## 已写入 Figma Drafts(最终 88 个文件 key,47/56 套)
|
||||
|
||||
- W1 测试 1 个(手动 open)+ 42 个 slim 批量
|
||||
- **W37 Daily UI**:30 天的 kit 只入了第 1 天("Day 03 - Videos Website Landing"),其他 29 天本地 `extracted/W37/` 保留
|
||||
- W5 Wiloa 全 4 变体(Hotel/Plant/Restaurant/Travel)
|
||||
- W56 Orabel 全 6 页(Home/About/Portfolio/Blog/Contact/Open Menu)
|
||||
- 其他 32 个 template 各 1 个 fig
|
||||
- 35 套 `.fig` 原生全上云
|
||||
- 12 套 `.sketch` 经 Figma 自动转换上云
|
||||
- **W37 Daily UI 30 天全部上云**(30 个 variants,modal 8 行折行 tabs)
|
||||
- W5 Wiloa 4 变体 / W12 Premise 2 变体 / W36 AppStarter 4 变体 / W56 Orabel 6 页 全部多变体 tab 切换
|
||||
- 9 套 XD/PSD 只本地保留(Figma Import 不收 .xd/.psd)
|
||||
- 有 8 个重复 fileKey(Playwright 崩溃 + Figma 自动重试导致),API 403 删不了,需手动 Drafts 页删
|
||||
|
||||
## 非 Figma 原生的 21 套(已搁置)
|
||||
|
||||
|
||||
221
.memory/worklog.json
Normal file
221
.memory/worklog.json
Normal file
@@ -0,0 +1,221 @@
|
||||
{
|
||||
"entries": [
|
||||
{
|
||||
"ts": "2026-04-22T15:31:45+08:00",
|
||||
"type": "commit",
|
||||
"message": "feat: 初始化 Figma 模板库 56 套展示站",
|
||||
"hash": "ee719d0",
|
||||
"files_changed": 289
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T15:35:22+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 15:35 (+1)",
|
||||
"hash": "8992d36",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T15:40:52+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 15:40 (~1)",
|
||||
"hash": "3e4f4ee",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T15:46:22+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 15:46 (~1)",
|
||||
"hash": "ed5d7f3",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T15:51:52+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 15:51 (~1)",
|
||||
"hash": "54a0ca8",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T15:57:23+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 15:57 (~2)",
|
||||
"hash": "be6d4f7",
|
||||
"files_changed": 2
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T15:58:06+08:00",
|
||||
"type": "commit",
|
||||
"message": "feat: 12 套 Sketch 也上 Figma,47/47 模板全部投射就位",
|
||||
"hash": "3237ef8",
|
||||
"files_changed": 3
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T16:02:53+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 16:02 (~1)",
|
||||
"hash": "5a69e68",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T16:08:22+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 16:08 (~1)",
|
||||
"hash": "f46cf75",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T16:13:52+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 16:13 (~1)",
|
||||
"hash": "a3126d3",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T16:19:21+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 16:19 (~1)",
|
||||
"hash": "cc9bbd0",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T16:24:51+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 16:24 (~1)",
|
||||
"hash": "20eb938",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T16:30:21+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 16:30 (~1)",
|
||||
"hash": "a41e125",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T16:35:50+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 16:35 (~1)",
|
||||
"hash": "34e05c6",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T16:41:21+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 16:41 (~1)",
|
||||
"hash": "89dacb7",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T16:46:51+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 16:46 (~6)",
|
||||
"hash": "47dcdab",
|
||||
"files_changed": 6
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T16:52:21+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 16:52 (~1)",
|
||||
"hash": "fb11a1d",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T16:57:50+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 16:57 (~1)",
|
||||
"hash": "ea3e683",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T17:03:20+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 17:03 (~1)",
|
||||
"hash": "7cdc1eb",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T17:08:49+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 17:08 (+1, ~1)",
|
||||
"hash": "7c29d04",
|
||||
"files_changed": 2
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T17:14:19+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 17:14 (~1)",
|
||||
"hash": "a90b5e8",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T17:19:51+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 17:19 (~1)",
|
||||
"hash": "62763a5",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T17:25:21+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 17:25 (~1)",
|
||||
"hash": "bd00cba",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T17:31:01+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 17:30 (~1)",
|
||||
"hash": "6c398ad",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T17:36:31+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 17:36 (~1)",
|
||||
"hash": "39fd2c2",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T17:42:01+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 17:41 (~1)",
|
||||
"hash": "971e0f0",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T17:47:31+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 17:47 (~1)",
|
||||
"hash": "77fc031",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T17:53:02+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 17:52 (~1)",
|
||||
"hash": "f9cabfb",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T17:58:32+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 17:58 (~1)",
|
||||
"hash": "4bd1f3a",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T18:02:30+08:00",
|
||||
"type": "commit",
|
||||
"message": "feat: W37 DailyUI 30 天全上云 + 多变体 tab",
|
||||
"hash": "d42a413",
|
||||
"files_changed": 4
|
||||
},
|
||||
{
|
||||
"ts": "2026-04-22T18:04:02+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-04-22 18:03 (~1)",
|
||||
"hash": "9cb1bf5",
|
||||
"files_changed": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
23
.project.json
Normal file
23
.project.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"created" : "2026-04-22",
|
||||
"name" : "figma模板库",
|
||||
"ownership" : "personal",
|
||||
"pin_order" : 1776848911,
|
||||
"pinned" : true,
|
||||
"status" : "new",
|
||||
"urls" : [
|
||||
{
|
||||
"label" : "git",
|
||||
"type" : "repo",
|
||||
"url" : "https:\/\/git.kang-kang.com\/kangwan\/figma-templates-showcase"
|
||||
},
|
||||
{
|
||||
"label" : "figma-lib",
|
||||
"type" : "app",
|
||||
"url" : "https:\/\/figma-lib.kang-kang.com"
|
||||
}
|
||||
],
|
||||
"worklog" : {
|
||||
"path" : "\/Users\/kangwan\/Projects\/research\/20260422-figma模板库\/.memory\/worklog.json"
|
||||
}
|
||||
}
|
||||
379
figma-files.json
379
figma-files.json
@@ -1 +1,378 @@
|
||||
[{"key":"CLZepne3voPYx198q3wUHO","name":"Bright Kit"},{"key":"LA2daTQaigGkMUUNgPr6fp","name":"AKASHA-PAGEBUILDING-KIT"},{"key":"tLnL0G13yvkQtBZeQmPeq5","name":"06 Open Menu - Orabel Web UI Kit"},{"key":"bCrGhKu5PwOZh4F2EbyLk8","name":"05 Contact - Orabel Web UI Kit"},{"key":"Dc4uWhUeLCC6f2wiblXiBa","name":"04 Blog - Orabel Web UI Kit"},{"key":"BOnT7oN2pavJlDCdAO9Yih","name":"03 Portfolio - Orabel Web UI Kit"},{"key":"AEZMbGAy5IfnDAkFrbYwB6","name":"02 About - Orabel Web UI Kit"},{"key":"IoQBzPjHw51WjFKL52kJKN","name":"01 Home - Orabel Web UI Kit"},{"key":"IpdxPbiWuGZQpr3aNXsVpC","name":"Fecca"},{"key":"vcb4bLF79NTpybgXvAtkNM","name":"GETPAY - FINANCE TEMPLATES DESIGN"},{"key":"pMjAEiLKAFE57eaI4f4vva","name":"Aset - skill Shoot"},{"key":"U4YDJ7B0Sefem9r8LiEs8b","name":"Ui8_RealStatic_Static Mania"},{"key":"KtGIx2vrYNtApMiPYCTiiB","name":"Quicker Design system"},{"key":"3rhRDK0NC4oniMRGLNGnte","name":"WILOA - TRAVEL"},{"key":"1zIi1k19ngpoGixSB3upum","name":"WILOA - RESTAURANT"},{"key":"lv1hy5bS3Wx86slIXgorFn","name":"WILOA - PLANT"},{"key":"7C3QNOG6FhBRguT3nQ3dzf","name":"WILOA - HOTEL"},{"key":"df0oLsZta06a79s5iepJdF","name":"LANDINGKUY - Landing Page Design"},{"key":"Suvu5K5DSKPngkMKRb01MK","name":"Real Estate SaaS Kit & Dashboard (UI8)"},{"key":"sHmAQQxmvRTIxOg8OgQQFG","name":"3 template Agency"},{"key":"oZ7a2aFNZ21bg128ixnB3k","name":"Wiredunk_Wireframe"},{"key":"huDsMAoVThpYnGAU9j8WVB","name":"Modularity"},{"key":"4OTPxx5sgN8eFJ3joudoVH","name":"MasterFlow_UI_Kit"},{"key":"uAcopfnDXakv7l5Jr6sMqG","name":"iotask"},{"key":"fL1KqwIS3OmHCsUwhgJusG","name":"Figmaland- UI Kit (Startup)"},{"key":"PJHgFt29Lyo3JwMKxa5Tsm","name":"04_DailyUI_Video_Landing_Website"},{"key":"RNRNDiF6gFcTCi6wJncvgv","name":"JackCreative"},{"key":"BfBzvqu4VK53iSD5fbKNAo","name":"Intirior Architecture web ui kit"},{"key":"RKIYTIOCADVsASHNxZ5tr2","name":"Social Media Dashboard - UI Kit"},{"key":"qFC0pVEHe9Toc2aJ2MgO32","name":"DevAgency - Web Ui Kits"},{"key":"khWI1rrgwj5702NilEcha2","name":"Sydney Oasis Hotel Websites"},{"key":"5CZLD5lcxxRQNE1QWjqbmP","name":"UXFlow Web Kit"},{"key":"dvPWtG7KaEWr895iCI0Ioy","name":"LOOMI"},{"key":"5R9tevOwnk4iJzU3jEjg0q","name":"Landing UI Kit"},{"key":"oyHlh6eh7TjxYhCUbFTvBS","name":"Jobhuntly - Job Board & Portal UI Kit"},{"key":"G4mWQN0IWGkAKpD7Ga0bG3","name":"Core - Dashboard Builder"},{"key":"Sarco9c50gDttu37szmurE","name":"Webflew Agency UI Kit"},{"key":"x3g1FivshKeZ9PwccE7w3w","name":"Core - Dashboard Builder"},{"key":"fsufV596UmcNyM8yfCYlAr","name":"Eco -Ecommerce Analytics Admin Dashboard"},{"key":"s5KbowY6N6M4IkjHbgLjOc","name":"Figmaland-UI MAX ( ui8 )"},{"key":"ms5OYBa3fRlDwRmSLWWorY","name":"Online Shop UI Kit"},{"key":"pxsKzhDM8UL8oTSB4hUpOZ","name":"saascuy"},{"key":"EKp3ZDo2A3kDp88DMvFqte","name":"Havoc Agency UI Kit"}]
|
||||
[
|
||||
{
|
||||
"key": "CLZepne3voPYx198q3wUHO",
|
||||
"name": "Bright Kit"
|
||||
},
|
||||
{
|
||||
"key": "LA2daTQaigGkMUUNgPr6fp",
|
||||
"name": "AKASHA-PAGEBUILDING-KIT"
|
||||
},
|
||||
{
|
||||
"key": "tLnL0G13yvkQtBZeQmPeq5",
|
||||
"name": "06 Open Menu - Orabel Web UI Kit"
|
||||
},
|
||||
{
|
||||
"key": "bCrGhKu5PwOZh4F2EbyLk8",
|
||||
"name": "05 Contact - Orabel Web UI Kit"
|
||||
},
|
||||
{
|
||||
"key": "Dc4uWhUeLCC6f2wiblXiBa",
|
||||
"name": "04 Blog - Orabel Web UI Kit"
|
||||
},
|
||||
{
|
||||
"key": "BOnT7oN2pavJlDCdAO9Yih",
|
||||
"name": "03 Portfolio - Orabel Web UI Kit"
|
||||
},
|
||||
{
|
||||
"key": "AEZMbGAy5IfnDAkFrbYwB6",
|
||||
"name": "02 About - Orabel Web UI Kit"
|
||||
},
|
||||
{
|
||||
"key": "IoQBzPjHw51WjFKL52kJKN",
|
||||
"name": "01 Home - Orabel Web UI Kit"
|
||||
},
|
||||
{
|
||||
"key": "IpdxPbiWuGZQpr3aNXsVpC",
|
||||
"name": "Fecca"
|
||||
},
|
||||
{
|
||||
"key": "vcb4bLF79NTpybgXvAtkNM",
|
||||
"name": "GETPAY - FINANCE TEMPLATES DESIGN"
|
||||
},
|
||||
{
|
||||
"key": "pMjAEiLKAFE57eaI4f4vva",
|
||||
"name": "Aset - skill Shoot"
|
||||
},
|
||||
{
|
||||
"key": "U4YDJ7B0Sefem9r8LiEs8b",
|
||||
"name": "Ui8_RealStatic_Static Mania"
|
||||
},
|
||||
{
|
||||
"key": "KtGIx2vrYNtApMiPYCTiiB",
|
||||
"name": "Quicker Design system"
|
||||
},
|
||||
{
|
||||
"key": "3rhRDK0NC4oniMRGLNGnte",
|
||||
"name": "WILOA - TRAVEL"
|
||||
},
|
||||
{
|
||||
"key": "1zIi1k19ngpoGixSB3upum",
|
||||
"name": "WILOA - RESTAURANT"
|
||||
},
|
||||
{
|
||||
"key": "lv1hy5bS3Wx86slIXgorFn",
|
||||
"name": "WILOA - PLANT"
|
||||
},
|
||||
{
|
||||
"key": "7C3QNOG6FhBRguT3nQ3dzf",
|
||||
"name": "WILOA - HOTEL"
|
||||
},
|
||||
{
|
||||
"key": "df0oLsZta06a79s5iepJdF",
|
||||
"name": "LANDINGKUY - Landing Page Design"
|
||||
},
|
||||
{
|
||||
"key": "Suvu5K5DSKPngkMKRb01MK",
|
||||
"name": "Real Estate SaaS Kit & Dashboard (UI8)"
|
||||
},
|
||||
{
|
||||
"key": "sHmAQQxmvRTIxOg8OgQQFG",
|
||||
"name": "3 template Agency"
|
||||
},
|
||||
{
|
||||
"key": "oZ7a2aFNZ21bg128ixnB3k",
|
||||
"name": "Wiredunk_Wireframe"
|
||||
},
|
||||
{
|
||||
"key": "huDsMAoVThpYnGAU9j8WVB",
|
||||
"name": "Modularity"
|
||||
},
|
||||
{
|
||||
"key": "4OTPxx5sgN8eFJ3joudoVH",
|
||||
"name": "MasterFlow_UI_Kit"
|
||||
},
|
||||
{
|
||||
"key": "uAcopfnDXakv7l5Jr6sMqG",
|
||||
"name": "iotask"
|
||||
},
|
||||
{
|
||||
"key": "fL1KqwIS3OmHCsUwhgJusG",
|
||||
"name": "Figmaland- UI Kit (Startup)"
|
||||
},
|
||||
{
|
||||
"key": "PJHgFt29Lyo3JwMKxa5Tsm",
|
||||
"name": "04_DailyUI_Video_Landing_Website"
|
||||
},
|
||||
{
|
||||
"key": "RNRNDiF6gFcTCi6wJncvgv",
|
||||
"name": "JackCreative"
|
||||
},
|
||||
{
|
||||
"key": "BfBzvqu4VK53iSD5fbKNAo",
|
||||
"name": "Intirior Architecture web ui kit"
|
||||
},
|
||||
{
|
||||
"key": "RKIYTIOCADVsASHNxZ5tr2",
|
||||
"name": "Social Media Dashboard - UI Kit"
|
||||
},
|
||||
{
|
||||
"key": "qFC0pVEHe9Toc2aJ2MgO32",
|
||||
"name": "DevAgency - Web Ui Kits"
|
||||
},
|
||||
{
|
||||
"key": "khWI1rrgwj5702NilEcha2",
|
||||
"name": "Sydney Oasis Hotel Websites"
|
||||
},
|
||||
{
|
||||
"key": "5CZLD5lcxxRQNE1QWjqbmP",
|
||||
"name": "UXFlow Web Kit"
|
||||
},
|
||||
{
|
||||
"key": "dvPWtG7KaEWr895iCI0Ioy",
|
||||
"name": "LOOMI"
|
||||
},
|
||||
{
|
||||
"key": "5R9tevOwnk4iJzU3jEjg0q",
|
||||
"name": "Landing UI Kit"
|
||||
},
|
||||
{
|
||||
"key": "oyHlh6eh7TjxYhCUbFTvBS",
|
||||
"name": "Jobhuntly - Job Board & Portal UI Kit"
|
||||
},
|
||||
{
|
||||
"key": "G4mWQN0IWGkAKpD7Ga0bG3",
|
||||
"name": "Core - Dashboard Builder"
|
||||
},
|
||||
{
|
||||
"key": "Sarco9c50gDttu37szmurE",
|
||||
"name": "Webflew Agency UI Kit"
|
||||
},
|
||||
{
|
||||
"key": "x3g1FivshKeZ9PwccE7w3w",
|
||||
"name": "Core - Dashboard Builder"
|
||||
},
|
||||
{
|
||||
"key": "fsufV596UmcNyM8yfCYlAr",
|
||||
"name": "Eco -Ecommerce Analytics Admin Dashboard"
|
||||
},
|
||||
{
|
||||
"key": "s5KbowY6N6M4IkjHbgLjOc",
|
||||
"name": "Figmaland-UI MAX ( ui8 )"
|
||||
},
|
||||
{
|
||||
"key": "ms5OYBa3fRlDwRmSLWWorY",
|
||||
"name": "Online Shop UI Kit"
|
||||
},
|
||||
{
|
||||
"key": "pxsKzhDM8UL8oTSB4hUpOZ",
|
||||
"name": "saascuy"
|
||||
},
|
||||
{
|
||||
"key": "EKp3ZDo2A3kDp88DMvFqte",
|
||||
"name": "Havoc Agency UI Kit"
|
||||
},
|
||||
{
|
||||
"key": "yfsZXkLQbiWwQW9C2fwyDW",
|
||||
"name": "UI KIT Desktop - Froots"
|
||||
},
|
||||
{
|
||||
"key": "V6qWYeL6Hr5QA5Jz9rDmc7",
|
||||
"name": "Grocery Delivery Landing Page"
|
||||
},
|
||||
{
|
||||
"key": "m7bMqyeFaaO8XG8JqZYUu2",
|
||||
"name": "AppStarter"
|
||||
},
|
||||
{
|
||||
"key": "R0U9H8KEfOJdYPVZRMmLK6",
|
||||
"name": "AppStarter (Wireframe)"
|
||||
},
|
||||
{
|
||||
"key": "qhPf33kALID79IthiURFfK",
|
||||
"name": "AppStarter Sample"
|
||||
},
|
||||
{
|
||||
"key": "4lPiQwfUnlIh2cRvqFabSn",
|
||||
"name": "AppStarter Sample (Wireframe)"
|
||||
},
|
||||
{
|
||||
"key": "8Yk0Nw1JK1mLGBmAIhAVXR",
|
||||
"name": "Modularity"
|
||||
},
|
||||
{
|
||||
"key": "AcNy87P0xlqDvkeeBqrQpO",
|
||||
"name": "Rybble TM"
|
||||
},
|
||||
{
|
||||
"key": "L36XI3mBCDOi4IPN0d96wT",
|
||||
"name": "UI KIT Desktop - Froots"
|
||||
},
|
||||
{
|
||||
"key": "aSoBMXGcW9HxhyYpYGPxG1",
|
||||
"name": "AppStarter"
|
||||
},
|
||||
{
|
||||
"key": "ZqXrYPRqcVCWM9bwrlTKnd",
|
||||
"name": "AppStarter (Wireframe)"
|
||||
},
|
||||
{
|
||||
"key": "EffYROARIAH0I2PB3oy1HG",
|
||||
"name": "AppStarter Sample"
|
||||
},
|
||||
{
|
||||
"key": "zzWXoSvmdRvo4TmrAdqjXl",
|
||||
"name": "AppStarter Sample (Wireframe)"
|
||||
},
|
||||
{
|
||||
"key": "GgDyX8yYgCNzhMUNsPTBSH",
|
||||
"name": "Rybble TM"
|
||||
},
|
||||
{
|
||||
"key": "yIhPCq93LSUkzrJUVQjU1r",
|
||||
"name": "Omega"
|
||||
},
|
||||
{
|
||||
"key": "SYINzgEkzGIwZF15AvuDcn",
|
||||
"name": "Login_page_2020"
|
||||
},
|
||||
{
|
||||
"key": "crK1Yhtws6yWkBKcN1OCqB",
|
||||
"name": "Kovid Flew"
|
||||
},
|
||||
{
|
||||
"key": "byZYVoOiuEEtSMjH7JxcQO",
|
||||
"name": "Elemento-UI-Kit"
|
||||
},
|
||||
{
|
||||
"key": "dM5zUotUlacnEPU9Oo0RcJ",
|
||||
"name": "Sketch File"
|
||||
},
|
||||
{
|
||||
"key": "pEKy0RBAp93TLIDlnoTsFi",
|
||||
"name": "LIGHT:DESKTOP - Premise Landing Page Wireframe Kit - Jamie Syke"
|
||||
},
|
||||
{
|
||||
"key": "RCAZWKHkrBzwikzpBCebMz",
|
||||
"name": "DARK:DESKTOP - Premise Landing Page Wireframe Kit - Jamie Syke"
|
||||
},
|
||||
{
|
||||
"key": "IGfS4r69yANQazOxLSjnyQ",
|
||||
"name": "yoyolabs-Limitless-for-Web-file"
|
||||
},
|
||||
{
|
||||
"key": "IdA0ICXerQVBhYUfjXGL1H",
|
||||
"name": "02_DailyUI - Discover Mountain Tour"
|
||||
},
|
||||
{
|
||||
"key": "eVqhxYBPehYLPEGTCRipyW",
|
||||
"name": "02_DailyUI - Coffee Shop Subscription Website Landing"
|
||||
},
|
||||
{
|
||||
"key": "r0qplmCsBONsRIIDavwYF3",
|
||||
"name": "02_DailyUI - Coffee Shop Website Landing"
|
||||
},
|
||||
{
|
||||
"key": "0fNvQCQqC8KbFaquti76RM",
|
||||
"name": "04_DailyUI - Coffee Shop Website Landing"
|
||||
},
|
||||
{
|
||||
"key": "8yrmXShwcW73BB3cx1RzUO",
|
||||
"name": "04_DailyUI - Coffee Shop Website Landing"
|
||||
},
|
||||
{
|
||||
"key": "wppvrY7Zkept7rFW8BSEJv",
|
||||
"name": "04_DailyUI - Product Page Website Landing"
|
||||
},
|
||||
{
|
||||
"key": "eLgBq75wWJQFA4cnyCv6I5",
|
||||
"name": "04_DailyUI - Preloved Electronic Ecommerce Website Landing"
|
||||
},
|
||||
{
|
||||
"key": "hHHcJtfuhLAdrMLTAlF5Ba",
|
||||
"name": "04_DailyUI - Crypto Trading App Website Landing"
|
||||
},
|
||||
{
|
||||
"key": "3Bs5YdV3g3jOgqAOVv7IOW",
|
||||
"name": "04_DailyUI - Creative Digital Agency Website"
|
||||
},
|
||||
{
|
||||
"key": "z669xSruU8CdphtgLhRjcO",
|
||||
"name": "04_DailyUI - Technology Blog News Website UI"
|
||||
},
|
||||
{
|
||||
"key": "0GK6JkzINs5VzztfvA73m2",
|
||||
"name": "04_DailyUI - Web Development Agency Website"
|
||||
},
|
||||
{
|
||||
"key": "DnblGVf6MKSfWi0wPj8KZc",
|
||||
"name": "04_DailyUI - Travel Tour Booking Website Landing"
|
||||
},
|
||||
{
|
||||
"key": "cWaRxvQvuam5z03BkeESwG",
|
||||
"name": "04_DailyUI - Nursery & Kids Furniture Product Sale"
|
||||
},
|
||||
{
|
||||
"key": "KaWKPHRdIJn5GiJabbwSzp",
|
||||
"name": "02_DailyUI - Dentist Service Appointment"
|
||||
},
|
||||
{
|
||||
"key": "9IEKPzpkUgZniVdnmC10Aw",
|
||||
"name": "03_DailyUI - Baby Fashion Landing"
|
||||
},
|
||||
{
|
||||
"key": "pB2abP5veEWUYLsf7HS9tF",
|
||||
"name": "03_DailyUI - Movie Streaming Landing"
|
||||
},
|
||||
{
|
||||
"key": "hvcfo3wknaJGqnjPBv9a0P",
|
||||
"name": "03_DailyUI - Female Boots Product Detail"
|
||||
},
|
||||
{
|
||||
"key": "sMyOUigPVBCqS1lt7YpIEV",
|
||||
"name": "03_DailyUI - Freelancer Hiring Website UI"
|
||||
},
|
||||
{
|
||||
"key": "oUvrAAeDBqoeFpRa2hh7Rc",
|
||||
"name": "03_DailyUI - Online Daily Catering Order"
|
||||
},
|
||||
{
|
||||
"key": "ZUA5LAN9mmwgckGYYov4Nx",
|
||||
"name": "03_DailyUI House Rental Booking"
|
||||
},
|
||||
{
|
||||
"key": "U8Ivq70rEJ0PfApY7UozDO",
|
||||
"name": "03_DailyUI_Bridal_Dress_Rent"
|
||||
},
|
||||
{
|
||||
"key": "oDTnlaSfecAEE7BwM1skE9",
|
||||
"name": "03_DailyUI_Bridal_Dress_Rent"
|
||||
},
|
||||
{
|
||||
"key": "4uZw8jE1RTmULcmfHUQaiq",
|
||||
"name": "03_DailyUI_Restaurant_Booking"
|
||||
},
|
||||
{
|
||||
"key": "0FrxkoqSlwBmCfUkyQcnFf",
|
||||
"name": "03_DailyUI_Series_Movie"
|
||||
},
|
||||
{
|
||||
"key": "5WPExo1H1neQp1JyIwqHeZ",
|
||||
"name": "04_DailyUI_Laptop_Product_Detail"
|
||||
},
|
||||
{
|
||||
"key": "wJgnKYmet4emAvRir9b9F7",
|
||||
"name": "02_DailyUI_Shoes_Shop"
|
||||
},
|
||||
{
|
||||
"key": "x0mb4vUi4NXV9ehkwiHVUt",
|
||||
"name": "04_MovieTime_DailyUI"
|
||||
},
|
||||
{
|
||||
"key": "nBqXtoL8mA0ei5R1v6UPqa",
|
||||
"name": "04_Gowezz_Bike_Product_Detail"
|
||||
},
|
||||
{
|
||||
"key": "0vZIEbrB7t4RUTVggvABZH",
|
||||
"name": "04_DailyUI_v4_UI_Workspace_Website"
|
||||
}
|
||||
]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -35,71 +35,77 @@ def main():
|
||||
sys.exit(1)
|
||||
figma_files = json.loads(figma_files_path.read_text()) # list of {key, name, ...}
|
||||
|
||||
# for each W template that has fig, find matching figma file
|
||||
# Match each template source file to ALL matching cloud files (supports multi-variant)
|
||||
matches = []
|
||||
used_keys = set()
|
||||
for t in manifest['templates']:
|
||||
if not t['fig']: continue
|
||||
# use the .fig file's stem as match target (closer than archive name)
|
||||
targets = [Path(f).stem for f in t['fig']]
|
||||
# add archive stem as backup
|
||||
if t.get('archive'):
|
||||
targets.append(Path(t['archive']).stem)
|
||||
targets.append(t['name'])
|
||||
# try each target
|
||||
best_overall = (0, None)
|
||||
for tgt in targets:
|
||||
score, cand = best_match(tgt, [f for f in figma_files if f['key'] not in used_keys])
|
||||
if score > best_overall[0]:
|
||||
best_overall = (score, cand)
|
||||
if score > 0.95:
|
||||
break
|
||||
score, cand = best_overall
|
||||
if cand and score >= 0.6:
|
||||
used_keys.add(cand['key'])
|
||||
matches.append({
|
||||
'W': t['id'], 'name': t['name'], 'fig_stem': Path(t['fig'][0]).stem if t['fig'] else None,
|
||||
'matched': cand['name'], 'key': cand['key'], 'score': round(score, 3)
|
||||
})
|
||||
else:
|
||||
matches.append({
|
||||
'W': t['id'], 'name': t['name'], 'fig_stem': Path(t['fig'][0]).stem if t['fig'] else None,
|
||||
'matched': None, 'best_score': round(best_overall[0], 3) if cand else 0,
|
||||
'best_candidate': cand['name'] if cand else None
|
||||
})
|
||||
source_files = t['fig'] if t['fig'] else t['sketch']
|
||||
if not source_files: continue
|
||||
kind = 'fig' if t['fig'] else 'sketch'
|
||||
variants = []
|
||||
for src in source_files:
|
||||
stem = Path(src).stem
|
||||
# Match this specific source stem to best unused cloud file
|
||||
score, cand = best_match(stem, [f for f in figma_files if f['key'] not in used_keys])
|
||||
if cand and score >= 0.6:
|
||||
used_keys.add(cand['key'])
|
||||
variants.append({
|
||||
'source_stem': stem,
|
||||
'matched': cand['name'],
|
||||
'key': cand['key'],
|
||||
'score': round(score, 3)
|
||||
})
|
||||
matches.append({
|
||||
'W': t['id'], 'name': t['name'], 'kind': kind,
|
||||
'source_count': len(source_files),
|
||||
'variants': variants,
|
||||
})
|
||||
|
||||
# Update web/data.json
|
||||
data_path = ROOT/'web'/'data.json'
|
||||
data = json.loads(data_path.read_text())
|
||||
by_W = {m['W']: m for m in matches if m.get('key')}
|
||||
by_W = {m['W']: m for m in matches}
|
||||
for t in data['templates']:
|
||||
m = by_W.get(t['id'])
|
||||
if m:
|
||||
t['figma_key'] = m['key']
|
||||
t['figma_url'] = f"https://www.figma.com/file/{m['key']}"
|
||||
if m and m['variants']:
|
||||
first = m['variants'][0]
|
||||
t['figma_key'] = first['key']
|
||||
t['figma_url'] = f"https://www.figma.com/file/{first['key']}"
|
||||
t['figma_variants'] = [
|
||||
{'name': v['source_stem'], 'matched': v['matched'], 'key': v['key'],
|
||||
'url': f"https://www.figma.com/file/{v['key']}"}
|
||||
for v in m['variants']
|
||||
]
|
||||
else:
|
||||
t['figma_key'] = None
|
||||
t['figma_url'] = None
|
||||
t['figma_variants'] = []
|
||||
|
||||
# update banner with imported count
|
||||
# update banner with imported count + variant total
|
||||
imported = sum(1 for t in data['templates'] if t['figma_key'])
|
||||
total_variants = sum(len(t.get('figma_variants', [])) for t in data['templates'])
|
||||
fig_cnt = sum(1 for t in manifest['templates'] if t['fig'])
|
||||
sketch_only_cnt = sum(1 for t in manifest['templates'] if not t['fig'] and t['sketch'])
|
||||
data['imported_summary'] = (
|
||||
f"✅ <b>{imported} 个 Figma 原生文件</b>已云端就位在你的 "
|
||||
f"<a href='https://www.figma.com/files/team/1304178887825899477/drafts' target='_blank'>Figma Drafts</a>。"
|
||||
f"点卡片打开 modal 查看 iframe 实时投射 + 跳 Figma 编辑。"
|
||||
f"✅ <b>{imported}/56 套</b>(共 {total_variants} 个文件)已云端就位在 "
|
||||
f"<a href='https://www.figma.com/files/team/1304178887825899477/drafts' target='_blank'>Figma Drafts</a>"
|
||||
f"({fig_cnt} .fig + {sketch_only_cnt} .sketch 转换)。"
|
||||
f"点卡片 → modal → 多变体 tab 切换 + iframe 实时投射。"
|
||||
)
|
||||
data_path.write_text(json.dumps(data, ensure_ascii=False, indent=2))
|
||||
|
||||
# write match report
|
||||
report = ROOT/'figma-match-report.json'
|
||||
report.write_text(json.dumps(matches, ensure_ascii=False, indent=2))
|
||||
print(f"Matched {imported}/{sum(1 for t in manifest['templates'] if t['fig'])} fig templates")
|
||||
total_matchable = sum(1 for t in manifest['templates'] if t['fig'] or t['sketch'])
|
||||
multi_variant = sum(1 for m in matches if len(m['variants']) > 1)
|
||||
print(f"Matched {imported}/{total_matchable} templates, {total_variants} total file keys, {multi_variant} with multi variants")
|
||||
print(f"Report: {report.relative_to(ROOT)}")
|
||||
unmatched = [m for m in matches if not m.get('key')]
|
||||
unmatched = [m for m in matches if not m['variants']]
|
||||
if unmatched:
|
||||
print(f"\n⚠️ {len(unmatched)} unmatched:")
|
||||
for m in unmatched:
|
||||
print(f" {m['W']:4s} {m['name'][:50]:50s} best='{m.get('best_candidate','')[:40]}' score={m.get('best_score',0)}")
|
||||
print(f" {m['W']:4s} {m['name'][:50]:50s}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
48
web/app.js
48
web/app.js
@@ -89,11 +89,28 @@ function openModal(id) {
|
||||
const t = DATA.templates.find(x => x.id === id);
|
||||
if (!t) return;
|
||||
const body = document.getElementById('modalBody');
|
||||
const figmaSection = t.figma_key
|
||||
? `<iframe class="figma-embed" src="https://embed.figma.com/design/${t.figma_key}/?embed-host=kang&footer=false" allowfullscreen></iframe>`
|
||||
const variants = t.figma_variants || (t.figma_key ? [{name: t.name, key: t.figma_key, url: t.figma_url}] : []);
|
||||
const hasMulti = variants.length > 1;
|
||||
|
||||
const tabsHtml = hasMulti
|
||||
? `<div class="variant-tabs" id="variantTabs">
|
||||
${variants.map((v, i) => `<button class="vtab ${i===0?'active':''}" data-idx="${i}">${escapeHtml(v.name || v.matched || `变体 ${i+1}`)}</button>`).join('')}
|
||||
</div>`
|
||||
: '';
|
||||
|
||||
const firstVariant = variants[0];
|
||||
const iframeHtml = firstVariant
|
||||
? `<iframe class="figma-embed" id="variantFrame" src="https://embed.figma.com/design/${firstVariant.key}/?embed-host=kang&footer=false" allowfullscreen></iframe>`
|
||||
: '';
|
||||
|
||||
const openBtn = firstVariant
|
||||
? `<a class="btn" id="variantOpenBtn" href="${firstVariant.url}" target="_blank">在 Figma 打开 →</a>`
|
||||
: (t.has_fig
|
||||
? `<a class="btn" href="https://www.figma.com/files/recent" target="_blank">在 Figma Drafts 搜 "${escapeAttr(t.name.split(/[\s\-–—]/)[0])}" →</a>`
|
||||
: '');
|
||||
|
||||
body.innerHTML = `
|
||||
<h2>${escapeHtml(t.name)}</h2>
|
||||
<h2>${escapeHtml(t.name)}${hasMulti ? ` <span class="vcount">${variants.length} 变体</span>` : ''}</h2>
|
||||
<div class="sub2">
|
||||
<code>${t.id}</code>
|
||||
<span>${t.archive_size_mb} MB</span>
|
||||
@@ -103,24 +120,35 @@ function openModal(id) {
|
||||
${t.has_psd ? `<span class="badge psd">PSD</span>` : ''}
|
||||
</div>
|
||||
<div class="actions">
|
||||
${t.figma_url
|
||||
? `<a class="btn" href="${t.figma_url}" target="_blank">在 Figma 打开 →</a>`
|
||||
: (t.has_fig
|
||||
? `<a class="btn" href="https://www.figma.com/files/recent" target="_blank">在 Figma Drafts 搜 "${escapeAttr(t.name.split(/[\s\-–—]/)[0])}" →</a>`
|
||||
: '')}
|
||||
${openBtn}
|
||||
<a class="btn ghost" href="${t.source_rel}" onclick="revealSource('${t.id}');return false;">在 Finder 中显示源包</a>
|
||||
<a class="btn ghost" href="javascript:void(0)" onclick="copyPath('${t.id}');">复制源文件路径</a>
|
||||
</div>
|
||||
${figmaSection}
|
||||
${tabsHtml}
|
||||
${iframeHtml}
|
||||
<div class="spec">
|
||||
<div class="k">源包</div><div class="v">source/${t.id}/${t.archive}</div>
|
||||
<div class="k">解压目录</div><div class="v">extracted/${t.id}/</div>
|
||||
${t.figma_key ? `<div class="k">Figma Key</div><div class="v">${t.figma_key}</div>` : ''}
|
||||
${firstVariant ? `<div class="k">Figma Key</div><div class="v" id="variantKey">${firstVariant.key}</div>` : ''}
|
||||
</div>
|
||||
<div class="gallery">
|
||||
${(t.gallery||[]).map(g => `<img src="${g}" loading="lazy">`).join('')}
|
||||
</div>
|
||||
`;
|
||||
|
||||
if (hasMulti) {
|
||||
document.getElementById('variantTabs').addEventListener('click', e => {
|
||||
const btn = e.target.closest('.vtab');
|
||||
if (!btn) return;
|
||||
const idx = +btn.dataset.idx;
|
||||
const v = variants[idx];
|
||||
document.querySelectorAll('.vtab').forEach(b => b.classList.toggle('active', b === btn));
|
||||
document.getElementById('variantFrame').src = `https://embed.figma.com/design/${v.key}/?embed-host=kang&footer=false`;
|
||||
document.getElementById('variantOpenBtn').href = v.url;
|
||||
document.getElementById('variantKey').textContent = v.key;
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('modal').hidden = false;
|
||||
document.body.style.overflow = 'hidden';
|
||||
}
|
||||
|
||||
769
web/data.json
769
web/data.json
File diff suppressed because it is too large
Load Diff
@@ -79,6 +79,12 @@ main{padding:32px 0 80px}
|
||||
.spec .v{color:var(--text);font-family:ui-monospace,monospace;font-size:12px;word-break:break-all}
|
||||
.figma-embed{width:100%;aspect-ratio:16/10;border:0;border-radius:10px;background:var(--panel2);margin-bottom:16px}
|
||||
|
||||
.modal-body h2 .vcount{display:inline-block;margin-left:8px;padding:2px 10px;background:rgba(107,92,255,.2);color:#b5bbf8;font-size:12px;font-weight:500;border-radius:999px;vertical-align:middle}
|
||||
.variant-tabs{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:12px;padding-bottom:12px;border-bottom:1px solid var(--line)}
|
||||
.vtab{background:var(--panel2);border:1px solid var(--line);color:var(--muted);padding:6px 12px;border-radius:8px;cursor:pointer;font-size:12px;transition:all .15s;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||||
.vtab:hover{color:var(--text);border-color:#3a3f55}
|
||||
.vtab.active{background:var(--brand);border-color:var(--brand);color:#fff}
|
||||
|
||||
/* FOOTER */
|
||||
footer{border-top:1px solid var(--line);padding:20px 0;color:var(--muted);font-size:12px}
|
||||
footer .wrap{display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap}
|
||||
|
||||
Reference in New Issue
Block a user