@coincircuit/checkout 0.2.2 → 0.4.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.
@@ -102,6 +102,13 @@ function injectStyles() {
102
102
  border-radius: 16px;
103
103
  background: #fff;
104
104
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.4);
105
+ opacity: 0;
106
+ transform: scale(0.96);
107
+ transition: opacity 0.25s ease, transform 0.25s ease;
108
+ }
109
+ #${OVERLAY_ID} .cc-modal.cc-ready {
110
+ opacity: 1;
111
+ transform: scale(1);
105
112
  }
106
113
  #${OVERLAY_ID} .cc-close {
107
114
  position: fixed;
@@ -139,14 +146,14 @@ function injectStyles() {
139
146
  display: flex;
140
147
  align-items: center;
141
148
  justify-content: center;
142
- background: #fff;
149
+ z-index: 1;
143
150
  transition: opacity 0.2s;
144
151
  }
145
152
  #${OVERLAY_ID} .cc-spinner div {
146
153
  width: 36px;
147
154
  height: 36px;
148
- border: 3px solid #e5e7eb;
149
- border-top-color: #6366f1;
155
+ border: 3px solid rgba(255, 255, 255, 0.3);
156
+ border-top-color: #fff;
150
157
  border-radius: 50%;
151
158
  animation: cc-spin 0.8s linear infinite;
152
159
  }
