Skip to content

Commit

Permalink
Merge pull request #838 from dc7290/main
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
dc7290 authored Apr 13, 2024
2 parents 757487b + 96342af commit ed76866
Show file tree
Hide file tree
Showing 16 changed files with 213 additions and 40 deletions.
14 changes: 14 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# These are supported funding model platforms

github: dc7290 # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
4 changes: 4 additions & 0 deletions __tests__/e2e/app/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import ClientComponent from '../components/ClientComponent'

import imgSrc from '../images/img.png'
import legacyImgSrc from '../images/legacy-img.png'
import WithPropsComponent from '../components/WithPropsComponent'

export default function IndexPage() {
return (
Expand All @@ -19,6 +20,9 @@ export default function IndexPage() {
{/* Static image */}
<Image src="/images/img.png" width={1920} height={1280} sizes="(min-width: 768px) 720px, 85vw" alt="" />

{/* Image with props */}
<WithPropsComponent />

{/* Invalid format image */}
<Image src="/images/img.svg" width={1920} height={1280} alt="" />

Expand Down
36 changes: 36 additions & 0 deletions __tests__/e2e/components/WithPropsComponent.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use client'

import React from 'react'
import { getOptimizedImageProps } from '../../../image'

import getPropsSrc from '../images/get-props.png'
import getPropsMobileSrc from '../images/get-props-mobile.png'

const WithPropsComponent = () => {
const props = getOptimizedImageProps({ src: getPropsSrc, alt: '' }).props
const mobileProps = getOptimizedImageProps({ src: getPropsMobileSrc, alt: '' }).props

return (
<div>
<img {...props} />
<div
style={{
backgroundImage: `url(${props.src})`,
width: props.width,
height: props.height,
}}
></div>
<picture>
<source
srcSet={mobileProps.srcSet}
width={mobileProps.width}
height={mobileProps.height}
media="(max-width: 768px)"
/>
<img {...props} />
</picture>
</div>
)
}

export default WithPropsComponent
Binary file added __tests__/e2e/images/get-props-mobile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added __tests__/e2e/images/get-props.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions __tests__/e2e/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const files = [

// next/image
'_next/static/media/img.8a5ad2fe_[width].avif',
'_next/static/media/get-props.8a5ad2fe_[width].avif',
'_next/static/media/get-props-mobile.7d5f5264_[width].avif',
'images/img_[width].avif',
'id/237/200/300_[width].avif',
'id/238/200/300_[width].avif',
Expand All @@ -23,6 +25,8 @@ const files = [

// next/image
'_next/static/media/img.8a5ad2fe_[width].webp',
'_next/static/media/get-props.8a5ad2fe_[width].webp',
'_next/static/media/get-props-mobile.7d5f5264_[width].webp',
'images/img_[width].webp',
'id/237/200/300_[width].webp',
'id/238/200/300_[width].webp',
Expand All @@ -36,6 +40,8 @@ const files = [

// next/image
'_next/static/media/img.8a5ad2fe_[width].png',
'_next/static/media/get-props.8a5ad2fe_[width].png',
'_next/static/media/get-props-mobile.7d5f5264_[width].png',
'images/img_[width].png',
'id/237/200/300_[width].jpg',
'id/238/200/300_[width].jpg',
Expand Down
68 changes: 68 additions & 0 deletions docs/docs/03-Features/03-get-props.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
description: This page introduces the `getOptimizedImageProps` function, which is used to get the props of a component.
---

# Get Optimized Image Props

`getOptimizedImageProps` is a function that extracts the internal processing of the `Image` component provided by this library.

For example, if you use the `<img>` element directly without using the `Image` component, you can use `getOptimizedImageProps` to get the properties to pass to the `<img>` element.
This allows for more advanced use cases such as art direction using the `<picture>` element or displaying images using the CSS `background-image` property.

## Usage

### Background image

```tsx
'use client'

import { getOptimizedImageProps } from 'next-export-optimize-images/image'

import src from '../images/sample.png'

export default function BackgroundImage() {
const props = getOptimizedImageProps({ src, alt: '' }).props

return (
<div
style={{
backgroundImage: `url(${props.src})`,
width: props.width,
height: props.height,
}}
></div>
)
}

export default WithPropsComponent
```

### Art direction

```tsx
'use client'

import { getOptimizedImageProps } from 'next-export-optimize-images/image'

import srcDesktop from '../images/sample-desktop.png'
import srcMobile from '../images/sample-mobile.png'

export default function BackgroundImage() {
const propsDesktop = getOptimizedImageProps({ src: srcDesktop, alt: '' }).props
const propsMobile = getOptimizedImageProps({ src: srcMobile, alt: '' }).props

return (
<picture>
<source
srcSet={propsMobile.srcSet}
width={propsMobile.width}
height={propsMobile.height}
media="(max-width: 768px)"
/>
<img {...propsDesktop} />
</picture>
)
}

export default WithPropsComponent
```
4 changes: 2 additions & 2 deletions docs/docs/05-comparison.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ Let me list some of the disadvantages.

Because of the above characteristics, the library is recommended for users other than those listed below.

- I want to develop without being conscious of the fact that it is an export, the same as when using next/image.
- Remote images need to be optimized.
- Want to use it as simply as possible.
- When multiple formats of images are required to be supported by Picture component.
-

## Please let me know if there are others!

Expand Down
6 changes: 3 additions & 3 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@
"devDependencies": {
"@docusaurus/core": "2.4.3",
"@docusaurus/preset-classic": "2.4.3",
"@heroicons/react": "2.1.1",
"@heroicons/react": "2.1.3",
"@mdx-js/react": "1.6.22",
"autoprefixer": "10.4.18",
"autoprefixer": "10.4.19",
"clsx": "2.1.0",
"postcss": "8.4.35",
"postcss": "8.4.38",
"prettier": "3.2.5",
"prettier-plugin-tailwindcss": "0.5.12",
"prism-react-renderer": "1.3.5",
Expand Down
50 changes: 34 additions & 16 deletions docs/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2471,7 +2471,7 @@
"@docusaurus/theme-search-algolia" "2.4.3"
"@docusaurus/types" "2.4.3"

"@docusaurus/[email protected]", "react-loadable@npm:@docusaurus/[email protected]":
"@docusaurus/[email protected]":
version "5.5.2"
resolved "https://registry.yarnpkg.com/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz#81aae0db81ecafbdaee3651f12804580868fa6ce"
integrity sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==
Expand Down Expand Up @@ -2628,10 +2628,10 @@
dependencies:
"@hapi/hoek" "^9.0.0"

"@heroicons/[email protected].1":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-2.1.1.tgz#422deb80c4d6caf3371aec6f4bee8361a354dc13"
integrity sha512-JyyN9Lo66kirbCMuMMRPtJxtKJoIsXKS569ebHGGRKbl8s4CtUfLnyKJxteA+vIKySocO4s1SkTkGS4xtG/yEA==
"@heroicons/[email protected].3":
version "2.1.3"
resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-2.1.3.tgz#78a2a7f504a7370283d07eabcddc7fec04f503db"
integrity sha512-fEcPfo4oN345SoqdlCDdSa4ivjaKbk0jTd+oubcgNxnNgAfzysfwWfQUr+51wigiWHQQRiZNd1Ao0M5Y3M2EGg==

"@jridgewell/gen-mapping@^0.1.0":
version "0.1.1"
Expand Down Expand Up @@ -3503,13 +3503,13 @@ at-least-node@^1.0.0:
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==

[email protected].18:
version "10.4.18"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.18.tgz#fcb171a3b017be7cb5d8b7a825f5aacbf2045163"
integrity sha512-1DKbDfsr6KUElM6wg+0zRNkB/Q7WcKYAaK+pzXn+Xqmszm/5Xa9coeNdtP88Vi+dPzZnMjhge8GIV49ZQkDa+g==
[email protected].19:
version "10.4.19"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.19.tgz#ad25a856e82ee9d7898c59583c1afeb3fa65f89f"
integrity sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==
dependencies:
browserslist "^4.23.0"
caniuse-lite "^1.0.30001591"
caniuse-lite "^1.0.30001599"
fraction.js "^4.3.7"
normalize-range "^0.1.2"
picocolors "^1.0.0"
Expand Down Expand Up @@ -3791,11 +3791,16 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001332, caniuse-lite@^1.0.30001335:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001340.tgz#029a2f8bfc025d4820fafbfaa6259fd7778340c7"
integrity sha512-jUNz+a9blQTQVu4uFcn17uAD8IDizPzQkIKh3LCJfg9BkyIqExYYdyc/ZSlWUSKb8iYiXxKsxbv4zYSvkqjrxw==

caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001591:
caniuse-lite@^1.0.30001587:
version "1.0.30001591"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz#16745e50263edc9f395895a7cd468b9f3767cf33"
integrity sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==

caniuse-lite@^1.0.30001599:
version "1.0.30001609"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001609.tgz#fc34fad75c0c6d6d6303bdbceec2da8f203dabd6"
integrity sha512-JFPQs34lHKx1B5t1EpQpWH4c+29zIyn/haGsbpfq3suuV9v56enjFt23zqijxGTMwy1p/4H2tjnQMY+p1WoAyA==

ccount@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043"
Expand Down Expand Up @@ -7093,14 +7098,14 @@ postcss-zindex@^5.1.0:
resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-5.1.0.tgz#4a5c7e5ff1050bd4c01d95b1847dfdcc58a496ff"
integrity sha512-fgFMf0OtVSBR1va1JNHYgMxYk73yhn/qb4uQDq1DLGYolz8gHCyr/sesEuGUaYs58E3ZJRcpoGuPVoB7Meiq9A==

[email protected].35:
version "8.4.35"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.35.tgz#60997775689ce09011edf083a549cea44aabe2f7"
integrity sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==
[email protected].38:
version "8.4.38"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e"
integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==
dependencies:
nanoid "^3.3.7"
picocolors "^1.0.0"
source-map-js "^1.0.2"
source-map-js "^1.2.0"

postcss@^8.3.11, postcss@^8.4.13, postcss@^8.4.7:
version "8.4.13"
Expand Down Expand Up @@ -7393,6 +7398,14 @@ react-loadable-ssr-addon-v5-slorber@^1.0.1:
dependencies:
"@babel/runtime" "^7.10.3"

"react-loadable@npm:@docusaurus/[email protected]":
version "5.5.2"
resolved "https://registry.yarnpkg.com/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz#81aae0db81ecafbdaee3651f12804580868fa6ce"
integrity sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==
dependencies:
"@types/react" "*"
prop-types "^15.6.2"

react-router-config@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/react-router-config/-/react-router-config-5.1.1.tgz#0f4263d1a80c6b2dc7b9c1902c9526478194a988"
Expand Down Expand Up @@ -8044,6 +8057,11 @@ source-map-js@^1.0.2:
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==

source-map-js@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af"
integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==

source-map-support@~0.5.20:
version "0.5.21"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
Expand Down
1 change: 1 addition & 0 deletions image.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import Image from './dist/components/image'
export * from './dist/components/image'
export default Image
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@
"@semantic-release/git": "10.0.1",
"@testing-library/jest-dom": "6.4.2",
"@testing-library/react": "14.2.1",
"@tsconfig/strictest": "2.0.3",
"@tsconfig/strictest": "2.0.5",
"@types/app-root-path": "1.2.8",
"@types/cli-progress": "3.11.5",
"@types/fs-extra": "11.0.4",
"@types/jest": "29.5.12",
"@types/lodash.uniqwith": "4.5.9",
"@types/node": "20.11.25",
"@types/react": "18.2.64",
"@types/react": "18.2.77",
"@types/recursive-readdir": "^2.2.4",
"@types/sharp": "0.32.0",
"@typescript-eslint/eslint-plugin": "6.21.0",
Expand Down
1 change: 1 addition & 0 deletions src/components/image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ const CustomImage = forwardRef<HTMLImageElement, ImageProps>((props, forwardedRe
})
CustomImage.displayName = 'CustomImage'

export { default as getOptimizedImageProps } from './utils/getOptimizedImageProps'
export default CustomImage
19 changes: 11 additions & 8 deletions src/components/picture.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@ const Picture = forwardRef<HTMLImageElement, ImageProps>((props, forwardedRef) =
}

const additionalFormats = [...new Set(config.generateFormats ?? ['webp'])]
const sources = additionalFormats.map((format, i) => ({
srcSet: getImageProps({
const sources = additionalFormats.map((format, i) => {
const sourceProps = getImageProps({
...props,
loader: imageLoader(i),
}).props.srcSet,
type: `image/${format}`,
width: props.width,
height: props.height,
sizes: props.sizes,
}))
}).props
return {
srcSet: sourceProps.srcSet,
type: `image/${format}`,
width: sourceProps.width,
height: sourceProps.height,
sizes: sourceProps.sizes,
}
})

return (
<picture>
Expand Down
23 changes: 23 additions & 0 deletions src/components/utils/getOptimizedImageProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { getImageProps, ImageProps } from 'next/image'

import getStringSrc from './getStringSrc'
import imageLoader from './imageLoader'

export type ImgProps = ReturnType<typeof getImageProps>

const getOptimizedImageProps = (props: ImageProps): ImgProps => {
const srcStr = getStringSrc(props.src)

return getImageProps({
...props,
loader: props.loader || imageLoader(),
...(props.blurDataURL
? { blurDataURL: props.blurDataURL }
: typeof props.src === 'string' && props.placeholder === 'blur' && props.loader === undefined
? { blurDataURL: imageLoader()({ src: props.src, width: 8, quality: 10 }) }
: {}),
unoptimized: props.unoptimized !== undefined ? props.unoptimized : srcStr.endsWith('.svg'),
})
}

export default getOptimizedImageProps
Loading

0 comments on commit ed76866

Please sign in to comment.