From 7d78a33a9d9d8f250c61fe40c76176f41e1d3973 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Nov 2026 17:27:51 +0800 Subject: [PATCH] fix(user-center): match the reference meta pills on the profile header card MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The username and e-mail entries under the profile header rendered as plain grey text on a solid icon. The reference makes each one a bordered pill that copies its own value on click, drawn with the outline glyphs. Both entries now carry `.but` plus `data-clipboard-tag` / `data-clipboard-text` so the existing frontend clipboard runtime (assets/js/runtime/libs/clipboard.js) picks them up and toasts "用户名已复制". Icons move from `fas` to `far`, which is the FA5 equivalent of the reference's `fa-user-o` / `fa-envelope-o`. Geometry follows `.author-header .user-identity > .but/.badg` exactly: padding 2px 6px, margin 5px 6px 0 0, 12px type, 1.4 line height, and the meta row gets the reference's 520px max width. medal.css already carried its own approximation of this pill (2px 8px 2px 0, .3em .6em, 1.44) for the medal entry; it now uses the same numbers so the two entries line up. The base rule lives in layout.css rather than medal.css because the medal module is only enqueued when badges are enabled, and the header must keep its shape either way. Verification: rendered the real header through a PHP stub and measured the computed styles in the browser — padding 2px 6px, margin 5px 6px 0 0, 12px / 16.8px, 23px tall, both entries carrying the right clipboard payload. Added user-center-header-meta-contract.test.cjs to pin the markup and geometry; 864 widget/navigation tests pass. --- assets/css/frontend/medal.css | 7 +-- assets/css/routes/profile/layout.css | 33 ++++++++++--- .../user-center-renderers/profile-header.php | 8 ++-- .../user-center-header-meta-contract.test.cjs | 48 +++++++++++++++++++ 4 files changed, 82 insertions(+), 14 deletions(-) create mode 100644 tests/widget-system/user-center-header-meta-contract.test.cjs diff --git a/assets/css/frontend/medal.css b/assets/css/frontend/medal.css index 397ad5f6..3608bd45 100644 --- a/assets/css/frontend/medal.css +++ b/assets/css/frontend/medal.css @@ -11,8 +11,9 @@ align-items: center; gap: 4px; min-width: 0; - margin: 2px 8px 2px 0; - padding: .3em .6em; + /* 参考主题 .author-header .user-identity > .but/.badg:5px 6px 0 0 + 1.4 行高 */ + margin: 5px 6px 0 0; + padding: 2px 6px; border: 1px solid var(--color-line-soft, var(--main-border-color, rgba(136, 136, 136, .18))); border-radius: var(--mini-radius, 4px); background: var(--surface-2, rgba(136, 136, 136, .1)); @@ -20,7 +21,7 @@ color: var(--muted-2-color, var(--color-ink-3)); font: inherit; font-size: 12px; - line-height: 1.44; + line-height: 1.4; white-space: nowrap; } .jio-medal-entry { diff --git a/assets/css/routes/profile/layout.css b/assets/css/routes/profile/layout.css index 4420791d..1eb0ee35 100644 --- a/assets/css/routes/profile/layout.css +++ b/assets/css/routes/profile/layout.css @@ -269,24 +269,43 @@ .uc-header__meta { display: flex; flex-wrap: wrap; - gap: 6px; + align-items: center; + gap: 0; + max-width: 520px; font-size: 13px; color: var(--color-ink-3); } -.uc-header__meta .jio-ip-geo-badge { - margin: 2px 0; -} - +/* Reference geometry: every meta entry is a pill — 12px type, 2px/6px padding, + * 5px 6px 0 0 spacing, 1.4 line height (same numbers as .author-header + * .user-identity > .but/.badg). Declared here so the header keeps its shape even + * when the medal module is not enqueued. */ .uc-header__meta-item { display: inline-flex; align-items: center; - gap: 5px; + gap: 4px; + min-width: 0; + margin: 5px 6px 0 0; + padding: 2px 6px; + border: 1px solid var(--color-line-soft, var(--main-border-color, rgba(136, 136, 136, .18))); + border-radius: var(--mini-radius, 4px); + background: var(--surface-2, rgba(136, 136, 136, .1)); + color: var(--color-ink-3); + font-size: 12px; + line-height: 1.4; + white-space: nowrap; } .uc-header__meta-item i { font-size: 12px; - opacity: 0.65; + opacity: 0.8; +} + +.uc-header__meta .jio-ip-geo-badge { + font-size: 12px; + padding: 2px 6px; + margin: 5px 6px 0 0; + line-height: 1.4; } /* 治理状态提示:与相邻元信息同排版;链接默认色会让箭头/图标偏离行内墨色 */ diff --git a/inc/helpers/user-center-renderers/profile-header.php b/inc/helpers/user-center-renderers/profile-header.php index dc35416c..306767c7 100644 --- a/inc/helpers/user-center-renderers/profile-header.php +++ b/inc/helpers/user-center-renderers/profile-header.php @@ -56,12 +56,12 @@ extract($context, EXTR_SKIP); // phpcs:ignore WordPress.PHP.DontExtract.extract_ - - user_login); ?> + + user_login); ?> user_email) : ?> - - user_email); ?> + + user_email); ?> .but 同形。 + * 2) 图标使用描边字形(far fa-user / far fa-envelope),不是实心 fas。 + * 3) 几何参数与参考一致:padding 2px 6px、margin 5px 6px 0 0、字号 12px、 + * 行高 1.4;这套规则由 layout.css 自持,不依赖 medal.css 是否入队。 + */ +'use strict'; + +const assert = require('node:assert/strict'); +const fs = require('node:fs'); +const path = require('node:path'); +const test = require('node:test'); + +const root = path.resolve(__dirname, '..', '..'); +const read = (file) => fs.readFileSync(path.join(root, file), 'utf8'); + +test('用户中心元信息是参考主题的可复制胶囊条目', () => { + const header = read('inc/helpers/user-center-renderers/profile-header.php'); + + assert.match(header, /class="uc-header__meta-item but"\s+data-clipboard-tag=/); + assert.match(header, /data-clipboard-text="<\?php echo esc_attr\(\$target_user->user_login\); \?>"/); + assert.match(header, /data-clipboard-text="<\?php echo esc_attr\(\$target_user->user_email\); \?>"/); + + // 描边字形,与参考的 fa-user-o / fa-envelope-o 等价(FA5 用 far 表示)。 + assert.match(header, /fa far fa-user/); + assert.match(header, /fa far fa-envelope/); + assert.doesNotMatch(header, /fa fas fa-user"|fa fas fa-envelope"/); +}); + +test('元信息胶囊的几何参数与参考主题一致', () => { + const layout = read('assets/css/routes/profile/layout.css'); + + const block = layout.slice( + layout.indexOf('.uc-header__meta-item {'), + layout.indexOf('.uc-header__meta-item {') + 700, + ); + assert.match(block, /padding:\s*2px 6px;/); + assert.match(block, /margin:\s*5px 6px 0 0;/); + assert.match(block, /font-size:\s*12px;/); + assert.match(block, /line-height:\s*1\.4;/); + + // 版式由 layout.css 自持,medal 模块未入队时形态不变。 + assert.match(layout, /\.uc-header__meta-item \{/); +});