astro-lqip 1.2.2 → 1.3.1

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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- <a href="https://github.com/felixicaza/astro-lqip/">
1
+ <a href="https://astro-lqip.web.app/">
2
2
  <img src="./assets/logo.png" alt="Astro LQIP Logo" width="200" height="200" />
3
3
  </a>
4
4
 
@@ -7,7 +7,7 @@
7
7
  [![GitHub Release](https://img.shields.io/github/v/release/felixicaza/astro-lqip?logo=npm)](https://www.npmjs.com/package/astro-lqip)
8
8
  [![GitHub License](https://img.shields.io/github/license/felixicaza/astro-lqip)](https://github.com/felixicaza/astro-lqip/blob/main/LICENSE)
9
9
 
10
- Native extended Astro component for generating low quality image placeholders (LQIP).
10
+ Native extended Astro components for generating low quality image placeholders (LQIP).
11
11
 
12
12
  ## ⬇️ Installation
13
13
 
@@ -31,7 +31,16 @@ yarn add astro-lqip
31
31
 
32
32
  ## 🚀 Usage
33
33
 
34
- In your current Astro project, just replace the import of the native Astro `<Picture />` component with the one provided by [astro-lqip](https://www.npmjs.com/package/astro-lqip).
34
+ In your current Astro project, just replace the import of the native Astro `<Image>` or `<Picture>` components with the ones provided by [astro-lqip](https://astro-lqip.web.app/).
35
+
36
+ ### Image
37
+
38
+ ```diff
39
+ - import { Image } from 'astro:assets';
40
+ + import { Image } from 'astro-lqip/components';
41
+ ```
42
+
43
+ ### Picture
35
44
 
36
45
  ```diff
37
46
  - import { Picture } from 'astro:assets';
@@ -42,16 +51,19 @@ Example:
42
51
 
43
52
  ```astro
44
53
  ---
45
- import { Picture } from 'astro-lqip/components'
46
- import image from './path/to/image.png'
54
+ import { Image, Picture } from 'astro-lqip/components';
55
+
56
+ import image from './path/to/image.png';
57
+ import otherImage from './path/to/other-image.png';
47
58
  ---
48
59
 
49
- <Picture src={image} alt="Cover Image" width={220} height={220} />
60
+ <Image src={image} alt="Cover Image" width={220} height={220} />
61
+ <Picture src={otherImage} alt="Other cover Image" width={220} height={220} />
50
62
  ```
51
63
 
52
64
  ## ⚙️ Props
53
65
 
54
- This `<Picture />` component supports all the props of the [native Astro component](https://docs.astro.build/en/reference/modules/astro-assets/#picture-properties), but adds a couple of props for LQIP management:
66
+ Both `<Image>` and `<Picture>` components support all the props of the [native Astro components](https://docs.astro.build/en/reference/modules/astro-assets/), but adds a couple of props for LQIP management:
55
67
 
56
68
  - `lqip`: The LQIP type to use. It can be one of the following:
57
69
  - `base64`: Generates a Base64-encoded LQIP image. (default option)
@@ -61,31 +73,37 @@ This `<Picture />` component supports all the props of the [native Astro compone
61
73
  - `lqipSize`: The size of the LQIP image, which can be any number from `4` to `64`. (default is 4)
62
74
 
63
75
  > [!WARNING]
64
- > A major size in the lqipSize prop can significantly impact the performance of your application.
76
+ > A major size in the `lqipSize` prop can significantly impact the performance of your application.
65
77
 
66
78
  Example:
67
79
 
68
80
  ```astro
69
81
  ---
70
- import { Picture } from 'astro-lqip/components'
71
- import image from './path/to/image.png'
82
+ import { Image, Picture } from 'astro-lqip/components';
83
+
84
+ import image from './path/to/image.png';
85
+ import otherImage from './path/to/other-image.png';
72
86
  ---
73
87
 
74
- <Picture src={image} alt="Cover Image" width={220} height={220} lqip="css" lqipSize={7} />
88
+ <Image src={image} alt="Cover Image" width={220} height={220} lqip="svg" lqipSize={10} />
89
+ <Picture src={otherImage} alt="Other cover Image" width={220} height={220} lqip="css" lqipSize={7} />
75
90
  ```
76
91
 
92
+ > [!TIP]
93
+ > For the `<Image>` component, a `parentAttributes` prop similar to `pictureAttributes` has been added.
94
+
77
95
  ## 📝 ToDo
78
96
 
79
- - [ ] Add support for Image component.
97
+ - [x] Add support for Image component.
80
98
  - [x] Add support for more lqip techniques.
81
99
  - [ ] Test for remote images.
82
- - [ ] Optimize current CSS usage.
100
+ - [x] Optimize current CSS usage.
83
101
  - [x] Improve docs page.
84
102
  - [ ] Test support for SSR mode.
85
103
 
86
104
  ## 💡 Knowledge
87
105
 
88
- Since this integration is built on top of Astro's native `<Picture>` component, you can refer to the [Astro documentation](https://docs.astro.build/en/guides/images/#picture-) for more information on how to use it.
106
+ Since this integration is built on top of Astro native `<Image>` and `<Picture>` components, you can refer to the [Astro documentation](https://docs.astro.build/en/guides/images/) for more information on how to use it.
89
107
 
90
108
  ## 🤝 Contributing
91
109
  If you wish to contribute to this project, you can do so by reading the [contribution guide](https://github.com/felixicaza/astro-lqip/blob/main/CONTRIBUTING.md).
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "astro-lqip",
3
- "version": "1.2.2",
4
- "description": "Native extended Astro component for generating low quality image placeholders (LQIP).",
3
+ "version": "1.3.1",
4
+ "description": "Native extended Astro components for generating low quality image placeholders (LQIP).",
5
5
  "keywords": [
6
6
  "astro",
7
7
  "astro-component",
8
8
  "astro-integration",
9
9
  "image",
10
+ "picture",
10
11
  "lqip"
11
12
  ],
12
- "homepage": "https://github.com/felixicaza/astro-lqip",
13
+ "homepage": "https://astro-lqip.web.app",
13
14
  "bugs": {
14
15
  "url": "https://github.com/felixicaza/astro-lqip/issues"
15
16
  },
@@ -36,21 +37,21 @@
36
37
  "plaiceholder": "3.0.0"
37
38
  },
38
39
  "devDependencies": {
39
- "@eslint/js": "9.30.1",
40
- "@typescript-eslint/parser": "8.36.0",
41
- "astro": "5.11.0",
42
- "bumpp": "10.2.0",
43
- "eslint": "9.30.1",
40
+ "@eslint/js": "9.33.0",
41
+ "@typescript-eslint/parser": "8.39.1",
42
+ "astro": "5.12.9",
43
+ "bumpp": "10.2.3",
44
+ "eslint": "9.33.0",
44
45
  "eslint-plugin-astro": "1.3.1",
45
46
  "eslint-plugin-jsonc": "2.20.1",
46
47
  "eslint-plugin-jsx-a11y": "6.10.2",
47
- "eslint-plugin-package-json": "0.44.1",
48
+ "eslint-plugin-package-json": "0.53.0",
48
49
  "eslint-plugin-yml": "1.18.0",
49
50
  "globals": "16.3.0",
50
- "jiti": "2.4.2",
51
+ "jiti": "2.5.1",
51
52
  "nano-staged": "0.8.0",
52
53
  "neostandard": "0.12.2",
53
- "simple-git-hooks": "2.13.0"
54
+ "simple-git-hooks": "2.13.1"
54
55
  },
55
56
  "peerDependencies": {
56
57
  "astro": ">=3.3.0"
@@ -0,0 +1,64 @@
1
+ ---
2
+ import type { LocalImageProps, RemoteImageProps } from 'astro:assets'
3
+ import type { HTMLAttributes } from 'astro/types'
4
+ import type { Props as LqipProps } from '../types'
5
+
6
+ import { PREFIX } from '../constants'
7
+
8
+ import { resolveImageMetadata } from '../utils/resolveImageMetadata'
9
+ import { renderSVGNode } from '../utils/renderSVGNode'
10
+ import { getLqipStyle } from '../utils/getLqipStyle'
11
+ import { getLqip } from '../utils/getLqip'
12
+
13
+ import { Image as ImageComponent } from 'astro:assets'
14
+
15
+ import '../styles/lqip.css'
16
+
17
+ type Props = (LocalImageProps | RemoteImageProps) & LqipProps & {
18
+ parentAttributes?: HTMLAttributes<'div'>
19
+ }
20
+
21
+ const { class: className, lqip = 'base64', lqipSize = 4, parentAttributes = {}, ...props } = Astro.props as Props
22
+
23
+ const isDevelopment = import.meta.env.MODE === 'development'
24
+
25
+ const imageMetadata = await resolveImageMetadata(props.src)
26
+ const lqipImage = await getLqip(imageMetadata, isDevelopment, lqip, lqipSize)
27
+
28
+ let svgHTML = ''
29
+
30
+ if (lqip === 'svg' && Array.isArray(lqipImage)) {
31
+ svgHTML = renderSVGNode(lqipImage as [string, Record<string, any>, any[]])
32
+ }
33
+
34
+ const lqipStyle = getLqipStyle(lqip, lqipImage, svgHTML)
35
+
36
+ const forbiddenVars = ['--lqip-background', '--z-index', '--opacity']
37
+ const styleProps = parentAttributes.style ?? {}
38
+
39
+ for (const key of Object.keys(styleProps)) {
40
+ if (forbiddenVars.includes(key)) {
41
+ console.warn(
42
+ `${PREFIX} The CSS variable “${key}” should not be passed in \`parentAttributes.style\` because it can override the functionality of LQIP.`
43
+ )
44
+ }
45
+ }
46
+
47
+ const combinedStyle = {
48
+ ...styleProps,
49
+ ...lqipStyle
50
+ }
51
+
52
+ const combinedParentAttributes = {
53
+ ...parentAttributes,
54
+ style: combinedStyle
55
+ }
56
+ ---
57
+
58
+ <div class={className} data-astro-lqip {...combinedParentAttributes}>
59
+ <ImageComponent
60
+ {...props}
61
+ class={className}
62
+ onload="parentElement.style.setProperty('--z-index', 1), parentElement.style.setProperty('--opacity', 0)"
63
+ />
64
+ </div>
@@ -1,5 +1,6 @@
1
1
  ---
2
- import type { Props } from '../types'
2
+ import type { Props as AstroPictureProps } from 'astro/components/Picture.astro'
3
+ import type { Props as LqipProps } from '../types'
3
4
 
4
5
  import { PREFIX } from '../constants'
5
6
 
@@ -10,6 +11,10 @@ import { getLqip } from '../utils/getLqip'
10
11
 
11
12
  import { Picture as PictureComponent } from 'astro:assets'
12
13
 
14
+ import '../styles/lqip.css'
15
+
16
+ type Props = AstroPictureProps & LqipProps
17
+
13
18
  const { class: className, lqip = 'base64', lqipSize = 4, pictureAttributes = {}, ...props } = Astro.props as Props
14
19
 
15
20
  const isDevelopment = import.meta.env.MODE === 'development'
@@ -47,40 +52,9 @@ const combinedPictureAttributes = {
47
52
  }
48
53
  ---
49
54
 
50
- <style is:inline>
51
- picture {
52
- --opacity: 1;
53
- --z-index: 0;
54
-
55
- position: relative;
56
- display: inline-block;
57
- }
58
-
59
- picture::after {
60
- content: "";
61
- inset: 0;
62
- width: 100%;
63
- height: 100%;
64
- position: absolute;
65
- pointer-events: none;
66
- transition: opacity 1s;
67
- opacity: var(--opacity);
68
- z-index: var(--z-index);
69
- background: var(--lqip-background);
70
- background-size: cover;
71
- background-position: 50% 50%;
72
- }
73
-
74
- picture img {
75
- z-index: 1;
76
- position: relative;
77
- overflow: hidden;
78
- }
79
- </style>
80
-
81
55
  <PictureComponent
82
56
  {...props}
83
57
  class={className}
84
- pictureAttributes={{ ...combinedPictureAttributes }}
58
+ pictureAttributes={{ 'data-astro-lqip': '', ...combinedPictureAttributes }}
85
59
  onload="parentElement.style.setProperty('--z-index', 1), parentElement.style.setProperty('--opacity', 0)"
86
60
  />
package/src/index.ts CHANGED
@@ -1 +1,2 @@
1
1
  export { default as Picture } from './components/Picture.astro'
2
+ export { default as Image } from './components/Image.astro'
@@ -0,0 +1,30 @@
1
+ [data-astro-lqip] {
2
+ --opacity: 1;
3
+ --z-index: 0;
4
+
5
+ position: relative;
6
+ display: inline-block;
7
+ width: fit-content;
8
+ height: fit-content;
9
+ }
10
+
11
+ [data-astro-lqip]::after {
12
+ content: "";
13
+ inset: 0;
14
+ width: 100%;
15
+ height: 100%;
16
+ position: absolute;
17
+ pointer-events: none;
18
+ transition: opacity 1s;
19
+ opacity: var(--opacity);
20
+ z-index: var(--z-index);
21
+ background: var(--lqip-background);
22
+ background-size: cover;
23
+ background-position: 50% 50%;
24
+ }
25
+
26
+ [data-astro-lqip] img {
27
+ z-index: 1;
28
+ position: relative;
29
+ overflow: hidden;
30
+ }
@@ -1,8 +1,6 @@
1
- import type { Props as PictureProps } from 'astro/components/Picture.astro'
2
-
3
1
  import type { LqipType } from './lqip.type'
4
2
 
5
- export type Props = PictureProps & {
3
+ export type Props = {
6
4
  /**
7
5
  * LQIP type.
8
6
  * This can be 'color', 'css', 'svg' or 'base64'.