Skip to content
Merged
20 changes: 18 additions & 2 deletions packages/next/client/image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,29 @@ allSizes.sort((a, b) => a - b)

function getWidths(
width: number | undefined,
layout: LayoutValue
layout: LayoutValue,
sizes: string | undefined
): { widths: number[]; kind: 'w' | 'x' } {
if (
typeof width !== 'number' ||
layout === 'fill' ||
layout === 'responsive'
) {
if (sizes) {
const percentSizes = [...sizes.matchAll(/(^|\s)(1?\d?\d)vw/g)].map((m) =>
parseInt(m[2])
)
if (percentSizes.length) {
const smallestRatio = Math.min(...percentSizes) * 0.01
return {
widths: allSizes.filter(
(s) => s >= configDeviceSizes[0] * smallestRatio
),
kind: 'w',
}
}
return { widths: allSizes, kind: 'w' }
}
return { widths: configDeviceSizes, kind: 'w' }
}

Expand Down Expand Up @@ -146,7 +162,7 @@ function generateImgAttrs({
return { src, srcSet: undefined, sizes: undefined }
}

const { widths, kind } = getWidths(width, layout)
const { widths, kind } = getWidths(width, layout, sizes)
const last = widths.length - 1

return {
Expand Down
23 changes: 23 additions & 0 deletions test/integration/image-component/default/pages/layout-fill.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,29 @@ const Page = () => {
/>
</div>
<p>Layout Fill</p>
<div style={{ position: 'relative', width: '50vw', height: '50vh' }}>
<Image
id="fill3"
src="/wide.png"
layout="fill"
objectFit="cover"
objectPosition="left center"
sizes="(min-width: 1200px) 90vw,
(min-width: 800px) 30vw,
100vw"
/>
</div>
<p>Layout Fill</p>
<div style={{ position: 'relative', width: '50vw', height: '50vh' }}>
<Image
id="fill4"
src="/wide.png"
layout="fill"
objectFit="cover"
objectPosition="left center"
sizes="500px"
/>
</div>
</div>
)
}
Expand Down
6 changes: 6 additions & 0 deletions test/integration/image-component/default/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,12 @@ function runTests(mode) {
expect(await browser.elementById(id).getAttribute('srcset')).toBe(
'/_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w'
)
expect(await browser.elementById('fill3').getAttribute('srcset')).toBe(
'/_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w'
)
expect(await browser.elementById('fill4').getAttribute('srcset')).toBe(
'/_next/image?url=%2Fwide.png&amp;w=16&amp;q=75 16w, /_next/image?url=%2Fwide.png&amp;w=32&amp;q=75 32w, /_next/image?url=%2Fwide.png&amp;w=48&amp;q=75 48w, /_next/image?url=%2Fwide.png&amp;w=64&amp;q=75 64w, /_next/image?url=%2Fwide.png&amp;w=96&amp;q=75 96w, /_next/image?url=%2Fwide.png&amp;w=128&amp;q=75 128w, /_next/image?url=%2Fwide.png&amp;w=256&amp;q=75 256w, /_next/image?url=%2Fwide.png&amp;w=384&amp;q=75 384w, /_next/image?url=%2Fwide.png&amp;w=640&amp;q=75 640w, /_next/image?url=%2Fwide.png&amp;w=750&amp;q=75 750w, /_next/image?url=%2Fwide.png&amp;w=828&amp;q=75 828w, /_next/image?url=%2Fwide.png&amp;w=1080&amp;q=75 1080w, /_next/image?url=%2Fwide.png&amp;w=1200&amp;q=75 1200w, /_next/image?url=%2Fwide.png&amp;w=1920&amp;q=75 1920w, /_next/image?url=%2Fwide.png&amp;w=2048&amp;q=75 2048w, /_next/image?url=%2Fwide.png&amp;w=3840&amp;q=75 3840w'
)
expect(await browser.elementById(id).getAttribute('sizes')).toBe('100vw')
expect(await getComputed(browser, id, 'width')).toBe(width)
expect(await getComputed(browser, id, 'height')).toBe(height)
Expand Down