@stapel/listings-react 0.18.2 → 0.19.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 (120) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/dist/api/generated/schema.d.ts +101 -13
  3. package/dist/api/generated/schema.d.ts.map +1 -1
  4. package/dist/api/listingsApi.d.ts +26 -1
  5. package/dist/api/listingsApi.d.ts.map +1 -1
  6. package/dist/api/listingsApi.js +9 -0
  7. package/dist/api/listingsApi.js.map +1 -1
  8. package/dist/api/types.d.ts +91 -6
  9. package/dist/api/types.d.ts.map +1 -1
  10. package/dist/api/types.js +32 -0
  11. package/dist/api/types.js.map +1 -1
  12. package/dist/default/GateReasonPopover.d.ts.map +1 -1
  13. package/dist/default/GateReasonPopover.js +47 -2
  14. package/dist/default/GateReasonPopover.js.map +1 -1
  15. package/dist/default/ListingCard.d.ts +32 -1
  16. package/dist/default/ListingCard.d.ts.map +1 -1
  17. package/dist/default/ListingCard.js +65 -14
  18. package/dist/default/ListingCard.js.map +1 -1
  19. package/dist/default/ListingDetailPane.d.ts.map +1 -1
  20. package/dist/default/ListingDetailPane.js +12 -7
  21. package/dist/default/ListingDetailPane.js.map +1 -1
  22. package/dist/default/ListingFeedCard.d.ts +32 -7
  23. package/dist/default/ListingFeedCard.d.ts.map +1 -1
  24. package/dist/default/ListingFeedCard.js +11 -3
  25. package/dist/default/ListingFeedCard.js.map +1 -1
  26. package/dist/default/ListingPrice.d.ts +13 -2
  27. package/dist/default/ListingPrice.d.ts.map +1 -1
  28. package/dist/default/ListingPrice.js.map +1 -1
  29. package/dist/default/ListingSerpCard.d.ts.map +1 -1
  30. package/dist/default/ListingSerpCard.js +10 -2
  31. package/dist/default/ListingSerpCard.js.map +1 -1
  32. package/dist/default/favorite.d.ts +11 -0
  33. package/dist/default/favorite.d.ts.map +1 -1
  34. package/dist/default/favorite.js +24 -9
  35. package/dist/default/favorite.js.map +1 -1
  36. package/dist/default/icons.d.ts +17 -3
  37. package/dist/default/icons.d.ts.map +1 -1
  38. package/dist/default/icons.js +2 -1
  39. package/dist/default/icons.js.map +1 -1
  40. package/dist/default/index.d.ts +1 -1
  41. package/dist/default/index.d.ts.map +1 -1
  42. package/dist/default/index.js +4 -1
  43. package/dist/default/index.js.map +1 -1
  44. package/dist/headless/Engagement.d.ts +62 -0
  45. package/dist/headless/Engagement.d.ts.map +1 -0
  46. package/dist/headless/Engagement.js +116 -0
  47. package/dist/headless/Engagement.js.map +1 -0
  48. package/dist/headless/Favorites.d.ts +50 -0
  49. package/dist/headless/Favorites.d.ts.map +1 -1
  50. package/dist/headless/Favorites.js +63 -3
  51. package/dist/headless/Favorites.js.map +1 -1
  52. package/dist/headless/ListingDetail.d.ts +21 -1
  53. package/dist/headless/ListingDetail.d.ts.map +1 -1
  54. package/dist/headless/ListingDetail.js +39 -3
  55. package/dist/headless/ListingDetail.js.map +1 -1
  56. package/dist/i18n/es.d.ts.map +1 -1
  57. package/dist/i18n/es.js +4 -0
  58. package/dist/i18n/es.js.map +1 -1
  59. package/dist/i18n/generated/errors.es.gen.d.ts +1 -1
  60. package/dist/i18n/generated/errors.es.gen.js +1 -1
  61. package/dist/i18n/generated/errors.gen.d.ts +12 -0
  62. package/dist/i18n/generated/errors.gen.d.ts.map +1 -1
  63. package/dist/i18n/generated/errors.gen.js +6 -0
  64. package/dist/i18n/generated/errors.gen.js.map +1 -1
  65. package/dist/i18n/generated/errors.ru.gen.d.ts +1 -1
  66. package/dist/i18n/generated/errors.ru.gen.js +1 -1
  67. package/dist/i18n/keys.d.ts +7 -0
  68. package/dist/i18n/keys.d.ts.map +1 -1
  69. package/dist/i18n/keys.js +8 -0
  70. package/dist/i18n/keys.js.map +1 -1
  71. package/dist/i18n/ru.d.ts.map +1 -1
  72. package/dist/i18n/ru.js +6 -0
  73. package/dist/i18n/ru.js.map +1 -1
  74. package/dist/index.d.ts +6 -3
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +5 -2
  77. package/dist/index.js.map +1 -1
  78. package/dist/model/engagement.d.ts +85 -0
  79. package/dist/model/engagement.d.ts.map +1 -0
  80. package/dist/model/engagement.js +59 -0
  81. package/dist/model/engagement.js.map +1 -0
  82. package/dist/model/queries.d.ts +28 -1
  83. package/dist/model/queries.d.ts.map +1 -1
  84. package/dist/model/queries.js +36 -0
  85. package/dist/model/queries.js.map +1 -1
  86. package/dist/model/queryKeys.d.ts +12 -13
  87. package/dist/model/queryKeys.d.ts.map +1 -1
  88. package/dist/model/queryKeys.js +15 -0
  89. package/dist/model/queryKeys.js.map +1 -1
  90. package/llms.txt +6 -3
  91. package/manifest.json +71 -3
  92. package/nav-manifest.json +1 -1
  93. package/package.json +8 -8
  94. package/src/analytics/generated/events.json +1 -1
  95. package/src/api/generated/schema.ts +101 -13
  96. package/src/api/listingsApi.ts +39 -0
  97. package/src/api/types.ts +115 -6
  98. package/src/default/GateReasonPopover.tsx +62 -3
  99. package/src/default/ListingCard.tsx +84 -10
  100. package/src/default/ListingDetailPane.tsx +48 -16
  101. package/src/default/ListingFeedCard.tsx +45 -8
  102. package/src/default/ListingPrice.tsx +13 -2
  103. package/src/default/ListingSerpCard.tsx +11 -1
  104. package/src/default/favorite.tsx +49 -21
  105. package/src/default/icons.tsx +21 -3
  106. package/src/default/index.ts +4 -0
  107. package/src/headless/Engagement.tsx +177 -0
  108. package/src/headless/Favorites.tsx +93 -3
  109. package/src/headless/ListingDetail.tsx +64 -4
  110. package/src/i18n/es.ts +7 -0
  111. package/src/i18n/generated/errors.es.gen.ts +1 -1
  112. package/src/i18n/generated/errors.gen.ts +6 -0
  113. package/src/i18n/generated/errors.json +14 -0
  114. package/src/i18n/generated/errors.ru.gen.ts +1 -1
  115. package/src/i18n/keys.ts +8 -0
  116. package/src/i18n/ru.ts +9 -0
  117. package/src/index.ts +27 -0
  118. package/src/model/engagement.ts +118 -0
  119. package/src/model/queries.ts +41 -0
  120. package/src/model/queryKeys.ts +14 -0
