@enadhq/enad-react-sdk 1.1.0 → 1.3.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.
Files changed (232) hide show
  1. package/dist/client/cart/components/cart-drawer.mjs +3 -3
  2. package/dist/client/cart/components/cart-drawer.mjs.map +1 -1
  3. package/dist/client/cart/components/cart-trigger.mjs +1 -1
  4. package/dist/client/cart/components/cart-trigger.mjs.map +1 -1
  5. package/dist/client/storefront/blocks/card-video.mjs +1 -1
  6. package/dist/client/storefront/blocks/card-video.mjs.map +1 -1
  7. package/dist/client/storefront/blocks/gallery-with-link-blocks.d.ts.map +1 -1
  8. package/dist/client/storefront/blocks/gallery-with-link-blocks.mjs +13 -5
  9. package/dist/client/storefront/blocks/gallery-with-link-blocks.mjs.map +1 -1
  10. package/dist/client/storefront/blocks/gallery.d.ts +10 -1
  11. package/dist/client/storefront/blocks/gallery.d.ts.map +1 -1
  12. package/dist/client/storefront/blocks/gallery.mjs +51 -27
  13. package/dist/client/storefront/blocks/gallery.mjs.map +1 -1
  14. package/dist/client/storefront/blocks/hero.d.ts +12 -1
  15. package/dist/client/storefront/blocks/hero.d.ts.map +1 -1
  16. package/dist/client/storefront/blocks/hero.mjs +143 -145
  17. package/dist/client/storefront/blocks/hero.mjs.map +1 -1
  18. package/dist/client/storefront/blocks/link-block-small.d.ts.map +1 -1
  19. package/dist/client/storefront/blocks/link-block-small.mjs +1 -1
  20. package/dist/client/storefront/blocks/link-block-small.mjs.map +1 -1
  21. package/dist/client/storefront/blocks/link-block.d.ts.map +1 -1
  22. package/dist/client/storefront/blocks/link-block.mjs +4 -4
  23. package/dist/client/storefront/blocks/link-block.mjs.map +1 -1
  24. package/dist/client/storefront/blocks/product-card-parts.d.ts +1 -1
  25. package/dist/client/storefront/blocks/product-card-parts.d.ts.map +1 -1
  26. package/dist/client/storefront/blocks/product-card-parts.mjs +2 -2
  27. package/dist/client/storefront/blocks/product-card-parts.mjs.map +1 -1
  28. package/dist/client/storefront/blocks/product-card.d.ts +10 -1
  29. package/dist/client/storefront/blocks/product-card.d.ts.map +1 -1
  30. package/dist/client/storefront/blocks/product-card.mjs +122 -116
  31. package/dist/client/storefront/blocks/product-card.mjs.map +1 -1
  32. package/dist/client/storefront/blocks/product-image.mjs +2 -2
  33. package/dist/client/storefront/blocks/product-image.mjs.map +1 -1
  34. package/dist/client/storefront/blocks/text-content-with-image.d.ts +14 -1
  35. package/dist/client/storefront/blocks/text-content-with-image.d.ts.map +1 -1
  36. package/dist/client/storefront/blocks/text-content-with-image.mjs +141 -164
  37. package/dist/client/storefront/blocks/text-content-with-image.mjs.map +1 -1
  38. package/dist/client/storefront/carousel/swipeable-carousel.d.ts +5 -1
  39. package/dist/client/storefront/carousel/swipeable-carousel.d.ts.map +1 -1
  40. package/dist/client/storefront/carousel/swipeable-carousel.mjs +2 -1
  41. package/dist/client/storefront/carousel/swipeable-carousel.mjs.map +1 -1
  42. package/dist/client/storefront/checkout/cart-summary.mjs +1 -1
  43. package/dist/client/storefront/checkout/cart-summary.mjs.map +1 -1
  44. package/dist/client/storefront/components/language-selector.d.ts.map +1 -1
  45. package/dist/client/storefront/components/language-selector.mjs +1 -1
  46. package/dist/client/storefront/components/language-selector.mjs.map +1 -1
  47. package/dist/client/storefront/components/product-recommendations.d.ts.map +1 -1
  48. package/dist/client/storefront/components/product-recommendations.mjs +29 -37
  49. package/dist/client/storefront/components/product-recommendations.mjs.map +1 -1
  50. package/dist/client/storefront/filters/filter-chip.d.ts +5 -2
  51. package/dist/client/storefront/filters/filter-chip.d.ts.map +1 -1
  52. package/dist/client/storefront/filters/filter-chip.mjs +6 -4
  53. package/dist/client/storefront/filters/filter-chip.mjs.map +1 -1
  54. package/dist/client/storefront/filters/filter-panel.mjs +2 -2
  55. package/dist/client/storefront/filters/filter-panel.mjs.map +1 -1
  56. package/dist/client/storefront/filters/toggle-list-view.mjs +1 -1
  57. package/dist/client/storefront/filters/toggle-list-view.mjs.map +1 -1
  58. package/dist/client/storefront/index.d.ts +12 -1
  59. package/dist/client/storefront/index.mjs +12 -1
  60. package/dist/client/storefront/layout/header.d.ts.map +1 -1
  61. package/dist/client/storefront/layout/header.mjs +1 -1
  62. package/dist/client/storefront/layout/header.mjs.map +1 -1
  63. package/dist/client/storefront/layout/mobile-menu-drawer.mjs +1 -1
  64. package/dist/client/storefront/layout/promotion-bar.d.ts.map +1 -1
  65. package/dist/client/storefront/layout/promotion-bar.mjs +3 -3
  66. package/dist/client/storefront/layout/promotion-bar.mjs.map +1 -1
  67. package/dist/client/storefront/primitives/block-heading.d.ts +40 -0
  68. package/dist/client/storefront/primitives/block-heading.d.ts.map +1 -0
  69. package/dist/client/storefront/primitives/block-heading.mjs +43 -0
  70. package/dist/client/storefront/primitives/block-heading.mjs.map +1 -0
  71. package/dist/client/storefront/primitives/button.d.ts +2 -2
  72. package/dist/client/storefront/primitives/button.d.ts.map +1 -1
  73. package/dist/client/storefront/primitives/button.mjs +4 -4
  74. package/dist/client/storefront/primitives/button.mjs.map +1 -1
  75. package/dist/client/storefront/primitives/cta-group.d.ts +25 -0
  76. package/dist/client/storefront/primitives/cta-group.d.ts.map +1 -0
  77. package/dist/client/storefront/primitives/cta-group.mjs +27 -0
  78. package/dist/client/storefront/primitives/cta-group.mjs.map +1 -0
  79. package/dist/client/storefront/primitives/image-with-hover.d.ts +18 -0
  80. package/dist/client/storefront/primitives/image-with-hover.d.ts.map +1 -0
  81. package/dist/client/storefront/primitives/image-with-hover.mjs +16 -0
  82. package/dist/client/storefront/primitives/image-with-hover.mjs.map +1 -0
  83. package/dist/client/storefront/primitives/index.d.ts +4 -1
  84. package/dist/client/storefront/primitives/index.mjs +4 -1
  85. package/dist/client/storefront/primitives/input.d.ts +1 -1
  86. package/dist/client/storefront/primitives/input.mjs.map +1 -1
  87. package/dist/client/storefront/primitives/pagination.mjs +2 -2
  88. package/dist/client/storefront/primitives/pagination.mjs.map +1 -1
  89. package/dist/client/storefront/product/quantity-picker.mjs +2 -2
  90. package/dist/client/storefront/product/quantity-picker.mjs.map +1 -1
  91. package/dist/client/storefront/types.d.ts +1 -1
  92. package/dist/client/storefront/types.d.ts.map +1 -1
  93. package/dist/client/storefront/types.mjs.map +1 -1
  94. package/dist/client/theme/apply.d.ts +1 -1
  95. package/dist/client/theme/apply.d.ts.map +1 -1
  96. package/dist/client/theme/apply.mjs +0 -12
  97. package/dist/client/theme/apply.mjs.map +1 -1
  98. package/dist/client/theme/cli.mjs +0 -16
  99. package/dist/client/theme/cli.mjs.map +1 -1
  100. package/dist/client/theme/codec.d.ts.map +1 -1
  101. package/dist/client/theme/codec.mjs +0 -2
  102. package/dist/client/theme/codec.mjs.map +1 -1
  103. package/dist/client/theme/defaults.d.ts +0 -2
  104. package/dist/client/theme/defaults.mjs +0 -2
  105. package/dist/client/theme/defaults.mjs.map +1 -1
  106. package/dist/client/ui/accordion.d.ts +12 -1
  107. package/dist/client/ui/accordion.d.ts.map +1 -1
  108. package/dist/client/ui/accordion.mjs +23 -5
  109. package/dist/client/ui/accordion.mjs.map +1 -1
  110. package/dist/client/ui/alert.d.ts +16 -7
  111. package/dist/client/ui/alert.d.ts.map +1 -1
  112. package/dist/client/ui/alert.mjs +21 -8
  113. package/dist/client/ui/alert.mjs.map +1 -1
  114. package/dist/client/ui/avatar.d.ts +10 -1
  115. package/dist/client/ui/avatar.d.ts.map +1 -1
  116. package/dist/client/ui/avatar.mjs +18 -4
  117. package/dist/client/ui/avatar.mjs.map +1 -1
  118. package/dist/client/ui/breadcrumb.d.ts +13 -1
  119. package/dist/client/ui/breadcrumb.d.ts.map +1 -1
  120. package/dist/client/ui/breadcrumb.mjs +27 -7
  121. package/dist/client/ui/breadcrumb.mjs.map +1 -1
  122. package/dist/client/ui/button.d.ts +28 -10
  123. package/dist/client/ui/button.d.ts.map +1 -1
  124. package/dist/client/ui/button.mjs +45 -20
  125. package/dist/client/ui/button.mjs.map +1 -1
  126. package/dist/client/ui/card.d.ts +20 -1
  127. package/dist/client/ui/card.d.ts.map +1 -1
  128. package/dist/client/ui/card.mjs +36 -8
  129. package/dist/client/ui/card.mjs.map +1 -1
  130. package/dist/client/ui/carousel.d.ts +9 -1
  131. package/dist/client/ui/carousel.d.ts.map +1 -1
  132. package/dist/client/ui/carousel.mjs +20 -4
  133. package/dist/client/ui/carousel.mjs.map +1 -1
  134. package/dist/client/ui/checkbox.d.ts +9 -1
  135. package/dist/client/ui/checkbox.d.ts.map +1 -1
  136. package/dist/client/ui/checkbox.mjs +12 -3
  137. package/dist/client/ui/checkbox.mjs.map +1 -1
  138. package/dist/client/ui/dialog.d.ts +13 -1
  139. package/dist/client/ui/dialog.d.ts.map +1 -1
  140. package/dist/client/ui/dialog.mjs +27 -7
  141. package/dist/client/ui/dialog.mjs.map +1 -1
  142. package/dist/client/ui/hover-card.d.ts +6 -1
  143. package/dist/client/ui/hover-card.d.ts.map +1 -1
  144. package/dist/client/ui/hover-card.mjs +4 -2
  145. package/dist/client/ui/hover-card.mjs.map +1 -1
  146. package/dist/client/ui/input.d.ts +20 -7
  147. package/dist/client/ui/input.d.ts.map +1 -1
  148. package/dist/client/ui/input.mjs +33 -9
  149. package/dist/client/ui/input.mjs.map +1 -1
  150. package/dist/client/ui/label.d.ts +6 -1
  151. package/dist/client/ui/label.d.ts.map +1 -1
  152. package/dist/client/ui/label.mjs +4 -2
  153. package/dist/client/ui/label.mjs.map +1 -1
  154. package/dist/client/ui/navigation-menu.d.ts +20 -3
  155. package/dist/client/ui/navigation-menu.d.ts.map +1 -1
  156. package/dist/client/ui/navigation-menu.mjs +34 -12
  157. package/dist/client/ui/navigation-menu.mjs.map +1 -1
  158. package/dist/client/ui/pagination.d.ts.map +1 -1
  159. package/dist/client/ui/pagination.mjs +3 -3
  160. package/dist/client/ui/pagination.mjs.map +1 -1
  161. package/dist/client/ui/popover.d.ts +11 -1
  162. package/dist/client/ui/popover.d.ts.map +1 -1
  163. package/dist/client/ui/popover.mjs +21 -5
  164. package/dist/client/ui/popover.mjs.map +1 -1
  165. package/dist/client/ui/progress.d.ts +9 -1
  166. package/dist/client/ui/progress.d.ts.map +1 -1
  167. package/dist/client/ui/progress.mjs +12 -3
  168. package/dist/client/ui/progress.mjs.map +1 -1
  169. package/dist/client/ui/select.d.ts +14 -2
  170. package/dist/client/ui/select.d.ts.map +1 -1
  171. package/dist/client/ui/select.mjs +35 -9
  172. package/dist/client/ui/select.mjs.map +1 -1
  173. package/dist/client/ui/separator.d.ts +6 -1
  174. package/dist/client/ui/separator.d.ts.map +1 -1
  175. package/dist/client/ui/separator.mjs +4 -2
  176. package/dist/client/ui/separator.mjs.map +1 -1
  177. package/dist/client/ui/sheet.d.ts +13 -1
  178. package/dist/client/ui/sheet.d.ts.map +1 -1
  179. package/dist/client/ui/sheet.mjs +35 -7
  180. package/dist/client/ui/sheet.mjs.map +1 -1
  181. package/dist/client/ui/slot-wrapper.d.ts +28 -0
  182. package/dist/client/ui/slot-wrapper.d.ts.map +1 -0
  183. package/dist/client/ui/slot-wrapper.mjs +38 -0
  184. package/dist/client/ui/slot-wrapper.mjs.map +1 -0
  185. package/dist/client/ui/tabs.d.ts +11 -1
  186. package/dist/client/ui/tabs.d.ts.map +1 -1
  187. package/dist/client/ui/tabs.mjs +21 -5
  188. package/dist/client/ui/tabs.mjs.map +1 -1
  189. package/dist/client/ui/toggle-group.d.ts +7 -4
  190. package/dist/client/ui/toggle-group.d.ts.map +1 -1
  191. package/dist/client/ui/toggle-group.mjs +4 -4
  192. package/dist/client/ui/toggle-group.mjs.map +1 -1
  193. package/dist/client/ui/toggle.d.ts +17 -8
  194. package/dist/client/ui/toggle.d.ts.map +1 -1
  195. package/dist/client/ui/toggle.mjs +11 -9
  196. package/dist/client/ui/toggle.mjs.map +1 -1
  197. package/dist/client/ui/tooltip.d.ts +6 -1
  198. package/dist/client/ui/tooltip.d.ts.map +1 -1
  199. package/dist/client/ui/tooltip.mjs +4 -2
  200. package/dist/client/ui/tooltip.mjs.map +1 -1
  201. package/dist/client/ui-resolver/button.d.ts +3 -4
  202. package/dist/client/ui-resolver/button.d.ts.map +1 -1
  203. package/dist/client/ui-resolver/button.mjs +2 -2
  204. package/dist/client/ui-resolver/button.mjs.map +1 -1
  205. package/dist/client/ui-resolver/card.d.ts +14 -1
  206. package/dist/client/ui-resolver/card.d.ts.map +1 -1
  207. package/dist/client/ui-resolver/card.mjs +3 -2
  208. package/dist/client/ui-resolver/card.mjs.map +1 -1
  209. package/dist/client/ui-resolver/context.mjs +1 -1
  210. package/dist/client/ui-resolver/context.mjs.map +1 -1
  211. package/dist/client/ui-resolver/index.d.ts +7 -4
  212. package/dist/client/ui-resolver/index.mjs +8 -6
  213. package/dist/client/ui-resolver/input.d.ts +3 -4
  214. package/dist/client/ui-resolver/input.d.ts.map +1 -1
  215. package/dist/client/ui-resolver/input.mjs +2 -2
  216. package/dist/client/ui-resolver/input.mjs.map +1 -1
  217. package/dist/client/ui-resolver/navigation-menu.d.ts +1 -2
  218. package/dist/client/ui-resolver/navigation-menu.d.ts.map +1 -1
  219. package/dist/client/ui-resolver/recipe.d.ts +95 -0
  220. package/dist/client/ui-resolver/recipe.d.ts.map +1 -0
  221. package/dist/client/ui-resolver/recipe.mjs +134 -0
  222. package/dist/client/ui-resolver/recipe.mjs.map +1 -0
  223. package/dist/client/ui-resolver/toggle.d.ts +2 -2
  224. package/dist/client/ui-resolver/toggle.mjs +2 -2
  225. package/dist/client/ui-resolver/toggle.mjs.map +1 -1
  226. package/dist/client/ui-resolver/types.d.ts +14 -0
  227. package/dist/client/ui-resolver/types.d.ts.map +1 -0
  228. package/dist/client/ui-resolver/types.mjs +1 -0
  229. package/dist/client/wishlist/wishlist-drawer.mjs +4 -4
  230. package/dist/client/wishlist/wishlist-drawer.mjs.map +1 -1
  231. package/dist/styles.css +1 -1
  232. package/package.json +4 -3
