From b18776f1f77f850315a353aac32a336cdc05f006 Mon Sep 17 00:00:00 2001 From: Steven Date: Thu, 5 Nov 2020 12:37:02 -0500 Subject: [PATCH 1/4] Add objectFit and objectPosition --- packages/next/client/image.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index f3164d711a02f..12a48c7a5ab96 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -30,6 +30,8 @@ type ImageData = { domains?: string[] } +type ImgElementStyle = NonNullable + type ImageProps = Omit< JSX.IntrinsicElements['img'], 'src' | 'srcSet' | 'ref' | 'width' | 'height' | 'loading' | 'style' @@ -39,6 +41,8 @@ type ImageProps = Omit< priority?: boolean loading?: LoadingValue unoptimized?: boolean + objectFit?: ImgElementStyle['objectFit'] + objectPosition?: ImgElementStyle['objectPosition'] } & ( | { width?: never @@ -247,6 +251,8 @@ export default function Image({ quality, width, height, + objectFit, + objectPosition, ...all }: ImageProps) { const thisEl = useRef(null) @@ -342,7 +348,7 @@ export default function Image({ let wrapperStyle: JSX.IntrinsicElements['div']['style'] | undefined let sizerStyle: JSX.IntrinsicElements['div']['style'] | undefined let sizerSvg: string | undefined - let imgStyle: JSX.IntrinsicElements['img']['style'] = { + let imgStyle: ImgElementStyle | undefined = { visibility: lazy ? 'hidden' : 'visible', position: 'absolute', @@ -363,6 +369,9 @@ export default function Image({ maxWidth: '100%', minHeight: '100%', maxHeight: '100%', + + objectFit, + objectPosition, } if ( typeof widthInt !== 'undefined' && From 3678365ab02bf6945ccf9b91b812b547687e2c8a Mon Sep 17 00:00:00 2001 From: Steven Date: Thu, 5 Nov 2020 12:55:45 -0500 Subject: [PATCH 2/4] Add tests and update example --- examples/image-component/pages/background.js | 4 ++-- examples/image-component/pages/layout-fill.js | 11 +++-------- examples/image-component/styles.module.css | 10 ---------- .../image-component/default/pages/layout-fill.js | 8 +++++++- .../image-component/default/test/index.test.js | 9 +++++++++ .../image-component/typescript/pages/valid.tsx | 14 ++++++++++++++ 6 files changed, 35 insertions(+), 21 deletions(-) diff --git a/examples/image-component/pages/background.js b/examples/image-component/pages/background.js index d2bded5e1bb9f..b2680e7cd797c 100644 --- a/examples/image-component/pages/background.js +++ b/examples/image-component/pages/background.js @@ -1,5 +1,5 @@ import Image from 'next/image' -import { bgWrap, bgText, objectFitCover } from '../styles.module.css' +import { bgWrap, bgText } from '../styles.module.css' const Background = () => (
@@ -8,8 +8,8 @@ const Background = () => ( alt="Mountains" src="/mountains.jpg" layout="fill" + objectFit="cover" quality={100} - className={objectFitCover} />

diff --git a/examples/image-component/pages/layout-fill.js b/examples/image-component/pages/layout-fill.js index a65587cb6c928..824958478c581 100644 --- a/examples/image-component/pages/layout-fill.js +++ b/examples/image-component/pages/layout-fill.js @@ -1,9 +1,4 @@ import Image from 'next/image' -import { - objectFitContain, - objectFitCover, - objectFitNone, -} from '../styles.module.css' const Fill = () => (

@@ -13,7 +8,7 @@ const Fill = () => ( alt="Mountains" src="/mountains.jpg" layout="fill" - className={objectFitCover} + objectFit="cover" />
@@ -21,7 +16,7 @@ const Fill = () => ( alt="Mountains" src="/mountains.jpg" layout="fill" - className={objectFitContain} + objectFit="contain" />
@@ -29,7 +24,7 @@ const Fill = () => ( alt="Mountains" src="/mountains.jpg" layout="fill" - className={objectFitNone} + objectFit="none" quality={100} />
diff --git a/examples/image-component/styles.module.css b/examples/image-component/styles.module.css index 2186eedaa8eea..2e3e92d886a7e 100644 --- a/examples/image-component/styles.module.css +++ b/examples/image-component/styles.module.css @@ -48,13 +48,3 @@ padding-top: 40vh; text-shadow: 1px 1px 1px #3c5c5e; } - -.objectFitContain { - object-fit: contain; -} -.objectFitCover { - object-fit: cover; -} -.objectFitNone { - object-fit: none; -} diff --git a/test/integration/image-component/default/pages/layout-fill.js b/test/integration/image-component/default/pages/layout-fill.js index 299e357175a4f..41e50efa989b6 100644 --- a/test/integration/image-component/default/pages/layout-fill.js +++ b/test/integration/image-component/default/pages/layout-fill.js @@ -10,7 +10,13 @@ const Page = () => {

Layout Fill

- +

Layout Fill

diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index 4cf85eb54c121..e90db40869e8f 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -294,6 +294,15 @@ function runTests(mode) { }) expect(await getComputed(browser, id, 'width')).toBe(smallWidth) expect(await getComputed(browser, id, 'height')).toBe(smallHeight) + + const objectFit = await browser.eval( + `document.getElementById("${id}").style.objectFit` + ) + const objectPosition = await browser.eval( + `document.getElementById("${id}").style.objectPosition` + ) + expect(objectFit).toBe('cover') + expect(objectPosition).toBe('left') } finally { if (browser) { await browser.close() diff --git a/test/integration/image-component/typescript/pages/valid.tsx b/test/integration/image-component/typescript/pages/valid.tsx index dede52cea1448..640211ea9c560 100644 --- a/test/integration/image-component/typescript/pages/valid.tsx +++ b/test/integration/image-component/typescript/pages/valid.tsx @@ -44,6 +44,20 @@ const Page = () => { width={100} height={100} /> + +

This is valid usage of the Image component

) From dee3a360365fe4b7d4b554d7755bfaa9861f0df2 Mon Sep 17 00:00:00 2001 From: Steven Date: Thu, 5 Nov 2020 14:14:21 -0500 Subject: [PATCH 3/4] Fix test --- test/integration/image-component/default/pages/layout-fill.js | 2 +- test/integration/image-component/default/test/index.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/image-component/default/pages/layout-fill.js b/test/integration/image-component/default/pages/layout-fill.js index 41e50efa989b6..e442c041b9a2e 100644 --- a/test/integration/image-component/default/pages/layout-fill.js +++ b/test/integration/image-component/default/pages/layout-fill.js @@ -15,7 +15,7 @@ const Page = () => { src="/wide.png" layout="fill" objectFit="cover" - objectPosition="left" + objectPosition="left center" />

Layout Fill

diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index e90db40869e8f..35ad401a47a1d 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -302,7 +302,7 @@ function runTests(mode) { `document.getElementById("${id}").style.objectPosition` ) expect(objectFit).toBe('cover') - expect(objectPosition).toBe('left') + expect(objectPosition).toBe('left center') } finally { if (browser) { await browser.close() From aa234b422633e034f3504486a8dda925648487b9 Mon Sep 17 00:00:00 2001 From: Steven Date: Thu, 5 Nov 2020 14:21:11 -0500 Subject: [PATCH 4/4] Add docs --- docs/api-reference/next/image.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/api-reference/next/image.md b/docs/api-reference/next/image.md index 93f01c3615160..6ce19500a0134 100644 --- a/docs/api-reference/next/image.md +++ b/docs/api-reference/next/image.md @@ -113,6 +113,18 @@ Should only be used when the image is visible above the fold. Defaults to false. In some cases, you may need more advanced usage. The `Image` component optionally accepts the following advanced properties. +### objectFit + +The image fit when using `layout="fill"`. + +[Learn more](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit) + +### objectPosition + +The image position when using `layout="fill"`. + +[Learn more](https://developer.mozilla.org/en-US/docs/Web/CSS/object-position) + ### loading The loading behavior of the image. Defaults to `lazy`.