@@ -36,10 +36,91 @@ import type { FeatureConfig, FeatureDef, FeatureValueDto } from "@stapel/attribu
36
36
  import type { components } from "./generated/schema.js";
37
37
  /** The generated schema table — the one source of truth for wire shapes. */
38
38
  export type Schemas = components["schemas"];
39
+ /**
40
+ * The engagement fields, named off the GENERATED row so a rename upstream
41
+ * breaks the build here rather than going quiet on a grid.
42
+ *
43
+ * These were hand-written mirrors while this pair's contract pin sat at
44
+ * `>=0.12 <0.13` and the emitted schema could not see stapel-listings
45
+ * 0.16/0.17. The pin has landed, so the mirrors are gone and the names come
46
+ * from `Schemas["ListingCard"]`. What is kept is the OPTIONALITY, and that is
47
+ * not laziness:
48
+ *
49
+ * **A generated type is a promise about the contract, not about the bytes a
50
+ * particular deployment sends.** The schema says every card carries `viewed`
51
+ * and `view_count`; a storefront pointed at a server still running 0.15 gets
52
+ * rows without them, and the two surfaces this feature exists for — a feed
53
+ * and a SERP — are served by the SEARCH index, whose stored document carries
54
+ * neither by construction. `Partial` is what keeps `model/engagement.ts`
55
+ * allowed to ask, and every reader there answers "absent" with the same
56
+ * silence it answers `null` with.
57
+ */
58
+ export type ListingEngagementFields = Partial<Pick<Schemas["ListingCard"], "viewed" | "view_count">>;
59
+ /** A generated row with its engagement fields relaxed to optional — see
60
+ * {@link ListingEngagementFields} for why every row type below is spelled
61
+ * this way rather than taken from `Schemas` whole. */
62
+ type WithOptionalEngagement<Row extends ListingEngagementFields> = Omit<Row, keyof ListingEngagementFields> & ListingEngagementFields;
63
+ /**
64
+ * The per-viewer overlay for ONE listing, as the batch read answers it.
65
+ *
66
+ * Note what is REQUIRED here and optional on the row: the overlay always
67
+ * carries all three keys, because it is the answer to a question that was
68
+ * actually asked. A row that carries none of them was serialized by a build
69
+ * that had never heard of them.
70
+ */
71
+ export type ListingEngagement = Schemas["ListingEngagement"];
72
+ /**
73
+ * `GET /listings/engagement/?ids=…` 200 — `{listing id: overlay}`.
74
+ *
75
+ * The keys are the ids as STRINGS (a DRF `DictField`), and an id with no
76
+ * listing is simply absent rather than present-and-empty. Both facts are why
77
+ * `model/engagement.ts` looks entries up through one function instead of
78
+ * indexing the object at call sites.
79
+ */
80
+ export type ListingEngagementBatch = Schemas["ListingEngagementBatch"];
81
+ /**
82
+ * The most ids one overlay call may carry — `ENGAGEMENT_BATCH_LIMIT`
83
+ * upstream, which silently TRUNCATES anything longer ("one page of cards, not
84
+ * a crawl of the board").
85
+ *
86
+ * Mirrored here so the truncation happens where it can be seen and named
87
+ * rather than in a response that quietly came back short. A page of more than
88
+ * a hundred cards is not a page; a caller that has one should ask per screen.
89
+ */
90
+ export declare const LISTINGS_ENGAGEMENT_BATCH_LIMIT = 100;
91
+ /**
92
+ * Normalize the ids on a page into the exact list the request sends.
93
+ *
94
+ * Sorted, de-duplicated, non-integer values dropped, capped at
95
+ * {@link LISTINGS_ENGAGEMENT_BATCH_LIMIT}. Sorting is what makes the cache
96
+ * key honest: the answer is a MAP keyed by id, so two renders that ask for
97
+ * the same ids in different orders are asking the identical question and must
98
+ * not buy two cache entries and two requests. De-duplication is the same
99
+ * argument for a grid that shows one listing twice (a promoted slot above the
100
+ * organic result it also occupies).
101
+ *
102
+ * `queryKeys.engagement` and `api.engagement` are both built from THIS, so
103
+ * the key cannot drift from the request it stands for.
104
+ */
105
+ export declare function engagementIds(ids: readonly number[]): readonly number[];
39
106
  /** `GET /listings/{pk}/` 200 — everything a detail page reads. */
40
- export type ListingDetail = Schemas["ListingDetail"];
41
- /** One row of a card list (`GET /listings/`, `GET /listings/my/favorites/`). */
42
- export type ListingCard = Schemas["ListingCard"];
107
+ export type ListingDetail = WithOptionalEngagement<Schemas["ListingDetail"]>;
108
+ /**
109
+ * One row of a card list (`GET /listings/`, `GET /listings/my/favorites/`) —
110
+ * and the PROP every card component in this pair takes, which is why its
111
+ * engagement fields are optional where the schema makes them required.
112
+ *
113
+ * The schema is right about this module's own responses: `GET /listings/`
114
+ * carries `viewed` and `view_count` on every row. But the card components are
115
+ * handed rows from elsewhere, and the most important elsewhere is the SEARCH
116
+ * index — `@stapel/search-react` fills `renderCard` with a stored document
117
+ * that cannot hold a per-reader flag by construction. Requiring the fields on
118
+ * the prop would make the pair's primary consumer unable to satisfy its own
119
+ * type, for data no one can supply; it is precisely the case
120
+ * `<ListingEngagementScope>` exists to answer. A deployment running a server
121
+ * older than 0.16 is the same shape of fact.
122
+ */
123
+ export type ListingCard = WithOptionalEngagement<Schemas["ListingCard"]>;
43
124
  /** `POST /listings/` request+response and `POST /{pk}/save-draft/` response —
44
125
  * the draft twin. Every user-editable field is a `*_draft` one, promoted onto
45
126
  * its published sibling by `publish`. */
