@stapel/listings-react 0.20.0 → 0.21.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.
- package/CHANGELOG.md +12 -0
- package/dist/default/ListingCard.d.ts +11 -0
- package/dist/default/ListingCard.d.ts.map +1 -1
- package/dist/default/ListingCard.js +34 -4
- package/dist/default/ListingCard.js.map +1 -1
- package/dist/default/ListingPhoto.d.ts +40 -0
- package/dist/default/ListingPhoto.d.ts.map +1 -1
- package/dist/default/ListingPhoto.js +53 -6
- package/dist/default/ListingPhoto.js.map +1 -1
- package/llms.txt +2 -2
- package/manifest.json +2 -2
- package/nav-manifest.json +1 -1
- package/package.json +2 -2
- package/src/analytics/generated/events.json +1 -1
- package/src/default/ListingCard.tsx +44 -9
- package/src/default/ListingPhoto.tsx +102 -18
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @stapel/listings-react
|
|
2
2
|
|
|
3
|
+
## 0.21.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 8279cb6: **The picture opens the listing, and the card looks like something you can open.**
|
|
8
|
+
|
|
9
|
+
Measured on a live 1440px grid: `<ListingCard>`'s anchor covered only the 267×104 text block. The 267×200 photograph — the largest and most obvious target on the card — sat outside it, with `cursor: auto`, and clicking it left the visitor exactly where they were. The card had no hover state of any kind: `box-shadow: none`, `transform: none`, the border unchanged.
|
|
10
|
+
|
|
11
|
+
- `<ListingPhotoStrip href linkComponent>` links each SLIDE. The strip itself stays a sibling of the reading anchor — a swipeable scroller is a control and a link may not contain one — but the picture inside it is now part of the card's target. The slide links are `aria-hidden` + `tabIndex={-1}`, so the card is still one tab stop with one accessible name: a second way to reach a destination, not a second destination.
|
|
12
|
+
- `<ListingCard>` passes its own `href` through and carries `CARD_HOVER_CLASS`, which raises the theme's own `boxShadowSecondary` and the focus colour on the border. antd's `hoverable` was not used: it hard-codes one shadow, cannot state a border, and cannot stand still for somebody who asked their system for less motion — this rule does, under `prefers-reduced-motion`.
|
|
13
|
+
- A surface that passes no `href` to the strip renders exactly as before. `<ListingSerpCard>` passes none: a horizontal swipe is a real gesture on a phone, and it is the gesture that rule was written for.
|
|
14
|
+
|
|
3
15
|
## 0.20.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
|
@@ -204,6 +204,17 @@ export declare const CARD_BLEED_CLASS = "stapel-listing-card-bleed";
|
|
|
204
204
|
* the card behind it is old news.
|
|
205
205
|
*/
|
|
206
206
|
export declare const CARD_VIEWED_CLASS = "stapel-listing-card-seen";
|
|
207
|
+
/**
|
|
208
|
+
* The class that makes a card LOOK like a target.
|
|
209
|
+
*
|
|
210
|
+
* Measured on a live 1440px grid before this pack: `box-shadow: none`,
|
|
211
|
+
* `transform: none`, the border unchanged and `cursor: auto` — a card that
|
|
212
|
+
* opens a listing and gives a person no reason to believe it does. antd's own
|
|
213
|
+
* `hoverable` was not used: it hard-codes `boxShadowCard` and nothing else, so
|
|
214
|
+
* it cannot state a border and cannot be told to stand still for somebody who
|
|
215
|
+
* asked their system for less motion.
|
|
216
|
+
*/
|
|
217
|
+
export declare const CARD_HOVER_CLASS = "stapel-listing-card-hoverable";
|
|
207
218
|
/**
|
|
208
219
|
* How far a seen card is dimmed.
|
|
209
220
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListingCard.d.ts","sourceRoot":"","sources":["../../src/default/ListingCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyGG;AACH,OAAO,KAAK,EAAiB,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKpE,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGjE,OAAO,KAAK,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAatE,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEtE;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,oBAAoB,GAC5B;IACE;iEAC6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;8CAE0C;IAC1C,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;CAC7B,GACD;IACE;wEACoE;IACpE,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC;CACpC,GACD;IACE;kBACc;IACd,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC;CACpC,CAAC;AAEN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,MAAM,wBAAwB,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAEnE,0EAA0E;AAC1E,eAAO,MAAM,iBAAiB,+BAA+B,CAAC;AAC9D;;0CAE0C;AAC1C,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AACxD,iDAAiD;AACjD,eAAO,MAAM,gBAAgB,8BAA8B,CAAC;AAC5D,+CAA+C;AAC/C,eAAO,MAAM,gBAAgB,8BAA8B,CAAC;AAC5D,4CAA4C;AAC5C,eAAO,MAAM,eAAe,6BAA6B,CAAC;AAC1D;gFACgF;AAChF,eAAO,MAAM,gBAAgB,8BAA8B,CAAC;AAE5D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,6BAA6B,CAAC;AAE5D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C,iEAAiE;AACjE,eAAO,MAAM,sBAAsB,gCAAgC,CAAC;AAEpE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;wEACwE;AACxE,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"ListingCard.d.ts","sourceRoot":"","sources":["../../src/default/ListingCard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -14,7 +14,7 @@ import { LISTINGS_I18N_KEYS } from "../i18n/keys.js";
|
|
|
14
14
|
import { GateReasonPopover } from "./GateReasonPopover.js";
|
|
15
15
|
import { HeartIcon } from "./icons.js";
|
|
16
16
|
import { SignInLink } from "./SignInLink.js";
|
|
17
|
-
import { ListingPhotoStrip } from "./ListingPhoto.js";
|
|
17
|
+
import { PHOTO_LINK_CLASS, ListingPhotoStrip } from "./ListingPhoto.js";
|
|
18
18
|
import { ListingPrice } from "./ListingPrice.js";
|
|
19
19
|
/** The class the whole-card target carries, for {@link cardTargetCss}. */
|
|
20
20
|
export const CARD_TARGET_CLASS = "stapel-listing-card-target";
|
|
@@ -43,6 +43,17 @@ export const CARD_BLEED_CLASS = "stapel-listing-card-bleed";
|
|
|
43
43
|
* the card behind it is old news.
|
|
44
44
|
*/
|
|
45
45
|
export const CARD_VIEWED_CLASS = "stapel-listing-card-seen";
|
|
46
|
+
/**
|
|
47
|
+
* The class that makes a card LOOK like a target.
|
|
48
|
+
*
|
|
49
|
+
* Measured on a live 1440px grid before this pack: `box-shadow: none`,
|
|
50
|
+
* `transform: none`, the border unchanged and `cursor: auto` — a card that
|
|
51
|
+
* opens a listing and gives a person no reason to believe it does. antd's own
|
|
52
|
+
* `hoverable` was not used: it hard-codes `boxShadowCard` and nothing else, so
|
|
53
|
+
* it cannot state a border and cannot be told to stand still for somebody who
|
|
54
|
+
* asked their system for less motion.
|
|
55
|
+
*/
|
|
56
|
+
export const CARD_HOVER_CLASS = "stapel-listing-card-hoverable";
|
|
46
57
|
/**
|
|
47
58
|
* How far a seen card is dimmed.
|
|
48
59
|
*
|
|
@@ -98,6 +109,7 @@ export function cardTargetCss() {
|
|
|
98
109
|
const media = `.${CARD_MEDIA_CLASS}`;
|
|
99
110
|
const main = `.${CARD_MAIN_CLASS}`;
|
|
100
111
|
const bleed = `.${CARD_BLEED_CLASS}`;
|
|
112
|
+
const hover = CARD_HOVER_CLASS;
|
|
101
113
|
return [
|
|
102
114
|
`.${CARD_TARGET_CLASS}{display:block;color:inherit;text-decoration:none}`,
|
|
103
115
|
`.${CARD_TARGET_CLASS}:focus-visible{outline:2px solid var(--listing-card-focus);outline-offset:2px}`,
|
|
@@ -120,6 +132,18 @@ export function cardTargetCss() {
|
|
|
120
132
|
`${bleed}{padding-block:var(--listing-card-inset);` +
|
|
121
133
|
`padding-inline-start:var(--listing-card-inset)}` +
|
|
122
134
|
`}`,
|
|
135
|
+
// A linked slide. `display:block` kills the inline baseline gap under the
|
|
136
|
+
// picture, which on a grid of tiles reads as cards of unequal height; the
|
|
137
|
+
// ring is for a browser that focuses an `aria-hidden` anchor anyway.
|
|
138
|
+
`.${PHOTO_LINK_CLASS}{display:block}`,
|
|
139
|
+
`.${PHOTO_LINK_CLASS}:focus-visible{outline:2px solid var(--listing-card-focus);outline-offset:2px}`,
|
|
140
|
+
// The card says it is a target. Two properties, both from the theme's own
|
|
141
|
+
// tokens, and a transition that a person who asked for less motion does
|
|
142
|
+
// not get.
|
|
143
|
+
`.${hover}{transition:box-shadow 160ms ease,border-color 160ms ease}`,
|
|
144
|
+
`.${hover}:hover{box-shadow:var(--listing-card-hover-shadow);` +
|
|
145
|
+
`border-color:var(--listing-card-focus)}`,
|
|
146
|
+
`@media (prefers-reduced-motion:reduce){.${hover}{transition:none}}`,
|
|
123
147
|
// Already seen. The photo and everything inside the card's anchor dim
|
|
124
148
|
// together; the heart is outside the anchor and stays as it was — see
|
|
125
149
|
// CARD_VIEWED_CLASS.
|
|
@@ -238,9 +262,10 @@ export function ListingCard(props) {
|
|
|
238
262
|
listing.location_label.length > 0 ? (_jsx(Typography.Text, { type: "secondary", "data-testid": "listings-card-location", children: listing.location_label })) : null] }));
|
|
239
263
|
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
|
|
240
264
|
? { "data-listing-status": status.status }
|
|
241
|
-
: {}), ...(viewed
|
|
242
|
-
? { className: CARD_VIEWED_CLASS, "data-listing-viewed": "true" }
|
|
243
265
|
: {}),
|
|
266
|
+
// `viewed` only when the server actually said so: absent and `null`
|
|
267
|
+
// leave the card's dimming exactly as it renders today.
|
|
268
|
+
className: viewed ? `${CARD_HOVER_CLASS} ${CARD_VIEWED_CLASS}` : CARD_HOVER_CLASS, ...(viewed ? { "data-listing-viewed": "true" } : {}),
|
|
244
269
|
// The body's own padding is zero because the frame fills the card and
|
|
245
270
|
// the photo runs edge to edge when it is stacked: padding here would
|
|
246
271
|
// be a strip of card around a picture. The text block inside the
|
|
@@ -249,7 +274,12 @@ export function ListingCard(props) {
|
|
|
249
274
|
styles: { body: { minWidth: 0, padding: 0 } }, style: {
|
|
250
275
|
["--listing-card-focus"]: token.colorPrimary,
|
|
251
276
|
["--listing-card-inset"]: `${String(token.paddingSM)}px`,
|
|
252
|
-
|
|
277
|
+
// The theme's own elevation, so the lift is the same one every
|
|
278
|
+
// raised surface in the skin uses and it is right in both modes.
|
|
279
|
+
["--listing-card-hover-shadow"]: token.boxShadowSecondary,
|
|
280
|
+
}, 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", ...(props.href !== undefined ? { href: props.href } : {}), ...(props.href !== undefined && props.linkComponent !== undefined
|
|
281
|
+
? { linkComponent: props.linkComponent }
|
|
282
|
+
: {}) }) }), _jsxs("div", { className: CARD_MAIN_CLASS, children: [_jsx(CardTarget, { ...props, listingId: listing.id, label: targetLabel, children: content }), props.showFavorite === false ? null : (_jsxs("div", { style: {
|
|
253
283
|
paddingInline: token.paddingSM,
|
|
254
284
|
paddingBlockEnd: token.paddingSM,
|
|
255
285
|
}, children: [blockedReason === "popover" &&
|
|
@@ -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":";AA2GA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAClE,OAAO,EAAE,UAAU,IAAI,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAErG,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AA6EjD,0EAA0E;AAC1E,MAAM,CAAC,MAAM,iBAAiB,GAAG,4BAA4B,CAAC;AAC9D;;0CAE0C;AAC1C,MAAM,CAAC,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AACxD,iDAAiD;AACjD,MAAM,CAAC,MAAM,gBAAgB,GAAG,2BAA2B,CAAC;AAC5D,+CAA+C;AAC/C,MAAM,CAAC,MAAM,gBAAgB,GAAG,2BAA2B,CAAC;AAC5D,4CAA4C;AAC5C,MAAM,CAAC,MAAM,eAAe,GAAG,0BAA0B,CAAC;AAC1D;gFACgF;AAChF,MAAM,CAAC,MAAM,gBAAgB,GAAG,2BAA2B,CAAC;AAE5D;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,0BAA0B,CAAC;AAE5D;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,+BAA+B,CAAC;AAEhE;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAE3C,iEAAiE;AACjE,MAAM,CAAC,MAAM,sBAAsB,GAAG,6BAA6B,CAAC;AAEpE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAExC;wEACwE;AACxE,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAE1C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,CAAC,GAAG,IAAI,gBAAgB,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,IAAI,gBAAgB,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,gBAAgB,EAAE,CAAC;IACrC,MAAM,IAAI,GAAG,IAAI,eAAe,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,IAAI,gBAAgB,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,gBAAgB,CAAC;IAC/B,OAAO;QACL,IAAI,iBAAiB,oDAAoD;QACzE,IAAI,iBAAiB,gFAAgF;QACrG,4DAA4D;QAC5D,0BAA0B;QAC1B,GAAG,CAAC,8BAA8B;QAClC,GAAG,KAAK,wDAAwD;QAChE,GAAG,KAAK,qBAAqB;QAC7B,GAAG,IAAI,sEAAsE;QAC7E,wEAAwE;QACxE,wEAAwE;QACxE,uDAAuD;QACvD,yBAAyB,MAAM,CAAC,oBAAoB,CAAC,MAAM;YACzD,GAAG,KAAK,6CAA6C;YACrD,GAAG,KAAK,aAAa,MAAM,CAAC,sBAAsB,CAAC,KAAK;YACxD,mBAAmB,MAAM,CAAC,sBAAsB,CAAC,KAAK;YACtD,sEAAsE;YACtE,sEAAsE;YACtE,0BAA0B;YAC1B,GAAG,KAAK,2CAA2C;YACnD,iDAAiD;YACjD,GAAG;QACL,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,IAAI,gBAAgB,iBAAiB;QACrC,IAAI,gBAAgB,gFAAgF;QACpG,0EAA0E;QAC1E,wEAAwE;QACxE,WAAW;QACX,IAAI,KAAK,4DAA4D;QACrE,IAAI,KAAK,qDAAqD;YAC5D,yCAAyC;QAC3C,2CAA2C,KAAK,oBAAoB;QACpE,sEAAsE;QACtE,sEAAsE;QACtE,qBAAqB;QACrB,IAAI,iBAAiB,KAAK,iBAAiB,GAAG;YAC5C,IAAI,iBAAiB,KAAK,gBAAgB,EAAE;YAC5C,yCAAyC,MAAM,CAAC,sBAAsB,CAAC,IAAI;KAC9E,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACb,CAAC;AAED;+CAC+C;AAC/C,MAAM,YAAY,GAAkB;IAClC,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,SAAS;IAChB,cAAc,EAAE,MAAM;CACvB,CAAC;AAEF;;6BAE6B;AAC7B,MAAM,mBAAmB,GAAkB;IACzC,GAAG,YAAY;IACf,KAAK,EAAE,MAAM;IACb,OAAO,EAAE,CAAC;IACV,MAAM,EAAE,MAAM;IACd,UAAU,EAAE,MAAM;IAClB,IAAI,EAAE,SAAS;IACf,SAAS,EAAE,OAAO;IAClB,MAAM,EAAE,SAAS;CAClB,CAAC;AAmBF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,UAAU,CACxB,KAUC;IAED,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAClC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,oBAAoB,CAAC;IAEpD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC;QACjC,yEAAyE;QACzE,yEAAyE;QACzE,8DAA8D;QAC9D,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAC1B,KAAC,IAAI,IACH,IAAI,EAAE,KAAK,CAAC,IAAI,gBACJ,KAAK,EACjB,SAAS,EAAE,iBAAiB,iBACf,MAAM,oBACJ,MAAM,2BACC,8DAAyD,YAE9E,QAAQ,GACJ,CACR,CAAC,CAAC,CAAC,CACF,YACE,IAAI,EAAE,KAAK,CAAC,IAAI,gBACJ,KAAK,EACjB,SAAS,EAAE,iBAAiB,EAC5B,KAAK,EAAE,YAAY,iBACN,MAAM,oBACJ,MAAM,2BACC,8DAAyD,YAE9E,QAAQ,GACP,CACL,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,OAAO,CACL,iBACE,IAAI,EAAC,QAAQ,gBACD,KAAK,EACjB,SAAS,EAAE,iBAAiB,EAC5B,KAAK,EAAE,mBAAmB,iBACb,MAAM,oBACJ,MAAM,2BACC,8DAAyD,EAC/E,OAAO,EAAE,GAAG,EAAE;gBACZ,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAC1B,CAAC,YAEA,QAAQ,GACF,CACV,CAAC;IACJ,CAAC;IAED,uEAAuE;IACvE,OAAO,CACL,6BAAkB,KAAK,CAAC,UAAU,IAAI,oBAAoB,YAAG,QAAQ,GAAO,CAC7E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,2EAA2E;IAC3E,mEAAmE;IACnE,qEAAqE;IACrE,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACrE,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;IAEvC,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IAC5D,qEAAqE;IACrE,2EAA2E;IAC3E,qEAAqE;IACrE,MAAM,IAAI,GACR,KAAK,CAAC,gBAAgB,KAAK,SAAS;QAClC,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EAAE;QAC9C,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,aAAa,GAAG,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC3D,MAAM,WAAW,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAE3D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAE3F,MAAM,YAAY,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,IAAI,MAAM,CAAC;IACpD,wEAAwE;IACxE,gEAAgE;IAChE,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACxC,0EAA0E;IAC1E,qEAAqE;IACrE,yDAAyD;IACzD,MAAM,SAAS,GAAG,CAChB,KAAC,SAAS,IACR,MAAM,EAAE,QAAQ,CAAC,SAAS,KACtB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAC7D,CACH,CAAC;IAEF,MAAM,aAAa,GAAG,CAAC,CACrB,QAAQ,CAAC,SAAS;QAChB,CAAC,CAAC,kBAAkB,CAAC,kBAAkB;QACvC,CAAC,CAAC,kBAAkB,CAAC,eAAe,CACvC,CAAC;IAEF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;IAClC,2EAA2E;IAC3E,4EAA4E;IAC5E,eAAe;IACf,MAAM,WAAW,GACf,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAEhE;;;;;;;;;;OAUG;IACH,MAAM,OAAO,GAAG,CACd,MAAC,IAAI,IACH,QAAQ,QACR,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EACf,KAAK,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,aAE/C,KAAK,CAAC,KAAK,EAEZ,KAAC,UAAU,CAAC,IAAI,IAAC,MAAM,uBAAa,qBAAqB,YACvD,KAAC,YAAY,IACX,MAAM,EAAE,OAAO,CAAC,KAAK,KACjB,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAC1E,GACc,EAElB,KAAC,UAAU,CAAC,IAAI,IAAC,QAAQ,uBAAa,qBAAqB,YACxD,KAAK,GACU,EAIjB,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACtB,KAAC,UAAU,CAAC,IAAI,IAAC,IAAI,EAAC,WAAW,EAAC,QAAQ,kBACxC,KAAC,aAAa,IACZ,QAAQ,EAAE,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,GAAG,CAChD,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CACvB,EACD,MAAM,EAAE,sBAAsB,CAAC,SAAS,CAAC,GACzC,GACc,CACnB,CAAC,CAAC,CAAC,IAAI,EAEP,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC1B,KAAC,aAAa,IACZ,QAAQ,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EACnD,MAAM,EAAE,WAAW,GACnB,CACH,CAAC,CAAC,CAAC,IAAI,EAEP,OAAO,CAAC,cAAc,KAAK,SAAS;gBACrC,OAAO,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAClC,KAAC,UAAU,CAAC,IAAI,IAAC,IAAI,EAAC,WAAW,iBAAa,wBAAwB,YACnE,OAAO,CAAC,cAAc,GACP,CACnB,CAAC,CAAC,CAAC,IAAI,IACH,CACR,CAAC;IAEF,OAAO,CACL,MAAC,SAAS,IACR,OAAO,EAAC,MAAM,KACV,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAE1D,gBAAO,IAAI,EAAE,sBAAsB,EAAE,UAAU,EAAC,SAAS,YACtD,aAAa,EAAE,GACV,EACR,KAAC,IAAI,IACH,IAAI,EAAC,OAAO,iBACA,eAAe,qBACV,OAAO,CAAC,EAAE,KACvB,CAAC,MAAM,KAAK,SAAS;oBACvB,CAAC,CAAC,EAAE,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE;oBAC1C,CAAC,CAAC,EAAE,CAAC;gBACP,oEAAoE;gBACpE,wDAAwD;gBACxD,SAAS,EACP,MAAM,CAAC,CAAC,CAAC,GAAG,gBAAgB,IAAI,iBAAiB,EAAE,CAAC,CAAC,CAAC,gBAAgB,KAEpE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,qBAAqB,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrD,sEAAsE;gBACtE,qEAAqE;gBACrE,iEAAiE;gBACjE,qEAAqE;gBACrE,yDAAyD;gBACzD,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAC7C,KAAK,EAAE;oBACL,CAAC,sBAAgC,CAAC,EAAE,KAAK,CAAC,YAAY;oBACtD,CAAC,sBAAgC,CAAC,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI;oBAClE,+DAA+D;oBAC/D,iEAAiE;oBACjE,CAAC,6BAAuC,CAAC,EAAE,KAAK,CAAC,kBAAkB;iBACpE,YAED,cAAK,SAAS,EAAE,gBAAgB,YAC9B,eAAK,SAAS,EAAE,GAAG,gBAAgB,IAAI,gBAAgB,EAAE,aAMvD,cAAK,SAAS,EAAE,gBAAgB,YAC9B,KAAC,iBAAiB,IAChB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE,EAC5B,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EACpD,MAAM,EAAC,sBAAsB,KACzB,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KACtD,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,aAAa,KAAK,SAAS;wCAChE,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE;wCACxC,CAAC,CAAC,EAAE,CAAC,GACP,GACE,EAEN,eAAK,SAAS,EAAE,eAAe,aAC7B,KAAC,UAAU,OAAK,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,WAAW,YAC7D,OAAO,GACG,EAOZ,KAAK,CAAC,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACrC,eACE,KAAK,EAAE;4CACL,aAAa,EAAE,KAAK,CAAC,SAAS;4CAC9B,eAAe,EAAE,KAAK,CAAC,SAAS;yCACjC,aAEA,aAAa,KAAK,SAAS;gDAC5B,YAAY,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC;4CAClC;;;;;uGAK2D;4CAC3D,KAAC,iBAAiB,IAChB,MAAM,EAAE,YAAY,CAAC,MAAM,EAC3B,GAAG,EAAE,KAAK,CAAC,MAAM,EACjB,MAAM,EAAC,+BAA+B,EACtC,YAAY,EAAC,uBAAuB,YAEnC,CAAC,IAAI,EAAE,EAAE,CAAC,CACT,KAAC,IAAI,IAAC,OAAO,EAAC,UAAU,EAAC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAC/C,KAAC,MAAM,8BAED,IAAI,gBACI,aAAa,kBACX,QAAQ,CAAC,SAAS,iBACpB,wBAAwB,oBACpB,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,oBAC3B,MAAM,2BACC,8DAAyD,EAC/E,OAAO,EAAE,QAAQ,CAAC,MAAM,EACxB,IAAI,EAAE,SAAS,GACf,GACG,CACR,GACiB,CACrB,CAAC,CAAC,CAAC,CACF,8BACE,KAAC,YAAY,IACX,IAAI,EAAE,QAAQ,CAAC,IAAI,EACnB,MAAM,EAAC,uBAAuB,EAC9B,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAEvB,CAAC,IAAI,EAAE,EAAE,CAAC,CACT,KAAC,IAAI,IAAC,OAAO,EAAC,UAAU,EAAC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAC/C,KAAC,MAAM;4DACL,gDAAgD;4DAChD,2CAA2C;4DAC3C,8CAA8C;4DAC9C,6CAA6C;4DAC7C,+BAA+B;mEAC3B,IAAI,gBACI,aAAa,kBACX,QAAQ,CAAC,SAAS,iBACpB,wBAAwB,oBACpB,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,oBAC3B,MAAM,2BACC,8DAAyD,EAC/E,OAAO,EAAE,QAAQ,CAAC,MAAM,EACxB,IAAI,EAAE,SAAS,GACf,GACG,CACR,GACY,EAQd,YAAY,CAAC,MAAM,KAAK,SAAS,IAAI,aAAa,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACtE,KAAC,UAAU,CAAC,IAAI,IACd,IAAI,EAAC,WAAW,iBACJ,gCAAgC,YAE5C,KAAC,UAAU,IAAC,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAC,uBAAuB,GAAG,GAChD,CACnB,IACA,CACJ,EAQD,KAAC,UAAU,IACT,MAAM,EAAC,8BAA8B,EACrC,MAAM,EAAE,QAAQ,CAAC,KAAK,EACtB,OAAO,EAAC,QAAQ,GAChB,IACE,CACP,IACG,IACF,GACF,GACD,IACG,CACb,CAAC;AACJ,CAAC"}
|
|
@@ -22,6 +22,16 @@
|
|
|
22
22
|
* belongs here — it is why `@stapel/image` exists.
|
|
23
23
|
*/
|
|
24
24
|
import type { CSSProperties, ReactElement } from "react";
|
|
25
|
+
import type { LinkComponent } from "@stapel/core";
|
|
26
|
+
/**
|
|
27
|
+
* The class a linked slide carries.
|
|
28
|
+
*
|
|
29
|
+
* `display:block` is the load-bearing half: an inline anchor around a block
|
|
30
|
+
* image leaves a baseline gap under the picture, which on a grid of tiles is a
|
|
31
|
+
* visible row of mismatched card heights. The rule itself lives in
|
|
32
|
+
* `cardTargetCss()`, beside the card's other one-rule-per-defect entries.
|
|
33
|
+
*/
|
|
34
|
+
export declare const PHOTO_LINK_CLASS = "stapel-listing-photo-link";
|
|
25
35
|
/** The default shape of a listing photo box everywhere in this skin. Declared
|
|
26
36
|
* once so a card, a detail hero and a dashboard thumbnail cannot drift into
|
|
27
37
|
* three different crops. */
|
|
@@ -50,6 +60,28 @@ export declare function ListingPhoto(props: ListingPhotoProps): ReactElement;
|
|
|
50
60
|
* SERP was measured correct on while the desktop card (a still `<img>` inside
|
|
51
61
|
* the anchor, one photo, no dots) was not.
|
|
52
62
|
*
|
|
63
|
+
* ── …and why each SLIDE may still be one, when a card asks (`href`) ────────
|
|
64
|
+
*
|
|
65
|
+
* The rule above is about the STRIP, and it was read as a rule about the
|
|
66
|
+
* picture. It is not, and the difference was measured: on a 1440px grid the
|
|
67
|
+
* photo is 267x200 — the largest, most obvious target on the card — and
|
|
68
|
+
* clicking it did nothing at all. `cursor: auto`, no hover, and the visitor
|
|
69
|
+
* stayed on the page they were already on. A person who clicks a picture of a
|
|
70
|
+
* phone is asking to see the phone; there is no reading of that click in which
|
|
71
|
+
* the right answer is silence.
|
|
72
|
+
*
|
|
73
|
+
* So a card may hand this strip its own `href`, and each slide becomes a link
|
|
74
|
+
* around its picture. What that does NOT do is make the strip a link: the
|
|
75
|
+
* scroller, its arrows and its dots stay controls, outside every anchor,
|
|
76
|
+
* because they are what the header's rule is actually protecting. And the
|
|
77
|
+
* slide links are `tabIndex={-1}` + `aria-hidden`, so a card is still ONE tab
|
|
78
|
+
* stop and one accessible name — the reading anchor's — rather than one per
|
|
79
|
+
* photograph.
|
|
80
|
+
*
|
|
81
|
+
* A surface that does not pass `href` is byte-identical to before. The phone
|
|
82
|
+
* SERP passes none: a horizontal swipe is a real gesture there, and it is the
|
|
83
|
+
* gesture the header's rule was written for.
|
|
84
|
+
*
|
|
53
85
|
* A listing with no photos still gets one slide, so a row's height does not
|
|
54
86
|
* depend on whether a seller uploaded anything, and a ONE-photo strip gets
|
|
55
87
|
* neither peek nor dots: the sliver of a next slide is an affordance for
|
|
@@ -63,5 +95,13 @@ export declare function ListingPhotoStrip(props: {
|
|
|
63
95
|
/** The surface's own test id, so a screen holding two kinds of card does
|
|
64
96
|
* not hand a test two elements under one name. */
|
|
65
97
|
readonly testId: string;
|
|
98
|
+
/**
|
|
99
|
+
* Where a click on the PICTURE goes — the card's own `href`, when the card
|
|
100
|
+
* wants its photograph to be part of its target. Omitted, every slide is
|
|
101
|
+
* inert exactly as it has always been.
|
|
102
|
+
*/
|
|
103
|
+
readonly href?: string;
|
|
104
|
+
/** The host's `<Link>`, so the click stays inside the SPA. */
|
|
105
|
+
readonly linkComponent?: LinkComponent;
|
|
66
106
|
}): ReactElement;
|
|
67
107
|
//# sourceMappingURL=ListingPhoto.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListingPhoto.d.ts","sourceRoot":"","sources":["../../src/default/ListingPhoto.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ListingPhoto.d.ts","sourceRoot":"","sources":["../../src/default/ListingPhoto.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAMzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAMlD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,8BAA8B,CAAC;AAE5D;;4BAE4B;AAC5B,eAAO,MAAM,oBAAoB,UAAU,CAAC;AAE5C,MAAM,WAAW,iBAAiB;IAChC,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,uEAAuE;IACvE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;CAChC;AAwBD,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAmEnE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;sDACkD;IAClD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;CACxC,GAAG,YAAY,CA0Ef"}
|
|
@@ -7,6 +7,15 @@ import { useT } from "@stapel/core";
|
|
|
7
7
|
import { radii, spacing } from "@stapel/tokens";
|
|
8
8
|
import { useListingsRuntime } from "../model/context.js";
|
|
9
9
|
import { LISTINGS_I18N_KEYS } from "../i18n/keys.js";
|
|
10
|
+
/**
|
|
11
|
+
* The class a linked slide carries.
|
|
12
|
+
*
|
|
13
|
+
* `display:block` is the load-bearing half: an inline anchor around a block
|
|
14
|
+
* image leaves a baseline gap under the picture, which on a grid of tiles is a
|
|
15
|
+
* visible row of mismatched card heights. The rule itself lives in
|
|
16
|
+
* `cardTargetCss()`, beside the card's other one-rule-per-defect entries.
|
|
17
|
+
*/
|
|
18
|
+
export const PHOTO_LINK_CLASS = "stapel-listing-photo-link";
|
|
10
19
|
/** The default shape of a listing photo box everywhere in this skin. Declared
|
|
11
20
|
* once so a card, a detail hero and a dashboard thumbnail cannot drift into
|
|
12
21
|
* three different crops. */
|
|
@@ -72,6 +81,28 @@ export function ListingPhoto(props) {
|
|
|
72
81
|
* SERP was measured correct on while the desktop card (a still `<img>` inside
|
|
73
82
|
* the anchor, one photo, no dots) was not.
|
|
74
83
|
*
|
|
84
|
+
* ── …and why each SLIDE may still be one, when a card asks (`href`) ────────
|
|
85
|
+
*
|
|
86
|
+
* The rule above is about the STRIP, and it was read as a rule about the
|
|
87
|
+
* picture. It is not, and the difference was measured: on a 1440px grid the
|
|
88
|
+
* photo is 267x200 — the largest, most obvious target on the card — and
|
|
89
|
+
* clicking it did nothing at all. `cursor: auto`, no hover, and the visitor
|
|
90
|
+
* stayed on the page they were already on. A person who clicks a picture of a
|
|
91
|
+
* phone is asking to see the phone; there is no reading of that click in which
|
|
92
|
+
* the right answer is silence.
|
|
93
|
+
*
|
|
94
|
+
* So a card may hand this strip its own `href`, and each slide becomes a link
|
|
95
|
+
* around its picture. What that does NOT do is make the strip a link: the
|
|
96
|
+
* scroller, its arrows and its dots stay controls, outside every anchor,
|
|
97
|
+
* because they are what the header's rule is actually protecting. And the
|
|
98
|
+
* slide links are `tabIndex={-1}` + `aria-hidden`, so a card is still ONE tab
|
|
99
|
+
* stop and one accessible name — the reading anchor's — rather than one per
|
|
100
|
+
* photograph.
|
|
101
|
+
*
|
|
102
|
+
* A surface that does not pass `href` is byte-identical to before. The phone
|
|
103
|
+
* SERP passes none: a horizontal swipe is a real gesture there, and it is the
|
|
104
|
+
* gesture the header's rule was written for.
|
|
105
|
+
*
|
|
75
106
|
* A listing with no photos still gets one slide, so a row's height does not
|
|
76
107
|
* depend on whether a seller uploaded anything, and a ONE-photo strip gets
|
|
77
108
|
* neither peek nor dots: the sliver of a next slide is an affordance for
|
|
@@ -81,11 +112,27 @@ export function ListingPhotoStrip(props) {
|
|
|
81
112
|
const t = useT();
|
|
82
113
|
const { images, title } = props;
|
|
83
114
|
const many = images.length > 1;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
115
|
+
/**
|
|
116
|
+
* One slide, linked or not.
|
|
117
|
+
*
|
|
118
|
+
* `aria-hidden` + `tabIndex={-1}`: this is a SECOND way to reach a
|
|
119
|
+
* destination the card already names, not a second destination. Without it a
|
|
120
|
+
* grid of twenty-four cards grows twenty-four extra tab stops, each
|
|
121
|
+
* announcing the same listing the card announced a moment ago.
|
|
122
|
+
*/
|
|
123
|
+
const slide = (photo, key) => {
|
|
124
|
+
if (props.href === undefined)
|
|
125
|
+
return photo;
|
|
126
|
+
const Link = props.linkComponent;
|
|
127
|
+
return Link !== undefined ? (_jsx(Link, { href: props.href, className: PHOTO_LINK_CLASS, "aria-hidden": "true", tabIndex: -1, "data-testid": "listings-photo-link", "data-analytics": "none", "data-analytics-reason": "business action \u2014 host app wraps with its own tracked()", children: photo }, key)) : (_jsx("a", { href: props.href, className: PHOTO_LINK_CLASS, "aria-hidden": "true", tabIndex: -1, "data-testid": "listings-photo-link", "data-analytics": "none", "data-analytics-reason": "business action \u2014 host app wraps with its own tracked()", children: photo }, key));
|
|
128
|
+
};
|
|
129
|
+
return (_jsx(SkinCarousel, { label: t(LISTINGS_I18N_KEYS.cardPhotos), aspectRatio: LISTING_PHOTO_ASPECT, peek: many, dots: many, "data-testid": props.testId, children: images.length === 0
|
|
130
|
+
? slide(_jsx(ListingPhoto, { imageRef: undefined, alt: title }), "empty")
|
|
131
|
+
: images.map((reference, index) => slide(_jsx(ListingPhoto, { imageRef: reference, alt: many
|
|
132
|
+
? t(LISTINGS_I18N_KEYS.detailPhotoAlt, {
|
|
133
|
+
index: index + 1,
|
|
134
|
+
total: images.length,
|
|
135
|
+
})
|
|
136
|
+
: title }, reference), reference)) }));
|
|
90
137
|
}
|
|
91
138
|
//# sourceMappingURL=ListingPhoto.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListingPhoto.js","sourceRoot":"","sources":["../../src/default/ListingPhoto.tsx"],"names":[],"mappings":";AAwBA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"ListingPhoto.js","sourceRoot":"","sources":["../../src/default/ListingPhoto.tsx"],"names":[],"mappings":"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"}
|
package/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# @stapel/listings-react 0.
|
|
1
|
+
# @stapel/listings-react 0.21.0
|
|
2
2
|
|
|
3
|
-
Headless React flow pair for stapel-listings (contract >=0.
|
|
3
|
+
Headless React flow pair for stapel-listings (contract >=0.19 <0.20) — business + state, zero visual opinion.
|
|
4
4
|
Built on @stapel/core: typed client + StapelApiError envelope, auth token refresh,
|
|
5
5
|
verification-403 interception, i18n engine, analytics facade, TanStack Query layer.
|
|
6
6
|
|
package/manifest.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
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.
|
|
4
|
+
"version": "0.21.0",
|
|
5
5
|
"backend": {
|
|
6
6
|
"module": "stapel-listings",
|
|
7
|
-
"contract": ">=0.
|
|
7
|
+
"contract": ">=0.19 <0.20"
|
|
8
8
|
},
|
|
9
9
|
"layers": [
|
|
10
10
|
"api",
|
package/nav-manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stapel/listings-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.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": {
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"typescript": "^5.8.3",
|
|
104
104
|
"vitest": "^3.2.4",
|
|
105
105
|
"@stapel/attributes-react": "^0.14.1",
|
|
106
|
-
"@stapel/core": "^0.
|
|
106
|
+
"@stapel/core": "^0.24.0",
|
|
107
107
|
"@stapel/currencies-react": "^0.3.0",
|
|
108
108
|
"@stapel/image": "^0.4.2",
|
|
109
109
|
"@stapel/showcase": "^0.3.0",
|
|
@@ -123,7 +123,7 @@ import { LISTINGS_I18N_KEYS } from "../i18n/keys.js";
|
|
|
123
123
|
import { GateReasonPopover } from "./GateReasonPopover.js";
|
|
124
124
|
import { HeartIcon } from "./icons.js";
|
|
125
125
|
import { SignInLink } from "./SignInLink.js";
|
|
126
|
-
import { ListingPhotoStrip } from "./ListingPhoto.js";
|
|
126
|
+
import { PHOTO_LINK_CLASS, ListingPhotoStrip } from "./ListingPhoto.js";
|
|
127
127
|
import { ListingPrice } from "./ListingPrice.js";
|
|
128
128
|
import type { CategoryFeaturesProp, ThemeModeProp } from "./types.js";
|
|
129
129
|
|
|
@@ -230,6 +230,18 @@ export const CARD_BLEED_CLASS = "stapel-listing-card-bleed";
|
|
|
230
230
|
*/
|
|
231
231
|
export const CARD_VIEWED_CLASS = "stapel-listing-card-seen";
|
|
232
232
|
|
|
233
|
+
/**
|
|
234
|
+
* The class that makes a card LOOK like a target.
|
|
235
|
+
*
|
|
236
|
+
* Measured on a live 1440px grid before this pack: `box-shadow: none`,
|
|
237
|
+
* `transform: none`, the border unchanged and `cursor: auto` — a card that
|
|
238
|
+
* opens a listing and gives a person no reason to believe it does. antd's own
|
|
239
|
+
* `hoverable` was not used: it hard-codes `boxShadowCard` and nothing else, so
|
|
240
|
+
* it cannot state a border and cannot be told to stand still for somebody who
|
|
241
|
+
* asked their system for less motion.
|
|
242
|
+
*/
|
|
243
|
+
export const CARD_HOVER_CLASS = "stapel-listing-card-hoverable";
|
|
244
|
+
|
|
233
245
|
/**
|
|
234
246
|
* How far a seen card is dimmed.
|
|
235
247
|
*
|
|
@@ -289,6 +301,7 @@ export function cardTargetCss(): string {
|
|
|
289
301
|
const media = `.${CARD_MEDIA_CLASS}`;
|
|
290
302
|
const main = `.${CARD_MAIN_CLASS}`;
|
|
291
303
|
const bleed = `.${CARD_BLEED_CLASS}`;
|
|
304
|
+
const hover = CARD_HOVER_CLASS;
|
|
292
305
|
return [
|
|
293
306
|
`.${CARD_TARGET_CLASS}{display:block;color:inherit;text-decoration:none}`,
|
|
294
307
|
`.${CARD_TARGET_CLASS}:focus-visible{outline:2px solid var(--listing-card-focus);outline-offset:2px}`,
|
|
@@ -311,6 +324,18 @@ export function cardTargetCss(): string {
|
|
|
311
324
|
`${bleed}{padding-block:var(--listing-card-inset);` +
|
|
312
325
|
`padding-inline-start:var(--listing-card-inset)}` +
|
|
313
326
|
`}`,
|
|
327
|
+
// A linked slide. `display:block` kills the inline baseline gap under the
|
|
328
|
+
// picture, which on a grid of tiles reads as cards of unequal height; the
|
|
329
|
+
// ring is for a browser that focuses an `aria-hidden` anchor anyway.
|
|
330
|
+
`.${PHOTO_LINK_CLASS}{display:block}`,
|
|
331
|
+
`.${PHOTO_LINK_CLASS}:focus-visible{outline:2px solid var(--listing-card-focus);outline-offset:2px}`,
|
|
332
|
+
// The card says it is a target. Two properties, both from the theme's own
|
|
333
|
+
// tokens, and a transition that a person who asked for less motion does
|
|
334
|
+
// not get.
|
|
335
|
+
`.${hover}{transition:box-shadow 160ms ease,border-color 160ms ease}`,
|
|
336
|
+
`.${hover}:hover{box-shadow:var(--listing-card-hover-shadow);` +
|
|
337
|
+
`border-color:var(--listing-card-focus)}`,
|
|
338
|
+
`@media (prefers-reduced-motion:reduce){.${hover}{transition:none}}`,
|
|
314
339
|
// Already seen. The photo and everything inside the card's anchor dim
|
|
315
340
|
// together; the heart is outside the anchor and stays as it was — see
|
|
316
341
|
// CARD_VIEWED_CLASS.
|
|
@@ -577,11 +602,12 @@ export function ListingCard(props: ListingCardProps): ReactElement {
|
|
|
577
602
|
{...(status !== undefined
|
|
578
603
|
? { "data-listing-status": status.status }
|
|
579
604
|
: {})}
|
|
580
|
-
//
|
|
581
|
-
// the card
|
|
582
|
-
{
|
|
583
|
-
? {
|
|
584
|
-
|
|
605
|
+
// `viewed` only when the server actually said so: absent and `null`
|
|
606
|
+
// leave the card's dimming exactly as it renders today.
|
|
607
|
+
className={
|
|
608
|
+
viewed ? `${CARD_HOVER_CLASS} ${CARD_VIEWED_CLASS}` : CARD_HOVER_CLASS
|
|
609
|
+
}
|
|
610
|
+
{...(viewed ? { "data-listing-viewed": "true" } : {})}
|
|
585
611
|
// The body's own padding is zero because the frame fills the card and
|
|
586
612
|
// the photo runs edge to edge when it is stacked: padding here would
|
|
587
613
|
// be a strip of card around a picture. The text block inside the
|
|
@@ -591,18 +617,27 @@ export function ListingCard(props: ListingCardProps): ReactElement {
|
|
|
591
617
|
style={{
|
|
592
618
|
["--listing-card-focus" as string]: token.colorPrimary,
|
|
593
619
|
["--listing-card-inset" as string]: `${String(token.paddingSM)}px`,
|
|
620
|
+
// The theme's own elevation, so the lift is the same one every
|
|
621
|
+
// raised surface in the skin uses and it is right in both modes.
|
|
622
|
+
["--listing-card-hover-shadow" as string]: token.boxShadowSecondary,
|
|
594
623
|
}}
|
|
595
624
|
>
|
|
596
625
|
<div className={CARD_QUERY_CLASS}>
|
|
597
626
|
<div className={`${CARD_FRAME_CLASS} ${CARD_BLEED_CLASS}`}>
|
|
598
|
-
{/* The
|
|
599
|
-
|
|
600
|
-
|
|
627
|
+
{/* The STRIP is outside the anchor — a swipeable scroller is a
|
|
628
|
+
control and a link may not contain one — but each SLIDE is
|
|
629
|
+
linked, so the 267x200 photograph is part of the card's target
|
|
630
|
+
instead of the one place on it where a click does nothing.
|
|
631
|
+
See `<ListingPhotoStrip>` for where that line is drawn. */}
|
|
601
632
|
<div className={CARD_MEDIA_CLASS}>
|
|
602
633
|
<ListingPhotoStrip
|
|
603
634
|
images={listing.images ?? []}
|
|
604
635
|
title={title.length > 0 ? title : String(listing.id)}
|
|
605
636
|
testId="listings-card-photos"
|
|
637
|
+
{...(props.href !== undefined ? { href: props.href } : {})}
|
|
638
|
+
{...(props.href !== undefined && props.linkComponent !== undefined
|
|
639
|
+
? { linkComponent: props.linkComponent }
|
|
640
|
+
: {})}
|
|
606
641
|
/>
|
|
607
642
|
</div>
|
|
608
643
|
|
|
@@ -27,10 +27,22 @@ import { Typography, theme as antdTheme } from "antd";
|
|
|
27
27
|
import { Image } from "@stapel/image";
|
|
28
28
|
import { SkinCarousel } from "@stapel/tokens-antd/skin";
|
|
29
29
|
import { useT } from "@stapel/core";
|
|
30
|
+
import type { LinkComponent } from "@stapel/core";
|
|
30
31
|
import { radii, spacing } from "@stapel/tokens";
|
|
31
32
|
import { useListingsRuntime } from "../model/context.js";
|
|
32
33
|
import { LISTINGS_I18N_KEYS } from "../i18n/keys.js";
|
|
33
34
|
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The class a linked slide carries.
|
|
38
|
+
*
|
|
39
|
+
* `display:block` is the load-bearing half: an inline anchor around a block
|
|
40
|
+
* image leaves a baseline gap under the picture, which on a grid of tiles is a
|
|
41
|
+
* visible row of mismatched card heights. The rule itself lives in
|
|
42
|
+
* `cardTargetCss()`, beside the card's other one-rule-per-defect entries.
|
|
43
|
+
*/
|
|
44
|
+
export const PHOTO_LINK_CLASS = "stapel-listing-photo-link";
|
|
45
|
+
|
|
34
46
|
/** The default shape of a listing photo box everywhere in this skin. Declared
|
|
35
47
|
* once so a card, a detail hero and a dashboard thumbnail cannot drift into
|
|
36
48
|
* three different crops. */
|
|
@@ -151,6 +163,28 @@ export function ListingPhoto(props: ListingPhotoProps): ReactElement {
|
|
|
151
163
|
* SERP was measured correct on while the desktop card (a still `<img>` inside
|
|
152
164
|
* the anchor, one photo, no dots) was not.
|
|
153
165
|
*
|
|
166
|
+
* ── …and why each SLIDE may still be one, when a card asks (`href`) ────────
|
|
167
|
+
*
|
|
168
|
+
* The rule above is about the STRIP, and it was read as a rule about the
|
|
169
|
+
* picture. It is not, and the difference was measured: on a 1440px grid the
|
|
170
|
+
* photo is 267x200 — the largest, most obvious target on the card — and
|
|
171
|
+
* clicking it did nothing at all. `cursor: auto`, no hover, and the visitor
|
|
172
|
+
* stayed on the page they were already on. A person who clicks a picture of a
|
|
173
|
+
* phone is asking to see the phone; there is no reading of that click in which
|
|
174
|
+
* the right answer is silence.
|
|
175
|
+
*
|
|
176
|
+
* So a card may hand this strip its own `href`, and each slide becomes a link
|
|
177
|
+
* around its picture. What that does NOT do is make the strip a link: the
|
|
178
|
+
* scroller, its arrows and its dots stay controls, outside every anchor,
|
|
179
|
+
* because they are what the header's rule is actually protecting. And the
|
|
180
|
+
* slide links are `tabIndex={-1}` + `aria-hidden`, so a card is still ONE tab
|
|
181
|
+
* stop and one accessible name — the reading anchor's — rather than one per
|
|
182
|
+
* photograph.
|
|
183
|
+
*
|
|
184
|
+
* A surface that does not pass `href` is byte-identical to before. The phone
|
|
185
|
+
* SERP passes none: a horizontal swipe is a real gesture there, and it is the
|
|
186
|
+
* gesture the header's rule was written for.
|
|
187
|
+
*
|
|
154
188
|
* A listing with no photos still gets one slide, so a row's height does not
|
|
155
189
|
* depend on whether a seller uploaded anything, and a ONE-photo strip gets
|
|
156
190
|
* neither peek nor dots: the sliver of a next slide is an affordance for
|
|
@@ -164,10 +198,59 @@ export function ListingPhotoStrip(props: {
|
|
|
164
198
|
/** The surface's own test id, so a screen holding two kinds of card does
|
|
165
199
|
* not hand a test two elements under one name. */
|
|
166
200
|
readonly testId: string;
|
|
201
|
+
/**
|
|
202
|
+
* Where a click on the PICTURE goes — the card's own `href`, when the card
|
|
203
|
+
* wants its photograph to be part of its target. Omitted, every slide is
|
|
204
|
+
* inert exactly as it has always been.
|
|
205
|
+
*/
|
|
206
|
+
readonly href?: string;
|
|
207
|
+
/** The host's `<Link>`, so the click stays inside the SPA. */
|
|
208
|
+
readonly linkComponent?: LinkComponent;
|
|
167
209
|
}): ReactElement {
|
|
168
210
|
const t = useT();
|
|
169
211
|
const { images, title } = props;
|
|
170
212
|
const many = images.length > 1;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* One slide, linked or not.
|
|
216
|
+
*
|
|
217
|
+
* `aria-hidden` + `tabIndex={-1}`: this is a SECOND way to reach a
|
|
218
|
+
* destination the card already names, not a second destination. Without it a
|
|
219
|
+
* grid of twenty-four cards grows twenty-four extra tab stops, each
|
|
220
|
+
* announcing the same listing the card announced a moment ago.
|
|
221
|
+
*/
|
|
222
|
+
const slide = (photo: ReactElement, key: string): ReactElement => {
|
|
223
|
+
if (props.href === undefined) return photo;
|
|
224
|
+
const Link = props.linkComponent;
|
|
225
|
+
return Link !== undefined ? (
|
|
226
|
+
<Link
|
|
227
|
+
key={key}
|
|
228
|
+
href={props.href}
|
|
229
|
+
className={PHOTO_LINK_CLASS}
|
|
230
|
+
aria-hidden="true"
|
|
231
|
+
tabIndex={-1}
|
|
232
|
+
data-testid="listings-photo-link"
|
|
233
|
+
data-analytics="none"
|
|
234
|
+
data-analytics-reason="business action — host app wraps with its own tracked()"
|
|
235
|
+
>
|
|
236
|
+
{photo}
|
|
237
|
+
</Link>
|
|
238
|
+
) : (
|
|
239
|
+
<a
|
|
240
|
+
key={key}
|
|
241
|
+
href={props.href}
|
|
242
|
+
className={PHOTO_LINK_CLASS}
|
|
243
|
+
aria-hidden="true"
|
|
244
|
+
tabIndex={-1}
|
|
245
|
+
data-testid="listings-photo-link"
|
|
246
|
+
data-analytics="none"
|
|
247
|
+
data-analytics-reason="business action — host app wraps with its own tracked()"
|
|
248
|
+
>
|
|
249
|
+
{photo}
|
|
250
|
+
</a>
|
|
251
|
+
);
|
|
252
|
+
};
|
|
253
|
+
|
|
171
254
|
return (
|
|
172
255
|
<SkinCarousel
|
|
173
256
|
label={t(LISTINGS_I18N_KEYS.cardPhotos)}
|
|
@@ -176,24 +259,25 @@ export function ListingPhotoStrip(props: {
|
|
|
176
259
|
dots={many}
|
|
177
260
|
data-testid={props.testId}
|
|
178
261
|
>
|
|
179
|
-
{images.length === 0
|
|
180
|
-
<ListingPhoto imageRef={undefined} alt={title}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
262
|
+
{images.length === 0
|
|
263
|
+
? slide(<ListingPhoto imageRef={undefined} alt={title} />, "empty")
|
|
264
|
+
: images.map((reference, index) =>
|
|
265
|
+
slide(
|
|
266
|
+
<ListingPhoto
|
|
267
|
+
key={reference}
|
|
268
|
+
imageRef={reference}
|
|
269
|
+
alt={
|
|
270
|
+
many
|
|
271
|
+
? t(LISTINGS_I18N_KEYS.detailPhotoAlt, {
|
|
272
|
+
index: index + 1,
|
|
273
|
+
total: images.length,
|
|
274
|
+
})
|
|
275
|
+
: title
|
|
276
|
+
}
|
|
277
|
+
/>,
|
|
278
|
+
reference
|
|
279
|
+
)
|
|
280
|
+
)}
|
|
197
281
|
</SkinCarousel>
|
|
198
282
|
);
|
|
199
283
|
}
|