@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 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, RateResultOptions, RateResultResponse, ResultRating, SlopImageOptions, SlopMachineError, SlopTextOptions, SlopVideoOptions, VideoAspectRatio, preloadImage, preloadText, preloadVideo, rateResult } from '@slopmachine/core';
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" | "alt">, Omit<SlopImageOptions, "aspectRatio"> {
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.8.1
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.8.1
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
- * Optional error component to show if the text generation fails
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
- errorFallback?: React.ReactNode;
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.8.1
177
+ * @version 1.0.0
160
178
  */
161
179
  declare const SlopText: React.ForwardRefExoticComponent<SlopTextProps & React.RefAttributes<HTMLDivElement>>;
162
180
 
163
- export { type SlopErrorFallback, SlopImage, type SlopImageProps, SlopText, type SlopTextProps, SlopVideo, type SlopVideoProps };
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, RateResultOptions, RateResultResponse, ResultRating, SlopImageOptions, SlopMachineError, SlopTextOptions, SlopVideoOptions, VideoAspectRatio, preloadImage, preloadText, preloadVideo, rateResult } from '@slopmachine/core';
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" | "alt">, Omit<SlopImageOptions, "aspectRatio"> {
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.8.1
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.8.1
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
- * Optional error component to show if the text generation fails
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
- errorFallback?: React.ReactNode;
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.8.1
177
+ * @version 1.0.0
160
178
  */
161
179
  declare const SlopText: React.ForwardRefExoticComponent<SlopTextProps & React.RefAttributes<HTMLDivElement>>;
162
180
 
163
- export { type SlopErrorFallback, SlopImage, type SlopImageProps, SlopText, type SlopTextProps, SlopVideo, type SlopVideoProps };
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: { ...overlayStyle, backgroundColor: "var(--muted, #f3f4f6)" },
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 object-cover transition-opacity duration-500",
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: "cover",
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
- let isMounted = true;
794
- const fetchText = async () => {
795
- try {
796
- setLoading(true);
797
- setError(null);
798
- const response = await fetch(rawUrl, { cache: "no-store" });
799
- if (!response.ok) {
800
- let errorMessage = response.statusText;
801
- try {
802
- const errorText = await response.text();
803
- const errorData = JSON.parse(errorText);
804
- if (errorData.error) {
805
- errorMessage = errorData.error;
806
- }
807
- } catch (e) {
808
- }
809
- throw new Error(`Failed to fetch text: ${errorMessage}`);
810
- }
811
- const content = await response.text();
812
- if (isMounted) {
813
- setText(content);
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 && errorFallback) {
833
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: errorFallback });
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