@@ -62,7 +143,9 @@ export type FavoriteToggleResponse = Schemas["FavoriteToggleResponse"];
62
143
  export type DeleteResponse = Schemas["DeleteResponse"];
63
144
  /** The keyset envelope both public card lists come back in
64
145
  * (`IDAnchorPagination`). */
65
- export type PaginatedListingCards = Schemas["PaginatedListingCardList"];
146
+ export type PaginatedListingCards = Omit<Schemas["PaginatedListingCardList"], "items"> & {
147
+ items: ListingCard[];
148
+ };
66
149
  /**
67
150
  * One row of `GET /listings/my/listings/` — the OWNER's card.
68
151
  *
@@ -80,11 +163,13 @@ export type PaginatedListingCards = Schemas["PaginatedListingCardList"];
80
163
  * tab keyed off them is a column of blank rows. `myListingTitle` /
81
164
  * `myListingPrice` (`model/mine.ts`) are the one place the fallback lives.
82
165
  */
83
- export type MyListingCard = Schemas["MyListingCard"];
166
+ export type MyListingCard = WithOptionalEngagement<Schemas["MyListingCard"]>;
84
167
  /** The keyset envelope `GET /listings/my/listings/` comes back in — the same
85
168
  * `IDAnchorPagination` shape as {@link PaginatedListingCards}, over the owner
86
169
  * row. */
87
- export type PaginatedMyListingCards = Schemas["PaginatedMyListingCardList"];
170
+ export type PaginatedMyListingCards = Omit<Schemas["PaginatedMyListingCardList"], "items"> & {
171
+ items: MyListingCard[];
172
+ };
88
173
  /**
89
174
  * The nine lifecycle states, as `models.ListingStatus` declares them.
90
175
  *
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"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"}
package/dist/api/types.js CHANGED
@@ -1,3 +1,35 @@
1
+ /**
2
+ * The most ids one overlay call may carry — `ENGAGEMENT_BATCH_LIMIT`
3
+ * upstream, which silently TRUNCATES anything longer ("one page of cards, not
4
+ * a crawl of the board").
5
+ *
6
+ * Mirrored here so the truncation happens where it can be seen and named
7
+ * rather than in a response that quietly came back short. A page of more than
8
+ * a hundred cards is not a page; a caller that has one should ask per screen.
9
+ */
10
+ export const LISTINGS_ENGAGEMENT_BATCH_LIMIT = 100;
11
+ /**
12
+ * Normalize the ids on a page into the exact list the request sends.
13
+ *
14
+ * Sorted, de-duplicated, non-integer values dropped, capped at
15
+ * {@link LISTINGS_ENGAGEMENT_BATCH_LIMIT}. Sorting is what makes the cache
16
+ * key honest: the answer is a MAP keyed by id, so two renders that ask for
17
+ * the same ids in different orders are asking the identical question and must
18
+ * not buy two cache entries and two requests. De-duplication is the same
19
+ * argument for a grid that shows one listing twice (a promoted slot above the
20
+ * organic result it also occupies).
21
+ *
22
+ * `queryKeys.engagement` and `api.engagement` are both built from THIS, so
23
+ * the key cannot drift from the request it stands for.
24
+ */
25
+ export function engagementIds(ids) {
26
+ const seen = new Set();
27
+ for (const id of ids) {
28
+ if (Number.isInteger(id))
29
+ seen.add(id);
30
+ }
31
+ return [...seen].sort((a, b) => a - b).slice(0, LISTINGS_ENGAGEMENT_BATCH_LIMIT);
32
+ }
1
33
  /**
2
34
  * The nine lifecycle states, as `models.ListingStatus` declares them.
3
35
  *
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAsGA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAsC;IACjE,OAAO;IACP,SAAS;IACT,WAAW;IACX,QAAQ;IACR,SAAS;IACT,MAAM;IACN,UAAU;IACV,SAAS;IACT,UAAU;CACX,CAAC;AAMF;gEACgE;AAChE,MAAM,CAAC,MAAM,mBAAmB,GAAuC;IACrE,SAAS;IACT,UAAU;IACV,UAAU;IACV,cAAc;CACf,CAAC;AAsIF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AA4FA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,GAAG,CAAC;AAEnD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAAC,GAAsB;IAClD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,IAAI,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,+BAA+B,CAAC,CAAC;AACnF,CAAC;AAwFD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAsC;IACjE,OAAO;IACP,SAAS;IACT,WAAW;IACX,QAAQ;IACR,SAAS;IACT,MAAM;IACN,UAAU;IACV,SAAS;IACT,UAAU;CACX,CAAC;AAMF;gEACgE;AAChE,MAAM,CAAC,MAAM,mBAAmB,GAAuC;IACrE,SAAS;IACT,UAAU;IACV,UAAU;IACV,cAAc;CACf,CAAC;AAsIF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"GateReasonPopover.d.ts","sourceRoot":"","sources":["../../src/default/GateReasonPopover.tsx"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C;0DAC0D;AAC1D,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,sBAAsB;IACrC,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;oDACgD;IAChD,QAAQ,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS,CAAC;IACpC,2CAA2C;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;6EACyE;IACzE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B;kFAC8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,SAAS,CAAC;CACrE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,YAAY,CA8B7E"}
1
+ {"version":3,"file":"GateReasonPopover.d.ts","sourceRoot":"","sources":["../../src/default/GateReasonPopover.tsx"],"names":[],"mappings":"AAuDA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C;0DAC0D;AAC1D,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,sBAAsB;IACrC,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;oDACgD;IAChD,QAAQ,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS,CAAC;IACpC,2CAA2C;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;6EACyE;IACzE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B;kFAC8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,SAAS,CAAC;CACrE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,YAAY,CAmE7E"}
@@ -27,11 +27,33 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
27
27
  * screen (see `ListingCardBlockedReason`). The rule's disables below are the
28
28
  * documented decision §2.4 asks for, not a hole.
29
29
  *
30
+ * ── Why the disclosure is CONTROLLED: hover opened it, the click shut it ───
31
+ *
32
+ * An uncontrolled popover triggered by hover AND click treats the click as a
33
+ * TOGGLE, so the natural pointer gesture — rest on the control, then press it
34
+ * — opens the disclosure on the hover and closes it again on the press. The
35
+ * overlay comes back marked `ant-popover-hidden` and the person has pressed
36
+ * the one control that was supposed to explain itself and watched it go
37
+ * blank. Reproduced in jsdom and gated by `test/favoriteGesture.test.tsx`.
38
+ *
39
+ * It needs the DELAY to reproduce, which is the interesting part: antd opens
40
+ * a hover popover after 0.1s, so two events fired back to back (a thumb's
41
+ * emulated `mouseenter` + `click`) land while nothing is open yet and the
42
+ * click opens it correctly. A cursor that lingers is past the delay, and its
43
+ * click closes what the hover opened. The suite was green throughout because
44
+ * every existing test fired `click` alone — a synthetic click carries no
45
+ * hover in front of it, so it exercised the one ordering that worked.
46
+ *
47
+ * So `open` is this component's own state and activation is MONOTONIC: a
48
+ * click may only open the disclosure, never close it. Hover-out, blur and a
49
+ * click outside still close it, because those arrive as an `onOpenChange`
50
+ * that no activation is claiming.
51
+ *
30
52
  * Deliberately NOT exported from `src/default/index.ts`: it is how this
31
53
  * pair's own gated hearts speak, not a control a host composes with — the
32
54
  * same standing `favorite.tsx` has.
33
55
  */
