@slopmachine/react 0.8.1 → 0.9.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/CHANGELOG.md +27 -0
- package/dist/index.d.mts +26 -8
- package/dist/index.d.ts +26 -8
- package/dist/index.js +63 -57
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +69 -61
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @slopmachine/react
|
|
2
2
|
|
|
3
|
+
## 0.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 56eaf03: Component polish (React and Svelte):
|
|
8
|
+
|
|
9
|
+
- **`alt` on `SlopImage`:** describe the image for screen readers (or pass `""` for decorative images). The default text is unchanged.
|
|
10
|
+
- **`objectFit` on `SlopVideo`:** matches `SlopImage`; defaults to `"cover"`.
|
|
11
|
+
- **`SlopText` error handling** now matches `SlopImage`/`SlopVideo`:
|
|
12
|
+
- a default "Failed to load text" message instead of an empty element;
|
|
13
|
+
- `onGenerationError(error)`;
|
|
14
|
+
- errors are `SlopMachineError` with the API's message and HTTP `status`;
|
|
15
|
+
- React's `errorFallback` also accepts `(error) => node`.
|
|
16
|
+
- **Stale text fix:** `SlopText` cancels in-flight requests when its props change, so a slow response can no longer replace newer text. This affected Svelte.
|
|
17
|
+
- **Theming:** the loader, shimmer and error states read new `--slop-muted`, `--slop-muted-foreground` and `--slop-shimmer` CSS variables. These fall back to `--muted`/`--muted-foreground`, so the default look is unchanged; set them to style the components independently, or to fix themes whose `--muted` isn't a plain colour.
|
|
18
|
+
- **Svelte now matches React:**
|
|
19
|
+
- `SlopImage`/`SlopVideo` render the media URL immediately, including when server-rendering (previously an empty `src` for 50 ms);
|
|
20
|
+
- later prop changes are debounced by 100 ms, as in React;
|
|
21
|
+
- `SlopText` bypasses the HTTP cache, as React already did;
|
|
22
|
+
- `SlopTextProps` is now exported.
|
|
23
|
+
- **Core:** new `fetchRenderedText(url, { signal })`, shared by both `SlopText` components.
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- Updated dependencies [56eaf03]
|
|
28
|
+
- @slopmachine/core@0.9.0
|
|
29
|
+
|
|
3
30
|
## 0.8.1
|
|
4
31
|
|
|
5
32
|
### Patch Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -8,11 +8,17 @@ export { ImageAspectRatio, RateResultOptions, RateResultResponse, ResultRating,
|
|
|
8
8
|
*/
|
|
9
9
|
type SlopErrorFallback = React.ReactNode | ((error: SlopMachineError) => React.ReactNode);
|
|
10
10
|
|
|
11
|
-
interface SlopImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src"
|
|
11
|
+
interface SlopImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src">, Omit<SlopImageOptions, "aspectRatio"> {
|
|
12
12
|
/**
|
|
13
13
|
* The aspect ratio of the generated image. Defaults to "1:1".
|
|
14
14
|
*/
|
|
15
15
|
aspectRatio?: ImageAspectRatio;
|
|
16
|
+
/**
|
|
17
|
+
* Alternative text describing the image, for screen readers and when the image
|
|
18
|
+
* can't be shown. Defaults to "Image produced by Slop Machine (slopmachine.dev)".
|
|
19
|
+
* Describe what the image shows, or pass `""` if it's purely decorative.
|
|
20
|
+
*/
|
|
21
|
+
alt?: string;
|
|
16
22
|
/**
|
|
17
23
|
* Custom React node to display while the image is loading.
|
|
18
24
|
* If not provided, a default spinner and shimmer effect will be shown.
|
|
@@ -64,7 +70,7 @@ interface SlopImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>,
|
|
|
64
70
|
* />
|
|
65
71
|
* ```
|
|
66
72
|
*
|
|
67
|
-
* @version 0.
|
|
73
|
+
* @version 0.9.0
|
|
68
74
|
*/
|
|
69
75
|
declare const SlopImage: React.FC<SlopImageProps>;
|
|
70
76
|
|
|
@@ -78,6 +84,10 @@ interface SlopVideoProps extends Omit<React.VideoHTMLAttributes<HTMLVideoElement
|
|
|
78
84
|
* If not provided, a default spinner and shimmer effect will be shown.
|
|
79
85
|
*/
|
|
80
86
|
loader?: React.ReactNode;
|
|
87
|
+
/**
|
|
88
|
+
* How the video should be resized to fit its container. Defaults to "cover".
|
|
89
|
+
*/
|
|
90
|
+
objectFit?: React.CSSProperties["objectFit"];
|
|
81
91
|
/**
|
|
82
92
|
* Content to display if the video fails to generate or load.
|
|
83
93
|
* Pass a node, or a function that receives the `SlopMachineError` and returns a node.
|
|
@@ -118,19 +128,27 @@ interface SlopVideoProps extends Omit<React.VideoHTMLAttributes<HTMLVideoElement
|
|
|
118
128
|
* />
|
|
119
129
|
* ```
|
|
120
130
|
*
|
|
121
|
-
* @version 0.
|
|
131
|
+
* @version 0.9.0
|
|
122
132
|
*/
|
|
123
133
|
declare const SlopVideo: React.FC<SlopVideoProps>;
|
|
124
134
|
|
|
125
135
|
interface SlopTextProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children">, SlopTextOptions {
|
|
126
136
|
/**
|
|
127
|
-
* Optional loading component to show while the text is being generated
|
|
137
|
+
* Optional loading component to show while the text is being generated.
|
|
138
|
+
* If not provided, a default spinner and shimmer effect will be shown.
|
|
128
139
|
*/
|
|
129
140
|
fallback?: React.ReactNode;
|
|
130
141
|
/**
|
|
131
|
-
*
|
|
142
|
+
* Content to display if the text fails to generate or load.
|
|
143
|
+
* Pass a node, or a function that receives the `SlopMachineError` and returns a node.
|
|
144
|
+
* If not provided, a default error message is shown.
|
|
145
|
+
*/
|
|
146
|
+
errorFallback?: SlopErrorFallback;
|
|
147
|
+
/**
|
|
148
|
+
* Called once per URL when the text fails to generate or load.
|
|
149
|
+
* `error.status` holds the HTTP status when the API reported the failure.
|
|
132
150
|
*/
|
|
133
|
-
|
|
151
|
+
onGenerationError?: (error: SlopMachineError) => void;
|
|
134
152
|
}
|
|
135
153
|
/**
|
|
136
154
|
* Renders text generated by Slop Machine.
|
|
@@ -144,7 +162,7 @@ interface SlopTextProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "chil
|
|
|
144
162
|
* <SlopText
|
|
145
163
|
* bucketId="my-text-bucket"
|
|
146
164
|
* fallback={<div>Loading story...</div>}
|
|
147
|
-
* errorFallback={<div>Failed to load story</div>}
|
|
165
|
+
* errorFallback={(error) => <div>Failed to load story: {error.message}</div>}
|
|
148
166
|
* className="text-lg text-gray-800"
|
|
149
167
|
* />
|
|
150
168
|
*
|
|
@@ -156,7 +174,7 @@ interface SlopTextProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "chil
|
|
|
156
174
|
* />
|
|
157
175
|
* ```
|
|
158
176
|
*
|
|
159
|
-
* @version 0.
|
|
177
|
+
* @version 0.9.0
|
|
160
178
|
*/
|
|
161
179
|
declare const SlopText: React.ForwardRefExoticComponent<SlopTextProps & React.RefAttributes<HTMLDivElement>>;
|
|
162
180
|
|
package/dist/index.d.ts
CHANGED
|
@@ -8,11 +8,17 @@ export { ImageAspectRatio, RateResultOptions, RateResultResponse, ResultRating,
|
|
|
8
8
|
*/
|
|
9
9
|
type SlopErrorFallback = React.ReactNode | ((error: SlopMachineError) => React.ReactNode);
|
|
10
10
|
|
|
11
|
-
interface SlopImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src"
|
|
11
|
+
interface SlopImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src">, Omit<SlopImageOptions, "aspectRatio"> {
|
|
12
12
|
/**
|
|
13
13
|
* The aspect ratio of the generated image. Defaults to "1:1".
|
|
14
14
|
*/
|
|
15
15
|
aspectRatio?: ImageAspectRatio;
|
|
16
|
+
/**
|
|
17
|
+
* Alternative text describing the image, for screen readers and when the image
|
|
18
|
+
* can't be shown. Defaults to "Image produced by Slop Machine (slopmachine.dev)".
|
|
19
|
+
* Describe what the image shows, or pass `""` if it's purely decorative.
|
|
20
|
+
*/
|
|
21
|
+
alt?: string;
|
|
16
22
|
/**
|
|
17
23
|
* Custom React node to display while the image is loading.
|
|
18
24
|
* If not provided, a default spinner and shimmer effect will be shown.
|
|
@@ -64,7 +70,7 @@ interface SlopImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>,
|
|
|
64
70
|
* />
|
|
65
71
|
* ```
|
|
66
72
|
*
|
|
67
|
-
* @version 0.
|
|
73
|
+
* @version 0.9.0
|
|
68
74
|
*/
|
|
69
75
|
declare const SlopImage: React.FC<SlopImageProps>;
|
|
70
76
|
|
|
@@ -78,6 +84,10 @@ interface SlopVideoProps extends Omit<React.VideoHTMLAttributes<HTMLVideoElement
|
|
|
78
84
|
* If not provided, a default spinner and shimmer effect will be shown.
|
|
79
85
|
*/
|
|
80
86
|
loader?: React.ReactNode;
|
|
87
|
+
/**
|
|
88
|
+
* How the video should be resized to fit its container. Defaults to "cover".
|
|
89
|
+
*/
|
|
90
|
+
objectFit?: React.CSSProperties["objectFit"];
|
|
81
91
|
/**
|
|
82
92
|
* Content to display if the video fails to generate or load.
|
|
83
93
|
* Pass a node, or a function that receives the `SlopMachineError` and returns a node.
|
|
@@ -118,19 +128,27 @@ interface SlopVideoProps extends Omit<React.VideoHTMLAttributes<HTMLVideoElement
|
|
|
118
128
|
* />
|
|
119
129
|
* ```
|
|
120
130
|
*
|
|
121
|
-
* @version 0.
|
|
131
|
+
* @version 0.9.0
|
|
122
132
|
*/
|
|
123
133
|
declare const SlopVideo: React.FC<SlopVideoProps>;
|
|
124
134
|
|
|
125
135
|
interface SlopTextProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children">, SlopTextOptions {
|
|
126
136
|
/**
|
|
127
|
-
* Optional loading component to show while the text is being generated
|
|
137
|
+
* Optional loading component to show while the text is being generated.
|
|
138
|
+
* If not provided, a default spinner and shimmer effect will be shown.
|
|
128
139
|
*/
|
|
129
140
|
fallback?: React.ReactNode;
|
|
130
141
|
/**
|
|
131
|
-
*
|
|
142
|
+
* Content to display if the text fails to generate or load.
|
|
143
|
+
* Pass a node, or a function that receives the `SlopMachineError` and returns a node.
|
|
144
|
+
* If not provided, a default error message is shown.
|
|
145
|
+
*/
|
|
146
|
+
errorFallback?: SlopErrorFallback;
|
|
147
|
+
/**
|
|
148
|
+
* Called once per URL when the text fails to generate or load.
|
|
149
|
+
* `error.status` holds the HTTP status when the API reported the failure.
|
|
132
150
|
*/
|
|
133
|
-
|
|
151
|
+
onGenerationError?: (error: SlopMachineError) => void;
|
|
134
152
|
}
|
|
135
153
|
/**
|
|
136
154
|
* Renders text generated by Slop Machine.
|
|
@@ -144,7 +162,7 @@ interface SlopTextProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "chil
|
|
|
144
162
|
* <SlopText
|
|
145
163
|
* bucketId="my-text-bucket"
|
|
146
164
|
* fallback={<div>Loading story...</div>}
|
|
147
|
-
* errorFallback={<div>Failed to load story</div>}
|
|
165
|
+
* errorFallback={(error) => <div>Failed to load story: {error.message}</div>}
|
|
148
166
|
* className="text-lg text-gray-800"
|
|
149
167
|
* />
|
|
150
168
|
*
|
|
@@ -156,7 +174,7 @@ interface SlopTextProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "chil
|
|
|
156
174
|
* />
|
|
157
175
|
* ```
|
|
158
176
|
*
|
|
159
|
-
* @version 0.
|
|
177
|
+
* @version 0.9.0
|
|
160
178
|
*/
|
|
161
179
|
declare const SlopText: React.ForwardRefExoticComponent<SlopTextProps & React.RefAttributes<HTMLDivElement>>;
|
|
162
180
|
|
package/dist/index.js
CHANGED
|
@@ -80,7 +80,10 @@ var ErrorOverlay = ({
|
|
|
80
80
|
"div",
|
|
81
81
|
{
|
|
82
82
|
className: "absolute inset-0 z-10 flex items-center justify-center bg-muted",
|
|
83
|
-
style: {
|
|
83
|
+
style: {
|
|
84
|
+
...overlayStyle,
|
|
85
|
+
backgroundColor: "var(--slop-muted, var(--muted, #f3f4f6))"
|
|
86
|
+
},
|
|
84
87
|
title: error.message,
|
|
85
88
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
86
89
|
"div",
|
|
@@ -91,7 +94,7 @@ var ErrorOverlay = ({
|
|
|
91
94
|
flexDirection: "column",
|
|
92
95
|
alignItems: "center",
|
|
93
96
|
gap: "0.5rem",
|
|
94
|
-
color: "var(--muted-foreground, #6b7280)"
|
|
97
|
+
color: "var(--slop-muted-foreground, var(--muted-foreground, #6b7280))"
|
|
95
98
|
},
|
|
96
99
|
children: [
|
|
97
100
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
@@ -123,6 +126,7 @@ var ErrorOverlay = ({
|
|
|
123
126
|
|
|
124
127
|
// src/components/SlopImage.tsx
|
|
125
128
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
129
|
+
var DEFAULT_ALT = "Image produced by Slop Machine (slopmachine.dev)";
|
|
126
130
|
function cn(...inputs) {
|
|
127
131
|
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
|
|
128
132
|
}
|
|
@@ -134,6 +138,7 @@ var SlopImage = ({
|
|
|
134
138
|
metadata,
|
|
135
139
|
className,
|
|
136
140
|
aspectRatio = "1:1",
|
|
141
|
+
alt = DEFAULT_ALT,
|
|
137
142
|
model,
|
|
138
143
|
version,
|
|
139
144
|
resultId,
|
|
@@ -190,7 +195,6 @@ var SlopImage = ({
|
|
|
190
195
|
}, 100);
|
|
191
196
|
return () => clearTimeout(timer);
|
|
192
197
|
}, [rawSrc]);
|
|
193
|
-
const alt = "Image produced by Slop Machine (slopmachine.dev)";
|
|
194
198
|
const [isLoading, setIsLoading] = (0, import_react.useState)(true);
|
|
195
199
|
const [error, setError] = (0, import_react.useState)(null);
|
|
196
200
|
const [currentSrc, setCurrentSrc] = (0, import_react.useState)(src);
|
|
@@ -289,7 +293,7 @@ var SlopImage = ({
|
|
|
289
293
|
display: "flex",
|
|
290
294
|
alignItems: "center",
|
|
291
295
|
justifyContent: "center",
|
|
292
|
-
backgroundColor: "var(--muted, #f3f4f6)",
|
|
296
|
+
backgroundColor: "var(--slop-muted, var(--muted, #f3f4f6))",
|
|
293
297
|
opacity: isLoading ? 1 : 0,
|
|
294
298
|
pointerEvents: isLoading ? "auto" : "none",
|
|
295
299
|
transition: "opacity 300ms ease-in-out"
|
|
@@ -315,7 +319,7 @@ var SlopImage = ({
|
|
|
315
319
|
style: {
|
|
316
320
|
width: "24px",
|
|
317
321
|
height: "24px",
|
|
318
|
-
color: "var(--muted-foreground, #6b7280)",
|
|
322
|
+
color: "var(--slop-muted-foreground, var(--muted-foreground, #6b7280))",
|
|
319
323
|
animation: "slop-spin 1s linear infinite"
|
|
320
324
|
},
|
|
321
325
|
children: [
|
|
@@ -349,7 +353,7 @@ var SlopImage = ({
|
|
|
349
353
|
className: "text-xs text-muted-foreground",
|
|
350
354
|
style: {
|
|
351
355
|
fontSize: "0.75rem",
|
|
352
|
-
color: "var(--muted-foreground, #6b7280)"
|
|
356
|
+
color: "var(--slop-muted-foreground, var(--muted-foreground, #6b7280))"
|
|
353
357
|
},
|
|
354
358
|
children: "Loading..."
|
|
355
359
|
}
|
|
@@ -372,7 +376,7 @@ var SlopImage = ({
|
|
|
372
376
|
left: 0,
|
|
373
377
|
right: 0,
|
|
374
378
|
bottom: 0,
|
|
375
|
-
background: "linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)",
|
|
379
|
+
background: "linear-gradient(90deg, var(--slop-muted, var(--muted, #f3f4f6)) 0%, var(--slop-shimmer, var(--muted-foreground, #e5e7eb)) 50%, var(--slop-muted, var(--muted, #f3f4f6)) 100%)",
|
|
376
380
|
backgroundSize: "200% 100%",
|
|
377
381
|
animation: "slop-shimmer 2s ease-in-out infinite",
|
|
378
382
|
opacity: isLoading ? 1 : 0,
|
|
@@ -450,6 +454,7 @@ var SlopVideo = ({
|
|
|
450
454
|
original,
|
|
451
455
|
attachments,
|
|
452
456
|
loader,
|
|
457
|
+
objectFit = "cover",
|
|
453
458
|
errorFallback,
|
|
454
459
|
onGenerationError,
|
|
455
460
|
autoPlay = true,
|
|
@@ -598,7 +603,7 @@ var SlopVideo = ({
|
|
|
598
603
|
display: "flex",
|
|
599
604
|
alignItems: "center",
|
|
600
605
|
justifyContent: "center",
|
|
601
|
-
backgroundColor: "var(--muted, #f3f4f6)",
|
|
606
|
+
backgroundColor: "var(--slop-muted, var(--muted, #f3f4f6))",
|
|
602
607
|
opacity: isLoading ? 1 : 0,
|
|
603
608
|
pointerEvents: isLoading ? "auto" : "none",
|
|
604
609
|
transition: "opacity 300ms ease-in-out"
|
|
@@ -624,7 +629,7 @@ var SlopVideo = ({
|
|
|
624
629
|
style: {
|
|
625
630
|
width: "24px",
|
|
626
631
|
height: "24px",
|
|
627
|
-
color: "var(--muted-foreground, #6b7280)",
|
|
632
|
+
color: "var(--slop-muted-foreground, var(--muted-foreground, #6b7280))",
|
|
628
633
|
animation: "slop-spin 1s linear infinite"
|
|
629
634
|
},
|
|
630
635
|
children: [
|
|
@@ -658,7 +663,7 @@ var SlopVideo = ({
|
|
|
658
663
|
className: "text-xs text-muted-foreground",
|
|
659
664
|
style: {
|
|
660
665
|
fontSize: "0.75rem",
|
|
661
|
-
color: "var(--muted-foreground, #6b7280)"
|
|
666
|
+
color: "var(--slop-muted-foreground, var(--muted-foreground, #6b7280))"
|
|
662
667
|
},
|
|
663
668
|
children: "Loading..."
|
|
664
669
|
}
|
|
@@ -681,7 +686,7 @@ var SlopVideo = ({
|
|
|
681
686
|
left: 0,
|
|
682
687
|
right: 0,
|
|
683
688
|
bottom: 0,
|
|
684
|
-
background: "linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)",
|
|
689
|
+
background: "linear-gradient(90deg, var(--slop-muted, var(--muted, #f3f4f6)) 0%, var(--slop-shimmer, var(--muted-foreground, #e5e7eb)) 50%, var(--slop-muted, var(--muted, #f3f4f6)) 100%)",
|
|
685
690
|
backgroundSize: "200% 100%",
|
|
686
691
|
animation: "slop-shimmer 2s ease-in-out infinite",
|
|
687
692
|
opacity: isLoading ? 1 : 0,
|
|
@@ -718,13 +723,13 @@ var SlopVideo = ({
|
|
|
718
723
|
},
|
|
719
724
|
"aria-hidden": error ? true : props["aria-hidden"],
|
|
720
725
|
className: cn2(
|
|
721
|
-
"h-full w-full
|
|
726
|
+
"h-full w-full transition-opacity duration-500",
|
|
722
727
|
isLoading || error ? "opacity-0" : "opacity-100"
|
|
723
728
|
),
|
|
724
729
|
style: {
|
|
725
730
|
height: "100%",
|
|
726
731
|
width: "100%",
|
|
727
|
-
objectFit
|
|
732
|
+
objectFit,
|
|
728
733
|
transition: "opacity 500ms",
|
|
729
734
|
opacity: isLoading || error ? 0 : 1
|
|
730
735
|
}
|
|
@@ -756,6 +761,7 @@ var SlopText = import_react3.default.forwardRef(
|
|
|
756
761
|
attachments,
|
|
757
762
|
fallback,
|
|
758
763
|
errorFallback,
|
|
764
|
+
onGenerationError,
|
|
759
765
|
...props
|
|
760
766
|
}, ref) => {
|
|
761
767
|
const [text, setText] = (0, import_react3.useState)(null);
|
|
@@ -789,48 +795,48 @@ var SlopText = import_react3.default.forwardRef(
|
|
|
789
795
|
JSON.stringify(attachments)
|
|
790
796
|
]
|
|
791
797
|
);
|
|
798
|
+
const onGenerationErrorRef = (0, import_react3.useRef)(onGenerationError);
|
|
792
799
|
(0, import_react3.useEffect)(() => {
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
} catch (err) {
|
|
816
|
-
if (isMounted) {
|
|
817
|
-
const finalError = err instanceof Error ? err : new Error("Failed to generate text");
|
|
818
|
-
console.error(finalError);
|
|
819
|
-
setError(finalError);
|
|
820
|
-
}
|
|
821
|
-
} finally {
|
|
822
|
-
if (isMounted) {
|
|
823
|
-
setLoading(false);
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
};
|
|
827
|
-
fetchText();
|
|
828
|
-
return () => {
|
|
829
|
-
isMounted = false;
|
|
830
|
-
};
|
|
800
|
+
onGenerationErrorRef.current = onGenerationError;
|
|
801
|
+
});
|
|
802
|
+
(0, import_react3.useEffect)(() => {
|
|
803
|
+
const controller = new AbortController();
|
|
804
|
+
setLoading(true);
|
|
805
|
+
setError(null);
|
|
806
|
+
(0, import_core3.fetchRenderedText)(rawUrl, { signal: controller.signal }).then((content) => {
|
|
807
|
+
setText(content);
|
|
808
|
+
setLoading(false);
|
|
809
|
+
}).catch((err) => {
|
|
810
|
+
if (controller.signal.aborted) return;
|
|
811
|
+
const finalError = err instanceof import_core3.SlopMachineError ? err : new import_core3.SlopMachineError("Failed to load text");
|
|
812
|
+
console.error(
|
|
813
|
+
"SlopText error:",
|
|
814
|
+
finalError.status ?? "",
|
|
815
|
+
finalError.message
|
|
816
|
+
);
|
|
817
|
+
setError(finalError);
|
|
818
|
+
setLoading(false);
|
|
819
|
+
onGenerationErrorRef.current?.(finalError);
|
|
820
|
+
});
|
|
821
|
+
return () => controller.abort();
|
|
831
822
|
}, [rawUrl]);
|
|
832
|
-
if (error
|
|
833
|
-
|
|
823
|
+
if (error) {
|
|
824
|
+
if (errorFallback !== void 0) {
|
|
825
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: typeof errorFallback === "function" ? errorFallback(error) : errorFallback });
|
|
826
|
+
}
|
|
827
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
828
|
+
"div",
|
|
829
|
+
{
|
|
830
|
+
className: "slop-wrapper relative overflow-hidden w-full",
|
|
831
|
+
style: {
|
|
832
|
+
position: "relative",
|
|
833
|
+
overflow: "hidden",
|
|
834
|
+
width: "100%",
|
|
835
|
+
minHeight: "100px"
|
|
836
|
+
},
|
|
837
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ErrorOverlay, { error, label: "Failed to load text" })
|
|
838
|
+
}
|
|
839
|
+
) });
|
|
834
840
|
}
|
|
835
841
|
if (loading) {
|
|
836
842
|
if (fallback) {
|
|
@@ -872,7 +878,7 @@ var SlopText = import_react3.default.forwardRef(
|
|
|
872
878
|
display: "flex",
|
|
873
879
|
alignItems: "center",
|
|
874
880
|
justifyContent: "center",
|
|
875
|
-
backgroundColor: "var(--muted, #f3f4f6)"
|
|
881
|
+
backgroundColor: "var(--slop-muted, var(--muted, #f3f4f6))"
|
|
876
882
|
},
|
|
877
883
|
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
878
884
|
"div",
|
|
@@ -895,7 +901,7 @@ var SlopText = import_react3.default.forwardRef(
|
|
|
895
901
|
style: {
|
|
896
902
|
width: "24px",
|
|
897
903
|
height: "24px",
|
|
898
|
-
color: "var(--muted-foreground, #6b7280)",
|
|
904
|
+
color: "var(--slop-muted-foreground, var(--muted-foreground, #6b7280))",
|
|
899
905
|
animation: "slop-spin 1s linear infinite"
|
|
900
906
|
},
|
|
901
907
|
children: [
|
|
@@ -929,7 +935,7 @@ var SlopText = import_react3.default.forwardRef(
|
|
|
929
935
|
className: "text-xs text-muted-foreground",
|
|
930
936
|
style: {
|
|
931
937
|
fontSize: "0.75rem",
|
|
932
|
-
color: "var(--muted-foreground, #6b7280)"
|
|
938
|
+
color: "var(--slop-muted-foreground, var(--muted-foreground, #6b7280))"
|
|
933
939
|
},
|
|
934
940
|
children: "Loading..."
|
|
935
941
|
}
|
|
@@ -949,7 +955,7 @@ var SlopText = import_react3.default.forwardRef(
|
|
|
949
955
|
left: 0,
|
|
950
956
|
right: 0,
|
|
951
957
|
bottom: 0,
|
|
952
|
-
background: "linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)",
|
|
958
|
+
background: "linear-gradient(90deg, var(--slop-muted, var(--muted, #f3f4f6)) 0%, var(--slop-shimmer, var(--muted-foreground, #e5e7eb)) 50%, var(--slop-muted, var(--muted, #f3f4f6)) 100%)",
|
|
953
959
|
backgroundSize: "200% 100%",
|
|
954
960
|
animation: "slop-shimmer 2s ease-in-out infinite"
|
|
955
961
|
}
|