astro-lqip 1.2.2 → 1.3.0
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 +28 -10
- package/package.json +9 -9
- package/src/components/Image.astro +95 -0
- package/src/components/Picture.astro +8 -5
- package/src/index.ts +1 -0
- package/src/types/props.type.ts +1 -3
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<a href="https://
|
|
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
|
[](https://www.npmjs.com/package/astro-lqip)
|
|
8
8
|
[](https://github.com/felixicaza/astro-lqip/blob/main/LICENSE)
|
|
9
9
|
|
|
10
|
-
Native extended Astro
|
|
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
|
|
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'
|
|
54
|
+
import { Image, Picture } from 'astro-lqip/components'
|
|
55
|
+
|
|
46
56
|
import image from './path/to/image.png'
|
|
57
|
+
import otherImage from './path/to/other-image.png'
|
|
47
58
|
---
|
|
48
59
|
|
|
49
|
-
<
|
|
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
|
-
|
|
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)
|
|
@@ -67,16 +79,22 @@ Example:
|
|
|
67
79
|
|
|
68
80
|
```astro
|
|
69
81
|
---
|
|
70
|
-
import { Picture } from 'astro-lqip/components'
|
|
82
|
+
import { Image, Picture } from 'astro-lqip/components'
|
|
83
|
+
|
|
71
84
|
import image from './path/to/image.png'
|
|
85
|
+
import otherImage from './path/to/other-image.png'
|
|
72
86
|
---
|
|
73
87
|
|
|
74
|
-
<
|
|
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
|
-
- [
|
|
97
|
+
- [x] Add support for Image component.
|
|
80
98
|
- [x] Add support for more lqip techniques.
|
|
81
99
|
- [ ] Test for remote images.
|
|
82
100
|
- [ ] Optimize current CSS usage.
|
|
@@ -85,7 +103,7 @@ import image from './path/to/image.png'
|
|
|
85
103
|
|
|
86
104
|
## 💡 Knowledge
|
|
87
105
|
|
|
88
|
-
Since this integration is built on top of Astro
|
|
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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro-lqip",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Native extended Astro component for generating low quality image placeholders (LQIP).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"astro",
|
|
@@ -36,21 +36,21 @@
|
|
|
36
36
|
"plaiceholder": "3.0.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@eslint/js": "9.
|
|
40
|
-
"@typescript-eslint/parser": "8.
|
|
41
|
-
"astro": "5.
|
|
42
|
-
"bumpp": "10.2.
|
|
43
|
-
"eslint": "9.
|
|
39
|
+
"@eslint/js": "9.33.0",
|
|
40
|
+
"@typescript-eslint/parser": "8.39.1",
|
|
41
|
+
"astro": "5.12.9",
|
|
42
|
+
"bumpp": "10.2.3",
|
|
43
|
+
"eslint": "9.33.0",
|
|
44
44
|
"eslint-plugin-astro": "1.3.1",
|
|
45
45
|
"eslint-plugin-jsonc": "2.20.1",
|
|
46
46
|
"eslint-plugin-jsx-a11y": "6.10.2",
|
|
47
|
-
"eslint-plugin-package-json": "0.
|
|
47
|
+
"eslint-plugin-package-json": "0.53.0",
|
|
48
48
|
"eslint-plugin-yml": "1.18.0",
|
|
49
49
|
"globals": "16.3.0",
|
|
50
|
-
"jiti": "2.
|
|
50
|
+
"jiti": "2.5.1",
|
|
51
51
|
"nano-staged": "0.8.0",
|
|
52
52
|
"neostandard": "0.12.2",
|
|
53
|
-
"simple-git-hooks": "2.13.
|
|
53
|
+
"simple-git-hooks": "2.13.1"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"astro": ">=3.3.0"
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { LocalImageProps, RemoteImageProps } from 'astro:assets'
|
|
3
|
+
import type { Props as LqipProps } from '../types'
|
|
4
|
+
import type { HTMLAttributes } from 'astro/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
|
+
type Props = (LocalImageProps | RemoteImageProps) & LqipProps & {
|
|
16
|
+
parentAttributes?: HTMLAttributes<'div'>
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const { class: className, lqip = 'base64', lqipSize = 4, parentAttributes = {}, ...props } = Astro.props as Props
|
|
20
|
+
|
|
21
|
+
const isDevelopment = import.meta.env.MODE === 'development'
|
|
22
|
+
|
|
23
|
+
const imageMetadata = await resolveImageMetadata(props.src)
|
|
24
|
+
const lqipImage = await getLqip(imageMetadata, isDevelopment, lqip, lqipSize)
|
|
25
|
+
|
|
26
|
+
let svgHTML = ''
|
|
27
|
+
|
|
28
|
+
if (lqip === 'svg' && Array.isArray(lqipImage)) {
|
|
29
|
+
svgHTML = renderSVGNode(lqipImage as [string, Record<string, any>, any[]])
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const lqipStyle = getLqipStyle(lqip, lqipImage, svgHTML)
|
|
33
|
+
|
|
34
|
+
const forbiddenVars = ['--lqip-background', '--z-index', '--opacity']
|
|
35
|
+
const styleProps = parentAttributes.style ?? {}
|
|
36
|
+
|
|
37
|
+
for (const key of Object.keys(styleProps)) {
|
|
38
|
+
if (forbiddenVars.includes(key)) {
|
|
39
|
+
console.warn(
|
|
40
|
+
`${PREFIX} The CSS variable “${key}” should not be passed in \`parentAttributes.style\` because it can override the functionality of LQIP.`
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const combinedStyle = {
|
|
46
|
+
...styleProps,
|
|
47
|
+
...lqipStyle
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const combinedParentAttributes = {
|
|
51
|
+
...parentAttributes,
|
|
52
|
+
style: combinedStyle
|
|
53
|
+
}
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
<style is:inline>
|
|
57
|
+
div[data-astro-lqip] {
|
|
58
|
+
--opacity: 1;
|
|
59
|
+
--z-index: 0;
|
|
60
|
+
|
|
61
|
+
position: relative;
|
|
62
|
+
display: inline-block;
|
|
63
|
+
width: fit-content;
|
|
64
|
+
height: fit-content;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
div[data-astro-lqip]::after {
|
|
68
|
+
content: "";
|
|
69
|
+
inset: 0;
|
|
70
|
+
width: 100%;
|
|
71
|
+
height: 100%;
|
|
72
|
+
position: absolute;
|
|
73
|
+
pointer-events: none;
|
|
74
|
+
transition: opacity 1s;
|
|
75
|
+
opacity: var(--opacity);
|
|
76
|
+
z-index: var(--z-index);
|
|
77
|
+
background: var(--lqip-background);
|
|
78
|
+
background-size: cover;
|
|
79
|
+
background-position: 50% 50%;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
div[data-astro-lqip] img {
|
|
83
|
+
z-index: 1;
|
|
84
|
+
position: relative;
|
|
85
|
+
overflow: hidden;
|
|
86
|
+
}
|
|
87
|
+
</style>
|
|
88
|
+
|
|
89
|
+
<div class={className} data-astro-lqip {...combinedParentAttributes}>
|
|
90
|
+
<ImageComponent
|
|
91
|
+
{...props}
|
|
92
|
+
class={className}
|
|
93
|
+
onload="parentElement.style.setProperty('--z-index', 1), parentElement.style.setProperty('--opacity', 0)"
|
|
94
|
+
/>
|
|
95
|
+
</div>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
import type { Props } from '
|
|
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,8 @@ import { getLqip } from '../utils/getLqip'
|
|
|
10
11
|
|
|
11
12
|
import { Picture as PictureComponent } from 'astro:assets'
|
|
12
13
|
|
|
14
|
+
type Props = AstroPictureProps & LqipProps
|
|
15
|
+
|
|
13
16
|
const { class: className, lqip = 'base64', lqipSize = 4, pictureAttributes = {}, ...props } = Astro.props as Props
|
|
14
17
|
|
|
15
18
|
const isDevelopment = import.meta.env.MODE === 'development'
|
|
@@ -48,7 +51,7 @@ const combinedPictureAttributes = {
|
|
|
48
51
|
---
|
|
49
52
|
|
|
50
53
|
<style is:inline>
|
|
51
|
-
picture {
|
|
54
|
+
picture[data-astro-lqip] {
|
|
52
55
|
--opacity: 1;
|
|
53
56
|
--z-index: 0;
|
|
54
57
|
|
|
@@ -56,7 +59,7 @@ const combinedPictureAttributes = {
|
|
|
56
59
|
display: inline-block;
|
|
57
60
|
}
|
|
58
61
|
|
|
59
|
-
picture::after {
|
|
62
|
+
picture[data-astro-lqip]::after {
|
|
60
63
|
content: "";
|
|
61
64
|
inset: 0;
|
|
62
65
|
width: 100%;
|
|
@@ -71,7 +74,7 @@ const combinedPictureAttributes = {
|
|
|
71
74
|
background-position: 50% 50%;
|
|
72
75
|
}
|
|
73
76
|
|
|
74
|
-
picture img {
|
|
77
|
+
picture[data-astro-lqip] img {
|
|
75
78
|
z-index: 1;
|
|
76
79
|
position: relative;
|
|
77
80
|
overflow: hidden;
|
|
@@ -81,6 +84,6 @@ const combinedPictureAttributes = {
|
|
|
81
84
|
<PictureComponent
|
|
82
85
|
{...props}
|
|
83
86
|
class={className}
|
|
84
|
-
pictureAttributes={{ ...combinedPictureAttributes }}
|
|
87
|
+
pictureAttributes={{ 'data-astro-lqip': '', ...combinedPictureAttributes }}
|
|
85
88
|
onload="parentElement.style.setProperty('--z-index', 1), parentElement.style.setProperty('--opacity', 0)"
|
|
86
89
|
/>
|
package/src/index.ts
CHANGED
package/src/types/props.type.ts
CHANGED