34
- import { useId } from "react";
56
+ import { useCallback, useId, useRef, useState } from "react";
35
57
  import { Flex, Typography } from "antd";
36
58
  // eslint-disable-next-line stapel/no-tooltip-in-skin -- interaction disclosure, not a hover: opens on click/tap and focus too, anchored to a non-disabled control, with the reason kept in the a11y tree via aria-describedby (see this file's header)
37
59
  import { Popover } from "antd";
@@ -40,6 +62,29 @@ import { spacing } from "@stapel/tokens";
40
62
  import { SignInLink } from "./SignInLink.js";
41
63
  export function GateReasonPopover(props) {
42
64
  const reasonId = useId();
43
- return (_jsxs(_Fragment, { children: [_jsx("span", { id: reasonId, style: visuallyHidden, children: props.reason }), _jsx(Popover, { trigger: ["hover", "focus", "click"], content: _jsxs(Flex, { vertical: true, gap: spacing[1], "data-testid": props.testId, children: [_jsx(Typography.Text, { children: props.reason }), _jsx(SignInLink, { cta: props.cta, testId: props.signInTestId })] }), children: _jsx("div", { children: props.children({ "aria-describedby": reasonId }) }) })] }));
65
+ const [open, setOpen] = useState(false);
66
+ // Set in the capture phase of a click, i.e. BEFORE the popover's own
67
+ // handler runs on the same event, and dropped once that event is fully
68
+ // dispatched. While it is set, "close" is the tap's own toggle and is
69
+ // refused; see the file header.
70
+ const activating = useRef(false);
71
+ const handleOpenChange = useCallback((next) => {
72
+ if (!next && activating.current)
73
+ return;
74
+ setOpen(next);
75
+ }, []);
76
+ const activate = useCallback(() => {
77
+ activating.current = true;
78
+ setOpen(true);
79
+ // A microtask runs after the whole event dispatch, so the flag covers
80
+ // exactly this gesture and no later hover-out.
81
+ queueMicrotask(() => {
82
+ activating.current = false;
83
+ });
84
+ }, []);
85
+ return (_jsxs(_Fragment, { children: [_jsx("span", { id: reasonId, style: visuallyHidden, children: props.reason }), _jsx(Popover, { trigger: ["hover", "focus", "click"], open: open, onOpenChange: handleOpenChange, content: _jsxs(Flex, { vertical: true, gap: spacing[1], "data-testid": props.testId, children: [_jsx(Typography.Text, { children: props.reason }), _jsx(SignInLink, { cta: props.cta, testId: props.signInTestId })] }), children: _jsx("div", { onClickCapture: activate, onKeyDownCapture: (event) => {
86
+ if (event.key === "Enter" || event.key === " ")
87
+ activate();
88
+ }, children: props.children({ "aria-describedby": reasonId }) }) })] }));
44
89
  }
45
90
  //# sourceMappingURL=GateReasonPopover.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"GateReasonPopover.js","sourceRoot":"","sources":["../../src/default/GateReasonPopover.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE9B,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AACxC,uPAAuP;AACvP,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAwB7C,MAAM,UAAU,iBAAiB,CAAC,KAA6B;IAC7D,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAC;IACzB,OAAO,CACL,8BAIE,eAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,YACtC,KAAK,CAAC,MAAM,GACR,EAEP,KAAC,OAAO,IACN,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EACpC,OAAO,EACL,MAAC,IAAI,IAAC,QAAQ,QAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,iBAAe,KAAK,CAAC,MAAM,aACvD,KAAC,UAAU,CAAC,IAAI,cAAE,KAAK,CAAC,MAAM,GAAmB,EACjD,KAAC,UAAU,IAAC,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,YAAY,GAAI,IACrD,YAST,wBAAM,KAAK,CAAC,QAAQ,CAAC,EAAE,kBAAkB,EAAE,QAAQ,EAAE,CAAC,GAAO,GACrD,IACT,CACJ,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"GateReasonPopover.js","sourceRoot":"","sources":["../../src/default/GateReasonPopover.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE7D,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AACxC,uPAAuP;AACvP,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAwB7C,MAAM,UAAU,iBAAiB,CAAC,KAA6B;IAC7D,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAC;IACzB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,qEAAqE;IACrE,uEAAuE;IACvE,sEAAsE;IACtE,gCAAgC;IAChC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAEjC,MAAM,gBAAgB,GAAG,WAAW,CAAC,CAAC,IAAa,EAAQ,EAAE;QAC3D,IAAI,CAAC,IAAI,IAAI,UAAU,CAAC,OAAO;YAAE,OAAO;QACxC,OAAO,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAS,EAAE;QACtC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;QAC1B,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,sEAAsE;QACtE,+CAA+C;QAC/C,cAAc,CAAC,GAAG,EAAE;YAClB,UAAU,CAAC,OAAO,GAAG,KAAK,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,8BAIE,eAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,YACtC,KAAK,CAAC,MAAM,GACR,EAEP,KAAC,OAAO,IACN,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EACpC,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,gBAAgB,EAC9B,OAAO,EACL,MAAC,IAAI,IAAC,QAAQ,QAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,iBAAe,KAAK,CAAC,MAAM,aACvD,KAAC,UAAU,CAAC,IAAI,cAAE,KAAK,CAAC,MAAM,GAAmB,EACjD,KAAC,UAAU,IAAC,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,YAAY,GAAI,IACrD,YAeT,cACE,cAAc,EAAE,QAAQ,EACxB,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE;wBAC1B,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG;4BAAE,QAAQ,EAAE,CAAC;oBAC7D,CAAC,YAEA,KAAK,CAAC,QAAQ,CAAC,EAAE,kBAAkB,EAAE,QAAQ,EAAE,CAAC,GAC7C,GACE,IACT,CACJ,CAAC;AACJ,CAAC"}
