@adsterra-ad/react 0.1.2 → 0.1.4

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;
71
- const wrapperStyle = getWrapperStyle(adLabelPosition);
76
+ if (adFailed && !showFallbackPlaceholder) return null;
77
+ const wrapperStyle = getWrapperStyle(config);
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" };
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
  }
@@ -128,11 +140,12 @@ function parseStyle(styleString) {
128
140
  justifyContent: "center"
129
141
  };
130
142
  }
131
- function getWrapperStyle(position) {
143
+ function getWrapperStyle(config) {
132
144
  return {
133
145
  display: "inline-flex",
134
146
  flexDirection: "column",
135
- alignItems: position.endsWith("left") ? "flex-start" : position.endsWith("right") ? "flex-end" : "center"
147
+ alignItems: "flex-start",
148
+ width: typeof config.width === "number" ? `${config.width}px` : config.width
136
149
  };
137
150
  }
138
151
  function getLabelStyle(position) {
@@ -141,7 +154,7 @@ function getLabelStyle(position) {
141
154
  fontWeight: 600,
142
155
  letterSpacing: "0.1em",
143
156
  textTransform: "uppercase",
144
- color: "#9ca3af",
157
+ opacity: 0.6,
145
158
  marginBottom: position.startsWith("top") ? 4 : 0,
146
159
  marginTop: position.startsWith("bottom") ? 4 : 0,
147
160
  textAlign: position.endsWith("left") ? "left" : position.endsWith("right") ? "right" : "center",
@@ -160,6 +173,35 @@ function getVisibilityStyle(isVisible) {
160
173
  overflow: "hidden"
161
174
  };
162
175
  }
176
+ function FallbackPlaceholder({ format, text }) {
177
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
178
+ "div",
179
+ {
180
+ role: "img",
181
+ "aria-label": `${text} placeholder`,
182
+ style: {
183
+ width: "100%",
184
+ height: "100%",
185
+ display: "flex",
186
+ flexDirection: "column",
187
+ alignItems: "center",
188
+ justifyContent: "center",
189
+ gap: 6,
190
+ boxSizing: "border-box",
191
+ padding: 12,
192
+ border: "1px dashed currentColor",
193
+ opacity: 0.7,
194
+ background: "transparent",
195
+ textAlign: "center",
196
+ fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'
197
+ },
198
+ children: [
199
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { style: { fontSize: 13, lineHeight: 1.2 }, children: text }),
200
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 11, lineHeight: 1.2 }, children: format })
201
+ ]
202
+ }
203
+ );
204
+ }
163
205
  var index_default = AdBanner;
164
206
  // Annotate the CommonJS export names for ESM import in node:
165
207
  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;
50
- const wrapperStyle = getWrapperStyle(adLabelPosition);
55
+ if (adFailed && !showFallbackPlaceholder) return null;
56
+ const wrapperStyle = getWrapperStyle(config);
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" };
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
  }
@@ -107,11 +119,12 @@ function parseStyle(styleString) {
107
119
  justifyContent: "center"
108
120
  };
109
121
  }
110
- function getWrapperStyle(position) {
122
+ function getWrapperStyle(config) {
111
123
  return {
112
124
  display: "inline-flex",
113
125
  flexDirection: "column",
114
- alignItems: position.endsWith("left") ? "flex-start" : position.endsWith("right") ? "flex-end" : "center"
126
+ alignItems: "flex-start",
127
+ width: typeof config.width === "number" ? `${config.width}px` : config.width
115
128
  };
116
129
  }
117
130
  function getLabelStyle(position) {
@@ -120,7 +133,7 @@ function getLabelStyle(position) {
120
133
  fontWeight: 600,
121
134
  letterSpacing: "0.1em",
122
135
  textTransform: "uppercase",
123
- color: "#9ca3af",
136
+ opacity: 0.6,
124
137
  marginBottom: position.startsWith("top") ? 4 : 0,
125
138
  marginTop: position.startsWith("bottom") ? 4 : 0,
126
139
  textAlign: position.endsWith("left") ? "left" : position.endsWith("right") ? "right" : "center",
@@ -139,6 +152,35 @@ function getVisibilityStyle(isVisible) {
139
152
  overflow: "hidden"
140
153
  };
141
154
  }
155
+ function FallbackPlaceholder({ format, text }) {
156
+ return /* @__PURE__ */ jsxs(
157
+ "div",
158
+ {
159
+ role: "img",
160
+ "aria-label": `${text} placeholder`,
161
+ style: {
162
+ width: "100%",
163
+ height: "100%",
164
+ display: "flex",
165
+ flexDirection: "column",
166
+ alignItems: "center",
167
+ justifyContent: "center",
168
+ gap: 6,
169
+ boxSizing: "border-box",
170
+ padding: 12,
171
+ border: "1px dashed currentColor",
172
+ opacity: 0.7,
173
+ background: "transparent",
174
+ textAlign: "center",
175
+ fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'
176
+ },
177
+ children: [
178
+ /* @__PURE__ */ jsx("strong", { style: { fontSize: 13, lineHeight: 1.2 }, children: text }),
179
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 11, lineHeight: 1.2 }, children: format })
180
+ ]
181
+ }
182
+ );
183
+ }
142
184
  var index_default = AdBanner;
143
185
  export {
144
186
  AdBanner,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adsterra-ad/react",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
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.2"
34
+ "@adsterra-ad/core": "0.1.4"
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
+ }