@son426/vite-image 0.1.2 → 0.1.3
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 +17 -47
- package/dist/react/index.d.ts +4 -8
- package/dist/react/index.js +8 -18
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
- package/types.d.ts +1 -19
package/README.md
CHANGED
|
@@ -48,13 +48,13 @@ export default defineConfig({
|
|
|
48
48
|
});
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
**Important**:
|
|
51
|
+
**Important**: The `viteImage()` function returns an array of plugins, so you should spread it when adding to the plugins array.
|
|
52
52
|
|
|
53
53
|
### 2. Use the Component
|
|
54
54
|
|
|
55
|
-
####
|
|
55
|
+
#### Using `?vite-image` query (Required)
|
|
56
56
|
|
|
57
|
-
The
|
|
57
|
+
The `?vite-image` query parameter is required and automatically generates all required image data. When using `?vite-image`, the `src` prop must be an object (not a string).
|
|
58
58
|
|
|
59
59
|
```typescript
|
|
60
60
|
import Image from "@son426/vite-image/react";
|
|
@@ -63,7 +63,7 @@ import bgImage from "@/assets/image.webp?vite-image";
|
|
|
63
63
|
function MyComponent() {
|
|
64
64
|
return (
|
|
65
65
|
<Image
|
|
66
|
-
|
|
66
|
+
src={bgImage}
|
|
67
67
|
fill={false}
|
|
68
68
|
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 100vw, 1920px"
|
|
69
69
|
alt="Description"
|
|
@@ -72,6 +72,8 @@ function MyComponent() {
|
|
|
72
72
|
}
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
+
**Important**: When using `?vite-image`, the `src` prop must receive the imported object directly. String URLs are not supported for `?vite-image` imports.
|
|
76
|
+
|
|
75
77
|
The `?vite-image` query automatically generates:
|
|
76
78
|
|
|
77
79
|
- `src`: Optimized image URL
|
|
@@ -79,40 +81,13 @@ The `?vite-image` query automatically generates:
|
|
|
79
81
|
- `lqipSrc`: Low Quality Image Placeholder (base64 inline)
|
|
80
82
|
- `width` and `height`: Image dimensions
|
|
81
83
|
|
|
82
|
-
#### Method 2: Using individual props
|
|
83
|
-
|
|
84
|
-
You can also import and use individual image data:
|
|
85
|
-
|
|
86
|
-
```typescript
|
|
87
|
-
import Image from "@son426/vite-image/react";
|
|
88
|
-
|
|
89
|
-
import imageSrcSet from "@/assets/image.webp?w=640;1024;1920&format=webp&as=srcset";
|
|
90
|
-
import imageMeta from "@/assets/image.webp?w=1920&format=webp&as=meta";
|
|
91
|
-
import imageLqipSrc from "@/assets/image.webp?w=20&blur=2&quality=20&format=webp&inline";
|
|
92
|
-
|
|
93
|
-
function MyComponent() {
|
|
94
|
-
return (
|
|
95
|
-
<Image
|
|
96
|
-
src={imageMeta.src}
|
|
97
|
-
srcSet={imageSrcSet}
|
|
98
|
-
lqipSrc={imageLqipSrc}
|
|
99
|
-
width={imageMeta.width}
|
|
100
|
-
height={imageMeta.height}
|
|
101
|
-
fill={false}
|
|
102
|
-
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 100vw, 1920px"
|
|
103
|
-
alt="Description"
|
|
104
|
-
/>
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
84
|
### Fill Mode
|
|
110
85
|
|
|
111
86
|
For images that fill their container (similar to Next.js Image):
|
|
112
87
|
|
|
113
88
|
```typescript
|
|
114
89
|
<div style={{ position: "relative", width: "100%", height: "400px" }}>
|
|
115
|
-
<Image
|
|
90
|
+
<Image src={bgImage} fill={true} sizes="100vw" alt="Description" />
|
|
116
91
|
</div>
|
|
117
92
|
```
|
|
118
93
|
|
|
@@ -120,21 +95,16 @@ For images that fill their container (similar to Next.js Image):
|
|
|
120
95
|
|
|
121
96
|
### Image Props
|
|
122
97
|
|
|
123
|
-
| Prop | Type | Required | Description
|
|
124
|
-
| ----------- | --------------------- | -------- |
|
|
125
|
-
| `
|
|
126
|
-
| `
|
|
127
|
-
| `
|
|
128
|
-
| `
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
| `className` | `string` | No | Additional CSS classes |
|
|
134
|
-
| `style` | `CSSProperties` | No | Additional inline styles |
|
|
135
|
-
| `...props` | `ImgHTMLAttributes` | No | All standard img element attributes |
|
|
136
|
-
|
|
137
|
-
\* Either `imgData` or `src` (with `width` and `height` when `fill={false}`) is required.
|
|
98
|
+
| Prop | Type | Required | Description |
|
|
99
|
+
| ----------- | --------------------- | -------- | ------------------------------------------ |
|
|
100
|
+
| `src` | `ResponsiveImageData` | Yes | Image data object from `?vite-image` query |
|
|
101
|
+
| `fill` | `boolean` | No | Fill container mode (default: `false`) |
|
|
102
|
+
| `sizes` | `string` | No | Sizes attribute (default: `"100vw"`) |
|
|
103
|
+
| `className` | `string` | No | Additional CSS classes |
|
|
104
|
+
| `style` | `CSSProperties` | No | Additional inline styles |
|
|
105
|
+
| `...props` | `ImgHTMLAttributes` | No | All standard img element attributes |
|
|
106
|
+
|
|
107
|
+
**Note**: The `src` prop must be an object imported from `?vite-image` query. String URLs are not supported. The `width` and `height` are automatically extracted from the `src` object.
|
|
138
108
|
|
|
139
109
|
### ResponsiveImageData
|
|
140
110
|
|
package/dist/react/index.d.ts
CHANGED
|
@@ -12,14 +12,9 @@ interface ResponsiveImageData {
|
|
|
12
12
|
lqipSrc?: string;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
interface BaseImageProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, "
|
|
15
|
+
interface BaseImageProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, "src" | "srcSet" | "width" | "height"> {
|
|
16
|
+
src: ResponsiveImageData;
|
|
16
17
|
sizes?: string;
|
|
17
|
-
src?: string;
|
|
18
|
-
srcSet?: string;
|
|
19
|
-
lqipSrc?: string;
|
|
20
|
-
width?: number;
|
|
21
|
-
height?: number;
|
|
22
|
-
imgData?: ResponsiveImageData;
|
|
23
18
|
}
|
|
24
19
|
interface FillImageProps extends BaseImageProps {
|
|
25
20
|
fill: true;
|
|
@@ -28,6 +23,7 @@ interface StandardImageProps extends BaseImageProps {
|
|
|
28
23
|
fill?: false | undefined;
|
|
29
24
|
}
|
|
30
25
|
type ImageProps = FillImageProps | StandardImageProps;
|
|
31
|
-
declare function Image({
|
|
26
|
+
declare function Image({ src, // 이제 이 src는 객체입니다.
|
|
27
|
+
fill, sizes, className, style, ...props }: ImageProps): react_jsx_runtime.JSX.Element;
|
|
32
28
|
|
|
33
29
|
export { type ImageProps, type ResponsiveImageData, Image as default };
|
package/dist/react/index.js
CHANGED
|
@@ -3,12 +3,8 @@ import { jsxs, jsx } from 'react/jsx-runtime';
|
|
|
3
3
|
|
|
4
4
|
// src/react/Image.tsx
|
|
5
5
|
function Image({
|
|
6
|
-
imgData,
|
|
7
6
|
src,
|
|
8
|
-
|
|
9
|
-
lqipSrc,
|
|
10
|
-
width,
|
|
11
|
-
height,
|
|
7
|
+
// 이제 이 src는 객체입니다.
|
|
12
8
|
fill = false,
|
|
13
9
|
sizes = "100vw",
|
|
14
10
|
className = "",
|
|
@@ -16,15 +12,13 @@ function Image({
|
|
|
16
12
|
...props
|
|
17
13
|
}) {
|
|
18
14
|
const [isImageLoaded, setIsImageLoaded] = useState(false);
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
15
|
+
const {
|
|
16
|
+
src: currentSrc,
|
|
17
|
+
srcSet: currentSrcSet,
|
|
18
|
+
lqipSrc: currentLqip,
|
|
19
|
+
width: currentWidth,
|
|
20
|
+
height: currentHeight
|
|
21
|
+
} = src;
|
|
28
22
|
const containerStyle = fill ? {
|
|
29
23
|
position: "absolute",
|
|
30
24
|
top: 0,
|
|
@@ -55,14 +49,10 @@ function Image({
|
|
|
55
49
|
const lqipStyle = {
|
|
56
50
|
...imgStyle,
|
|
57
51
|
filter: "blur(20px)",
|
|
58
|
-
// blur 효과 강화 (선택사항)
|
|
59
52
|
transform: "scale(1.1)",
|
|
60
|
-
// blur 경계선 숨기기
|
|
61
53
|
transition: "opacity 500ms ease-out",
|
|
62
|
-
// 부드러운 전환
|
|
63
54
|
opacity: isImageLoaded ? 0 : 1,
|
|
64
55
|
zIndex: 1
|
|
65
|
-
// 로딩 중에는 위에 표시
|
|
66
56
|
};
|
|
67
57
|
return /* @__PURE__ */ jsxs("div", { className, style: mergedContainerStyle, children: [
|
|
68
58
|
/* @__PURE__ */ jsx(
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/react/Image.tsx"],"names":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"sources":["../../src/react/Image.tsx"],"names":[],"mappings":";;;;AAwBe,SAAR,KAAA,CAAuB;AAAA,EAC5B,GAAA;AAAA;AAAA,EACA,IAAA,GAAO,KAAA;AAAA,EACP,KAAA,GAAQ,OAAA;AAAA,EACR,SAAA,GAAY,EAAA;AAAA,EACZ,KAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAe;AACb,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAAS,KAAK,CAAA;AAGxD,EAAA,MAAM;AAAA,IACJ,GAAA,EAAK,UAAA;AAAA,IACL,MAAA,EAAQ,aAAA;AAAA,IACR,OAAA,EAAS,WAAA;AAAA,IACT,KAAA,EAAO,YAAA;AAAA,IACP,MAAA,EAAQ;AAAA,GACV,GAAI,GAAA;AAGJ,EAAA,MAAM,iBAAgC,IAAA,GAClC;AAAA,IACE,QAAA,EAAU,UAAA;AAAA,IACV,GAAA,EAAK,CAAA;AAAA,IACL,IAAA,EAAM,CAAA;AAAA,IACN,KAAA,EAAO,CAAA;AAAA,IACP,MAAA,EAAQ,CAAA;AAAA,IACR,KAAA,EAAO,MAAA;AAAA,IACP,MAAA,EAAQ,MAAA;AAAA,IACR,QAAA,EAAU;AAAA,GACZ,GACA;AAAA,IACE,QAAA,EAAU,UAAA;AAAA,IACV,KAAA,EAAO,MAAA;AAAA,IACP,QAAA,EAAU,QAAA;AAAA;AAAA,IAEV,GAAI,YAAA,IAAgB,aAAA,GAChB,EAAE,WAAA,EAAa,CAAA,EAAG,YAAY,CAAA,GAAA,EAAM,aAAa,CAAA,CAAA,EAAG,GACpD;AAAC,GACP;AAEJ,EAAA,MAAM,oBAAA,GAAuB,EAAE,GAAG,cAAA,EAAgB,GAAG,KAAA,EAAM;AAG3D,EAAA,MAAM,QAAA,GAA0B;AAAA,IAC9B,QAAA,EAAU,UAAA;AAAA,IACV,GAAA,EAAK,CAAA;AAAA,IACL,IAAA,EAAM,CAAA;AAAA,IACN,KAAA,EAAO,CAAA;AAAA,IACP,MAAA,EAAQ,CAAA;AAAA,IACR,KAAA,EAAO,MAAA;AAAA,IACP,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW;AAAA,GACb;AAGA,EAAA,MAAM,SAAA,GAA2B;AAAA,IAC/B,GAAG,QAAA;AAAA,IACH,MAAA,EAAQ,YAAA;AAAA,IACR,SAAA,EAAW,YAAA;AAAA,IACX,UAAA,EAAY,wBAAA;AAAA,IACZ,OAAA,EAAS,gBAAgB,CAAA,GAAI,CAAA;AAAA,IAC7B,MAAA,EAAQ;AAAA,GACV;AAEA,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAsB,KAAA,EAAO,oBAAA,EAEhC,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACE,GAAG,KAAA;AAAA,QACJ,GAAA,EAAK,UAAA;AAAA,QACL,MAAA,EAAQ,aAAA;AAAA,QACR,KAAA;AAAA,QACA,KAAA,EAAO,OAAO,MAAA,GAAY,YAAA;AAAA,QAC1B,MAAA,EAAQ,OAAO,MAAA,GAAY,aAAA;AAAA,QAC3B,MAAA,EAAQ,MAAM,gBAAA,CAAiB,IAAI,CAAA;AAAA,QACnC,KAAA,EAAO,EAAE,GAAG,QAAA,EAAU,QAAQ,CAAA;AAAE;AAAA,KAClC;AAAA,IAGC,WAAA,oBACC,GAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,WAAA,EAAa,KAAI,EAAA,EAAG,aAAA,EAAY,MAAA,EAAO,KAAA,EAAO,SAAA,EAAW;AAAA,GAAA,EAEvE,CAAA;AAEJ","file":"index.js","sourcesContent":["import { useState, type ImgHTMLAttributes, type CSSProperties } from \"react\";\nimport type { ResponsiveImageData } from \"../types\";\n\n// ?vite-image import 결과 타입\ninterface BaseImageProps\n extends Omit<\n ImgHTMLAttributes<HTMLImageElement>,\n \"src\" | \"srcSet\" | \"width\" | \"height\"\n > {\n // 핵심 변경: src는 무조건 최적화된 이미지 객체만 받음\n src: ResponsiveImageData;\n sizes?: string;\n}\n\ninterface FillImageProps extends BaseImageProps {\n fill: true;\n}\n\ninterface StandardImageProps extends BaseImageProps {\n fill?: false | undefined;\n}\n\nexport type ImageProps = FillImageProps | StandardImageProps;\n\nexport default function Image({\n src, // 이제 이 src는 객체입니다.\n fill = false,\n sizes = \"100vw\",\n className = \"\",\n style,\n ...props\n}: ImageProps) {\n const [isImageLoaded, setIsImageLoaded] = useState(false);\n\n // 1. 데이터 추출: src 객체에서 바로 꺼내씀 (병합 로직 제거)\n const {\n src: currentSrc,\n srcSet: currentSrcSet,\n lqipSrc: currentLqip,\n width: currentWidth,\n height: currentHeight,\n } = src;\n\n // 2. 컨테이너 스타일 계산 (기존 로직 유지)\n const containerStyle: CSSProperties = fill\n ? {\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n width: \"100%\",\n height: \"100%\",\n overflow: \"hidden\",\n }\n : {\n position: \"relative\",\n width: \"100%\",\n overflow: \"hidden\",\n // Standard 모드일 때 aspect-ratio 처리\n ...(currentWidth && currentHeight\n ? { aspectRatio: `${currentWidth} / ${currentHeight}` }\n : {}),\n };\n\n const mergedContainerStyle = { ...containerStyle, ...style };\n\n // 3. 실제 이미지 스타일 (기존 로직 유지)\n const imgStyle: CSSProperties = {\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n };\n\n // 4. LQIP 스타일 (기존 로직 유지)\n const lqipStyle: CSSProperties = {\n ...imgStyle,\n filter: \"blur(20px)\",\n transform: \"scale(1.1)\",\n transition: \"opacity 500ms ease-out\",\n opacity: isImageLoaded ? 0 : 1,\n zIndex: 1,\n };\n\n return (\n <div className={className} style={mergedContainerStyle}>\n {/* 실제 이미지 */}\n <img\n {...props}\n src={currentSrc}\n srcSet={currentSrcSet}\n sizes={sizes}\n width={fill ? undefined : currentWidth}\n height={fill ? undefined : currentHeight}\n onLoad={() => setIsImageLoaded(true)}\n style={{ ...imgStyle, zIndex: 0 }}\n />\n\n {/* LQIP 레이어 */}\n {currentLqip && (\n <img src={currentLqip} alt=\"\" aria-hidden=\"true\" style={lqipStyle} />\n )}\n </div>\n );\n}\n"]}
|
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -5,14 +5,7 @@
|
|
|
5
5
|
* These types extend the default vite-imagetools types
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
interface ResponsiveImageData {
|
|
10
|
-
src: string;
|
|
11
|
-
width: number;
|
|
12
|
-
height: number;
|
|
13
|
-
srcSet?: string;
|
|
14
|
-
lqipSrc?: string;
|
|
15
|
-
}
|
|
8
|
+
import type { ResponsiveImageData } from "./types";
|
|
16
9
|
|
|
17
10
|
// vite-image 쿼리 파라미터 타입
|
|
18
11
|
declare module "*?vite-image" {
|
|
@@ -43,14 +36,3 @@ declare module "*?w=*&blur=*&quality=*&format=*&inline" {
|
|
|
43
36
|
const src: string;
|
|
44
37
|
export default src;
|
|
45
38
|
}
|
|
46
|
-
|
|
47
|
-
// 일반 imagetools 확장
|
|
48
|
-
declare module "*&imagetools" {
|
|
49
|
-
type ImageToolsOutput =
|
|
50
|
-
| string // 기본 출력
|
|
51
|
-
| { src: string; width: number; height: number } // meta
|
|
52
|
-
| string; // srcset
|
|
53
|
-
|
|
54
|
-
const out: ImageToolsOutput;
|
|
55
|
-
export default out;
|
|
56
|
-
}
|