@@ -93,7 +93,11 @@
93
93
  * `<GatedControl>`, which renders it as text linked by `aria-describedby` —
94
94
  * a disabled antd button receives no pointer events and is not focusable, so
95
95
  * the `Tooltip` this component used to offer as a "quieter" volume was a
96
- * reason nobody could read on any device. That arm is gone; `blockedReason`
96
+ * reason nobody could read on any device. The heart itself is never
97
+ * html-`disabled` in ANY volume for the same reason: it carries
98
+ * `aria-disabled` and a live handler, and refuses on ACTIVATION (the gate
99
+ * makes `toggle` a no-op). An inert control cannot be tapped, cannot be
100
+ * focused, and cannot disclose anything. That arm is gone; `blockedReason`
97
101
  * is "text" (reason + door), "line" (reason alone, for a grid), or
98
102
  * "popover" — the reason and the door disclosed on the heart itself, with
99
103
  * the reason still in the accessibility tree. The third arm is NOT the old
@@ -188,6 +192,33 @@ export declare const CARD_MAIN_CLASS = "stapel-listing-card-main";
188
192
  /** Added to the frame by a card whose media is FULL-BLEED when stacked
189
193
  * (`<ListingCard>`), so the row arm gets the inset the stacked arm does not. */
190
194
  export declare const CARD_BLEED_CLASS = "stapel-listing-card-bleed";
195
+ /**
196
+ * The class an ALREADY-SEEN card carries — the mark every mature classified
197
+ * puts on a result you have opened before, and the reason a shopper on their
198
+ * third evening of the same search is not re-reading the same twenty offers.
199
+ *
200
+ * All three card surfaces take it, and all three take it on their OUTER box,
201
+ * so the rule below can reach the photo and the reading column while leaving
202
+ * the favourite heart at full strength: a dimmed heart reads as a disabled
203
+ * heart, and the one control on the card must not look switched off because
204
+ * the card behind it is old news.
205
+ */
206
+ export declare const CARD_VIEWED_CLASS = "stapel-listing-card-seen";
207
+ /**
208
+ * How far a seen card is dimmed.
209
+ *
210
+ * OPACITY and not a colour, which is the whole reason this needs no dark-mode
211
+ * arm: opacity composites the card against whatever ground the theme painted,
212
+ * so the same number is a grey card on a white page and a dim card on a black
213
+ * one. A `color` here would have to be picked twice, and the second pick is
214
+ * the one nobody photographs. 0.55 is far enough to sort seen from unseen at
215
+ * a glance and not so far that the price stops being readable — a seen
216
+ * listing is still a listing, not a disabled control.
217
+ *
218
+ * A host that wants another value sets `--listing-viewed-opacity` on any
219
+ * ancestor; the rule reads the property and falls back to this.
220
+ */
221
+ export declare const LISTING_VIEWED_OPACITY = 0.55;
191
222
  /** The `href` the hoisted card stylesheet is deduplicated by. */
192
223
  export declare const CARD_TARGET_STYLE_HREF = "stapel-listings-card-target";
193
224
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ListingCard.d.ts","sourceRoot":"","sources":["../../src/default/ListingCard.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ListingCard.d.ts","sourceRoot":"","sources":["../../src/default/ListingCard.tsx"],"names":[],"mappings":"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"}
@@ -1,12 +1,14 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Card, Flex, Typography, theme as antdTheme } from "antd";
3
3
  import { SkinButton as Button } from "@stapel/tokens-antd/skin";
4
- import { GatedControl, SkinTheme } from "@stapel/tokens-antd/skin";
4
+ import { ErrorAlert, GatedControl, SkinTheme } from "@stapel/tokens-antd/skin";
5
5
  import { useActionGate, useT } from "@stapel/core";
6
6
  import { spacing } from "@stapel/tokens";
7
7
  import { FeatureBadges } from "@stapel/attributes-react/default";
8
8
  import { asFeatureDaoList, featuresDtoFromDaoList, featuresFromDaoList } from "../model/features.js";
9
9
  import { lifecycleCaption } from "../model/status.js";
10
+ import { isListingViewed } from "../model/engagement.js";
11
+ import { useEngagedListing } from "../headless/Engagement.js";
10
12
  import { useFavoriteToggle } from "../headless/Favorites.js";
11
13
  import { LISTINGS_I18N_KEYS } from "../i18n/keys.js";
12
14
  import { GateReasonPopover } from "./GateReasonPopover.js";
@@ -29,6 +31,33 @@ export const CARD_MAIN_CLASS = "stapel-listing-card-main";
29
31
  /** Added to the frame by a card whose media is FULL-BLEED when stacked
30
32
  * (`<ListingCard>`), so the row arm gets the inset the stacked arm does not. */
31
33
  export const CARD_BLEED_CLASS = "stapel-listing-card-bleed";
34
+ /**
35
+ * The class an ALREADY-SEEN card carries — the mark every mature classified
36
+ * puts on a result you have opened before, and the reason a shopper on their
37
+ * third evening of the same search is not re-reading the same twenty offers.
38
+ *
39
+ * All three card surfaces take it, and all three take it on their OUTER box,
40
+ * so the rule below can reach the photo and the reading column while leaving
41
+ * the favourite heart at full strength: a dimmed heart reads as a disabled
42
+ * heart, and the one control on the card must not look switched off because
43
+ * the card behind it is old news.
44
+ */
45
+ export const CARD_VIEWED_CLASS = "stapel-listing-card-seen";
46
+ /**
47
+ * How far a seen card is dimmed.
48
+ *
49
+ * OPACITY and not a colour, which is the whole reason this needs no dark-mode
50
+ * arm: opacity composites the card against whatever ground the theme painted,
51
+ * so the same number is a grey card on a white page and a dim card on a black
52
+ * one. A `color` here would have to be picked twice, and the second pick is
53
+ * the one nobody photographs. 0.55 is far enough to sort seen from unseen at
54
+ * a glance and not so far that the price stops being readable — a seen
55
+ * listing is still a listing, not a disabled control.
56
+ *
57
+ * A host that wants another value sets `--listing-viewed-opacity` on any
58
+ * ancestor; the rule reads the property and falls back to this.
59
+ */
60
+ export const LISTING_VIEWED_OPACITY = 0.55;
32
61
  /** The `href` the hoisted card stylesheet is deduplicated by. */
33
62
  export const CARD_TARGET_STYLE_HREF = "stapel-listings-card-target";