@@ -179,7 +186,8 @@ function createOverlay(checkoutUrl, onCloseClick) {
179
186
  modal.className = "cc-modal";
180
187
  const spinner = document.createElement("div");
181
188
  spinner.className = "cc-spinner";
182
- spinner.innerHTML = "<div></div>";
189
+ const spinnerRing = document.createElement("div");
190
+ spinner.appendChild(spinnerRing);
183
191
  const iframe = document.createElement("iframe");
184
192
  iframe.src = checkoutUrl;
185
193
  iframe.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox");
@@ -191,8 +199,8 @@ function createOverlay(checkoutUrl, onCloseClick) {
191
199
  closeBtn.setAttribute("aria-label", "Close checkout");
192
200
  closeBtn.textContent = "\u2715";
193
201
  closeBtn.addEventListener("click", onCloseClick);
194
- modal.appendChild(spinner);
195
202
  modal.appendChild(iframe);
203
+ overlay.appendChild(spinner);
196
204
  overlay.appendChild(modal);
197
205
  overlay.appendChild(closeBtn);
198
206
  return { overlay, iframe };
@@ -217,6 +225,10 @@ function hideSpinner(overlay) {
217
225
  spinner.style.opacity = "0";
218
226
  setTimeout(() => spinner.parentNode?.removeChild(spinner), 200);
219
227
  }
228
+ const modal = overlay.querySelector(".cc-modal");
229
+ if (modal) {
230
+ modal.classList.add("cc-ready");
231
+ }
220
232
  }
221
233
  function showErrorToast(message) {
222
234
  const toast = document.createElement("div");
@@ -258,6 +270,7 @@ var CoinCircuitCheckout = class {
258
270
  overlay = null;
259
271
  removeMessageListener = null;
260
272
  loadTimeout = null;
273
+ openedAt = 0;
261
274
  constructor(config = {}) {
262
275
  this.baseUrl = config.baseUrl ? validateBaseUrl(config.baseUrl) : DEFAULT_BASE_URL;
263
276
  this.origin = extractOrigin(this.baseUrl);
@@ -274,6 +287,8 @@ var CoinCircuitCheckout = class {
274
287
  if (!options.reference) {
275
288
  throw new Error('CoinCircuitCheckout: "reference" is required.');
276
289
  }
290
+ this.openedAt = performance.now();
291
+ console.log("[CoinCircuit] open() called \u2014 waiting for coincircuit:ready");
277
292
  const checkoutUrl = buildCheckoutUrl(
278
293
  this.baseUrl,
279
294
  options.reference,
@@ -292,11 +307,17 @@ var CoinCircuitCheckout = class {
292
307
  }, 15e3);
293
308
  iframe.addEventListener("error", () => {
294
309
  if (this.loadTimeout) clearTimeout(this.loadTimeout);
310
+ console.error(`[CoinCircuit] iframe error after ${Math.round(performance.now() - this.openedAt)}ms`);
295
311
  showErrorToast("Checkout failed to load. Please try again.");
296
312
  this.close();
297
313
  });
314
+ iframe.addEventListener("load", () => {
315
+ console.log(`[CoinCircuit] iframe DOM loaded at ${Math.round(performance.now() - this.openedAt)}ms (still waiting for coincircuit:ready)`);
316
+ });
298
317
  this.removeMessageListener = createMessageListener(this.origin, {
299
318
  onReady: () => {
319
+ const elapsed = Math.round(performance.now() - this.openedAt);
320
+ console.log(`[CoinCircuit] coincircuit:ready received at ${elapsed}ms`);
300
321
  if (this.loadTimeout) {
301
322
  clearTimeout(this.loadTimeout);
302
323
  this.loadTimeout = null;
@@ -305,6 +326,7 @@ var CoinCircuitCheckout = class {
305
326
  options.onReady?.();
306
327
  },
307
328
  onPaymentComplete: (data) => {
329
+ console.log(`[CoinCircuit] coincircuit:payment_complete at ${Math.round(performance.now() - this.openedAt)}ms`);
308
330
  options.onPaymentComplete?.(data);
309
331
  },
310
332
  onPaymentFailed: (data) => {
package/dist/index.cjs CHANGED
@@ -133,6 +133,13 @@ function injectStyles() {
133
133
  border-radius: 16px;
134
134
  background: #fff;
135
135
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.4);
136
+ opacity: 0;
137
+ transform: scale(0.96);
138
+ transition: opacity 0.25s ease, transform 0.25s ease;
139
+ }
140
+ #${OVERLAY_ID} .cc-modal.cc-ready {
141
+ opacity: 1;
142
+ transform: scale(1);
136
143
  }
137
144
  #${OVERLAY_ID} .cc-close {
138
145
  position: fixed;
@@ -170,14 +177,14 @@ function injectStyles() {
170
177
  display: flex;
171
178
  align-items: center;
172
179
  justify-content: center;
173
- background: #fff;
180
+ z-index: 1;
174
181
  transition: opacity 0.2s;
175
182
  }
176
183
  #${OVERLAY_ID} .cc-spinner div {
177
184
  width: 36px;
178
185
  height: 36px;
179
- border: 3px solid #e5e7eb;
180
- border-top-color: #6366f1;
186
+ border: 3px solid rgba(255, 255, 255, 0.3);
187
+ border-top-color: #fff;
181
188
  border-radius: 50%;
182
189
  animation: cc-spin 0.8s linear infinite;
183
190
  }
@@ -210,7 +217,8 @@ function createOverlay(checkoutUrl, onCloseClick) {
210
217
  modal.className = "cc-modal";
211
218
  const spinner = document.createElement("div");
212
219
  spinner.className = "cc-spinner";
213
- spinner.innerHTML = "<div></div>";
220
+ const spinnerRing = document.createElement("div");
221
+ spinner.appendChild(spinnerRing);
214
222
  const iframe = document.createElement("iframe");
215
223
  iframe.src = checkoutUrl;
216
224
  iframe.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox");
@@ -222,8 +230,8 @@ function createOverlay(checkoutUrl, onCloseClick) {
222
230
  closeBtn.setAttribute("aria-label", "Close checkout");
223
231
  closeBtn.textContent = "\u2715";
224
232
  closeBtn.addEventListener("click", onCloseClick);
225
- modal.appendChild(spinner);
226
233
  modal.appendChild(iframe);
234
+ overlay.appendChild(spinner);
227
235
  overlay.appendChild(modal);
228
236
  overlay.appendChild(closeBtn);
229
237
  return { overlay, iframe };
@@ -248,6 +256,10 @@ function hideSpinner(overlay) {
248
256
  spinner.style.opacity = "0";
249
257
  setTimeout(() => spinner.parentNode?.removeChild(spinner), 200);
250
258
  }
259
+ const modal = overlay.querySelector(".cc-modal");
260
+ if (modal) {
261
+ modal.classList.add("cc-ready");
262
+ }
251
263
  }
252
264
  function showErrorToast(message) {
253
265
  const toast = document.createElement("div");
@@ -289,6 +301,7 @@ var CoinCircuitCheckout = class {
289
301
  overlay = null;
290
302
  removeMessageListener = null;
291
303
  loadTimeout = null;
304
+ openedAt = 0;
292
305
  constructor(config = {}) {
293
306
  this.baseUrl = config.baseUrl ? validateBaseUrl(config.baseUrl) : DEFAULT_BASE_URL;
294
307
  this.origin = extractOrigin(this.baseUrl);
@@ -305,6 +318,8 @@ var CoinCircuitCheckout = class {
305
318
  if (!options.reference) {
306
319
  throw new Error('CoinCircuitCheckout: "reference" is required.');
307
320
  }
321
+ this.openedAt = performance.now();
322
+ console.log("[CoinCircuit] open() called \u2014 waiting for coincircuit:ready");
308
323
  const checkoutUrl = buildCheckoutUrl(
309
324
  this.baseUrl,
310
325
  options.reference,
@@ -323,11 +338,17 @@ var CoinCircuitCheckout = class {
323
338
  }, 15e3);
324
339
  iframe.addEventListener("error", () => {
325
340
  if (this.loadTimeout) clearTimeout(this.loadTimeout);
341
+ console.error(`[CoinCircuit] iframe error after ${Math.round(performance.now() - this.openedAt)}ms`);
326
342
  showErrorToast("Checkout failed to load. Please try again.");
327
343
  this.close();
328
344
  });
345
+ iframe.addEventListener("load", () => {
346
+ console.log(`[CoinCircuit] iframe DOM loaded at ${Math.round(performance.now() - this.openedAt)}ms (still waiting for coincircuit:ready)`);
347
+ });
329
348
  this.removeMessageListener = createMessageListener(this.origin, {
330
349
  onReady: () => {
350
+ const elapsed = Math.round(performance.now() - this.openedAt);
351
+ console.log(`[CoinCircuit] coincircuit:ready received at ${elapsed}ms`);
331
352
  if (this.loadTimeout) {
332
353
  clearTimeout(this.loadTimeout);
333
354
  this.loadTimeout = null;
@@ -336,6 +357,7 @@ var CoinCircuitCheckout = class {
336
357
  options.onReady?.();
337
358
  },
338
359
  onPaymentComplete: (data) => {
360
+ console.log(`[CoinCircuit] coincircuit:payment_complete at ${Math.round(performance.now() - this.openedAt)}ms`);
339
361
  options.onPaymentComplete?.(data);
340
362
  },
341
363
  onPaymentFailed: (data) => {
package/dist/index.d.cts CHANGED
@@ -24,6 +24,7 @@ declare class CoinCircuitCheckout {
24
24
  private overlay;
25
25
  private removeMessageListener;
26
26
  private loadTimeout;
27
+ private openedAt;
27
28
  constructor(config?: CheckoutConfig);
28
29
  /**
29
30
  * Opens the checkout modal overlay.
package/dist/index.d.ts CHANGED
@@ -24,6 +24,7 @@ declare class CoinCircuitCheckout {
24
24
  private overlay;
25
25
  private removeMessageListener;
26
26
  private loadTimeout;
27
+ private openedAt;
27
28
  constructor(config?: CheckoutConfig);
28
29
  /**
29
30
  * Opens the checkout modal overlay.
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  buildCheckoutUrl,
6
6
  createMessageListener,
7
7
  extractOrigin
8
- } from "./chunk-DG6Y255K.js";
8
+ } from "./chunk-RJ3FMO5K.js";
9
9
  export {
10
10
  CHECKOUT_MESSAGE_TYPES,
11
11
  CoinCircuitCheckout,
package/dist/react.cjs CHANGED
@@ -129,6 +129,13 @@ function injectStyles() {
129
129
  border-radius: 16px;
130
130
  background: #fff;
131
131
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.4);
132
+ opacity: 0;
133
+ transform: scale(0.96);
134
+ transition: opacity 0.25s ease, transform 0.25s ease;
135
+ }
136
+ #${OVERLAY_ID} .cc-modal.cc-ready {
137
+ opacity: 1;
138
+ transform: scale(1);
132
139
  }
133
140
  #${OVERLAY_ID} .cc-close {
134
141
  position: fixed;
@@ -166,14 +173,14 @@ function injectStyles() {
166
173
  display: flex;
167
174
  align-items: center;
168
175
  justify-content: center;
169
- background: #fff;
176
+ z-index: 1;
170
177
  transition: opacity 0.2s;
171
178
  }
172
179
  #${OVERLAY_ID} .cc-spinner div {
173
180
  width: 36px;
174
181
  height: 36px;
175
- border: 3px solid #e5e7eb;
176
- border-top-color: #6366f1;
182
+ border: 3px solid rgba(255, 255, 255, 0.3);
183
+ border-top-color: #fff;
177
184
  border-radius: 50%;
178
185
  animation: cc-spin 0.8s linear infinite;
179
186
  }
@@ -206,7 +213,8 @@ function createOverlay(checkoutUrl, onCloseClick) {
206
213
  modal.className = "cc-modal";
207
214
  const spinner = document.createElement("div");
208
215
  spinner.className = "cc-spinner";
209
- spinner.innerHTML = "<div></div>";
216
+ const spinnerRing = document.createElement("div");
217
+ spinner.appendChild(spinnerRing);
210
218
  const iframe = document.createElement("iframe");
211
219
  iframe.src = checkoutUrl;
212
220
  iframe.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox");
@@ -218,8 +226,8 @@ function createOverlay(checkoutUrl, onCloseClick) {
218
226
  closeBtn.setAttribute("aria-label", "Close checkout");
219
227
  closeBtn.textContent = "\u2715";
220
228
  closeBtn.addEventListener("click", onCloseClick);
221
- modal.appendChild(spinner);
222
229
  modal.appendChild(iframe);
230
+ overlay.appendChild(spinner);
223
231
  overlay.appendChild(modal);
224
232
  overlay.appendChild(closeBtn);
225
233
  return { overlay, iframe };
@@ -244,6 +252,10 @@ function hideSpinner(overlay) {
244
252
  spinner.style.opacity = "0";
245
253
  setTimeout(() => spinner.parentNode?.removeChild(spinner), 200);
246
254
  }
255
+ const modal = overlay.querySelector(".cc-modal");
256
+ if (modal) {
257
+ modal.classList.add("cc-ready");
258
+ }
247
259
  }
248
260
  function showErrorToast(message) {
249
261
  const toast = document.createElement("div");
@@ -285,6 +297,7 @@ var CoinCircuitCheckout = class {
285
297
  overlay = null;
286
298
  removeMessageListener = null;
287
299
  loadTimeout = null;
300
+ openedAt = 0;
288
301
  constructor(config = {}) {
289
302
  this.baseUrl = config.baseUrl ? validateBaseUrl(config.baseUrl) : DEFAULT_BASE_URL;
290
303
  this.origin = extractOrigin(this.baseUrl);
@@ -301,6 +314,8 @@ var CoinCircuitCheckout = class {
301
314
  if (!options.reference) {
302
315
  throw new Error('CoinCircuitCheckout: "reference" is required.');
303
316
  }
317
+ this.openedAt = performance.now();
318
+ console.log("[CoinCircuit] open() called \u2014 waiting for coincircuit:ready");
304
319
  const checkoutUrl = buildCheckoutUrl(
305
320
  this.baseUrl,
306
321
  options.reference,
@@ -319,11 +334,17 @@ var CoinCircuitCheckout = class {
319
334
  }, 15e3);
320
335
  iframe.addEventListener("error", () => {
321
336
  if (this.loadTimeout) clearTimeout(this.loadTimeout);
337
+ console.error(`[CoinCircuit] iframe error after ${Math.round(performance.now() - this.openedAt)}ms`);
322
338
  showErrorToast("Checkout failed to load. Please try again.");
323
339
  this.close();
324
340
  });
341
+ iframe.addEventListener("load", () => {
342
+ console.log(`[CoinCircuit] iframe DOM loaded at ${Math.round(performance.now() - this.openedAt)}ms (still waiting for coincircuit:ready)`);
343
+ });
325
344
  this.removeMessageListener = createMessageListener(this.origin, {
326
345
  onReady: () => {
346
+ const elapsed = Math.round(performance.now() - this.openedAt);
347
+ console.log(`[CoinCircuit] coincircuit:ready received at ${elapsed}ms`);
327
348
  if (this.loadTimeout) {
328
349
  clearTimeout(this.loadTimeout);
329
350
  this.loadTimeout = null;
@@ -332,6 +353,7 @@ var CoinCircuitCheckout = class {
332
353
  options.onReady?.();
333
354
  },
334
355
  onPaymentComplete: (data) => {
356
+ console.log(`[CoinCircuit] coincircuit:payment_complete at ${Math.round(performance.now() - this.openedAt)}ms`);
335
357
  options.onPaymentComplete?.(data);
336
358
  },
337
359
  onPaymentFailed: (data) => {
package/dist/react.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  CoinCircuitCheckout
3
- } from "./chunk-DG6Y255K.js";
3
+ } from "./chunk-RJ3FMO5K.js";
4
4
 
5
5
  // src/react.ts
6
6
  import { useRef, useCallback, useEffect, createElement } from "react";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coincircuit/checkout",
3
- "version": "0.2.2",
3
+ "version": "0.4.0",
4
4
  "description": "Embed CoinCircuit checkout in your site via iframe, with vanilla JS and React support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",