@@ -1,23 +1,53 @@
1
1
  "use client";
2
2
  import { cn } from "../../ui/utils.mjs";
3
+ import { defineSlotRecipe } from "../../ui-resolver/recipe.mjs";
3
4
  import { useVariantDefault } from "../../ui-resolver/context.mjs";
4
- import { StorefrontButton } from "../primitives/button.mjs";
5
- import { StorefrontTextLink } from "../primitives/text-link.mjs";
5
+ import { BlockHeading } from "../primitives/block-heading.mjs";
6
+ import { CTAGroup } from "../primitives/cta-group.mjs";
6
7
  import { colorThemeClasses, isThemeDark } from "../types.mjs";
7
8
  import "react";
8
9
  import { jsx, jsxs } from "react/jsx-runtime";
9
10
  //#region src/client/storefront/blocks/hero.tsx
11
+ const heroRecipe = defineSlotRecipe({
12
+ slots: [
13
+ "root",
14
+ "background",
15
+ "overlay",
16
+ "content"
17
+ ],
18
+ base: {
19
+ root: "",
20
+ background: "size-full object-cover",
21
+ overlay: "absolute inset-0",
22
+ content: ""
23
+ },
24
+ variants: {
25
+ layout: {
26
+ overlay: { root: "relative overflow-hidden" },
27
+ split: { root: "grid" },
28
+ minimal: { root: "px-[var(--enad-hero-px,2rem)] py-[var(--enad-hero-py,4rem)] md:py-[calc(var(--enad-hero-py,4rem)*1.5)] lg:py-[calc(var(--enad-hero-py,4rem)*2)]" },
29
+ banner: { root: "relative max-h-64 overflow-hidden" },
30
+ "image-only": { root: "relative overflow-hidden bg-muted" }
31
+ },
32
+ contentWidth: {
33
+ sm: { content: "max-w-sm" },
34
+ md: { content: "max-w-xl" },
35
+ lg: { content: "max-w-3xl" }
36
+ }
37
+ },
38
+ defaultVariants: {
39
+ layout: "overlay",
40
+ contentWidth: "md"
41
+ }
42
+ });
10
43
  const aspectClasses = {
11
44
  "9:16": "aspect-[9/16]",
12
45
  "4:5": "aspect-[4/5]",
13
46
  "1:1": "aspect-square",
14
47
  "16:9": "aspect-video"
15
48
  };