34
63
  /**
@@ -91,6 +120,12 @@ export function cardTargetCss() {
91
120
  `${bleed}{padding-block:var(--listing-card-inset);` +
92
121
  `padding-inline-start:var(--listing-card-inset)}` +
93
122
  `}`,
123
+ // Already seen. The photo and everything inside the card's anchor dim
124
+ // together; the heart is outside the anchor and stays as it was — see
125
+ // CARD_VIEWED_CLASS.
126
+ `.${CARD_VIEWED_CLASS} .${CARD_TARGET_CLASS},` +
127
+ `.${CARD_VIEWED_CLASS} .${CARD_MEDIA_CLASS}` +
128
+ `{opacity:var(--listing-viewed-opacity,${String(LISTING_VIEWED_OPACITY)})}`,
94
129
  ].join("");
95
130
  }
96
131
  /** The anchor: a block that inherits the card's own type colour rather than
@@ -154,7 +189,10 @@ export function CardTarget(props) {
154
189
  }
155
190
  export function ListingCard(props) {
156
191
  const t = useT();
157
- const { listing } = props;
192
+ // The engagement scope's answer laid over the row, when a container opened
193
+ // one — the same object otherwise. A card fed by search carries no
194
+ // `viewed`/`is_favorited` of its own; see `headless/Engagement.tsx`.
195
+ const listing = useEngagedListing(props.listing);
158
196
  const favorite = useFavoriteToggle(listing.id, listing.is_favorited);
159
197
  const { token } = antdTheme.useToken();
160
198
  const badgeDaos = asFeatureDaoList(listing.features_badges);
@@ -170,6 +208,13 @@ export function ListingCard(props) {
170
208
  const status = listing.status === undefined ? undefined : lifecycleCaption(listing.status);
171
209
  const favoriteGate = useActionGate(favorite.gate);
172
210
  const blockedReason = props.blockedReason ?? "text";
211
+ // Absent on every response the fleet answers today, and a plain `false`
212
+ // when it is — no dimming, no attribute, nothing said about it.
213
+ const viewed = isListingViewed(listing);
214
+ // A saved heart is a SOLID accent shape; an unsaved one is the outline it
215
+ // has always been. `is_favorited: null` reads as unsaved (`favorite`
216
+ // resolves the third state), never as a look of its own.
217
+ const heartIcon = (_jsx(HeartIcon, { filled: favorite.favorited, ...(favorite.favorited ? { color: token.colorPrimary } : {}) }));
173
218
  const favoriteLabel = t(favorite.favorited
174
219
  ? LISTINGS_I18N_KEYS.cardFavoriteRemove
175
220
  : LISTINGS_I18N_KEYS.cardFavoriteAdd);
@@ -193,6 +238,8 @@ export function ListingCard(props) {
193
238
  listing.location_label.length > 0 ? (_jsx(Typography.Text, { type: "secondary", "data-testid": "listings-card-location", children: listing.location_label })) : null] }));
194
239
  return (_jsxs(SkinTheme, { surface: "bare", ...(props.mode !== undefined ? { mode: props.mode } : {}), children: [_jsx("style", { href: CARD_TARGET_STYLE_HREF, precedence: "default", children: cardTargetCss() }), _jsx(Card, { size: "small", "data-testid": "listings-card", "data-listing-id": listing.id, ...(status !== undefined
195
240
  ? { "data-listing-status": status.status }
241
+ : {}), ...(viewed
242
+ ? { className: CARD_VIEWED_CLASS, "data-listing-viewed": "true" }
196
243
  : {}),
197
244
  // The body's own padding is zero because the frame fills the card and
198
245
  // the photo runs edge to edge when it is stacked: padding here would
@@ -202,19 +249,23 @@ export function ListingCard(props) {
202
249
  styles: { body: { minWidth: 0, padding: 0 } }, style: {
203
250
  ["--listing-card-focus"]: token.colorPrimary,
204
251
  ["--listing-card-inset"]: `${String(token.paddingSM)}px`,
205
- }, children: _jsx("div", { className: CARD_QUERY_CLASS, children: _jsxs("div", { className: `${CARD_FRAME_CLASS} ${CARD_BLEED_CLASS}`, children: [_jsx("div", { className: CARD_MEDIA_CLASS, children: _jsx(ListingPhotoStrip, { images: listing.images ?? [], title: title.length > 0 ? title : String(listing.id), testId: "listings-card-photos" }) }), _jsxs("div", { className: CARD_MAIN_CLASS, children: [_jsx(CardTarget, { ...props, listingId: listing.id, label: targetLabel, children: content }), props.showFavorite === false ? null : (_jsx("div", { style: {
252
+ }, children: _jsx("div", { className: CARD_QUERY_CLASS, children: _jsxs("div", { className: `${CARD_FRAME_CLASS} ${CARD_BLEED_CLASS}`, children: [_jsx("div", { className: CARD_MEDIA_CLASS, children: _jsx(ListingPhotoStrip, { images: listing.images ?? [], title: title.length > 0 ? title : String(listing.id), testId: "listings-card-photos" }) }), _jsxs("div", { className: CARD_MAIN_CLASS, children: [_jsx(CardTarget, { ...props, listingId: listing.id, label: targetLabel, children: content }), props.showFavorite === false ? null : (_jsxs("div", { style: {
206
253
  paddingInline: token.paddingSM,
207
254
  paddingBlockEnd: token.paddingSM,
208
- }, children: blockedReason === "popover" &&
209
- favoriteGate.reason !== undefined ? (
210
- /* The third volume: nothing standing in the layout. The
211
- heart is `aria-disabled`, NOT `disabled` — the gate
212
- already refuses the action (`toggle` is a no-op while
213
- blocked), and an html-disabled button would swallow
214
- the hover, the focus and the tap the disclosure opens
215
- on, which is the exact grave the old Tooltip died in. */
216
- _jsx(GateReasonPopover, { reason: favoriteGate.reason, cta: props.signIn, testId: "listings-card-favorite-reason", signInTestId: "listings-card-sign-in", children: (bind) => (_jsx(Flex, { justify: "flex-end", style: { width: "100%" }, children: _jsx(Button, { "aria-disabled": true, ...bind, "aria-label": favoriteLabel, "aria-pressed": favorite.favorited, "data-testid": "listings-card-favorite", "data-favorited": String(favorite.favorited), "data-analytics": "none", "data-analytics-reason": "business action \u2014 host app wraps with its own tracked()", onClick: favorite.toggle, icon: _jsx(HeartIcon, { filled: favorite.favorited }) }) })) })) : (_jsxs(_Fragment, { children: [_jsx(GatedControl, { gate: favorite.gate, testId: "listings-card-actions", style: { width: "100%" }, children: (bind) => (_jsx(Flex, { justify: "flex-end", style: { width: "100%" }, children: _jsx(Button, { disabled: bind.disabled, "data-disabled-reason": "the enclosing <GatedControl> renders the gate's reason beside this button", ...(bind["aria-describedby"] !== undefined
217
- ? { "aria-describedby": bind["aria-describedby"] }
218
- : {}), "aria-label": favoriteLabel, "aria-pressed": favorite.favorited, "data-testid": "listings-card-favorite", "data-favorited": String(favorite.favorited), "data-analytics": "none", "data-analytics-reason": "business action \u2014 host app wraps with its own tracked()", onClick: favorite.toggle, icon: _jsx(HeartIcon, { filled: favorite.favorited }) }) })) }), favoriteGate.reason === undefined || blockedReason === "line" ? null : (_jsx(Typography.Text, { type: "secondary", "data-testid": "listings-card-favorite-blocked", children: _jsx(SignInLink, { cta: props.signIn, testId: "listings-card-sign-in" }) }))] })) }))] })] }) }) })] }));
255
+ }, children: [blockedReason === "popover" &&
256
+ favoriteGate.reason !== undefined ? (
257
+ /* The third volume: nothing standing in the layout. The
258
+ heart is `aria-disabled`, NOT `disabled` — the gate
259
+ already refuses the action (`toggle` is a no-op while
260
+ blocked), and an html-disabled button would swallow
261
+ the hover, the focus and the tap the disclosure opens
262
+ on, which is the exact grave the old Tooltip died in. */
263
+ _jsx(GateReasonPopover, { reason: favoriteGate.reason, cta: props.signIn, testId: "listings-card-favorite-reason", signInTestId: "listings-card-sign-in", children: (bind) => (_jsx(Flex, { justify: "flex-end", style: { width: "100%" }, children: _jsx(Button, { "aria-disabled": true, ...bind, "aria-label": favoriteLabel, "aria-pressed": favorite.favorited, "data-testid": "listings-card-favorite", "data-favorited": String(favorite.favorited), "data-analytics": "none", "data-analytics-reason": "business action \u2014 host app wraps with its own tracked()", onClick: favorite.toggle, icon: heartIcon }) })) })) : (_jsxs(_Fragment, { children: [_jsx(GatedControl, { gate: favorite.gate, testId: "listings-card-actions", style: { width: "100%" }, children: (bind) => (_jsx(Flex, { justify: "flex-end", style: { width: "100%" }, children: _jsx(Button
264
+ // The substrate's binding, spread whole: it now
265
+ // owns "never inert" for the whole fleet
266
+ // `disabled` stays false, `aria-disabled` and
267
+ // `tabIndex` come from it, and the reason is
268
+ // wired by `aria-describedby`.
269
+ , { ...bind, "aria-label": favoriteLabel, "aria-pressed": favorite.favorited, "data-testid": "listings-card-favorite", "data-favorited": String(favorite.favorited), "data-analytics": "none", "data-analytics-reason": "business action \u2014 host app wraps with its own tracked()", onClick: favorite.toggle, icon: heartIcon }) })) }), favoriteGate.reason === undefined || blockedReason === "line" ? null : (_jsx(Typography.Text, { type: "secondary", "data-testid": "listings-card-favorite-blocked", children: _jsx(SignInLink, { cta: props.signIn, testId: "listings-card-sign-in" }) }))] })), _jsx(ErrorAlert, { testId: "listings-card-favorite-error", thrown: favorite.error, variant: "inline" })] }))] })] }) }) })] }));
219
270
  }
