@sudobility/consumables_pages 0.0.44 → 0.0.45

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.
@@ -0,0 +1,15 @@
1
+ import { CreditPaywallDialogProps } from './types';
2
+ /**
3
+ * Renders a centred modal containing the credit store, with the heading
4
+ * saying why it appeared.
5
+ *
6
+ * The shell is hand-rolled rather than taken from a component library,
7
+ * matching the rest of this package: it depends on `@sudobility/design` alone,
8
+ * so it drops into any consumer without dragging a UI framework behind it.
9
+ * That means it owns the behaviours a dialog is expected to have -- Escape to
10
+ * dismiss, a click on the backdrop to dismiss, focus moved in on open and
11
+ * returned on close, and a labelled `role="dialog"`.
12
+ *
13
+ * @param props - See {@link CreditPaywallDialogProps} for full prop documentation.
14
+ */
15
+ export declare function CreditPaywallDialog({ isOpen, onClose, isAuthenticated, balance, packages, isLoading, isPurchasing, error, onPurchase, onLoginClick, labels, formatters, className, }: CreditPaywallDialogProps): import("react").JSX.Element | null;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { CreditStorePage } from './CreditStorePage';
2
+ export { CreditPaywallDialog } from './CreditPaywallDialog';
2
3
  export { PurchaseHistoryPage } from './PurchaseHistoryPage';
3
4
  export { UsageHistoryPage } from './UsageHistoryPage';
4
5
  export { CreditBalanceBadge } from './CreditBalanceBadge';
5
- export type { CreditStorePageProps, CreditStorePageLabels, CreditStorePageFormatters, PurchaseHistoryPageProps, PurchaseHistoryPageLabels, PurchaseHistoryPageFormatters, UsageHistoryPageProps, UsageHistoryPageLabels, UsageHistoryPageFormatters, CreditBalanceBadgeProps, } from './types';
6
+ export type { CreditStorePageProps, CreditStorePageLabels, CreditStorePageFormatters, CreditPaywallDialogProps, CreditPaywallDialogLabels, PurchaseHistoryPageProps, PurchaseHistoryPageLabels, PurchaseHistoryPageFormatters, UsageHistoryPageProps, UsageHistoryPageLabels, UsageHistoryPageFormatters, CreditBalanceBadgeProps, } from './types';
6
7
  export type { ConsumableSource } from '@sudobility/types';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
