dsh-m 0.9.54 → 0.9.56
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/CHANGELOG.md +26 -0
- package/lib/client.js +53 -38
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,19 @@ The full release history of dsh-m, maintained bilingually: **Chinese first, Engl
|
|
|
8
8
|
|
|
9
9
|
## 中文
|
|
10
10
|
|
|
11
|
+
### 0.9.56 变更:ZoneChips +N 重叠根治——in-flow 文档流布局 + 折行减类(主人方案)
|
|
12
|
+
|
|
13
|
+
- **缺陷(0.9.55 真机复现)**:折叠态 `+N` 采用「绝对定位 + contentW−48 夹取」,当末可见行剩余空间小于徽章宽时,徽章压住末可见 chip(真机:+9 压住「文档与渲染 61」右端计数)。
|
|
14
|
+
- **根治(in-flow 文档流布局)**:`+N` 弃绝对定位,以 in-flow 插在「末可见分类」与「被裁分类」之间——flow 布局与 chip 的重叠在构造上不可能。
|
|
15
|
+
- **折行减类(主人方案)**:被裁分类 `visibility:hidden` → **`display:none`**(不占位,折行减类生效前提);测量发现 `+N` 顶 > 末可见 chip 行顶(被折出)⇒ `hiddenCount +1`,一枚可见分类退位、`+N` 退回末可见行,同时 `max-height` 扩一行给 `+N` 独占;棘轮单向下行,宽度增大时保守不多显(+N 计数仍真实)。
|
|
16
|
+
- **测试**:全量 1221 例零失败、typecheck 零错误;无头探针实证常宽 880/窄宽 420/展开/收起/Q1 回归全部 `chipOverlapPx = 0`、`+N` 全程可见、展开态 23+⌃+筛选全量、收起后 +N 回归蓝筐位。
|
|
17
|
+
|
|
18
|
+
### 0.9.55 变更:ZoneChips 折叠/展开切换钮内联化(对齐 dsh-market 参考设计)+ overlay 叠涂 scrim 强化对比度
|
|
19
|
+
|
|
20
|
+
- **切换钮内联化(主人提出,dsh-market v1.66.11 参考设计)**:`+N` 从右侧 overlay 组改为**绝对定位内联**——钉在「末可见分类 chip 右侧 +6px」(即末可见行剩余空位),与展开态 `⌃`(列表末尾 in-flow)构成统一位置语义「紧跟当前列表末尾」,只翻方向不挪位;窄宽度放不下时贴内容右缘收口(不侵入筛选槽)。gutter 随 `+N` 移出由 132px 瘦身至 96px(仅承载钉住筛选),同宽度可多显示约 1 颗分类。overlay 组内 `+N` 移除后仅剩钉住筛选,第④类碰撞(R2-N1)自然消解。
|
|
21
|
+
- **overlay 叠涂 scrim(主人提出:浅色主题对比度偏低)**:根因是 `--dsw-alias-bg-base` token 本身 0.55 半透明;overlay 底衬改同 token **三层叠涂**(background-color + 双 linear-gradient 层),有效不透明度 ≈ 1−0.45³ ≈ 91%,深浅主题自适应(深色 rgba(12,26,38,·) / 浅色 rgba(247,250,252,·) 均显著强化),不引入硬编码色值。
|
|
22
|
+
- **测试**:全量 1221 例零失败、typecheck 零错误;无头探针实证:折叠态 `+N` 左缘 = 末可见 chip 右缘 +6px 同行对齐、scrim 双梯度、筛选单钮零碰撞、收起/展开往复位置稳定、Q1 回归(长文案 hidden>0);真机截图见发版记录。
|
|
23
|
+
|
|
11
24
|
### 0.9.54 变更:评审修复随版(ZoneChips 重测盲区/⌃ 弹回/overlay 居中)+ dsh-skip-browser-auth 收录文案对账
|
|
12
25
|
|
|
13
26
|
- **ZoneChips 三处评审修复(执行结果评审 R1,`b2aab5f`)**:① 测量 deps 以 `chips` 引用替代 `chips.length` 并叠加 `active`——同长度内容变化(计数刷新/激活加粗变宽)确定性重测,消除 RO 因 max-height 钳制失聪导致的陈旧 geom 盲区(被裁 chip 保持可聚焦/激活分类越界不自动展开的失效窗口,D4 违背态);② `⌃` 手动收起无条件记录 autoRef——手动收起全路径被尊重,消除展开态 geom 陈旧时收起被决策 effect 弹回的边缘漂移;③ overlay 组按 rowHeight 垂直居中(bottom 补偿偏移)。
|
|
@@ -406,6 +419,19 @@ The full release history of dsh-m, maintained bilingually: **Chinese first, Engl
|
|
|
406
419
|
|
|
407
420
|
## English
|
|
408
421
|
|
|
422
|
+
### Fixed in 0.9.56 — ZoneChips +N overlap eradicated: in-flow document layout + wrap-yield-a-category (owner's design)
|
|
423
|
+
|
|
424
|
+
- **Defect (reproduced on 0.9.55)**: the collapsed `+N` used "absolute positioning + contentW−48 clamp"; when the last visible row's leftover was narrower than the badge, the badge covered the last visible chip (real panel: +9 covering the tail of 文档与渲染 61).
|
|
425
|
+
- **Fix (in-flow document layout)**: `+N` abandons absolute positioning and flows inline between the last visible category and the clipped categories — chip/badge overlap is impossible by construction.
|
|
426
|
+
- **Wrap-yield-a-category (owner's design)**: clipped categories switch `visibility:hidden` → **`display:none`** (no space — the prerequisite for yielding to work); when the measure finds the `+N` top beyond the last visible chip's row top (wrapped), `hiddenCount +1` — one visible category yields, `+N` pulls back into the last visible row, and `max-height` grows one row to give `+N` its own line; the ratchet is single-direction (down), staying conservative on width growth while the count stays truthful.
|
|
427
|
+
- **Tests**: full suite 1221 cases zero failures, typecheck clean; headless probe verified 880px/420px/expanded/collapsed/Q1-regression all at `chipOverlapPx = 0` with `+N` visible throughout, expanded view showing 23+⌃+filter in full, and `+N` returning to its inline slot after collapse.
|
|
428
|
+
|
|
429
|
+
### Changed in 0.9.55 — ZoneChips expand/collapse toggle inline (aligned with the dsh-market reference design) + overlay stacked scrim for contrast
|
|
430
|
+
|
|
431
|
+
- **Inline toggle (owner-requested, reference: dsh-market v1.66.11)**: `+N` moves out of the right-side overlay group into an **absolutely-positioned inline slot** pinned at "last visible category chip's right edge + 6px" (the leftover of the last visible row), sharing one position semantic with the expanded `⌃` (in-flow at list end): "hug the current end of the list", flipping direction without relocating; when the leftover is too narrow it clamps to the content right edge without entering the filter gutter. The gutter slims from 132px to 96px (hosting only the pinned filter), showing ~1 more category per width. With `+N` removed, the overlay group hosts only the pinned filter and the R2-N1 4th collision class dissolves naturally.
|
|
432
|
+
- **Overlay stacked scrim (owner-requested: low contrast in light theme)**: root cause is that the `--dsw-alias-bg-base` token itself is 0.55-translucent; the overlay scrim now paints the same token in a **three-layer stack** (background-color + two linear-gradient layers), effective opacity ≈ 1−0.45³ ≈ 91%, theme-adaptive (dark rgba(12,26,38,·) / light rgba(247,250,252,·) both significantly strengthened) with zero hard-coded colors.
|
|
433
|
+
- **Tests**: full suite 1221 cases zero failures, typecheck clean; headless probe verified collapsed-state `+N` left edge = last visible chip right edge + 6px on the same row, double scrim gradients, single-button zero-collision filter, stable toggle position across collapse/expand cycles, and the Q1 regression (long labels: hidden > 0); real-panel screenshots in the release record.
|
|
434
|
+
|
|
409
435
|
### Changed in 0.9.54 — review fixes ship (ZoneChips stale-geom / ⌃ bounce / overlay centering) + dsh-skip-browser-auth catalog copy reconciliation
|
|
410
436
|
|
|
411
437
|
- **ZoneChips review fixes (execution-review R1, `b2aab5f`)**: ① measure deps use the `chips` reference instead of `chips.length` plus `active` — same-length content changes (count refresh / active bold reflow) now deterministically re-measure, closing the stale-geom blind window where RO is deafened by the max-height clamp (clipped-but-focusable chips / missed auto-expand, a D4 violation); ② manual `⌃` collapse unconditionally records autoRef — manual collapse is respected on every path, removing the edge drift where a stale-geom decision effect bounced the collapse back; ③ the overlay group is vertically centered per measured row-height (compensated bottom offset).
|
package/lib/client.js
CHANGED
|
@@ -1558,7 +1558,7 @@ var h = React.createElement;
|
|
|
1558
1558
|
var { useState, useEffect, useLayoutEffect, useCallback, useMemo, useRef } = React;
|
|
1559
1559
|
var PLUGIN_ID = "dsh-m";
|
|
1560
1560
|
var API = "/dshm";
|
|
1561
|
-
var { DEFAULT_PAGE_SIZE: DEFAULT_PAGE_SIZE2, MARKET_PAGE_SIZES: MARKET_PAGE_SIZES2, pageItems: pageItems2, createZoneState: createZoneState2, normalizeMarketQuery: normalizeMarketQuery2, resetPageOnFilterChange: resetPageOnFilterChange2, normalizeMarketResponse: normalizeMarketResponse2, registryNotice: registryNotice2, zoneChips: zoneChips2, marketNotice: marketNotice2, searchSourceOf: searchSourceOf2, mergeLatestFields: mergeLatestFields2, chipRows: chipRows2, countBeyondRows: countBeyondRows2,
|
|
1561
|
+
var { DEFAULT_PAGE_SIZE: DEFAULT_PAGE_SIZE2, MARKET_PAGE_SIZES: MARKET_PAGE_SIZES2, pageItems: pageItems2, createZoneState: createZoneState2, normalizeMarketQuery: normalizeMarketQuery2, resetPageOnFilterChange: resetPageOnFilterChange2, normalizeMarketResponse: normalizeMarketResponse2, registryNotice: registryNotice2, zoneChips: zoneChips2, marketNotice: marketNotice2, searchSourceOf: searchSourceOf2, mergeLatestFields: mergeLatestFields2, chipRows: chipRows2, countBeyondRows: countBeyondRows2, autoExpandDecision: autoExpandDecision2 } = (init_market_state(), __toCommonJS(market_state_exports));
|
|
1562
1562
|
var { readMarketSnapshot: readMarketSnapshot2, writeMarketSnapshot: writeMarketSnapshot2, isDefaultFirstPageQuery: isDefaultFirstPageQuery2 } = (init_market_snapshot(), __toCommonJS(market_snapshot_exports));
|
|
1563
1563
|
var { backdropCloseHandlers: backdropCloseHandlers2 } = (init_backdrop(), __toCommonJS(backdrop_exports));
|
|
1564
1564
|
var { createMarkdown: createMarkdown2 } = (init_markdown(), __toCommonJS(markdown_exports));
|
|
@@ -2188,8 +2188,8 @@ var CSS = `
|
|
|
2188
2188
|
.dshm-input:focus{border-color:var(--dsw-alias-interactive-bg-selected,#4f46e5)}
|
|
2189
2189
|
.dshm-chips{display:flex;flex-wrap:wrap;gap:6px;position:relative}
|
|
2190
2190
|
.dshm-chips-clip{overflow:hidden}
|
|
2191
|
-
.dshm-chips-gutter{padding-right:var(--dshm-clip-gutter,
|
|
2192
|
-
.dsvm-chipmore{position:absolute;right:8px;
|
|
2191
|
+
.dshm-chips-gutter{padding-right:var(--dshm-clip-gutter,96px)}
|
|
2192
|
+
.dsvm-chipmore{position:absolute;right:8px;display:flex;align-items:center;gap:8px;min-height:28px;background-color:var(--dsw-alias-bg-base,#fff);background-image:linear-gradient(var(--dsw-alias-bg-base,#fff),var(--dsw-alias-bg-base,#fff)),linear-gradient(var(--dsw-alias-bg-base,#fff),var(--dsw-alias-bg-base,#fff));border:1px solid var(--dsw-alias-border-l1,rgba(127,127,127,.18));border-radius:999px;padding:2px 8px;box-sizing:border-box}
|
|
2193
2193
|
.dsvm-searchrow{display:flex;align-items:center;gap:8px}
|
|
2194
2194
|
.dsvm-searchrow .dshm-search{flex:1;display:flex}
|
|
2195
2195
|
.dshm-search{position:relative}
|
|
@@ -2719,22 +2719,42 @@ function ZoneChips({ zone, counts, labels, active, onPick, trailing, wrapTitle }
|
|
|
2719
2719
|
const autoRef = useRef(null);
|
|
2720
2720
|
const maxRows = stuck ? 1 : 2;
|
|
2721
2721
|
const activeIdx = active ? chips.findIndex((c) => c.id === active) : -1;
|
|
2722
|
-
const
|
|
2722
|
+
const plusWrapped = !!(geom && geom.plusWrapped);
|
|
2723
|
+
const maxRowsEff = maxRows + (plusWrapped ? 1 : 0);
|
|
2724
|
+
const maxH = maxRowsEff * (rowHeight || 22) + (maxRowsEff - 1) * 6;
|
|
2723
2725
|
const measure = useCallback(() => {
|
|
2724
2726
|
const el = wrapRef.current;
|
|
2725
2727
|
if (!el || expanded) return;
|
|
2726
2728
|
const tops = [];
|
|
2727
2729
|
let rh = 0;
|
|
2730
|
+
let plusTopMeas = null;
|
|
2731
|
+
let hiddenMeas = 0;
|
|
2728
2732
|
for (const k of el.children) {
|
|
2729
|
-
if (!(k instanceof HTMLElement)
|
|
2733
|
+
if (!(k instanceof HTMLElement)) continue;
|
|
2734
|
+
if (k.getAttribute("data-more") === "1") {
|
|
2735
|
+
plusTopMeas = k.offsetTop;
|
|
2736
|
+
continue;
|
|
2737
|
+
}
|
|
2738
|
+
if (k.getAttribute("data-chip") !== "1") continue;
|
|
2739
|
+
if (getComputedStyle(k).display === "none") {
|
|
2740
|
+
hiddenMeas += 1;
|
|
2741
|
+
continue;
|
|
2742
|
+
}
|
|
2730
2743
|
tops.push(k.offsetTop);
|
|
2731
2744
|
if (!rh && k.offsetHeight) rh = k.offsetHeight;
|
|
2732
2745
|
}
|
|
2733
2746
|
if (!tops.length) return;
|
|
2734
|
-
const
|
|
2735
|
-
|
|
2747
|
+
const lastRowTop = tops[tops.length - 1];
|
|
2748
|
+
const plusWrappedNow = plusTopMeas != null && plusTopMeas > lastRowTop;
|
|
2749
|
+
setGeom((prev) => {
|
|
2750
|
+
const prevHC = prev ? prev.hiddenCount : countBeyondRows2(tops.slice(1), maxRows);
|
|
2751
|
+
const hiddenCount2 = plusWrappedNow ? prevHC + 1 : prevHC;
|
|
2752
|
+
const next = { tops, hiddenCount: hiddenCount2 };
|
|
2753
|
+
const same = prev && prev.hiddenCount === next.hiddenCount && prev.tops.length === next.tops.length && prev.tops.every((t, i) => t === next.tops[i]);
|
|
2754
|
+
return same ? prev : next;
|
|
2755
|
+
});
|
|
2736
2756
|
setRowHeight((prev) => Math.abs(prev - rh) <= 0.5 ? prev : rh);
|
|
2737
|
-
}, [expanded, maxRows]);
|
|
2757
|
+
}, [expanded, maxRows, chips.length]);
|
|
2738
2758
|
useEffect(() => {
|
|
2739
2759
|
if (!active) {
|
|
2740
2760
|
autoRef.current = null;
|
|
@@ -2743,14 +2763,14 @@ function ZoneChips({ zone, counts, labels, active, onPick, trailing, wrapTitle }
|
|
|
2743
2763
|
}, [active]);
|
|
2744
2764
|
useEffect(() => {
|
|
2745
2765
|
if (!active || !geom) return;
|
|
2746
|
-
const
|
|
2747
|
-
const d = autoExpandDecision2(
|
|
2766
|
+
const visCats = geom.tops.length - 1;
|
|
2767
|
+
const d = autoExpandDecision2(activeIdx, visCats, autoRef.current === active, expanded);
|
|
2748
2768
|
if (d.record) autoRef.current = active;
|
|
2749
2769
|
if (d.expand) setExpanded(true);
|
|
2750
2770
|
}, [active, activeIdx, expanded, geom]);
|
|
2751
2771
|
useLayoutEffect(() => {
|
|
2752
2772
|
if (!expanded) measure();
|
|
2753
|
-
}, [chips, active, expanded, zone, stuck, rowHeight, measure]);
|
|
2773
|
+
}, [chips, active, expanded, zone, stuck, rowHeight, measure, geom]);
|
|
2754
2774
|
useEffect(() => {
|
|
2755
2775
|
const el = wrapRef.current;
|
|
2756
2776
|
if (!el || expanded || typeof ResizeObserver === "undefined") return;
|
|
@@ -2783,25 +2803,21 @@ function ZoneChips({ zone, counts, labels, active, onPick, trailing, wrapTitle }
|
|
|
2783
2803
|
return () => io.disconnect();
|
|
2784
2804
|
}, []);
|
|
2785
2805
|
const clip = !expanded;
|
|
2786
|
-
const
|
|
2787
|
-
const clipTop = geom ? geom.clipTop : Infinity;
|
|
2806
|
+
const filterPinned = clip && trailing != null;
|
|
2788
2807
|
const hiddenCount = geom ? geom.hiddenCount : 0;
|
|
2789
|
-
const
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
`${c.labelKey ? lookup(c.labelKey) : c.label} ${c.count || 0}`
|
|
2803
|
-
);
|
|
2804
|
-
};
|
|
2808
|
+
const visCount = geom ? Math.max(0, chips.length - hiddenCount) : chips.length;
|
|
2809
|
+
const btn = (c, i, hide) => h(
|
|
2810
|
+
"button",
|
|
2811
|
+
{
|
|
2812
|
+
key: c.id,
|
|
2813
|
+
"data-chip": "1",
|
|
2814
|
+
style: hide ? { display: "none" } : void 0,
|
|
2815
|
+
className: `dshm-chip${active === c.id ? " on" : ""}${c.count === 0 ? " zero" : ""}`,
|
|
2816
|
+
onClick: () => onPick(active === c.id ? null : c.id)
|
|
2817
|
+
},
|
|
2818
|
+
// 0.9.45 U3/U7:0 计数桶显式渲染「0」+ 降透明(社区区 chip 计数恒 >0,行为不变)
|
|
2819
|
+
`${c.labelKey ? lookup(c.labelKey) : c.label} ${c.count || 0}`
|
|
2820
|
+
);
|
|
2805
2821
|
return h(
|
|
2806
2822
|
React.Fragment,
|
|
2807
2823
|
null,
|
|
@@ -2818,12 +2834,15 @@ function ZoneChips({ zone, counts, labels, active, onPick, trailing, wrapTitle }
|
|
|
2818
2834
|
"div",
|
|
2819
2835
|
{
|
|
2820
2836
|
ref: wrapRef,
|
|
2821
|
-
className: `dshm-chips${clip ? " dshm-chips-clip" : ""}${
|
|
2837
|
+
className: `dshm-chips${clip ? " dshm-chips-clip" : ""}${filterPinned ? " dshm-chips-gutter" : ""}`,
|
|
2822
2838
|
title: wrapTitle || void 0,
|
|
2823
2839
|
style: { maxHeight: clip ? `${maxH}px` : "none" }
|
|
2824
2840
|
},
|
|
2825
2841
|
h("button", { "data-chip": "1", className: `dshm-chip${active == null ? " on" : ""}`, onClick: () => onPick(null) }, lookup("cat.all")),
|
|
2826
|
-
...chips.map((c, i) => btn(c, i)),
|
|
2842
|
+
...chips.slice(0, visCount).map((c, i) => btn(c, i, false)),
|
|
2843
|
+
clip && chips.length > 0 && hiddenCount > 0 ? h("button", { key: "more", "data-more": "1", className: "dshm-chip", onClick: () => setExpanded(true) }, `+${hiddenCount}`) : null,
|
|
2844
|
+
...chips.slice(visCount).map((c, i) => btn(c, visCount + i, clip)),
|
|
2845
|
+
// hide 仅折叠态生效;展开态全量可见
|
|
2827
2846
|
expanded ? [
|
|
2828
2847
|
h("button", {
|
|
2829
2848
|
key: "collapse",
|
|
@@ -2839,18 +2858,14 @@ function ZoneChips({ zone, counts, labels, active, onPick, trailing, wrapTitle }
|
|
|
2839
2858
|
trailing || null
|
|
2840
2859
|
] : null
|
|
2841
2860
|
),
|
|
2842
|
-
//
|
|
2843
|
-
|
|
2844
|
-
// ⚠️ 展开态不用 overlay(⌃/筛选 in-flow,与现状一致);弹层锚点 .dsvm-filterwrap 随组定位。
|
|
2845
|
-
clip && overlay ? h(
|
|
2861
|
+
// 折叠态钉住的筛选触发器(gutter 几何保证与 chip 零相交;叠涂 scrim 强化浅色对比度,评审 R1 后主人优化②)
|
|
2862
|
+
filterPinned ? h(
|
|
2846
2863
|
"div",
|
|
2847
2864
|
{
|
|
2848
2865
|
className: "dsvm-chipmore",
|
|
2849
|
-
// 评审 R1-Q4:按行高垂直居中于末可见行(28px 组盒在 22px 行高上居中 → bottom 补偿 -3px)
|
|
2850
2866
|
style: { bottom: `${8 + ((rowHeight || 22) - 28) / 2}px` }
|
|
2851
2867
|
},
|
|
2852
|
-
trailing || null
|
|
2853
|
-
hiddenCount > 0 ? h("button", { className: "dshm-chip", onClick: () => setExpanded(true) }, `+${hiddenCount}`) : null
|
|
2868
|
+
trailing || null
|
|
2854
2869
|
) : null
|
|
2855
2870
|
)
|
|
2856
2871
|
);
|