@stapel/listings-react 0.26.0 → 0.27.0

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/MODULE.md +3 -1
  3. package/README.md +46 -1
  4. package/dist/api/generated/schema.d.ts +20 -10
  5. package/dist/api/generated/schema.d.ts.map +1 -1
  6. package/dist/default/ListingDetailPane.d.ts +96 -8
  7. package/dist/default/ListingDetailPane.d.ts.map +1 -1
  8. package/dist/default/ListingDetailPane.js +127 -17
  9. package/dist/default/ListingDetailPane.js.map +1 -1
  10. package/dist/default/MyListingsPane.d.ts.map +1 -1
  11. package/dist/default/MyListingsPane.js +10 -6
  12. package/dist/default/MyListingsPane.js.map +1 -1
  13. package/dist/default/detailGallery.d.ts +77 -0
  14. package/dist/default/detailGallery.d.ts.map +1 -0
  15. package/dist/default/detailGallery.js +91 -0
  16. package/dist/default/detailGallery.js.map +1 -0
  17. package/dist/default/index.d.ts +3 -1
  18. package/dist/default/index.d.ts.map +1 -1
  19. package/dist/default/index.js +4 -0
  20. package/dist/default/index.js.map +1 -1
  21. package/dist/default/movableCluster.d.ts +18 -0
  22. package/dist/default/movableCluster.d.ts.map +1 -0
  23. package/dist/default/movableCluster.js +110 -0
  24. package/dist/default/movableCluster.js.map +1 -0
  25. package/dist/headless/MyListings.d.ts +31 -10
  26. package/dist/headless/MyListings.d.ts.map +1 -1
  27. package/dist/headless/MyListings.js +19 -2
  28. package/dist/headless/MyListings.js.map +1 -1
  29. package/dist/model/status.d.ts +31 -16
  30. package/dist/model/status.d.ts.map +1 -1
  31. package/dist/model/status.js +30 -15
  32. package/dist/model/status.js.map +1 -1
  33. package/llms.txt +1 -1
  34. package/manifest.json +1 -1
  35. package/nav-manifest.json +1 -1
  36. package/package.json +3 -3
  37. package/src/analytics/generated/events.json +1 -1
  38. package/src/api/generated/schema.ts +20 -10
  39. package/src/default/ListingDetailPane.tsx +259 -15
  40. package/src/default/MyListingsPane.tsx +10 -6
  41. package/src/default/detailGallery.ts +97 -0
  42. package/src/default/index.ts +14 -1
  43. package/src/default/movableCluster.tsx +137 -0
  44. package/src/headless/MyListings.tsx +52 -12
  45. package/src/model/status.ts +31 -16
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/default/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,OAAO,EACL,WAAW;AACX,6EAA6E;AAC7E,6EAA6E;AAC7E,oBAAoB,EACpB,sBAAsB;AACtB,0EAA0E;AAC1E,4EAA4E;AAC5E,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAO1B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAMvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAKvD,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE5D,OAAO,EACL,iBAAiB,EACjB,cAAc;AACd,wEAAwE;AACxE,+DAA+D;AAC/D,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,mBAAmB,EACnB,0BAA0B,EAC1B,gBAAgB,EAChB,eAAe,GAChB,MAAM,0BAA0B,CAAC;AASlC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAOvE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEnF,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAG3B,gFAAgF;AAChF,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG3D,+EAA+E;AAC/E,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,cAAc,EACd,YAAY,EACZ,SAAS,EACT,cAAc,GACf,MAAM,kBAAkB,CAAC;AAE1B,+EAA+E;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAKrD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EACL,qBAAqB,EACrB,6BAA6B,EAC7B,0BAA0B,EAC1B,oBAAoB,EACpB,kBAAkB,EAClB,0BAA0B,EAC1B,yBAAyB,EACzB,uBAAuB,EACvB,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/default/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,OAAO,EACL,WAAW;AACX,6EAA6E;AAC7E,6EAA6E;AAC7E,oBAAoB,EACpB,sBAAsB;AACtB,0EAA0E;AAC1E,4EAA4E;AAC5E,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAO1B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAMvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAKvD,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE5D,OAAO,EACL,iBAAiB,EACjB,cAAc;AACd,wEAAwE;AACxE,+DAA+D;AAC/D,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAKhC,8EAA8E;AAC9E,+EAA+E;AAC/E,oBAAoB;AACpB,OAAO,EACL,sBAAsB,EACtB,2BAA2B,EAC3B,4BAA4B,EAC5B,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,mBAAmB,EACnB,0BAA0B,EAC1B,gBAAgB,EAChB,eAAe,GAChB,MAAM,0BAA0B,CAAC;AASlC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAOvE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEnF,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAG3B,gFAAgF;AAChF,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG3D,+EAA+E;AAC/E,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,cAAc,EACd,YAAY,EACZ,SAAS,EACT,cAAc,GACf,MAAM,kBAAkB,CAAC;AAE1B,+EAA+E;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAKrD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EACL,qBAAqB,EACrB,6BAA6B,EAC7B,0BAA0B,EAC1B,oBAAoB,EACpB,kBAAkB,EAClB,0BAA0B,EAC1B,yBAAyB,EACzB,uBAAuB,EACvB,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { ReactElement, ReactNode } from "react";
2
+ export interface MovableCluster {
3
+ /**
4
+ * True when there is a document to portal into. `false` under SSR, where
5
+ * the caller renders the cluster inline at its primary placement instead —
6
+ * a server render has no scrolling and therefore no second placement.
7
+ */
8
+ readonly portable: boolean;
9
+ /** Render the cluster ONCE, anywhere in the tree. Returns the portal. */
10
+ render(cluster: ReactNode): ReactNode;
11
+ /**
12
+ * A mount point. The highest `priority` currently on screen holds the
13
+ * cluster; when it goes, the next one down gets it back.
14
+ */
15
+ slot(priority: number, name: string): ReactElement;
16
+ }
17
+ export declare function useMovableCluster(enabled: boolean): MovableCluster;
18
+ //# sourceMappingURL=movableCluster.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"movableCluster.d.ts","sourceRoot":"","sources":["../../src/default/movableCluster.tsx"],"names":[],"mappings":"AAoDA,OAAO,KAAK,EAAiB,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMpE,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,yEAAyE;IACzE,MAAM,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,CAAC;IACtC;;;OAGG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CAAC;CACpD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc,CA8DlE"}
@@ -0,0 +1,110 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * ONE CLUSTER, TWO PLACES ON THE PAGE — the same instance, moved.
4
+ *
5
+ * ── The ask this answers, and why the obvious shape does not ──────────────
6
+ *
7
+ * A listing page wants the reader's two verbs beside the title AND in the
8
+ * condensed bar that arrives when the title scrolls away (reference §24). A
9
+ * host cannot do that today: `<ListingDetailPane>` mounts its cluster at
10
+ * exactly one `actionsPlacement`, so a container that wants the second one
11
+ * mounts a `<ListingActions>` of its own — which is a SECOND
12
+ * `useFavoriteToggle` on one page, two hearts that agree only after a refetch,
13
+ * and two copies of a control whose geometry this pair exists to rule once.
14
+ *
15
+ * The shapes that do NOT close it, stated because each looks like it would:
16
+ *
17
+ * a render prop handed the cluster ELEMENT
18
+ * A React element is a description, not an instance. Rendered in two
19
+ * places it mounts twice — exactly the defect, now with the pair's name
20
+ * on it.
21
+ *
22
+ * the host moving one element between two parents
23
+ * React unmounts and remounts across a parent change: the hook state
24
+ * goes, the DOM node is a different node, and an optimistic favourite
25
+ * in flight is lost mid-write.
26
+ *
27
+ * two mounts kept in step by lifting the state
28
+ * Two controls, one state — and then the page has two `aria-pressed`
29
+ * hearts, two focus targets and two things for a probe to count.
30
+ *
31
+ * ── What this does ────────────────────────────────────────────────────────
32
+ *
33
+ * The cluster is rendered ONCE, through a portal, into a `<div>` this hook
34
+ * owns. The page draws SLOTS — empty `display: contents` divs — wherever the
35
+ * cluster may sit, and the container element is `appendChild`-ed into whichever
36
+ * slot is currently on screen with the highest priority. Moving a DOM node
37
+ * between parents is not a React tree change, so:
38
+ *
39
+ * - `<ListingActions>` (and everything under it) mounts exactly once;
40
+ * - the favourite button is literally the SAME `HTMLElement` in both
41
+ * placements — `test/detailActionsPlacements.test.tsx` holds the node
42
+ * across the move and asserts identity, which is the only assertion that
43
+ * can tell this apart from a well-behaved remount;
44
+ * - a slot that unmounts hands the cluster back to the next one down,
45
+ * rather than taking it off the page.
46
+ *
47
+ * `display: contents` on both the slot and the container is load-bearing: the
48
+ * cluster must remain a direct flex item of the heading row (it is laid out by
49
+ * `justify="space-between"`) and must stay absolutely positionable against the
50
+ * gallery's containing block in the overlay arm. A wrapper that generated a
51
+ * box would change both.
52
+ */
53
+ import { useCallback, useEffect, useRef } from "react";
54
+ import { createPortal } from "react-dom";
55
+ /** Neither slot nor container may generate a box — see the file header. */
56
+ const CONTENTS = { display: "contents" };
57
+ export function useMovableCluster(enabled) {
58
+ const container = useRef(null);
59
+ if (enabled && container.current === null && typeof document !== "undefined") {
60
+ const host = document.createElement("div");
61
+ host.style.display = "contents";
62
+ host.setAttribute("data-listings-cluster-portal", "");
63
+ container.current = host;
64
+ }
65
+ const slots = useRef(new Map());
66
+ const refs = useRef(new Map());
67
+ /** Put the container in the highest-priority slot that is on the page. */
68
+ const settle = useCallback(() => {
69
+ const host = container.current;
70
+ if (host === null)
71
+ return;
72
+ let best;
73
+ let bestPriority = -1;
74
+ for (const [priority, node] of slots.current) {
75
+ // `isConnected` matters during a commit that removes a slot: React may
76
+ // hand back a node it is about to drop, and appending into it would take
77
+ // the cluster off the page with it.
78
+ if (node.isConnected && priority > bestPriority) {
79
+ bestPriority = priority;
80
+ best = node;
81
+ }
82
+ }
83
+ if (best !== undefined && host.parentNode !== best)
84
+ best.appendChild(host);
85
+ }, []);
86
+ // The belt. A slot's ref cleanup is what normally moves the cluster, but a
87
+ // subtree removed around it would leave the container detached with nothing
88
+ // to notice; this runs after every commit and repairs that in one comparison.
89
+ useEffect(settle);
90
+ const refFor = useCallback((priority) => {
91
+ let ref = refs.current.get(priority);
92
+ if (ref === undefined) {
93
+ ref = (node) => {
94
+ if (node === null)
95
+ slots.current.delete(priority);
96
+ else
97
+ slots.current.set(priority, node);
98
+ settle();
99
+ };
100
+ refs.current.set(priority, ref);
101
+ }
102
+ return ref;
103
+ }, [settle]);
104
+ return {
105
+ portable: container.current !== null,
106
+ render: (cluster) => container.current === null ? null : createPortal(cluster, container.current),
107
+ slot: (priority, name) => (_jsx("div", { ref: refFor(priority), style: CONTENTS, "data-listings-cluster-slot": name })),
108
+ };
109
+ }
110
+ //# sourceMappingURL=movableCluster.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"movableCluster.js","sourceRoot":"","sources":["../../src/default/movableCluster.tsx"],"names":[],"mappings":"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"}
@@ -21,13 +21,23 @@ import type { MyListingsAddress } from "../model/tabAddress.js";
21
21
  * `blockedRows` is fetched beside them, off the same route, narrowed to
