@slopmachine/react 0.1.2 → 0.1.4
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/dist/index.js +6 -7
- package/dist/index.mjs +7 -11
- package/package.json +4 -1
- package/src/components/SlopImage.tsx +0 -236
- package/src/index.ts +0 -1
- package/tsconfig.json +0 -28
- package/tsconfig.tsbuildinfo +0 -1
- package/tsup.config.ts +0 -9
package/dist/index.js
CHANGED
|
@@ -45,9 +45,10 @@ function cn(...inputs) {
|
|
|
45
45
|
}
|
|
46
46
|
var SlopImage = ({
|
|
47
47
|
bucketId,
|
|
48
|
-
prompt,
|
|
49
48
|
className,
|
|
50
49
|
aspectRatio = "1:1",
|
|
50
|
+
version,
|
|
51
|
+
resultId,
|
|
51
52
|
model,
|
|
52
53
|
variables = {},
|
|
53
54
|
baseUrl,
|
|
@@ -56,13 +57,14 @@ var SlopImage = ({
|
|
|
56
57
|
const rawSrc = (0, import_react.useMemo)(
|
|
57
58
|
() => (0, import_core.buildImageUrl)({
|
|
58
59
|
bucketId,
|
|
59
|
-
prompt,
|
|
60
60
|
aspectRatio,
|
|
61
|
+
version,
|
|
62
|
+
resultId,
|
|
61
63
|
variables,
|
|
62
64
|
baseUrl,
|
|
63
65
|
model
|
|
64
66
|
}),
|
|
65
|
-
[bucketId,
|
|
67
|
+
[bucketId, aspectRatio, version, resultId, variables, baseUrl, model]
|
|
66
68
|
);
|
|
67
69
|
const [src, setSrc] = (0, import_react.useState)(rawSrc);
|
|
68
70
|
import_react.default.useEffect(() => {
|
|
@@ -71,10 +73,7 @@ var SlopImage = ({
|
|
|
71
73
|
}, 100);
|
|
72
74
|
return () => clearTimeout(timer);
|
|
73
75
|
}, [rawSrc]);
|
|
74
|
-
const alt =
|
|
75
|
-
() => (0, import_core.interpolatePrompt)(prompt, variables) ?? "Generated image",
|
|
76
|
-
[prompt, variables]
|
|
77
|
-
);
|
|
76
|
+
const alt = "Generated image";
|
|
78
77
|
const [isLoading, setIsLoading] = (0, import_react.useState)(true);
|
|
79
78
|
const [currentSrc, setCurrentSrc] = (0, import_react.useState)(src);
|
|
80
79
|
if (src !== currentSrc) {
|
package/dist/index.mjs
CHANGED
|
@@ -2,19 +2,17 @@
|
|
|
2
2
|
import React, { useMemo, useState } from "react";
|
|
3
3
|
import { clsx } from "clsx";
|
|
4
4
|
import { twMerge } from "tailwind-merge";
|
|
5
|
-
import {
|
|
6
|
-
buildImageUrl,
|
|
7
|
-
interpolatePrompt
|
|
8
|
-
} from "@slopmachine/core";
|
|
5
|
+
import { buildImageUrl } from "@slopmachine/core";
|
|
9
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
10
7
|
function cn(...inputs) {
|
|
11
8
|
return twMerge(clsx(inputs));
|
|
12
9
|
}
|
|
13
10
|
var SlopImage = ({
|
|
14
11
|
bucketId,
|
|
15
|
-
prompt,
|
|
16
12
|
className,
|
|
17
13
|
aspectRatio = "1:1",
|
|
14
|
+
version,
|
|
15
|
+
resultId,
|
|
18
16
|
model,
|
|
19
17
|
variables = {},
|
|
20
18
|
baseUrl,
|
|
@@ -23,13 +21,14 @@ var SlopImage = ({
|
|
|
23
21
|
const rawSrc = useMemo(
|
|
24
22
|
() => buildImageUrl({
|
|
25
23
|
bucketId,
|
|
26
|
-
prompt,
|
|
27
24
|
aspectRatio,
|
|
25
|
+
version,
|
|
26
|
+
resultId,
|
|
28
27
|
variables,
|
|
29
28
|
baseUrl,
|
|
30
29
|
model
|
|
31
30
|
}),
|
|
32
|
-
[bucketId,
|
|
31
|
+
[bucketId, aspectRatio, version, resultId, variables, baseUrl, model]
|
|
33
32
|
);
|
|
34
33
|
const [src, setSrc] = useState(rawSrc);
|
|
35
34
|
React.useEffect(() => {
|
|
@@ -38,10 +37,7 @@ var SlopImage = ({
|
|
|
38
37
|
}, 100);
|
|
39
38
|
return () => clearTimeout(timer);
|
|
40
39
|
}, [rawSrc]);
|
|
41
|
-
const alt =
|
|
42
|
-
() => interpolatePrompt(prompt, variables) ?? "Generated image",
|
|
43
|
-
[prompt, variables]
|
|
44
|
-
);
|
|
40
|
+
const alt = "Generated image";
|
|
45
41
|
const [isLoading, setIsLoading] = useState(true);
|
|
46
42
|
const [currentSrc, setCurrentSrc] = useState(src);
|
|
47
43
|
if (src !== currentSrc) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slopmachine/react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "The official React SDK for Slop Machine",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
"require": "./dist/index.js"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
15
18
|
"scripts": {
|
|
16
19
|
"build": "tsup",
|
|
17
20
|
"dev": "tsup --watch"
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
import React, { useMemo, useState } from "react";
|
|
2
|
-
import { clsx, type ClassValue } from "clsx";
|
|
3
|
-
import { twMerge } from "tailwind-merge";
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
buildImageUrl,
|
|
7
|
-
interpolatePrompt,
|
|
8
|
-
type SlopImageOptions,
|
|
9
|
-
} from "@slopmachine/core";
|
|
10
|
-
|
|
11
|
-
// Utility for Tailwind classes
|
|
12
|
-
function cn(...inputs: ClassValue[]) {
|
|
13
|
-
return twMerge(clsx(inputs));
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
interface SlopImageProps
|
|
17
|
-
extends
|
|
18
|
-
Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src" | "alt">,
|
|
19
|
-
SlopImageOptions {}
|
|
20
|
-
|
|
21
|
-
export const SlopImage: React.FC<SlopImageProps> = ({
|
|
22
|
-
bucketId,
|
|
23
|
-
prompt,
|
|
24
|
-
className,
|
|
25
|
-
aspectRatio = "1:1",
|
|
26
|
-
model,
|
|
27
|
-
variables = {},
|
|
28
|
-
baseUrl,
|
|
29
|
-
...props
|
|
30
|
-
}) => {
|
|
31
|
-
// Construct API URL
|
|
32
|
-
const rawSrc = useMemo(
|
|
33
|
-
() =>
|
|
34
|
-
buildImageUrl({
|
|
35
|
-
bucketId,
|
|
36
|
-
prompt,
|
|
37
|
-
aspectRatio,
|
|
38
|
-
variables,
|
|
39
|
-
baseUrl,
|
|
40
|
-
model,
|
|
41
|
-
}),
|
|
42
|
-
[bucketId, prompt, aspectRatio, variables, baseUrl, model],
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
const [src, setSrc] = useState(rawSrc);
|
|
46
|
-
|
|
47
|
-
React.useEffect(() => {
|
|
48
|
-
const timer = setTimeout(() => {
|
|
49
|
-
setSrc(rawSrc);
|
|
50
|
-
}, 100);
|
|
51
|
-
return () => clearTimeout(timer);
|
|
52
|
-
}, [rawSrc]);
|
|
53
|
-
|
|
54
|
-
const alt = useMemo(
|
|
55
|
-
() => interpolatePrompt(prompt, variables) ?? "Generated image",
|
|
56
|
-
[prompt, variables],
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
60
|
-
const [currentSrc, setCurrentSrc] = useState(src);
|
|
61
|
-
|
|
62
|
-
if (src !== currentSrc) {
|
|
63
|
-
setCurrentSrc(src);
|
|
64
|
-
setIsLoading(true);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
React.useEffect(() => {
|
|
68
|
-
if (!src) return;
|
|
69
|
-
|
|
70
|
-
fetch(src, { method: "HEAD" })
|
|
71
|
-
.then(async (res) => {
|
|
72
|
-
if (!res.ok) {
|
|
73
|
-
// console.error(
|
|
74
|
-
// `Failed to load image from ${src}. Status: ${res.status} ${res.statusText}`,
|
|
75
|
-
// );
|
|
76
|
-
try {
|
|
77
|
-
const errRes = await fetch(src);
|
|
78
|
-
const errJson = await errRes.json();
|
|
79
|
-
console.error("SlopImage error:", res.status, errJson.error);
|
|
80
|
-
} catch (e) {
|
|
81
|
-
// Failed to fetch or parse error details
|
|
82
|
-
}
|
|
83
|
-
setIsLoading(false);
|
|
84
|
-
}
|
|
85
|
-
})
|
|
86
|
-
.catch((err) => {
|
|
87
|
-
console.error(`Error fetching image from ${src}:`, err);
|
|
88
|
-
setIsLoading(false);
|
|
89
|
-
});
|
|
90
|
-
}, [src]);
|
|
91
|
-
|
|
92
|
-
return (
|
|
93
|
-
<>
|
|
94
|
-
<style>{`
|
|
95
|
-
@keyframes slop-shimmer {
|
|
96
|
-
0% {
|
|
97
|
-
background-position: 200% 0;
|
|
98
|
-
}
|
|
99
|
-
100% {
|
|
100
|
-
background-position: -200% 0;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
@keyframes slop-spin {
|
|
104
|
-
from {
|
|
105
|
-
transform: rotate(0deg);
|
|
106
|
-
}
|
|
107
|
-
to {
|
|
108
|
-
transform: rotate(360deg);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
`}</style>
|
|
112
|
-
<div
|
|
113
|
-
className={cn("relative overflow-hidden", className)}
|
|
114
|
-
style={{
|
|
115
|
-
aspectRatio: String(aspectRatio).replace(":", "/"),
|
|
116
|
-
backgroundColor: "var(--muted, #f3f4f6)",
|
|
117
|
-
position: "relative",
|
|
118
|
-
overflow: "hidden",
|
|
119
|
-
}}
|
|
120
|
-
>
|
|
121
|
-
{/* Loading overlay */}
|
|
122
|
-
<div
|
|
123
|
-
className={cn(
|
|
124
|
-
"absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300",
|
|
125
|
-
isLoading ? "opacity-100" : "opacity-0 pointer-events-none",
|
|
126
|
-
)}
|
|
127
|
-
style={{
|
|
128
|
-
position: "absolute",
|
|
129
|
-
top: 0,
|
|
130
|
-
left: 0,
|
|
131
|
-
right: 0,
|
|
132
|
-
bottom: 0,
|
|
133
|
-
zIndex: 10,
|
|
134
|
-
display: "flex",
|
|
135
|
-
alignItems: "center",
|
|
136
|
-
justifyContent: "center",
|
|
137
|
-
backgroundColor: "var(--muted, #f3f4f6)",
|
|
138
|
-
opacity: isLoading ? 1 : 0,
|
|
139
|
-
pointerEvents: isLoading ? "auto" : "none",
|
|
140
|
-
transition: "opacity 300ms ease-in-out",
|
|
141
|
-
}}
|
|
142
|
-
>
|
|
143
|
-
<div
|
|
144
|
-
className="flex flex-col items-center gap-2"
|
|
145
|
-
style={{
|
|
146
|
-
display: "flex",
|
|
147
|
-
flexDirection: "column",
|
|
148
|
-
alignItems: "center",
|
|
149
|
-
gap: "0.5rem",
|
|
150
|
-
}}
|
|
151
|
-
>
|
|
152
|
-
<svg
|
|
153
|
-
className="spinner size-6 text-muted-foreground"
|
|
154
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
155
|
-
fill="none"
|
|
156
|
-
viewBox="0 0 24 24"
|
|
157
|
-
style={{
|
|
158
|
-
width: "24px",
|
|
159
|
-
height: "24px",
|
|
160
|
-
color: "var(--muted-foreground, #6b7280)",
|
|
161
|
-
animation: "slop-spin 1s linear infinite",
|
|
162
|
-
}}
|
|
163
|
-
>
|
|
164
|
-
<circle
|
|
165
|
-
className="opacity-25"
|
|
166
|
-
cx="12"
|
|
167
|
-
cy="12"
|
|
168
|
-
r="10"
|
|
169
|
-
stroke="currentColor"
|
|
170
|
-
strokeWidth="4"
|
|
171
|
-
style={{ opacity: 0.25 }}
|
|
172
|
-
/>
|
|
173
|
-
<path
|
|
174
|
-
className="opacity-75"
|
|
175
|
-
fill="currentColor"
|
|
176
|
-
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
177
|
-
style={{ opacity: 0.75 }}
|
|
178
|
-
/>
|
|
179
|
-
</svg>
|
|
180
|
-
<span
|
|
181
|
-
className="text-xs text-muted-foreground"
|
|
182
|
-
style={{
|
|
183
|
-
fontSize: "0.75rem",
|
|
184
|
-
color: "var(--muted-foreground, #6b7280)",
|
|
185
|
-
}}
|
|
186
|
-
>
|
|
187
|
-
Loading...
|
|
188
|
-
</span>
|
|
189
|
-
</div>
|
|
190
|
-
</div>
|
|
191
|
-
|
|
192
|
-
{/* Shimmer effect underneath */}
|
|
193
|
-
<div
|
|
194
|
-
className={cn(
|
|
195
|
-
"shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted",
|
|
196
|
-
isLoading ? "opacity-100" : "opacity-0",
|
|
197
|
-
)}
|
|
198
|
-
style={{
|
|
199
|
-
position: "absolute",
|
|
200
|
-
top: 0,
|
|
201
|
-
left: 0,
|
|
202
|
-
right: 0,
|
|
203
|
-
bottom: 0,
|
|
204
|
-
background:
|
|
205
|
-
"linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)",
|
|
206
|
-
backgroundSize: "200% 100%",
|
|
207
|
-
animation: "slop-shimmer 2s ease-in-out infinite",
|
|
208
|
-
opacity: isLoading ? 1 : 0,
|
|
209
|
-
transition: "opacity 300ms",
|
|
210
|
-
}}
|
|
211
|
-
/>
|
|
212
|
-
|
|
213
|
-
{/* Image */}
|
|
214
|
-
<img
|
|
215
|
-
key={src}
|
|
216
|
-
src={src}
|
|
217
|
-
alt={alt}
|
|
218
|
-
onLoad={() => setIsLoading(false)}
|
|
219
|
-
onError={() => setIsLoading(false)}
|
|
220
|
-
className={cn(
|
|
221
|
-
"h-full w-full object-cover transition-opacity duration-500",
|
|
222
|
-
isLoading ? "opacity-0" : "opacity-100",
|
|
223
|
-
)}
|
|
224
|
-
style={{
|
|
225
|
-
height: "100%",
|
|
226
|
-
width: "100%",
|
|
227
|
-
objectFit: "cover",
|
|
228
|
-
transition: "opacity 500ms",
|
|
229
|
-
opacity: isLoading ? 0 : 1,
|
|
230
|
-
}}
|
|
231
|
-
{...props}
|
|
232
|
-
/>
|
|
233
|
-
</div>
|
|
234
|
-
</>
|
|
235
|
-
);
|
|
236
|
-
};
|
package/src/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { SlopImage } from './components/SlopImage';
|
package/tsconfig.json
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"useDefineForClassFields": true,
|
|
5
|
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
-
"module": "ESNext",
|
|
7
|
-
"skipLibCheck": true,
|
|
8
|
-
|
|
9
|
-
/* Bundler mode */
|
|
10
|
-
"moduleResolution": "bundler",
|
|
11
|
-
"allowImportingTsExtensions": true,
|
|
12
|
-
"resolveJsonModule": true,
|
|
13
|
-
"isolatedModules": true,
|
|
14
|
-
"noEmit": true,
|
|
15
|
-
"jsx": "react-jsx",
|
|
16
|
-
|
|
17
|
-
/* Linting */
|
|
18
|
-
"strict": true,
|
|
19
|
-
"noUnusedLocals": true,
|
|
20
|
-
"noUnusedParameters": true,
|
|
21
|
-
"noFallthroughCasesInSwitch": true,
|
|
22
|
-
|
|
23
|
-
"declaration": true,
|
|
24
|
-
"baseUrl": "."
|
|
25
|
-
},
|
|
26
|
-
"include": ["src"],
|
|
27
|
-
"exclude": ["node_modules", "dist"]
|
|
28
|
-
}
|
package/tsconfig.tsbuildinfo
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"root":["./src/index.ts","./src/components/slopimage.tsx"],"version":"5.9.3"}
|