@slopmachine/react 0.8.1 → 1.0.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 +38 -0
- package/dist/index.d.mts +29 -10
- package/dist/index.d.ts +29 -10
- package/dist/index.js +65 -61
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +70 -64
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# @slopmachine/react
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 2c939d3: Require `apiKey` in `rateResult` options (`POST /api/results/{resultId}/rating` with `x-api-key`, optional `apiBaseUrl`) and remove `rateResult` re-exports from `@slopmachine/react` and `@slopmachine/svelte` since rating is for server-side use only.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [2c939d3]
|
|
12
|
+
- @slopmachine/core@1.0.0
|
|
13
|
+
|
|
14
|
+
## 0.9.0
|
|
15
|
+
|
|
16
|
+
### Minor Changes
|
|
17
|
+
|
|
18
|
+
- 56eaf03: Component polish (React and Svelte):
|
|
19
|
+
|
|
20
|
+
- **`alt` on `SlopImage`:** describe the image for screen readers (or pass `""` for decorative images). The default text is unchanged.
|
|
21
|
+
- **`objectFit` on `SlopVideo`:** matches `SlopImage`; defaults to `"cover"`.
|
|
22
|
+
- **`SlopText` error handling** now matches `SlopImage`/`SlopVideo`:
|
|
23
|
+
- a default "Failed to load text" message instead of an empty element;
|
|
24
|
+
- `onGenerationError(error)`;
|
|
25
|
+
- errors are `SlopMachineError` with the API's message and HTTP `status`;
|
|
26
|
+
- React's `errorFallback` also accepts `(error) => node`.
|
|
27
|
+
- **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.
|
|
28
|
+
- **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.
|
|
29
|
+
- **Svelte now matches React:**
|
|
30
|
+
- `SlopImage`/`SlopVideo` render the media URL immediately, including when server-rendering (previously an empty `src` for 50 ms);
|
|
31
|
+
- later prop changes are debounced by 100 ms, as in React;
|
|
32
|
+
- `SlopText` bypasses the HTTP cache, as React already did;
|
|
33
|
+
- `SlopTextProps` is now exported.
|
|
34
|
+
- **Core:** new `fetchRenderedText(url, { signal })`, shared by both `SlopText` components.
|
|
35
|
+
|
|
36
|
+
### Patch Changes
|
|
37
|
+
|
|
38
|
+
- Updated dependencies [56eaf03]
|
|
39
|
+
- @slopmachine/core@0.9.0
|
|
40
|
+
|
|
3
41
|
## 0.8.1
|
|
4
42
|
|
|
5
43
|
### Patch Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { SlopMachineError, SlopImageOptions, ImageAspectRatio, SlopVideoOptions, VideoAspectRatio, SlopTextOptions } from '@slopmachine/core';
|
|
3
|
-
export { ImageAspectRatio,
|
|
3
|
+
export { ImageAspectRatio, SlopImageOptions, SlopMachineError, SlopTextOptions, SlopVideoOptions, VideoAspectRatio, preloadImage, preloadText, preloadVideo } from '@slopmachine/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Content to render when generation or loading fails. Either a node, or a
|
|
@@ -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 1.0.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 1.0.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,8 +174,9 @@ interface SlopTextProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "chil
|
|
|
156
174
|
* />
|
|
157
175
|
* ```
|
|
158
176
|
*
|
|
159
|
-
* @version 0.
|
|
177
|
+
* @version 1.0.0
|
|
160
178
|
*/
|
|
161
179
|
declare const SlopText: React.ForwardRefExoticComponent<SlopTextProps & React.RefAttributes<HTMLDivElement>>;
|
|
162
180
|
|
|
163
|
-
export {
|
|
181
|
+
export { SlopImage, SlopText, SlopVideo };
|
|
182
|
+
export type { SlopErrorFallback, SlopImageProps, SlopTextProps, SlopVideoProps };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { SlopMachineError, SlopImageOptions, ImageAspectRatio, SlopVideoOptions, VideoAspectRatio, SlopTextOptions } from '@slopmachine/core';
|
|
3
|
-
export { ImageAspectRatio,
|
|
3
|
+
export { ImageAspectRatio, SlopImageOptions, SlopMachineError, SlopTextOptions, SlopVideoOptions, VideoAspectRatio, preloadImage, preloadText, preloadVideo } from '@slopmachine/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Content to render when generation or loading fails. Either a node, or a
|
|
@@ -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 1.0.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 1.0.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,8 +174,9 @@ interface SlopTextProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "chil
|
|
|
156
174
|
* />
|
|
157
175
|
* ```
|
|
158
176
|
*
|
|
159
|
-
* @version 0.
|
|
177
|
+
* @version 1.0.0
|
|
160
178
|
*/
|
|
161
179
|
declare const SlopText: React.ForwardRefExoticComponent<SlopTextProps & React.RefAttributes<HTMLDivElement>>;
|
|
162
180
|
|
|
163
|
-
export {
|
|
181
|
+
export { SlopImage, SlopText, SlopVideo };
|
|
182
|
+
export type { SlopErrorFallback, SlopImageProps, SlopTextProps, SlopVideoProps };
|
package/dist/index.js
CHANGED
|
@@ -37,8 +37,7 @@ __export(index_exports, {
|
|
|
37
37
|
SlopVideo: () => SlopVideo,
|
|
38
38
|
preloadImage: () => import_core4.preloadImage,
|
|
39
39
|
preloadText: () => import_core4.preloadText,
|
|
40
|
-
preloadVideo: () => import_core4.preloadVideo
|
|
41
|
-
rateResult: () => import_core4.rateResult
|
|
40
|
+
preloadVideo: () => import_core4.preloadVideo
|
|
42
41
|
});
|
|
43
42
|
module.exports = __toCommonJS(index_exports);
|
|
44
43
|
|
|
@@ -80,7 +79,10 @@ var ErrorOverlay = ({
|
|
|
80
79
|
"div",
|
|
81
80
|
{
|
|
82
81
|
className: "absolute inset-0 z-10 flex items-center justify-center bg-muted",
|
|
83
|
-
style: {
|
|
82
|
+
style: {
|
|
83
|
+
...overlayStyle,
|
|
84
|
+
backgroundColor: "var(--slop-muted, var(--muted, #f3f4f6))"
|
|
85
|
+
},
|
|
84
86
|
title: error.message,
|
|
85
87
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
86
88
|
"div",
|
|
@@ -91,7 +93,7 @@ var ErrorOverlay = ({
|
|
|
91
93
|
flexDirection: "column",
|
|
92
94
|
alignItems: "center",
|
|
93
95
|
gap: "0.5rem",
|
|
94
|
-
color: "var(--muted-foreground, #6b7280)"
|
|
96
|
+
color: "var(--slop-muted-foreground, var(--muted-foreground, #6b7280))"
|
|
95
97
|
},
|
|
96
98
|
children: [
|
|
97
99
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
@@ -123,6 +125,7 @@ var ErrorOverlay = ({
|
|
|
123
125
|
|
|
124
126
|
// src/components/SlopImage.tsx
|
|
125
127
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
128
|
+
var DEFAULT_ALT = "Image produced by Slop Machine (slopmachine.dev)";
|
|
126
129
|
function cn(...inputs) {
|
|
127
130
|
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
|
|
128
131
|
}
|
|
@@ -134,6 +137,7 @@ var SlopImage = ({
|
|
|
134
137
|
metadata,
|
|
135
138
|
className,
|
|
136
139
|
aspectRatio = "1:1",
|
|
140
|
+
alt = DEFAULT_ALT,
|
|
137
141
|
model,
|
|
138
142
|
version,
|
|
139
143
|
resultId,
|
|
@@ -190,7 +194,6 @@ var SlopImage = ({
|
|
|
190
194
|
}, 100);
|
|
191
195
|
return () => clearTimeout(timer);
|
|
192
196
|
}, [rawSrc]);
|
|
193
|
-
const alt = "Image produced by Slop Machine (slopmachine.dev)";
|
|
194
197
|
const [isLoading, setIsLoading] = (0, import_react.useState)(true);
|
|
195
198
|
const [error, setError] = (0, import_react.useState)(null);
|
|
196
199
|
const [currentSrc, setCurrentSrc] = (0, import_react.useState)(src);
|
|
@@ -289,7 +292,7 @@ var SlopImage = ({
|
|
|
289
292
|
display: "flex",
|
|
290
293
|
alignItems: "center",
|
|
291
294
|
justifyContent: "center",
|
|
292
|
-
backgroundColor: "var(--muted, #f3f4f6)",
|
|
295
|
+
backgroundColor: "var(--slop-muted, var(--muted, #f3f4f6))",
|
|
293
296
|
opacity: isLoading ? 1 : 0,
|
|
294
297
|
pointerEvents: isLoading ? "auto" : "none",
|
|
295
298
|
transition: "opacity 300ms ease-in-out"
|
|
@@ -315,7 +318,7 @@ var SlopImage = ({
|
|
|
315
318
|
style: {
|
|
316
319
|
width: "24px",
|
|
317
320
|
height: "24px",
|
|
318
|
-
color: "var(--muted-foreground, #6b7280)",
|
|
321
|
+
color: "var(--slop-muted-foreground, var(--muted-foreground, #6b7280))",
|
|
319
322
|
animation: "slop-spin 1s linear infinite"
|
|
320
323
|
},
|
|
321
324
|
children: [
|
|
@@ -349,7 +352,7 @@ var SlopImage = ({
|
|
|
349
352
|
className: "text-xs text-muted-foreground",
|
|
350
353
|
style: {
|
|
351
354
|
fontSize: "0.75rem",
|
|
352
|
-
color: "var(--muted-foreground, #6b7280)"
|
|
355
|
+
color: "var(--slop-muted-foreground, var(--muted-foreground, #6b7280))"
|
|
353
356
|
},
|
|
354
357
|
children: "Loading..."
|
|
355
358
|
}
|
|
@@ -372,7 +375,7 @@ var SlopImage = ({
|
|
|
372
375
|
left: 0,
|
|
373
376
|
right: 0,
|
|
374
377
|
bottom: 0,
|
|
375
|
-
background: "linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)",
|
|
378
|
+
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
379
|
backgroundSize: "200% 100%",
|
|
377
380
|
animation: "slop-shimmer 2s ease-in-out infinite",
|
|
378
381
|
opacity: isLoading ? 1 : 0,
|
|
@@ -450,6 +453,7 @@ var SlopVideo = ({
|
|
|
450
453
|
original,
|
|
451
454
|
attachments,
|
|
452
455
|
loader,
|
|
456
|
+
objectFit = "cover",
|
|
453
457
|
errorFallback,
|
|
454
458
|
onGenerationError,
|
|
455
459
|
autoPlay = true,
|
|
@@ -598,7 +602,7 @@ var SlopVideo = ({
|
|
|
598
602
|
display: "flex",
|
|
599
603
|
alignItems: "center",
|
|
600
604
|
justifyContent: "center",
|
|
601
|
-
backgroundColor: "var(--muted, #f3f4f6)",
|
|
605
|
+
backgroundColor: "var(--slop-muted, var(--muted, #f3f4f6))",
|
|
602
606
|
opacity: isLoading ? 1 : 0,
|
|
603
607
|
pointerEvents: isLoading ? "auto" : "none",
|
|
604
608
|
transition: "opacity 300ms ease-in-out"
|
|
@@ -624,7 +628,7 @@ var SlopVideo = ({
|
|
|
624
628
|
style: {
|
|
625
629
|
width: "24px",
|
|
626
630
|
height: "24px",
|
|
627
|
-
color: "var(--muted-foreground, #6b7280)",
|
|
631
|
+
color: "var(--slop-muted-foreground, var(--muted-foreground, #6b7280))",
|
|
628
632
|
animation: "slop-spin 1s linear infinite"
|
|
629
633
|
},
|
|
630
634
|
children: [
|
|
@@ -658,7 +662,7 @@ var SlopVideo = ({
|
|
|
658
662
|
className: "text-xs text-muted-foreground",
|
|
659
663
|
style: {
|
|
660
664
|
fontSize: "0.75rem",
|
|
661
|
-
color: "var(--muted-foreground, #6b7280)"
|
|
665
|
+
color: "var(--slop-muted-foreground, var(--muted-foreground, #6b7280))"
|
|
662
666
|
},
|
|
663
667
|
children: "Loading..."
|
|
664
668
|
}
|
|
@@ -681,7 +685,7 @@ var SlopVideo = ({
|
|
|
681
685
|
left: 0,
|
|
682
686
|
right: 0,
|
|
683
687
|
bottom: 0,
|
|
684
|
-
background: "linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)",
|
|
688
|
+
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
689
|
backgroundSize: "200% 100%",
|
|
686
690
|
animation: "slop-shimmer 2s ease-in-out infinite",
|
|
687
691
|
opacity: isLoading ? 1 : 0,
|
|
@@ -718,13 +722,13 @@ var SlopVideo = ({
|
|
|
718
722
|
},
|
|
719
723
|
"aria-hidden": error ? true : props["aria-hidden"],
|
|
720
724
|
className: cn2(
|
|
721
|
-
"h-full w-full
|
|
725
|
+
"h-full w-full transition-opacity duration-500",
|
|
722
726
|
isLoading || error ? "opacity-0" : "opacity-100"
|
|
723
727
|
),
|
|
724
728
|
style: {
|
|
725
729
|
height: "100%",
|
|
726
730
|
width: "100%",
|
|
727
|
-
objectFit
|
|
731
|
+
objectFit,
|
|
728
732
|
transition: "opacity 500ms",
|
|
729
733
|
opacity: isLoading || error ? 0 : 1
|
|
730
734
|
}
|
|
@@ -756,6 +760,7 @@ var SlopText = import_react3.default.forwardRef(
|
|
|
756
760
|
attachments,
|
|
757
761
|
fallback,
|
|
758
762
|
errorFallback,
|
|
763
|
+
onGenerationError,
|
|
759
764
|
...props
|
|
760
765
|
}, ref) => {
|
|
761
766
|
const [text, setText] = (0, import_react3.useState)(null);
|
|
@@ -789,48 +794,48 @@ var SlopText = import_react3.default.forwardRef(
|
|
|
789
794
|
JSON.stringify(attachments)
|
|
790
795
|
]
|
|
791
796
|
);
|
|
797
|
+
const onGenerationErrorRef = (0, import_react3.useRef)(onGenerationError);
|
|
792
798
|
(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
|
-
};
|
|
799
|
+
onGenerationErrorRef.current = onGenerationError;
|
|
800
|
+
});
|
|
801
|
+
(0, import_react3.useEffect)(() => {
|
|
802
|
+
const controller = new AbortController();
|
|
803
|
+
setLoading(true);
|
|
804
|
+
setError(null);
|
|
805
|
+
(0, import_core3.fetchRenderedText)(rawUrl, { signal: controller.signal }).then((content) => {
|
|
806
|
+
setText(content);
|
|
807
|
+
setLoading(false);
|
|
808
|
+
}).catch((err) => {
|
|
809
|
+
if (controller.signal.aborted) return;
|
|
810
|
+
const finalError = err instanceof import_core3.SlopMachineError ? err : new import_core3.SlopMachineError("Failed to load text");
|
|
811
|
+
console.error(
|
|
812
|
+
"SlopText error:",
|
|
813
|
+
finalError.status ?? "",
|
|
814
|
+
finalError.message
|
|
815
|
+
);
|
|
816
|
+
setError(finalError);
|
|
817
|
+
setLoading(false);
|
|
818
|
+
onGenerationErrorRef.current?.(finalError);
|
|
819
|
+
});
|
|
820
|
+
return () => controller.abort();
|
|
831
821
|
}, [rawUrl]);
|
|
832
|
-
if (error
|
|
833
|
-
|
|
822
|
+
if (error) {
|
|
823
|
+
if (errorFallback !== void 0) {
|
|
824
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: typeof errorFallback === "function" ? errorFallback(error) : errorFallback });
|
|
825
|
+
}
|
|
826
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
827
|
+
"div",
|
|
828
|
+
{
|
|
829
|
+
className: "slop-wrapper relative overflow-hidden w-full",
|
|
830
|
+
style: {
|
|
831
|
+
position: "relative",
|
|
832
|
+
overflow: "hidden",
|
|
833
|
+
width: "100%",
|
|
834
|
+
minHeight: "100px"
|
|
835
|
+
},
|
|
836
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ErrorOverlay, { error, label: "Failed to load text" })
|
|
837
|
+
}
|
|
838
|
+
) });
|
|
834
839
|
}
|
|
835
840
|
if (loading) {
|
|
836
841
|
if (fallback) {
|
|
@@ -872,7 +877,7 @@ var SlopText = import_react3.default.forwardRef(
|
|
|
872
877
|
display: "flex",
|
|
873
878
|
alignItems: "center",
|
|
874
879
|
justifyContent: "center",
|
|
875
|
-
backgroundColor: "var(--muted, #f3f4f6)"
|
|
880
|
+
backgroundColor: "var(--slop-muted, var(--muted, #f3f4f6))"
|
|
876
881
|
},
|
|
877
882
|
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
878
883
|
"div",
|
|
@@ -895,7 +900,7 @@ var SlopText = import_react3.default.forwardRef(
|
|
|
895
900
|
style: {
|
|
896
901
|
width: "24px",
|
|
897
902
|
height: "24px",
|
|
898
|
-
color: "var(--muted-foreground, #6b7280)",
|
|
903
|
+
color: "var(--slop-muted-foreground, var(--muted-foreground, #6b7280))",
|
|
899
904
|
animation: "slop-spin 1s linear infinite"
|
|
900
905
|
},
|
|
901
906
|
children: [
|
|
@@ -929,7 +934,7 @@ var SlopText = import_react3.default.forwardRef(
|
|
|
929
934
|
className: "text-xs text-muted-foreground",
|
|
930
935
|
style: {
|
|
931
936
|
fontSize: "0.75rem",
|
|
932
|
-
color: "var(--muted-foreground, #6b7280)"
|
|
937
|
+
color: "var(--slop-muted-foreground, var(--muted-foreground, #6b7280))"
|
|
933
938
|
},
|
|
934
939
|
children: "Loading..."
|
|
935
940
|
}
|
|
@@ -949,7 +954,7 @@ var SlopText = import_react3.default.forwardRef(
|
|
|
949
954
|
left: 0,
|
|
950
955
|
right: 0,
|
|
951
956
|
bottom: 0,
|
|
952
|
-
background: "linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)",
|
|
957
|
+
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
958
|
backgroundSize: "200% 100%",
|
|
954
959
|
animation: "slop-shimmer 2s ease-in-out infinite"
|
|
955
960
|
}
|
|
@@ -984,7 +989,6 @@ var import_core4 = require("@slopmachine/core");
|
|
|
984
989
|
SlopVideo,
|
|
985
990
|
preloadImage,
|
|
986
991
|
preloadText,
|
|
987
|
-
preloadVideo
|
|
988
|
-
rateResult
|
|
992
|
+
preloadVideo
|
|
989
993
|
});
|
|
990
994
|
//# sourceMappingURL=index.js.map
|