@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 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 bg-muted transition-opacity duration-300",
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: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
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
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
218
- "div",
219
- {
220
- className: cn(
221
- "shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted",
222
- isLoading ? "opacity-100" : "opacity-0"
223
- ),
224
- style: {
225
- position: "absolute",
226
- top: 0,
227
- left: 0,
228
- right: 0,
229
- bottom: 0,
230
- background: "linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)",
231
- backgroundSize: "200% 100%",
232
- animation: "slop-shimmer 2s ease-in-out infinite",
233
- opacity: isLoading ? 1 : 0,
234
- transition: "opacity 300ms"
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 bg-muted transition-opacity duration-300",
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: /* @__PURE__ */ jsxs(
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
- /* @__PURE__ */ jsx(
182
- "div",
183
- {
184
- className: cn(
185
- "shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted",
186
- isLoading ? "opacity-100" : "opacity-0"
187
- ),
188
- style: {
189
- position: "absolute",
190
- top: 0,
191
- left: 0,
192
- right: 0,
193
- bottom: 0,
194
- background: "linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)",
195
- backgroundSize: "200% 100%",
196
- animation: "slop-shimmer 2s ease-in-out infinite",
197
- opacity: isLoading ? 1 : 0,
198
- transition: "opacity 300ms"
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slopmachine/react",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "The official React SDK for Slop Machine",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -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 overlay */}
117
- <div
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="flex flex-col items-center gap-2"
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
- gap: "0.5rem",
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
- <svg
148
- className="spinner size-6 text-muted-foreground"
149
- xmlns="http://www.w3.org/2000/svg"
150
- fill="none"
151
- viewBox="0 0 24 24"
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
- width: "24px",
154
- height: "24px",
155
- color: "var(--muted-foreground, #6b7280)",
156
- animation: "slop-spin 1s linear infinite",
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
- <circle
160
- className="opacity-25"
161
- cx="12"
162
- cy="12"
163
- r="10"
164
- stroke="currentColor"
165
- strokeWidth="4"
166
- style={{ opacity: 0.25 }}
167
- />
168
- <path
169
- className="opacity-75"
170
- fill="currentColor"
171
- 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"
172
- style={{ opacity: 0.75 }}
173
- />
174
- </svg>
175
- <span
176
- className="text-xs text-muted-foreground"
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
- fontSize: "0.75rem",
179
- color: "var(--muted-foreground, #6b7280)",
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
- Loading...
183
- </span>
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