adkit-react 0.1.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/README.md +122 -0
- package/dist/index.d.mts +95 -0
- package/dist/index.d.ts +95 -0
- package/dist/index.js +412 -0
- package/dist/index.mjs +373 -0
- package/dist/styles.css +284 -0
- package/dist/styles.d.mts +2 -0
- package/dist/styles.d.ts +2 -0
- package/package.json +56 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
|
|
31
|
+
// src/index.ts
|
|
32
|
+
var index_exports = {};
|
|
33
|
+
__export(index_exports, {
|
|
34
|
+
AdSlot: () => AdSlot,
|
|
35
|
+
AdkitProvider: () => AdkitProvider,
|
|
36
|
+
BookingModal: () => BookingModal,
|
|
37
|
+
useAdkit: () => useAdkit
|
|
38
|
+
});
|
|
39
|
+
module.exports = __toCommonJS(index_exports);
|
|
40
|
+
|
|
41
|
+
// src/AdSlot.tsx
|
|
42
|
+
var React3 = __toESM(require("react"));
|
|
43
|
+
|
|
44
|
+
// src/eventClient.ts
|
|
45
|
+
var API_URL = "https://adkit.dev/api/events";
|
|
46
|
+
function sendEvent(payload) {
|
|
47
|
+
try {
|
|
48
|
+
fetch(API_URL, {
|
|
49
|
+
method: "POST",
|
|
50
|
+
headers: { "Content-Type": "application/json" },
|
|
51
|
+
body: JSON.stringify({ ...payload, timestamp: Date.now() }),
|
|
52
|
+
keepalive: true
|
|
53
|
+
}).catch(() => {
|
|
54
|
+
});
|
|
55
|
+
} catch {
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/AdkitContext.tsx
|
|
60
|
+
var React = __toESM(require("react"));
|
|
61
|
+
var AdkitContext = React.createContext(null);
|
|
62
|
+
function useAdkit() {
|
|
63
|
+
const ctx = React.useContext(AdkitContext);
|
|
64
|
+
if (!ctx) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
'[Adkit] <AdSlot /> must be used inside <AdkitProvider />. Wrap your app with <AdkitProvider siteId="your-site-id">.'
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
return ctx;
|
|
70
|
+
}
|
|
71
|
+
function deriveSlotIdentity(siteId, slot) {
|
|
72
|
+
return `${siteId}:${slot}`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// src/BookingModal.tsx
|
|
76
|
+
var React2 = __toESM(require("react"));
|
|
77
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
78
|
+
function BookingModal({ siteId, slot, price, onClose }) {
|
|
79
|
+
const overlayRef = React2.useRef(null);
|
|
80
|
+
React2.useEffect(() => {
|
|
81
|
+
const handleKey = (e) => {
|
|
82
|
+
if (e.key === "Escape") onClose();
|
|
83
|
+
};
|
|
84
|
+
document.addEventListener("keydown", handleKey);
|
|
85
|
+
return () => document.removeEventListener("keydown", handleKey);
|
|
86
|
+
}, [onClose]);
|
|
87
|
+
React2.useEffect(() => {
|
|
88
|
+
const prev = document.body.style.overflow;
|
|
89
|
+
document.body.style.overflow = "hidden";
|
|
90
|
+
return () => {
|
|
91
|
+
document.body.style.overflow = prev;
|
|
92
|
+
};
|
|
93
|
+
}, []);
|
|
94
|
+
const handleOverlayClick = (e) => {
|
|
95
|
+
if (e.target === overlayRef.current) onClose();
|
|
96
|
+
};
|
|
97
|
+
const dollars = price / 100;
|
|
98
|
+
const formatted = Number.isInteger(dollars) ? `$${dollars}` : `$${dollars.toFixed(2)}`;
|
|
99
|
+
const handleBook = () => {
|
|
100
|
+
const params = new URLSearchParams({
|
|
101
|
+
siteId,
|
|
102
|
+
slot,
|
|
103
|
+
price: String(price),
|
|
104
|
+
ref: window.location.href
|
|
105
|
+
});
|
|
106
|
+
window.location.href = `https://adkit.dev/book?${params.toString()}`;
|
|
107
|
+
};
|
|
108
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
109
|
+
"div",
|
|
110
|
+
{
|
|
111
|
+
ref: overlayRef,
|
|
112
|
+
className: "adkit-modal-overlay",
|
|
113
|
+
onClick: handleOverlayClick,
|
|
114
|
+
role: "dialog",
|
|
115
|
+
"aria-modal": "true",
|
|
116
|
+
"aria-label": "Book this ad space",
|
|
117
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "adkit-modal-card", children: [
|
|
118
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h2", { className: "adkit-modal-headline", children: [
|
|
119
|
+
"Advertise directly on ",
|
|
120
|
+
typeof window !== "undefined" ? window.location.hostname : "this site",
|
|
121
|
+
"."
|
|
122
|
+
] }),
|
|
123
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "adkit-modal-subhead", children: [
|
|
124
|
+
"Rent this ad space for a fixed price and reach your target audience where they really are: ",
|
|
125
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "right here" }),
|
|
126
|
+
"."
|
|
127
|
+
] }),
|
|
128
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("ul", { className: "adkit-modal-bullets", children: [
|
|
129
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { children: "Exclusive placement, no other ads will be shown" }),
|
|
130
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { children: "Fixed price \u2014 no bidding, auctions, or fees" }),
|
|
131
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { children: "See your ad before you pay, no commitments" }),
|
|
132
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { children: "Track your ad's performance on your dashboard" }),
|
|
133
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { children: "Guaranteed to display 24/7 or your money back" })
|
|
134
|
+
] }),
|
|
135
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "adkit-modal-price-section", children: [
|
|
136
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "adkit-modal-price", children: [
|
|
137
|
+
formatted,
|
|
138
|
+
" / day"
|
|
139
|
+
] }),
|
|
140
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "adkit-modal-price-helper", children: "Zero commitment. No minimum booking period." })
|
|
141
|
+
] }),
|
|
142
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "adkit-modal-actions", children: [
|
|
143
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "adkit-modal-cta", onClick: handleBook, children: "Book this ad" }),
|
|
144
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "adkit-modal-redirect-hint", children: "You'll be redirected to Adkit to upload your ad and choose dates." }),
|
|
145
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "adkit-modal-cancel", onClick: onClose, children: "Cancel" })
|
|
146
|
+
] }),
|
|
147
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "adkit-modal-footer", children: [
|
|
148
|
+
"Powered by ",
|
|
149
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href: "https://adkit.dev", target: "_blank", rel: "noopener noreferrer", children: "Adkit" })
|
|
150
|
+
] })
|
|
151
|
+
] })
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// src/AdSlot.tsx
|
|
157
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
158
|
+
var RATIO_CSS = {
|
|
159
|
+
"16:9": "16 / 9",
|
|
160
|
+
"4:3": "4 / 3",
|
|
161
|
+
"1:1": "1 / 1",
|
|
162
|
+
"9:16": "9 / 16",
|
|
163
|
+
"banner": "728 / 90"
|
|
164
|
+
};
|
|
165
|
+
var RATIO_VALUE = {
|
|
166
|
+
"16:9": 16 / 9,
|
|
167
|
+
"4:3": 4 / 3,
|
|
168
|
+
"1:1": 1,
|
|
169
|
+
"9:16": 9 / 16,
|
|
170
|
+
"banner": 728 / 90
|
|
171
|
+
};
|
|
172
|
+
var mountedSlots = /* @__PURE__ */ new Set();
|
|
173
|
+
var SERVE_BASE = "https://adkit.dev";
|
|
174
|
+
function useSystemDark() {
|
|
175
|
+
const [isDark, setIsDark] = React3.useState(false);
|
|
176
|
+
React3.useEffect(() => {
|
|
177
|
+
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
178
|
+
setIsDark(mq.matches);
|
|
179
|
+
const handler = (e) => setIsDark(e.matches);
|
|
180
|
+
mq.addEventListener("change", handler);
|
|
181
|
+
return () => mq.removeEventListener("change", handler);
|
|
182
|
+
}, []);
|
|
183
|
+
return isDark;
|
|
184
|
+
}
|
|
185
|
+
function AdSlot({
|
|
186
|
+
slot,
|
|
187
|
+
siteId: manualSiteId,
|
|
188
|
+
aspectRatio,
|
|
189
|
+
price = 2500,
|
|
190
|
+
size = "lg",
|
|
191
|
+
theme = "auto",
|
|
192
|
+
className,
|
|
193
|
+
styles,
|
|
194
|
+
silent = false
|
|
195
|
+
}) {
|
|
196
|
+
var _a, _b, _c, _d;
|
|
197
|
+
const slotRef = React3.useRef(null);
|
|
198
|
+
const hasViewedRef = React3.useRef(false);
|
|
199
|
+
const bookingIdRef = React3.useRef(void 0);
|
|
200
|
+
const systemDark = useSystemDark();
|
|
201
|
+
const [servedAd, setServedAd] = React3.useState({ status: "loading" });
|
|
202
|
+
React3.useEffect(() => {
|
|
203
|
+
bookingIdRef.current = servedAd.status === "active" ? servedAd.bookingId : void 0;
|
|
204
|
+
}, [servedAd]);
|
|
205
|
+
if (!aspectRatio) {
|
|
206
|
+
throw new Error("[Adkit] Missing aspectRatio. This prop is required and determines the ad format.");
|
|
207
|
+
}
|
|
208
|
+
if (!/^[A-Za-z0-9_-]+$/.test(slot)) {
|
|
209
|
+
throw new Error(`[Adkit] Invalid slot name "${slot}". Only letters, numbers, hyphens, and underscores allowed.`);
|
|
210
|
+
}
|
|
211
|
+
const ctx = React3.useContext(AdkitContext);
|
|
212
|
+
const siteId = manualSiteId != null ? manualSiteId : ctx == null ? void 0 : ctx.siteId;
|
|
213
|
+
if (!siteId) {
|
|
214
|
+
throw new Error('[Adkit] Missing siteId. Either wrap your app with <AdkitProvider siteId="..."> or pass siteId directly.');
|
|
215
|
+
}
|
|
216
|
+
const slotIdentity = deriveSlotIdentity(siteId, slot);
|
|
217
|
+
const expectedRatio = RATIO_VALUE[aspectRatio];
|
|
218
|
+
React3.useEffect(() => {
|
|
219
|
+
if (!ctx) return;
|
|
220
|
+
const isUnique = ctx.registerSlot(slotIdentity);
|
|
221
|
+
if (!isUnique) {
|
|
222
|
+
console.warn(`[Adkit] Duplicate slot "${slot}" detected on this page.`);
|
|
223
|
+
if (!silent) {
|
|
224
|
+
sendEvent({ type: "slot_duplicate", siteId, slot, pathname: window.location.pathname });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return () => ctx.unregisterSlot(slotIdentity);
|
|
228
|
+
}, [ctx, siteId, slotIdentity, slot, silent]);
|
|
229
|
+
React3.useEffect(() => {
|
|
230
|
+
if (silent || mountedSlots.has(slotIdentity)) return;
|
|
231
|
+
mountedSlots.add(slotIdentity);
|
|
232
|
+
sendEvent({
|
|
233
|
+
type: "slot_mount",
|
|
234
|
+
siteId,
|
|
235
|
+
slot,
|
|
236
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "",
|
|
237
|
+
price,
|
|
238
|
+
aspectRatio
|
|
239
|
+
});
|
|
240
|
+
}, [siteId, slotIdentity, slot, silent, price, aspectRatio]);
|
|
241
|
+
React3.useEffect(() => {
|
|
242
|
+
const ac = new AbortController();
|
|
243
|
+
fetch(`${SERVE_BASE}/api/serve?slotId=${encodeURIComponent(slotIdentity)}`, { signal: ac.signal }).then((res) => res.json()).then((data) => {
|
|
244
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
245
|
+
const d = data;
|
|
246
|
+
if (d.status === "active" && typeof d.imageUrl === "string" && typeof d.linkUrl === "string") {
|
|
247
|
+
const bookingId = typeof d.bookingId === "string" ? d.bookingId : void 0;
|
|
248
|
+
setServedAd({ status: "active", bookingId, imageUrl: d.imageUrl, linkUrl: d.linkUrl });
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
setServedAd({ status: "empty" });
|
|
253
|
+
}).catch(() => setServedAd({ status: "empty" }));
|
|
254
|
+
return () => ac.abort();
|
|
255
|
+
}, [slotIdentity]);
|
|
256
|
+
React3.useEffect(() => {
|
|
257
|
+
if (silent) return;
|
|
258
|
+
const el = slotRef.current;
|
|
259
|
+
if (!el || typeof IntersectionObserver === "undefined") return;
|
|
260
|
+
const observer = new IntersectionObserver(
|
|
261
|
+
([entry]) => {
|
|
262
|
+
if (entry.isIntersecting && entry.intersectionRatio >= 0.5 && !hasViewedRef.current) {
|
|
263
|
+
hasViewedRef.current = true;
|
|
264
|
+
const payload = {
|
|
265
|
+
type: "slot_view",
|
|
266
|
+
slotId: slotIdentity,
|
|
267
|
+
pathname: window.location.pathname,
|
|
268
|
+
viewport: { width: window.innerWidth, height: window.innerHeight }
|
|
269
|
+
};
|
|
270
|
+
if (bookingIdRef.current) payload.bookingId = bookingIdRef.current;
|
|
271
|
+
sendEvent(payload);
|
|
272
|
+
observer.disconnect();
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
{ threshold: [0.5] }
|
|
276
|
+
);
|
|
277
|
+
observer.observe(el);
|
|
278
|
+
return () => observer.disconnect();
|
|
279
|
+
}, [slotIdentity, siteId, slot, silent]);
|
|
280
|
+
React3.useEffect(() => {
|
|
281
|
+
const el = slotRef.current;
|
|
282
|
+
if (!el || typeof ResizeObserver === "undefined") return;
|
|
283
|
+
const checkRatio = () => {
|
|
284
|
+
const { width, height } = el.getBoundingClientRect();
|
|
285
|
+
if (width === 0 || height === 0) return;
|
|
286
|
+
const diff = Math.abs(width / height - expectedRatio) / expectedRatio;
|
|
287
|
+
if (diff > 0.05) {
|
|
288
|
+
console.warn("[Adkit] Slot aspect ratio mismatch. External CSS may be interfering.");
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
const observer = new ResizeObserver(checkRatio);
|
|
292
|
+
observer.observe(el);
|
|
293
|
+
checkRatio();
|
|
294
|
+
return () => observer.disconnect();
|
|
295
|
+
}, [expectedRatio]);
|
|
296
|
+
const [modalOpen, setModalOpen] = React3.useState(false);
|
|
297
|
+
const sendSlotClick = (bookingId) => {
|
|
298
|
+
if (typeof window === "undefined") return;
|
|
299
|
+
const payload = {
|
|
300
|
+
type: "slot_click",
|
|
301
|
+
slotId: slotIdentity,
|
|
302
|
+
pathname: window.location.pathname,
|
|
303
|
+
viewport: { width: window.innerWidth, height: window.innerHeight }
|
|
304
|
+
};
|
|
305
|
+
if (bookingId) payload.bookingId = bookingId;
|
|
306
|
+
sendEvent(payload);
|
|
307
|
+
};
|
|
308
|
+
const handlePlaceholderClick = () => {
|
|
309
|
+
if (silent) return;
|
|
310
|
+
sendSlotClick();
|
|
311
|
+
setModalOpen(true);
|
|
312
|
+
};
|
|
313
|
+
const handleAdClick = () => {
|
|
314
|
+
if (!silent && servedAd.status === "active") sendSlotClick(servedAd.bookingId);
|
|
315
|
+
};
|
|
316
|
+
const isDark = theme === "dark" ? true : theme === "light" ? false : systemDark;
|
|
317
|
+
const styleVars = {
|
|
318
|
+
"--adkit-aspect": RATIO_CSS[aspectRatio],
|
|
319
|
+
"--adkit-bg": (_a = styles == null ? void 0 : styles.backgroundColor) != null ? _a : "transparent",
|
|
320
|
+
"--adkit-text-muted": (_b = styles == null ? void 0 : styles.textColorSecondary) != null ? _b : isDark ? "rgba(255,255,255,0.6)" : "rgba(0,0,0,0.6)",
|
|
321
|
+
"--adkit-text": (_c = styles == null ? void 0 : styles.textColorSecondary) != null ? _c : isDark ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)",
|
|
322
|
+
"--adkit-text-strong": (_d = styles == null ? void 0 : styles.textColorPrimary) != null ? _d : isDark ? "rgba(255,255,255,0.9)" : "rgba(0,0,0,0.9)",
|
|
323
|
+
"--adkit-border": (styles == null ? void 0 : styles.borderColor) ? `color-mix(in srgb, ${styles.borderColor} 40%, transparent)` : isDark ? "rgba(255,255,255,0.22)" : "rgba(0,0,0,0.1)",
|
|
324
|
+
"--adkit-border-hover": (styles == null ? void 0 : styles.borderColor) ? `color-mix(in srgb, ${styles.borderColor} 60%, transparent)` : isDark ? "rgba(255,255,255,0.38)" : "rgba(0,0,0,0.2)"
|
|
325
|
+
};
|
|
326
|
+
const dollars = price / 100;
|
|
327
|
+
const formattedPrice = Number.isInteger(dollars) ? dollars.toLocaleString() : dollars.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
|
328
|
+
const isBanner = aspectRatio === "banner";
|
|
329
|
+
const isActive = servedAd.status === "active";
|
|
330
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
331
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
332
|
+
"div",
|
|
333
|
+
{
|
|
334
|
+
ref: slotRef,
|
|
335
|
+
className: `adkit-slot ${className ? className : "adkit-slot--default-width"}`,
|
|
336
|
+
style: styleVars,
|
|
337
|
+
"data-adkit-site": siteId,
|
|
338
|
+
"data-adkit-slot": slot,
|
|
339
|
+
"data-adkit-ratio": aspectRatio,
|
|
340
|
+
"data-adkit-size": size,
|
|
341
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "adkit-canvas", children: isActive ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
342
|
+
"a",
|
|
343
|
+
{
|
|
344
|
+
id: slot,
|
|
345
|
+
href: servedAd.linkUrl,
|
|
346
|
+
target: "_blank",
|
|
347
|
+
rel: "noopener noreferrer",
|
|
348
|
+
onClick: handleAdClick,
|
|
349
|
+
style: { display: "block", width: "100%", height: "100%" },
|
|
350
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
351
|
+
"img",
|
|
352
|
+
{
|
|
353
|
+
src: servedAd.imageUrl,
|
|
354
|
+
alt: "",
|
|
355
|
+
style: { display: "block", width: "100%", height: "100%", objectFit: "contain" }
|
|
356
|
+
}
|
|
357
|
+
)
|
|
358
|
+
}
|
|
359
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { id: `${slot}-placeholder`, className: "adkit-box", role: "button", tabIndex: 0, onClick: handlePlaceholderClick, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "adkit-content", children: [
|
|
360
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "adkit-label", children: "Your ad here" }),
|
|
361
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "adkit-price", children: [
|
|
362
|
+
"$",
|
|
363
|
+
formattedPrice,
|
|
364
|
+
"/day"
|
|
365
|
+
] }),
|
|
366
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "adkit-cta", children: [
|
|
367
|
+
isBanner ? "Rent" : "Rent this spot",
|
|
368
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "adkit-arrow", children: "\u2192" })
|
|
369
|
+
] })
|
|
370
|
+
] }) }) })
|
|
371
|
+
}
|
|
372
|
+
),
|
|
373
|
+
!isActive && modalOpen && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
374
|
+
BookingModal,
|
|
375
|
+
{
|
|
376
|
+
siteId,
|
|
377
|
+
slot,
|
|
378
|
+
price,
|
|
379
|
+
onClose: () => setModalOpen(false)
|
|
380
|
+
}
|
|
381
|
+
)
|
|
382
|
+
] });
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// src/AdkitProvider.tsx
|
|
386
|
+
var React4 = __toESM(require("react"));
|
|
387
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
388
|
+
function AdkitProvider({ siteId, children }) {
|
|
389
|
+
const slotsRef = React4.useRef(/* @__PURE__ */ new Set());
|
|
390
|
+
const registerSlot = React4.useCallback((identity) => {
|
|
391
|
+
if (slotsRef.current.has(identity)) {
|
|
392
|
+
return false;
|
|
393
|
+
}
|
|
394
|
+
slotsRef.current.add(identity);
|
|
395
|
+
return true;
|
|
396
|
+
}, []);
|
|
397
|
+
const unregisterSlot = React4.useCallback((identity) => {
|
|
398
|
+
slotsRef.current.delete(identity);
|
|
399
|
+
}, []);
|
|
400
|
+
const value = React4.useMemo(
|
|
401
|
+
() => ({ siteId, registerSlot, unregisterSlot }),
|
|
402
|
+
[siteId, registerSlot, unregisterSlot]
|
|
403
|
+
);
|
|
404
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AdkitContext.Provider, { value, children });
|
|
405
|
+
}
|
|
406
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
407
|
+
0 && (module.exports = {
|
|
408
|
+
AdSlot,
|
|
409
|
+
AdkitProvider,
|
|
410
|
+
BookingModal,
|
|
411
|
+
useAdkit
|
|
412
|
+
});
|