2026-10-14-freight-card-sample-collapse-demo.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
  6. <title>运费信息 · 列表卡片样本折叠 Demo</title>
  7. <style>
  8. :root {
  9. --primary: #0a9f6d;
  10. --primary-dark: #087f57;
  11. --primary-soft: #e9f9f2;
  12. --text: #18332a;
  13. --muted: #6b7c74;
  14. --border: #dce8e2;
  15. --surface: #fff;
  16. --page: #f3f6f5;
  17. --money: #c98312;
  18. }
  19. * { box-sizing: border-box; }
  20. body {
  21. margin: 0;
  22. font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", sans-serif;
  23. font-size: 14px;
  24. line-height: 1.5;
  25. color: var(--text);
  26. background: var(--page);
  27. }
  28. .page {
  29. max-width: 420px;
  30. margin: 0 auto;
  31. padding: 20px 14px 48px;
  32. }
  33. .hero {
  34. margin-bottom: 18px;
  35. }
  36. .hero h1 {
  37. margin: 0 0 6px;
  38. font-size: 20px;
  39. font-weight: 700;
  40. }
  41. .hero p {
  42. margin: 0;
  43. color: var(--muted);
  44. font-size: 13px;
  45. }
  46. .section-label {
  47. display: flex;
  48. align-items: center;
  49. justify-content: space-between;
  50. margin: 18px 0 8px;
  51. color: var(--muted);
  52. font-size: 12px;
  53. font-weight: 600;
  54. }
  55. .section-label em {
  56. font-style: normal;
  57. color: var(--primary-dark);
  58. background: var(--primary-soft);
  59. padding: 2px 8px;
  60. border-radius: 999px;
  61. }
  62. .card {
  63. padding: 14px;
  64. border: 1px solid var(--border);
  65. border-radius: 16px;
  66. background: var(--surface);
  67. box-shadow: 0 6px 20px rgb(8 127 87 / 7%);
  68. }
  69. .card + .card { margin-top: 12px; }
  70. .head {
  71. display: flex;
  72. align-items: center;
  73. gap: 10px;
  74. padding-bottom: 12px;
  75. border-bottom: 1px solid #eef4f1;
  76. }
  77. .index {
  78. display: grid;
  79. width: 30px;
  80. height: 30px;
  81. flex: 0 0 30px;
  82. place-items: center;
  83. border-radius: 50%;
  84. background: var(--primary-soft);
  85. color: var(--primary-dark);
  86. font-size: 13px;
  87. font-weight: 700;
  88. }
  89. .identity {
  90. min-width: 0;
  91. flex: 1;
  92. display: flex;
  93. flex-direction: column;
  94. gap: 3px;
  95. }
  96. .title {
  97. overflow: hidden;
  98. font-size: 16px;
  99. font-weight: 700;
  100. text-overflow: ellipsis;
  101. white-space: nowrap;
  102. }
  103. .subtitle {
  104. overflow: hidden;
  105. color: var(--muted);
  106. font-size: 12px;
  107. text-overflow: ellipsis;
  108. white-space: nowrap;
  109. }
  110. .tag {
  111. display: inline-flex;
  112. max-width: 128px;
  113. align-self: center;
  114. padding: 5px 12px;
  115. overflow: hidden;
  116. border-radius: 999px;
  117. background: var(--primary-soft);
  118. color: var(--primary-dark);
  119. font-size: 12px;
  120. line-height: 1.3;
  121. text-overflow: ellipsis;
  122. white-space: nowrap;
  123. }
  124. .tag.warn {
  125. background: #fff7e8;
  126. color: #b45309;
  127. }
  128. .fields {
  129. display: grid;
  130. grid-template-columns: repeat(2, minmax(0, 1fr));
  131. gap: 12px 16px;
  132. padding: 14px 0;
  133. }
  134. .field {
  135. display: flex;
  136. min-width: 0;
  137. flex-direction: column;
  138. gap: 4px;
  139. color: var(--muted);
  140. font-size: 12px;
  141. }
  142. .field.wide { grid-column: 1 / -1; }
  143. .field b {
  144. color: var(--text);
  145. font-weight: 500;
  146. overflow-wrap: anywhere;
  147. }
  148. .field b.money {
  149. color: var(--money);
  150. font-size: 15px;
  151. font-weight: 700;
  152. }
  153. /* —— 样本折叠区 —— */
  154. .samples {
  155. margin: 0 0 12px;
  156. border: 1px solid #eef4f1;
  157. border-radius: 12px;
  158. background: #fafcfb;
  159. overflow: hidden;
  160. }
  161. .samples__toggle {
  162. display: flex;
  163. width: 100%;
  164. min-height: 44px;
  165. align-items: center;
  166. gap: 8px;
  167. padding: 10px 12px;
  168. border: 0;
  169. background: transparent;
  170. color: var(--text);
  171. font: inherit;
  172. text-align: left;
  173. cursor: pointer;
  174. }
  175. .samples__toggle:active { background: #f0f7f3; }
  176. .samples__toggle-icon {
  177. display: grid;
  178. width: 22px;
  179. height: 22px;
  180. flex: 0 0 22px;
  181. place-items: center;
  182. border-radius: 6px;
  183. background: var(--primary-soft);
  184. color: var(--primary-dark);
  185. font-size: 12px;
  186. transition: transform 0.2s ease;
  187. }
  188. .samples.is-open .samples__toggle-icon {
  189. transform: rotate(90deg);
  190. }
  191. .samples__toggle-title {
  192. flex: 1;
  193. font-size: 13px;
  194. font-weight: 600;
  195. }
  196. .samples__toggle-meta {
  197. color: var(--muted);
  198. font-size: 12px;
  199. }
  200. .samples__chevron {
  201. color: var(--muted);
  202. font-size: 12px;
  203. transition: transform 0.2s ease;
  204. }
  205. .samples.is-open .samples__chevron {
  206. transform: rotate(180deg);
  207. }
  208. .samples__body {
  209. display: none;
  210. padding: 0 10px 10px;
  211. border-top: 1px solid #eef4f1;
  212. }
  213. .samples.is-open .samples__body { display: block; }
  214. .sample-block {
  215. margin-top: 10px;
  216. padding: 10px;
  217. border-radius: 10px;
  218. background: #fff;
  219. border: 1px solid #eef4f1;
  220. }
  221. .sample-block__head {
  222. display: flex;
  223. align-items: center;
  224. justify-content: space-between;
  225. gap: 8px;
  226. margin-bottom: 8px;
  227. }
  228. .sample-block__title {
  229. font-size: 13px;
  230. font-weight: 600;
  231. }
  232. .sample-block .fields {
  233. padding: 0;
  234. gap: 10px 12px;
  235. }
  236. .privacy {
  237. display: flex;
  238. min-height: 36px;
  239. align-items: center;
  240. gap: 6px;
  241. margin: 0 0 12px;
  242. padding: 0 10px;
  243. border-radius: 9px;
  244. background: #f6f7f7;
  245. color: var(--muted);
  246. font-size: 12px;
  247. }
  248. .actions {
  249. display: flex;
  250. flex-wrap: wrap;
  251. justify-content: flex-end;
  252. gap: 8px;
  253. padding-top: 12px;
  254. border-top: 1px solid #eef4f1;
  255. }
  256. .btn {
  257. min-width: 76px;
  258. min-height: 44px;
  259. padding: 0 14px;
  260. border-radius: 9px;
  261. border: 1px solid var(--border);
  262. background: #fff;
  263. color: var(--text);
  264. font-size: 13px;
  265. cursor: pointer;
  266. }
  267. .btn.primary {
  268. border-color: var(--primary);
  269. background: var(--primary);
  270. color: #fff;
  271. }
  272. .btn.danger {
  273. border-color: #f3c4c4;
  274. color: #c0392b;
  275. }
  276. .hint {
  277. margin-top: 16px;
  278. padding: 12px 14px;
  279. border-radius: 12px;
  280. background: #fff;
  281. border: 1px dashed var(--border);
  282. color: var(--muted);
  283. font-size: 12px;
  284. }
  285. .hint strong { color: var(--text); }
  286. </style>
  287. </head>
  288. <body>
  289. <div class="page">
  290. <header class="hero">
  291. <h1>运费卡片 · 样本折叠</h1>
  292. <p>默认折叠样本区,点击可展开/收起。对齐市场 H5 卡片视觉。</p>
  293. </header>
  294. <div class="section-label">
  295. <span>改后(默认折叠)</span>
  296. <em>推荐</em>
  297. </div>
  298. <!-- 卡片 1:折叠态 -->
  299. <article class="card" data-demo-card>
  300. <header class="head">
  301. <span class="index">1</span>
  302. <span class="identity">
  303. <strong class="title">YF20261014001</strong>
  304. <small class="subtitle">专线车 · ¥1,280.00</small>
  305. </span>
  306. <span class="tag">细胞存储</span>
  307. </header>
  308. <div class="fields">
  309. <div class="field wide"><span>批次号</span><b>YF20261014001</b></div>
  310. <div class="field"><span>运输方式</span><span class="tag">专线车</span></div>
  311. <div class="field"><span>运费金额</span><b class="money">¥1,280.00</b></div>
  312. <div class="field"><span>关联数</span><b>5</b></div>
  313. <div class="field"><span>创建人</span><b>张专员</b></div>
  314. <div class="field"><span>创建时间</span><b>2026-10-14 09:20</b></div>
  315. <div class="field wide"><span>备注</span><b>冷链同批次出库</b></div>
  316. </div>
  317. <div class="samples" data-samples>
  318. <button type="button" class="samples__toggle" aria-expanded="false">
  319. <span class="samples__toggle-icon">样</span>
  320. <span class="samples__toggle-title">关联样本(5)</span>
  321. <span class="samples__toggle-meta">点击展开</span>
  322. <span class="samples__chevron">▾</span>
  323. </button>
  324. <div class="samples__body">
  325. <div class="sample-block">
  326. <div class="sample-block__head">
  327. <span class="sample-block__title">样本 1 · S-10021</span>
  328. <span class="tag">细胞存储</span>
  329. </div>
  330. <div class="fields">
  331. <div class="field wide"><span>协议号</span><b>XY20261008012</b></div>
  332. <div class="field"><span>母亲姓名</span><b>王晓敏</b></div>
  333. <div class="field"><span>子女姓名</span><b>宝宝甲</b></div>
  334. <div class="field wide"><span>样本类型</span><b>脐带血</b></div>
  335. </div>
  336. </div>
  337. <div class="sample-block">
  338. <div class="sample-block__head">
  339. <span class="sample-block__title">样本 2 · S-10022</span>
  340. <span class="tag">细胞存储</span>
  341. </div>
  342. <div class="fields">
  343. <div class="field wide"><span>协议号</span><b>XY20261008018</b></div>
  344. <div class="field"><span>母亲姓名</span><b>李婷</b></div>
  345. <div class="field"><span>子女姓名</span><b>宝宝乙</b></div>
  346. <div class="field wide"><span>样本类型</span><b>脐带</b></div>
  347. </div>
  348. </div>
  349. <div class="sample-block">
  350. <div class="sample-block__head">
  351. <span class="sample-block__title">样本 3 · S-10023</span>
  352. <span class="tag warn">科研捐赠</span>
  353. </div>
  354. <div class="fields">
  355. <div class="field wide"><span>协议号</span><b>XY20261009003</b></div>
  356. <div class="field"><span>母亲姓名</span><b>周雨桐</b></div>
  357. <div class="field"><span>子女姓名</span><b>宝宝丙</b></div>
  358. <div class="field wide"><span>样本类型</span><b>胎盘</b></div>
  359. </div>
  360. </div>
  361. <div class="sample-block">
  362. <div class="sample-block__head">
  363. <span class="sample-block__title">样本 4 · S-10024</span>
  364. <span class="tag">细胞存储</span>
  365. </div>
  366. <div class="fields">
  367. <div class="field wide"><span>协议号</span><b>XY20261010007</b></div>
  368. <div class="field"><span>母亲姓名</span><b>陈思琪</b></div>
  369. <div class="field"><span>子女姓名</span><b>宝宝丁</b></div>
  370. <div class="field wide"><span>样本类型</span><b>脐带血</b></div>
  371. </div>
  372. </div>
  373. <div class="sample-block">
  374. <div class="sample-block__head">
  375. <span class="sample-block__title">样本 5 · S-10025</span>
  376. <span class="tag">细胞存储</span>
  377. </div>
  378. <div class="fields">
  379. <div class="field wide"><span>协议号</span><b>XY20261011002</b></div>
  380. <div class="field"><span>母亲姓名</span><b>赵倩</b></div>
  381. <div class="field"><span>子女姓名</span><b>宝宝戊</b></div>
  382. <div class="field wide"><span>样本类型</span><b>脐带</b></div>
  383. </div>
  384. </div>
  385. </div>
  386. </div>
  387. <p class="privacy">仅展示当前权限范围内的关联样本</p>
  388. <footer class="actions">
  389. <button type="button" class="btn">编辑</button>
  390. <button type="button" class="btn">关联样本</button>
  391. <button type="button" class="btn danger">取消关联</button>
  392. </footer>
  393. </article>
  394. <!-- 卡片 2:默认已展开,方便对比 -->
  395. <div class="section-label">
  396. <span>展开态示意</span>
  397. <em>点击上方卡片可切换</em>
  398. </div>
  399. <article class="card">
  400. <header class="head">
  401. <span class="index">2</span>
  402. <span class="identity">
  403. <strong class="title">YF20261014008</strong>
  404. <small class="subtitle">冷链 · ¥360.00</small>
  405. </span>
  406. <span class="tag">细胞存储</span>
  407. </header>
  408. <div class="fields">
  409. <div class="field wide"><span>批次号</span><b>YF20261014008</b></div>
  410. <div class="field"><span>运输方式</span><span class="tag">冷链</span></div>
  411. <div class="field"><span>运费金额</span><b class="money">¥360.00</b></div>
  412. <div class="field"><span>关联数</span><b>2</b></div>
  413. </div>
  414. <div class="samples is-open" data-samples>
  415. <button type="button" class="samples__toggle" aria-expanded="true">
  416. <span class="samples__toggle-icon">样</span>
  417. <span class="samples__toggle-title">关联样本(2)</span>
  418. <span class="samples__toggle-meta">点击收起</span>
  419. <span class="samples__chevron">▾</span>
  420. </button>
  421. <div class="samples__body">
  422. <div class="sample-block">
  423. <div class="sample-block__head">
  424. <span class="sample-block__title">样本 1 · S-20001</span>
  425. <span class="tag">细胞存储</span>
  426. </div>
  427. <div class="fields">
  428. <div class="field wide"><span>协议号</span><b>XY20261012001</b></div>
  429. <div class="field"><span>母亲姓名</span><b>孙悦</b></div>
  430. <div class="field"><span>子女姓名</span><b>宝宝己</b></div>
  431. <div class="field wide"><span>样本类型</span><b>脐带血</b></div>
  432. </div>
  433. </div>
  434. <div class="sample-block">
  435. <div class="sample-block__head">
  436. <span class="sample-block__title">样本 2 · S-20002</span>
  437. <span class="tag">细胞存储</span>
  438. </div>
  439. <div class="fields">
  440. <div class="field wide"><span>协议号</span><b>XY20261012005</b></div>
  441. <div class="field"><span>母亲姓名</span><b>吴芳</b></div>
  442. <div class="field"><span>子女姓名</span><b>宝宝庚</b></div>
  443. <div class="field wide"><span>样本类型</span><b>脐带</b></div>
  444. </div>
  445. </div>
  446. </div>
  447. </div>
  448. <footer class="actions">
  449. <button type="button" class="btn primary">查看</button>
  450. <button type="button" class="btn">编辑</button>
  451. </footer>
  452. </article>
  453. <div class="hint">
  454. <strong>交互说明:</strong>默认折叠,只占一行摘要;展开后按样本分块展示。无样本时不显示该区域。
  455. 文件路径:<code>docs/demos/2026-10-14-freight-card-sample-collapse-demo.html</code>
  456. </div>
  457. </div>
  458. <script>
  459. document.querySelectorAll('[data-samples]').forEach((panel) => {
  460. const btn = panel.querySelector('.samples__toggle')
  461. const meta = panel.querySelector('.samples__toggle-meta')
  462. btn.addEventListener('click', () => {
  463. const open = panel.classList.toggle('is-open')
  464. btn.setAttribute('aria-expanded', open ? 'true' : 'false')
  465. if (meta) meta.textContent = open ? '点击收起' : '点击展开'
  466. })
  467. })
  468. </script>
  469. </body>
  470. </html>