@xenterprises/nuxt-x-marketing 1.4.15 → 1.5.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 +11 -0
- package/app/components/X/Mark/Hero/index.vue +46 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
30
30
|
section and its sample product data were dropped with them. Every other section of the
|
|
31
31
|
demo page is unchanged.
|
|
32
32
|
|
|
33
|
+
## [1.5.0] - 2026-10-12
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- `XMarkHero` `overlay="heavier"`: flat 75% black (title about 8:1 on the worst measured desk-lamps image area, versus about 5.9:1 with `heavy`).
|
|
38
|
+
- `XMarkHero` `overlay="scrim-left"` and `overlay="scrim-bottom"`: 90% black where the text sits, fading to 30%. White title holds 7:1 (subtitle 5.2:1) even over pure white image areas. `scrim-left` is a full 90% below `md`.
|
|
39
|
+
- `XMarkHero` `height` prop: `full` (default, unchanged), `tall` (75svh), `short` (50svh).
|
|
40
|
+
- `XMarkHero` `imagePosition` prop: CSS `object-position` for the background image or video, e.g. `left center`.
|
|
41
|
+
|
|
42
|
+
Existing values are unchanged: `heavy` stays 60%, and the default height is still full viewport.
|
|
43
|
+
|
|
33
44
|
## [1.4.15] - 2026-10-12
|
|
34
45
|
|
|
35
46
|
### Fixed
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<section
|
|
3
|
-
class="relative
|
|
3
|
+
class="relative flex overflow-hidden"
|
|
4
4
|
:class="[
|
|
5
|
+
heightClass,
|
|
5
6
|
alignmentClasses,
|
|
6
7
|
verticalAlignClasses,
|
|
7
8
|
{ 'pt-20': includeNavPadding },
|
|
@@ -21,6 +22,7 @@
|
|
|
21
22
|
muted
|
|
22
23
|
playsinline
|
|
23
24
|
class="absolute inset-0 w-full h-full object-cover xParallax"
|
|
25
|
+
:style="imagePositionStyle"
|
|
24
26
|
data-parallax-speed="0.3"
|
|
25
27
|
/>
|
|
26
28
|
|
|
@@ -31,6 +33,7 @@
|
|
|
31
33
|
:alt="img.alt || ''"
|
|
32
34
|
fetchpriority="high"
|
|
33
35
|
class="absolute inset-0 w-full h-full object-cover xParallax"
|
|
36
|
+
:style="imagePositionStyle"
|
|
34
37
|
data-parallax-speed="0.3"
|
|
35
38
|
/>
|
|
36
39
|
</slot>
|
|
@@ -137,7 +140,15 @@ const props = defineProps({
|
|
|
137
140
|
overlay: {
|
|
138
141
|
type: String,
|
|
139
142
|
default: "gradient",
|
|
140
|
-
validator: (v) => [
|
|
143
|
+
validator: (v) => [
|
|
144
|
+
"light",
|
|
145
|
+
"heavy",
|
|
146
|
+
"heavier",
|
|
147
|
+
"gradient",
|
|
148
|
+
"scrim-left",
|
|
149
|
+
"scrim-bottom",
|
|
150
|
+
"none",
|
|
151
|
+
].includes(v),
|
|
141
152
|
},
|
|
142
153
|
/** Small text above title */
|
|
143
154
|
eyebrow: {
|
|
@@ -177,6 +188,17 @@ const props = defineProps({
|
|
|
177
188
|
type: Boolean,
|
|
178
189
|
default: true,
|
|
179
190
|
},
|
|
191
|
+
/** Section height: full (viewport minus header, default), tall (75svh), short (50svh) */
|
|
192
|
+
height: {
|
|
193
|
+
type: String,
|
|
194
|
+
default: "full",
|
|
195
|
+
validator: (v) => ["full", "tall", "short"].includes(v),
|
|
196
|
+
},
|
|
197
|
+
/** CSS object-position for the background image/video, e.g. "left center" */
|
|
198
|
+
imagePosition: {
|
|
199
|
+
type: String,
|
|
200
|
+
default: "",
|
|
201
|
+
},
|
|
180
202
|
/** Add top padding for non-transparent nav */
|
|
181
203
|
includeNavPadding: {
|
|
182
204
|
type: Boolean,
|
|
@@ -188,11 +210,33 @@ const overlayClass = computed(() => {
|
|
|
188
210
|
const overlays = {
|
|
189
211
|
light: "bg-black/30",
|
|
190
212
|
heavy: "bg-black/60",
|
|
213
|
+
// 75% flat: white title >= 8:1 on image areas up to ~0.32 relative luminance
|
|
214
|
+
heavier: "bg-black/75",
|
|
191
215
|
gradient: "bg-gradient-to-t from-black/80 via-black/40 to-transparent",
|
|
216
|
+
// 90% where text sits: white title >= 7:1 even over pure white image areas.
|
|
217
|
+
// Full 90% on small screens where text spans the width.
|
|
218
|
+
"scrim-left":
|
|
219
|
+
"bg-black/90 md:bg-transparent md:bg-gradient-to-r md:from-black/90 md:via-black/90 md:via-55% md:to-black/30",
|
|
220
|
+
// 90% across the bottom half; pair with verticalAlign="bottom"
|
|
221
|
+
"scrim-bottom":
|
|
222
|
+
"bg-gradient-to-t from-black/90 via-black/90 via-50% to-black/30",
|
|
192
223
|
};
|
|
193
224
|
return overlays[props.overlay] || "";
|
|
194
225
|
});
|
|
195
226
|
|
|
227
|
+
const heightClass = computed(() => {
|
|
228
|
+
const heights = {
|
|
229
|
+
full: "min-h-[calc(100svh-var(--ui-header-height))]",
|
|
230
|
+
tall: "min-h-[75svh]",
|
|
231
|
+
short: "min-h-[50svh]",
|
|
232
|
+
};
|
|
233
|
+
return heights[props.height] || heights.full;
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
const imagePositionStyle = computed(() =>
|
|
237
|
+
props.imagePosition ? { objectPosition: props.imagePosition } : undefined,
|
|
238
|
+
);
|
|
239
|
+
|
|
196
240
|
const alignmentClasses = computed(() => {
|
|
197
241
|
const aligns = {
|
|
198
242
|
left: "text-left",
|