dsh-m 0.9.58 → 0.9.59
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 +12 -0
- package/lib/client.js +19 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,12 @@ The full release history of dsh-m, maintained bilingually: **Chinese first, Engl
|
|
|
8
8
|
|
|
9
9
|
## 中文
|
|
10
10
|
|
|
11
|
+
### 0.9.59 优化:分类行左缘内缩 8px + 全屏下空转 ⌃ 收起钮按行数派生隐藏
|
|
12
|
+
|
|
13
|
+
- **分类行内缩(`f42e5be`)**:分类 chips 行与搜索框/卡片左缘齐平,小颗粒胶囊贴着大元素左缘视觉憋仄;分类行整体右移 8px 留出呼吸空间。仅作用分类行(ZoneChips),上方分区 chips 行不随动。`offsetLeft` 与 absolute 定位同以 `.dshm-chips` 的 padding 盒为原点 → `+N` 跟随、右侧筛选钉位、`offsetTop` 裁剪几何均不受影响。
|
|
14
|
+
- **⌃ 空转修复(`7cbdf11`)**:全屏等宽容器下分类 chips 可能排进 ≤ maxRows(2)行,展开态 `⌃` 收起钮点击后布局零变化(`hiddenCount=0` 连 `+N` 都不会出现),成死按钮。新增展开态行数测量 `expRows`(复用 `chipRows` 纯函数,measure 展开态分支只写 `expRows` 不动 `geom`),`⌃` 仅当展开行数 > maxRows 时渲染;ResizeObserver 在展开态也挂载——全屏↔窗口切换的宽度变化正是重测触发源,全屏下 `⌃` 自动隐藏、退回窗口自动恢复,行数含 `⌃` 自身故显隐收敛不振荡。
|
|
15
|
+
- **验证**:1224 项测试全绿;真实 DSH Web 实测窗口/全屏两态 `⌃` 显隐与收起行为、分类行 8px 内缩生效。
|
|
16
|
+
|
|
11
17
|
### 0.9.58 优化:+N 动态紧跟末可见分类,并与其框高一致
|
|
12
18
|
|
|
13
19
|
- **位置(`4ade54f`)**:在 0.9.57 的独立安全槽位中,根据末可见分类 chip 的实测右缘设置 `+N` 左缘 = 右缘 + 6px;槽位由 52px 扩为 60px,窄宽时仍不与分类或筛选重叠。精选区没有筛选时不额外预留筛选 gutter;展开态 `⌃` 仍位于列表尾部。
|
|
@@ -432,6 +438,12 @@ The full release history of dsh-m, maintained bilingually: **Chinese first, Engl
|
|
|
432
438
|
|
|
433
439
|
## English
|
|
434
440
|
|
|
441
|
+
### Improved in 0.9.59 — 8px category-row inset and a derived visibility for the no-op collapse toggle
|
|
442
|
+
|
|
443
|
+
- **Category-row inset (`f42e5be`)**: the category chip row sat flush with the search box and card grid, and small pills hugging large elements felt cramped; the row now starts 8px further right for breathing room. Only the category row (ZoneChips) moves — the zone chip row above stays put. `offsetLeft` and absolute positioning share the `.dshm-chips` padding-box origin, so `+N` tracking, the pinned Filter trigger and `offsetTop`-based clip geometry are all unaffected.
|
|
444
|
+
- **No-op `⌃` fix (`7cbdf11`)**: at fullscreen width all category chips can fit within maxRows (2) rows, where clicking the expanded-state `⌃` collapse toggle changed nothing visually (`hiddenCount=0`, not even a `+N` appears) — a dead button. Added an expanded-state row measurement `expRows` (reusing the pure `chipRows` helper; the expanded measure branch only writes `expRows`, never `geom`), and `⌃` renders only when expanded rows exceed maxRows. The ResizeObserver now also observes while expanded — the width change of fullscreen↔window switches is exactly the remeasure trigger — so `⌃` hides itself in fullscreen and returns back in the window; counting includes `⌃` itself, so visibility converges without oscillation.
|
|
445
|
+
- **Verification**: 1224 tests pass; verified against real DSH Web for `⌃` visibility and collapse behavior in both window and fullscreen, and for the 8px category-row inset.
|
|
446
|
+
|
|
435
447
|
### Improved in 0.9.58 — the +N toggle follows the last visible category at matching height
|
|
436
448
|
|
|
437
449
|
- **Position (`4ade54f`)**: within the 0.9.57 reserved, overlap-free slot, position `+N` from the measured right edge of the last visible category chip plus 6px. The slot grows from 52px to 60px to preserve clearance at narrow widths. Curated rows without a Filter trigger still reserve no unnecessary Filter gutter; expanded `⌃` remains at list end.
|
package/lib/client.js
CHANGED
|
@@ -1573,7 +1573,7 @@ var h = React.createElement;
|
|
|
1573
1573
|
var { useState, useEffect, useLayoutEffect, useCallback, useMemo, useRef } = React;
|
|
1574
1574
|
var PLUGIN_ID = "dsh-m";
|
|
1575
1575
|
var API = "/dshm";
|
|
1576
|
-
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, countBeyondRows: countBeyondRows2, clipTopOf: clipTopOf2, visibleRowTop: visibleRowTop2, autoExpandDecision: autoExpandDecision2 } = (init_market_state(), __toCommonJS(market_state_exports));
|
|
1576
|
+
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, clipTopOf: clipTopOf2, visibleRowTop: visibleRowTop2, autoExpandDecision: autoExpandDecision2 } = (init_market_state(), __toCommonJS(market_state_exports));
|
|
1577
1577
|
var { readMarketSnapshot: readMarketSnapshot2, writeMarketSnapshot: writeMarketSnapshot2, isDefaultFirstPageQuery: isDefaultFirstPageQuery2 } = (init_market_snapshot(), __toCommonJS(market_snapshot_exports));
|
|
1578
1578
|
var { backdropCloseHandlers: backdropCloseHandlers2 } = (init_backdrop(), __toCommonJS(backdrop_exports));
|
|
1579
1579
|
var { createMarkdown: createMarkdown2 } = (init_markdown(), __toCommonJS(markdown_exports));
|
|
@@ -2230,6 +2230,10 @@ var CSS = `
|
|
|
2230
2230
|
.dshm-chip:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(38,49,72,.06))}
|
|
2231
2231
|
.dshm-chip.on{background:var(--dsw-specific-sidebar-nav-item-active,rgba(38,49,72,.08));border-color:transparent;color:var(--dsw-alias-label-primary,inherit);font-weight:500}
|
|
2232
2232
|
.dsvm-chipswrap{position:sticky;top:-14px;z-index:5;background:var(--dsw-alias-bg-base,#fff);padding:8px 0;margin:-8px 0;border-bottom:1px solid var(--dsw-alias-border-l1,rgba(127,127,127,.14))}
|
|
2233
|
+
/* 0.9.59 \u5206\u7C7B\u884C\u5DE6\u7F18\u5185\u7F29 8px\uFF1A\u4E0E\u641C\u7D22\u6846/\u5361\u7247\u5DE6\u7F18\u9F50\u5E73\u65F6\u80F6\u56CA\u884C\u89C6\u89C9\u618B\u4EC4\uFF0C\u6574\u4F53\u53F3\u79FB\u7559\u51FA\u547C\u5438\u7A7A\u95F4\u3002
|
|
2234
|
+
\u4EC5\u4F5C\u7528\u5206\u7C7B\u884C\uFF08ZoneChips\uFF09\uFF0C\u4E0A\u65B9\u5206\u533A chips \u884C\u4E0D\u968F\u52A8\uFF1BoffsetLeft \u4E0E absolute \u5B9A\u4F4D\u540C\u4EE5
|
|
2235
|
+
.dshm-chips \u7684 padding \u76D2\u4E3A\u539F\u70B9 \u2192 +N \u8DDF\u968F\u3001\u53F3\u4FA7\u7B5B\u9009\u9489\u4F4D\u3001offsetTop \u88C1\u526A\u51E0\u4F55\u5747\u4E0D\u53D7\u5F71\u54CD\u3002 */
|
|
2236
|
+
.dsvm-chipswrap .dshm-chips{padding-left:8px}
|
|
2233
2237
|
.dsvm-pagejump{display:inline-flex;align-items:center;gap:4px;margin-left:8px}
|
|
2234
2238
|
.dsvm-pagejump-input{width:56px;height:24px;box-sizing:border-box;border:1px solid var(--dsw-alias-border-l1,rgba(127,127,127,.28));background:transparent;color:var(--dsw-alias-label-secondary,#4b5563);border-radius:999px;padding:0 10px;font:inherit;font-size:12px;outline:none;text-align:center;transition:border-color .15s,color .15s}
|
|
2235
2239
|
.dsvm-pagejump-input:hover{color:var(--dsw-alias-label-primary,inherit)}
|
|
@@ -2732,6 +2736,7 @@ function ZoneChips({ zone, counts, labels, active, onPick, trailing, wrapTitle }
|
|
|
2732
2736
|
const chipsSignature = JSON.stringify(chips.map((c) => [c.id, c.labelKey ? lookup(c.labelKey) : c.label, c.count]));
|
|
2733
2737
|
const [expanded, setExpanded] = useState(false);
|
|
2734
2738
|
const [stuck, setStuck] = useState(false);
|
|
2739
|
+
const [expRows, setExpRows] = useState(0);
|
|
2735
2740
|
const [geom, setGeom] = useState(null);
|
|
2736
2741
|
const [rowHeight, setRowHeight] = useState(0);
|
|
2737
2742
|
const wrapRef = useRef(null);
|
|
@@ -2742,7 +2747,7 @@ function ZoneChips({ zone, counts, labels, active, onPick, trailing, wrapTitle }
|
|
|
2742
2747
|
const maxH = maxRows * (rowHeight || 22) + (maxRows - 1) * 6;
|
|
2743
2748
|
const measure = useCallback(() => {
|
|
2744
2749
|
const el = wrapRef.current;
|
|
2745
|
-
if (!el
|
|
2750
|
+
if (!el) return;
|
|
2746
2751
|
const tops = [];
|
|
2747
2752
|
let rh = 0;
|
|
2748
2753
|
for (const k of el.children) {
|
|
@@ -2751,6 +2756,11 @@ function ZoneChips({ zone, counts, labels, active, onPick, trailing, wrapTitle }
|
|
|
2751
2756
|
if (!rh && k.offsetHeight) rh = k.offsetHeight;
|
|
2752
2757
|
}
|
|
2753
2758
|
if (!tops.length) return;
|
|
2759
|
+
if (expanded) {
|
|
2760
|
+
const rows = chipRows2(tops);
|
|
2761
|
+
setExpRows((prev) => prev === rows ? prev : rows);
|
|
2762
|
+
return;
|
|
2763
|
+
}
|
|
2754
2764
|
setGeom((prev) => {
|
|
2755
2765
|
const clipTopV = clipTopOf2(tops, maxRows);
|
|
2756
2766
|
const hiddenCount2 = countBeyondRows2(tops, maxRows);
|
|
@@ -2784,7 +2794,7 @@ function ZoneChips({ zone, counts, labels, active, onPick, trailing, wrapTitle }
|
|
|
2784
2794
|
if (d.expand) setExpanded(true);
|
|
2785
2795
|
}, [active, activeIdx, expanded, geom]);
|
|
2786
2796
|
useLayoutEffect(() => {
|
|
2787
|
-
|
|
2797
|
+
measure();
|
|
2788
2798
|
}, [chipsSignature, active, expanded, zone, stuck, rowHeight, measure]);
|
|
2789
2799
|
useEffect(() => {
|
|
2790
2800
|
if (expanded || !geom || typeof requestAnimationFrame !== "function") return;
|
|
@@ -2793,7 +2803,7 @@ function ZoneChips({ zone, counts, labels, active, onPick, trailing, wrapTitle }
|
|
|
2793
2803
|
}, [geom, expanded, measure]);
|
|
2794
2804
|
useEffect(() => {
|
|
2795
2805
|
const el = wrapRef.current;
|
|
2796
|
-
if (!el ||
|
|
2806
|
+
if (!el || typeof ResizeObserver === "undefined") return;
|
|
2797
2807
|
let raf = 0;
|
|
2798
2808
|
const ro = new ResizeObserver(() => {
|
|
2799
2809
|
cancelAnimationFrame(raf);
|
|
@@ -2804,7 +2814,7 @@ function ZoneChips({ zone, counts, labels, active, onPick, trailing, wrapTitle }
|
|
|
2804
2814
|
ro.disconnect();
|
|
2805
2815
|
cancelAnimationFrame(raf);
|
|
2806
2816
|
};
|
|
2807
|
-
}, [
|
|
2817
|
+
}, [measure]);
|
|
2808
2818
|
useEffect(() => {
|
|
2809
2819
|
if (expanded || typeof document === "undefined" || !document.fonts?.ready) return;
|
|
2810
2820
|
let cancelled = false;
|
|
@@ -2878,7 +2888,9 @@ function ZoneChips({ zone, counts, labels, active, onPick, trailing, wrapTitle }
|
|
|
2878
2888
|
onClick: () => setExpanded(true)
|
|
2879
2889
|
}, `+${hiddenCount}`) : null,
|
|
2880
2890
|
expanded ? [
|
|
2881
|
-
|
|
2891
|
+
// 0.9.59:仅当展开布局真实超过 maxRows 行才渲染 ⌃——否则收起是零变化空操作(死按钮)。
|
|
2892
|
+
// 行数含 ⌃ 自身:若它恰好独占一行,隐藏后行数回落仍 ≤ maxRows,显隐收敛不振荡。
|
|
2893
|
+
expRows > maxRows ? h("button", {
|
|
2882
2894
|
key: "collapse",
|
|
2883
2895
|
"data-chip": "1",
|
|
2884
2896
|
className: "dshm-chip",
|
|
@@ -2888,7 +2900,7 @@ function ZoneChips({ zone, counts, labels, active, onPick, trailing, wrapTitle }
|
|
|
2888
2900
|
if (active) autoRef.current = active;
|
|
2889
2901
|
setExpanded(false);
|
|
2890
2902
|
}
|
|
2891
|
-
}, "\u2303"),
|
|
2903
|
+
}, "\u2303") : null,
|
|
2892
2904
|
trailing || null
|
|
2893
2905
|
] : null
|
|
2894
2906
|
),
|