fix(chart): symbol bubble no longer flickers (global tooltip rule switched the stage's pointer events off); rounded chart tables (BUG-1120)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
3e29b697db
commit
90b1b6fba9
@@ -1,5 +1,10 @@
|
||||
# 印度占星 Skill 更新日志
|
||||
|
||||
## 2026-09-30 — 星盘符号气泡不再闪;星盘表格恢复圆角
|
||||
|
||||
- 鼠标停在星盘里的行星、上升或星座编号上,说明气泡会稳定显示;之前鼠标每动一下气泡就消失再出现。
|
||||
- 星盘页下方的行星表、分盘表、Bhava 表和西洋表加上圆角边框,与上方盘面外框一致。Skill 版本不 bump。
|
||||
|
||||
## 2026-09-30 — 性别只在星盘档案里设置
|
||||
|
||||
- 设置 →「个人资料」里的性别选项删除;本人和其他人的性别都在「星盘档案」→「编辑」里改,详情卡照常显示。已保存的性别不受影响。Skill 版本不 bump。
|
||||
|
||||
@@ -14948,3 +14948,18 @@
|
||||
- 防复发:同一字段新增编辑入口时,同一轮撤掉旧入口并在 DESIGN 标明唯一入口。
|
||||
- 相关记录:BUG-1081、TASK-consult-gender-optional-20260927
|
||||
- 修复版本:分支 `codex/gender-archive-only-20260930`
|
||||
|
||||
## BUG-1120 | 星盘符号说明气泡在鼠标悬停时频闪
|
||||
|
||||
- 状态:resolved(代码 + 回归测试 + 本机 Chromium 复现 / 复验;待部署)
|
||||
- 首次发现 / 最近更新:2026-09-30 / 2026-09-30
|
||||
- 影响面:`frontend/src/app/globals.css` 的全局 `:has(> [role="tooltip"])` 规则;`frontend/src/components/chart-page/chart-symbol-help.tsx`(印度盘与西洋盘共用)。
|
||||
- 现象:产品反馈「鼠标浮动到图标上方会频闪」。本机 Chromium 用真实 golden 盘复现:在任一符号上移动 1px,气泡被移除再插入,22 个标记全部如此。
|
||||
- 触发条件:桌面鼠标悬停星盘内任一可说明的标记(行星、上升、星座编号)。
|
||||
- 根因:侧栏悬停提示的全局规则 `:has(> [role="tooltip"]) { pointer-events: none }` 本为弹出层定位器写的;气泡(`role="tooltip"`)是 `.chart-page-symbol-help` 的直接子元素,于是整个星盘舞台在气泡出现时失去指针事件 → 标记收到 pointerout(relatedTarget 为外框)→ 气泡关闭 → 舞台恢复命中 → pointerover → 气泡再开,循环即频闪。BUG-1100 引入气泡时单测只在无样式的 DOM 里跑,看不到这条全局 CSS。
|
||||
- 修复:全局规则改为 `:has(> [role="tooltip"]):not(.chart-page-symbol-help)`;气泡保留 `role="tooltip"`。
|
||||
- 验证:`chart-symbol-help.test.tsx` 新增 CSS 合同(带 pointer-events:none 的 tooltip 规则必须排除星盘舞台);本机 Chromium 复验:同样的移动序列下气泡不再移除 / 插入,只在盘心相邻星座编号间切换文字;chart 相关 158 条测试通过。
|
||||
- 防复发:新增内联 `role="tooltip"` 时检查全局 `:has(> [role="tooltip"])` 规则的作用范围;悬停类交互需在真实浏览器(带全站 CSS)里至少走一次。
|
||||
- 相关记录:BUG-1100(气泡引入)
|
||||
- 修复版本:分支 `codex/notice-loading-polish-20260930`
|
||||
|
||||
|
||||
@@ -1094,6 +1094,8 @@ D40 / D45 / D60 的表格上方,出生时间不是「已校正」时多一句
|
||||
|
||||
每一张 `.chart-page-planet-table`(本命、分盘、月亮盘、Bhava 两张、行运、西洋相位)都包在 `.chart-page-planet-table-wrap` 里:`min-width: 0` + `overflow-x: auto`。375px 下表格在自己的盒子里横滚,页面不横滚。`min-width: 0` 和 overflow 一样是必需的——grid item 默认按内容定宽,少了它表格会把页面撑宽而不是滚动。外层 `.secondary-page` 的单列同理是 `minmax(0, 1fr)`(BUG-1083),否则撑宽发生在更外面一层。印度盘那张从四列扩到八列后 `min-width` 由 `26rem` 提到 `34rem`。
|
||||
|
||||
**圆角(2026-09-30)。** 行星表和西洋表与上方盘面外框同一语言:表格 1px `--color-border` 边框 + `--radius-lg` 圆角,`border-collapse: separate`(collapse 下圆角不生效),四个角单元格各自圆角;换宫 / 选中 / 悬停的底色落在单元格上而不是行上,这样角上的格子也能跟着圆。表题(caption)在边框外。
|
||||
|
||||
**印度盘行星表的八列(2026-09-18)。** 盘里不再写的东西全部落在这里:
|
||||
|
||||
| 列 | 内容 |
|
||||
|
||||
@@ -1968,7 +1968,11 @@ button:disabled:where(:not([data-slot="button"])) { cursor: default; opacity: .4
|
||||
.account-menu-danger, .account-menu-danger > svg { color: var(--color-danger); }
|
||||
.account-menu-danger[data-highlighted] { background: var(--color-danger-muted); }
|
||||
|
||||
:has(> [role="tooltip"]) { z-index: 40; max-width: calc(100vw - var(--space-6)); pointer-events: none; }
|
||||
/* For portalled tooltip positioners only. The chart's symbol bubble is an inline
|
||||
child of the stage that holds the whole drawing; matching it switched the
|
||||
drawing's pointer events off while the bubble was up, so the mark lost the
|
||||
hover, the bubble closed, the mark got it back — a flicker loop (BUG-1120). */
|
||||
:has(> [role="tooltip"]):not(.chart-page-symbol-help) { z-index: 40; max-width: calc(100vw - var(--space-6)); pointer-events: none; }
|
||||
[role="tooltip"] { max-width: min(240px, calc(100vw - var(--space-6))); padding: var(--space-2) var(--space-3); border: 1px solid var(--sidebar-border); border-radius: var(--radius-md); background: var(--sidebar-solid); color: var(--sidebar-foreground); box-shadow: var(--shadow-elevated); pointer-events: none; font-size: var(--type-caption); font-weight: 500; line-height: 1.4; transform-origin: var(--transform-origin); transition: opacity 120ms ease-out, transform 120ms var(--ease-out); }
|
||||
[role="tooltip"][data-starting-style], [role="tooltip"][data-ending-style] { opacity: 0; transform: translateX(var(--space-1)); }
|
||||
|
||||
@@ -5345,7 +5349,8 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
.chart-page-varga-table-block { min-width: 0; }
|
||||
.chart-page-varga-table-block > .chart-page-planet-table-wrap + .chart-page-planet-table-wrap { margin-top: var(--space-4); }
|
||||
/* A body the Bhava boundaries move to another house. */
|
||||
.chart-page-planet-table tr.is-shifted { background: var(--color-selected); }
|
||||
.chart-page-planet-table tr.is-shifted > td,
|
||||
.chart-page-planet-table tr.is-shifted > th { background: var(--color-selected); }
|
||||
.chart-page-waiting-plot {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
@@ -5482,7 +5487,6 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
/* Eight columns now (symbol+name, longitude, speed, house, nakshatra, its
|
||||
lord, pada, dignity); 26rem was sized for four and crushed the last three. */
|
||||
min-width: 34rem;
|
||||
border-collapse: collapse;
|
||||
background: var(--color-canvas);
|
||||
font-size: var(--type-body-sm);
|
||||
}
|
||||
@@ -5768,7 +5772,6 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
}
|
||||
.chart-page-western-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
background: var(--color-canvas);
|
||||
font-size: var(--type-body-sm);
|
||||
}
|
||||
@@ -5787,8 +5790,28 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
}
|
||||
.chart-page-western-num { font-variant-numeric: tabular-nums; }
|
||||
.chart-page-western-table tbody tr[tabindex] { cursor: pointer; }
|
||||
.chart-page-western-table tbody tr[tabindex]:hover { background: var(--color-canvas-muted); }
|
||||
.chart-page-western-table tr.is-selected { background: var(--color-selected); }
|
||||
.chart-page-western-table tbody tr[tabindex]:hover > td { background: var(--color-canvas-muted); }
|
||||
.chart-page-western-table tr.is-selected > td { background: var(--color-selected); }
|
||||
/* Rounded like the chart stage above them (2026-09-30, product: 「表格圆角怎么没了」).
|
||||
Separate borders so the table's own radius clips; row tints sit on the cells
|
||||
so the corner cells can round them too. */
|
||||
.chart-page-planet-table,
|
||||
.chart-page-western-table {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-lg);
|
||||
}
|
||||
.chart-page-planet-table thead th:first-child,
|
||||
.chart-page-western-table thead th:first-child { border-top-left-radius: calc(var(--radius-lg) - 1px); }
|
||||
.chart-page-planet-table thead th:last-child,
|
||||
.chart-page-western-table thead th:last-child { border-top-right-radius: calc(var(--radius-lg) - 1px); }
|
||||
.chart-page-planet-table tbody tr:last-child > :first-child,
|
||||
.chart-page-western-table tbody tr:last-child > :first-child { border-bottom-left-radius: calc(var(--radius-lg) - 1px); }
|
||||
.chart-page-planet-table tbody tr:last-child > :last-child,
|
||||
.chart-page-western-table tbody tr:last-child > :last-child { border-bottom-right-radius: calc(var(--radius-lg) - 1px); }
|
||||
.chart-page-planet-table tbody tr:last-child > *,
|
||||
.chart-page-western-table tbody tr:last-child > * { border-bottom: 0; }
|
||||
.chart-page-unavailable > p { margin: 0 0 var(--space-3); font-size: var(--type-body-md); }
|
||||
|
||||
@media (min-width: 768px) {
|
||||
|
||||
@@ -155,3 +155,16 @@ test("Western visible caption and hit target explain the same nearest planet as
|
||||
assert.deepEqual(h.errors, []);
|
||||
} finally { await h.close(); }
|
||||
});
|
||||
|
||||
test("the global tooltip-positioner rule does not switch off the chart stage's pointer events (BUG-1120)", () => {
|
||||
// The bubble is an inline role="tooltip" child of .chart-page-symbol-help. A bare
|
||||
// `:has(> [role="tooltip"]) { pointer-events: none }` matched the stage, so the
|
||||
// drawing under the cursor stopped being hoverable while the bubble was up and
|
||||
// the bubble flickered on every mouse move (reproduced in Chromium).
|
||||
const css = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8");
|
||||
const rules = [...css.matchAll(/([^{}]*:has\(>\s*\[role="tooltip"\]\)[^{}]*)\{([^}]*)\}/g)];
|
||||
assert.ok(rules.length > 0);
|
||||
for (const [, selector, body] of rules) {
|
||||
if (/pointer-events:\s*none/.test(body)) assert.match(selector, /:not\(\.chart-page-symbol-help\)/, selector.trim());
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user