16
- const contentWidthClasses = {
17
- sm: "max-w-sm",
18
- md: "max-w-xl",
19
- lg: "max-w-3xl"
20
- };
49
+ const overlayGradientStyle = (direction) => ({ background: `linear-gradient(${direction}, color-mix(in oklch, var(--enad-overlay-color) calc(var(--enad-overlay-from-opacity) * 100%), transparent), color-mix(in oklch, var(--enad-overlay-color) calc(var(--enad-overlay-to-opacity) * 100%), transparent))` });
50
+ const centerOverlayStyle = { background: "color-mix(in oklch, var(--enad-overlay-color) 30%, transparent)" };
21
51
  const alignItemsMap = {
22
52
  top: "items-start",
23
53
  center: "items-center",
@@ -38,7 +68,6 @@ function getTextAlign(position) {
38
68
  if (horizontal === "right") return "right";
39
69
  return "left";
40
70
  }
41
- const overlayGradientStyle = (direction) => ({ background: `linear-gradient(${direction}, color-mix(in oklch, var(--enad-overlay-color) calc(var(--enad-overlay-from-opacity) * 100%), transparent), color-mix(in oklch, var(--enad-overlay-color) calc(var(--enad-overlay-to-opacity) * 100%), transparent))` });
42
71
  function getGradientDirection(position) {
43
72
  const [vertical, horizontal] = position.split("-");
44
73
  if (vertical === "bottom") return "to top";
@@ -47,88 +76,120 @@ function getGradientDirection(position) {
47
76
  if (horizontal === "right") return "to left";
48
77
  return null;
49
78
  }
50
- const centerOverlayStyle = { background: "color-mix(in oklch, var(--enad-overlay-color) 30%, transparent)" };
51
- const headingStyle = {
52
- fontWeight: "var(--enad-heading-weight)",
53
- letterSpacing: "var(--enad-heading-tracking)",
54
- textTransform: "var(--enad-heading-transform)"
55
- };
56
- function HeroCTA({ buttonLabel, buttonHref, textLinkLabel, textLinkHref, dark }) {
57
- if (!buttonLabel && !textLinkLabel) return null;
58
- return /* @__PURE__ */ jsxs("div", {
59
- className: "mt-6 flex flex-wrap items-center gap-4",
60
- children: [buttonLabel && buttonHref && /* @__PURE__ */ jsx(StorefrontButton, {
61
- href: buttonHref,
62
- variant: dark ? "outline" : "primary",
63
- children: buttonLabel
64
- }), textLinkLabel && textLinkHref && /* @__PURE__ */ jsx(StorefrontTextLink, {
65
- href: textLinkHref,
66
- className: dark ? "text-white" : void 0,
67
- children: textLinkLabel
68
- })]
79
+ function HeroWithImage({ layout, image, aspectRatio = "16:9", contentPosition = "bottom-center", contentWidth = "md", preheader, heading, buttonLabel, buttonHref, textLinkLabel, textLinkHref, dark, themeClasses, align, className }) {
80
+ const classes = heroRecipe({
81
+ layout,
82
+ contentWidth
69
83
  });
70
- }
71
- function HeroTextBlock({ preheader, heading, buttonLabel, buttonHref, textLinkLabel, textLinkHref, contentWidth = "md", dark = false, align = "left", headingClamp }) {
72
- return /* @__PURE__ */ jsxs("div", {
73
- className: cn("flex min-w-0 flex-col", contentWidthClasses[contentWidth], align === "center" && "items-center text-center", align === "right" && "items-end text-end", align === "left" && "items-start text-start"),
74
- children: [
75
- preheader && /* @__PURE__ */ jsx("p", {
76
- className: cn("mb-2 text-sm uppercase tracking-widest line-clamp-2", dark ? "text-white/70" : "text-muted-foreground"),
77
- children: preheader
78
- }),
79
- heading && /* @__PURE__ */ jsx("h1", {
80
- className: cn("text-3xl font-heading md:text-4xl lg:text-5xl", dark ? "text-white" : "text-foreground", headingClamp),
81
- style: headingStyle,
82
- children: heading
83
- }),
84
- /* @__PURE__ */ jsx(HeroCTA, {
84
+ const hasImage = Boolean(image?.src);
85
+ const hasContent = preheader || heading || buttonLabel || textLinkLabel;
86
+ const position = contentPosition ?? "bottom-center";
87
+ if (layout === "split") return /* @__PURE__ */ jsxs("section", {
88
+ className: cn(classes.root, hasImage && "lg:grid-cols-2", themeClasses, className),
89
+ children: [/* @__PURE__ */ jsxs("div", {
90
+ className: "flex min-w-0 flex-col justify-center px-8 py-12 lg:px-16 lg:py-20",
91
+ children: [/* @__PURE__ */ jsx(BlockHeading, {
92
+ preheader,
93
+ heading,
94
+ dark,
95
+ align,
96
+ headingTag: "h1",
97
+ headingSize: "lg",
98
+ headingClamp: "line-clamp-4",
99
+ className: classes.content
100
+ }), /* @__PURE__ */ jsx(CTAGroup, {
85
101
  buttonLabel,
86
102
  buttonHref,
87
103
  textLinkLabel,
88
104
  textLinkHref,
89
105
  dark
106
+ })]
107
+ }), hasImage && /* @__PURE__ */ jsx("div", {
108
+ className: cn("relative overflow-hidden bg-muted", aspectClasses[aspectRatio]),
109
+ children: /* @__PURE__ */ jsx("img", {
110
+ src: image?.src,
111
+ alt: image?.alt ?? "",
112
+ className: classes.background,
113
+ loading: "lazy"
114
+ })
115
+ })]
116
+ });
117
+ const gradientDirection = getGradientDirection(position);
118
+ const overlayStyle = gradientDirection ? overlayGradientStyle(gradientDirection) : centerOverlayStyle;
119
+ return /* @__PURE__ */ jsxs("section", {
120
+ className: cn(classes.root, hasImage ? "bg-muted" : "bg-primary", aspectClasses[aspectRatio], themeClasses, className),
121
+ children: [
122
+ hasImage && /* @__PURE__ */ jsx("img", {
123
+ src: image?.src,
124
+ alt: image?.alt ?? "",
125
+ className: classes.background,
126
+ loading: "lazy"
127
+ }),
128
+ /* @__PURE__ */ jsx("div", {
129
+ className: classes.overlay,
130
+ style: overlayStyle
131
+ }),
132
+ hasContent && /* @__PURE__ */ jsx("div", {
133
+ className: getPositionClasses(position),
134
+ children: /* @__PURE__ */ jsxs("div", {
135
+ className: cn("flex min-w-0 flex-col", classes.content),
136
+ children: [/* @__PURE__ */ jsx(BlockHeading, {
137
+ preheader,
138
+ heading,
139
+ dark,
140
+ align,
141
+ headingTag: "h1",
142
+ headingSize: "lg",
143
+ headingClamp: "line-clamp-3"
144
+ }), /* @__PURE__ */ jsx(CTAGroup, {
145
+ buttonLabel,
146
+ buttonHref,
147
+ textLinkLabel,
148
+ textLinkHref,
149
+ dark
150
+ })]
151
+ })
90
152
  })
91
153
  ]
92
154
  });
93
155
  }
94
- function HeroMinimal({ preheader, heading, buttonLabel, buttonHref, textLinkLabel, textLinkHref, dark, themeClasses, className }) {
156
+ function HeroTextOnly({ preheader, heading, buttonLabel, buttonHref, textLinkLabel, textLinkHref, dark, themeClasses, className }) {
95
157
  return /* @__PURE__ */ jsx("section", {
96
- className: cn("px-8 py-16 md:py-24 lg:py-32", themeClasses || "bg-background", className),
158
+ className: cn(heroRecipe({ layout: "minimal" }).root, themeClasses || "bg-background", className),
97
159
  children: /* @__PURE__ */ jsxs("div", {
98
160
  className: "mx-auto flex max-w-4xl flex-col items-center text-center",
99
- children: [
100
- preheader && /* @__PURE__ */ jsx("p", {
101
- className: cn("mb-2 text-sm uppercase tracking-widest", dark ? "text-white/70" : "text-muted-foreground"),
102
- children: preheader
103
- }),
104
- heading && /* @__PURE__ */ jsx("h1", {
105
- className: cn("max-w-prose text-3xl font-heading line-clamp-3 md:text-5xl lg:text-6xl", dark ? "text-white" : "text-foreground"),
106
- style: headingStyle,
107
- children: heading
108
- }),
109
- /* @__PURE__ */ jsx(HeroCTA, {
110
- buttonLabel,
111
- buttonHref,
112
- textLinkLabel,
113
- textLinkHref,
114
- dark
115
- })
116
- ]
161
+ children: [/* @__PURE__ */ jsx(BlockHeading, {
162
+ preheader,
163
+ heading,
164
+ dark,
165
+ align: "center",
166
+ headingTag: "h1",
167
+ headingSize: "xl",
168
+ headingClamp: "line-clamp-3",
169
+ className: "max-w-prose"
170
+ }), /* @__PURE__ */ jsx(CTAGroup, {
171
+ buttonLabel,
172
+ buttonHref,
173
+ textLinkLabel,
174
+ textLinkHref,
175
+ dark
176
+ })]
117
177
  })
118
178
  });
119
179
  }
120
- function HeroBanner({ image, preheader, heading, buttonLabel, buttonHref, textLinkLabel, textLinkHref, themeClasses, className }) {
180
+ function HeroCompact({ image, preheader, heading, buttonLabel, buttonHref, textLinkLabel, textLinkHref, themeClasses, className }) {
181
+ const classes = heroRecipe({ layout: "banner" });
121
182
  return /* @__PURE__ */ jsxs("section", {
122
- className: cn("relative max-h-64 overflow-hidden", image?.src ? "bg-muted" : "bg-primary", themeClasses, className),
183
+ className: cn(classes.root, image?.src ? "bg-muted" : "bg-primary", themeClasses, className),
123
184
  children: [
124
185
  image?.src && /* @__PURE__ */ jsx("img", {
125
186
  src: image?.src,
126
187
  alt: image?.alt ?? "",
127
- className: "size-full object-cover",
188
+ className: classes.background,
128
189
  loading: "lazy"
129
190
  }),
130
191
  /* @__PURE__ */ jsx("div", {
131
- className: "absolute inset-0",
192
+ className: classes.overlay,
132
193
  style: overlayGradientStyle("to right")
133
194
  }),
134
195
  /* @__PURE__ */ jsx("div", {
@@ -142,10 +203,14 @@ function HeroBanner({ image, preheader, heading, buttonLabel, buttonHref, textLi
142
203
  children: preheader
143
204
  }), heading && /* @__PURE__ */ jsx("h2", {
144
205
  className: "min-w-0 truncate text-xl font-heading text-white md:text-2xl lg:text-3xl",
145
- style: headingStyle,
206
+ style: {
207
+ fontWeight: "var(--enad-heading-weight)",
208
+ letterSpacing: "var(--enad-heading-tracking)",
209
+ textTransform: "var(--enad-heading-transform)"
210
+ },
146
211
  children: heading
147
212
  })]
148
- }), /* @__PURE__ */ jsx(HeroCTA, {
213
+ }), /* @__PURE__ */ jsx(CTAGroup, {
149
214
  buttonLabel,
150
215
  buttonHref,
151
216
  textLinkLabel,
@@ -157,87 +222,18 @@ function HeroBanner({ image, preheader, heading, buttonLabel, buttonHref, textLi
157
222
  ]
158
223
  });
159
224
  }
160
- function HeroSplit({ image, aspectRatio = "16:9", preheader, heading, buttonLabel, buttonHref, textLinkLabel, textLinkHref, contentWidth = "md", dark, themeClasses, align, className }) {
161
- const hasImage = Boolean(image?.src);
162
- return /* @__PURE__ */ jsxs("section", {
163
- className: cn("grid", hasImage && "lg:grid-cols-2", themeClasses, className),
164
- children: [/* @__PURE__ */ jsx("div", {
165
- className: "flex min-w-0 items-center px-8 py-12 lg:px-16 lg:py-20",
166
- children: /* @__PURE__ */ jsx(HeroTextBlock, {
167
- preheader,
168
- heading,
169
- buttonLabel,
170
- buttonHref,
171
- textLinkLabel,
172
- textLinkHref,
173
- contentWidth,
174
- dark,
175
- align,
176
- headingClamp: "line-clamp-4"
177
- })
178
- }), hasImage && /* @__PURE__ */ jsx("div", {
179
- className: cn("relative overflow-hidden bg-muted", aspectClasses[aspectRatio]),
180
- children: /* @__PURE__ */ jsx("img", {
181
- src: image?.src,
182
- alt: image?.alt ?? "",
183
- className: "size-full object-cover",
184
- loading: "lazy"
185
- })
186
- })]
187
- });
188
- }
189
225
  function HeroImageOnly({ image, aspectRatio = "16:9", className }) {
226
+ const classes = heroRecipe({ layout: "image-only" });
190
227
  return /* @__PURE__ */ jsx("section", {
191
- className: cn("relative overflow-hidden bg-muted", aspectClasses[aspectRatio], className),
228
+ className: cn(classes.root, aspectClasses[aspectRatio], className),
192
229
  children: image?.src && /* @__PURE__ */ jsx("img", {
193
230
  src: image?.src,
194
231
  alt: image?.alt ?? "",
195
- className: "size-full object-cover",
232
+ className: classes.background,
196
233
  loading: "lazy"
197
234
  })
198
235
  });
199
236
  }
200
- function resolveOverlayGradient(position) {
201
- const direction = getGradientDirection(position);
202
- return direction ? overlayGradientStyle(direction) : centerOverlayStyle;
203
- }
204
- function resolveOverlayBg(imageSrc) {
205
- return imageSrc ? "bg-muted" : "bg-primary";
206
- }
207
- function HeroOverlay({ image, aspectRatio = "16:9", contentPosition = "bottom-center", contentWidth = "md", preheader, heading, buttonLabel, buttonHref, textLinkLabel, textLinkHref, dark, themeClasses, align, className }) {
208
- const hasContent = preheader || heading || buttonLabel || textLinkLabel;
209
- const position = contentPosition ?? "bottom-center";
210
- return /* @__PURE__ */ jsxs("section", {
211
- className: cn("relative overflow-hidden", resolveOverlayBg(image?.src), aspectClasses[aspectRatio], themeClasses, className),
212
- children: [
213
- image?.src && /* @__PURE__ */ jsx("img", {
214
- src: image?.src,
215
- alt: image?.alt ?? "",
216
- className: "size-full object-cover",
217
- loading: "lazy"
218
- }),
219
- /* @__PURE__ */ jsx("div", {
220
- className: "absolute inset-0",
221
- style: resolveOverlayGradient(position)
222
- }),
223
- hasContent && /* @__PURE__ */ jsx("div", {
224
- className: getPositionClasses(position),
225
- children: /* @__PURE__ */ jsx(HeroTextBlock, {
226
- preheader,
227
- heading,
228
- buttonLabel,
229
- buttonHref,
230
- textLinkLabel,
231
- textLinkHref,
232
- contentWidth,
233
- dark,
234
- align,
235
- headingClamp: "line-clamp-3"
236
- })
237
- })
238
- ]
239
- });
240
- }
241
237
  function Hero(props) {
242
238
  const heroDefault = useVariantDefault("hero");
243
239
  const { layout = heroDefault ?? "overlay", contentPosition = "bottom-center", textAlign, colorTheme } = props;
@@ -252,14 +248,16 @@ function Hero(props) {
252
248
  align
253
249
  };
254
250
  switch (layout) {
255
- case "minimal": return /* @__PURE__ */ jsx(HeroMinimal, { ...layoutProps });
256
- case "banner": return /* @__PURE__ */ jsx(HeroBanner, { ...layoutProps });
257
- case "split": return /* @__PURE__ */ jsx(HeroSplit, { ...layoutProps });
251
+ case "minimal": return /* @__PURE__ */ jsx(HeroTextOnly, { ...layoutProps });
252
+ case "banner": return /* @__PURE__ */ jsx(HeroCompact, { ...layoutProps });
258
253
  case "image-only": return /* @__PURE__ */ jsx(HeroImageOnly, { ...layoutProps });
259
- default: return /* @__PURE__ */ jsx(HeroOverlay, { ...layoutProps });
254
+ default: return /* @__PURE__ */ jsx(HeroWithImage, {
255
+ ...layoutProps,
256
+ layout
257
+ });
260
258
  }
261
259
  }
262
260
  //#endregion
263
- export { Hero };
261
+ export { Hero, heroRecipe };
264
262
 
265
263
  //# sourceMappingURL=hero.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"hero.mjs","names":[],"sources":["../../../../src/client/storefront/blocks/hero.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../ui/utils\";\nimport { useVariantDefault } from \"../../ui-resolver/context\";\nimport { StorefrontButton } from \"../primitives/button\";\nimport { StorefrontTextLink } from \"../primitives/text-link\";\nimport {\n colorThemeClasses,\n isThemeDark,\n type HeroProps,\n type HeroContentPosition,\n type HeroContentWidth,\n type HeroTextAlign,\n} from \"../types\";\n\nconst aspectClasses: Record<string, string> = {\n \"9:16\": \"aspect-[9/16]\",\n \"4:5\": \"aspect-[4/5]\",\n \"1:1\": \"aspect-square\",\n \"16:9\": \"aspect-video\",\n};\n\nconst contentWidthClasses: Record<HeroContentWidth, string> = {\n sm: \"max-w-sm\",\n md: \"max-w-xl\",\n lg: \"max-w-3xl\",\n};\n\n/* ─── 3×3 content positioning (overlay only) ─── */\n\nconst alignItemsMap: Record<string, string> = {\n top: \"items-start\",\n center: \"items-center\",\n bottom: \"items-end\",\n};\n\nconst justifyMap: Record<string, string> = {\n left: \"justify-start\",\n center: \"justify-center\",\n right: \"justify-end\",\n};\n\nfunction getPositionClasses(position: HeroContentPosition): string {\n const [vertical, horizontal] = position.split(\"-\") as [string, string];\n return cn(\n \"absolute inset-0 flex p-8 md:p-12 lg:p-16\",\n alignItemsMap[vertical],\n justifyMap[horizontal],\n );\n}\n\nfunction getTextAlign(position: HeroContentPosition): \"left\" | \"center\" | \"right\" {\n const horizontal = position.split(\"-\")[1];\n if (horizontal === \"center\") return \"center\";\n if (horizontal === \"right\") return \"right\";\n return \"left\";\n}\n\n/* ─── Directional gradient based on content position ─── */\n\nconst overlayGradientStyle = (direction: string): React.CSSProperties => ({\n background: `linear-gradient(${direction}, color-mix(in oklch, var(--enad-overlay-color) calc(var(--enad-overlay-from-opacity) * 100%), transparent), color-mix(in oklch, var(--enad-overlay-color) calc(var(--enad-overlay-to-opacity) * 100%), transparent))`,\n});\n\nfunction getGradientDirection(position: HeroContentPosition): string | null {\n const [vertical, horizontal] = position.split(\"-\") as [string, string];\n\n if (vertical === \"bottom\") return \"to top\";\n if (vertical === \"top\") return \"to bottom\";\n if (horizontal === \"left\") return \"to right\";\n if (horizontal === \"right\") return \"to left\";\n\n return null; // center-center fallback\n}\n\nconst centerOverlayStyle: React.CSSProperties = {\n background: \"color-mix(in oklch, var(--enad-overlay-color) 30%, transparent)\",\n};\n\nconst headingStyle = {\n fontWeight: \"var(--enad-heading-weight)\",\n letterSpacing: \"var(--enad-heading-tracking)\",\n textTransform: \"var(--enad-heading-transform)\",\n} as unknown as React.CSSProperties;\n\n/* ─── Shared sub-components ─── */\n\nfunction HeroCTA({\n buttonLabel,\n buttonHref,\n textLinkLabel,\n textLinkHref,\n dark,\n}: {\n buttonLabel?: string;\n buttonHref?: string;\n textLinkLabel?: string;\n textLinkHref?: string;\n dark?: boolean;\n}) {\n if (!buttonLabel && !textLinkLabel) return null;\n return (\n <div className=\"mt-6 flex flex-wrap items-center gap-4\">\n {buttonLabel && buttonHref && (\n <StorefrontButton href={buttonHref} variant={dark ? \"outline\" : \"primary\"}>\n {buttonLabel}\n </StorefrontButton>\n )}\n {textLinkLabel && textLinkHref && (\n <StorefrontTextLink href={textLinkHref} className={dark ? \"text-white\" : undefined}>\n {textLinkLabel}\n </StorefrontTextLink>\n )}\n </div>\n );\n}\n\nfunction HeroTextBlock({\n preheader,\n heading,\n buttonLabel,\n buttonHref,\n textLinkLabel,\n textLinkHref,\n contentWidth = \"md\",\n dark = false,\n align = \"left\",\n headingClamp,\n}: {\n preheader?: string;\n heading?: string;\n buttonLabel?: string;\n buttonHref?: string;\n textLinkLabel?: string;\n textLinkHref?: string;\n contentWidth?: HeroContentWidth;\n dark?: boolean;\n align?: \"left\" | \"center\" | \"right\";\n headingClamp?: string;\n}) {\n return (\n <div\n className={cn(\n \"flex min-w-0 flex-col\",\n contentWidthClasses[contentWidth],\n align === \"center\" && \"items-center text-center\",\n align === \"right\" && \"items-end text-end\",\n align === \"left\" && \"items-start text-start\",\n )}\n >\n {preheader && (\n <p\n className={cn(\n \"mb-2 text-sm uppercase tracking-widest line-clamp-2\",\n dark ? \"text-white/70\" : \"text-muted-foreground\",\n )}\n >\n {preheader}\n </p>\n )}\n {heading && (\n <h1\n className={cn(\n \"text-3xl font-heading md:text-4xl lg:text-5xl\",\n dark ? \"text-white\" : \"text-foreground\",\n headingClamp,\n )}\n style={headingStyle}\n >\n {heading}\n </h1>\n )}\n <HeroCTA\n buttonLabel={buttonLabel}\n buttonHref={buttonHref}\n textLinkLabel={textLinkLabel}\n textLinkHref={textLinkHref}\n dark={dark}\n />\n </div>\n );\n}\n\n/* ─── Shared layout prop types ─── */\n\ntype HeroLayoutProps = HeroProps & {\n dark: boolean;\n themeClasses: string;\n align: HeroTextAlign;\n};\n\n/* ─── Layout: Minimal ─── */\n\nfunction HeroMinimal({\n preheader,\n heading,\n buttonLabel,\n buttonHref,\n textLinkLabel,\n textLinkHref,\n dark,\n themeClasses,\n className,\n}: HeroLayoutProps) {\n return (\n <section\n className={cn(\"px-8 py-16 md:py-24 lg:py-32\", themeClasses || \"bg-background\", className)}\n >\n <div className=\"mx-auto flex max-w-4xl flex-col items-center text-center\">\n {preheader && (\n <p\n className={cn(\n \"mb-2 text-sm uppercase tracking-widest\",\n dark ? \"text-white/70\" : \"text-muted-foreground\",\n )}\n >\n {preheader}\n </p>\n )}\n {heading && (\n <h1\n className={cn(\n \"max-w-prose text-3xl font-heading line-clamp-3 md:text-5xl lg:text-6xl\",\n dark ? \"text-white\" : \"text-foreground\",\n )}\n style={headingStyle}\n >\n {heading}\n </h1>\n )}\n <HeroCTA\n buttonLabel={buttonLabel}\n buttonHref={buttonHref}\n textLinkLabel={textLinkLabel}\n textLinkHref={textLinkHref}\n dark={dark}\n />\n </div>\n </section>\n );\n}\n\n/* ─── Layout: Banner ─── */\n\nfunction HeroBanner({\n image,\n preheader,\n heading,\n buttonLabel,\n buttonHref,\n textLinkLabel,\n textLinkHref,\n themeClasses,\n className,\n}: HeroLayoutProps) {\n return (\n <section\n className={cn(\n \"relative max-h-64 overflow-hidden\",\n image?.src ? \"bg-muted\" : \"bg-primary\",\n themeClasses,\n className,\n )}\n >\n {image?.src && (\n <img\n src={image?.src}\n alt={image?.alt ?? \"\"}\n className=\"size-full object-cover\"\n loading=\"lazy\"\n />\n )}\n <div className=\"absolute inset-0\" style={overlayGradientStyle(\"to right\")} />\n <div className=\"absolute inset-0 flex items-center px-8 md:px-12 lg:px-16\">\n <div className=\"flex w-full min-w-0 flex-wrap items-center justify-between gap-4\">\n <div className=\"flex min-w-0 items-center gap-4\">\n {preheader && (\n <span className=\"shrink-0 text-sm uppercase tracking-widest text-white/70\">\n {preheader}\n </span>\n )}\n {heading && (\n <h2\n className=\"min-w-0 truncate text-xl font-heading text-white md:text-2xl lg:text-3xl\"\n style={headingStyle}\n >\n {heading}\n </h2>\n )}\n </div>\n <HeroCTA\n buttonLabel={buttonLabel}\n buttonHref={buttonHref}\n textLinkLabel={textLinkLabel}\n textLinkHref={textLinkHref}\n dark\n />\n </div>\n </div>\n </section>\n );\n}\n\n/* ─── Layout: Split ─── */\n\nfunction HeroSplit({\n image,\n aspectRatio = \"16:9\",\n preheader,\n heading,\n buttonLabel,\n buttonHref,\n textLinkLabel,\n textLinkHref,\n contentWidth = \"md\",\n dark,\n themeClasses,\n align,\n className,\n}: HeroLayoutProps) {\n const hasImage = Boolean(image?.src);\n return (\n <section className={cn(\"grid\", hasImage && \"lg:grid-cols-2\", themeClasses, className)}>\n <div className=\"flex min-w-0 items-center px-8 py-12 lg:px-16 lg:py-20\">\n <HeroTextBlock\n preheader={preheader}\n heading={heading}\n buttonLabel={buttonLabel}\n buttonHref={buttonHref}\n textLinkLabel={textLinkLabel}\n textLinkHref={textLinkHref}\n contentWidth={contentWidth}\n dark={dark}\n align={align}\n headingClamp=\"line-clamp-4\"\n />\n </div>\n {hasImage && (\n <div className={cn(\"relative overflow-hidden bg-muted\", aspectClasses[aspectRatio])}>\n <img\n src={image?.src}\n alt={image?.alt ?? \"\"}\n className=\"size-full object-cover\"\n loading=\"lazy\"\n />\n </div>\n )}\n </section>\n );\n}\n\n/* ─── Layout: Image only ─── */\n\nfunction HeroImageOnly({ image, aspectRatio = \"16:9\", className }: HeroLayoutProps) {\n return (\n <section\n className={cn(\"relative overflow-hidden bg-muted\", aspectClasses[aspectRatio], className)}\n >\n {image?.src && (\n <img\n src={image?.src}\n alt={image?.alt ?? \"\"}\n className=\"size-full object-cover\"\n loading=\"lazy\"\n />\n )}\n </section>\n );\n}\n\n/* ─── Overlay background helper ─── */\n\nfunction resolveOverlayGradient(position: HeroContentPosition): React.CSSProperties {\n const direction = getGradientDirection(position);\n return direction ? overlayGradientStyle(direction) : centerOverlayStyle;\n}\n\nfunction resolveOverlayBg(imageSrc?: string): string {\n return imageSrc ? \"bg-muted\" : \"bg-primary\";\n}\n\n/* ─── Layout: Overlay ─── */\n\nfunction HeroOverlay({\n image,\n aspectRatio = \"16:9\",\n contentPosition = \"bottom-center\",\n contentWidth = \"md\",\n preheader,\n heading,\n buttonLabel,\n buttonHref,\n textLinkLabel,\n textLinkHref,\n dark,\n themeClasses,\n align,\n className,\n}: HeroLayoutProps) {\n const hasContent = preheader || heading || buttonLabel || textLinkLabel;\n const position = contentPosition ?? \"bottom-center\";\n\n return (\n <section\n className={cn(\n \"relative overflow-hidden\",\n resolveOverlayBg(image?.src),\n aspectClasses[aspectRatio],\n themeClasses,\n className,\n )}\n >\n {image?.src && (\n <img\n src={image?.src}\n alt={image?.alt ?? \"\"}\n className=\"size-full object-cover\"\n loading=\"lazy\"\n />\n )}\n <div className=\"absolute inset-0\" style={resolveOverlayGradient(position)} />\n {hasContent && (\n <div className={getPositionClasses(position)}>\n <HeroTextBlock\n preheader={preheader}\n heading={heading}\n buttonLabel={buttonLabel}\n buttonHref={buttonHref}\n textLinkLabel={textLinkLabel}\n textLinkHref={textLinkHref}\n contentWidth={contentWidth}\n dark={dark}\n align={align}\n headingClamp=\"line-clamp-3\"\n />\n </div>\n )}\n </section>\n );\n}\n\n/* ─── Main component (dispatcher) ─── */\n\nfunction Hero(props: HeroProps) {\n const heroDefault = useVariantDefault(\"hero\");\n const {\n layout = heroDefault ?? \"overlay\",\n contentPosition = \"bottom-center\",\n textAlign,\n colorTheme,\n } = props;\n\n const dark = isThemeDark(colorTheme) || layout === \"overlay\";\n const themeClasses = colorThemeClasses(colorTheme);\n const defaultAlign: HeroTextAlign =\n layout === \"overlay\" ? getTextAlign(contentPosition ?? \"bottom-center\") : \"left\";\n const align = textAlign ?? defaultAlign;\n\n const layoutProps: HeroLayoutProps = {\n ...props,\n dark,\n themeClasses,\n align,\n };\n\n switch (layout) {\n case \"minimal\":\n return <HeroMinimal {...layoutProps} />;\n case \"banner\":\n return <HeroBanner {...layoutProps} />;\n case \"split\":\n return <HeroSplit {...layoutProps} />;\n case \"image-only\":\n return <HeroImageOnly {...layoutProps} />;\n default:\n return <HeroOverlay {...layoutProps} />;\n }\n}\n\nexport { Hero, type HeroProps };\n"],"mappings":"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"}
1
+ {"version":3,"file":"hero.mjs","names":[],"sources":["../../../../src/client/storefront/blocks/hero.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../ui/utils\";\nimport { defineSlotRecipe } from \"../../ui-resolver/recipe\";\nimport { useVariantDefault } from \"../../ui-resolver/context\";\nimport { BlockHeading } from \"../primitives/block-heading\";\nimport { CTAGroup } from \"../primitives/cta-group\";\nimport {\n colorThemeClasses,\n isThemeDark,\n type HeroProps,\n type HeroContentPosition,\n type HeroTextAlign,\n} from \"../types\";\n\n/* ─── Recipe ─── */\n\nconst heroRecipe = defineSlotRecipe({\n slots: [\"root\", \"background\", \"overlay\", \"content\"] as const,\n base: {\n root: \"\",\n background: \"size-full object-cover\",\n overlay: \"absolute inset-0\",\n content: \"\",\n },\n variants: {\n layout: {\n overlay: {\n root: \"relative overflow-hidden\",\n },\n split: {\n root: \"grid\",\n },\n minimal: {\n root: \"px-[var(--enad-hero-px,2rem)] py-[var(--enad-hero-py,4rem)] md:py-[calc(var(--enad-hero-py,4rem)*1.5)] lg:py-[calc(var(--enad-hero-py,4rem)*2)]\",\n },\n banner: {\n root: \"relative max-h-64 overflow-hidden\",\n },\n \"image-only\": {\n root: \"relative overflow-hidden bg-muted\",\n },\n },\n contentWidth: {\n sm: { content: \"max-w-sm\" },\n md: { content: \"max-w-xl\" },\n lg: { content: \"max-w-3xl\" },\n },\n },\n defaultVariants: {\n layout: \"overlay\",\n contentWidth: \"md\",\n },\n});\n\n/* ─── Aspect ratio map ─── */\n\nconst aspectClasses: Record<string, string> = {\n \"9:16\": \"aspect-[9/16]\",\n \"4:5\": \"aspect-[4/5]\",\n \"1:1\": \"aspect-square\",\n \"16:9\": \"aspect-video\",\n};\n\n/* ─── Overlay gradient ─── */\n\nconst overlayGradientStyle = (direction: string): React.CSSProperties => ({\n background: `linear-gradient(${direction}, color-mix(in oklch, var(--enad-overlay-color) calc(var(--enad-overlay-from-opacity) * 100%), transparent), color-mix(in oklch, var(--enad-overlay-color) calc(var(--enad-overlay-to-opacity) * 100%), transparent))`,\n});\n\nconst centerOverlayStyle: React.CSSProperties = {\n background: \"color-mix(in oklch, var(--enad-overlay-color) 30%, transparent)\",\n};\n\n/* ─── Position helpers ─── */\n\nconst alignItemsMap: Record<string, string> = {\n top: \"items-start\",\n center: \"items-center\",\n bottom: \"items-end\",\n};\n\nconst justifyMap: Record<string, string> = {\n left: \"justify-start\",\n center: \"justify-center\",\n right: \"justify-end\",\n};\n\nfunction getPositionClasses(position: HeroContentPosition): string {\n const [vertical, horizontal] = position.split(\"-\") as [string, string];\n return cn(\n \"absolute inset-0 flex p-8 md:p-12 lg:p-16\",\n alignItemsMap[vertical],\n justifyMap[horizontal],\n );\n}\n\nfunction getTextAlign(position: HeroContentPosition): \"left\" | \"center\" | \"right\" {\n const horizontal = position.split(\"-\")[1];\n if (horizontal === \"center\") return \"center\";\n if (horizontal === \"right\") return \"right\";\n return \"left\";\n}\n\nfunction getGradientDirection(position: HeroContentPosition): string | null {\n const [vertical, horizontal] = position.split(\"-\") as [string, string];\n if (vertical === \"bottom\") return \"to top\";\n if (vertical === \"top\") return \"to bottom\";\n if (horizontal === \"left\") return \"to right\";\n if (horizontal === \"right\") return \"to left\";\n return null;\n}\n\n/* ─── Layout prop types ─── */\n\ntype HeroLayoutProps = HeroProps & {\n dark: boolean;\n themeClasses: string;\n align: HeroTextAlign;\n};\n\n/* ─── Layout: WithImage (overlay + split) ─── */\n\nfunction HeroWithImage({\n layout,\n image,\n aspectRatio = \"16:9\",\n contentPosition = \"bottom-center\",\n contentWidth = \"md\",\n preheader,\n heading,\n buttonLabel,\n buttonHref,\n textLinkLabel,\n textLinkHref,\n dark,\n themeClasses,\n align,\n className,\n}: HeroLayoutProps) {\n const classes = heroRecipe({ layout, contentWidth });\n const hasImage = Boolean(image?.src);\n const hasContent = preheader || heading || buttonLabel || textLinkLabel;\n const position = contentPosition ?? \"bottom-center\";\n\n if (layout === \"split\") {\n return (\n <section className={cn(classes.root, hasImage && \"lg:grid-cols-2\", themeClasses, className)}>\n <div className=\"flex min-w-0 flex-col justify-center px-8 py-12 lg:px-16 lg:py-20\">\n <BlockHeading\n preheader={preheader}\n heading={heading}\n dark={dark}\n align={align}\n headingTag=\"h1\"\n headingSize=\"lg\"\n headingClamp=\"line-clamp-4\"\n className={classes.content}\n />\n <CTAGroup\n buttonLabel={buttonLabel}\n buttonHref={buttonHref}\n textLinkLabel={textLinkLabel}\n textLinkHref={textLinkHref}\n dark={dark}\n />\n </div>\n {hasImage && (\n <div className={cn(\"relative overflow-hidden bg-muted\", aspectClasses[aspectRatio])}>\n <img\n src={image?.src}\n alt={image?.alt ?? \"\"}\n className={classes.background}\n loading=\"lazy\"\n />\n </div>\n )}\n </section>\n );\n }\n\n /* Overlay */\n const gradientDirection = getGradientDirection(position);\n const overlayStyle = gradientDirection\n ? overlayGradientStyle(gradientDirection)\n : centerOverlayStyle;\n\n return (\n <section\n className={cn(\n classes.root,\n hasImage ? \"bg-muted\" : \"bg-primary\",\n aspectClasses[aspectRatio],\n themeClasses,\n className,\n )}\n >\n {hasImage && (\n <img\n src={image?.src}\n alt={image?.alt ?? \"\"}\n className={classes.background}\n loading=\"lazy\"\n />\n )}\n <div className={classes.overlay} style={overlayStyle} />\n {hasContent && (\n <div className={getPositionClasses(position)}>\n <div className={cn(\"flex min-w-0 flex-col\", classes.content)}>\n <BlockHeading\n preheader={preheader}\n heading={heading}\n dark={dark}\n align={align}\n headingTag=\"h1\"\n headingSize=\"lg\"\n headingClamp=\"line-clamp-3\"\n />\n <CTAGroup\n buttonLabel={buttonLabel}\n buttonHref={buttonHref}\n textLinkLabel={textLinkLabel}\n textLinkHref={textLinkHref}\n dark={dark}\n />\n </div>\n </div>\n )}\n </section>\n );\n}\n\n/* ─── Layout: TextOnly (minimal) ─── */\n\nfunction HeroTextOnly({\n preheader,\n heading,\n buttonLabel,\n buttonHref,\n textLinkLabel,\n textLinkHref,\n dark,\n themeClasses,\n className,\n}: HeroLayoutProps) {\n const classes = heroRecipe({ layout: \"minimal\" });\n\n return (\n <section className={cn(classes.root, themeClasses || \"bg-background\", className)}>\n <div className=\"mx-auto flex max-w-4xl flex-col items-center text-center\">\n <BlockHeading\n preheader={preheader}\n heading={heading}\n dark={dark}\n align=\"center\"\n headingTag=\"h1\"\n headingSize=\"xl\"\n headingClamp=\"line-clamp-3\"\n className=\"max-w-prose\"\n />\n <CTAGroup\n buttonLabel={buttonLabel}\n buttonHref={buttonHref}\n textLinkLabel={textLinkLabel}\n textLinkHref={textLinkHref}\n dark={dark}\n />\n </div>\n </section>\n );\n}\n\n/* ─── Layout: Compact (banner) ─── */\n\nfunction HeroCompact({\n image,\n preheader,\n heading,\n buttonLabel,\n buttonHref,\n textLinkLabel,\n textLinkHref,\n themeClasses,\n className,\n}: HeroLayoutProps) {\n const classes = heroRecipe({ layout: \"banner\" });\n\n return (\n <section\n className={cn(classes.root, image?.src ? \"bg-muted\" : \"bg-primary\", themeClasses, className)}\n >\n {image?.src && (\n <img\n src={image?.src}\n alt={image?.alt ?? \"\"}\n className={classes.background}\n loading=\"lazy\"\n />\n )}\n <div className={classes.overlay} style={overlayGradientStyle(\"to right\")} />\n <div className=\"absolute inset-0 flex items-center px-8 md:px-12 lg:px-16\">\n <div className=\"flex w-full min-w-0 flex-wrap items-center justify-between gap-4\">\n <div className=\"flex min-w-0 items-center gap-4\">\n {preheader && (\n <span className=\"shrink-0 text-sm uppercase tracking-widest text-white/70\">\n {preheader}\n </span>\n )}\n {heading && (\n <h2\n className=\"min-w-0 truncate text-xl font-heading text-white md:text-2xl lg:text-3xl\"\n style={\n {\n fontWeight: \"var(--enad-heading-weight)\",\n letterSpacing: \"var(--enad-heading-tracking)\",\n textTransform: \"var(--enad-heading-transform)\",\n } as unknown as React.CSSProperties\n }\n >\n {heading}\n </h2>\n )}\n </div>\n <CTAGroup\n buttonLabel={buttonLabel}\n buttonHref={buttonHref}\n textLinkLabel={textLinkLabel}\n textLinkHref={textLinkHref}\n dark\n />\n </div>\n </div>\n </section>\n );\n}\n\n/* ─── Layout: ImageOnly ─── */\n\nfunction HeroImageOnly({ image, aspectRatio = \"16:9\", className }: HeroLayoutProps) {\n const classes = heroRecipe({ layout: \"image-only\" });\n\n return (\n <section className={cn(classes.root, aspectClasses[aspectRatio], className)}>\n {image?.src && (\n <img\n src={image?.src}\n alt={image?.alt ?? \"\"}\n className={classes.background}\n loading=\"lazy\"\n />\n )}\n </section>\n );\n}\n\n/* ─── Main component (dispatcher) ─── */\n\nfunction Hero(props: HeroProps) {\n const heroDefault = useVariantDefault(\"hero\");\n const {\n layout = heroDefault ?? \"overlay\",\n contentPosition = \"bottom-center\",\n textAlign,\n colorTheme,\n } = props;\n\n const dark = isThemeDark(colorTheme) || layout === \"overlay\";\n const themeClasses = colorThemeClasses(colorTheme);\n const defaultAlign: HeroTextAlign =\n layout === \"overlay\" ? getTextAlign(contentPosition ?? \"bottom-center\") : \"left\";\n const align = textAlign ?? defaultAlign;\n\n const layoutProps: HeroLayoutProps = {\n ...props,\n dark,\n themeClasses,\n align,\n };\n\n switch (layout) {\n case \"minimal\":\n return <HeroTextOnly {...layoutProps} />;\n case \"banner\":\n return <HeroCompact {...layoutProps} />;\n case \"image-only\":\n return <HeroImageOnly {...layoutProps} />;\n case \"split\":\n default:\n return <HeroWithImage {...layoutProps} layout={layout} />;\n }\n}\n\nexport { Hero, heroRecipe, type HeroProps };\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"link-block-small.d.ts","names":[],"sources":["../../../../src/client/storefront/blocks/link-block-small.tsx"],"mappings":";;;;iBAIS,cAAA,CAAA;EACP,KAAA;EACA,KAAA;EACA,IAAA;EACA;AAAA,GACC,mBAAA,GAAmB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"link-block-small.d.ts","names":[],"sources":["../../../../src/client/storefront/blocks/link-block-small.tsx"],"mappings":";;;;iBAIS,cAAA,CAAA;EAAiB,KAAA;EAAO,KAAA;EAAO,IAAA;EAAM;AAAA,GAAa,mBAAA,GAAmB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -9,7 +9,7 @@ function LinkBlockSmall({ image, title, href, className }) {
9
9
  image?.src ? /* @__PURE__ */ jsx("img", {
10
10
  src: image.src,
11
11
  alt: image.alt ?? title ?? "",
12
- className: "size-full object-cover transition-transform duration-[var(--enad-image-hover-duration)] group-hover:scale-[var(--enad-image-hover-scale)]"
12
+ className: "size-full object-cover"
13
13
  }) : /* @__PURE__ */ jsx("div", { className: "size-full bg-muted" }),
14
14
  /* @__PURE__ */ jsx("div", {
15
15
  className: "absolute inset-0",
@@ -1 +1 @@
1
- {"version":3,"file":"link-block-small.mjs","names":[],"sources":["../../../../src/client/storefront/blocks/link-block-small.tsx"],"sourcesContent":["import * as React from \"react\"\nimport { cn } from \"../../ui/utils\"\nimport type { LinkBlockSmallProps } from \"../types\"\n\nfunction LinkBlockSmall({\n image,\n title,\n href,\n className,\n}: LinkBlockSmallProps) {\n const card = (\n <div className={cn(\"enad-interactive group relative aspect-[3/4] overflow-hidden rounded-[var(--enad-card-radius)]\", className)}>\n {image?.src ? (\n <img\n src={image.src}\n alt={image.alt ?? title ?? \"\"}\n className=\"size-full object-cover transition-transform duration-[var(--enad-image-hover-duration)] group-hover:scale-[var(--enad-image-hover-scale)]\"\n />\n ) : (\n <div className=\"size-full bg-muted\" />\n )}\n <div\n className=\"absolute inset-0\"\n style={{ background: \"linear-gradient(to top, color-mix(in oklch, var(--enad-overlay-color) calc(var(--enad-overlay-from-opacity) * 100%), transparent), color-mix(in oklch, var(--enad-overlay-color) calc(var(--enad-overlay-to-opacity) * 100%), transparent))\" }}\n />\n {title && (\n <p className=\"absolute inset-x-0 bottom-0 p-3 text-sm font-medium text-white\">\n {title}\n </p>\n )}\n </div>\n )\n\n if (href) {\n return <a href={href} className=\"block\">{card}</a>\n }\n\n return card\n}\n\nexport { LinkBlockSmall, type LinkBlockSmallProps }\n"],"mappings":";;;;AAIA,SAAS,eAAe,EACtB,OACA,OACA,MACA,aACsB;CACtB,MAAM,OACJ,qBAAC,OAAD;EAAK,WAAW,GAAG,kGAAkG,UAAU;YAA/H;GACG,OAAO,MACN,oBAAC,OAAD;IACE,KAAK,MAAM;IACX,KAAK,MAAM,OAAO,SAAS;IAC3B,WAAU;IACV,CAAA,GAEF,oBAAC,OAAD,EAAK,WAAU,sBAAuB,CAAA;GAExC,oBAAC,OAAD;IACE,WAAU;IACV,OAAO,EAAE,YAAY,+OAA+O;IACpQ,CAAA;GACD,SACC,oBAAC,KAAD;IAAG,WAAU;cACV;IACC,CAAA;GAEF;;AAGR,KAAI,KACF,QAAO,oBAAC,KAAD;EAAS;EAAM,WAAU;YAAS;EAAS,CAAA;AAGpD,QAAO"}
1
+ {"version":3,"file":"link-block-small.mjs","names":[],"sources":["../../../../src/client/storefront/blocks/link-block-small.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../ui/utils\";\nimport type { LinkBlockSmallProps } from \"../types\";\n\nfunction LinkBlockSmall({ image, title, href, className }: LinkBlockSmallProps) {\n const card = (\n <div\n className={cn(\n \"enad-interactive group relative aspect-[3/4] overflow-hidden rounded-[var(--enad-card-radius)]\",\n className,\n )}\n >\n {image?.src ? (\n <img src={image.src} alt={image.alt ?? title ?? \"\"} className=\"size-full object-cover\" />\n ) : (\n <div className=\"size-full bg-muted\" />\n )}\n <div\n className=\"absolute inset-0\"\n style={{\n background:\n \"linear-gradient(to top, color-mix(in oklch, var(--enad-overlay-color) calc(var(--enad-overlay-from-opacity) * 100%), transparent), color-mix(in oklch, var(--enad-overlay-color) calc(var(--enad-overlay-to-opacity) * 100%), transparent))\",\n }}\n />\n {title && (\n <p className=\"absolute inset-x-0 bottom-0 p-3 text-sm font-medium text-white\">{title}</p>\n )}\n </div>\n );\n\n if (href) {\n return (\n <a href={href} className=\"block\">\n {card}\n </a>\n );\n }\n\n return card;\n}\n\nexport { LinkBlockSmall, type LinkBlockSmallProps };\n"],"mappings":";;;;AAIA,SAAS,eAAe,EAAE,OAAO,OAAO,MAAM,aAAkC;CAC9E,MAAM,OACJ,qBAAC,OAAD;EACE,WAAW,GACT,kGACA,UACD;YAJH;GAMG,OAAO,MACN,oBAAC,OAAD;IAAK,KAAK,MAAM;IAAK,KAAK,MAAM,OAAO,SAAS;IAAI,WAAU;IAA2B,CAAA,GAEzF,oBAAC,OAAD,EAAK,WAAU,sBAAuB,CAAA;GAExC,oBAAC,OAAD;IACE,WAAU;IACV,OAAO,EACL,YACE,+OACH;IACD,CAAA;GACD,SACC,oBAAC,KAAD;IAAG,WAAU;cAAkE;IAAU,CAAA;GAEvF;;AAGR,KAAI,KACF,QACE,oBAAC,KAAD;EAAS;EAAM,WAAU;YACtB;EACC,CAAA;AAIR,QAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"link-block.d.ts","names":[],"sources":["../../../../src/client/storefront/blocks/link-block.tsx"],"mappings":";;;;iBAgNS,SAAA,CAAU,KAAA,EAAO,cAAA,GAAc,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"link-block.d.ts","names":[],"sources":["../../../../src/client/storefront/blocks/link-block.tsx"],"mappings":";;;;iBAqPS,SAAA,CAAU,KAAA,EAAO,cAAA,GAAc,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -21,14 +21,14 @@ function CardVariant({ image, eyebrow, title, buttonLabel, buttonHref, dark, the
21
21
  href: buttonHref,
22
22
  radiusClass: "rounded-[var(--enad-card-radius)]",
23
23
  children: /* @__PURE__ */ jsxs("div", {
24
- className: cn("enad-interactive group overflow-hidden rounded-[var(--enad-card-radius)]", "shadow-[var(--enad-card-shadow)] transition-shadow duration-[var(--enad-motion-duration)] hover:shadow-[var(--enad-card-hover-shadow)]", themeClasses || "bg-background", className),
24
+ className: cn("enad-interactive group overflow-hidden rounded-[var(--enad-card-radius)]", "shadow-[var(--enad-card-shadow)]", themeClasses || "bg-background", className),
25
25
  children: [image?.src ? /* @__PURE__ */ jsx("div", {
26
26
  className: "overflow-hidden rounded-t-[var(--enad-image-radius)] bg-muted",
27
27
  children: /* @__PURE__ */ jsx("img", {
28
28
  src: image.src,
29
29
  alt: image.alt ?? title ?? "",
30
30
  loading: "lazy",
31
- className: "aspect-[3/2] w-full object-cover transition-transform duration-[var(--enad-image-hover-duration)] group-hover:scale-[var(--enad-image-hover-scale)]"
31
+ className: "aspect-[3/2] w-full object-cover"
32
32
  })
33
33
  }) : /* @__PURE__ */ jsx("div", {
34
34
  className: "aspect-[3/2] w-full bg-muted",
@@ -59,7 +59,7 @@ function TextOnlyVariant({ eyebrow, title, buttonLabel, buttonHref, dark, themeC
59
59
  href: buttonHref,
60
60
  radiusClass: "rounded-[var(--enad-card-radius)]",
61
61
  children: /* @__PURE__ */ jsxs("div", {
62
- className: cn("enad-interactive group rounded-[var(--enad-card-radius)] border transition-colors duration-[var(--enad-motion-duration)]", "border-[length:var(--enad-border-width)] px-6 py-5", dark ? "border-white/20 hover:bg-white/10" : "border-border hover:bg-accent", themeClasses, className),
62
+ className: cn("rounded-[var(--enad-card-radius)] border transition-colors duration-[var(--enad-motion-duration)]", "border-[length:var(--enad-border-width)] px-6 py-5", dark ? "border-white/20 hover:bg-white/10" : "border-border hover:bg-accent", themeClasses, className),
63
63
  children: [
64
64
  eyebrow && /* @__PURE__ */ jsx("p", {
65
65
  className: cn("mb-1 text-sm uppercase tracking-widest", dark ? "text-white/70" : "text-muted-foreground"),
@@ -88,7 +88,7 @@ function OverlayVariant({ image, eyebrow, title, buttonLabel, buttonHref, classN
88
88
  src: image.src,
89
89
  alt: image.alt ?? title ?? "",
90
90
  loading: "lazy",
91
- className: "size-full object-cover transition-transform duration-[var(--enad-image-hover-duration)] group-hover:scale-[var(--enad-image-hover-scale)]"
91
+ className: "size-full object-cover"
92
92
  }) : /* @__PURE__ */ jsx("div", {
93
93
  className: "size-full bg-primary",
94
94
  "aria-hidden": "true"
@@ -1 +1 @@
1
- {"version":3,"file":"link-block.mjs","names":[],"sources":["../../../../src/client/storefront/blocks/link-block.tsx"],"sourcesContent":["import * as React from \"react\"\nimport { cn } from \"../../ui/utils\"\nimport { colorThemeClasses, isThemeDark, type LinkBlockProps } from \"../types\"\n\n/* ─── Shared types ─── */\n\ntype VariantProps = LinkBlockProps & {\n dark: boolean\n themeClasses: string\n}\n\nconst headingStyle = { fontWeight: \"var(--enad-heading-weight)\", letterSpacing: \"var(--enad-heading-tracking)\", textTransform: \"var(--enad-heading-transform)\" } as unknown as React.CSSProperties\n\n/* ─── Shared link wrapper ─── */\n\nfunction OptionalLink({\n href,\n radiusClass,\n children,\n}: {\n href?: string\n radiusClass?: string\n children: React.ReactNode\n}) {\n if (!href) return children\n return (\n <a\n href={href}\n className={cn(\"block focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\", radiusClass)}\n >\n {children}\n </a>\n )\n}\n\n/* ─── Card variant ─── */\n\nfunction CardVariant({\n image,\n eyebrow,\n title,\n buttonLabel,\n buttonHref,\n dark,\n themeClasses,\n className,\n}: VariantProps) {\n const content = (\n <div\n className={cn(\n \"enad-interactive group overflow-hidden rounded-[var(--enad-card-radius)]\",\n \"shadow-[var(--enad-card-shadow)] transition-shadow duration-[var(--enad-motion-duration)] hover:shadow-[var(--enad-card-hover-shadow)]\",\n themeClasses || \"bg-background\",\n className,\n )}\n >\n {/* Image top */}\n {image?.src ? (\n <div className=\"overflow-hidden rounded-t-[var(--enad-image-radius)] bg-muted\">\n <img\n src={image.src}\n alt={image.alt ?? title ?? \"\"}\n loading=\"lazy\"\n className=\"aspect-[3/2] w-full object-cover transition-transform duration-[var(--enad-image-hover-duration)] group-hover:scale-[var(--enad-image-hover-scale)]\"\n />\n </div>\n ) : (\n <div className=\"aspect-[3/2] w-full bg-muted\" aria-hidden=\"true\" />\n )}\n\n {/* Text content below */}\n <div className=\"min-w-0 p-6\">\n {eyebrow && (\n <p className={cn(\"mb-1 text-sm uppercase tracking-widest\", dark ? \"text-white/70\" : \"text-muted-foreground\")}>\n {eyebrow}\n </p>\n )}\n {title && (\n <h3\n className={cn(\"line-clamp-2 text-xl font-heading\", dark ? \"text-white\" : \"text-foreground\")}\n style={headingStyle}\n >\n {title}\n </h3>\n )}\n {buttonLabel && (\n <span className={cn(\"mt-3 inline-block text-sm font-medium line-clamp-3\", dark ? \"text-white/80\" : \"text-foreground\")}>\n {buttonLabel}\n </span>\n )}\n </div>\n </div>\n )\n\n return (\n <OptionalLink href={buttonHref} radiusClass=\"rounded-[var(--enad-card-radius)]\">\n {content}\n </OptionalLink>\n )\n}\n\n/* ─── Text-only variant ─── */\n\nfunction TextOnlyVariant({\n eyebrow,\n title,\n buttonLabel,\n buttonHref,\n dark,\n themeClasses,\n className,\n}: VariantProps) {\n const content = (\n <div\n className={cn(\n \"enad-interactive group rounded-[var(--enad-card-radius)] border transition-colors duration-[var(--enad-motion-duration)]\",\n \"border-[length:var(--enad-border-width)] px-6 py-5\",\n dark\n ? \"border-white/20 hover:bg-white/10\"\n : \"border-border hover:bg-accent\",\n themeClasses,\n className,\n )}\n >\n {eyebrow && (\n <p className={cn(\"mb-1 text-sm uppercase tracking-widest\", dark ? \"text-white/70\" : \"text-muted-foreground\")}>\n {eyebrow}\n </p>\n )}\n {title && (\n <h3\n className={cn(\"truncate text-lg font-heading\", dark ? \"text-white\" : \"text-foreground\")}\n style={headingStyle}\n >\n {title}\n </h3>\n )}\n {buttonLabel && (\n <span className={cn(\"mt-2 inline-block text-sm font-medium\", dark ? \"text-white/80\" : \"text-muted-foreground\")}>\n {buttonLabel}\n </span>\n )}\n </div>\n )\n\n return (\n <OptionalLink href={buttonHref} radiusClass=\"rounded-[var(--enad-card-radius)]\">\n {content}\n </OptionalLink>\n )\n}\n\n/* ─── Overlay variant (default) ─── */\n\nfunction OverlayVariant({\n image,\n eyebrow,\n title,\n buttonLabel,\n buttonHref,\n className,\n}: VariantProps) {\n const content = (\n <div className={cn(\"enad-interactive group relative aspect-[3/4] overflow-hidden md:aspect-[2/1]\", className)}>\n {/* Background image */}\n {image?.src ? (\n <img\n src={image.src}\n alt={image.alt ?? title ?? \"\"}\n loading=\"lazy\"\n className=\"size-full object-cover transition-transform duration-[var(--enad-image-hover-duration)] group-hover:scale-[var(--enad-image-hover-scale)]\"\n />\n ) : (\n <div className=\"size-full bg-primary\" aria-hidden=\"true\" />\n )}\n\n {/* Gradient overlay */}\n <div\n className=\"absolute inset-0\"\n style={{ background: \"linear-gradient(to top, color-mix(in oklch, var(--enad-overlay-color) calc(var(--enad-overlay-from-opacity) * 100%), transparent), color-mix(in oklch, var(--enad-overlay-color) calc(var(--enad-overlay-to-opacity) * 100%), transparent))\" }}\n />\n\n {/* Text content */}\n <div className=\"absolute inset-x-0 bottom-0 min-w-0 p-6 md:p-8\">\n {eyebrow && (\n <p className=\"mb-1 text-sm uppercase tracking-widest text-white/70\">\n {eyebrow}\n </p>\n )}\n {title && (\n <h3 className=\"line-clamp-2 text-xl font-heading text-white md:text-2xl\" style={headingStyle}>\n {title}\n </h3>\n )}\n {buttonLabel && (\n <span className=\"mt-3 inline-block border-b border-white/50 pb-0.5 text-sm text-white transition-colors group-hover:border-white\">\n {buttonLabel}\n </span>\n )}\n </div>\n </div>\n )\n\n return <OptionalLink href={buttonHref}>{content}</OptionalLink>\n}\n\n/* ─── Main component (dispatcher) ─── */\n\nfunction LinkBlock(props: LinkBlockProps) {\n const dark = isThemeDark(props.colorTheme)\n const themeClasses = colorThemeClasses(props.colorTheme)\n const variantProps: VariantProps = { ...props, dark, themeClasses }\n\n switch (props.variant ?? \"overlay\") {\n case \"card\":\n return <CardVariant {...variantProps} />\n case \"text-only\":\n return <TextOnlyVariant {...variantProps} />\n default:\n return <OverlayVariant {...variantProps} />\n }\n}\n\nexport { LinkBlock, type LinkBlockProps }\n"],"mappings":"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"}
1
+ {"version":3,"file":"link-block.mjs","names":[],"sources":["../../../../src/client/storefront/blocks/link-block.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../ui/utils\";\nimport { colorThemeClasses, isThemeDark, type LinkBlockProps } from \"../types\";\n\n/* ─── Shared types ─── */\n\ntype VariantProps = LinkBlockProps & {\n dark: boolean;\n themeClasses: string;\n};\n\nconst headingStyle = {\n fontWeight: \"var(--enad-heading-weight)\",\n letterSpacing: \"var(--enad-heading-tracking)\",\n textTransform: \"var(--enad-heading-transform)\",\n} as unknown as React.CSSProperties;\n\n/* ─── Shared link wrapper ─── */\n\nfunction OptionalLink({\n href,\n radiusClass,\n children,\n}: {\n href?: string;\n radiusClass?: string;\n children: React.ReactNode;\n}) {\n if (!href) return children;\n return (\n <a\n href={href}\n className={cn(\n \"block focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n radiusClass,\n )}\n >\n {children}\n </a>\n );\n}\n\n/* ─── Card variant ─── */\n\nfunction CardVariant({\n image,\n eyebrow,\n title,\n buttonLabel,\n buttonHref,\n dark,\n themeClasses,\n className,\n}: VariantProps) {\n const content = (\n <div\n className={cn(\n \"enad-interactive group overflow-hidden rounded-[var(--enad-card-radius)]\",\n \"shadow-[var(--enad-card-shadow)]\",\n themeClasses || \"bg-background\",\n className,\n )}\n >\n {/* Image top */}\n {image?.src ? (\n <div className=\"overflow-hidden rounded-t-[var(--enad-image-radius)] bg-muted\">\n <img\n src={image.src}\n alt={image.alt ?? title ?? \"\"}\n loading=\"lazy\"\n className=\"aspect-[3/2] w-full object-cover\"\n />\n </div>\n ) : (\n <div className=\"aspect-[3/2] w-full bg-muted\" aria-hidden=\"true\" />\n )}\n\n {/* Text content below */}\n <div className=\"min-w-0 p-6\">\n {eyebrow && (\n <p\n className={cn(\n \"mb-1 text-sm uppercase tracking-widest\",\n dark ? \"text-white/70\" : \"text-muted-foreground\",\n )}\n >\n {eyebrow}\n </p>\n )}\n {title && (\n <h3\n className={cn(\n \"line-clamp-2 text-xl font-heading\",\n dark ? \"text-white\" : \"text-foreground\",\n )}\n style={headingStyle}\n >\n {title}\n </h3>\n )}\n {buttonLabel && (\n <span\n className={cn(\n \"mt-3 inline-block text-sm font-medium line-clamp-3\",\n dark ? \"text-white/80\" : \"text-foreground\",\n )}\n >\n {buttonLabel}\n </span>\n )}\n </div>\n </div>\n );\n\n return (\n <OptionalLink href={buttonHref} radiusClass=\"rounded-[var(--enad-card-radius)]\">\n {content}\n </OptionalLink>\n );\n}\n\n/* ─── Text-only variant ─── */\n\nfunction TextOnlyVariant({\n eyebrow,\n title,\n buttonLabel,\n buttonHref,\n dark,\n themeClasses,\n className,\n}: VariantProps) {\n const content = (\n <div\n className={cn(\n \"rounded-[var(--enad-card-radius)] border transition-colors duration-[var(--enad-motion-duration)]\",\n \"border-[length:var(--enad-border-width)] px-6 py-5\",\n dark ? \"border-white/20 hover:bg-white/10\" : \"border-border hover:bg-accent\",\n themeClasses,\n className,\n )}\n >\n {eyebrow && (\n <p\n className={cn(\n \"mb-1 text-sm uppercase tracking-widest\",\n dark ? \"text-white/70\" : \"text-muted-foreground\",\n )}\n >\n {eyebrow}\n </p>\n )}\n {title && (\n <h3\n className={cn(\"truncate text-lg font-heading\", dark ? \"text-white\" : \"text-foreground\")}\n style={headingStyle}\n >\n {title}\n </h3>\n )}\n {buttonLabel && (\n <span\n className={cn(\n \"mt-2 inline-block text-sm font-medium\",\n dark ? \"text-white/80\" : \"text-muted-foreground\",\n )}\n >\n {buttonLabel}\n </span>\n )}\n </div>\n );\n\n return (\n <OptionalLink href={buttonHref} radiusClass=\"rounded-[var(--enad-card-radius)]\">\n {content}\n </OptionalLink>\n );\n}\n\n/* ─── Overlay variant (default) ─── */\n\nfunction OverlayVariant({\n image,\n eyebrow,\n title,\n buttonLabel,\n buttonHref,\n className,\n}: VariantProps) {\n const content = (\n <div\n className={cn(\n \"enad-interactive group relative aspect-[3/4] overflow-hidden md:aspect-[2/1]\",\n className,\n )}\n >\n {/* Background image */}\n {image?.src ? (\n <img\n src={image.src}\n alt={image.alt ?? title ?? \"\"}\n loading=\"lazy\"\n className=\"size-full object-cover\"\n />\n ) : (\n <div className=\"size-full bg-primary\" aria-hidden=\"true\" />\n )}\n\n {/* Gradient overlay */}\n <div\n className=\"absolute inset-0\"\n style={{\n background:\n \"linear-gradient(to top, color-mix(in oklch, var(--enad-overlay-color) calc(var(--enad-overlay-from-opacity) * 100%), transparent), color-mix(in oklch, var(--enad-overlay-color) calc(var(--enad-overlay-to-opacity) * 100%), transparent))\",\n }}\n />\n\n {/* Text content */}\n <div className=\"absolute inset-x-0 bottom-0 min-w-0 p-6 md:p-8\">\n {eyebrow && (\n <p className=\"mb-1 text-sm uppercase tracking-widest text-white/70\">{eyebrow}</p>\n )}\n {title && (\n <h3\n className=\"line-clamp-2 text-xl font-heading text-white md:text-2xl\"\n style={headingStyle}\n >\n {title}\n </h3>\n )}\n {buttonLabel && (\n <span className=\"mt-3 inline-block border-b border-white/50 pb-0.5 text-sm text-white transition-colors group-hover:border-white\">\n {buttonLabel}\n </span>\n )}\n </div>\n </div>\n );\n\n return <OptionalLink href={buttonHref}>{content}</OptionalLink>;\n}\n\n/* ─── Main component (dispatcher) ─── */\n\nfunction LinkBlock(props: LinkBlockProps) {\n const dark = isThemeDark(props.colorTheme);\n const themeClasses = colorThemeClasses(props.colorTheme);\n const variantProps: VariantProps = { ...props, dark, themeClasses };\n\n switch (props.variant ?? \"overlay\") {\n case \"card\":\n return <CardVariant {...variantProps} />;\n case \"text-only\":\n return <TextOnlyVariant {...variantProps} />;\n default:\n return <OverlayVariant {...variantProps} />;\n }\n}\n\nexport { LinkBlock, type LinkBlockProps };\n"],"mappings":"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"}
@@ -4,7 +4,7 @@ import * as react_jsx_runtime0 from "react/jsx-runtime";
4
4
  //#region src/client/storefront/blocks/product-card-parts.d.ts
5
5
  /**
6
6
  * Root container for a composable product card.
7
- * Provides group context for hover effects and overflow handling.
7
+ * Provides grouping and overflow handling for composed layouts.
8
8
  */
9
9
  declare function ProductCardRoot({
10
10
  className,
@@ -1 +1 @@
1
- {"version":3,"file":"product-card-parts.d.ts","names":[],"sources":["../../../../src/client/storefront/blocks/product-card-parts.tsx"],"mappings":";;;;;;;AAE+B;iBAStB,eAAA,CAAA;EAAkB,SAAA;EAAA,GAAc;AAAA,GAAS,OAAA,CAAM,cAAA,UAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;;iBAiBpE,oBAAA,CAAA;EAAuB,SAAA;EAAA,GAAc;AAAA,GAAS,OAAA,CAAM,cAAA,UAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;iBAazE,gBAAA,CAAA;EACP,SAAA;EACA,GAAA;EACA,OAAA;EAAA,GACG;AAAA,GACF,OAAA,CAAM,cAAA,UAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;;iBAgBrB,cAAA,CAAA;EAAiB,SAAA;EAAA,GAAc;AAAA,GAAS,OAAA,CAAM,cAAA,WAAsB,kBAAA,CAAA,GAAA,CAAA,OAAA;;AAnDA;;;iBAoEpE,yBAAA,CAAA;EACP,SAAA;EACA,OAAA;EAAA,GACG;AAAA,GACF,OAAA,CAAM,cAAA,aAAwB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;iBAuBxB,kBAAA,CAAA;EAAqB,SAAA;EAAA,GAAc;AAAA,GAAS,OAAA,CAAM,cAAA,UAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;iBAavE,gBAAA,CAAA;EAAmB,SAAA;EAAA,GAAc;AAAA,GAAS,OAAA,CAAM,cAAA,QAAmB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;iBAanE,mBAAA,CAAA;EAAsB,SAAA;EAAA,GAAc;AAAA,GAAS,OAAA,CAAM,cAAA,QAAmB,kBAAA,CAAA,GAAA,CAAA,OAAA;;AAxGG;;iBAqHzE,gBAAA,CAAA;EAAmB,SAAA;EAAA,GAAc;AAAA,GAAS,OAAA,CAAM,cAAA,WAAsB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"product-card-parts.d.ts","names":[],"sources":["../../../../src/client/storefront/blocks/product-card-parts.tsx"],"mappings":";;;;;;;AAE+B;iBAStB,eAAA,CAAA;EAAkB,SAAA;EAAA,GAAc;AAAA,GAAS,OAAA,CAAM,cAAA,UAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;;iBAcpE,oBAAA,CAAA;EAAuB,SAAA;EAAA,GAAc;AAAA,GAAS,OAAA,CAAM,cAAA,UAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;iBAazE,gBAAA,CAAA;EACP,SAAA;EACA,GAAA;EACA,OAAA;EAAA,GACG;AAAA,GACF,OAAA,CAAM,cAAA,UAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;;iBAgBrB,cAAA,CAAA;EAAiB,SAAA;EAAA,GAAc;AAAA,GAAS,OAAA,CAAM,cAAA,WAAsB,kBAAA,CAAA,GAAA,CAAA,OAAA;;AAhDA;;;iBAiEpE,yBAAA,CAAA;EACP,SAAA;EACA,OAAA;EAAA,GACG;AAAA,GACF,OAAA,CAAM,cAAA,aAAwB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;iBAuBxB,kBAAA,CAAA;EAAqB,SAAA;EAAA,GAAc;AAAA,GAAS,OAAA,CAAM,cAAA,UAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;iBAavE,gBAAA,CAAA;EAAmB,SAAA;EAAA,GAAc;AAAA,GAAS,OAAA,CAAM,cAAA,QAAmB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;iBAanE,mBAAA,CAAA;EAAsB,SAAA;EAAA,GAAc;AAAA,GAAS,OAAA,CAAM,cAAA,QAAmB,kBAAA,CAAA,GAAA,CAAA,OAAA;;AAxGG;;iBAqHzE,gBAAA,CAAA;EAAmB,SAAA;EAAA,GAAc;AAAA,GAAS,OAAA,CAAM,cAAA,WAAsB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -5,12 +5,12 @@ import { jsx } from "react/jsx-runtime";
5
5
  //#region src/client/storefront/blocks/product-card-parts.tsx
6
6
  /**
7
7
  * Root container for a composable product card.
8
- * Provides group context for hover effects and overflow handling.
8
+ * Provides grouping and overflow handling for composed layouts.
9
9
  */
10
10
  function ProductCardRoot({ className, ...props }) {
11
11
  return /* @__PURE__ */ jsx("div", {
12
12
  "data-slot": "product-card",
13
- className: cn("enad-interactive group overflow-hidden rounded-[var(--enad-card-radius)]", className),
13
+ className: cn("group overflow-hidden rounded-[var(--enad-card-radius)]", className),
14
14
  ...props
15
15
  });
16
16
  }