- import { jsx as e, jsxs as d, Fragment as p } from "react/jsx-runtime";
2
- const k = {
1
+ import { jsx as e, jsxs as d, Fragment as v } from "react/jsx-runtime";
2
+ import { useRef as C, useEffect as D } from "react";
3
+ const y = {
3
4
  button: {
4
5
  // Primary button - main brand actions
5
6
  primary: {
@@ -203,23 +204,23 @@ const k = {
203
204
  icon: "text-red-600 dark:text-red-400"
204
205
  }
205
206
  }
206
- }, v = {
207
+ }, S = {
207
208
  get button() {
208
- return k.button;
209
+ return y.button;
209
210
  },
210
211
  get card() {
211
- return k.card;
212
+ return y.card;
212
213
  },
213
214
  get badge() {
214
- return k.badge;
215
+ return y.badge;
215
216
  },
216
217
  get alert() {
217
- return k.alert;
218
+ return y.alert;
218
219
  }
219
220
  }, t = {
220
221
  // Component-specific colors (use for components)
221
- component: v
222
- }, r = (n, l) => l, i = {
222
+ component: S
223
+ }, r = (n, i) => i, l = {
223
224
  // Border utilities (theme-aware getter)
224
225
  get border() {
225
226
  return {
@@ -277,7 +278,7 @@ const k = {
277
278
  };
278
279
  }
279
280
  };
280
- function y() {
281
+ function $() {
281
282
  return /* @__PURE__ */ e(
282
283
  "div",
283
284
  {
@@ -294,22 +295,22 @@ function y() {
294
295
  }
295
296
  );
296
297
  }
297
- function N({
298
+ function B({
298
299
  isAuthenticated: n,
299
- balance: l,
300
- packages: g,
301
- isLoading: c,
302
- isPurchasing: u,
300
+ balance: i,
301
+ packages: s,
302
+ isLoading: b,
303
+ isPurchasing: f,
303
304
  error: o,
304
305
  onPurchase: x,
305
- onLoginClick: f,
306
- labels: b,
306
+ onLoginClick: h,
307
+ labels: c,
307
308
  formatters: a,
308
- className: h
309
+ className: m
309
310
  }) {
310
- return /* @__PURE__ */ d("div", { className: h, children: [
311
- /* @__PURE__ */ e("h1", { className: "text-2xl font-bold mb-6 text-foreground", children: b.title }),
312
- n && l !== null && /* @__PURE__ */ d(
311
+ return /* @__PURE__ */ d("div", { className: m, children: [
312
+ c.title !== "" && /* @__PURE__ */ e("h1", { className: "text-2xl font-bold mb-6 text-foreground", children: c.title }),
313
+ n && i !== null && /* @__PURE__ */ d(
313
314
  "div",
314
315
  {
315
316
  className: `mb-8 p-4 rounded-lg border ${t.component.alert.info.base} ${t.component.alert.info.dark}`,
@@ -318,10 +319,10 @@ function N({
318
319
  "p",
319
320
  {
320
321
  className: `text-sm font-medium ${t.component.alert.info.icon}`,
321
- children: b.currentBalanceLabel
322
+ children: c.currentBalanceLabel
322
323
  }
323
324
  ),
324
- /* @__PURE__ */ e("p", { className: "text-3xl font-bold", children: a.formatCredits(l) })
325
+ /* @__PURE__ */ e("p", { className: "text-3xl font-bold", children: a.formatCredits(i) })
325
326
  ]
326
327
  }
327
328
  ),
@@ -331,7 +332,7 @@ function N({
331
332
  className: `mb-6 p-4 rounded-lg border ${t.component.alert.error.base} ${t.component.alert.error.dark}`,
332
333
  role: "alert",
333
334
  children: [
334
- /* @__PURE__ */ e("p", { className: "text-sm font-medium", children: b.errorTitle }),
335
+ /* @__PURE__ */ e("p", { className: "text-sm font-medium", children: c.errorTitle }),
335
336
  /* @__PURE__ */ e("p", { className: `text-sm ${t.component.alert.error.icon}`, children: o })
336
337
  ]
337
338
  }
@@ -341,100 +342,191 @@ function N({
341
342
  {
342
343
  className: `mb-6 p-4 rounded-lg border ${t.component.alert.warning.base} ${t.component.alert.warning.dark}`,
343
344
  children: [
344
- /* @__PURE__ */ e("p", { className: "text-sm", children: b.loginRequired }),
345
+ /* @__PURE__ */ e("p", { className: "text-sm", children: c.loginRequired }),
345
346
  /* @__PURE__ */ e(
346
347
  "button",
347
348
  {
348
- onClick: f,
349
+ onClick: h,
349
350
  className: `mt-2 px-4 py-2 text-sm font-medium rounded-lg transition-colors ${t.component.button.primary.base} ${t.component.button.primary.dark}`,
350
- children: b.loginButton ?? "Log in"
351
+ children: c.loginButton ?? "Log in"
351
352
  }
352
353
  )
353
354
  ]
354
355
  }
355
356
  ),
356
- c && /* @__PURE__ */ e(y, {}),
357
- !c && g.length === 0 && /* @__PURE__ */ e("p", { className: `${i.text.muted} text-center py-8`, children: b.noProducts }),
358
- !c && g.length > 0 && /* @__PURE__ */ e("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4", children: g.map((m) => /* @__PURE__ */ e(
357
+ b && /* @__PURE__ */ e($, {}),
358
+ !b && s.length === 0 && /* @__PURE__ */ e("p", { className: `${l.text.muted} text-center py-8`, children: c.noProducts }),
359
+ !b && s.length > 0 && /* @__PURE__ */ e("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4", children: s.map((u) => /* @__PURE__ */ e(
359
360
  "div",
360
361
  {
361
362
  className: `p-6 rounded-xl border shadow-sm hover:shadow-md transition-shadow ${t.component.card.default.base} ${t.component.card.default.dark}`,
362
363
  children: /* @__PURE__ */ d("div", { className: "text-center", children: [
363
- /* @__PURE__ */ e("p", { className: "text-3xl font-bold text-foreground", children: a.formatCredits(m.credits) }),
364
- a.getPackageDescription && /* @__PURE__ */ e("p", { className: "text-sm text-muted-foreground mt-1", children: a.getPackageDescription(m.packageId) }),
364
+ /* @__PURE__ */ e("p", { className: "text-3xl font-bold text-foreground", children: a.formatCredits(u.credits) }),
365
+ a.getPackageDescription && /* @__PURE__ */ e("p", { className: "text-sm text-muted-foreground mt-1", children: a.getPackageDescription(u.packageId) }),
365
366
  /* @__PURE__ */ e(
366
367
  "p",
367
368
  {
368
369
  className: `text-xl font-semibold mt-3 ${t.component.alert.info.icon}`,
369
- children: m.priceString
370
+ children: u.priceString
370
371
  }
371
372
  ),
372
373
  /* @__PURE__ */ e(
373
374
  "button",
374
375
  {
375
- onClick: () => x(m.packageId),
376
- disabled: u || !n,
376
+ onClick: () => x(u.packageId),
377
+ disabled: f || !n,
377
378
  className: `mt-4 w-full px-4 py-2.5 font-medium rounded-lg disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 ${t.component.button.primary.base} ${t.component.button.primary.dark}`,
378
- children: u ? b.purchasingButton : b.purchaseButton
379
+ children: f ? c.purchasingButton : c.purchaseButton
379
380
  }
380
381
  )
381
382
  ] })
382
383
  },
383
- m.packageId
384
+ u.packageId
384
385
  )) })
385
386
  ] });
386
387
  }
387
- function w({
388
+ function P({
389
+ isOpen: n,
390
+ onClose: i,
391
+ isAuthenticated: s,
392
+ balance: b,
393
+ packages: f,
394
+ isLoading: o,
395
+ isPurchasing: x,
396
+ error: h,
397
+ onPurchase: c,
398
+ onLoginClick: a,
399
+ labels: m,
400
+ formatters: u,
401
+ className: g
402
+ }) {
403
+ const N = C(null), w = C(null);
404
+ return D(() => {
405
+ if (!n) return;
406
+ w.current = document.activeElement, N.current?.focus();
407
+ const p = (k) => {
408
+ k.key === "Escape" && i();
409
+ };
410
+ return document.addEventListener("keydown", p), () => {
411
+ document.removeEventListener("keydown", p);
412
+ const k = w.current;
413
+ k instanceof HTMLElement && k.focus();
414
+ };
415
+ }, [n, i]), n ? /* @__PURE__ */ d(
416
+ "div",
417
+ {
418
+ className: "fixed inset-0 z-50 flex items-center justify-center p-4",
419
+ onMouseDown: (p) => {
420
+ p.target === p.currentTarget && i();
421
+ },
422
+ children: [
423
+ /* @__PURE__ */ e("div", { className: "absolute inset-0 bg-black/50", "aria-hidden": "true" }),
424
+ /* @__PURE__ */ d(
425
+ "div",
426
+ {
427
+ ref: N,
428
+ role: "dialog",
429
+ "aria-modal": "true",
430
+ "aria-labelledby": "credit-paywall-title",
431
+ tabIndex: -1,
432
+ className: `relative w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-xl border p-6 shadow-lg outline-none ${t.component.card.default.base} ${t.component.card.default.dark} ${l.border.default} ${g ?? ""}`,
433
+ children: [
434
+ /* @__PURE__ */ d("div", { className: "flex items-start justify-between gap-4 mb-4", children: [
435
+ /* @__PURE__ */ d("div", { children: [
436
+ /* @__PURE__ */ e(
437
+ "h2",
438
+ {
439
+ id: "credit-paywall-title",
440
+ className: "text-2xl font-bold text-foreground",
441
+ children: m.paywallTitle
442
+ }
443
+ ),
444
+ m.paywallMessage && /* @__PURE__ */ e("p", { className: `mt-2 text-sm ${l.text.muted}`, children: m.paywallMessage })
445
+ ] }),
446
+ /* @__PURE__ */ e(
447
+ "button",
448
+ {
449
+ type: "button",
450
+ onClick: i,
451
+ "aria-label": m.closeLabel,
452
+ className: `shrink-0 rounded-lg px-2 py-1 text-xl leading-none transition-colors ${l.text.muted} hover:text-foreground`,
453
+ children: "×"
454
+ }
455
+ )
456
+ ] }),
457
+ /* @__PURE__ */ e(
458
+ B,
459
+ {
460
+ isAuthenticated: s,
461
+ balance: b,
462
+ packages: f,
463
+ isLoading: o,
464
+ isPurchasing: x,
465
+ error: h,
466
+ onPurchase: c,
467
+ onLoginClick: a,
468
+ labels: { ...m, title: "" },
469
+ formatters: u
470
+ }
471
+ )
472
+ ]
473
+ }
474
+ )
475
+ ]
476
+ }
477
+ ) : null;
478
+ }
479
+ function j({
388
480
  purchases: n,
389
- isLoading: l,
390
- error: g,
391
- onLoadMore: c,
392
- hasMore: u,
481
+ isLoading: i,
482
+ error: s,
483
+ onLoadMore: b,
484
+ hasMore: f,
393
485
  labels: o,
394
486
  formatters: x,
395
- className: f,
396
- emptyStateComponent: b
487
+ className: h,
488
+ emptyStateComponent: c
397
489
  }) {
398
- return /* @__PURE__ */ d("div", { className: f, children: [
490
+ return /* @__PURE__ */ d("div", { className: h, children: [
399
491
  /* @__PURE__ */ e("h1", { className: "text-2xl font-bold mb-6 text-foreground", children: o.title }),
400
- g && /* @__PURE__ */ e(
492
+ s && /* @__PURE__ */ e(
401
493
  "div",
402
494
  {
403
495
  className: `mb-4 p-3 rounded-lg border ${t.component.alert.error.base} ${t.component.alert.error.dark}`,
404
496
  role: "alert",
405
- children: /* @__PURE__ */ e("p", { className: `text-sm ${t.component.alert.error.icon}`, children: g })
497
+ children: /* @__PURE__ */ e("p", { className: `text-sm ${t.component.alert.error.icon}`, children: s })
406
498
  }
407
499
  ),
408
- l && /* @__PURE__ */ e(y, {}),
409
- !l && n.length === 0 && /* @__PURE__ */ e(p, { children: b ?? /* @__PURE__ */ e("p", { className: `${i.text.muted} text-center py-8`, children: o.noRecords }) }),
410
- !l && n.length > 0 && /* @__PURE__ */ d(p, { children: [
500
+ i && /* @__PURE__ */ e($, {}),
501
+ !i && n.length === 0 && /* @__PURE__ */ e(v, { children: c ?? /* @__PURE__ */ e("p", { className: `${l.text.muted} text-center py-8`, children: o.noRecords }) }),
502
+ !i && n.length > 0 && /* @__PURE__ */ d(v, { children: [
411
503
  /* @__PURE__ */ e("div", { className: "hidden sm:block overflow-x-auto", children: /* @__PURE__ */ d("table", { className: "w-full text-sm", "aria-label": o.title, children: [
412
- /* @__PURE__ */ e("thead", { children: /* @__PURE__ */ d("tr", { className: `border-b ${i.border.default}`, children: [
504
+ /* @__PURE__ */ e("thead", { children: /* @__PURE__ */ d("tr", { className: `border-b ${l.border.default}`, children: [
413
505
  /* @__PURE__ */ e(
414
506
  "th",
415
507
  {
416
- className: `text-left py-3 px-4 font-medium ${i.text.muted}`,
508
+ className: `text-left py-3 px-4 font-medium ${l.text.muted}`,
417
509
  children: o.columnDate
418
510
  }
419
511
  ),
420
512
  /* @__PURE__ */ e(
421
513
  "th",
422
514
  {
423
- className: `text-right py-3 px-4 font-medium ${i.text.muted}`,
515
+ className: `text-right py-3 px-4 font-medium ${l.text.muted}`,
424
516
  children: o.columnCredits
425
517
  }
426
518
  ),
427
519
  /* @__PURE__ */ e(
428
520
  "th",
429
521
  {
430
- className: `text-left py-3 px-4 font-medium ${i.text.muted}`,
522
+ className: `text-left py-3 px-4 font-medium ${l.text.muted}`,
431
523
  children: o.columnSource
432
524
  }
433
525
  ),
434
526
  /* @__PURE__ */ e(
435
527
  "th",
436
528
  {
437
- className: `text-right py-3 px-4 font-medium ${i.text.muted}`,
529
+ className: `text-right py-3 px-4 font-medium ${l.text.muted}`,
438
530
  children: o.columnAmount
439
531
  }
440
532
  )
@@ -442,7 +534,7 @@ function w({
442
534
  /* @__PURE__ */ e("tbody", { children: n.map((a) => /* @__PURE__ */ d(
443
535
  "tr",
444
536
  {
445
- className: `border-b ${i.border.subtle} hover:bg-accent`,
537
+ className: `border-b ${l.border.subtle} hover:bg-accent`,
446
538
  children: [
447
539
  /* @__PURE__ */ e("td", { className: "py-3 px-4 text-foreground", children: x.formatDate(a.created_at) }),
448
540
  /* @__PURE__ */ d("td", { className: "py-3 px-4 text-right font-medium text-success", children: [
@@ -486,127 +578,127 @@ function w({
486
578
  },
487
579
  a.id
488
580
  )) }),
489
- u && c && /* @__PURE__ */ e("div", { className: "mt-4 text-center", children: /* @__PURE__ */ e(
581
+ f && b && /* @__PURE__ */ e("div", { className: "mt-4 text-center", children: /* @__PURE__ */ e(
490
582
  "button",
491
583
  {
492
- onClick: c,
493
- className: `px-4 py-2 text-sm font-medium ${i.text.link}`,
584
+ onClick: b,
585
+ className: `px-4 py-2 text-sm font-medium ${l.text.link}`,
494
586
  children: o.loadMore
495
587
  }
496
588
  ) })
497
589
  ] })
498
590
  ] });
499
591
  }
500
- function C({
592
+ function E({
501
593
  usages: n,
502
- isLoading: l,
503
- error: g,
504
- onLoadMore: c,
505
- hasMore: u,
594
+ isLoading: i,
595
+ error: s,
596
+ onLoadMore: b,
597
+ hasMore: f,
506
598
  labels: o,
507
599
  formatters: x,
508
- className: f,
509
- emptyStateComponent: b
600
+ className: h,
601
+ emptyStateComponent: c
510
602
  }) {
511
- const a = (s) => s.reference || s.filename || "-", h = (s) => s.credits ?? 1, m = o.columnCredits !== void 0;
512
- return /* @__PURE__ */ d("div", { className: f, children: [
603
+ const a = (g) => g.reference || g.filename || "-", m = (g) => g.credits ?? 1, u = o.columnCredits !== void 0;
604
+ return /* @__PURE__ */ d("div", { className: h, children: [
513
605
  /* @__PURE__ */ e("h1", { className: "text-2xl font-bold mb-6 text-foreground", children: o.title }),
514
- g && /* @__PURE__ */ e(
606
+ s && /* @__PURE__ */ e(
515
607
  "div",
516
608
  {
517
609
  className: `mb-4 p-3 rounded-lg border ${t.component.alert.error.base} ${t.component.alert.error.dark}`,
518
610
  role: "alert",
519
- children: /* @__PURE__ */ e("p", { className: `text-sm ${t.component.alert.error.icon}`, children: g })
611
+ children: /* @__PURE__ */ e("p", { className: `text-sm ${t.component.alert.error.icon}`, children: s })
520
612
  }
521
613
  ),
522
- l && /* @__PURE__ */ e(y, {}),
523
- !l && n.length === 0 && /* @__PURE__ */ e(p, { children: b ?? /* @__PURE__ */ e("p", { className: `${i.text.muted} text-center py-8`, children: o.noRecords }) }),
524
- !l && n.length > 0 && /* @__PURE__ */ d(p, { children: [
614
+ i && /* @__PURE__ */ e($, {}),
615
+ !i && n.length === 0 && /* @__PURE__ */ e(v, { children: c ?? /* @__PURE__ */ e("p", { className: `${l.text.muted} text-center py-8`, children: o.noRecords }) }),
616
+ !i && n.length > 0 && /* @__PURE__ */ d(v, { children: [
525
617
  /* @__PURE__ */ e("div", { className: "hidden sm:block overflow-x-auto", children: /* @__PURE__ */ d("table", { className: "w-full text-sm", "aria-label": o.title, children: [
526
- /* @__PURE__ */ e("thead", { children: /* @__PURE__ */ d("tr", { className: `border-b ${i.border.default}`, children: [
618
+ /* @__PURE__ */ e("thead", { children: /* @__PURE__ */ d("tr", { className: `border-b ${l.border.default}`, children: [
527
619
  /* @__PURE__ */ e(
528
620
  "th",
529
621
  {
530
- className: `text-left py-3 px-4 font-medium ${i.text.muted}`,
622
+ className: `text-left py-3 px-4 font-medium ${l.text.muted}`,
531
623
  children: o.columnDate
532
624
  }
533
625
  ),
534
626
  /* @__PURE__ */ e(
535
627
  "th",
536
628
  {
537
- className: `text-left py-3 px-4 font-medium ${i.text.muted}`,
629
+ className: `text-left py-3 px-4 font-medium ${l.text.muted}`,
538
630
  children: o.columnFilename
539
631
  }
540
632
  ),
541
- m && /* @__PURE__ */ e(
633
+ u && /* @__PURE__ */ e(
542
634
  "th",
543
635
  {
544
- className: `text-right py-3 px-4 font-medium ${i.text.muted}`,
636
+ className: `text-right py-3 px-4 font-medium ${l.text.muted}`,
545
637
  children: o.columnCredits
546
638
  }
547
639
  )
548
640
  ] }) }),
549
- /* @__PURE__ */ e("tbody", { children: n.map((s) => /* @__PURE__ */ d(
641
+ /* @__PURE__ */ e("tbody", { children: n.map((g) => /* @__PURE__ */ d(
550
642
  "tr",
551
643
  {
552
- className: `border-b ${i.border.subtle} hover:bg-accent`,
644
+ className: `border-b ${l.border.subtle} hover:bg-accent`,
553
645
  children: [
554
- /* @__PURE__ */ e("td", { className: "py-3 px-4 text-foreground", children: x.formatDate(s.created_at) }),
555
- /* @__PURE__ */ e("td", { className: "py-3 px-4 text-muted-foreground", children: a(s) }),
556
- m && /* @__PURE__ */ e("td", { className: "py-3 px-4 text-right text-foreground tabular-nums", children: h(s) })
646
+ /* @__PURE__ */ e("td", { className: "py-3 px-4 text-foreground", children: x.formatDate(g.created_at) }),
647
+ /* @__PURE__ */ e("td", { className: "py-3 px-4 text-muted-foreground", children: a(g) }),
648
+ u && /* @__PURE__ */ e("td", { className: "py-3 px-4 text-right text-foreground tabular-nums", children: m(g) })
557
649
  ]
558
650
  },
559
- s.id
651
+ g.id
560
652
  )) })
561
653
  ] }) }),
562
- /* @__PURE__ */ e("div", { className: "sm:hidden space-y-3", children: n.map((s) => /* @__PURE__ */ d(
654
+ /* @__PURE__ */ e("div", { className: "sm:hidden space-y-3", children: n.map((g) => /* @__PURE__ */ d(
563
655
  "div",
564
656
  {
565
657
  className: `p-4 rounded-lg border ${t.component.card.default.base} ${t.component.card.default.dark}`,
566
658
  children: [
567
- /* @__PURE__ */ e("p", { className: "text-sm text-muted-foreground", children: x.formatDate(s.created_at) }),
568
- /* @__PURE__ */ e("p", { className: "text-sm text-foreground font-medium", children: a(s) }),
569
- m && /* @__PURE__ */ d("p", { className: "text-sm text-muted-foreground", children: [
659
+ /* @__PURE__ */ e("p", { className: "text-sm text-muted-foreground", children: x.formatDate(g.created_at) }),
660
+ /* @__PURE__ */ e("p", { className: "text-sm text-foreground font-medium", children: a(g) }),
661
+ u && /* @__PURE__ */ d("p", { className: "text-sm text-muted-foreground", children: [
570
662
  o.columnCredits,
571
663
  ": ",
572
- h(s)
664
+ m(g)
573
665
  ] })
574
666
  ]
575
667
  },
576
- s.id
668
+ g.id
577
669
  )) }),
578
- u && c && /* @__PURE__ */ e("div", { className: "mt-4 text-center", children: /* @__PURE__ */ e(
670
+ f && b && /* @__PURE__ */ e("div", { className: "mt-4 text-center", children: /* @__PURE__ */ e(
579
671
  "button",
580
672
  {
581
- onClick: c,
582
- className: `px-4 py-2 text-sm font-medium ${i.text.link}`,
673
+ onClick: b,
674
+ className: `px-4 py-2 text-sm font-medium ${l.text.link}`,
583
675
  children: o.loadMore
584
676
  }
585
677
  ) })
586
678
  ] })
587
679
  ] });
588
680
  }
589
- function S({
681
+ function M({
590
682
  balance: n,
591
- isLoading: l,
592
- onClick: g,
593
- className: c
683
+ isLoading: i,
684
+ onClick: s,
685
+ className: b
594
686
  }) {
595
- return l ? /* @__PURE__ */ e(
687
+ return i ? /* @__PURE__ */ e(
596
688
  "span",
597
689
  {
598
- className: `inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium ${i.text.muted} ${c || ""}`,
690
+ className: `inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium ${l.text.muted} ${b || ""}`,
599
691
  role: "status",
600
692
  "aria-label": "Loading balance",
601
693
  "aria-busy": "true",
602
694
  children: /* @__PURE__ */ e("span", { className: "animate-pulse", children: "..." })
603
695
  }
604
696
  ) : n === null ? null : /* @__PURE__ */ d(
605
- g ? "button" : "span",
697
+ s ? "button" : "span",
606
698
  {
607
- onClick: g,
608
- "aria-label": g ? `Credit balance: ${n}` : void 0,
609
- className: `inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium ${n > 0 ? `${t.component.badge.primary.base} ${t.component.badge.primary.dark}` : `${t.component.badge.error.base} ${t.component.badge.error.dark}`} ${g ? "cursor-pointer hover:opacity-80" : ""} ${c || ""}`,
699
+ onClick: s,
700
+ "aria-label": s ? `Credit balance: ${n}` : void 0,
701
+ className: `inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium ${n > 0 ? `${t.component.badge.primary.base} ${t.component.badge.primary.dark}` : `${t.component.badge.error.base} ${t.component.badge.error.dark}`} ${s ? "cursor-pointer hover:opacity-80" : ""} ${b || ""}`,
610
702
  children: [
611
703
  /* @__PURE__ */ e(
612
704
  "svg",
@@ -631,8 +723,9 @@ function S({
631
723
  );
632
724
  }
633
725
  export {
634
- S as CreditBalanceBadge,
635
- N as CreditStorePage,
636
- w as PurchaseHistoryPage,
637
- C as UsageHistoryPage
726
+ M as CreditBalanceBadge,
727
+ P as CreditPaywallDialog,
728
+ B as CreditStorePage,
729
+ j as PurchaseHistoryPage,
730
+ E as UsageHistoryPage
638
731
  };
package/dist/types.d.ts CHANGED
@@ -32,6 +32,22 @@ export interface CreditStorePageProps {
32
32
  formatters: CreditStorePageFormatters;
33
33
  className?: string;
34
34
  }
35
+ /** Localizable label strings for the CreditPaywallDialog component. */
36
+ export interface CreditPaywallDialogLabels extends CreditStorePageLabels {
37
+ /** The dialog's heading: why it appeared, not what it contains. */
38
+ paywallTitle: string;
39
+ /** A sentence under the heading, explaining what was refused. */
40
+ paywallMessage?: string;
41
+ /** Accessible name for the close control. */
42
+ closeLabel: string;
43
+ }
44
+ /** Props for the CreditPaywallDialog component. */
45
+ export interface CreditPaywallDialogProps extends Omit<CreditStorePageProps, 'labels' | 'className'> {
46
+ isOpen: boolean;
47
+ onClose: () => void;
48
+ labels: CreditPaywallDialogLabels;
49
+ className?: string;
50
+ }
35
51
  /** Localizable label strings for the PurchaseHistoryPage component. */
36
52
  export interface PurchaseHistoryPageLabels {
37
53
  title: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sudobility/consumables_pages",
3
- "version": "0.0.44",
3
+ "version": "0.0.45",
4
4
  "description": "Web UI components for consumable credits (credit store, purchase history, usage history)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",