220
271
  //# sourceMappingURL=ListingCard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ListingCard.js","sourceRoot":"","sources":["../../src/default/ListingCard.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ListingCard.js","sourceRoot":"","sources":["../../src/default/ListingCard.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ListingDetailPane.d.ts","sourceRoot":"","sources":["../../src/default/ListingDetailPane.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAiBrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAc9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEtE;;oBAEoB;AACpB,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,UAAU,CAAC;AAE5C;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAE1C;;;;iCAIiC;AACjC,eAAO,MAAM,gBAAgB,UAAU,CAAC;AAExC,MAAM,WAAW,sBACf,SAAQ,aAAa,EACnB,oBAAoB;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;6BAEyB;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IACrC;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC;IACjC;6EACyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC;;sDAEkD;IAClD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC;IAC7B;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;CAC7B;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,YAAY,CA+e7E"}
1
+ {"version":3,"file":"ListingDetailPane.d.ts","sourceRoot":"","sources":["../../src/default/ListingDetailPane.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAiBrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAc9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEtE;;oBAEoB;AACpB,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,UAAU,CAAC;AAE5C;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAE1C;;;;iCAIiC;AACjC,eAAO,MAAM,gBAAgB,UAAU,CAAC;AAExC,MAAM,WAAW,sBACf,SAAQ,aAAa,EACnB,oBAAoB;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;6BAEyB;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IACrC;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC;IACjC;6EACyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC;;sDAEkD;IAClD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC;IAC7B;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;CAC7B;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,YAAY,CA+gB7E"}
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Descriptions, Divider, Flex, Typography } from "antd";
2
+ import { Descriptions, Divider, Flex, Typography, theme as antdTheme } from "antd";
3
3
  import { SkinButton as Button } from "@stapel/tokens-antd/skin";
4
4
  import { ErrorAlert, EmptyState, GatedButton, GatedControl, SkinTheme, } from "@stapel/tokens-antd/skin";
5
5
  import { SlotPlaceholder, matchLoad, useActionGate, useI18n, useT, } from "@stapel/core";
