@stapel/search-react 0.12.0 → 0.13.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 +58 -0
- package/MODULE.md +7 -3
- package/dist/default/SearchResultCard.d.ts.map +1 -1
- package/dist/default/SearchResultCard.js +83 -37
- package/dist/default/SearchResultCard.js.map +1 -1
- package/dist/default/cardPhotos.d.ts +65 -0
- package/dist/default/cardPhotos.d.ts.map +1 -0
- package/dist/default/cardPhotos.js +127 -0
- package/dist/default/cardPhotos.js.map +1 -0
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/es.js +3 -0
- package/dist/i18n/es.js.map +1 -1
- package/dist/i18n/keys.d.ts +10 -0
- package/dist/i18n/keys.d.ts.map +1 -1
- package/dist/i18n/keys.js +13 -0
- package/dist/i18n/keys.js.map +1 -1
- package/dist/i18n/ru.d.ts.map +1 -1
- package/dist/i18n/ru.js +3 -0
- package/dist/i18n/ru.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/model/runtime.d.ts +40 -3
- package/dist/model/runtime.d.ts.map +1 -1
- package/dist/model/runtime.js +2 -1
- package/dist/model/runtime.js.map +1 -1
- package/llms.txt +2 -2
- package/manifest.json +12 -3
- package/nav-manifest.json +1 -1
- package/package.json +3 -3
- package/src/analytics/generated/events.json +1 -1
- package/src/default/SearchResultCard.tsx +157 -71
- package/src/default/cardPhotos.ts +195 -0
- package/src/i18n/es.ts +3 -0
- package/src/i18n/keys.ts +13 -0
- package/src/i18n/ru.ts +3 -0
- package/src/index.ts +1 -0
- package/src/model/runtime.ts +43 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
# @stapel/search-react
|
|
2
2
|
|
|
3
|
+
## 0.13.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- e76ab28: The default SERP card draws the photos — the whole gallery, not one, and not none.
|
|
8
|
+
|
|
9
|
+
`<SearchResultCard>` read `card.image` as an object with a `url` key and fell
|
|
10
|
+
back to `card.image_url`. Neither is a shape this fleet emits, so **every
|
|
11
|
+
consumer that did not pass its own `renderCard` got a card with no photo at
|
|
12
|
+
all**:
|
|
13
|
+
|
|
14
|
+
- `image_url` is a convention nothing in the fleet writes. It was declared in
|
|
15
|
+
`GENERIC_CARD_FIELDS`, drawn in the demos from a data URI, and never once
|
|
16
|
+
served by a backend.
|
|
17
|
+
- `card.image` IS emitted — `stapel-classified`'s search projection stores it —
|
|
18
|
+
and it is a plain `<type>/<hash>` CDN reference **string**, not an object.
|
|
19
|
+
- the one rich shape that exists (chat's subject card, which serves the same
|
|
20
|
+
CDN render descriptor its attachments carry) has `ref` + `variants[]` and no
|
|
21
|
+
top-level `url`, so the `"url" in rich` guard rejected it too.
|
|
22
|
+
|
|
23
|
+
**What the card reads now** (`default/cardPhotos.ts`, unit-tested as data):
|
|
24
|
+
`images[]` first — the whole seller-ordered gallery `stapel-classified` 0.7.0
|
|
25
|
+
projects, capped by its `CARD_IMAGES_LIMIT` — with the singular `image` as the
|
|
26
|
+
fallback for a doc type that never grew a list. Never both: `image` IS
|
|
27
|
+
`images[0]`, so reading the singular after the list would draw the first photo
|
|
28
|
+
twice. Each entry may be a CDN reference, a URL the doc type stored itself (a
|
|
29
|
+
reference is `<type>/<hash>`: no scheme, no leading slash, so the two are told
|
|
30
|
+
apart by shape and never by a guess), or a render descriptor, whose whole
|
|
31
|
+
variant ladder survives so `<Image>` still has tiers to choose between.
|
|
32
|
+
|
|
33
|
+
**How a reference becomes a picture: a new `resolveImage` seam** on
|
|
34
|
+
`createSearchRuntime`, the same seam `@stapel/listings-react` states and the
|
|
35
|
+
same function a container passes to both. No contract in this fleet resolves a
|
|
36
|
+
stranger's reference — stapel-cdn's `file/exists/` is owner-scoped — so the
|
|
37
|
+
deployment hands its own knowledge in once rather than having a library invent
|
|
38
|
+
a URL convention nobody agreed to.
|
|
39
|
+
|
|
40
|
+
**A gallery is a strip.** Two or more photos render as a `<SkinCarousel>` with
|
|
41
|
+
the peek and the position indicator (one photo gets neither: a sliver of a next
|
|
42
|
+
slide is an affordance for something that is not there). The strip is a
|
|
43
|
+
**sibling** of the card's anchor, never a child — a horizontal swipe that ends
|
|
44
|
+
inside an `<a>` can be delivered as a click, which is the defect that makes
|
|
45
|
+
phone galleries unusable.
|
|
46
|
+
|
|
47
|
+
**Three honest answers about a photo, drawn as three different things.** A card
|
|
48
|
+
with no photo field reserves nothing (a text corpus is not a gallery with holes
|
|
49
|
+
in it); a card whose references nothing resolved draws the well and _says_ the
|
|
50
|
+
photo is unavailable — that is what an unwired `resolveImage` looks like, and a
|
|
51
|
+
sentence gets it fixed where an empty grey box does not; anything else is the
|
|
52
|
+
strip.
|
|
53
|
+
|
|
54
|
+
BREAKING for a host that stored `card.image_url`: that field is no longer read
|
|
55
|
+
(nothing in the fleet wrote it). Store the URL in `image`/`images` instead — a
|
|
56
|
+
stored URL still needs no resolver.
|
|
57
|
+
|
|
58
|
+
New i18n keys in all three bundles: `search.results.photos`,
|
|
59
|
+
`search.results.photo_alt`, `search.results.photo_unavailable`.
|
|
60
|
+
|
|
3
61
|
## 0.12.0
|
|
4
62
|
|
|
5
63
|
### Minor Changes
|
package/MODULE.md
CHANGED
|
@@ -112,9 +112,13 @@ are props, not dependencies (spec §6.2 items 1–2):
|
|
|
112
112
|
|
|
113
113
|
- **`renderCard`** — `<ListingCard>` from `@stapel/listings-react/default`. The
|
|
114
114
|
generic card here is a working default over a documented set of conventional
|
|
115
|
-
`card` fields (`title`, `price`, `currency`, `location`, `
|
|
116
|
-
`SearchItem.card` is deliberately free-form: "stored row
|
|
117
|
-
page costs one query".
|
|
115
|
+
`card` fields (`title`, `price`, `currency`, `location`, `images`, `image`,
|
|
116
|
+
`url`), because `SearchItem.card` is deliberately free-form: "stored row
|
|
117
|
+
fields, so a result page costs one query". `images` is the whole gallery in
|
|
118
|
+
seller order (stapel-classified 0.7.0) and `image` is `images[0]`; both hold
|
|
119
|
+
opaque `<type>/<hash>` CDN references, so the card draws them through the
|
|
120
|
+
runtime's `resolveImage` seam — the same seam `@stapel/listings-react`
|
|
121
|
+
states, and the same function a container passes to both.
|
|
118
122
|
- **`categoryFeatures`** — the category's feature schema, from
|
|
119
123
|
`categories-react`. The server sends `{value: count}` and no labels; the
|
|
120
124
|
captions are translation keys in that schema.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchResultCard.d.ts","sourceRoot":"","sources":["../../src/default/SearchResultCard.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SearchResultCard.d.ts","sourceRoot":"","sources":["../../src/default/SearchResultCard.tsx"],"names":[],"mappings":"AAiDA,OAAO,KAAK,EAAiB,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKpE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAMlD,oCAAoC;AACpC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;CAC3B;AAED,wDAAwD;AACxD,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,UAAU,KAAK,SAAS,CAAC;AAQjE;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAWhD,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,GAAG,SAAS,CAoBpB;AA0KD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,YAAY,CAmFrE"}
|
|
@@ -19,11 +19,14 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
19
19
|
*
|
|
20
20
|
* ── Two things this card used to get wrong ────────────────────────────────
|
|
21
21
|
*
|
|
22
|
-
* 1. **It
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
22
|
+
* 1. **It read a photo shape nothing in this fleet emits.** `card.image` was
|
|
23
|
+
* read as an object with a `url` key and `card.image_url` as the fallback;
|
|
24
|
+
* what the fleet actually stores is a `<type>/<hash>` CDN reference, and
|
|
25
|
+
* where it does store an object that object carries `ref` + `variants[]`
|
|
26
|
+
* and no top-level `url`. So every consumer that did not pass its own
|
|
27
|
+
* `renderCard` got a card with no photo at all. `cardPhotos.ts` reads the
|
|
28
|
+
* real shapes, through the runtime's `resolveImage` seam, and the whole
|
|
29
|
+
* `images[]` gallery rather than one photo.
|
|
27
30
|
* 2. **The marking's EXPLANATION was in a `Tooltip`.** Touch has no hover, so
|
|
28
31
|
* on the device most of this traffic arrives from, the sentence the law is
|
|
29
32
|
* actually about was unreachable — the tag said "Promoted" and nothing on
|
|
@@ -47,8 +50,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
47
50
|
import { useMemo } from "react";
|
|
48
51
|
import { Card, Flex, Typography } from "antd";
|
|
49
52
|
import { Image } from "@stapel/image";
|
|
53
|
+
import { SkinCarousel } from "@stapel/tokens-antd/skin";
|
|
50
54
|
import { useFormat, useT } from "@stapel/core";
|
|
51
55
|
import { cssVar, fontSize, fontWeight, radii, spacing } from "@stapel/tokens";
|
|
56
|
+
import { useSearchRuntime } from "../model/context.js";
|
|
57
|
+
import { readCardPhotos } from "./cardPhotos.js";
|
|
52
58
|
import { SEARCH_I18N_KEYS } from "../i18n/keys.js";
|
|
53
59
|
function text(value) {
|
|
54
60
|
if (typeof value === "string" && value.length > 0)
|
|
@@ -67,7 +73,11 @@ export const GENERIC_CARD_FIELDS = [
|
|
|
67
73
|
"price",
|
|
68
74
|
"currency",
|
|
69
75
|
"location",
|
|
70
|
-
|
|
76
|
+
// The gallery, and the singular first photo the projection keeps beside it
|
|
77
|
+
// (`images[0]`). Both hold CDN references; see `cardPhotos.ts`. The old
|
|
78
|
+
// `image_url` is gone — no backend in this fleet ever wrote it.
|
|
79
|
+
"images",
|
|
80
|
+
"image",
|
|
71
81
|
"url",
|
|
72
82
|
];
|
|
73
83
|
/**
|
|
@@ -137,41 +147,74 @@ const PROMOTED_TAG = {
|
|
|
137
147
|
lineHeight: `${String(fontSize.md.lineHeight)}px`,
|
|
138
148
|
whiteSpace: "nowrap",
|
|
139
149
|
};
|
|
140
|
-
/**
|
|
141
|
-
|
|
150
|
+
/**
|
|
151
|
+
* The shape of one photo well, everywhere on this card. Declared once so the
|
|
152
|
+
* placeholder and the loaded photo cannot drift into two different crops, and
|
|
153
|
+
* so the well is on screen before the network answers.
|
|
154
|
+
*/
|
|
155
|
+
const CARD_PHOTO_ASPECT = "4 / 3";
|
|
156
|
+
/** The placeholder well: the box the photo would have occupied. */
|
|
157
|
+
const PHOTO_ABSENT = {
|
|
158
|
+
display: "flex",
|
|
159
|
+
flexDirection: "column",
|
|
160
|
+
alignItems: "center",
|
|
161
|
+
justifyContent: "center",
|
|
162
|
+
gap: spacing[1],
|
|
142
163
|
width: "100%",
|
|
143
|
-
aspectRatio:
|
|
164
|
+
aspectRatio: CARD_PHOTO_ASPECT,
|
|
144
165
|
overflow: "hidden",
|
|
145
166
|
borderRadius: radii.md,
|
|
146
167
|
background: cssVar("surface-sunken"),
|
|
168
|
+
color: cssVar("text-muted"),
|
|
147
169
|
};
|
|
170
|
+
/** The slide's own fill — the strip's well owns the shape. */
|
|
171
|
+
const PHOTO_FILL = { width: "100%", height: "100%" };
|
|
172
|
+
/** A camera outline in `currentColor` — no icon dependency, and it inherits
|
|
173
|
+
* the theme rather than carrying a colour. `aria-hidden` because the sentence
|
|
174
|
+
* beside it is the label. */
|
|
175
|
+
function CameraGlyph() {
|
|
176
|
+
return (_jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("path", { d: "M3 8.5A2.5 2.5 0 0 1 5.5 6h1.7l1.2-2h6.2l1.2 2h1.7A2.5 2.5 0 0 1 20 8.5v8A2.5 2.5 0 0 1 17.5 19h-11A2.5 2.5 0 0 1 4 16.5z" }), _jsx("circle", { cx: "12", cy: "12.5", r: "3.2" })] }));
|
|
177
|
+
}
|
|
148
178
|
/**
|
|
149
|
-
*
|
|
179
|
+
* The card's photos — the whole gallery, as a swipeable strip.
|
|
180
|
+
*
|
|
181
|
+
* ── Why the strip is OUTSIDE the card's anchor ────────────────────────────
|
|
150
182
|
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
183
|
+
* `<SkinCarousel>` is a scroll container with its own tab stop, and a
|
|
184
|
+
* horizontal swipe that ends inside an `<a>` is a swipe the browser may
|
|
185
|
+
* deliver as a click. Inside the anchor, every attempt to look at photo two
|
|
186
|
+
* would navigate to the result — the defect that makes phone galleries
|
|
187
|
+
* unusable. So it sits above the anchor as a sibling, exactly as
|
|
188
|
+
* `<ListingSerpCard>` does it, and the anchor still covers everything a
|
|
189
|
+
* person reads.
|
|
190
|
+
*
|
|
191
|
+
* Three states, and they are three different facts. No photo FIELD at all —
|
|
192
|
+
* a doc type that indexes text — draws nothing, because reserving a 4:3 well
|
|
193
|
+
* for a corpus that has no photos is a hole in every row. A field with
|
|
194
|
+
* nothing behind it draws the well and says the photo is unavailable: that is
|
|
195
|
+
* usually an unwired `resolveImage`, and a sentence gets it fixed where an
|
|
196
|
+
* empty grey box does not. Anything else is the strip.
|
|
155
197
|
*/
|
|
156
|
-
function
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
198
|
+
function CardPhotoStrip(props) {
|
|
199
|
+
const t = useT();
|
|
200
|
+
const { photos, title } = props;
|
|
201
|
+
if (photos.stored === 0)
|
|
202
|
+
return null;
|
|
203
|
+
if (photos.images.length === 0) {
|
|
204
|
+
const caption = t(SEARCH_I18N_KEYS.resultsPhotoUnavailable);
|
|
205
|
+
return (_jsxs("div", { role: "img", "aria-label": caption, "data-testid": "search-result-photo-absent", style: PHOTO_ABSENT, children: [_jsx(CameraGlyph, {}), _jsx(Typography.Text, { type: "secondary", style: { fontSize: fontSize.xs.fontSize }, children: caption })] }));
|
|
160
206
|
}
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
preview_b64: null,
|
|
173
|
-
variants: [],
|
|
174
|
-
};
|
|
207
|
+
const total = photos.images.length;
|
|
208
|
+
// A one-photo strip gets neither a peek nor dots: the sliver of a next
|
|
209
|
+
// slide is an affordance for something that is there.
|
|
210
|
+
const many = total > 1;
|
|
211
|
+
return (_jsx(SkinCarousel, { label: t(SEARCH_I18N_KEYS.resultsPhotos), aspectRatio: CARD_PHOTO_ASPECT, peek: many, dots: many, "data-testid": "search-result-photos", children: photos.images.map((image, index) => (_jsx(Image, { meta: image, alt: many
|
|
212
|
+
? t(SEARCH_I18N_KEYS.resultsPhotoAlt, {
|
|
213
|
+
index: index + 1,
|
|
214
|
+
total,
|
|
215
|
+
title,
|
|
216
|
+
})
|
|
217
|
+
: t(SEARCH_I18N_KEYS.resultsImageAlt, { title }), fit: "cover", "data-testid": "search-result-photo", style: PHOTO_FILL }, `${String(index)}:${image.url}`))) }));
|
|
175
218
|
}
|
|
176
219
|
/**
|
|
177
220
|
* The whole card as ONE tap target.
|
|
@@ -193,6 +236,7 @@ export function SearchResultCard(props) {
|
|
|
193
236
|
const t = useT();
|
|
194
237
|
const format = useFormat();
|
|
195
238
|
const card = props.item.card;
|
|
239
|
+
const resolve = useSearchRuntime().resolveImage;
|
|
196
240
|
const title = text(card["title"]) ?? t(SEARCH_I18N_KEYS.resultsUntitled);
|
|
197
241
|
const price = formatCardPrice(format, text(card["price"]), text(card["currency"]));
|
|
198
242
|
const href = text(card["url"]);
|
|
@@ -202,10 +246,12 @@ export function SearchResultCard(props) {
|
|
|
202
246
|
km: props.item.distance_km.toFixed(1),
|
|
203
247
|
})
|
|
204
248
|
: undefined;
|
|
205
|
-
// Memoised on the
|
|
206
|
-
//
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
249
|
+
// Memoised on the card and the resolver: a host resolver is a plain
|
|
250
|
+
// function returning a fresh object, so resolving inline hands `<Image>` a
|
|
251
|
+
// new `meta` identity on every render — a load it then has to decide is or
|
|
252
|
+
// is not the same one.
|
|
253
|
+
const photos = useMemo(() => readCardPhotos(card, resolve), [card, resolve]);
|
|
254
|
+
const body = (_jsxs(Flex, { vertical: true, gap: spacing[1], children: [_jsx(Typography.Text, { strong: true, children: title }), price !== undefined && (_jsx(Typography.Text, { strong: true, style: { fontSize: fontSize.lg.fontSize }, "data-testid": "search-result-price", children: price })), (location !== undefined || distance !== undefined) && (_jsx(Typography.Text, { type: "secondary", children: [location, distance].filter((v) => v !== undefined).join(" · ") }))] }));
|
|
255
|
+
return (_jsx(Card, { size: "small", "data-testid": "search-result-card", "data-promoted": props.item.promoted ? "true" : "false", ...(href !== undefined ? { hoverable: true } : {}), styles: { body: { padding: spacing[3] } }, children: _jsxs(Flex, { vertical: true, gap: spacing[2], children: [_jsx(CardPhotoStrip, { photos: photos, title: title }), href === undefined ? (body) : (_jsx("a", { href: href, style: CARD_LINK, "data-testid": "search-result-link", children: body })), props.item.promoted && (_jsxs(Flex, { vertical: true, gap: spacing[1], "data-testid": "search-result-promotion", children: [_jsx("span", { style: PROMOTED_TAG, "data-testid": "search-result-promoted", children: t(SEARCH_I18N_KEYS.resultsPromoted) }), _jsx(Typography.Text, { type: "secondary", style: { fontSize: fontSize.xs.fontSize }, "data-testid": "search-result-promoted-hint", children: t(SEARCH_I18N_KEYS.resultsPromotedHint) })] }))] }) }));
|
|
210
256
|
}
|
|
211
257
|
//# sourceMappingURL=SearchResultCard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchResultCard.js","sourceRoot":"","sources":["../../src/default/SearchResultCard.tsx"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"SearchResultCard.js","sourceRoot":"","sources":["../../src/default/SearchResultCard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WHAT A SEARCH CARD ACTUALLY STORES FOR A PHOTO, and how it becomes something
|
|
3
|
+
* `@stapel/image` can draw.
|
|
4
|
+
*
|
|
5
|
+
* ── The defect this file exists to end ────────────────────────────────────
|
|
6
|
+
*
|
|
7
|
+
* The default card used to read `card.image` expecting an object with a `url`
|
|
8
|
+
* key, and fall back to `card.image_url`. Neither is what this fleet emits:
|
|
9
|
+
*
|
|
10
|
+
* - `image_url` is a convention NOTHING in the fleet writes. It was declared
|
|
11
|
+
* in `GENERIC_CARD_FIELDS`, drawn in the demos from a data URI, and never
|
|
12
|
+
* once served by a backend.
|
|
13
|
+
* - `card.image` IS emitted — by `stapel-classified`'s search projection —
|
|
14
|
+
* and it is a plain `<type>/<hash>` STRING, not an object.
|
|
15
|
+
* - where a card DOES carry an object (chat's subject card, which serves the
|
|
16
|
+
* same CDN render descriptor its attachments carry), that object has `ref`
|
|
17
|
+
* and `variants[]` and NO top-level `url` — so the `"url" in rich` guard
|
|
18
|
+
* rejected the one rich shape the fleet has.
|
|
19
|
+
*
|
|
20
|
+
* The net effect was a card with no photo on every consumer that did not pass
|
|
21
|
+
* its own `renderCard`. Read the two real shapes instead, and read `images[]`
|
|
22
|
+
* first: since stapel-classified 0.7.0 the projection carries the whole
|
|
23
|
+
* gallery in seller order, deduplicated and capped by `CARD_IMAGES_LIMIT`,
|
|
24
|
+
* with the singular `image` kept as `images[0]`.
|
|
25
|
+
*
|
|
26
|
+
* ── Three shapes, one output ──────────────────────────────────────────────
|
|
27
|
+
*
|
|
28
|
+
* 1. A CDN reference (`"image/9f2c…"`) — resolved through the runtime's
|
|
29
|
+
* {@link SearchImageResolver}, the same seam `@stapel/listings-react`
|
|
30
|
+
* states, for the same reason: no contract in this fleet resolves a
|
|
31
|
+
* stranger's reference, so the deployment hands its own knowledge in once.
|
|
32
|
+
* 2. A URL a doc type stored directly (`"https://…"`, `"/media/…"`,
|
|
33
|
+
* `"data:image/…"`) — no ladder to shop, so it degrades to `source:
|
|
34
|
+
* "link"`. A CDN reference is `<type>/<hash>`: no scheme and no leading
|
|
35
|
+
* slash, so the two are told apart by shape and never by a guess.
|
|
36
|
+
* 3. A render descriptor object — `variants[]` with a `tier` each, an inline
|
|
37
|
+
* `preview_b64`, geometry. Read defensively (the field is `unknown` by
|
|
38
|
+
* contract) exactly as `@stapel/chat-react` reads the same descriptor.
|
|
39
|
+
*/
|
|
40
|
+
import type { StapelImage } from "@stapel/image";
|
|
41
|
+
import type { SearchImageResolver } from "../model/runtime.js";
|
|
42
|
+
/** A card's photo fields, and how many of them the card carried at all. */
|
|
43
|
+
export interface CardPhotos {
|
|
44
|
+
/**
|
|
45
|
+
* How many photo entries the card STORES — before resolving. `0` means the
|
|
46
|
+
* doc type has no photo for this row (or no photo field at all), which is a
|
|
47
|
+
* different thing from "a photo nothing could resolve", and the card draws
|
|
48
|
+
* the two differently.
|
|
49
|
+
*/
|
|
50
|
+
readonly stored: number;
|
|
51
|
+
/** The ones that became something drawable, in the stored order. */
|
|
52
|
+
readonly images: readonly StapelImage[];
|
|
53
|
+
}
|
|
54
|
+
/** One stored entry, in whichever of the three shapes it arrived. */
|
|
55
|
+
export declare function cardImage(value: unknown, resolve: SearchImageResolver | undefined): StapelImage | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* The card's gallery: `images[]` when the doc type carries one, the singular
|
|
58
|
+
* `image` otherwise.
|
|
59
|
+
*
|
|
60
|
+
* Never both — `stapel-classified` stores `image` as `images[0]`, so reading
|
|
61
|
+
* the singular after the list would draw the first photo twice. The singular
|
|
62
|
+
* stays the fallback for a doc type that never grew a list.
|
|
63
|
+
*/
|
|
64
|
+
export declare function readCardPhotos(card: Readonly<Record<string, unknown>>, resolve: SearchImageResolver | undefined): CardPhotos;
|
|
65
|
+
//# sourceMappingURL=cardPhotos.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cardPhotos.d.ts","sourceRoot":"","sources":["../../src/default/cardPhotos.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,2EAA2E;AAC3E,MAAM,WAAW,UAAU;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,oEAAoE;IACpE,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;CACzC;AA0GD,qEAAqE;AACrE,wBAAgB,SAAS,CACvB,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,mBAAmB,GAAG,SAAS,GACvC,WAAW,GAAG,SAAS,CAOzB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACvC,OAAO,EAAE,mBAAmB,GAAG,SAAS,GACvC,UAAU,CAWZ"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
function isRecord(value) {
|
|
2
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3
|
+
}
|
|
4
|
+
function str(value) {
|
|
5
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
6
|
+
}
|
|
7
|
+
function num(value) {
|
|
8
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A stored string that is already a URL rather than a CDN reference.
|
|
12
|
+
*
|
|
13
|
+
* stapel-cdn's unit is `<type>/<hash>` — a relative pair with no scheme and no
|
|
14
|
+
* leading slash — so anything carrying a scheme, a protocol-relative prefix or
|
|
15
|
+
* a leading `/` is a URL the doc type stored itself.
|
|
16
|
+
*/
|
|
17
|
+
function isUrl(value) {
|
|
18
|
+
return (value.startsWith("/") ||
|
|
19
|
+
value.startsWith("data:") ||
|
|
20
|
+
/^[a-z][a-z0-9+.-]*:/i.test(value));
|
|
21
|
+
}
|
|
22
|
+
/** A bare URL as the descriptor `<Image>` consumes: one rung, no ladder. */
|
|
23
|
+
function linkImage(url) {
|
|
24
|
+
return {
|
|
25
|
+
source: "link",
|
|
26
|
+
url,
|
|
27
|
+
mime: null,
|
|
28
|
+
width: null,
|
|
29
|
+
height: null,
|
|
30
|
+
aspect: null,
|
|
31
|
+
square: false,
|
|
32
|
+
preview_b64: null,
|
|
33
|
+
variants: [],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* One rung of a render descriptor's ladder, in `@stapel/image`'s spelling.
|
|
38
|
+
*
|
|
39
|
+
* `tier` arrives in two spellings inside the SAME array — an int for the
|
|
40
|
+
* ladder rungs and the string sentinel `"original"` for the entry the snapshot
|
|
41
|
+
* builder appends. `String()` is right for both, which is why there is no
|
|
42
|
+
* branch here (`@stapel/cdn-react`'s `model/refs.ts` argues it at length).
|
|
43
|
+
*/
|
|
44
|
+
function rung(value) {
|
|
45
|
+
if (!isRecord(value))
|
|
46
|
+
return undefined;
|
|
47
|
+
const url = str(value["url"]);
|
|
48
|
+
if (url === undefined)
|
|
49
|
+
return undefined;
|
|
50
|
+
const tier = value["tier"];
|
|
51
|
+
const branch = value["branch"];
|
|
52
|
+
return {
|
|
53
|
+
tier: typeof tier === "number" || typeof tier === "string" ? String(tier) : "",
|
|
54
|
+
branch: branch === "w" || branch === "h" ? branch : null,
|
|
55
|
+
url,
|
|
56
|
+
width: num(value["width"]),
|
|
57
|
+
height: num(value["height"]),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A CDN render descriptor → the descriptor `<Image>` consumes.
|
|
62
|
+
*
|
|
63
|
+
* The display URL is the descriptor's own `url` when it has one, else the
|
|
64
|
+
* `original` rung, else the largest rung — a snapshot carries no
|
|
65
|
+
* `original_url`, so the top of the ladder IS the original. With no rung at
|
|
66
|
+
* all the inline `preview_b64` is used: a real, honestly blurry image beats
|
|
67
|
+
* nothing. A descriptor with neither is not drawable and says so.
|
|
68
|
+
*/
|
|
69
|
+
function metaImage(meta) {
|
|
70
|
+
const raw = meta["variants"];
|
|
71
|
+
const variants = (Array.isArray(raw) ? raw : [])
|
|
72
|
+
.map(rung)
|
|
73
|
+
.filter((v) => v !== undefined);
|
|
74
|
+
const original = variants.find((v) => v.tier === "original");
|
|
75
|
+
const largest = variants.reduce((best, v) => {
|
|
76
|
+
const size = Number(v.tier);
|
|
77
|
+
if (!Number.isFinite(size))
|
|
78
|
+
return best;
|
|
79
|
+
return best === undefined || size > Number(best.tier) ? v : best;
|
|
80
|
+
}, undefined);
|
|
81
|
+
const preview = str(meta["preview_b64"]);
|
|
82
|
+
const url = str(meta["url"]) ?? original?.url ?? largest?.url ?? preview;
|
|
83
|
+
if (url === undefined)
|
|
84
|
+
return undefined;
|
|
85
|
+
return {
|
|
86
|
+
source: "cdn",
|
|
87
|
+
url,
|
|
88
|
+
mime: str(meta["mime"]) ?? null,
|
|
89
|
+
width: num(meta["width"]),
|
|
90
|
+
height: num(meta["height"]),
|
|
91
|
+
aspect: num(meta["aspect"]),
|
|
92
|
+
square: meta["square"] === true,
|
|
93
|
+
preview_b64: preview ?? null,
|
|
94
|
+
variants,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/** One stored entry, in whichever of the three shapes it arrived. */
|
|
98
|
+
export function cardImage(value, resolve) {
|
|
99
|
+
const ref = str(value);
|
|
100
|
+
if (ref !== undefined) {
|
|
101
|
+
return isUrl(ref) ? linkImage(ref) : resolve?.(ref);
|
|
102
|
+
}
|
|
103
|
+
if (isRecord(value))
|
|
104
|
+
return metaImage(value);
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* The card's gallery: `images[]` when the doc type carries one, the singular
|
|
109
|
+
* `image` otherwise.
|
|
110
|
+
*
|
|
111
|
+
* Never both — `stapel-classified` stores `image` as `images[0]`, so reading
|
|
112
|
+
* the singular after the list would draw the first photo twice. The singular
|
|
113
|
+
* stays the fallback for a doc type that never grew a list.
|
|
114
|
+
*/
|
|
115
|
+
export function readCardPhotos(card, resolve) {
|
|
116
|
+
const list = card["images"];
|
|
117
|
+
const stored = Array.isArray(list)
|
|
118
|
+
? list
|
|
119
|
+
: card["image"] === undefined || card["image"] === null
|
|
120
|
+
? []
|
|
121
|
+
: [card["image"]];
|
|
122
|
+
const images = stored
|
|
123
|
+
.map((entry) => cardImage(entry, resolve))
|
|
124
|
+
.filter((image) => image !== undefined);
|
|
125
|
+
return { stored: stored.length, images };
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=cardPhotos.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cardPhotos.js","sourceRoot":"","sources":["../../src/default/cardPhotos.ts"],"names":[],"mappings":"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"}
|
package/dist/i18n/es.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"es.d.ts","sourceRoot":"","sources":["../../src/i18n/es.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"es.d.ts","sourceRoot":"","sources":["../../src/i18n/es.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,cAuJhC,CAAC;AAEF,+DAA+D;AAC/D,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAE7D"}
|
package/dist/i18n/es.js
CHANGED
|
@@ -33,6 +33,9 @@ export const searchI18nBundleEs = {
|
|
|
33
33
|
"search.results.untitled": "Sin título",
|
|
34
34
|
"search.results.open": "Abrir",
|
|
35
35
|
"search.results.image_alt": "Foto de {title}",
|
|
36
|
+
"search.results.photo_alt": "Foto {index} de {total}: {title}",
|
|
37
|
+
"search.results.photos": "Fotos",
|
|
38
|
+
"search.results.photo_unavailable": "Foto no disponible",
|
|
36
39
|
"search.box.label": "Buscar",
|
|
37
40
|
"search.box.placeholder": "¿Qué estás buscando?",
|
|
38
41
|
"search.box.submit": "Buscar",
|
package/dist/i18n/es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"es.js","sourceRoot":"","sources":["../../src/i18n/es.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAmB;IAChD,GAAG,mBAAmB;IAEtB,sBAAsB,EAAE,4BAA4B;IAEpD,sBAAsB,EAAE,YAAY;IACpC,wBAAwB,EAAE,WAAW;IACrC,4BAA4B,EAAE,oCAAoC;IAClE,sBAAsB,EAAE,6CAA6C;IACrE,sBAAsB,EAAE,YAAY;IACpC,sCAAsC,EAAE,mCAAmC;IAC3E,wCAAwC,EAAE,yBAAyB;IACnE,mCAAmC,EAAE,oBAAoB;IACzD,qCAAqC,EAAE,qBAAqB;IAC5D,gCAAgC,EAAE,mBAAmB;IACrD,kCAAkC,EAAE,oBAAoB;IACxD,wBAAwB,EAAE,SAAS;IACnC,qBAAqB,EAAE,kBAAkB;IACzC,qBAAqB,EAAE,iBAAiB;IACxC,+BAA+B,EAAE,0BAA0B;IAC3D,iCAAiC,EAAE,2BAA2B;IAC9D,gCAAgC,EAC9B,iHAAiH;IACnH,yBAAyB,EAAE,cAAc;IACzC,8BAA8B,EAC5B,yGAAyG;IAC3G,4BAA4B,EAAE,WAAW;IACzC,yBAAyB,EAAE,YAAY;IACvC,qBAAqB,EAAE,OAAO;IAC9B,0BAA0B,EAAE,iBAAiB;
|
|
1
|
+
{"version":3,"file":"es.js","sourceRoot":"","sources":["../../src/i18n/es.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAmB;IAChD,GAAG,mBAAmB;IAEtB,sBAAsB,EAAE,4BAA4B;IAEpD,sBAAsB,EAAE,YAAY;IACpC,wBAAwB,EAAE,WAAW;IACrC,4BAA4B,EAAE,oCAAoC;IAClE,sBAAsB,EAAE,6CAA6C;IACrE,sBAAsB,EAAE,YAAY;IACpC,sCAAsC,EAAE,mCAAmC;IAC3E,wCAAwC,EAAE,yBAAyB;IACnE,mCAAmC,EAAE,oBAAoB;IACzD,qCAAqC,EAAE,qBAAqB;IAC5D,gCAAgC,EAAE,mBAAmB;IACrD,kCAAkC,EAAE,oBAAoB;IACxD,wBAAwB,EAAE,SAAS;IACnC,qBAAqB,EAAE,kBAAkB;IACzC,qBAAqB,EAAE,iBAAiB;IACxC,+BAA+B,EAAE,0BAA0B;IAC3D,iCAAiC,EAAE,2BAA2B;IAC9D,gCAAgC,EAC9B,iHAAiH;IACnH,yBAAyB,EAAE,cAAc;IACzC,8BAA8B,EAC5B,yGAAyG;IAC3G,4BAA4B,EAAE,WAAW;IACzC,yBAAyB,EAAE,YAAY;IACvC,qBAAqB,EAAE,OAAO;IAC9B,0BAA0B,EAAE,iBAAiB;IAC7C,0BAA0B,EAAE,kCAAkC;IAC9D,uBAAuB,EAAE,OAAO;IAChC,kCAAkC,EAAE,oBAAoB;IAExD,kBAAkB,EAAE,QAAQ;IAC5B,wBAAwB,EAAE,sBAAsB;IAChD,mBAAmB,EAAE,QAAQ;IAC7B,kBAAkB,EAAE,oBAAoB;IACxC,wBAAwB,EAAE,aAAa;IACvC,uBAAuB,EAAE,WAAW;IACpC,+BAA+B,EAAE,iBAAiB;IAClD,iCAAiC,EAAE,kBAAkB;IAErD,mBAAmB,EAAE,OAAO;IAC5B,uBAAuB,EAAE,gBAAgB;IACzC,oBAAoB,EAAE,eAAe;IACrC,uBAAuB,EAAE,0BAA0B;IACnD,wBAAwB,EAAE,0BAA0B;IACpD,sBAAsB,EAAE,cAAc;IACtC,0BAA0B,EAAE,qBAAqB;IAEjD,mBAAmB,EAAE,OAAO;IAC5B,kBAAkB,EAAE,OAAO;IAC3B,kBAAkB,EAAE,YAAY;IAEhC,qBAAqB,EAAE,SAAS;IAChC,uBAAuB,EAAE,mBAAmB;IAC5C,2BAA2B,EAAE,gCAAgC;IAC7D,qBAAqB,EAAE,kCAAkC;IACzD,qBAAqB,EAAE,QAAQ;IAC/B,yBAAyB,EAAE,oCAAoC;IAC/D,2BAA2B,EACzB,kFAAkF;IACpF,uBAAuB,EACrB,0DAA0D;IAC5D,2BAA2B,EAAE,YAAY;IACzC,+BAA+B,EAC7B,6EAA6E;IAC/E,oBAAoB,EAAE,QAAQ;IAC9B,0BAA0B,EAAE,OAAO;IACnC,wBAAwB,EAAE,OAAO;IACjC,2BAA2B,EAAE,SAAS;IACtC,2BAA2B,EAAE,QAAQ;IACrC,+BAA+B,EAAE,kBAAkB;IACnD,6BAA6B,EAAE,kBAAkB;IACjD,wBAAwB,EAAE,qBAAqB;IAC/C,yBAAyB,EAAE,WAAW;IACtC,6BAA6B,EAC3B,oGAAoG;IAEtG,qBAAqB,EAAE,mBAAmB;IAC1C,sBAAsB,EAAE,gBAAgB;IACxC,+BAA+B,EAAE,uBAAuB;IACxD,iCAAiC,EAAE,wBAAwB;IAC3D,wCAAwC,EAAE,wBAAwB;IAClE,0CAA0C,EAAE,yBAAyB;IACrE,wBAAwB,EAAE,oBAAoB;IAC9C,4BAA4B,EAAE,SAAS;IACvC,oBAAoB,EAAE,mBAAmB;IACzC,sBAAsB,EAAE,SAAS;IACjC,0BAA0B,EAAE,YAAY;IAExC,uBAAuB,EAAE,WAAW;IACpC,uBAAuB,EAAE,4BAA4B;IACrD,yBAAyB,EAAE,2BAA2B;IAEtD,uBAAuB,EAAE,uBAAuB;IAChD,qBAAqB,EAAE,kBAAkB;IAEzC,oBAAoB,EAAE,YAAY;IAClC,qBAAqB,EAAE,oBAAoB;IAC3C,wBAAwB,EAAE,8CAA8C;IAExE,kBAAkB,EAAE,WAAW;IAC/B,sBAAsB,EAAE,oBAAoB;IAC5C,yBAAyB,EAAE,WAAW;IACtC,kBAAkB,EAAE,oBAAoB;IACxC,uBAAuB,EAAE,0BAA0B;IACnD,gBAAgB,EAAE,0BAA0B;IAC5C,yBAAyB,EAAE,6BAA6B;IAExD,yBAAyB,EAAE,sCAAsC;IACjE,+BAA+B,EAC7B,6DAA6D;IAC/D,iCAAiC,EAC/B,gEAAgE;IAClE,iCAAiC,EAC/B,oEAAoE;IACtE,kCAAkC,EAChC,wEAAwE;IAE1E,uBAAuB,EAAE,oCAAoC;IAC7D,gCAAgC,EAC9B,+EAA+E;IACjF,iCAAiC,EAC/B,+EAA+E;IACjF,6BAA6B,EAAE,4CAA4C;IAC3E,oCAAoC,EAAE,2CAA2C;IACjF,iCAAiC,EAC/B,0FAA0F;IAC5F,wBAAwB,EACtB,2FAA2F;IAC7F,yBAAyB,EACvB,qFAAqF;IAEvF,sBAAsB,EAAE,kCAAkC;IAC1D,sBAAsB,EACpB,2FAA2F;IAC7F,wBAAwB,EAAE,qCAAqC;IAC/D,4BAA4B,EAAE,8CAA8C;IAC5E,sBAAsB,EAAE,oDAAoD;IAC5E,0BAA0B,EAAE,WAAW;IACvC,uBAAuB,EAAE,MAAM;IAC/B,2BAA2B,EAAE,aAAa;IAC1C,yBAAyB,EAAE,uBAAuB;IAClD,sBAAsB,EAAE,OAAO;IAC/B,qBAAqB,EAAE,kCAAkC;IAEzD,oBAAoB,EAAE,QAAQ;IAC9B,oBAAoB,EAAE,qBAAqB;IAC3C,0BAA0B,EAAE,OAAO;CACpC,CAAC;AAEF,+DAA+D;AAC/D,MAAM,UAAU,oBAAoB,CAAC,MAAkB;IACrD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;AAClD,CAAC"}
|
package/dist/i18n/keys.d.ts
CHANGED
|
@@ -52,6 +52,16 @@ export declare const SEARCH_I18N_KEYS: {
|
|
|
52
52
|
readonly resultsOpen: "search.results.open";
|
|
53
53
|
/** Alt text for the card photo — the card's own title, in a sentence. */
|
|
54
54
|
readonly resultsImageAlt: "search.results.image_alt";
|
|
55
|
+
/** Alt text for one photo of a GALLERY: its place in the strip, and the
|
|
56
|
+
* card's title. A row of ten photos all called "Photo of X" is ten
|
|
57
|
+
* identical announcements. */
|
|
58
|
+
readonly resultsPhotoAlt: "search.results.photo_alt";
|
|
59
|
+
/** The photo strip's accessible name. `SkinCarousel` takes its label from
|
|
60
|
+
* the caller for exactly this reason: the token bridge owns no i18n. */
|
|
61
|
+
readonly resultsPhotos: "search.results.photos";
|
|
62
|
+
/** The card stores a reference and nothing resolved it — a sentence gets
|
|
63
|
+
* the wiring fixed; an empty grey box teaches nobody anything. */
|
|
64
|
+
readonly resultsPhotoUnavailable: "search.results.photo_unavailable";
|
|
55
65
|
readonly boxLabel: "search.box.label";
|
|
56
66
|
readonly boxPlaceholder: "search.box.placeholder";
|
|
57
67
|
readonly boxSubmit: "search.box.submit";
|
package/dist/i18n/keys.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/i18n/keys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/D;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,gBAAgB;;;;;;;IAS3B;;;;;;;OAOG;;IAEH;kEAC8D;;IAE9D,sEAAsE;;;;;;;IAOtE,yDAAyD;;;;;;;IAOzD,yEAAyE;;;;;;
|
|
1
|
+
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/i18n/keys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/D;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,gBAAgB;;;;;;;IAS3B;;;;;;;OAOG;;IAEH;kEAC8D;;IAE9D,sEAAsE;;;;;;;IAOtE,yDAAyD;;;;;;;IAOzD,yEAAyE;;IAEzE;;kCAE8B;;IAE9B;4EACwE;;IAExE;sEACkE;;;;;;IAQlE,4DAA4D;;IAE5D;;;;;OAKG;;IAEH;;;;;;;OAOG;;;;;;;;;IAaH;2CACuC;;;;;;;;;;;;IAcvC,oEAAoE;;;;;;;IAOpE;kEAC8D;;;IAG9D,4DAA4D;;IAE5D;wEACoE;;IAEpE;;;sCAGkC;;;;IAMlC,2DAA2D;;IAE3D;0BACsB;;IAEtB,uEAAuE;;;IAGvE;mEAC+D;;IAE/D;8EAC0E;;IAE1E;4EACwE;;IAExE;qDACiD;;;;;;;;;IAejD;iFAC6E;;;;;;IAQ7E;;;;;;;;OAQG;;;IAGH;;;;;;;;;;OAUG;;;;;;;;;;;;;;;;;;;;;;;;;;IAkCH;;;;;;;;;;OAUG;;IAEH;;2BAEuB;;IAEvB;;;;;;;;OAQG;;CAEK,CAAC;AAEX,MAAM,MAAM,aAAa,GACvB,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,OAAO,gBAAgB,CAAC,CAAC;AAE3D;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,aAAa,EAO3D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAsJrD,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAEzD"}
|
package/dist/i18n/keys.js
CHANGED
|
@@ -53,6 +53,16 @@ export const SEARCH_I18N_KEYS = {
|
|
|
53
53
|
resultsOpen: "search.results.open",
|
|
54
54
|
/** Alt text for the card photo — the card's own title, in a sentence. */
|
|
55
55
|
resultsImageAlt: "search.results.image_alt",
|
|
56
|
+
/** Alt text for one photo of a GALLERY: its place in the strip, and the
|
|
57
|
+
* card's title. A row of ten photos all called "Photo of X" is ten
|
|
58
|
+
* identical announcements. */
|
|
59
|
+
resultsPhotoAlt: "search.results.photo_alt",
|
|
60
|
+
/** The photo strip's accessible name. `SkinCarousel` takes its label from
|
|
61
|
+
* the caller for exactly this reason: the token bridge owns no i18n. */
|
|
62
|
+
resultsPhotos: "search.results.photos",
|
|
63
|
+
/** The card stores a reference and nothing resolved it — a sentence gets
|
|
64
|
+
* the wiring fixed; an empty grey box teaches nobody anything. */
|
|
65
|
+
resultsPhotoUnavailable: "search.results.photo_unavailable",
|
|
56
66
|
// ── the query box ────────────────────────────────────────────────────────
|
|
57
67
|
boxLabel: "search.box.label",
|
|
58
68
|
boxPlaceholder: "search.box.placeholder",
|
|
@@ -293,6 +303,9 @@ export const searchI18nBundleEn = {
|
|
|
293
303
|
"search.results.untitled": "Untitled",
|
|
294
304
|
"search.results.open": "Open",
|
|
295
305
|
"search.results.image_alt": "Photo of {title}",
|
|
306
|
+
"search.results.photo_alt": "Photo {index} of {total}: {title}",
|
|
307
|
+
"search.results.photos": "Photos",
|
|
308
|
+
"search.results.photo_unavailable": "Photo unavailable",
|
|
296
309
|
"search.box.label": "Search",
|
|
297
310
|
"search.box.placeholder": "What are you looking for?",
|
|
298
311
|
"search.box.submit": "Search",
|