@graphcommerce/image 10.1.0-canary.36 → 10.1.0-canary.39
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 +32 -0
- package/config/config.ts +41 -0
- package/index.ts +1 -0
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 10.1.0-canary.39
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#2652](https://github.com/graphcommerce-org/graphcommerce/pull/2652) [`cd21a97`](https://github.com/graphcommerce-org/graphcommerce/commit/cd21a97c705ced2d051351a2860780f9ba173d4b) - Let a Storyblok video asset show a poster.
|
|
8
|
+
|
|
9
|
+
A `<video>` paints nothing until it has buffered enough for its first frame, and nothing at all when autoplay is blocked (iOS Low Power Mode) — so an autoplaying video banner starts out black, and can stay black. `Asset` now takes a `poster` prop, rendered as `<video poster>`.
|
|
10
|
+
|
|
11
|
+
Storyblok's own `type: asset` has no room for a poster, so `assetWithPoster()` is added to read the convention of an asset value carrying an extra `poster` key:
|
|
12
|
+
|
|
13
|
+
```jsonc
|
|
14
|
+
{
|
|
15
|
+
"fieldtype": "asset",
|
|
16
|
+
"id": 1,
|
|
17
|
+
"filename": "…",
|
|
18
|
+
"poster": { "filename": "…" },
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Keeping the poster beside the asset rather than nesting both under a wrapper means a custom field type storing that shape is a drop-in for a plain asset field: existing content stays valid and `value.filename` keeps working for consumers that ignore the poster. The narrowing is unavoidable — Storyblok has no JSONSchema for custom field types, so its type generator emits `unknown` for them.
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
const { asset, poster } = assetWithPoster(blok.asset)
|
|
26
|
+
return asset && <Asset asset={asset} poster={poster} />
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`@graphcommerce/image` gains `imageUrl(src, { width, quality })`, which builds an optimized URL outside of a React tree — for the places that need a bare URL string rather than an `<Image>`, such as `<video poster>`, a CSS `background-image` or an `og:image`. It routes through the configured loader exactly like `<Image>` does, so the bytes are served and cached by your own deployment rather than fetched from the origin host by every visitor, which matters when the origin meters bandwidth. `width` is snapped up to the nearest configured size, since the optimizer rejects any width outside `imageSizes`/`deviceSizes`. ([@bramvanderholst](https://github.com/bramvanderholst))
|
|
30
|
+
|
|
31
|
+
## 10.1.0-canary.38
|
|
32
|
+
|
|
33
|
+
## 10.1.0-canary.37
|
|
34
|
+
|
|
3
35
|
## 10.1.0-canary.36
|
|
4
36
|
|
|
5
37
|
## 10.1.0-canary.35
|
package/config/config.ts
CHANGED
|
@@ -130,3 +130,44 @@ export function customLoader({ src }: ImageLoaderProps): string {
|
|
|
130
130
|
'\nRead more: https://nextjs.org/docs/messages/next-image-missing-loader',
|
|
131
131
|
)
|
|
132
132
|
}
|
|
133
|
+
|
|
134
|
+
const urlLoaders = {
|
|
135
|
+
default: defaultLoader,
|
|
136
|
+
imgix: imgixLoader,
|
|
137
|
+
cloudinary: cloudinaryLoader,
|
|
138
|
+
akamai: akamaiLoader,
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Build an optimized image URL outside of a React tree, for the places that
|
|
143
|
+
* need a bare URL string rather than an `<Image>` — `<video poster>`, a CSS
|
|
144
|
+
* `background-image`, an `og:image`.
|
|
145
|
+
*
|
|
146
|
+
* Routes through the configured loader exactly like `<Image>` does, so the
|
|
147
|
+
* bytes are served and cached by your own deployment rather than fetched from
|
|
148
|
+
* the origin host by every visitor. That matters when the origin meters
|
|
149
|
+
* bandwidth.
|
|
150
|
+
*
|
|
151
|
+
* `width` is snapped up to the nearest configured size: the optimizer rejects
|
|
152
|
+
* any width outside `imageSizes`/`deviceSizes` with a 400. Format is negotiated
|
|
153
|
+
* by the optimizer on the request's `Accept` header and can't be pinned here.
|
|
154
|
+
*
|
|
155
|
+
* Returns `src` untouched under a `custom` loader, which exists only as a
|
|
156
|
+
* per-`<Image>` prop and so can't be resolved from here.
|
|
157
|
+
*/
|
|
158
|
+
export function imageUrl(src: string, options: { width: number; quality?: number }): string {
|
|
159
|
+
const { width, quality = 75 } = options
|
|
160
|
+
if (configLoader === 'custom') return src
|
|
161
|
+
|
|
162
|
+
const config =
|
|
163
|
+
(process.env.__NEXT_IMAGE_OPTS as unknown as ImageConfigComplete) || imageConfigDefault
|
|
164
|
+
const allSizes = [...configImageSizes, ...configDeviceSizes].sort((a, b) => a - b)
|
|
165
|
+
const snapped = allSizes.find((size) => size >= width) ?? allSizes[allSizes.length - 1]
|
|
166
|
+
|
|
167
|
+
return (urlLoaders[configLoader] ?? defaultLoader)({
|
|
168
|
+
config: { ...config, allSizes },
|
|
169
|
+
src,
|
|
170
|
+
width: snapped,
|
|
171
|
+
quality,
|
|
172
|
+
})
|
|
173
|
+
}
|
package/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@graphcommerce/image",
|
|
3
3
|
"homepage": "https://www.graphcommerce.org/",
|
|
4
4
|
"repository": "github:graphcommerce-org/graphcommerce",
|
|
5
|
-
"version": "10.1.0-canary.
|
|
5
|
+
"version": "10.1.0-canary.39",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"scripts": {
|
|
8
8
|
"dev": "tsc -W"
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
|
-
"@graphcommerce/eslint-config-pwa": "^10.1.0-canary.
|
|
22
|
-
"@graphcommerce/framer-utils": "^10.1.0-canary.
|
|
23
|
-
"@graphcommerce/prettier-config-pwa": "^10.1.0-canary.
|
|
24
|
-
"@graphcommerce/typescript-config-pwa": "^10.1.0-canary.
|
|
21
|
+
"@graphcommerce/eslint-config-pwa": "^10.1.0-canary.39",
|
|
22
|
+
"@graphcommerce/framer-utils": "^10.1.0-canary.39",
|
|
23
|
+
"@graphcommerce/prettier-config-pwa": "^10.1.0-canary.39",
|
|
24
|
+
"@graphcommerce/typescript-config-pwa": "^10.1.0-canary.39",
|
|
25
25
|
"@mui/material": "^7.0.0",
|
|
26
26
|
"next": "*",
|
|
27
27
|
"react": "^19.2.0",
|