@slopmachine/react 0.1.9 → 0.1.10
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.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +113 -87
- package/dist/index.mjs +113 -87
- package/package.json +1 -1
- package/src/components/SlopImage.tsx +112 -81
package/dist/index.d.mts
CHANGED
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { SlopImageOptions } from '@slopmachine/core';
|
|
3
3
|
|
|
4
4
|
interface SlopImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src" | "alt">, SlopImageOptions {
|
|
5
|
+
loader?: React.ReactNode;
|
|
5
6
|
}
|
|
6
7
|
declare const SlopImage: React.FC<SlopImageProps>;
|
|
7
8
|
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { SlopImageOptions } from '@slopmachine/core';
|
|
3
3
|
|
|
4
4
|
interface SlopImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src" | "alt">, SlopImageOptions {
|
|
5
|
+
loader?: React.ReactNode;
|
|
5
6
|
}
|
|
6
7
|
declare const SlopImage: React.FC<SlopImageProps>;
|
|
7
8
|
|
package/dist/index.js
CHANGED
|
@@ -52,6 +52,7 @@ var SlopImage = ({
|
|
|
52
52
|
model,
|
|
53
53
|
variables = {},
|
|
54
54
|
baseUrl,
|
|
55
|
+
loader,
|
|
55
56
|
...props
|
|
56
57
|
}) => {
|
|
57
58
|
const rawSrc = (0, import_react.useMemo)(
|
|
@@ -127,11 +128,11 @@ var SlopImage = ({
|
|
|
127
128
|
overflow: "hidden"
|
|
128
129
|
},
|
|
129
130
|
children: [
|
|
130
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
131
|
+
loader ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
131
132
|
"div",
|
|
132
133
|
{
|
|
133
134
|
className: cn(
|
|
134
|
-
"absolute inset-0 z-10 flex items-center justify-center
|
|
135
|
+
"absolute inset-0 z-10 flex items-center justify-center transition-opacity duration-300",
|
|
135
136
|
isLoading ? "opacity-100" : "opacity-0 pointer-events-none"
|
|
136
137
|
),
|
|
137
138
|
style: {
|
|
@@ -144,97 +145,122 @@ var SlopImage = ({
|
|
|
144
145
|
display: "flex",
|
|
145
146
|
alignItems: "center",
|
|
146
147
|
justifyContent: "center",
|
|
147
|
-
backgroundColor: "var(--muted, #f3f4f6)",
|
|
148
148
|
opacity: isLoading ? 1 : 0,
|
|
149
149
|
pointerEvents: isLoading ? "auto" : "none",
|
|
150
150
|
transition: "opacity 300ms ease-in-out"
|
|
151
151
|
},
|
|
152
|
-
children:
|
|
153
|
-
"div",
|
|
154
|
-
{
|
|
155
|
-
className: "flex flex-col items-center gap-2",
|
|
156
|
-
style: {
|
|
157
|
-
display: "flex",
|
|
158
|
-
flexDirection: "column",
|
|
159
|
-
alignItems: "center",
|
|
160
|
-
gap: "0.5rem"
|
|
161
|
-
},
|
|
162
|
-
children: [
|
|
163
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
164
|
-
"svg",
|
|
165
|
-
{
|
|
166
|
-
className: "spinner size-6 text-muted-foreground",
|
|
167
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
168
|
-
fill: "none",
|
|
169
|
-
viewBox: "0 0 24 24",
|
|
170
|
-
style: {
|
|
171
|
-
width: "24px",
|
|
172
|
-
height: "24px",
|
|
173
|
-
color: "var(--muted-foreground, #6b7280)",
|
|
174
|
-
animation: "slop-spin 1s linear infinite"
|
|
175
|
-
},
|
|
176
|
-
children: [
|
|
177
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
178
|
-
"circle",
|
|
179
|
-
{
|
|
180
|
-
className: "opacity-25",
|
|
181
|
-
cx: "12",
|
|
182
|
-
cy: "12",
|
|
183
|
-
r: "10",
|
|
184
|
-
stroke: "currentColor",
|
|
185
|
-
strokeWidth: "4",
|
|
186
|
-
style: { opacity: 0.25 }
|
|
187
|
-
}
|
|
188
|
-
),
|
|
189
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
190
|
-
"path",
|
|
191
|
-
{
|
|
192
|
-
className: "opacity-75",
|
|
193
|
-
fill: "currentColor",
|
|
194
|
-
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",
|
|
195
|
-
style: { opacity: 0.75 }
|
|
196
|
-
}
|
|
197
|
-
)
|
|
198
|
-
]
|
|
199
|
-
}
|
|
200
|
-
),
|
|
201
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
202
|
-
"span",
|
|
203
|
-
{
|
|
204
|
-
className: "text-xs text-muted-foreground",
|
|
205
|
-
style: {
|
|
206
|
-
fontSize: "0.75rem",
|
|
207
|
-
color: "var(--muted-foreground, #6b7280)"
|
|
208
|
-
},
|
|
209
|
-
children: "Loading..."
|
|
210
|
-
}
|
|
211
|
-
)
|
|
212
|
-
]
|
|
213
|
-
}
|
|
214
|
-
)
|
|
152
|
+
children: loader
|
|
215
153
|
}
|
|
216
|
-
),
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
154
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
155
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
156
|
+
"div",
|
|
157
|
+
{
|
|
158
|
+
className: cn(
|
|
159
|
+
"absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300",
|
|
160
|
+
isLoading ? "opacity-100" : "opacity-0 pointer-events-none"
|
|
161
|
+
),
|
|
162
|
+
style: {
|
|
163
|
+
position: "absolute",
|
|
164
|
+
top: 0,
|
|
165
|
+
left: 0,
|
|
166
|
+
right: 0,
|
|
167
|
+
bottom: 0,
|
|
168
|
+
zIndex: 10,
|
|
169
|
+
display: "flex",
|
|
170
|
+
alignItems: "center",
|
|
171
|
+
justifyContent: "center",
|
|
172
|
+
backgroundColor: "var(--muted, #f3f4f6)",
|
|
173
|
+
opacity: isLoading ? 1 : 0,
|
|
174
|
+
pointerEvents: isLoading ? "auto" : "none",
|
|
175
|
+
transition: "opacity 300ms ease-in-out"
|
|
176
|
+
},
|
|
177
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
178
|
+
"div",
|
|
179
|
+
{
|
|
180
|
+
className: "flex flex-col items-center gap-2",
|
|
181
|
+
style: {
|
|
182
|
+
display: "flex",
|
|
183
|
+
flexDirection: "column",
|
|
184
|
+
alignItems: "center",
|
|
185
|
+
gap: "0.5rem"
|
|
186
|
+
},
|
|
187
|
+
children: [
|
|
188
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
189
|
+
"svg",
|
|
190
|
+
{
|
|
191
|
+
className: "spinner size-6 text-muted-foreground",
|
|
192
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
193
|
+
fill: "none",
|
|
194
|
+
viewBox: "0 0 24 24",
|
|
195
|
+
style: {
|
|
196
|
+
width: "24px",
|
|
197
|
+
height: "24px",
|
|
198
|
+
color: "var(--muted-foreground, #6b7280)",
|
|
199
|
+
animation: "slop-spin 1s linear infinite"
|
|
200
|
+
},
|
|
201
|
+
children: [
|
|
202
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
203
|
+
"circle",
|
|
204
|
+
{
|
|
205
|
+
className: "opacity-25",
|
|
206
|
+
cx: "12",
|
|
207
|
+
cy: "12",
|
|
208
|
+
r: "10",
|
|
209
|
+
stroke: "currentColor",
|
|
210
|
+
strokeWidth: "4",
|
|
211
|
+
style: { opacity: 0.25 }
|
|
212
|
+
}
|
|
213
|
+
),
|
|
214
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
215
|
+
"path",
|
|
216
|
+
{
|
|
217
|
+
className: "opacity-75",
|
|
218
|
+
fill: "currentColor",
|
|
219
|
+
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",
|
|
220
|
+
style: { opacity: 0.75 }
|
|
221
|
+
}
|
|
222
|
+
)
|
|
223
|
+
]
|
|
224
|
+
}
|
|
225
|
+
),
|
|
226
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
227
|
+
"span",
|
|
228
|
+
{
|
|
229
|
+
className: "text-xs text-muted-foreground",
|
|
230
|
+
style: {
|
|
231
|
+
fontSize: "0.75rem",
|
|
232
|
+
color: "var(--muted-foreground, #6b7280)"
|
|
233
|
+
},
|
|
234
|
+
children: "Loading..."
|
|
235
|
+
}
|
|
236
|
+
)
|
|
237
|
+
]
|
|
238
|
+
}
|
|
239
|
+
)
|
|
235
240
|
}
|
|
236
|
-
|
|
237
|
-
|
|
241
|
+
),
|
|
242
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
243
|
+
"div",
|
|
244
|
+
{
|
|
245
|
+
className: cn(
|
|
246
|
+
"shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted",
|
|
247
|
+
isLoading ? "opacity-100" : "opacity-0"
|
|
248
|
+
),
|
|
249
|
+
style: {
|
|
250
|
+
position: "absolute",
|
|
251
|
+
top: 0,
|
|
252
|
+
left: 0,
|
|
253
|
+
right: 0,
|
|
254
|
+
bottom: 0,
|
|
255
|
+
background: "linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)",
|
|
256
|
+
backgroundSize: "200% 100%",
|
|
257
|
+
animation: "slop-shimmer 2s ease-in-out infinite",
|
|
258
|
+
opacity: isLoading ? 1 : 0,
|
|
259
|
+
transition: "opacity 300ms"
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
)
|
|
263
|
+
] }),
|
|
238
264
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
239
265
|
"img",
|
|
240
266
|
{
|
package/dist/index.mjs
CHANGED
|
@@ -16,6 +16,7 @@ var SlopImage = ({
|
|
|
16
16
|
model,
|
|
17
17
|
variables = {},
|
|
18
18
|
baseUrl,
|
|
19
|
+
loader,
|
|
19
20
|
...props
|
|
20
21
|
}) => {
|
|
21
22
|
const rawSrc = useMemo(
|
|
@@ -91,11 +92,11 @@ var SlopImage = ({
|
|
|
91
92
|
overflow: "hidden"
|
|
92
93
|
},
|
|
93
94
|
children: [
|
|
94
|
-
/* @__PURE__ */ jsx(
|
|
95
|
+
loader ? /* @__PURE__ */ jsx(
|
|
95
96
|
"div",
|
|
96
97
|
{
|
|
97
98
|
className: cn(
|
|
98
|
-
"absolute inset-0 z-10 flex items-center justify-center
|
|
99
|
+
"absolute inset-0 z-10 flex items-center justify-center transition-opacity duration-300",
|
|
99
100
|
isLoading ? "opacity-100" : "opacity-0 pointer-events-none"
|
|
100
101
|
),
|
|
101
102
|
style: {
|
|
@@ -108,97 +109,122 @@ var SlopImage = ({
|
|
|
108
109
|
display: "flex",
|
|
109
110
|
alignItems: "center",
|
|
110
111
|
justifyContent: "center",
|
|
111
|
-
backgroundColor: "var(--muted, #f3f4f6)",
|
|
112
112
|
opacity: isLoading ? 1 : 0,
|
|
113
113
|
pointerEvents: isLoading ? "auto" : "none",
|
|
114
114
|
transition: "opacity 300ms ease-in-out"
|
|
115
115
|
},
|
|
116
|
-
children:
|
|
117
|
-
"div",
|
|
118
|
-
{
|
|
119
|
-
className: "flex flex-col items-center gap-2",
|
|
120
|
-
style: {
|
|
121
|
-
display: "flex",
|
|
122
|
-
flexDirection: "column",
|
|
123
|
-
alignItems: "center",
|
|
124
|
-
gap: "0.5rem"
|
|
125
|
-
},
|
|
126
|
-
children: [
|
|
127
|
-
/* @__PURE__ */ jsxs(
|
|
128
|
-
"svg",
|
|
129
|
-
{
|
|
130
|
-
className: "spinner size-6 text-muted-foreground",
|
|
131
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
132
|
-
fill: "none",
|
|
133
|
-
viewBox: "0 0 24 24",
|
|
134
|
-
style: {
|
|
135
|
-
width: "24px",
|
|
136
|
-
height: "24px",
|
|
137
|
-
color: "var(--muted-foreground, #6b7280)",
|
|
138
|
-
animation: "slop-spin 1s linear infinite"
|
|
139
|
-
},
|
|
140
|
-
children: [
|
|
141
|
-
/* @__PURE__ */ jsx(
|
|
142
|
-
"circle",
|
|
143
|
-
{
|
|
144
|
-
className: "opacity-25",
|
|
145
|
-
cx: "12",
|
|
146
|
-
cy: "12",
|
|
147
|
-
r: "10",
|
|
148
|
-
stroke: "currentColor",
|
|
149
|
-
strokeWidth: "4",
|
|
150
|
-
style: { opacity: 0.25 }
|
|
151
|
-
}
|
|
152
|
-
),
|
|
153
|
-
/* @__PURE__ */ jsx(
|
|
154
|
-
"path",
|
|
155
|
-
{
|
|
156
|
-
className: "opacity-75",
|
|
157
|
-
fill: "currentColor",
|
|
158
|
-
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",
|
|
159
|
-
style: { opacity: 0.75 }
|
|
160
|
-
}
|
|
161
|
-
)
|
|
162
|
-
]
|
|
163
|
-
}
|
|
164
|
-
),
|
|
165
|
-
/* @__PURE__ */ jsx(
|
|
166
|
-
"span",
|
|
167
|
-
{
|
|
168
|
-
className: "text-xs text-muted-foreground",
|
|
169
|
-
style: {
|
|
170
|
-
fontSize: "0.75rem",
|
|
171
|
-
color: "var(--muted-foreground, #6b7280)"
|
|
172
|
-
},
|
|
173
|
-
children: "Loading..."
|
|
174
|
-
}
|
|
175
|
-
)
|
|
176
|
-
]
|
|
177
|
-
}
|
|
178
|
-
)
|
|
116
|
+
children: loader
|
|
179
117
|
}
|
|
180
|
-
),
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
118
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
119
|
+
/* @__PURE__ */ jsx(
|
|
120
|
+
"div",
|
|
121
|
+
{
|
|
122
|
+
className: cn(
|
|
123
|
+
"absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300",
|
|
124
|
+
isLoading ? "opacity-100" : "opacity-0 pointer-events-none"
|
|
125
|
+
),
|
|
126
|
+
style: {
|
|
127
|
+
position: "absolute",
|
|
128
|
+
top: 0,
|
|
129
|
+
left: 0,
|
|
130
|
+
right: 0,
|
|
131
|
+
bottom: 0,
|
|
132
|
+
zIndex: 10,
|
|
133
|
+
display: "flex",
|
|
134
|
+
alignItems: "center",
|
|
135
|
+
justifyContent: "center",
|
|
136
|
+
backgroundColor: "var(--muted, #f3f4f6)",
|
|
137
|
+
opacity: isLoading ? 1 : 0,
|
|
138
|
+
pointerEvents: isLoading ? "auto" : "none",
|
|
139
|
+
transition: "opacity 300ms ease-in-out"
|
|
140
|
+
},
|
|
141
|
+
children: /* @__PURE__ */ jsxs(
|
|
142
|
+
"div",
|
|
143
|
+
{
|
|
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
|
+
children: [
|
|
152
|
+
/* @__PURE__ */ jsxs(
|
|
153
|
+
"svg",
|
|
154
|
+
{
|
|
155
|
+
className: "spinner size-6 text-muted-foreground",
|
|
156
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
157
|
+
fill: "none",
|
|
158
|
+
viewBox: "0 0 24 24",
|
|
159
|
+
style: {
|
|
160
|
+
width: "24px",
|
|
161
|
+
height: "24px",
|
|
162
|
+
color: "var(--muted-foreground, #6b7280)",
|
|
163
|
+
animation: "slop-spin 1s linear infinite"
|
|
164
|
+
},
|
|
165
|
+
children: [
|
|
166
|
+
/* @__PURE__ */ jsx(
|
|
167
|
+
"circle",
|
|
168
|
+
{
|
|
169
|
+
className: "opacity-25",
|
|
170
|
+
cx: "12",
|
|
171
|
+
cy: "12",
|
|
172
|
+
r: "10",
|
|
173
|
+
stroke: "currentColor",
|
|
174
|
+
strokeWidth: "4",
|
|
175
|
+
style: { opacity: 0.25 }
|
|
176
|
+
}
|
|
177
|
+
),
|
|
178
|
+
/* @__PURE__ */ jsx(
|
|
179
|
+
"path",
|
|
180
|
+
{
|
|
181
|
+
className: "opacity-75",
|
|
182
|
+
fill: "currentColor",
|
|
183
|
+
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",
|
|
184
|
+
style: { opacity: 0.75 }
|
|
185
|
+
}
|
|
186
|
+
)
|
|
187
|
+
]
|
|
188
|
+
}
|
|
189
|
+
),
|
|
190
|
+
/* @__PURE__ */ jsx(
|
|
191
|
+
"span",
|
|
192
|
+
{
|
|
193
|
+
className: "text-xs text-muted-foreground",
|
|
194
|
+
style: {
|
|
195
|
+
fontSize: "0.75rem",
|
|
196
|
+
color: "var(--muted-foreground, #6b7280)"
|
|
197
|
+
},
|
|
198
|
+
children: "Loading..."
|
|
199
|
+
}
|
|
200
|
+
)
|
|
201
|
+
]
|
|
202
|
+
}
|
|
203
|
+
)
|
|
199
204
|
}
|
|
200
|
-
|
|
201
|
-
|
|
205
|
+
),
|
|
206
|
+
/* @__PURE__ */ jsx(
|
|
207
|
+
"div",
|
|
208
|
+
{
|
|
209
|
+
className: cn(
|
|
210
|
+
"shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted",
|
|
211
|
+
isLoading ? "opacity-100" : "opacity-0"
|
|
212
|
+
),
|
|
213
|
+
style: {
|
|
214
|
+
position: "absolute",
|
|
215
|
+
top: 0,
|
|
216
|
+
left: 0,
|
|
217
|
+
right: 0,
|
|
218
|
+
bottom: 0,
|
|
219
|
+
background: "linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)",
|
|
220
|
+
backgroundSize: "200% 100%",
|
|
221
|
+
animation: "slop-shimmer 2s ease-in-out infinite",
|
|
222
|
+
opacity: isLoading ? 1 : 0,
|
|
223
|
+
transition: "opacity 300ms"
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
)
|
|
227
|
+
] }),
|
|
202
228
|
/* @__PURE__ */ jsx(
|
|
203
229
|
"img",
|
|
204
230
|
{
|
package/package.json
CHANGED
|
@@ -12,7 +12,9 @@ function cn(...inputs: ClassValue[]) {
|
|
|
12
12
|
interface SlopImageProps
|
|
13
13
|
extends
|
|
14
14
|
Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src" | "alt">,
|
|
15
|
-
SlopImageOptions {
|
|
15
|
+
SlopImageOptions {
|
|
16
|
+
loader?: React.ReactNode;
|
|
17
|
+
}
|
|
16
18
|
|
|
17
19
|
export const SlopImage: React.FC<SlopImageProps> = ({
|
|
18
20
|
bucketId,
|
|
@@ -23,6 +25,7 @@ export const SlopImage: React.FC<SlopImageProps> = ({
|
|
|
23
25
|
model,
|
|
24
26
|
variables = {},
|
|
25
27
|
baseUrl,
|
|
28
|
+
loader,
|
|
26
29
|
...props
|
|
27
30
|
}) => {
|
|
28
31
|
// Construct API URL
|
|
@@ -113,97 +116,125 @@ export const SlopImage: React.FC<SlopImageProps> = ({
|
|
|
113
116
|
overflow: "hidden",
|
|
114
117
|
}}
|
|
115
118
|
>
|
|
116
|
-
{/* Loading
|
|
117
|
-
|
|
118
|
-
className={cn(
|
|
119
|
-
"absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300",
|
|
120
|
-
isLoading ? "opacity-100" : "opacity-0 pointer-events-none",
|
|
121
|
-
)}
|
|
122
|
-
style={{
|
|
123
|
-
position: "absolute",
|
|
124
|
-
top: 0,
|
|
125
|
-
left: 0,
|
|
126
|
-
right: 0,
|
|
127
|
-
bottom: 0,
|
|
128
|
-
zIndex: 10,
|
|
129
|
-
display: "flex",
|
|
130
|
-
alignItems: "center",
|
|
131
|
-
justifyContent: "center",
|
|
132
|
-
backgroundColor: "var(--muted, #f3f4f6)",
|
|
133
|
-
opacity: isLoading ? 1 : 0,
|
|
134
|
-
pointerEvents: isLoading ? "auto" : "none",
|
|
135
|
-
transition: "opacity 300ms ease-in-out",
|
|
136
|
-
}}
|
|
137
|
-
>
|
|
119
|
+
{/* Loading UI */}
|
|
120
|
+
{loader ? (
|
|
138
121
|
<div
|
|
139
|
-
className=
|
|
122
|
+
className={cn(
|
|
123
|
+
"absolute inset-0 z-10 flex items-center justify-center transition-opacity duration-300",
|
|
124
|
+
isLoading ? "opacity-100" : "opacity-0 pointer-events-none",
|
|
125
|
+
)}
|
|
140
126
|
style={{
|
|
127
|
+
position: "absolute",
|
|
128
|
+
top: 0,
|
|
129
|
+
left: 0,
|
|
130
|
+
right: 0,
|
|
131
|
+
bottom: 0,
|
|
132
|
+
zIndex: 10,
|
|
141
133
|
display: "flex",
|
|
142
|
-
flexDirection: "column",
|
|
143
134
|
alignItems: "center",
|
|
144
|
-
|
|
135
|
+
justifyContent: "center",
|
|
136
|
+
opacity: isLoading ? 1 : 0,
|
|
137
|
+
pointerEvents: isLoading ? "auto" : "none",
|
|
138
|
+
transition: "opacity 300ms ease-in-out",
|
|
145
139
|
}}
|
|
146
140
|
>
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
141
|
+
{loader}
|
|
142
|
+
</div>
|
|
143
|
+
) : (
|
|
144
|
+
<>
|
|
145
|
+
{/* Loading overlay */}
|
|
146
|
+
<div
|
|
147
|
+
className={cn(
|
|
148
|
+
"absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300",
|
|
149
|
+
isLoading ? "opacity-100" : "opacity-0 pointer-events-none",
|
|
150
|
+
)}
|
|
152
151
|
style={{
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
152
|
+
position: "absolute",
|
|
153
|
+
top: 0,
|
|
154
|
+
left: 0,
|
|
155
|
+
right: 0,
|
|
156
|
+
bottom: 0,
|
|
157
|
+
zIndex: 10,
|
|
158
|
+
display: "flex",
|
|
159
|
+
alignItems: "center",
|
|
160
|
+
justifyContent: "center",
|
|
161
|
+
backgroundColor: "var(--muted, #f3f4f6)",
|
|
162
|
+
opacity: isLoading ? 1 : 0,
|
|
163
|
+
pointerEvents: isLoading ? "auto" : "none",
|
|
164
|
+
transition: "opacity 300ms ease-in-out",
|
|
157
165
|
}}
|
|
158
166
|
>
|
|
159
|
-
<
|
|
160
|
-
className="
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
167
|
+
<div
|
|
168
|
+
className="flex flex-col items-center gap-2"
|
|
169
|
+
style={{
|
|
170
|
+
display: "flex",
|
|
171
|
+
flexDirection: "column",
|
|
172
|
+
alignItems: "center",
|
|
173
|
+
gap: "0.5rem",
|
|
174
|
+
}}
|
|
175
|
+
>
|
|
176
|
+
<svg
|
|
177
|
+
className="spinner size-6 text-muted-foreground"
|
|
178
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
179
|
+
fill="none"
|
|
180
|
+
viewBox="0 0 24 24"
|
|
181
|
+
style={{
|
|
182
|
+
width: "24px",
|
|
183
|
+
height: "24px",
|
|
184
|
+
color: "var(--muted-foreground, #6b7280)",
|
|
185
|
+
animation: "slop-spin 1s linear infinite",
|
|
186
|
+
}}
|
|
187
|
+
>
|
|
188
|
+
<circle
|
|
189
|
+
className="opacity-25"
|
|
190
|
+
cx="12"
|
|
191
|
+
cy="12"
|
|
192
|
+
r="10"
|
|
193
|
+
stroke="currentColor"
|
|
194
|
+
strokeWidth="4"
|
|
195
|
+
style={{ opacity: 0.25 }}
|
|
196
|
+
/>
|
|
197
|
+
<path
|
|
198
|
+
className="opacity-75"
|
|
199
|
+
fill="currentColor"
|
|
200
|
+
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"
|
|
201
|
+
style={{ opacity: 0.75 }}
|
|
202
|
+
/>
|
|
203
|
+
</svg>
|
|
204
|
+
<span
|
|
205
|
+
className="text-xs text-muted-foreground"
|
|
206
|
+
style={{
|
|
207
|
+
fontSize: "0.75rem",
|
|
208
|
+
color: "var(--muted-foreground, #6b7280)",
|
|
209
|
+
}}
|
|
210
|
+
>
|
|
211
|
+
Loading...
|
|
212
|
+
</span>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
|
|
216
|
+
{/* Shimmer effect underneath */}
|
|
217
|
+
<div
|
|
218
|
+
className={cn(
|
|
219
|
+
"shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted",
|
|
220
|
+
isLoading ? "opacity-100" : "opacity-0",
|
|
221
|
+
)}
|
|
177
222
|
style={{
|
|
178
|
-
|
|
179
|
-
|
|
223
|
+
position: "absolute",
|
|
224
|
+
top: 0,
|
|
225
|
+
left: 0,
|
|
226
|
+
right: 0,
|
|
227
|
+
bottom: 0,
|
|
228
|
+
background:
|
|
229
|
+
"linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)",
|
|
230
|
+
backgroundSize: "200% 100%",
|
|
231
|
+
animation: "slop-shimmer 2s ease-in-out infinite",
|
|
232
|
+
opacity: isLoading ? 1 : 0,
|
|
233
|
+
transition: "opacity 300ms",
|
|
180
234
|
}}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
</div>
|
|
185
|
-
</div>
|
|
186
|
-
|
|
187
|
-
{/* Shimmer effect underneath */}
|
|
188
|
-
<div
|
|
189
|
-
className={cn(
|
|
190
|
-
"shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted",
|
|
191
|
-
isLoading ? "opacity-100" : "opacity-0",
|
|
192
|
-
)}
|
|
193
|
-
style={{
|
|
194
|
-
position: "absolute",
|
|
195
|
-
top: 0,
|
|
196
|
-
left: 0,
|
|
197
|
-
right: 0,
|
|
198
|
-
bottom: 0,
|
|
199
|
-
background:
|
|
200
|
-
"linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)",
|
|
201
|
-
backgroundSize: "200% 100%",
|
|
202
|
-
animation: "slop-shimmer 2s ease-in-out infinite",
|
|
203
|
-
opacity: isLoading ? 1 : 0,
|
|
204
|
-
transition: "opacity 300ms",
|
|
205
|
-
}}
|
|
206
|
-
/>
|
|
235
|
+
/>
|
|
236
|
+
</>
|
|
237
|
+
)}
|
|
207
238
|
|
|
208
239
|
{/* Image */}
|
|
209
240
|
<img
|