22
22
  * whatever `MY_LISTINGS_UNTABBED_STATUSES` derives.
23
23
  *
24
- * That second read is also the fourth tab's COUNT (D407). `my/counters` has
25
- * three integers and no fourth, so the removed tab is counted from the rows it
26
- * holds — which is honest exactly because that read is unpaged and runs
27
- * whichever tab is open. The one thing it cannot describe is a page cap: a
28
- * seller with more takedowns than one page of `my/listings` would see the page
29
- * count and not the total, and there is no counter on the wire to check it
30
- * against (see `MyListingsBag.tabCounts`).
24
+ * That second read used to be the fourth tab's COUNT as well (D407):
25
+ * `my/counters` had three integers and no fourth, so the removed tab was
26
+ * counted from the rows it holds — honest, because that read is unpaged and
27
+ * runs whichever tab is open, and blind to exactly one thing: a page cap. A
28
+ * seller with more takedowns than one page of `my/listings` saw the page count
29
+ * and not the total, and there was no counter on the wire to check it against.
30
+ *
31
+ * **stapel-listings 0.22.4 answers it**: `MyCountersResponse.blocked`, required
32
+ * beside the other three, over the same owner scope and the same grouping. So
33
+ * the tab's number is the SERVER's now and the unpaged read is what it always
34
+ * was underneath — the removed tab's ROWS. The two consequences are both
35
+ * visible: the tab appears from the counter (a beat earlier, and without the
36
+ * seller's whole takedown page having to land first), and a seller with more
37
+ * takedowns than fit on a page is told how many there are rather than how many
38
+ * arrived. A deployment on a server older than 0.22.4 sends no `blocked` at
39
+ * all, and then the rows are the count again — degraded to the previous
40
+ * answer, never to a `0` (see `MyListingsBag.tabCounts`).
31
41
  */
32
42
  export interface MyListingsBag {
33
43
  readonly tab: MyListingsTab;
@@ -37,10 +47,16 @@ export interface MyListingsBag {
37
47
  * The server's three always; the removed one only where there is something
38
48
  * in it or the person asked for it by address. An empty "Taken down" tab is
39
49
  * a scare, and the seller it would scare is the one it has nothing to tell.
50
+ *
51
+ * "Something in it" is `counters.blocked` (stapel-listings 0.22.4) and no
52
+ * longer the unpaged takedown page: the two reads settle independently, and
53
+ * the one that decides whether a tab strip has three tabs or four should be
54
+ * the one that answers in three integers rather than the one that answers in
55
+ * a page of listings.
40
56
  */
41
57
  readonly tabs: readonly MyListingsTab[];
42
58
  setTab(tab: MyListingsTab): void;
43
- /** The three real counts, as the server reports them. */
59
+ /** The four real counts, as the server reports them. */
44
60
  readonly counters: LoadState<MyCounters>;
45
61
  /**
46
62
  * The number to DRAW on each tab — the server's counter, raised to what is
@@ -60,8 +76,13 @@ export interface MyListingsBag {
60
76
  *
61
77
  * The second half: a takedown was in no tab and therefore in no number, so
62
78
  * a cabinet holding one read "Active 0 · Drafts 0 · Archived 0" over it.
63
- * `removed` is counted from `blockedRows` there is no server counter to
64
- * read, and the rows are the only evidence on the wire.
79
+ * `removed` was counted from `blockedRows`, because there was no server
80
+ * counter to read and the rows were the only evidence on the wire. There is
81
+ * one now — `MyCountersResponse.blocked`, stapel-listings 0.22.4 — and it is
82
+ * what the fourth tab draws, under the same floor as the other three: the
83
+ * open tab's number is never below the rows on screen. `blockedRows` stays
84
+ * the FALLBACK for a deployment whose server predates the field, which is a
85
+ * count that is right up to a page and never a `0` over a visible row.
65
86
  */
66
87
  readonly tabCounts: LoadState<Readonly<Record<MyListingsTab, number>>>;
67
88
  /** The rows for the current tab — {@link MyListingsBag.blockedRows} while
@@ -1 +1 @@
1
- {"version":3,"file":"MyListings.d.ts","sourceRoot":"","sources":["../../src/headless/MyListings.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAUrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAChB,UAAU,EACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAU/D,OAAO,KAAK,EAAwB,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAIhE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,SAAS,aAAa,EAAE,CAAC;IACxC,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAAC;IACjC,yDAAyD;IACzD,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACzC;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACvE;2EACuE;IACvE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,aAAa,EAAE,CAAC,CAAC;IACnD;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC,SAAS,aAAa,EAAE,CAAC,CAAC;IAC1D,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IACtC,MAAM,IAAI,IAAI,CAAC;IACf,MAAM,IAAI,IAAI,CAAC;IACf,qDAAqD;IACrD,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC;oFACgF;IAChF,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC;CACtC;AAED,wBAAgB,aAAa,CAC3B,OAAO,GAAE,oBAAyB,GACjC,aAAa,CAqJf;AAED,oDAAoD;AACpD,wBAAgB,UAAU,CACxB,KAAK,EAAE,oBAAoB,GAAG;IAC5B,QAAQ,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,SAAS,CAAC;CAC7C,GACA,YAAY,CAGd"}
1
+ {"version":3,"file":"MyListings.d.ts","sourceRoot":"","sources":["../../src/headless/MyListings.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAUrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAChB,UAAU,EACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAU/D,OAAO,KAAK,EAAwB,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAIhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;IAC5B;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,IAAI,EAAE,SAAS,aAAa,EAAE,CAAC;IACxC,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAAC;IACjC,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACzC;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACvE;2EACuE;IACvE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,aAAa,EAAE,CAAC,CAAC;IACnD;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC,SAAS,aAAa,EAAE,CAAC,CAAC;IAC1D,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IACtC,MAAM,IAAI,IAAI,CAAC;IACf,MAAM,IAAI,IAAI,CAAC;IACf,qDAAqD;IACrD,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC;oFACgF;IAChF,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC;CACtC;AAED,wBAAgB,aAAa,CAC3B,OAAO,GAAE,oBAAyB,GACjC,aAAa,CAwKf;AAED,oDAAoD;AACpD,wBAAgB,UAAU,CACxB,KAAK,EAAE,oBAAoB,GAAG;IAC5B,QAAQ,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,SAAS,CAAC;CAC7C,GACA,YAAY,CAGd"}
@@ -67,7 +67,15 @@ export function useMyListings(options = {}) {
67
67
  // The takedown count, when it is known. Not a `0` while the read is in
68
68
  // flight: the tab strip is drawn off this number and a tab that appeared a
69
69
  // beat after the page settled would move the three beside it.
70
- const blockedCount = blockedRows.status === "ready" ? blockedRows.data.length : undefined;
70
+ //
71
+ // The SERVER's integer first (stapel-listings 0.22.4), the unpaged page's
72
+ // length only where a deployment's backend predates it. `counters.data` is
73
+ // typed with `blocked` required, so the runtime check is the honest one and
74
+ // not a type-driven one: an older server answers 200 with three keys, and a
75
+ // `?? 0` there would print "Taken down 0" over a row the seller can see.
76
+ const rowsBlockedCount = blockedRows.status === "ready" ? blockedRows.data.length : undefined;
77
+ const serverBlockedCount = typeof counters.data?.blocked === "number" ? counters.data.blocked : undefined;
78
+ const blockedCount = serverBlockedCount ?? rowsBlockedCount;
71
79
  // Paging belongs to the tab's own keyset read. The takedowns are fetched
72
80
  // unpaged on purpose, so the removed tab has nowhere to go and says so.
73
81
  const envelope = removed ? undefined : rowsQuery.data;
@@ -86,12 +94,21 @@ export function useMyListings(options = {}) {
86
94
  one,
87
95
  one === tab ? Math.max(server[one], visible) : server[one],
88
96
  ])),
89
- [MY_LISTINGS_REMOVED_TAB]: blockedCount ?? 0,
97
+ // The fourth tab takes the same floor as the other three: the server's
98
+ // number, raised to what is on screen while this tab is the open one.
99
+ // The counter and the unpaged page are two reads of one set and either
100
+ // may be the staler — a badge under its own rows is not a count.
101
+ [MY_LISTINGS_REMOVED_TAB]: tab === MY_LISTINGS_REMOVED_TAB
102
+ ? Math.max(blockedCount ?? 0, visible)
103
+ : (blockedCount ?? 0),
90
104
  });
91
105
  }, [counters.status, counters.error, counters.data, rows, tab, blockedCount]);
92
106
  // The removed tab is drawn where it has something to say — or where the
93
107
  // address named it, so `?tab=removed` opens a real (if empty) tab rather
94
108
  // than an activeKey pointing at nothing.
109
+ //
110
+ // "Something to say" is the COUNTER since 0.22.4, so the tab arrives with
111
+ // `my/counters` rather than waiting for a page of takedowns to come back.
95
112
  const tabs = removed || (blockedCount ?? 0) > 0 ? MY_LISTINGS_TABS : MY_LISTINGS_COUNTED_TABS;
96
113
  return {
97
114
  tab,
@@ -1 +1 @@
1
- {"version":3,"file":"MyListings.js","sourceRoot":"","sources":["../../src/headless/MyListings.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EACL,eAAe,EACf,aAAa,EACb,UAAU,EACV,WAAW,EACX,SAAS,EACT,qBAAqB,GACtB,MAAM,cAAc,CAAC;AAOtB,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EACL,wBAAwB,EACxB,uBAAuB,EACvB,gBAAgB,EAChB,6BAA6B,GAC9B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AA2GrD,MAAM,UAAU,aAAa,CAC3B,UAAgC,EAAE;IAElC,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;IAC9B,MAAM,YAAY,GAAG,qBAAqB,EAAE,CAAC;IAC7C,2EAA2E;IAC3E,4EAA4E;IAC5E,6EAA6E;IAC7E,uDAAuD;IACvD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,cAAc,EAAE,CAAC;IACpD,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,GAAG,QAAQ,CACjC,GAAG,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,UAAU,IAAI,QAAQ,CACtE,CAAC;IACF,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAC9B,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAC5D,CAAC;IAEF,MAAM,QAAQ,GAAG,aAAa,EAAE,CAAC;IACjC,MAAM,GAAG,GAAG,cAAc,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAChC,MAAM,MAAM,GAAG,OAAO,CACpB,GAAG,EAAE,CAAC,QAAQ,IAAI,uBAAuB,CAAC,GAAG,CAAC,EAC9C,CAAC,QAAQ,EAAE,GAAG,CAAC,CAChB,CAAC;IACF,MAAM,KAAK,GAAG,YAAY,IAAI,IAAI,CAAC,SAAS,CAAC;IAC7C,sEAAsE;IACtE,4EAA4E;IAC5E,8DAA8D;IAC9D,MAAM,OAAO,GAAG,GAAG,KAAK,uBAAuB,CAAC;IAChD,MAAM,UAAU,GAAyB,OAAO;QAC9C,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC;QAC7B,CAAC,CAAE,GAA4B,CAAC;IAElC,MAAM,SAAS,GAAG,QAAQ,CAAC;QACzB,QAAQ,EAAE,iBAAiB,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3D,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAClE,OAAO,EAAE,KAAK,IAAI,CAAC,OAAO;QAC1B,KAAK,EAAE,KAAK;KACb,CAAC,CAAC;IAEH,yEAAyE;IACzE,2EAA2E;IAC3E,yDAAyD;IACzD,MAAM,YAAY,GAAG,QAAQ,CAAC;QAC5B,QAAQ,EAAE,iBAAiB,CAAC,YAAY,EAAE;QAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CACtB,GAAG,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,6BAA6B,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;QACvE,OAAO,EAAE,KAAK,IAAI,6BAA6B,CAAC,MAAM,GAAG,CAAC;QAC1D,KAAK,EAAE,KAAK;KACb,CAAC,CAAC;IAEH,MAAM,WAAW,GAAwC,OAAO,CAAC,GAAG,EAAE;QACpE,IAAI,6BAA6B,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC,EAAE,CAAC,CAAC;QACrE,IAAI,YAAY,CAAC,MAAM,KAAK,OAAO;YAAE,OAAO,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC3E,IAAI,YAAY,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/E,OAAO,WAAW,EAAE,CAAC;IACvB,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;IAEjE,MAAM,OAAO,GAAwC,OAAO,CAAC,GAAG,EAAE;QAChE,IAAI,SAAS,CAAC,MAAM,KAAK,OAAO;YAAE,OAAO,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACrE,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzE,OAAO,WAAW,EAAE,CAAC;IACvB,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAExD,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC;IAE7C,uEAAuE;IACvE,2EAA2E;IAC3E,8DAA8D;IAC9D,MAAM,YAAY,GAChB,WAAW,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAEvE,yEAAyE;IACzE,wEAAwE;IACxE,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC;IAEtD,0EAA0E;IAC1E,kEAAkE;IAClE,6BAA6B;IAC7B,MAAM,SAAS,GACb,OAAO,CAAC,GAAG,EAAE;QACX,IAAI,QAAQ,CAAC,MAAM,KAAK,OAAO;YAAE,OAAO,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACnE,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,WAAW,EAAE,CAAC;QACtD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/D,OAAO,SAAS,CAAC;YACf,GAAI,MAAM,CAAC,WAAW,CACpB,wBAAwB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC;gBACpC,GAAG;gBACH,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aAC3D,CAAC,CACgD;YACpD,CAAC,uBAAuB,CAAC,EAAE,YAAY,IAAI,CAAC;SAC7C,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC;IAEhF,wEAAwE;IACxE,yEAAyE;IACzE,yCAAyC;IACzC,MAAM,IAAI,GACR,OAAO,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,wBAAwB,CAAC;IAEnF,OAAO;QACL,GAAG;QACH,IAAI;QACJ,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACf,sEAAsE;YACtE,8DAA8D;YAC9D,mEAAmE;YACnE,iCAAiC;YACjC,OAAO,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACrE,WAAW,CAAC,IAAI,CAAC,CAAC;YAClB,gEAAgE;YAChE,6CAA6C;YAC7C,CAAC,OAAO,CAAC,OAAO,IAAI,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACrD,CAAC;QACD,QAAQ,EACN,QAAQ,CAAC,MAAM,KAAK,OAAO;YACzB,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC;YAC5B,CAAC,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS;gBAC3B,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAC1B,CAAC,CAAC,WAAW,EAAE;QACrB,SAAS;QACT,IAAI;QACJ,WAAW;QACX,IAAI;QACJ,QAAQ,EACN,QAAQ,EAAE,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,WAAW,IAAI,IAAI;YACzD,CAAC,CAAC,eAAe,EAAE;YACnB,CAAC,CAAC,aAAa,CAAC,kBAAkB,CAAC,QAAQ,CAAC;QAChD,QAAQ,EACN,QAAQ,EAAE,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,WAAW,IAAI,IAAI;YACzD,CAAC,CAAC,eAAe,EAAE;YACnB,CAAC,CAAC,aAAa,CAAC,kBAAkB,CAAC,QAAQ,CAAC;QAChD,MAAM,EAAE,GAAG,EAAE;YACX,MAAM,MAAM,GAAG,QAAQ,EAAE,WAAW,CAAC;YACrC,IAAI,MAAM,IAAI,IAAI;gBAAE,OAAO;YAC3B,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,EAAE,GAAG,EAAE;YACX,MAAM,MAAM,GAAG,QAAQ,EAAE,WAAW,CAAC;YACrC,IAAI,MAAM,IAAI,IAAI;gBAAE,OAAO;YAC3B,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QACpE,CAAC;QACD,IAAI;QACJ,OAAO,EAAE,GAAG,EAAE;YACZ,KAAK,QAAQ,CAAC,OAAO,EAAE,CAAC;YACxB,KAAK,SAAS,CAAC,OAAO,EAAE,CAAC;YACzB,KAAK,YAAY,CAAC,OAAO,EAAE,CAAC;QAC9B,CAAC;KACF,CAAC;AACJ,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,UAAU,CACxB,KAEC;IAED,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO,4BAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAI,CAAC;AACpC,CAAC"}
1
+ {"version":3,"file":"MyListings.js","sourceRoot":"","sources":["../../src/headless/MyListings.tsx"],"names":[],"mappings":"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"}
@@ -67,8 +67,8 @@ export interface ListingStatusView {
67
67
  }
68
68
  export declare function listingStatusView(status: ListingLifecycleStatus, moderationStatus: ListingModerationStatus): ListingStatusView;
69
69
  /**
70
- * The three tabs `my/counters` COUNTS, and the statuses each one folds
71
- * together.
70
+ * The three tabs whose ROWS come off a keyset page, and the statuses each one
71
+ * folds together.
72
72
  *
73
73
  * The grouping is the SERVER's (`views.my_counters`), copied here so a tab's
74
74
  * caption and its count cannot describe different sets: `active` includes
@@ -76,21 +76,32 @@ export declare function listingStatusView(status: ListingLifecycleStatus, modera
76
76
  * both because a listing in those states is something the owner is still
77
77
  * working on. A client that grouped them its own way would show "3 active"
78
78
  * over two rows.
79
+ *
80
+ * The name is about the SOURCE, not about the counter: `MyCountersResponse`
81
+ * carries four integers since stapel-listings 0.22.4 (`blocked` joined the
82
+ * three), and this is still the set a {@link MyListingsCountedTab} —
83
+ * `MyListingsSource`'s whole parameter type — may name. The removed tab reads
84
+ * its rows off `?status=blocked` directly and unpaged, so a host that
85
+ * implemented the seam before the fourth tab existed is never handed it.
79
86
  */
80
87
  export declare const MY_LISTINGS_COUNTED_TABS: readonly ["active", "drafts", "archived"];
81
- /** One of the three tabs `MyCountersResponse` carries a number for. */
88
+ /** One of the three tabs a `MyListingsSource` is asked for. */
82
89
  export type MyListingsCountedTab = (typeof MY_LISTINGS_COUNTED_TABS)[number];
83
- /** Which of the three COUNTED tabs a status belongs to, or `undefined` for
84
- * one the server's own counter groups nowhere — `blocked`, today. */
90
+ /** Which of the three keyset-paged tabs a status belongs to, or `undefined`
91
+ * for one none of them folds in — `blocked`, today, which has a tab and a
92
+ * counter of its own and a different row source under it. */
85
93
  export declare function countedTabOf(status: ListingLifecycleStatus): MyListingsCountedTab | undefined;
86
94
  /**
87
- * The statuses the server's own counter groups nowhere — `blocked`, and
88
- * nothing else today.
95
+ * The statuses none of the three paged tabs folds in — `blocked`, and nothing
96
+ * else today.
89
97
  *
90
98
  * DERIVED, not written down a second time: a status added upstream and left
91
- * out of the counter groupings lands here automatically and gets shown, which
92
- * is the opposite of what a hardcoded `["blocked"]` would do the day it goes
93
- * stale.
99
+ * out of the tab groupings lands here automatically and gets shown, which is
100
+ * the opposite of what a hardcoded `["blocked"]` would do the day it goes
101
+ * stale. That the server now has a `blocked` COUNTER for the same set does not
102
+ * make the derivation redundant: the counter names one status and this names
103
+ * whatever the three groupings leave over, which is the set the fourth tab
104
+ * must ASK for.
94
105
  */
95
106
  export declare const MY_LISTINGS_UNTABBED_STATUSES: readonly ListingLifecycleStatus[];
96
107
  /**
@@ -112,12 +123,16 @@ export declare const MY_LISTINGS_UNTABBED_STATUSES: readonly ListingLifecycleSta
112
123
  * ── Why a fourth tab and not the archive ─────────────────────────────────
113
124
  *
114
125
  * Folding `blocked` into `archived` is the other shape this could take, and
115
- * it costs the count: `my/counters` has three integers and no fourth, so an
116
- * archive tab holding takedowns would read the server's `archived` number —
117
- * `0` — until the tab was opened and its rows could raise it. The fourth tab
118
- * is counted from its OWN read (`?status=blocked`, unpaged), so the number is
119
- * right while the seller is looking at a different tab, which is exactly the
120
- * moment D407 was measured at.
126
+ * it cost the count: when D407 was written `my/counters` had three integers
127
+ * and no fourth, so an archive tab holding takedowns would have read the
128
+ * server's `archived` number — `0` — until the tab was opened and its rows
129
+ * could raise it. The fourth tab was counted from its OWN read
130
+ * (`?status=blocked`, unpaged) so that the number was right while the seller
131
+ * was looking at a different tab, which is exactly the moment D407 was
132
+ * measured at. stapel-listings 0.22.4 puts `blocked` in the counter, so the
133
+ * number is the server's now and that read is only the tab's rows — but the
134
+ * property it was there to defend is the same one, and it is now defended by
135
+ * the wire instead of by a page.
121
136
  *
122
137
  * The archive keeps its meaning too, which is not nothing: "I put this away"
123
138
  * and "a moderator took this down" are not the same sentence and a tab that
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/model/status.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EACV,sBAAsB,EACtB,uBAAuB,EACxB,MAAM,iBAAiB,CAAC;AAIzB;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GACzB,SAAS,GACT,SAAS,GACT,MAAM,GACN,SAAS,GACT,SAAS,CAAC;AAEd,mDAAmD;AACnD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC;8DAC0D;IAC1D,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CACnC;AAoDD,4CAA4C;AAC5C,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,sBAAsB,GAC7B,gBAAgB,CAElB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAEzE;AAED,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,uBAAuB,CAAC;IACnD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;CACpC;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,sBAAsB,EAC9B,gBAAgB,EAAE,uBAAuB,GACxC,gBAAgB,GAAG,SAAS,CAiG9B;AAED,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,QAAQ,CAAC,UAAU,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAClD;;;2BAGuB;IACvB,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC;sCACkC;IAClC,QAAQ,CAAC,kBAAkB,EAAE,SAAS,sBAAsB,EAAE,CAAC;CAChE;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,sBAAsB,EAC9B,gBAAgB,EAAE,uBAAuB,GACxC,iBAAiB,CAQnB;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,2CAA4C,CAAC;AAElF,uEAAuE;AACvE,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAU7E;qEACqE;AACrE,wBAAgB,YAAY,CAC1B,MAAM,EAAE,sBAAsB,GAC7B,oBAAoB,GAAG,SAAS,CAKlC;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,6BAA6B,EAAE,SAAS,sBAAsB,EACF,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,uBAAuB,YAAY,CAAC;AAEjD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS;IACtC,GAAG,OAAO,wBAAwB;IAClC,OAAO,uBAAuB;CAC0B,CAAC;AAE3D,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAC7C,MAAM,CAAC,aAAa,EAAE,SAAS,sBAAsB,EAAE,CAAC,CAIzD,CAAC;AAEF;;;6DAG6D;AAC7D,wBAAgB,KAAK,CACnB,MAAM,EAAE,sBAAsB,GAC7B,aAAa,GAAG,SAAS,CAK3B"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/model/status.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EACV,sBAAsB,EACtB,uBAAuB,EACxB,MAAM,iBAAiB,CAAC;AAIzB;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GACzB,SAAS,GACT,SAAS,GACT,MAAM,GACN,SAAS,GACT,SAAS,CAAC;AAEd,mDAAmD;AACnD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC;8DAC0D;IAC1D,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CACnC;AAoDD,4CAA4C;AAC5C,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,sBAAsB,GAC7B,gBAAgB,CAElB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAEzE;AAED,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,uBAAuB,CAAC;IACnD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;CACpC;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,sBAAsB,EAC9B,gBAAgB,EAAE,uBAAuB,GACxC,gBAAgB,GAAG,SAAS,CAiG9B;AAED,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,QAAQ,CAAC,UAAU,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAClD;;;2BAGuB;IACvB,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC;sCACkC;IAClC,QAAQ,CAAC,kBAAkB,EAAE,SAAS,sBAAsB,EAAE,CAAC;CAChE;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,sBAAsB,EAC9B,gBAAgB,EAAE,uBAAuB,GACxC,iBAAiB,CAQnB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,wBAAwB,2CAA4C,CAAC;AAElF,+DAA+D;AAC/D,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAU7E;;6DAE6D;AAC7D,wBAAgB,YAAY,CAC1B,MAAM,EAAE,sBAAsB,GAC7B,oBAAoB,GAAG,SAAS,CAKlC;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,6BAA6B,EAAE,SAAS,sBAAsB,EACF,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,eAAO,MAAM,uBAAuB,YAAY,CAAC;AAEjD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS;IACtC,GAAG,OAAO,wBAAwB;IAClC,OAAO,uBAAuB;CAC0B,CAAC;AAE3D,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAC7C,MAAM,CAAC,aAAa,EAAE,SAAS,sBAAsB,EAAE,CAAC,CAIzD,CAAC;AAEF;;;6DAG6D;AAC7D,wBAAgB,KAAK,CACnB,MAAM,EAAE,sBAAsB,GAC7B,aAAa,GAAG,SAAS,CAK3B"}
@@ -206,8 +206,8 @@ export function listingStatusView(status, moderationStatus) {
206
206
  };
207
207
  }
208
208
  /**
209
- * The three tabs `my/counters` COUNTS, and the statuses each one folds
210
- * together.
209
+ * The three tabs whose ROWS come off a keyset page, and the statuses each one
210
+ * folds together.
211
211
  *
212
212
  * The grouping is the SERVER's (`views.my_counters`), copied here so a tab's
213
213
  * caption and its count cannot describe different sets: `active` includes
@@ -215,6 +215,13 @@ export function listingStatusView(status, moderationStatus) {
215
215
  * both because a listing in those states is something the owner is still
216
216
  * working on. A client that grouped them its own way would show "3 active"
217
217
  * over two rows.
218
+ *
219
+ * The name is about the SOURCE, not about the counter: `MyCountersResponse`
220
+ * carries four integers since stapel-listings 0.22.4 (`blocked` joined the
221
+ * three), and this is still the set a {@link MyListingsCountedTab} —
222
+ * `MyListingsSource`'s whole parameter type — may name. The removed tab reads
223
+ * its rows off `?status=blocked` directly and unpaged, so a host that
224
+ * implemented the seam before the fourth tab existed is never handed it.
218
225
  */
219
226
  export const MY_LISTINGS_COUNTED_TABS = ["active", "drafts", "archived"];
220
227
  const COUNTED_TAB_STATUSES = {
@@ -222,8 +229,9 @@ const COUNTED_TAB_STATUSES = {
222
229
  drafts: ["draft", "rejected"],
223
230
  archived: ["archived", "paused", "expired", "sold"],
224
231
  };
225
- /** Which of the three COUNTED tabs a status belongs to, or `undefined` for
226
- * one the server's own counter groups nowhere — `blocked`, today. */
232
+ /** Which of the three keyset-paged tabs a status belongs to, or `undefined`
233
+ * for one none of them folds in — `blocked`, today, which has a tab and a
234
+ * counter of its own and a different row source under it. */
227
235
  export function countedTabOf(status) {
228
236
  for (const tab of MY_LISTINGS_COUNTED_TABS) {
229
237
  if (COUNTED_TAB_STATUSES[tab].includes(status))
@@ -232,13 +240,16 @@ export function countedTabOf(status) {
232
240
  return undefined;
233
241
  }
234
242
  /**
235
- * The statuses the server's own counter groups nowhere — `blocked`, and
236
- * nothing else today.
243
+ * The statuses none of the three paged tabs folds in — `blocked`, and nothing
244
+ * else today.
237
245
  *
238
246
  * DERIVED, not written down a second time: a status added upstream and left
239
- * out of the counter groupings lands here automatically and gets shown, which
240
- * is the opposite of what a hardcoded `["blocked"]` would do the day it goes
241
- * stale.
247
+ * out of the tab groupings lands here automatically and gets shown, which is
248
+ * the opposite of what a hardcoded `["blocked"]` would do the day it goes
249
+ * stale. That the server now has a `blocked` COUNTER for the same set does not
250
+ * make the derivation redundant: the counter names one status and this names
251
+ * whatever the three groupings leave over, which is the set the fourth tab
252
+ * must ASK for.
242
253
  */
243
254
  export const MY_LISTINGS_UNTABBED_STATUSES = LISTING_STATUSES.filter((status) => countedTabOf(status) === undefined);
244
255
  /**
@@ -260,12 +271,16 @@ export const MY_LISTINGS_UNTABBED_STATUSES = LISTING_STATUSES.filter((status) =>
260
271
  * ── Why a fourth tab and not the archive ─────────────────────────────────
261
272
  *
262
273
  * Folding `blocked` into `archived` is the other shape this could take, and
263
- * it costs the count: `my/counters` has three integers and no fourth, so an
264
- * archive tab holding takedowns would read the server's `archived` number —
265
- * `0` — until the tab was opened and its rows could raise it. The fourth tab
266
- * is counted from its OWN read (`?status=blocked`, unpaged), so the number is
267
- * right while the seller is looking at a different tab, which is exactly the
268
- * moment D407 was measured at.
274
+ * it cost the count: when D407 was written `my/counters` had three integers
275
+ * and no fourth, so an archive tab holding takedowns would have read the
276
+ * server's `archived` number — `0` — until the tab was opened and its rows
277
+ * could raise it. The fourth tab was counted from its OWN read
278
+ * (`?status=blocked`, unpaged) so that the number was right while the seller
279
+ * was looking at a different tab, which is exactly the moment D407 was
280
+ * measured at. stapel-listings 0.22.4 puts `blocked` in the counter, so the
281
+ * number is the server's now and that read is only the tab's rows — but the
282
+ * property it was there to defend is the same one, and it is now defended by
283
+ * the wire instead of by a page.
269
284
  *
270
285
  * The archive keeps its meaning too, which is not nothing: "I put this away"
271
286
  * and "a moderator took this down" are not the same sentence and a tab that
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/model/status.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/model/status.ts"],"names":[],"mappings":"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"}
package/llms.txt CHANGED
@@ -1,4 +1,4 @@
1
- # @stapel/listings-react 0.26.0
1
+ # @stapel/listings-react 0.27.0
2
2
 
3
3
  Headless React flow pair for stapel-listings (contract >=0.22 <0.23) — business + state, zero visual opinion.
4
4
  Built on @stapel/core: typed client + StapelApiError envelope, auth token refresh,
package/manifest.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$generated": "by scripts/gen-manifest.mjs — do not edit; drift-gated (pnpm gen:manifest:check)",
3
3
  "package": "@stapel/listings-react",
4
- "version": "0.26.0",
4
+ "version": "0.27.0",
5
5
  "backend": {
6
6
  "module": "stapel-listings",
7
7
  "contract": ">=0.22 <0.23"
package/nav-manifest.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@stapel/listings-react",
3
- "version": "0.26.0",
3
+ "version": "0.27.0",
4
4
  "entries": [
5
5
  {
6
6
  "id": "listings.detail",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stapel/listings-react",
3
- "version": "0.26.0",
3
+ "version": "0.27.0",
4
4
  "description": "Headless React pair for stapel-listings: a typed client over the draft twin, the composer that turns a category schema into a submittable listing, and the owner's dashboard. Two independent axes are rendered as two — lifecycle `status` decides visibility and `moderation_status` decides nothing about it, so an edit to a live listing stays live and says 'under review' instead of vanishing. Feature values are drawn and mirrored by @stapel/attributes-react; photos arrive as an injected upload bag whose `refs` ARE `images_draft` and whose `settled` gates the submit; a publish refusal is routed onto the control that caused it by slug. Zero visual opinion in the main entry; an opt-in /default subpath ships the antd skin.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -53,9 +53,9 @@
53
53
  "limit": "17 KB"
54
54
  },
55
55
  {
56
- "name": "default — the antd skin (three cards, detail, composer, dashboard, the named slots and the delete confirmation) must stay out of the main bundle. Raised 17 -> 19 KB for the mobile wave: <ListingSerpCard> (photo strip + price-first block + action rail), <ListingFeedCard> and <FeedGrid> are two more card surfaces on the same shared target/favourite/photo parts, not three copies of one Raised 19 -> 20 KB for the desktop wave of the detail page: layout=\"split\" is a second ASSEMBLY of the money page (the sticky buy column, the two-column spec table, the widened measure) over the same parts, and GateReasonPopover is the blocked heart's third volume — the reason and the door disclosed on interaction, with the visually-hidden copy that keeps the refusal in the accessibility tree. Both are geometry and wiring, not new widgets. Raised 20 -> 21 KB (measured 20.22) for the engagement wave, which is four small things and no new component: the disclosure became a controlled open/close so a pointer that hovers and then clicks does not shut the only explanation the control has; the heart draws a filled accent when saved and states a failed save through the shared ErrorAlert; an already-seen card dims through one rule in the sheet all three cards already hoist; and the listing page gained a view-count row. 216 bytes is what a control that reports its own outcome costs. Raised 21 -> 22 KB for the seller's board becoming a door in both directions: the transition route and useTransitionListing, OWNER_TRANSITIONS/ownerMoves as the fallback mirror, ListingActionsBag.moves drawn in a stable order, listingHref/linkComponent on the cabinet pane, the refusal that stops quoting the wire, and the row that fits a phone. Measured on a clean tree, this package's src reverted to the previous commit with dependencies held constant: 20.82 -> 21.60 KB. The old ceiling had 180 B of room and the work needs 780; none of it is copy, and a fourth axis of owner state is not a rounding error. Raised 22 -> 25 KB (measured 23.94) for the three surfaces of the same wave: <ListingSpecList>/<ListingSpecColumns>, which is a REPLACEMENT of antd's <Descriptions> with a paragraph row (an inline muted label and the value in one text flow, so a long answer wraps at the measure instead of stacking inside a third-of-a-page cell) and therefore carries its own hoisted sheet; <CardBadges>/<CardSpecLine>, one badge renderer for all three card surfaces with the pre-contract path kept whole beside it; and cardGallery.ts, the hover-scrub and swipe gestures — a segment map, a horizontal-intent threshold, the pointer-capability gate and the touch-action rule that leaves the page's vertical scroll to the browser. A gallery a card did not have and a spec list rebuilt from a table are not a rounding error. Raised 25 -> 26 KB (measured 25.34) for three small things and no new component: the dashboard's fourth tab and the takedown notice that shrank to one line above it (D407), the delete dialog choosing its sentence from the row's own remaining moves rather than printing the archive at somebody standing in the archive, and the photo strip's \"1 of 16\" counter with its two CSS rules (D418's neighbour on the card). None of it is copy; the counter is the one thing on a phone card that says a swipe is worth making. Raised 26 -> 29 KB (measured 27.56) for the reader's two actions: <ShareAction> (the native-sheet arm, the desktop menu with its three outbound links and the clipboard row, and the copy confirmation that stands in the menu rather than only in a toast), <ListingActions> (the cluster the listing page and the cards lay out through), actionRow.ts (two hit-target tiers as a class contract — 44px on the page, 36/44 on a card — plus the overlay pin and the label's phone arm) and notice.ts (the message seam, which is antd's own App/static message and no new dependency). Measured with dependencies held constant: 25.34 -> 27.56 KB. A verb the product did not have at all is not a rounding error.",
56
+ "name": "default — the antd skin (three cards, detail, composer, dashboard, the named slots and the delete confirmation) must stay out of the main bundle. Raised 17 -> 19 KB for the mobile wave: <ListingSerpCard> (photo strip + price-first block + action rail), <ListingFeedCard> and <FeedGrid> are two more card surfaces on the same shared target/favourite/photo parts, not three copies of one Raised 19 -> 20 KB for the desktop wave of the detail page: layout=\"split\" is a second ASSEMBLY of the money page (the sticky buy column, the two-column spec table, the widened measure) over the same parts, and GateReasonPopover is the blocked heart's third volume — the reason and the door disclosed on interaction, with the visually-hidden copy that keeps the refusal in the accessibility tree. Both are geometry and wiring, not new widgets. Raised 20 -> 21 KB (measured 20.22) for the engagement wave, which is four small things and no new component: the disclosure became a controlled open/close so a pointer that hovers and then clicks does not shut the only explanation the control has; the heart draws a filled accent when saved and states a failed save through the shared ErrorAlert; an already-seen card dims through one rule in the sheet all three cards already hoist; and the listing page gained a view-count row. 216 bytes is what a control that reports its own outcome costs. Raised 21 -> 22 KB for the seller's board becoming a door in both directions: the transition route and useTransitionListing, OWNER_TRANSITIONS/ownerMoves as the fallback mirror, ListingActionsBag.moves drawn in a stable order, listingHref/linkComponent on the cabinet pane, the refusal that stops quoting the wire, and the row that fits a phone. Measured on a clean tree, this package's src reverted to the previous commit with dependencies held constant: 20.82 -> 21.60 KB. The old ceiling had 180 B of room and the work needs 780; none of it is copy, and a fourth axis of owner state is not a rounding error. Raised 22 -> 25 KB (measured 23.94) for the three surfaces of the same wave: <ListingSpecList>/<ListingSpecColumns>, which is a REPLACEMENT of antd's <Descriptions> with a paragraph row (an inline muted label and the value in one text flow, so a long answer wraps at the measure instead of stacking inside a third-of-a-page cell) and therefore carries its own hoisted sheet; <CardBadges>/<CardSpecLine>, one badge renderer for all three card surfaces with the pre-contract path kept whole beside it; and cardGallery.ts, the hover-scrub and swipe gestures — a segment map, a horizontal-intent threshold, the pointer-capability gate and the touch-action rule that leaves the page's vertical scroll to the browser. A gallery a card did not have and a spec list rebuilt from a table are not a rounding error. Raised 25 -> 26 KB (measured 25.34) for three small things and no new component: the dashboard's fourth tab and the takedown notice that shrank to one line above it (D407), the delete dialog choosing its sentence from the row's own remaining moves rather than printing the archive at somebody standing in the archive, and the photo strip's \"1 of 16\" counter with its two CSS rules (D418's neighbour on the card). None of it is copy; the counter is the one thing on a phone card that says a swipe is worth making. Raised 26 -> 29 KB (measured 27.56) for the reader's two actions: <ShareAction> (the native-sheet arm, the desktop menu with its three outbound links and the clipboard row, and the copy confirmation that stands in the menu rather than only in a toast), <ListingActions> (the cluster the listing page and the cards lay out through), actionRow.ts (two hit-target tiers as a class contract — 44px on the page, 36/44 on a card — plus the overlay pin and the label's phone arm) and notice.ts (the message seam, which is antd's own App/static message and no new dependency). Measured with dependencies held constant: 25.34 -> 27.56 KB. A verb the product did not have at all is not a rounding error. Raised 29 -> 31 KB (measured 29.92) for the two seams a live container was working around with a second component and an `!important`: the MOVABLE CLUSTER (movableCluster.tsx — the portal, the slot registry, the settle that appends the container into the highest-priority mount on screen, and the pane's two slots plus the bar layer) and the GALLERY LAYOUT (detailGallery.ts — the class, the two arms and the strip's child rule, hoisted because an inline style cannot reach a child), together with `useTitleVisibility`'s IntersectionObserver. Measured with dependencies held constant, this package's src at HEAD built into a scratch tree and then this one: 27.72 -> 29.92 KB. 30 would have left 80 B, which is the budget-passed-by-rounding this entry has warned about four times; 31 leaves 1.08 KB. What was bought: a page that mounts ONE `useFavoriteToggle` instead of two, and a host stylesheet that no longer needs `!important` over a pair's own geometry.",
57
57
  "path": "dist/default/index.js",
58
- "limit": "29 KB"
58
+ "limit": "31 KB"
59
59
  },
60
60
  {
61
61
  "name": "i18n/ru — the Russian bundle is opt-in, not carried by the main entry. Raised 5 -> 5.5 KB (measured 5.02): three sentences the wave added — the fourth tab and its empty state, and the delete warning that does not promise the archive to a listing already in it. A bundle sitting exactly ON its limit is a limit the next sentence breaks. Raised 5.5 -> 6 KB (measured 5.48) for the three features_draft refusals the stapel-listings 0.22.3 pin brought with it: the module is locale-exempt upstream, so a code that arrives without a ru sentence renders its own key on a Russian host, and each of these three has to NAME the shape it wanted rather than say \"try again\". 5.48 of 5.5 is twenty bytes of headroom — the rounding this entry already warns about.",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$generated": "by scripts/gen-events.mjs — do not edit; drift-gated (pnpm gen:events:check)",
3
3
  "package": "@stapel/listings-react",
4
- "version": "0.26.0",
4
+ "version": "0.27.0",
5
5
  "defined": [],
6
6
  "flows": []
7
7
  }