@adsterra-ad/react 0.1.1 → 0.1.3

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.cjs CHANGED
@@ -37,6 +37,8 @@ function AdBanner({
37
37
  adLabel = "Advertisement",
38
38
  showAdLabel = true,
39
39
  adLabelPosition = "top-left",
40
+ showFallbackPlaceholder = false,
41
+ fallbackPlaceholderText = "Test advertisement",
40
42
  onLoad,
41
43
  onError
42
44
  }) {
@@ -44,7 +46,11 @@ function AdBanner({
44
46
  const [activeProvider, setActiveProvider] = (0, import_react.useState)(provider);
45
47
  const [adLoaded, setAdLoaded] = (0, import_react.useState)(false);
46
48
  const [adFailed, setAdFailed] = (0, import_react.useState)(false);
47
- (0, import_react.useEffect)(() => setActiveProvider(provider), [provider]);
49
+ (0, import_react.useEffect)(() => {
50
+ setActiveProvider(provider);
51
+ setAdLoaded(false);
52
+ setAdFailed(false);
53
+ }, [provider, format, adKey]);
48
54
  const config = (0, import_core.resolveAdConfig)(format, adKey);
49
55
  const srcDoc = (0, import_react.useMemo)(
50
56
  () => (0, import_core.buildSrcDoc)({ format, provider: activeProvider, config, bannerId: bannerId.current }),
@@ -67,22 +73,24 @@ function AdBanner({
67
73
  window.addEventListener("message", handler);
68
74
  return () => window.removeEventListener("message", handler);
69
75
  }, [onLoad, onError]);
70
- if (adFailed) return null;
76
+ if (adFailed && !showFallbackPlaceholder) return null;
71
77
  const wrapperStyle = getWrapperStyle(adLabelPosition);
72
78
  const labelStyle = getLabelStyle(adLabelPosition);
73
- const visibilityStyle = getVisibilityStyle(adLoaded);
79
+ const visibilityStyle = getVisibilityStyle(adLoaded || adFailed && showFallbackPlaceholder);
80
+ const bannerStyle = { ...parseStyle((0, import_core.getBannerStyle)(config)), overflow: "hidden", borderRadius: 6, border: "1px solid #e5e7eb", background: "#f3f4f6" };
74
81
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: `${className ?? ""}`.trim(), style: { ...wrapperStyle, ...visibilityStyle }, children: [
75
82
  showAdLabel && adLabelPosition.startsWith("top") ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: labelStyle, children: adLabel }) : null,
76
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { "data-testid": "ad-banner", style: { ...parseStyle((0, import_core.getBannerStyle)(config)), overflow: "hidden", borderRadius: 6, border: "1px solid #e5e7eb", background: "#f3f4f6" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
83
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { "data-testid": "ad-banner", style: bannerStyle, children: adFailed && showFallbackPlaceholder ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FallbackPlaceholder, { format, text: fallbackPlaceholderText }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
77
84
  "iframe",
78
85
  {
79
86
  title: "Advertisement",
80
87
  srcDoc,
81
- width: typeof config.width === "number" ? config.width : void 0,
82
- height: typeof config.height === "number" ? config.height : void 0,
88
+ width: "100%",
89
+ height: "100%",
83
90
  frameBorder: 0,
84
91
  scrolling: "no",
85
- sandbox: "allow-scripts allow-forms allow-same-origin allow-popups allow-modals"
92
+ sandbox: "allow-scripts allow-forms allow-same-origin allow-popups allow-modals",
93
+ style: { display: "block", width: "100%", height: "100%" }
86
94
  }
87
95
  ) }),
88
96
  showAdLabel && adLabelPosition.startsWith("bottom") ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: labelStyle, children: adLabel }) : null
@@ -96,12 +104,14 @@ function AdContainer({
96
104
  adLabel,
97
105
  showAdLabel,
98
106
  adLabelPosition,
107
+ showFallbackPlaceholder,
108
+ fallbackPlaceholderText,
99
109
  containerClassName
100
110
  }) {
101
111
  const [adLoaded, setAdLoaded] = (0, import_react.useState)(false);
102
112
  const [adFailed, setAdFailed] = (0, import_react.useState)(false);
103
- if (adFailed) return null;
104
- const visibilityStyle = getVisibilityStyle(adLoaded);
113
+ if (adFailed && !showFallbackPlaceholder) return null;
114
+ const visibilityStyle = getVisibilityStyle(adLoaded || adFailed && !!showFallbackPlaceholder);
105
115
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `${containerClassName ?? ""}`.trim(), style: visibilityStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
106
116
  AdBanner,
107
117
  {
@@ -112,6 +122,8 @@ function AdContainer({
112
122
  adLabel,
113
123
  showAdLabel,
114
124
  adLabelPosition,
125
+ showFallbackPlaceholder,
126
+ fallbackPlaceholderText,
115
127
  onLoad: () => setAdLoaded(true),
116
128
  onError: () => setAdFailed(true)
117
129
  }
@@ -160,6 +172,34 @@ function getVisibilityStyle(isVisible) {
160
172
  overflow: "hidden"
161
173
  };
162
174
  }
175
+ function FallbackPlaceholder({ format, text }) {
176
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
177
+ "div",
178
+ {
179
+ role: "img",
180
+ "aria-label": `${text} placeholder`,
181
+ style: {
182
+ width: "100%",
183
+ height: "100%",
184
+ display: "flex",
185
+ flexDirection: "column",
186
+ alignItems: "center",
187
+ justifyContent: "center",
188
+ gap: 6,
189
+ boxSizing: "border-box",
190
+ padding: 12,
191
+ color: "#475569",
192
+ background: "repeating-linear-gradient(135deg, #f8fafc 0, #f8fafc 10px, #eef2f7 10px, #eef2f7 20px)",
193
+ textAlign: "center",
194
+ fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'
195
+ },
196
+ children: [
197
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { style: { fontSize: 13, lineHeight: 1.2 }, children: text }),
198
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 11, lineHeight: 1.2 }, children: format })
199
+ ]
200
+ }
201
+ );
202
+ }
163
203
  var index_default = AdBanner;
