@koehler8/cms 1.0.0-beta.28 → 1.0.0-beta.29
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/package.json
CHANGED
package/src/components/Hero.vue
CHANGED
|
@@ -273,10 +273,19 @@ function getHeaderOffset() {
|
|
|
273
273
|
.promo-surface {
|
|
274
274
|
position: relative;
|
|
275
275
|
min-height: var(--promo-surface-min-height, calc(100vh + 75px));
|
|
276
|
-
background: var(
|
|
276
|
+
background-color: var(
|
|
277
277
|
--promo-surface-bg,
|
|
278
278
|
var(--hero-surface-bg, var(--theme-body-background, #060212))
|
|
279
279
|
);
|
|
280
|
+
/* Two background-image declarations form a CSS-cascade fallback chain.
|
|
281
|
+
The first sets a basic url(); the second, if the browser parses
|
|
282
|
+
image-set() (and the type() argument), overrides with format
|
|
283
|
+
negotiation. Browsers that can't parse image-set fall back to the
|
|
284
|
+
url() above. Custom properties are populated by usePromoBackgroundStyles
|
|
285
|
+
via Vue's :style object binding — see that composable for why this
|
|
286
|
+
pattern is needed instead of a single background-image string. */
|
|
287
|
+
background-image: var(--promo-bg-fallback);
|
|
288
|
+
background-image: var(--promo-bg-set, var(--promo-bg-fallback));
|
|
280
289
|
background-repeat: no-repeat;
|
|
281
290
|
background-size: cover;
|
|
282
291
|
background-position: center;
|
|
@@ -23,14 +23,34 @@ function selectLargestEntry(srcset = '') {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
* Build a
|
|
27
|
-
*
|
|
26
|
+
* Build a hero-background style binding that pairs a `url()` fallback with an
|
|
27
|
+
* `image-set()` upgrade. Returns an OBJECT with two CSS custom properties.
|
|
28
|
+
*
|
|
29
|
+
* Why an object with custom properties instead of a single `background-image`
|
|
30
|
+
* string: Vue 3's `:style` parses a string into a normalized object keyed by
|
|
31
|
+
* property name. A string with two `background-image` declarations
|
|
32
|
+
* (`background-image: url(...); background-image: image-set(...)`) collapses
|
|
33
|
+
* to a single entry — only the last value survives. This loses the
|
|
34
|
+
* progressive-enhancement chain that's the whole point of pairing a `url()`
|
|
35
|
+
* fallback with an `image-set()` upgrade. By emitting two custom properties,
|
|
36
|
+
* Vue keeps both, and the consuming CSS rule chains them as two real
|
|
37
|
+
* declarations of `background-image` so browsers walk the cascade naturally.
|
|
38
|
+
*
|
|
39
|
+
* Consumed by Hero.vue's `.promo-surface` rule, which declares:
|
|
40
|
+
*
|
|
41
|
+
* background-image: var(--promo-bg-fallback);
|
|
42
|
+
* background-image: var(--promo-bg-set, var(--promo-bg-fallback));
|
|
43
|
+
*
|
|
44
|
+
* Browsers that can parse `image-set()` (and its `type()` argument) use the
|
|
45
|
+
* second declaration; browsers that can't fall through to the first.
|
|
46
|
+
*
|
|
28
47
|
* @param {object} options
|
|
29
48
|
* @param {{
|
|
30
49
|
* sources: import('vue').MaybeRefOrGetter<Array<{ type: string, srcset: string }>>,
|
|
31
50
|
* fallbackSrc: import('vue').MaybeRefOrGetter<string>,
|
|
32
51
|
* fallbackFormat: import('vue').MaybeRefOrGetter<string>
|
|
33
52
|
* }} options.imageSet
|
|
53
|
+
* @returns {import('vue').ComputedRef<Record<string, string> | null>}
|
|
34
54
|
*/
|
|
35
55
|
export function usePromoBackgroundStyles({ imageSet }) {
|
|
36
56
|
return computed(() => {
|
|
@@ -38,30 +58,26 @@ export function usePromoBackgroundStyles({ imageSet }) {
|
|
|
38
58
|
const fallbackFormat = (unref(imageSet?.fallbackFormat) || 'jpg').toLowerCase();
|
|
39
59
|
const sources = unref(imageSet?.sources) || [];
|
|
40
60
|
|
|
41
|
-
|
|
61
|
+
if (!fallbackSrc) return null;
|
|
42
62
|
|
|
63
|
+
const formatEntries = [];
|
|
43
64
|
sources.forEach((source) => {
|
|
44
65
|
const largest = selectLargestEntry(source?.srcset);
|
|
45
66
|
if (largest) {
|
|
46
67
|
formatEntries.push(`url("${largest}") type("${source?.type}") 1x`);
|
|
47
68
|
}
|
|
48
69
|
});
|
|
49
|
-
|
|
50
70
|
if (fallbackSrc) {
|
|
51
71
|
const fallbackMime = fallbackFormat === 'jpg' ? 'jpeg' : fallbackFormat;
|
|
52
72
|
formatEntries.push(`url("${fallbackSrc}") type("image/${fallbackMime}") 1x`);
|
|
53
73
|
}
|
|
54
74
|
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
if (cssImageSet) {
|
|
62
|
-
style += `background-image: ${cssImageSet};`;
|
|
75
|
+
const result = {
|
|
76
|
+
'--promo-bg-fallback': `url("${fallbackSrc}")`,
|
|
77
|
+
};
|
|
78
|
+
if (formatEntries.length) {
|
|
79
|
+
result['--promo-bg-set'] = `image-set(${formatEntries.join(', ')})`;
|
|
63
80
|
}
|
|
64
|
-
|
|
65
|
-
return style;
|
|
81
|
+
return result;
|
|
66
82
|
});
|
|
67
83
|
}
|