@@ -45,6 +45,7 @@ export const DETAIL_PHOTO_MIN = "14rem";
45
45
  export function ListingDetailPane(props) {
46
46
  const t = useT();
47
47
  const { locale } = useI18n();
48
+ const { token } = antdTheme.useToken();
48
49
  const bag = useListingDetail(props.id, {
49
50
  ...(props.viewerId !== undefined ? { viewerId: props.viewerId } : {}),
50
51
  ...(props.categoryFeatures !== undefined
@@ -58,9 +59,13 @@ export function ListingDetailPane(props) {
58
59
  // leaves rendering the reason to `<GatedControl>`, which computes its own.
59
60
  const favoriteView = useActionGate(bag.favoriteGate);
60
61
  const split = props.layout === "split";
61
- const favoriteLabel = t(bag.isFavorited === true
62
+ const favoriteLabel = t(bag.isFavorited
62
63
  ? LISTINGS_I18N_KEYS.cardFavoriteRemove
63
64
  : LISTINGS_I18N_KEYS.cardFavoriteAdd);
65
+ // Saved is a SOLID accent shape; not-saved (and `is_favorited: null`, which
66
+ // is "nobody asked", not "no") is the outline. The bag flips it on the
67
+ // gesture and rolls it back if the write fails — see `useListingDetail`.
68
+ const heartIcon = (_jsx(HeartIcon, { filled: bag.isFavorited, ...(bag.isFavorited ? { color: token.colorPrimary } : {}) }));
64
69
  return (_jsx(SkinTheme, { surface: "base", style: {
65
70
  maxWidth: split ? DETAIL_SPLIT_MEASURE : DETAIL_MEASURE,
66
71
  padding: spacing[4],
@@ -121,10 +126,10 @@ export function ListingDetailPane(props) {
121
126
  rather than `disabled`, so the disclosure's hover, focus
122
127
  and tap all arrive — and the click is a safe no-op, because
123
128
  `toggleFavorite` refuses while the gate is blocked. */
124
- _jsx(GateReasonPopover, { reason: favoriteView.reason, cta: props.signIn, testId: "listings-detail-favorite-reason", signInTestId: "listings-detail-sign-in", children: (bind) => (_jsx(Button, { "aria-disabled": true, ...bind, "aria-label": favoriteLabel, "aria-pressed": bag.isFavorited === true, icon: _jsx(HeartIcon, { filled: bag.isFavorited === true }), "data-testid": "listings-detail-favorite", "data-analytics": "none", "data-analytics-reason": "business action \u2014 host app wraps with its own tracked()", onClick: bag.toggleFavorite, children: favoriteLabel })) })) : (_jsxs(Flex, { vertical: true, gap: spacing[1], children: [_jsx(GatedControl, { gate: bag.favoriteGate, testId: "listings-detail-favorite-gate", children: (bind) => (_jsx(Button, { disabled: bind.disabled, "data-disabled-reason": "the enclosing <GatedControl> renders the gate's reason beside this button", ...(bind["aria-describedby"] !== undefined
125
- ? { "aria-describedby": bind["aria-describedby"] }
126
- : {}), "aria-label": favoriteLabel, "aria-pressed": bag.isFavorited === true, icon: _jsx(HeartIcon, { filled: bag.isFavorited === true }), "data-testid": "listings-detail-favorite", "data-analytics": "none", "data-analytics-reason": "business action \u2014 host app wraps with its own tracked()", onClick: bag.toggleFavorite, children: favoriteLabel })) }), bag.favoriteGate.available ? null : (_jsx(Typography.Text, { type: "secondary", "data-testid": "listings-detail-favorite-blocked", children: _jsx(SignInLink, { cta: props.signIn, testId: "listings-detail-sign-in" }) }))] })), props.actions] }));
127
- const actionError = actions.error !== undefined && actions.error !== null ? (_jsx(ErrorAlert, { testId: "listings-detail-action-error", thrown: actions.error, variant: "inline" })) : null;
129
+ _jsx(GateReasonPopover, { reason: favoriteView.reason, cta: props.signIn, testId: "listings-detail-favorite-reason", signInTestId: "listings-detail-sign-in", children: (bind) => (_jsx(Button, { "aria-disabled": true, ...bind, "aria-label": favoriteLabel, "aria-pressed": bag.isFavorited, icon: heartIcon, "data-testid": "listings-detail-favorite", "data-favorited": String(bag.isFavorited), "data-analytics": "none", "data-analytics-reason": "business action \u2014 host app wraps with its own tracked()", onClick: bag.toggleFavorite, children: favoriteLabel })) })) : (_jsxs(Flex, { vertical: true, gap: spacing[1], children: [_jsx(GatedControl, { gate: bag.favoriteGate, testId: "listings-detail-favorite-gate", children: (bind) => (_jsx(Button
130
+ // See `<ListingCard>`: the binding, spread whole.
131
+ , { ...bind, "aria-label": favoriteLabel, "aria-pressed": bag.isFavorited, icon: heartIcon, "data-testid": "listings-detail-favorite", "data-favorited": String(bag.isFavorited), "data-analytics": "none", "data-analytics-reason": "business action \u2014 host app wraps with its own tracked()", onClick: bag.toggleFavorite, children: favoriteLabel })) }), bag.favoriteGate.available ? null : (_jsx(Typography.Text, { type: "secondary", "data-testid": "listings-detail-favorite-blocked", children: _jsx(SignInLink, { cta: props.signIn, testId: "listings-detail-sign-in" }) }))] })), props.actions] }));
132
+ const actionError = (_jsxs(_Fragment, { children: [actions.error !== undefined && actions.error !== null ? (_jsx(ErrorAlert, { testId: "listings-detail-action-error", thrown: actions.error, variant: "inline" })) : null, _jsx(ErrorAlert, { testId: "listings-detail-favorite-error", thrown: bag.favoriteError, variant: "inline" })] }));
128
133
  const description = (_jsxs(_Fragment, { children: [_jsx(Typography.Title, { level: 5, children: t(LISTINGS_I18N_KEYS.detailDescription) }), _jsx(Typography.Paragraph, { "data-testid": "listings-detail-description", children: listing.description ?? "" })] }));
129
134
  /* The DISPLAY envelope, not the edit one: a redacted row keeps
130
135
  its place in the table and says the seller supplied the value.
@@ -153,7 +158,7 @@ export function ListingDetailPane(props) {
153
158
  count: bag.unreadableFeatures,
154
159
  }) })) : null] }));
155
160
  const meta = (_jsxs(Descriptions, { size: "small", column: 1, children: [listing.stock_quantity != null ? (_jsx(Descriptions.Item, { label: t(LISTINGS_I18N_KEYS.detailStock), children: _jsx("span", { "data-testid": "listings-detail-stock", children: listing.stock_quantity }) })) : null, listing.location_label !== undefined &&
156
- listing.location_label.length > 0 ? (_jsx(Descriptions.Item, { label: t(LISTINGS_I18N_KEYS.composeLocationLabel), children: listing.location_label })) : null] }));
161
+ listing.location_label.length > 0 ? (_jsx(Descriptions.Item, { label: t(LISTINGS_I18N_KEYS.composeLocationLabel), children: listing.location_label })) : null, bag.viewCount !== undefined ? (_jsx(Descriptions.Item, { label: t(LISTINGS_I18N_KEYS.detailViews), children: _jsx("span", { "data-testid": "listings-detail-views", children: bag.viewCount }) })) : null] }));
157
162
  const aside = props.aside !== undefined ? (_jsx("div", { "data-testid": "listings-detail-aside", children: props.aside })) : null;
158
163
  if (!split) {
159
164
  // The single column, in the order it has always read — the