@seed-design/react-image 0.1.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/lib/Image-12s-BLdJ3cIN.js +151 -0
- package/lib/Image-12s-LZ-Fna1t.cjs +155 -0
- package/lib/index.cjs +15 -0
- package/lib/index.d.ts +1183 -0
- package/lib/index.js +11 -0
- package/package.json +48 -0
- package/src/Image.namespace.ts +8 -0
- package/src/Image.tsx +66 -0
- package/src/index.ts +19 -0
- package/src/useImage.ts +101 -0
- package/src/useImageContext.tsx +17 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { composeRefs } from '@radix-ui/react-compose-refs';
|
|
4
|
+
import { useLayoutEffect } from '@radix-ui/react-use-layout-effect';
|
|
5
|
+
import { elementProps, imgProps, dataAttr, mergeProps } from '@seed-design/dom-utils';
|
|
6
|
+
import { Primitive } from '@seed-design/react-primitive';
|
|
7
|
+
import { useState, useRef, useMemo, useCallback, createContext, useContext, forwardRef } from 'react';
|
|
8
|
+
import { useCallbackRef } from '@radix-ui/react-use-callback-ref';
|
|
9
|
+
|
|
10
|
+
function useImage(props) {
|
|
11
|
+
const onLoadingStatusChange = useCallbackRef(props.onLoadingStatusChange);
|
|
12
|
+
const [loadingStatus, setLoadingStatus] = useState("loading");
|
|
13
|
+
const imageRef = useRef(null);
|
|
14
|
+
useLayoutEffect(()=>{
|
|
15
|
+
if (imageRef.current) {
|
|
16
|
+
if (imageRef.current.complete) {
|
|
17
|
+
if (imageRef.current.naturalWidth === 0 || imageRef.current.naturalHeight === 0) {
|
|
18
|
+
setLoadingStatus("error");
|
|
19
|
+
onLoadingStatusChange?.("error");
|
|
20
|
+
} else {
|
|
21
|
+
setLoadingStatus("loaded");
|
|
22
|
+
onLoadingStatusChange?.("loaded");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}, [
|
|
27
|
+
onLoadingStatusChange
|
|
28
|
+
]);
|
|
29
|
+
const isLoaded = loadingStatus === "loaded";
|
|
30
|
+
const stateProps = useMemo(()=>elementProps({
|
|
31
|
+
"data-loading-state": loadingStatus
|
|
32
|
+
}), [
|
|
33
|
+
loadingStatus
|
|
34
|
+
]);
|
|
35
|
+
const setSrc = useCallback((src)=>{
|
|
36
|
+
if (src === undefined || src === null) {
|
|
37
|
+
setLoadingStatus("error");
|
|
38
|
+
onLoadingStatusChange?.("error");
|
|
39
|
+
} else {
|
|
40
|
+
setLoadingStatus("loading");
|
|
41
|
+
onLoadingStatusChange?.("loading");
|
|
42
|
+
}
|
|
43
|
+
}, [
|
|
44
|
+
onLoadingStatusChange
|
|
45
|
+
]);
|
|
46
|
+
const getContentProps = useCallback(({ src })=>{
|
|
47
|
+
return imgProps({
|
|
48
|
+
hidden: !isLoaded,
|
|
49
|
+
"data-visible": dataAttr(isLoaded),
|
|
50
|
+
src,
|
|
51
|
+
...stateProps
|
|
52
|
+
});
|
|
53
|
+
}, [
|
|
54
|
+
isLoaded,
|
|
55
|
+
stateProps
|
|
56
|
+
]);
|
|
57
|
+
const handleLoad = useCallback(()=>{
|
|
58
|
+
setLoadingStatus("loaded");
|
|
59
|
+
onLoadingStatusChange?.("loaded");
|
|
60
|
+
}, [
|
|
61
|
+
onLoadingStatusChange
|
|
62
|
+
]);
|
|
63
|
+
const handleError = useCallback(()=>{
|
|
64
|
+
setLoadingStatus("error");
|
|
65
|
+
onLoadingStatusChange?.("error");
|
|
66
|
+
}, [
|
|
67
|
+
onLoadingStatusChange
|
|
68
|
+
]);
|
|
69
|
+
const fallbackProps = useMemo(()=>elementProps({
|
|
70
|
+
hidden: isLoaded,
|
|
71
|
+
"data-visible": dataAttr(!isLoaded),
|
|
72
|
+
...stateProps
|
|
73
|
+
}), [
|
|
74
|
+
isLoaded,
|
|
75
|
+
stateProps
|
|
76
|
+
]);
|
|
77
|
+
return {
|
|
78
|
+
refs: {
|
|
79
|
+
image: imageRef
|
|
80
|
+
},
|
|
81
|
+
loadingStatus,
|
|
82
|
+
stateProps,
|
|
83
|
+
rootProps: stateProps,
|
|
84
|
+
setSrc,
|
|
85
|
+
getContentProps,
|
|
86
|
+
handleLoad,
|
|
87
|
+
handleError,
|
|
88
|
+
fallbackProps
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const ImageContext = /*#__PURE__*/ createContext(null);
|
|
93
|
+
const ImageProvider = ImageContext.Provider;
|
|
94
|
+
function useImageContext({ strict = true } = {}) {
|
|
95
|
+
const context = useContext(ImageContext);
|
|
96
|
+
if (!context && strict) {
|
|
97
|
+
throw new Error("useImageContext must be used within an Image");
|
|
98
|
+
}
|
|
99
|
+
return context;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const ImageRoot = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
103
|
+
const { onLoadingStatusChange, ...otherProps } = props;
|
|
104
|
+
const api = useImage({
|
|
105
|
+
onLoadingStatusChange
|
|
106
|
+
});
|
|
107
|
+
return /*#__PURE__*/ jsx(ImageProvider, {
|
|
108
|
+
value: api,
|
|
109
|
+
children: /*#__PURE__*/ jsx(Primitive.div, {
|
|
110
|
+
ref: ref,
|
|
111
|
+
...mergeProps(api.rootProps, otherProps)
|
|
112
|
+
})
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
ImageRoot.displayName = "ImageRoot";
|
|
116
|
+
const ImageContent = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
117
|
+
const { src, onLoad, onError, ...otherProps } = props;
|
|
118
|
+
const { refs, setSrc, getContentProps, handleLoad, handleError } = useImageContext();
|
|
119
|
+
useLayoutEffect(()=>{
|
|
120
|
+
setSrc(src);
|
|
121
|
+
}, [
|
|
122
|
+
src,
|
|
123
|
+
setSrc
|
|
124
|
+
]);
|
|
125
|
+
const contentProps = getContentProps({
|
|
126
|
+
src
|
|
127
|
+
});
|
|
128
|
+
return /*#__PURE__*/ jsx(Primitive.img, {
|
|
129
|
+
ref: composeRefs(refs.image, ref),
|
|
130
|
+
...mergeProps(contentProps, otherProps),
|
|
131
|
+
onLoad: (e)=>{
|
|
132
|
+
handleLoad();
|
|
133
|
+
onLoad?.(e);
|
|
134
|
+
},
|
|
135
|
+
onError: (e)=>{
|
|
136
|
+
handleError();
|
|
137
|
+
onError?.(e);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
ImageContent.displayName = "ImageContent";
|
|
142
|
+
const ImageFallback = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
143
|
+
const { fallbackProps } = useImageContext();
|
|
144
|
+
return /*#__PURE__*/ jsx(Primitive.div, {
|
|
145
|
+
ref: ref,
|
|
146
|
+
...mergeProps(fallbackProps, props)
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
ImageFallback.displayName = "ImageFallback";
|
|
150
|
+
|
|
151
|
+
export { ImageContent as I, ImageFallback as a, ImageRoot as b, useImage as c, useImageContext as u };
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
3
|
+
var reactComposeRefs = require('@radix-ui/react-compose-refs');
|
|
4
|
+
var reactUseLayoutEffect = require('@radix-ui/react-use-layout-effect');
|
|
5
|
+
var domUtils = require('@seed-design/dom-utils');
|
|
6
|
+
var reactPrimitive = require('@seed-design/react-primitive');
|
|
7
|
+
var react = require('react');
|
|
8
|
+
var reactUseCallbackRef = require('@radix-ui/react-use-callback-ref');
|
|
9
|
+
|
|
10
|
+
function useImage(props) {
|
|
11
|
+
const onLoadingStatusChange = reactUseCallbackRef.useCallbackRef(props.onLoadingStatusChange);
|
|
12
|
+
const [loadingStatus, setLoadingStatus] = react.useState("loading");
|
|
13
|
+
const imageRef = react.useRef(null);
|
|
14
|
+
reactUseLayoutEffect.useLayoutEffect(()=>{
|
|
15
|
+
if (imageRef.current) {
|
|
16
|
+
if (imageRef.current.complete) {
|
|
17
|
+
if (imageRef.current.naturalWidth === 0 || imageRef.current.naturalHeight === 0) {
|
|
18
|
+
setLoadingStatus("error");
|
|
19
|
+
onLoadingStatusChange?.("error");
|
|
20
|
+
} else {
|
|
21
|
+
setLoadingStatus("loaded");
|
|
22
|
+
onLoadingStatusChange?.("loaded");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}, [
|
|
27
|
+
onLoadingStatusChange
|
|
28
|
+
]);
|
|
29
|
+
const isLoaded = loadingStatus === "loaded";
|
|
30
|
+
const stateProps = react.useMemo(()=>domUtils.elementProps({
|
|
31
|
+
"data-loading-state": loadingStatus
|
|
32
|
+
}), [
|
|
33
|
+
loadingStatus
|
|
34
|
+
]);
|
|
35
|
+
const setSrc = react.useCallback((src)=>{
|
|
36
|
+
if (src === undefined || src === null) {
|
|
37
|
+
setLoadingStatus("error");
|
|
38
|
+
onLoadingStatusChange?.("error");
|
|
39
|
+
} else {
|
|
40
|
+
setLoadingStatus("loading");
|
|
41
|
+
onLoadingStatusChange?.("loading");
|
|
42
|
+
}
|
|
43
|
+
}, [
|
|
44
|
+
onLoadingStatusChange
|
|
45
|
+
]);
|
|
46
|
+
const getContentProps = react.useCallback(({ src })=>{
|
|
47
|
+
return domUtils.imgProps({
|
|
48
|
+
hidden: !isLoaded,
|
|
49
|
+
"data-visible": domUtils.dataAttr(isLoaded),
|
|
50
|
+
src,
|
|
51
|
+
...stateProps
|
|
52
|
+
});
|
|
53
|
+
}, [
|
|
54
|
+
isLoaded,
|
|
55
|
+
stateProps
|
|
56
|
+
]);
|
|
57
|
+
const handleLoad = react.useCallback(()=>{
|
|
58
|
+
setLoadingStatus("loaded");
|
|
59
|
+
onLoadingStatusChange?.("loaded");
|
|
60
|
+
}, [
|
|
61
|
+
onLoadingStatusChange
|
|
62
|
+
]);
|
|
63
|
+
const handleError = react.useCallback(()=>{
|
|
64
|
+
setLoadingStatus("error");
|
|
65
|
+
onLoadingStatusChange?.("error");
|
|
66
|
+
}, [
|
|
67
|
+
onLoadingStatusChange
|
|
68
|
+
]);
|
|
69
|
+
const fallbackProps = react.useMemo(()=>domUtils.elementProps({
|
|
70
|
+
hidden: isLoaded,
|
|
71
|
+
"data-visible": domUtils.dataAttr(!isLoaded),
|
|
72
|
+
...stateProps
|
|
73
|
+
}), [
|
|
74
|
+
isLoaded,
|
|
75
|
+
stateProps
|
|
76
|
+
]);
|
|
77
|
+
return {
|
|
78
|
+
refs: {
|
|
79
|
+
image: imageRef
|
|
80
|
+
},
|
|
81
|
+
loadingStatus,
|
|
82
|
+
stateProps,
|
|
83
|
+
rootProps: stateProps,
|
|
84
|
+
setSrc,
|
|
85
|
+
getContentProps,
|
|
86
|
+
handleLoad,
|
|
87
|
+
handleError,
|
|
88
|
+
fallbackProps
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const ImageContext = /*#__PURE__*/ react.createContext(null);
|
|
93
|
+
const ImageProvider = ImageContext.Provider;
|
|
94
|
+
function useImageContext({ strict = true } = {}) {
|
|
95
|
+
const context = react.useContext(ImageContext);
|
|
96
|
+
if (!context && strict) {
|
|
97
|
+
throw new Error("useImageContext must be used within an Image");
|
|
98
|
+
}
|
|
99
|
+
return context;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const ImageRoot = /*#__PURE__*/ react.forwardRef((props, ref)=>{
|
|
103
|
+
const { onLoadingStatusChange, ...otherProps } = props;
|
|
104
|
+
const api = useImage({
|
|
105
|
+
onLoadingStatusChange
|
|
106
|
+
});
|
|
107
|
+
return /*#__PURE__*/ jsxRuntime.jsx(ImageProvider, {
|
|
108
|
+
value: api,
|
|
109
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(reactPrimitive.Primitive.div, {
|
|
110
|
+
ref: ref,
|
|
111
|
+
...domUtils.mergeProps(api.rootProps, otherProps)
|
|
112
|
+
})
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
ImageRoot.displayName = "ImageRoot";
|
|
116
|
+
const ImageContent = /*#__PURE__*/ react.forwardRef((props, ref)=>{
|
|
117
|
+
const { src, onLoad, onError, ...otherProps } = props;
|
|
118
|
+
const { refs, setSrc, getContentProps, handleLoad, handleError } = useImageContext();
|
|
119
|
+
reactUseLayoutEffect.useLayoutEffect(()=>{
|
|
120
|
+
setSrc(src);
|
|
121
|
+
}, [
|
|
122
|
+
src,
|
|
123
|
+
setSrc
|
|
124
|
+
]);
|
|
125
|
+
const contentProps = getContentProps({
|
|
126
|
+
src
|
|
127
|
+
});
|
|
128
|
+
return /*#__PURE__*/ jsxRuntime.jsx(reactPrimitive.Primitive.img, {
|
|
129
|
+
ref: reactComposeRefs.composeRefs(refs.image, ref),
|
|
130
|
+
...domUtils.mergeProps(contentProps, otherProps),
|
|
131
|
+
onLoad: (e)=>{
|
|
132
|
+
handleLoad();
|
|
133
|
+
onLoad?.(e);
|
|
134
|
+
},
|
|
135
|
+
onError: (e)=>{
|
|
136
|
+
handleError();
|
|
137
|
+
onError?.(e);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
ImageContent.displayName = "ImageContent";
|
|
142
|
+
const ImageFallback = /*#__PURE__*/ react.forwardRef((props, ref)=>{
|
|
143
|
+
const { fallbackProps } = useImageContext();
|
|
144
|
+
return /*#__PURE__*/ jsxRuntime.jsx(reactPrimitive.Primitive.div, {
|
|
145
|
+
ref: ref,
|
|
146
|
+
...domUtils.mergeProps(fallbackProps, props)
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
ImageFallback.displayName = "ImageFallback";
|
|
150
|
+
|
|
151
|
+
exports.ImageContent = ImageContent;
|
|
152
|
+
exports.ImageFallback = ImageFallback;
|
|
153
|
+
exports.ImageRoot = ImageRoot;
|
|
154
|
+
exports.useImage = useImage;
|
|
155
|
+
exports.useImageContext = useImageContext;
|
package/lib/index.cjs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
var Image12s = require('./Image-12s-LZ-Fna1t.cjs');
|
|
2
|
+
|
|
3
|
+
var Image_namespace = {
|
|
4
|
+
__proto__: null,
|
|
5
|
+
Content: Image12s.ImageContent,
|
|
6
|
+
Fallback: Image12s.ImageFallback,
|
|
7
|
+
Root: Image12s.ImageRoot
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
exports.ImageContent = Image12s.ImageContent;
|
|
11
|
+
exports.ImageFallback = Image12s.ImageFallback;
|
|
12
|
+
exports.ImageRoot = Image12s.ImageRoot;
|
|
13
|
+
exports.useImage = Image12s.useImage;
|
|
14
|
+
exports.useImageContext = Image12s.useImageContext;
|
|
15
|
+
exports.Image = Image_namespace;
|