@propeller-commerce/propeller-v2-react-ui 0.27.0 → 0.28.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/dist/index.cjs CHANGED
@@ -41,6 +41,9 @@ function PropellerProvider({ value, children }) {
41
41
  function usePropellerDeps() {
42
42
  return React6.useContext(PropellerDepsContext);
43
43
  }
44
+ function useImgComponent() {
45
+ return React6.useContext(PropellerDepsContext)?.imgComponent;
46
+ }
44
47
  function useRequiredPropellerDeps() {
45
48
  const deps = React6.useContext(PropellerDepsContext);
46
49
  if (!deps) {
@@ -4696,8 +4699,25 @@ function ActionCode(rawProps) {
4696
4699
  ] });
4697
4700
  }
4698
4701
  var ActionCode_default = ActionCode;
4702
+ function PropellerImg({ as: Injected, ...props }) {
4703
+ if (Injected) return /* @__PURE__ */ jsxRuntime.jsx(Injected, { ...props });
4704
+ const { src, alt, className, width, height, loading, onClick } = props;
4705
+ return /* @__PURE__ */ jsxRuntime.jsx(
4706
+ "img",
4707
+ {
4708
+ src,
4709
+ alt,
4710
+ className,
4711
+ width,
4712
+ height,
4713
+ loading,
4714
+ onClick
4715
+ }
4716
+ );
4717
+ }
4699
4718
  function CartBonusItems(rawProps) {
4700
4719
  const props = useInfraProps(rawProps);
4720
+ const Img = useImgComponent();
4701
4721
  const items = props.bonusItems ?? props.cart?.bonusItems ?? [];
4702
4722
  if (items.length === 0) return null;
4703
4723
  const currency = props.currency ?? "\u20AC";
@@ -4715,20 +4735,21 @@ function CartBonusItems(rawProps) {
4715
4735
  {
4716
4736
  className: "propeller-cart-bonus-item flex items-center gap-4 bg-card p-4 rounded-container shadow-sm border border-border",
4717
4737
  children: [
4718
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-cart-bonus-item__media w-20 h-20 flex-shrink-0 bg-surface-hover rounded-control overflow-hidden flex items-center justify-center", children: img ? /* @__PURE__ */ jsxRuntime.jsx("img", { className: "propeller-cart-bonus-item__image w-full h-full object-contain p-1", src: img, alt: name }) : /* @__PURE__ */ jsxRuntime.jsx(
4738
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-cart-bonus-item__media w-20 h-20 flex-shrink-0 bg-surface-hover rounded-control overflow-hidden flex items-center justify-center", children: img ? /* @__PURE__ */ jsxRuntime.jsx(PropellerImg, { as: Img, className: "propeller-cart-bonus-item__image w-full h-full object-contain p-1", src: img, alt: name, loading: "lazy" }) : /* @__PURE__ */ jsxRuntime.jsx(
4719
4739
  "svg",
4720
4740
  {
4741
+ "aria-hidden": "true",
4721
4742
  fill: "none",
4722
4743
  viewBox: "0 0 24 24",
4723
4744
  stroke: "currentColor",
4724
- className: "propeller-cart-bonus-item__image-placeholder w-8 h-8 text-foreground-subtle",
4725
- strokeWidth: 1.5,
4745
+ className: "propeller-cart-bonus-item__image-placeholder w-10 h-10 text-foreground-subtle",
4746
+ strokeWidth: 1,
4726
4747
  children: /* @__PURE__ */ jsxRuntime.jsx(
4727
4748
  "path",
4728
4749
  {
4729
4750
  strokeLinecap: "round",
4730
4751
  strokeLinejoin: "round",
4731
- d: "M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0022.5 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z"
4752
+ d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
4732
4753
  }
4733
4754
  )
4734
4755
  }
@@ -4773,6 +4794,7 @@ function mergeGrouped(p) {
4773
4794
  }
4774
4795
  function AddToCart(rawProps) {
4775
4796
  const props = mergeGrouped(useInfraProps(rawProps));
4797
+ const Img = useImgComponent();
4776
4798
  const { cart, loading, checkoutAllowed, addItem: addItem2, getMinQuantity, getStep } = useCart({
4777
4799
  graphqlClient: props.graphqlClient,
4778
4800
  user: props.user ?? null,
@@ -5129,27 +5151,30 @@ function AddToCart(rawProps) {
5129
5151
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-add-to-cart__modal-body px-6 py-5", children: [
5130
5152
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-add-to-cart__modal-product flex items-start gap-4", children: [
5131
5153
  !!getModalImageUrl() ? /* @__PURE__ */ jsxRuntime.jsx(
5132
- "img",
5154
+ PropellerImg,
5133
5155
  {
5156
+ as: Img,
5134
5157
  className: "propeller-add-to-cart__modal-image w-16 h-16 object-contain rounded border border-border-subtle flex-shrink-0",
5135
5158
  src: getModalImageUrl(),
5136
- alt: getModalName()
5159
+ alt: getModalName(),
5160
+ loading: "lazy"
5137
5161
  }
5138
5162
  ) : null,
5139
5163
  !getModalImageUrl() ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-add-to-cart__modal-image-placeholder w-16 h-16 flex items-center justify-center rounded border border-border-subtle flex-shrink-0 bg-surface-hover", children: /* @__PURE__ */ jsxRuntime.jsx(
5140
5164
  "svg",
5141
5165
  {
5166
+ "aria-hidden": "true",
5142
5167
  fill: "none",
5143
5168
  viewBox: "0 0 24 24",
5144
5169
  stroke: "currentColor",
5145
5170
  className: "w-8 h-8 text-foreground-subtle",
5146
- strokeWidth: 1.5,
5171
+ strokeWidth: 1,
5147
5172
  children: /* @__PURE__ */ jsxRuntime.jsx(
5148
5173
  "path",
5149
5174
  {
5150
5175
  strokeLinecap: "round",
5151
5176
  strokeLinejoin: "round",
5152
- d: "M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0022.5 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z"
5177
+ d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
5153
5178
  }
5154
5179
  )
5155
5180
  }
@@ -7209,29 +7234,33 @@ function CartItem(rawProps) {
7209
7234
  }
7210
7235
  function CartItemImage(props = {}) {
7211
7236
  const { derived } = useCartItemContext();
7237
+ const Img = useImgComponent();
7212
7238
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: props.className ?? "propeller-cart-item__media w-20 h-20 md:w-24 md:h-24 flex-shrink-0 bg-surface-hover flex items-center justify-center overflow-hidden relative rounded-control", children: [
7213
7239
  !!derived.imageUrl ? /* @__PURE__ */ jsxRuntime.jsx(
7214
- "img",
7240
+ PropellerImg,
7215
7241
  {
7242
+ as: Img,
7216
7243
  className: "propeller-cart-item__image w-full h-full object-contain p-1",
7217
7244
  src: derived.imageUrl,
7218
- alt: derived.name
7245
+ alt: derived.name,
7246
+ loading: "lazy"
7219
7247
  }
7220
7248
  ) : null,
7221
7249
  !derived.imageUrl ? /* @__PURE__ */ jsxRuntime.jsx(
7222
7250
  "svg",
7223
7251
  {
7252
+ "aria-hidden": "true",
7224
7253
  fill: "none",
7225
7254
  viewBox: "0 0 24 24",
7226
7255
  stroke: "currentColor",
7227
- className: "propeller-cart-item__image-placeholder w-8 h-8 text-foreground-subtle",
7228
- strokeWidth: 1.5,
7256
+ className: "propeller-cart-item__image-placeholder w-10 h-10 md:w-12 md:h-12 text-foreground-subtle",
7257
+ strokeWidth: 1,
7229
7258
  children: /* @__PURE__ */ jsxRuntime.jsx(
7230
7259
  "path",
7231
7260
  {
7232
7261
  strokeLinecap: "round",
7233
7262
  strokeLinejoin: "round",
7234
- d: "M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0022.5 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z"
7263
+ d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
7235
7264
  }
7236
7265
  )
7237
7266
  }
@@ -7352,6 +7381,7 @@ function CartItemNotes(props = {}) {
7352
7381
  }
7353
7382
  function CartItemCrossupsells(props = {}) {
7354
7383
  const { resolved, state, helpers, handlers } = useCartItemContext();
7384
+ const Img = useImgComponent();
7355
7385
  if (state.visibleCrossupsells.length === 0) return null;
7356
7386
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: props.className ?? "propeller-cart-item__crossupsells mt-3 pt-3 border-t border-border", children: [
7357
7387
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "propeller-cart-item__crossupsells-label text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2", children: propellerV2CoreUi.getLabel(resolved.labels, "crossupsellTitle", "You might also like") }),
@@ -7368,11 +7398,13 @@ function CartItemCrossupsells(props = {}) {
7368
7398
  onClick: (e) => handlers.onCrossupsellClick(item, e),
7369
7399
  children: [
7370
7400
  !!helpers.getCrossupsellImageUrl(item) ? /* @__PURE__ */ jsxRuntime.jsx(
7371
- "img",
7401
+ PropellerImg,
7372
7402
  {
7403
+ as: Img,
7373
7404
  className: "propeller-cart-item__crossupsell-image w-10 h-10 object-contain rounded flex-shrink-0",
7374
7405
  src: helpers.getCrossupsellImageUrl(item),
7375
- alt: helpers.getCrossupsellName(item)
7406
+ alt: helpers.getCrossupsellName(item),
7407
+ loading: "lazy"
7376
7408
  }
7377
7409
  ) : null,
7378
7410
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
@@ -7801,7 +7833,7 @@ function CartIconAndSidebar(rawProps) {
7801
7833
  includeTax: useTax,
7802
7834
  className: "propeller-cart-icon__item",
7803
7835
  children: [
7804
- /* @__PURE__ */ jsxRuntime.jsx(CartItem_default.Image, { className: "w-20 h-20 flex-shrink-0 bg-surface-hover rounded-control overflow-hidden border border-border-subtle" }),
7836
+ /* @__PURE__ */ jsxRuntime.jsx(CartItem_default.Image, { className: "w-20 h-20 flex-shrink-0 bg-surface-hover rounded-control overflow-hidden border border-border-subtle flex items-center justify-center relative" }),
7805
7837
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0 flex flex-col justify-between py-1", children: [
7806
7838
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7807
7839
  /* @__PURE__ */ jsxRuntime.jsx(CartItem_default.Title, { className: "propeller-cart-icon__item-name text-sm font-medium hover:text-primary line-clamp-2" }),
@@ -8568,6 +8600,7 @@ function ClusterCardImage(props) {
8568
8600
  const showFavorite = props.showFavorite ?? !!resolved.enableAddFavorite;
8569
8601
  const isRow = derived.isRow;
8570
8602
  const InjectedImage = resolved.imageComponent;
8603
+ const Img = useImgComponent();
8571
8604
  if (InjectedImage) {
8572
8605
  return /* @__PURE__ */ jsxRuntime.jsx(
8573
8606
  InjectedImage,
@@ -8586,13 +8619,15 @@ function ClusterCardImage(props) {
8586
8619
  className: props.className ?? `propeller-cluster-card__media relative overflow-hidden bg-surface-hover ${isRow ? "w-20 h-20 flex-shrink-0 p-2" : "aspect-[4/3] sm:aspect-square p-2 sm:p-4"}`,
8587
8620
  children: [
8588
8621
  /* @__PURE__ */ jsxRuntime.jsx("a", { className: "block h-full w-full", href: derived.clusterUrl, onClick: handleClusterClick, children: derived.imageUrl ? /* @__PURE__ */ jsxRuntime.jsx(
8589
- "img",
8622
+ PropellerImg,
8590
8623
  {
8624
+ as: Img,
8591
8625
  className: "propeller-cluster-card__image h-full w-full object-contain transition-transform duration-300 group-hover:scale-105",
8592
8626
  src: derived.imageUrl,
8593
- alt: derived.name
8627
+ alt: derived.name,
8628
+ loading: "lazy"
8594
8629
  }
8595
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-cluster-card__image-placeholder flex h-full w-full items-center justify-center text-foreground-subtle", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", className: "h-16 w-16", children: /* @__PURE__ */ jsxRuntime.jsx(
8630
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-cluster-card__image-placeholder flex h-full w-full items-center justify-center text-foreground-subtle", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", className: "h-16 w-16", children: /* @__PURE__ */ jsxRuntime.jsx(
8596
8631
  "path",
8597
8632
  {
8598
8633
  strokeLinecap: "round",
@@ -8810,6 +8845,7 @@ function getMachineImageUrl(machine) {
8810
8845
  }
8811
8846
  function MachineCard(props) {
8812
8847
  const { machine, href, language } = props;
8848
+ const Img = useImgComponent();
8813
8849
  const Wrapper = href ? "a" : "div";
8814
8850
  const showImage = props.showImage ?? true;
8815
8851
  const showDescription = props.showDescription ?? false;
@@ -8828,8 +8864,9 @@ function MachineCard(props) {
8828
8864
  className: "flex h-full flex-col focus:outline-none focus-visible:ring-2 focus-visible:ring-primary",
8829
8865
  children: [
8830
8866
  showImage && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-machine-card__image aspect-square w-full overflow-hidden bg-background-subtle", children: imageUrl ? /* @__PURE__ */ jsxRuntime.jsx(
8831
- "img",
8867
+ PropellerImg,
8832
8868
  {
8869
+ as: Img,
8833
8870
  src: imageUrl,
8834
8871
  alt: name,
8835
8872
  loading: "lazy",
@@ -8846,6 +8883,7 @@ function MachineCard(props) {
8846
8883
  children: /* @__PURE__ */ jsxRuntime.jsx(
8847
8884
  "svg",
8848
8885
  {
8886
+ "aria-hidden": "true",
8849
8887
  className: "h-12 w-12",
8850
8888
  fill: "none",
8851
8889
  stroke: "currentColor",
@@ -9150,6 +9188,7 @@ function ProductCardImage(props) {
9150
9188
  const showFavorite = props.showFavorite ?? !!resolved.enableAddFavorite;
9151
9189
  const isRow = derived.isRow;
9152
9190
  const InjectedImage = resolved.imageComponent;
9191
+ const Img = useImgComponent();
9153
9192
  if (InjectedImage) {
9154
9193
  return /* @__PURE__ */ jsxRuntime.jsx(
9155
9194
  InjectedImage,
@@ -9168,13 +9207,15 @@ function ProductCardImage(props) {
9168
9207
  className: props.className ?? `propeller-product-card__media relative overflow-hidden bg-surface-hover ${isRow ? "w-20 h-20 flex-shrink-0 p-2" : "aspect-[4/3] sm:aspect-square p-2 sm:p-4"}`,
9169
9208
  children: [
9170
9209
  /* @__PURE__ */ jsxRuntime.jsx("a", { className: "block h-full w-full", href: derived.productUrl, onClick: handleProductClick, children: derived.imageUrl ? /* @__PURE__ */ jsxRuntime.jsx(
9171
- "img",
9210
+ PropellerImg,
9172
9211
  {
9212
+ as: Img,
9173
9213
  className: "propeller-product-card__image h-full w-full object-contain transition-transform duration-300 group-hover:scale-105",
9174
9214
  src: derived.imageUrl,
9175
- alt: derived.name
9215
+ alt: derived.name,
9216
+ loading: "lazy"
9176
9217
  }
9177
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-product-card__image-placeholder flex h-full w-full items-center justify-center text-foreground-subtle", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", className: "h-16 w-16", children: /* @__PURE__ */ jsxRuntime.jsx(
9218
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-product-card__image-placeholder flex h-full w-full items-center justify-center text-foreground-subtle", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", className: "h-16 w-16", children: /* @__PURE__ */ jsxRuntime.jsx(
9178
9219
  "path",
9179
9220
  {
9180
9221
  strokeLinecap: "round",
@@ -11029,6 +11070,7 @@ function MachinePartsSearch(props) {
11029
11070
  ] });
11030
11071
  }
11031
11072
  function ClusterConfigurator(props) {
11073
+ const Img = useImgComponent();
11032
11074
  const { settingsWithValues, handleAttributeSelect, initFromProduct } = useClusterConfigurator({
11033
11075
  products: props.products,
11034
11076
  config: props.config,
@@ -11119,7 +11161,7 @@ function ClusterConfigurator(props) {
11119
11161
  "data-selected": setting.selectedValue === val ? "true" : "false",
11120
11162
  className: `propeller-cluster-configurator__image-swatch relative w-16 h-16 rounded-control border-2 overflow-hidden transition-all ${setting.disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"} ${setting.selectedValue === val ? "border-secondary ring-2 ring-secondary/30 ring-offset-1" : "border-border hover:border-secondary/30"}`,
11121
11163
  children: [
11122
- /* @__PURE__ */ jsxRuntime.jsx("img", { className: "propeller-cluster-configurator__image w-full h-full object-cover", src: val, alt: val }),
11164
+ /* @__PURE__ */ jsxRuntime.jsx(PropellerImg, { as: Img, className: "propeller-cluster-configurator__image w-full h-full object-cover", src: val, alt: val, loading: "lazy" }),
11123
11165
  setting.selectedValue === val ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-cluster-configurator__image-check absolute inset-0 bg-secondary bg-opacity-20 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
11124
11166
  "svg",
11125
11167
  {
@@ -11219,6 +11261,7 @@ function getProductImageUrl4(product) {
11219
11261
  }
11220
11262
  function ClusterOptions(rawProps) {
11221
11263
  const props = useInfraProps(rawProps);
11264
+ const Img = useImgComponent();
11222
11265
  const [selectedProductIds, setSelectedProductIds] = React6.useState({});
11223
11266
  function getOptionsForRender() {
11224
11267
  const language = props.language;
@@ -11305,20 +11348,23 @@ function ClusterOptions(rawProps) {
11305
11348
  option.hasError ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "propeller-cluster-options__error mt-1 text-xs text-destructive", children: propellerV2CoreUi.getLabel(props.labels, "requiredError", "This option is required") }) : null,
11306
11349
  option.hasSelection ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cluster-options__preview mt-3 flex items-center gap-3 rounded-container border border-border-subtle bg-surface-hover p-3", children: [
11307
11350
  !!option.previewImageUrl ? /* @__PURE__ */ jsxRuntime.jsx(
11308
- "img",
11351
+ PropellerImg,
11309
11352
  {
11353
+ as: Img,
11310
11354
  className: "propeller-cluster-options__preview-image h-12 w-12 flex-shrink-0 rounded border border-border-subtle bg-card object-contain",
11311
11355
  src: option.previewImageUrl,
11312
- alt: option.previewName
11356
+ alt: option.previewName,
11357
+ loading: "lazy"
11313
11358
  }
11314
11359
  ) : null,
11315
11360
  !option.previewImageUrl ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-cluster-options__preview-image-placeholder flex h-12 w-12 flex-shrink-0 items-center justify-center rounded border border-border bg-surface-hover", children: /* @__PURE__ */ jsxRuntime.jsx(
11316
11361
  "svg",
11317
11362
  {
11363
+ "aria-hidden": "true",
11318
11364
  fill: "none",
11319
11365
  stroke: "currentColor",
11320
11366
  viewBox: "0 0 24 24",
11321
- className: "h-5 w-5 text-foreground-subtle",
11367
+ className: "h-6 w-6 text-foreground-subtle",
11322
11368
  children: /* @__PURE__ */ jsxRuntime.jsx(
11323
11369
  "path",
11324
11370
  {
@@ -11802,19 +11848,22 @@ function FavoriteListItem(rawProps) {
11802
11848
  }
11803
11849
  function FavoriteListItemImage(props) {
11804
11850
  const { derived, handleItemClick, resolved } = useFavoriteListItemContext();
11851
+ const Img = useImgComponent();
11805
11852
  const { imageUrl, name, productUrl } = derived;
11806
11853
  const linkable = resolved.titleLinkable !== false;
11807
11854
  const wrapperClass = props.className ?? "propeller-favorite-list-item__media relative w-16 h-16 flex-shrink-0 overflow-hidden rounded-control bg-surface-hover p-1";
11808
11855
  const inner = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11809
11856
  !!imageUrl ? /* @__PURE__ */ jsxRuntime.jsx(
11810
- "img",
11857
+ PropellerImg,
11811
11858
  {
11859
+ as: Img,
11812
11860
  className: "propeller-favorite-list-item__image h-full w-full object-contain",
11813
11861
  src: imageUrl,
11814
- alt: name
11862
+ alt: name,
11863
+ loading: "lazy"
11815
11864
  }
11816
11865
  ) : null,
11817
- !imageUrl ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-favorite-list-item__image-placeholder flex h-full w-full items-center justify-center text-foreground-subtle", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", className: "h-8 w-8", children: /* @__PURE__ */ jsxRuntime.jsx(
11866
+ !imageUrl ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-favorite-list-item__image-placeholder flex h-full w-full items-center justify-center text-foreground-subtle", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", className: "h-10 w-10", children: /* @__PURE__ */ jsxRuntime.jsx(
11818
11867
  "path",
11819
11868
  {
11820
11869
  strokeLinecap: "round",
@@ -12012,6 +12061,7 @@ FavoriteListItemExport.Actions = FavoriteListItemActions;
12012
12061
  var FavoriteListItem_default = FavoriteListItemExport;
12013
12062
  function FavoriteListDetails(rawProps) {
12014
12063
  const props = useInfraProps(rawProps);
12064
+ const Img = useImgComponent();
12015
12065
  const FavoriteListItemImpl = props.favoriteListItemComponent ?? FavoriteListItem_default;
12016
12066
  const GridPaginationImpl = props.gridPaginationComponent ?? GridPagination_default;
12017
12067
  const { addToList } = useFavorites({
@@ -12593,11 +12643,13 @@ function FavoriteListDetails(rawProps) {
12593
12643
  "data-adding": isAdding ? "true" : "false",
12594
12644
  children: [
12595
12645
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-favorite-list-details__search-item-media h-14 w-14 flex-shrink-0 rounded-control bg-surface-hover overflow-hidden flex items-center justify-center", children: getSearchItemImage(item) ? /* @__PURE__ */ jsxRuntime.jsx(
12596
- "img",
12646
+ PropellerImg,
12597
12647
  {
12648
+ as: Img,
12598
12649
  src: getSearchItemImage(item),
12599
12650
  alt: getSearchItemName(item),
12600
- className: "h-full w-full object-contain"
12651
+ className: "h-full w-full object-contain",
12652
+ loading: "lazy"
12601
12653
  }
12602
12654
  ) : /* @__PURE__ */ jsxRuntime.jsxs(
12603
12655
  "svg",
@@ -13305,6 +13357,7 @@ function getBundleNonLeaders(item) {
13305
13357
  }
13306
13358
  function ItemsOverview(rawProps) {
13307
13359
  const props = useInfraProps(rawProps);
13360
+ const Img = useImgComponent();
13308
13361
  const language = props.language;
13309
13362
  const useTax = !!props.includeTax;
13310
13363
  const containerClass = props.itemsOverviewContainerClass || "cart-items-overview";
@@ -13363,26 +13416,29 @@ function ItemsOverview(rawProps) {
13363
13416
  "data-bundle": isBundle ? "true" : "false",
13364
13417
  children: [
13365
13418
  showImage ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-items-overview__item-media w-16 h-16 flex-shrink-0 bg-surface-hover rounded-control overflow-hidden border border-border-subtle flex items-center justify-center", children: getItemImageUrl(item) ? /* @__PURE__ */ jsxRuntime.jsx(
13366
- "img",
13419
+ PropellerImg,
13367
13420
  {
13421
+ as: Img,
13368
13422
  className: "propeller-items-overview__item-image w-full h-full object-contain p-1.5",
13369
13423
  src: getItemImageUrl(item),
13370
- alt: getItemName(item, language)
13424
+ alt: getItemName(item, language),
13425
+ loading: "lazy"
13371
13426
  }
13372
13427
  ) : /* @__PURE__ */ jsxRuntime.jsx(
13373
13428
  "svg",
13374
13429
  {
13430
+ "aria-hidden": "true",
13375
13431
  fill: "none",
13376
13432
  viewBox: "0 0 24 24",
13377
13433
  stroke: "currentColor",
13378
- strokeWidth: "1.5",
13379
- className: "propeller-items-overview__item-image-placeholder w-6 h-6 text-foreground-subtle",
13434
+ strokeWidth: "1",
13435
+ className: "propeller-items-overview__item-image-placeholder w-8 h-8 text-foreground-subtle",
13380
13436
  children: /* @__PURE__ */ jsxRuntime.jsx(
13381
13437
  "path",
13382
13438
  {
13383
13439
  strokeLinecap: "round",
13384
13440
  strokeLinejoin: "round",
13385
- d: "M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0022.5 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z"
13441
+ d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
13386
13442
  }
13387
13443
  )
13388
13444
  }
@@ -14006,11 +14062,13 @@ function OrderItemCard(props) {
14006
14062
  className: `propeller-order-item-card__cell propeller-order-item-card__cell--product ${isChildItem ? "px-6 py-2 pl-28" : "px-6 py-4"}`,
14007
14063
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
14008
14064
  showImage ? productImage ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-order-item-card__media relative w-16 h-16 flex-shrink-0 rounded overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
14009
- "img",
14065
+ PropellerImg,
14010
14066
  {
14067
+ as: props.imgComponent,
14011
14068
  className: "propeller-order-item-card__image object-cover w-full h-full",
14012
14069
  src: productImage,
14013
- alt: productName
14070
+ alt: productName,
14071
+ loading: "lazy"
14014
14072
  }
14015
14073
  ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-order-item-card__image-placeholder w-16 h-16 bg-surface-hover rounded flex items-center justify-center text-foreground-subtle text-xs", children: propellerV2CoreUi.getLabel(props.labels, "noImage", "No Img") }) : null,
14016
14074
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
@@ -14777,6 +14835,7 @@ function QuickOrderInner(props) {
14777
14835
  className,
14778
14836
  labels
14779
14837
  } = props;
14838
+ const Img = useImgComponent();
14780
14839
  const user = props.user ?? null;
14781
14840
  const graphqlClient = props.graphqlClient;
14782
14841
  const displayPrice = (n) => props.formatPrice ? props.formatPrice(n) : propellerV2CoreUi.formatPrice(n, { symbol: currency, locale: propellerV2CoreUi.localeForLanguage(props.language) });
@@ -15008,7 +15067,7 @@ function QuickOrderInner(props) {
15008
15067
  children: [
15009
15068
  m.imageUrl ? (
15010
15069
  // eslint-disable-next-line @next/next/no-img-element
15011
- /* @__PURE__ */ jsxRuntime.jsx("img", { src: m.imageUrl, alt: "", width: 32, height: 32, className: "rounded object-cover" })
15070
+ /* @__PURE__ */ jsxRuntime.jsx(PropellerImg, { as: Img, src: m.imageUrl, alt: "", width: 32, height: 32, className: "rounded object-cover", loading: "lazy" })
15012
15071
  ) : null,
15013
15072
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex-1", children: [
15014
15073
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-foreground", children: m.name }),
@@ -15673,6 +15732,7 @@ function getProductName4(product, language) {
15673
15732
  }
15674
15733
  function ProductBundles(rawProps) {
15675
15734
  const props = useInfraProps(rawProps);
15735
+ const Img = useImgComponent();
15676
15736
  const language = props.language;
15677
15737
  const currencySymbol = props.currency ?? "\u20AC";
15678
15738
  const money = (value) => propellerV2CoreUi.formatPrice(value, { symbol: currencySymbol, locale: propellerV2CoreUi.localeForLanguage(props.language) });
@@ -15808,11 +15868,13 @@ function ProductBundles(rawProps) {
15808
15868
  ) }) : null,
15809
15869
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center text-center w-40", children: [
15810
15870
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-product-bundles__item-media w-32 h-32 bg-surface-hover rounded-container overflow-hidden flex-shrink-0 mb-2", children: getProductImage(item.product) ? /* @__PURE__ */ jsxRuntime.jsx(
15811
- "img",
15871
+ PropellerImg,
15812
15872
  {
15873
+ as: Img,
15813
15874
  className: "propeller-product-bundles__item-image w-full h-full object-contain p-2",
15814
15875
  src: getProductImage(item.product),
15815
- alt: getProductName4(item.product, language)
15876
+ alt: getProductName4(item.product, language),
15877
+ loading: "lazy"
15816
15878
  }
15817
15879
  ) : null }),
15818
15880
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-product-bundles__item-name text-sm font-medium text-muted-foreground leading-tight mb-1", children: getProductName4(item.product, language) || "Product " + item.productId }),
@@ -15977,26 +16039,29 @@ function ProductBundles(rawProps) {
15977
16039
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-product-bundles__modal-body px-6 py-5", children: [
15978
16040
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-product-bundles__modal-product flex items-start gap-4", children: [
15979
16041
  lastAddedBundle && lastAddedBundle.items && lastAddedBundle.items.length > 0 && getProductImage(lastAddedBundle.items[0].product) ? /* @__PURE__ */ jsxRuntime.jsx(
15980
- "img",
16042
+ PropellerImg,
15981
16043
  {
16044
+ as: Img,
15982
16045
  className: "propeller-product-bundles__modal-image w-16 h-16 object-contain rounded border border-border-subtle flex-shrink-0",
15983
16046
  src: lastAddedBundle?.items?.[0] ? getProductImage(lastAddedBundle.items[0].product) : "",
15984
- alt: lastAddedBundle?.name || "Bundle"
16047
+ alt: lastAddedBundle?.name || "Bundle",
16048
+ loading: "lazy"
15985
16049
  }
15986
16050
  ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-product-bundles__modal-image-placeholder w-16 h-16 flex items-center justify-center rounded border border-border-subtle flex-shrink-0 bg-surface-hover", children: /* @__PURE__ */ jsxRuntime.jsx(
15987
16051
  "svg",
15988
16052
  {
16053
+ "aria-hidden": "true",
15989
16054
  fill: "none",
15990
16055
  viewBox: "0 0 24 24",
15991
16056
  stroke: "currentColor",
15992
16057
  className: "w-8 h-8 text-foreground-subtle",
15993
- strokeWidth: 1.5,
16058
+ strokeWidth: 1,
15994
16059
  children: /* @__PURE__ */ jsxRuntime.jsx(
15995
16060
  "path",
15996
16061
  {
15997
16062
  strokeLinecap: "round",
15998
16063
  strokeLinejoin: "round",
15999
- d: "M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0022.5 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z"
16064
+ d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
16000
16065
  }
16001
16066
  )
16002
16067
  }
@@ -16161,6 +16226,7 @@ function ProductDownloads(props) {
16161
16226
  }
16162
16227
  var ProductDownloads_default = ProductDownloads;
16163
16228
  function ProductGallery(props) {
16229
+ const Img = useImgComponent();
16164
16230
  const [selectedIndex, setSelectedIndex] = React6.useState(0);
16165
16231
  const [lightboxOpen, setLightboxOpen] = React6.useState(false);
16166
16232
  const images = props.images || [];
@@ -16198,11 +16264,13 @@ function ProductGallery(props) {
16198
16264
  }
16199
16265
  ) }) : null,
16200
16266
  images.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
16201
- "img",
16267
+ PropellerImg,
16202
16268
  {
16269
+ as: Img,
16203
16270
  alt: propellerV2CoreUi.getLabel(props.labels, "productImageAlt", "Product image"),
16204
16271
  src: mainImage,
16205
16272
  onClick: openLightbox,
16273
+ loading: "eager",
16206
16274
  className: `h-full w-full object-contain p-8 transition-transform duration-200 ${props.enableZoom !== false ? "cursor-zoom-in hover:scale-105" : ""}`
16207
16275
  }
16208
16276
  ) : null
@@ -16214,11 +16282,13 @@ function ProductGallery(props) {
16214
16282
  onClick: () => setSelectedIndex(index),
16215
16283
  className: `propeller-product-gallery__thumbnail relative flex-shrink-0 w-20 h-20 rounded-container border-2 overflow-hidden transition-all bg-card ${selectedIndex === index ? "border-primary ring-2 ring-primary/20" : "border-transparent hover:border-border"}`,
16216
16284
  children: /* @__PURE__ */ jsxRuntime.jsx(
16217
- "img",
16285
+ PropellerImg,
16218
16286
  {
16287
+ as: Img,
16219
16288
  className: "w-full h-full object-contain p-1",
16220
16289
  src: img,
16221
- alt: `${propellerV2CoreUi.getLabel(props.labels, "productImageAlt", "Product image")} ${index + 1}`
16290
+ alt: `${propellerV2CoreUi.getLabel(props.labels, "productImageAlt", "Product image")} ${index + 1}`,
16291
+ loading: "lazy"
16222
16292
  }
16223
16293
  )
16224
16294
  },
@@ -16273,12 +16343,13 @@ function ProductGallery(props) {
16273
16343
  }
16274
16344
  ) : null,
16275
16345
  /* @__PURE__ */ jsxRuntime.jsx(
16276
- "img",
16346
+ PropellerImg,
16277
16347
  {
16348
+ as: Img,
16278
16349
  alt: propellerV2CoreUi.getLabel(props.labels, "productImageFullscreenAlt", "Product image fullscreen"),
16279
16350
  className: "max-h-full max-w-full object-contain rounded-lg",
16280
16351
  src: mainImage,
16281
- onClick: (e) => e.stopPropagation()
16352
+ onClick: (e) => e.stopPropagation?.()
16282
16353
  }
16283
16354
  ),
16284
16355
  hasThumbnails ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -16332,6 +16403,7 @@ function pickImageUrl(mediaItems, target) {
16332
16403
  }
16333
16404
  function DefaultProductImage(props) {
16334
16405
  const { product, cluster, className } = props;
16406
+ const Img = useImgComponent();
16335
16407
  const targetLanguage = props.language ?? "NL";
16336
16408
  const mediaItems = (() => {
16337
16409
  const target = product ?? cluster?.defaultProduct ?? cluster;
@@ -16366,8 +16438,9 @@ function DefaultProductImage(props) {
16366
16438
  );
16367
16439
  }
16368
16440
  return /* @__PURE__ */ jsxRuntime.jsx(
16369
- "img",
16441
+ PropellerImg,
16370
16442
  {
16443
+ as: Img,
16371
16444
  src: url,
16372
16445
  alt: altText,
16373
16446
  className: className ?? "h-full w-full object-contain",
@@ -19276,6 +19349,7 @@ function mapToSearchBarResult(item, language, urls) {
19276
19349
  }
19277
19350
  function SearchBar(rawProps) {
19278
19351
  const props = useInfraProps(rawProps);
19352
+ const Img = useImgComponent();
19279
19353
  const [showDropdown, setShowDropdown] = React6.useState(false);
19280
19354
  const [localTerm, setLocalTerm] = React6.useState("");
19281
19355
  const containerRef = React6.useRef(null);
@@ -19441,11 +19515,13 @@ function SearchBar(rawProps) {
19441
19515
  ...resultProps,
19442
19516
  children: [
19443
19517
  result.imageUrl || noImageUrl() ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-search-bar__result-media relative w-16 h-16 flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
19444
- "img",
19518
+ PropellerImg,
19445
19519
  {
19520
+ as: Img,
19446
19521
  className: "propeller-search-bar__result-image w-full h-full object-contain",
19447
19522
  src: result.imageUrl || noImageUrl(),
19448
- alt: result.name
19523
+ alt: result.name,
19524
+ loading: "lazy"
19449
19525
  }
19450
19526
  ) }) : null,
19451
19527
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
@@ -19682,6 +19758,7 @@ exports.ProductSpecifications = ProductSpecifications_default;
19682
19758
  exports.ProductTabs = ProductTabs_default;
19683
19759
  exports.ProductVideos = ProductVideos_default;
19684
19760
  exports.PropellerDepsProvider = PropellerDepsProvider;
19761
+ exports.PropellerImg = PropellerImg;
19685
19762
  exports.PropellerProvider = PropellerProvider;
19686
19763
  exports.PurchaseAuthorizationConfigurator = PurchaseAuthorizationConfigurator_default;
19687
19764
  exports.PurchaseAuthorizationRequests = PurchaseAuthorizationRequests_default;
@@ -19707,6 +19784,7 @@ exports.useCheckout = useCheckout;
19707
19784
  exports.useClusterConfigurator = useClusterConfigurator;
19708
19785
  exports.useCompany = useCompany;
19709
19786
  exports.useFavorites = useFavorites;
19787
+ exports.useImgComponent = useImgComponent;
19710
19788
  exports.useInfraProps = useInfraProps;
19711
19789
  exports.useMachines = useMachines;
19712
19790
  exports.useMenu = useMenu;