@xenterprises/nuxt-x-marketing 1.15.1 → 1.15.3
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 +26 -0
- package/app/app.config.ts +17 -2
- package/app/components/X/Mark/Hero/index.vue +54 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,32 @@ 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.15.3] - 2026-10-20
|
|
34
|
+
|
|
35
|
+
### Added (opt-in)
|
|
36
|
+
|
|
37
|
+
- **`XMarkHero` `constrainToScrim`** (boolean, kebab `constrain-to-scrim`). With
|
|
38
|
+
`overlay="scrim-left"` and `align="left"`, at md and up the text column is capped so it stays
|
|
39
|
+
inside the 90% scrim zone: max width = effective scrim width (`scrimWidth`, or 55% when unset)
|
|
40
|
+
minus the container's left offset and a 2rem inner gap, never wider than the default
|
|
41
|
+
`max-w-3xl` and never narrower than 14rem. A `%` scrimWidth resolves against the hero width
|
|
42
|
+
(the section becomes an inline-size container at md+ only). Below md nothing changes,
|
|
43
|
+
including `scrimMobile="bottom"`. Lets a 50 to 55% scrim pass 4.5:1 at 768 to 1024px without
|
|
44
|
+
burying the photo. Unset: body HTML identical to 1.15.2 and 0 px difference at 1440, 1024,
|
|
45
|
+
768 and 390.
|
|
46
|
+
|
|
47
|
+
## [1.15.2] - 2026-10-19
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
|
|
51
|
+
- **No more literal `[object Object]` in UButton classes.** The layer's `app.config` overrode
|
|
52
|
+
`ui.button.variants.size.lg` / `xl` with plain strings, but Nuxt UI defines each size as a
|
|
53
|
+
per-part object (`base`, `leadingIcon`, `trailingIcon`, ...). tailwind-variants joined the two
|
|
54
|
+
as `${object} ${string}`, so every lg/xl UButton (XMarkCTA, XMarkHero, any site button) carried
|
|
55
|
+
an `[object Object]` class. The overrides are now per-part objects; `gap-0`, `size-[1em]` icons
|
|
56
|
+
and `size-8 text-base` avatars keep the look pixel-identical to 1.15.1 (home, CTA and button
|
|
57
|
+
grid at 1440/390/375: 0 px difference). HTML class lists of lg/xl buttons change.
|
|
58
|
+
|
|
33
59
|
## [1.15.1] - 2026-10-18
|
|
34
60
|
|
|
35
61
|
### Fixed
|
package/app/app.config.ts
CHANGED
|
@@ -13,9 +13,24 @@ export default defineAppConfig({
|
|
|
13
13
|
base: "font-medium tracking-wide",
|
|
14
14
|
},
|
|
15
15
|
variants: {
|
|
16
|
+
// 1.15.2: Nuxt UI size variants are per-slot objects. tailwind-variants merges an
|
|
17
|
+
// app.config string with the theme object as `${themeObject} ${string}`, which put a
|
|
18
|
+
// literal "[object Object]" in every lg/xl button class (and dropped the theme's lg/xl
|
|
19
|
+
// gap, icon and avatar sizes). Per-slot objects merge cleanly; gap-0, size-[1em] and
|
|
20
|
+
// the md avatar classes keep the look identical to 1.15.1 (no gap, icons at 1em, 32px avatar).
|
|
16
21
|
size: {
|
|
17
|
-
lg:
|
|
18
|
-
|
|
22
|
+
lg: {
|
|
23
|
+
base: "px-8 py-4 text-base gap-0",
|
|
24
|
+
leadingIcon: "size-[1em]",
|
|
25
|
+
trailingIcon: "size-[1em]",
|
|
26
|
+
leadingAvatar: "size-8 text-base",
|
|
27
|
+
},
|
|
28
|
+
xl: {
|
|
29
|
+
base: "px-10 py-5 text-lg gap-0",
|
|
30
|
+
leadingIcon: "size-[1em]",
|
|
31
|
+
trailingIcon: "size-[1em]",
|
|
32
|
+
leadingAvatar: "size-8 text-base",
|
|
33
|
+
},
|
|
19
34
|
},
|
|
20
35
|
},
|
|
21
36
|
},
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
heightClass,
|
|
6
6
|
alignmentClasses,
|
|
7
7
|
verticalAlignClasses,
|
|
8
|
-
{ 'pt-20': includeNavPadding },
|
|
8
|
+
{ 'pt-20': includeNavPadding, 'x-hero-cts': constrain },
|
|
9
9
|
]"
|
|
10
10
|
>
|
|
11
11
|
<!-- Background -->
|
|
@@ -81,7 +81,11 @@
|
|
|
81
81
|
|
|
82
82
|
<!-- Content -->
|
|
83
83
|
<div class="relative z-10 w-full max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
84
|
-
<div
|
|
84
|
+
<div
|
|
85
|
+
class="max-w-3xl pb-6 md:pb-8"
|
|
86
|
+
:class="[contentAlignmentClasses, { 'x-hero-cts-col': constrain }]"
|
|
87
|
+
v-bind="constrain ? { style: constrainStyle } : {}"
|
|
88
|
+
>
|
|
85
89
|
<!-- Eyebrow -->
|
|
86
90
|
<p v-if="eyebrow" class="xText-eyebrow text-white/70 mb-4">
|
|
87
91
|
{{ eyebrow }}
|
|
@@ -260,6 +264,18 @@ const props = defineProps({
|
|
|
260
264
|
default: "",
|
|
261
265
|
validator: (v) => ["", "bottom"].includes(v),
|
|
262
266
|
},
|
|
267
|
+
/**
|
|
268
|
+
* scrim-left only, opt-in (1.15.3). At md and up, caps the text column so its right
|
|
269
|
+
* edge stays inside the 90% scrim zone: max width = effective scrim width (scrimWidth,
|
|
270
|
+
* or 55% when unset) minus the container's left offset and a 2rem inner gap, never
|
|
271
|
+
* wider than the default max-w-3xl and never narrower than 14rem. Left-aligned
|
|
272
|
+
* content only (center/right alignment is unaffected). Below md nothing changes,
|
|
273
|
+
* including scrimMobile="bottom". Unset (default): output identical to 1.15.2.
|
|
274
|
+
*/
|
|
275
|
+
constrainToScrim: {
|
|
276
|
+
type: Boolean,
|
|
277
|
+
default: false,
|
|
278
|
+
},
|
|
263
279
|
/** Add top padding for non-transparent nav */
|
|
264
280
|
includeNavPadding: {
|
|
265
281
|
type: Boolean,
|
|
@@ -293,6 +309,19 @@ const mobileBottom = computed(
|
|
|
293
309
|
|
|
294
310
|
const softScrim = computed(() => props.overlay === "scrim-left" && !!props.scrimWidth);
|
|
295
311
|
|
|
312
|
+
// constrainToScrim (1.15.3): only meaningful for left-aligned content over scrim-left.
|
|
313
|
+
const constrain = computed(
|
|
314
|
+
() => props.constrainToScrim && props.overlay === "scrim-left" && props.align === "left",
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
// Effective scrim width in units that resolve against the hero section (a size container
|
|
318
|
+
// at md+ when constrained): N% of the section becomes Ncqw; other lengths pass through.
|
|
319
|
+
const constrainStyle = computed(() => {
|
|
320
|
+
if (!constrain.value) return undefined;
|
|
321
|
+
const w = props.scrimWidth || "55%";
|
|
322
|
+
return { "--x-cts-w": w.endsWith("%") ? `${parseFloat(w)}cqw` : w };
|
|
323
|
+
});
|
|
324
|
+
|
|
296
325
|
const heightClass = computed(() => {
|
|
297
326
|
const heights = {
|
|
298
327
|
full: "min-h-[calc(100svh-var(--ui-header-height))]",
|
|
@@ -370,6 +399,29 @@ const contentAlignmentClasses = computed(() => {
|
|
|
370
399
|
);
|
|
371
400
|
}
|
|
372
401
|
}
|
|
402
|
+
/* constrainToScrim (1.15.3), md+ only: the section is an inline-size container so the
|
|
403
|
+
* text column can be capped against the section width. Column left edge = container
|
|
404
|
+
* offset (max(0, (100cqw - 80rem) / 2)) + container padding (md 1.5rem, lg 2rem). */
|
|
405
|
+
@media (min-width: 768px) {
|
|
406
|
+
.x-hero-cts {
|
|
407
|
+
container-type: inline-size;
|
|
408
|
+
}
|
|
409
|
+
.x-hero-cts-col {
|
|
410
|
+
--x-cts-pad: 1.5rem;
|
|
411
|
+
max-width: min(
|
|
412
|
+
48rem,
|
|
413
|
+
max(
|
|
414
|
+
14rem,
|
|
415
|
+
calc(var(--x-cts-w, 55cqw) - max(0px, (100cqw - 80rem) / 2) - var(--x-cts-pad) - 2rem)
|
|
416
|
+
)
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
@media (min-width: 1024px) {
|
|
421
|
+
.x-hero-cts-col {
|
|
422
|
+
--x-cts-pad: 2rem;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
373
425
|
/* md+: 90% up to --x-scrim-w, then a long eased fade to clear. */
|
|
374
426
|
@media (min-width: 768px) {
|
|
375
427
|
.x-hero-scrim-w {
|