164
204
  // Annotate the CommonJS export names for ESM import in node:
165
205
  0 && (module.exports = {
package/dist/index.d.cts CHANGED
@@ -11,13 +11,15 @@ interface AdBannerProps {
11
11
  adLabel?: string;
12
12
  showAdLabel?: boolean;
13
13
  adLabelPosition?: AdLabelPosition;
14
+ showFallbackPlaceholder?: boolean;
15
+ fallbackPlaceholderText?: string;
14
16
  onLoad?: () => void;
15
17
  onError?: () => void;
16
18
  }
17
- declare function AdBanner({ format, provider, className, adKey, adLabel, showAdLabel, adLabelPosition, onLoad, onError }: AdBannerProps): react_jsx_runtime.JSX.Element | null;
19
+ declare function AdBanner({ format, provider, className, adKey, adLabel, showAdLabel, adLabelPosition, showFallbackPlaceholder, fallbackPlaceholderText, onLoad, onError }: AdBannerProps): react_jsx_runtime.JSX.Element | null;
18
20
  interface AdContainerProps extends Omit<AdBannerProps, 'onLoad' | 'onError'> {
19
21
  containerClassName?: string;
20
22
  }
21
- declare function AdContainer({ format, provider, className, adKey, adLabel, showAdLabel, adLabelPosition, containerClassName }: AdContainerProps): react_jsx_runtime.JSX.Element | null;
23
+ declare function AdContainer({ format, provider, className, adKey, adLabel, showAdLabel, adLabelPosition, showFallbackPlaceholder, fallbackPlaceholderText, containerClassName }: AdContainerProps): react_jsx_runtime.JSX.Element | null;
22
24
 
23
25
  export { AdBanner, type AdBannerProps, AdContainer, type AdContainerProps, type AdLabelPosition, AdBanner as default };
package/dist/index.d.ts CHANGED
@@ -11,13 +11,15 @@ interface AdBannerProps {
11
11
  adLabel?: string;
12
12
  showAdLabel?: boolean;
13
13
  adLabelPosition?: AdLabelPosition;
14
+ showFallbackPlaceholder?: boolean;
15
+ fallbackPlaceholderText?: string;
14
16
  onLoad?: () => void;
15
17
  onError?: () => void;
16
18
  }
17
- declare function AdBanner({ format, provider, className, adKey, adLabel, showAdLabel, adLabelPosition, onLoad, onError }: AdBannerProps): react_jsx_runtime.JSX.Element | null;
19
+ declare function AdBanner({ format, provider, className, adKey, adLabel, showAdLabel, adLabelPosition, showFallbackPlaceholder, fallbackPlaceholderText, onLoad, onError }: AdBannerProps): react_jsx_runtime.JSX.Element | null;
18
20
  interface AdContainerProps extends Omit<AdBannerProps, 'onLoad' | 'onError'> {
19
21
  containerClassName?: string;
20
22
  }
21
- declare function AdContainer({ format, provider, className, adKey, adLabel, showAdLabel, adLabelPosition, containerClassName }: AdContainerProps): react_jsx_runtime.JSX.Element | null;
23
+ declare function AdContainer({ format, provider, className, adKey, adLabel, showAdLabel, adLabelPosition, showFallbackPlaceholder, fallbackPlaceholderText, containerClassName }: AdContainerProps): react_jsx_runtime.JSX.Element | null;
22
24
 
23
25
  export { AdBanner, type AdBannerProps, AdContainer, type AdContainerProps, type AdLabelPosition, AdBanner as default };
package/dist/index.js CHANGED
@@ -16,6 +16,8 @@ function AdBanner({
16
16
  adLabel = "Advertisement",
17
17
  showAdLabel = true,
18
18
  adLabelPosition = "top-left",
19
+ showFallbackPlaceholder = false,
20
+ fallbackPlaceholderText = "Test advertisement",
19
21
  onLoad,
20
22
  onError
21
23
  }) {
@@ -23,7 +25,11 @@ function AdBanner({
23
25
  const [activeProvider, setActiveProvider] = useState(provider);
24
26
  const [adLoaded, setAdLoaded] = useState(false);
25
27
  const [adFailed, setAdFailed] = useState(false);
26
- useEffect(() => setActiveProvider(provider), [provider]);
28
+ useEffect(() => {
29
+ setActiveProvider(provider);
30
+ setAdLoaded(false);
31
+ setAdFailed(false);
32
+ }, [provider, format, adKey]);
27
33
  const config = resolveAdConfig(format, adKey);
28
34
  const srcDoc = useMemo(
29
35
  () => buildSrcDoc({ format, provider: activeProvider, config, bannerId: bannerId.current }),
@@ -46,22 +52,24 @@ function AdBanner({
46
52
  window.addEventListener("message", handler);
47
53
  return () => window.removeEventListener("message", handler);
48
54
  }, [onLoad, onError]);
49
- if (adFailed) return null;
55
+ if (adFailed && !showFallbackPlaceholder) return null;
50
56
  const wrapperStyle = getWrapperStyle(adLabelPosition);
51
57
  const labelStyle = getLabelStyle(adLabelPosition);
52
- const visibilityStyle = getVisibilityStyle(adLoaded);
58
+ const visibilityStyle = getVisibilityStyle(adLoaded || adFailed && showFallbackPlaceholder);
59
+ const bannerStyle = { ...parseStyle(getBannerStyle(config)), overflow: "hidden", borderRadius: 6, border: "1px solid #e5e7eb", background: "#f3f4f6" };
53
60
  return /* @__PURE__ */ jsxs("div", { className: `${className ?? ""}`.trim(), style: { ...wrapperStyle, ...visibilityStyle }, children: [
54
61
  showAdLabel && adLabelPosition.startsWith("top") ? /* @__PURE__ */ jsx("span", { style: labelStyle, children: adLabel }) : null,
55
- /* @__PURE__ */ jsx("div", { "data-testid": "ad-banner", style: { ...parseStyle(getBannerStyle(config)), overflow: "hidden", borderRadius: 6, border: "1px solid #e5e7eb", background: "#f3f4f6" }, children: /* @__PURE__ */ jsx(
62
+ /* @__PURE__ */ jsx("div", { "data-testid": "ad-banner", style: bannerStyle, children: adFailed && showFallbackPlaceholder ? /* @__PURE__ */ jsx(FallbackPlaceholder, { format, text: fallbackPlaceholderText }) : /* @__PURE__ */ jsx(
56
63
  "iframe",
57
64
  {
58
65
  title: "Advertisement",
59
66
  srcDoc,
60
- width: typeof config.width === "number" ? config.width : void 0,
61
- height: typeof config.height === "number" ? config.height : void 0,
67
+ width: "100%",
68
+ height: "100%",
62
69
  frameBorder: 0,
63
70
  scrolling: "no",
64
- sandbox: "allow-scripts allow-forms allow-same-origin allow-popups allow-modals"
71
+ sandbox: "allow-scripts allow-forms allow-same-origin allow-popups allow-modals",
72
+ style: { display: "block", width: "100%", height: "100%" }
65
73
  }
66
74
  ) }),
67
75
  showAdLabel && adLabelPosition.startsWith("bottom") ? /* @__PURE__ */ jsx("span", { style: labelStyle, children: adLabel }) : null
@@ -75,12 +83,14 @@ function AdContainer({
75
83
  adLabel,
76
84
  showAdLabel,
77
85
  adLabelPosition,
86
+ showFallbackPlaceholder,
87
+ fallbackPlaceholderText,
78
88
  containerClassName
79
89
  }) {
80
90
  const [adLoaded, setAdLoaded] = useState(false);
81
91
  const [adFailed, setAdFailed] = useState(false);
82
- if (adFailed) return null;
83
- const visibilityStyle = getVisibilityStyle(adLoaded);
92
+ if (adFailed && !showFallbackPlaceholder) return null;
93
+ const visibilityStyle = getVisibilityStyle(adLoaded || adFailed && !!showFallbackPlaceholder);
84
94
  return /* @__PURE__ */ jsx("div", { className: `${containerClassName ?? ""}`.trim(), style: visibilityStyle, children: /* @__PURE__ */ jsx(
85
95
  AdBanner,
86
96
  {
@@ -91,6 +101,8 @@ function AdContainer({
91
101
  adLabel,
92
102
  showAdLabel,
93
103
  adLabelPosition,
104
+ showFallbackPlaceholder,
105
+ fallbackPlaceholderText,
94
106
  onLoad: () => setAdLoaded(true),
95
107
  onError: () => setAdFailed(true)
96
108
  }
@@ -139,6 +151,34 @@ function getVisibilityStyle(isVisible) {
139
151
  overflow: "hidden"
140
152
  };
141
153
  }
154
+ function FallbackPlaceholder({ format, text }) {
155
+ return /* @__PURE__ */ jsxs(
156
+ "div",
157
+ {
158
+ role: "img",
159
+ "aria-label": `${text} placeholder`,
160
+ style: {
161
+ width: "100%",
162
+ height: "100%",
163
+ display: "flex",
164
+ flexDirection: "column",
165
+ alignItems: "center",
166
+ justifyContent: "center",
167
+ gap: 6,
168
+ boxSizing: "border-box",
169
+ padding: 12,
170
+ color: "#475569",
171
+ background: "repeating-linear-gradient(135deg, #f8fafc 0, #f8fafc 10px, #eef2f7 10px, #eef2f7 20px)",
172
+ textAlign: "center",
173
+ fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'
174
+ },
175
+ children: [
176
+ /* @__PURE__ */ jsx("strong", { style: { fontSize: 13, lineHeight: 1.2 }, children: text }),
177
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 11, lineHeight: 1.2 }, children: format })
178
+ ]
179
+ }
180
+ );
181
+ }
142
182
  var index_default = AdBanner;
143
183
  export {
144
184
  AdBanner,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adsterra-ad/react",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -31,7 +31,7 @@
31
31
  "react": "^18.0.0 || ^19.0.0"
32
32
  },
33
33
  "dependencies": {
34
- "@adsterra-ad/core": "0.1.1"
34
+ "@adsterra-ad/core": "0.1.3"
35
35
  },
36
36
  "scripts": {
37
37
  "build": "tsup src/index.tsx --format esm,cjs --dts",
@@ -43,4 +43,4 @@
43
43
  "tsup": "^8.2.4",
44
44
  "typescript": "^5.5.4"
45
45
  }
46
- }
46
+ }