routerino 2.3.0 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "routerino",
3
- "version": "2.3.0",
3
+ "version": "2.3.2",
4
4
  "description": "A lightweight, SEO-optimized React router for modern web applications",
5
5
  "repository": {
6
6
  "type": "git",
@@ -120,11 +120,13 @@ async function generateResponsiveImages(
120
120
  variants: {},
121
121
  };
122
122
 
123
- // Generate responsive variants for each width
124
- for (const width of config.widths) {
125
- // Skip if image is smaller than target width
126
- if (dimensions && dimensions.width < width) continue;
123
+ // Filter widths to only include those applicable to this image
124
+ const applicableWidths = config.widths.filter(
125
+ (width) => !dimensions || dimensions.width >= width
126
+ );
127
127
 
128
+ // Generate responsive variants for applicable widths only
129
+ for (const width of applicableWidths) {
128
130
  // Generate WebP version in output directory
129
131
  const webpPath = path.join(outputDir, `${base}-${width}w.webp`);
130
132
  await generateImageVariant(inputPath, webpPath, width, "webp");
@@ -1,3 +1,4 @@
1
+ import React, { useState, useEffect } from "react";
1
2
  import PropTypes from "prop-types";
2
3
 
3
4
  /**
@@ -54,19 +55,45 @@ function generateSrcSet(src, widths, format = null) {
54
55
  .join(", ");
55
56
  }
56
57
 
57
- export function Image({
58
- src,
59
- alt,
60
- priority,
61
- widths = DEFAULT_WIDTHS,
62
- sizes = DEFAULT_SIZES,
63
- className = "",
64
- style = {},
65
- loading: explicitLoading,
66
- decoding = "async",
67
- fetchpriority: explicitFetchPriority,
68
- ...rest
69
- }) {
58
+ export function Image(props) {
59
+ const {
60
+ src = "",
61
+ alt = "",
62
+ priority,
63
+ widths = DEFAULT_WIDTHS,
64
+ sizes = DEFAULT_SIZES,
65
+ className = "",
66
+ style = {},
67
+ loading: explicitLoading,
68
+ decoding = "async",
69
+ fetchpriority: explicitFetchPriority,
70
+ ...rest
71
+ } = props || {};
72
+
73
+ // Detect image dimensions to filter applicable widths
74
+ const [imageDimensions, setImageDimensions] = useState(null);
75
+
76
+ // Skip dimension detection when not needed
77
+ const shouldDetectDimensions = src && typeof window !== "undefined";
78
+
79
+ useEffect(() => {
80
+ if (!shouldDetectDimensions) return;
81
+
82
+ const img = new Image();
83
+ img.onload = () => {
84
+ setImageDimensions({
85
+ width: img.naturalWidth,
86
+ height: img.naturalHeight,
87
+ });
88
+ };
89
+ img.src = src;
90
+ }, [src, shouldDetectDimensions]);
91
+
92
+ // Filter widths to only include applicable ones (image width >= target width)
93
+ const applicableWidths = imageDimensions
94
+ ? widths.filter((width) => imageDimensions.width >= width)
95
+ : widths; // Fallback to all widths during loading
96
+
70
97
  // Smart priority detection if not explicitly set
71
98
  const autoPriority = priority ?? shouldUsePriority(src, className);
72
99
 
@@ -75,9 +102,9 @@ export function Image({
75
102
  const fetchPriority =
76
103
  explicitFetchPriority || (autoPriority ? "high" : undefined);
77
104
 
78
- // Generate srcsets for different formats
79
- const srcSetWebP = generateSrcSet(src, widths, "webp");
80
- const srcSetOriginal = generateSrcSet(src, widths);
105
+ // Generate srcsets for different formats using applicable widths only
106
+ const srcSetWebP = generateSrcSet(src, applicableWidths, "webp");
107
+ const srcSetOriginal = generateSrcSet(src, applicableWidths);
81
108
 
82
109
  // For SSG: This will be processed by routerino-forge.js to include LQIP
83
110
  // The data-routerino-image attribute signals to the forge to process this