@monetizekit/react 0.1.0 → 0.2.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/dist/index.cjs CHANGED
@@ -47,7 +47,13 @@ var THEME_PRESETS = {
47
47
  colorPrimaryForeground: "#ffffff",
48
48
  colorAccent: "#10b981",
49
49
  colorBorder: "#e4e4e7",
50
+ colorCard: "#ffffff",
51
+ colorCardForeground: "#0a0a0a",
52
+ colorSuccess: "#16a34a",
53
+ colorWarning: "#d97706",
54
+ colorDanger: "#dc2626",
50
55
  radius: "0.5rem",
56
+ shadow: "0 1px 3px rgba(0,0,0,0.1)",
51
57
  fontFamily: "system-ui, -apple-system, sans-serif"
52
58
  },
53
59
  dark: {
@@ -58,7 +64,13 @@ var THEME_PRESETS = {
58
64
  colorPrimaryForeground: "#0a0a0a",
59
65
  colorAccent: "#10b981",
60
66
  colorBorder: "#27272a",
67
+ colorCard: "#18181b",
68
+ colorCardForeground: "#fafafa",
69
+ colorSuccess: "#22c55e",
70
+ colorWarning: "#f59e0b",
71
+ colorDanger: "#ef4444",
61
72
  radius: "0.5rem",
73
+ shadow: "0 1px 3px rgba(0,0,0,0.4)",
62
74
  fontFamily: "system-ui, -apple-system, sans-serif"
63
75
  },
64
76
  memphis: {
@@ -69,7 +81,13 @@ var THEME_PRESETS = {
69
81
  colorPrimaryForeground: "#1a1a1a",
70
82
  colorAccent: "#00D9FF",
71
83
  colorBorder: "#1a1a1a",
84
+ colorCard: "#ffffff",
85
+ colorCardForeground: "#1a1a1a",
86
+ colorSuccess: "#00C853",
87
+ colorWarning: "#FFB400",
88
+ colorDanger: "#FF3B30",
72
89
  radius: "0",
90
+ shadow: "4px 4px 0 #1a1a1a",
73
91
  fontFamily: "system-ui, -apple-system, sans-serif"
74
92
  },
75
93
  dashboard: {
@@ -80,10 +98,119 @@ var THEME_PRESETS = {
80
98
  colorPrimaryForeground: "oklch(0.985 0 0)",
81
99
  colorAccent: "oklch(0.97 0 0)",
82
100
  colorBorder: "oklch(0.922 0 0)",
101
+ colorCard: "oklch(1 0 0)",
102
+ colorCardForeground: "oklch(0.145 0 0)",
103
+ colorSuccess: "#16a34a",
104
+ colorWarning: "#d97706",
105
+ colorDanger: "#dc2626",
83
106
  radius: "0.625rem",
107
+ shadow: "0 1px 2px rgba(0,0,0,0.06)",
84
108
  fontFamily: "Geist, system-ui, sans-serif"
109
+ },
110
+ console: {
111
+ colorBackground: "#0b0f14",
112
+ colorForeground: "#e6edf3",
113
+ colorMuted: "#8b949e",
114
+ colorPrimary: "#6366f1",
115
+ colorPrimaryForeground: "#ffffff",
116
+ colorAccent: "#00D9FF",
117
+ colorBorder: "#1f2630",
118
+ colorCard: "#11161d",
119
+ colorCardForeground: "#e6edf3",
120
+ colorSuccess: "#34d399",
121
+ colorWarning: "#fbbf24",
122
+ colorDanger: "#f87171",
123
+ radius: "0.625rem",
124
+ shadow: "0 8px 24px rgba(0,0,0,0.5)",
125
+ fontFamily: "Geist, system-ui, sans-serif"
126
+ },
127
+ midnight: {
128
+ colorBackground: "#0f172a",
129
+ colorForeground: "#e2e8f0",
130
+ colorMuted: "#94a3b8",
131
+ colorPrimary: "#818cf8",
132
+ colorPrimaryForeground: "#0f172a",
133
+ colorAccent: "#38bdf8",
134
+ colorBorder: "#1e293b",
135
+ colorCard: "#1e293b",
136
+ colorCardForeground: "#e2e8f0",
137
+ colorSuccess: "#4ade80",
138
+ colorWarning: "#facc15",
139
+ colorDanger: "#fb7185",
140
+ radius: "0.75rem",
141
+ shadow: "0 10px 30px rgba(2,6,23,0.6)",
142
+ fontFamily: "system-ui, -apple-system, sans-serif"
143
+ },
144
+ ocean: {
145
+ colorBackground: "#f0fdfa",
146
+ colorForeground: "#0f3d3e",
147
+ colorMuted: "#5b7c7d",
148
+ colorPrimary: "#0d9488",
149
+ colorPrimaryForeground: "#ffffff",
150
+ colorAccent: "#06b6d4",
151
+ colorBorder: "#99f6e4",
152
+ colorCard: "#ffffff",
153
+ colorCardForeground: "#0f3d3e",
154
+ colorSuccess: "#059669",
155
+ colorWarning: "#d97706",
156
+ colorDanger: "#e11d48",
157
+ radius: "0.75rem",
158
+ shadow: "0 4px 14px rgba(13,148,136,0.15)",
159
+ fontFamily: "system-ui, -apple-system, sans-serif"
160
+ },
161
+ forest: {
162
+ colorBackground: "#f7fee7",
163
+ colorForeground: "#1a2e05",
164
+ colorMuted: "#5c6b47",
165
+ colorPrimary: "#4d7c0f",
166
+ colorPrimaryForeground: "#ffffff",
167
+ colorAccent: "#65a30d",
168
+ colorBorder: "#d9f99d",
169
+ colorCard: "#ffffff",
170
+ colorCardForeground: "#1a2e05",
171
+ colorSuccess: "#16a34a",
172
+ colorWarning: "#ca8a04",
173
+ colorDanger: "#dc2626",
174
+ radius: "0.5rem",
175
+ shadow: "0 4px 14px rgba(77,124,15,0.12)",
176
+ fontFamily: "system-ui, -apple-system, sans-serif"
177
+ },
178
+ sunset: {
179
+ colorBackground: "#fff7ed",
180
+ colorForeground: "#431407",
181
+ colorMuted: "#9a6b4f",
182
+ colorPrimary: "#ea580c",
183
+ colorPrimaryForeground: "#ffffff",
184
+ colorAccent: "#f43f5e",
185
+ colorBorder: "#fed7aa",
186
+ colorCard: "#ffffff",
187
+ colorCardForeground: "#431407",
188
+ colorSuccess: "#16a34a",
189
+ colorWarning: "#d97706",
190
+ colorDanger: "#e11d48",
191
+ radius: "1rem",
192
+ shadow: "0 6px 20px rgba(234,88,12,0.15)",
193
+ fontFamily: "system-ui, -apple-system, sans-serif"
194
+ },
195
+ grape: {
196
+ colorBackground: "#faf5ff",
197
+ colorForeground: "#2e1065",
198
+ colorMuted: "#7c6f93",
199
+ colorPrimary: "#7c3aed",
200
+ colorPrimaryForeground: "#ffffff",
201
+ colorAccent: "#d946ef",
202
+ colorBorder: "#e9d5ff",
203
+ colorCard: "#ffffff",
204
+ colorCardForeground: "#2e1065",
205
+ colorSuccess: "#16a34a",
206
+ colorWarning: "#d97706",
207
+ colorDanger: "#dc2626",
208
+ radius: "0.875rem",
209
+ shadow: "0 6px 20px rgba(124,58,237,0.15)",
210
+ fontFamily: "system-ui, -apple-system, sans-serif"
85
211
  }
86
212
  };
213
+ var THEME_PRESET_NAMES = Object.keys(THEME_PRESETS);
87
214
  function resolveTokens(appearance = "light") {
88
215
  if (typeof appearance === "string") {
89
216
  return THEME_PRESETS[appearance];
@@ -99,7 +226,13 @@ var TOKEN_TO_CSS_VAR = {
99
226
  colorPrimaryForeground: "--mk-primary-fg",
100
227
  colorAccent: "--mk-accent",
101
228
  colorBorder: "--mk-border",
229
+ colorCard: "--mk-card",
230
+ colorCardForeground: "--mk-card-fg",
231
+ colorSuccess: "--mk-success",
232
+ colorWarning: "--mk-warning",
233
+ colorDanger: "--mk-danger",
102
234
  radius: "--mk-radius",
235
+ shadow: "--mk-shadow",
103
236
  fontFamily: "--mk-font"
104
237
  };
105
238
  function tokensToStyle(tokens) {
@@ -258,6 +391,99 @@ function describeUsageTerm(term, locale) {
258
391
  }
259
392
  return parts.join(", ");
260
393
  }
394
+
395
+ // src/lib/sample-data.ts
396
+ var SAMPLE_PLANS = [
397
+ {
398
+ id: "sample_free",
399
+ name: "Starter",
400
+ description: "Evaluate the platform and model your catalog",
401
+ pricing: [{ type: "flat", amount: 0, currency: "USD", interval: "monthly" }],
402
+ entitlements: [
403
+ { featureKey: "max_customers", featureDisplayName: "Tracked customers", type: "limit", value: 100 },
404
+ { featureKey: "api_access", featureDisplayName: "REST & GraphQL API", type: "boolean", value: true },
405
+ { featureKey: "metering", featureDisplayName: "Usage metering", type: "boolean", value: true }
406
+ ]
407
+ },
408
+ {
409
+ id: "sample_pro",
410
+ name: "Growth",
411
+ description: "Product-led monetization at scale",
412
+ pricing: [{ type: "flat", amount: 49900, currency: "USD", interval: "monthly" }],
413
+ entitlements: [
414
+ { featureKey: "max_customers", featureDisplayName: "Tracked customers", type: "limit", value: 1e4 },
415
+ { featureKey: "stripe", featureDisplayName: "Stripe integration", type: "boolean", value: true },
416
+ { featureKey: "experiments", featureDisplayName: "Experiments & A/B testing", type: "boolean", value: true },
417
+ { featureKey: "widgets", featureDisplayName: "Embeddable widgets", type: "boolean", value: true }
418
+ ]
419
+ },
420
+ {
421
+ id: "sample_scale",
422
+ name: "Scale",
423
+ description: "Volume-based capacity pricing",
424
+ pricing: [
425
+ { type: "flat", amount: 99900, currency: "USD", interval: "monthly" },
426
+ {
427
+ type: "usage",
428
+ amount: 0,
429
+ currency: "USD",
430
+ interval: "monthly",
431
+ meterId: "sample_mtc",
432
+ meterDisplayName: "Tracked customers",
433
+ includedUnits: 25e3,
434
+ tierMode: "graduated",
435
+ tieredPricing: [
436
+ { upTo: 1e5, unitPrice: 0.012 },
437
+ { upTo: null, unitPrice: 6e-3 }
438
+ ]
439
+ }
440
+ ],
441
+ entitlements: [
442
+ { featureKey: "everything_pro", featureDisplayName: "Everything in Growth", type: "boolean", value: true },
443
+ { featureKey: "approvals", featureDisplayName: "Approval workflows", type: "boolean", value: true }
444
+ ]
445
+ },
446
+ {
447
+ id: "sample_enterprise",
448
+ name: "Enterprise",
449
+ description: "Governance, scale, and advanced controls",
450
+ tags: ["contact_sales"],
451
+ pricing: [],
452
+ entitlements: [
453
+ { featureKey: "sso", featureDisplayName: "SSO / SAML", type: "boolean", value: true },
454
+ { featureKey: "sla", featureDisplayName: "Custom SLA", type: "boolean", value: true }
455
+ ]
456
+ }
457
+ ];
458
+ var SAMPLE_USAGE = {
459
+ api_calls: { meterId: "api_calls", current: 72e3, limit: 1e5 },
460
+ seats: { meterId: "seats", current: 8, limit: 10 },
461
+ storage_gb: { meterId: "storage_gb", current: 3, limit: 10 }
462
+ };
463
+ var SAMPLE_CREDITS = { balance: 12e4, currency: "USD" };
464
+ var SAMPLE_PORTAL = {
465
+ planName: "Growth",
466
+ meterIds: ["api_calls", "seats"]
467
+ };
468
+ var SAMPLE_NOTICE_TEXT = "Sample data for illustration only \u2014 define plans and products to show live values.";
469
+ var noticeStyle = {
470
+ display: "flex",
471
+ alignItems: "center",
472
+ gap: "0.5rem",
473
+ border: "1px dashed var(--mk-warning)",
474
+ borderRadius: "var(--mk-radius)",
475
+ background: "color-mix(in srgb, var(--mk-warning) 12%, transparent)",
476
+ color: "var(--mk-card-fg)",
477
+ fontFamily: "var(--mk-font)",
478
+ fontSize: "0.75rem",
479
+ padding: "0.5rem 0.75rem"
480
+ };
481
+ function SampleNotice({ children }) {
482
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "note", "data-mk-component": "sample-notice", style: noticeStyle, children: [
483
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", style: { color: "var(--mk-warning)", fontWeight: 700 }, children: "\u25CF" }),
484
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: children ?? SAMPLE_NOTICE_TEXT })
485
+ ] });
486
+ }
261
487
  var wrapperStyle = {
262
488
  display: "grid",
263
489
  gridTemplateColumns: "repeat(auto-fit, minmax(240px, 1fr))",
@@ -279,7 +505,9 @@ function PricingTable({
279
505
  highlightPlan,
280
506
  locale,
281
507
  onSelectPlan,
282
- onContactSales
508
+ onContactSales,
509
+ sampleWhenEmpty = true,
510
+ disclaimer
283
511
  }) {
284
512
  const { client, tokens } = useMonetizeKit();
285
513
  const [plans, setPlans] = react.useState(plansProp ?? null);
@@ -305,68 +533,84 @@ function PricingTable({
305
533
  if (!plans) {
306
534
  return /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-busy": "true", style: { color: "var(--mk-muted)" }, children: "Loading pricing\u2026" });
307
535
  }
308
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { ...tokensToStyle(tokens), ...wrapperStyle }, "data-mk-component": "pricing-table", children: plans.map((plan) => {
309
- const price = describePlanPrice(plan, locale);
310
- const highlighted = highlightPlan != null && plan.name.toLowerCase() === highlightPlan.toLowerCase();
311
- return /* @__PURE__ */ jsxRuntime.jsxs(
312
- "div",
313
- {
314
- style: {
315
- ...cardBase,
316
- borderColor: highlighted ? "var(--mk-primary)" : "var(--mk-border)",
317
- borderWidth: highlighted ? 2 : 1
318
- },
319
- "data-mk-plan": plan.name,
320
- "data-mk-highlighted": highlighted ? "true" : void 0,
321
- children: [
322
- highlighted ? /* @__PURE__ */ jsxRuntime.jsx(
323
- "span",
536
+ const isSample = plans.length === 0 && sampleWhenEmpty;
537
+ const effectivePlans = isSample ? SAMPLE_PLANS : plans;
538
+ if (effectivePlans.length === 0) {
539
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "var(--mk-muted)" }, children: "No plans available." });
540
+ }
541
+ return /* @__PURE__ */ jsxRuntime.jsxs(
542
+ "div",
543
+ {
544
+ style: { ...tokensToStyle(tokens), display: "flex", flexDirection: "column", gap: "1rem" },
545
+ "data-mk-component": "pricing-table",
546
+ "data-mk-sample": isSample ? "true" : void 0,
547
+ children: [
548
+ isSample ? /* @__PURE__ */ jsxRuntime.jsx(SampleNotice, { children: disclaimer }) : null,
549
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: wrapperStyle, children: effectivePlans.map((plan) => {
550
+ const price = describePlanPrice(plan, locale);
551
+ const highlighted = highlightPlan != null && plan.name.toLowerCase() === highlightPlan.toLowerCase();
552
+ return /* @__PURE__ */ jsxRuntime.jsxs(
553
+ "div",
324
554
  {
325
555
  style: {
326
- alignSelf: "flex-start",
327
- background: "var(--mk-primary)",
328
- color: "var(--mk-primary-fg)",
329
- borderRadius: "var(--mk-radius)",
330
- padding: "0.125rem 0.5rem",
331
- fontSize: "0.75rem",
332
- fontWeight: 600
556
+ ...cardBase,
557
+ borderColor: highlighted ? "var(--mk-primary)" : "var(--mk-border)",
558
+ borderWidth: highlighted ? 2 : 1
333
559
  },
334
- children: "Most Popular"
335
- }
336
- ) : null,
337
- /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { margin: 0, fontSize: "1.25rem", fontWeight: 700 }, children: plan.name }),
338
- plan.description ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, color: "var(--mk-muted)", fontSize: "0.875rem" }, children: plan.description }) : null,
339
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: "0.375rem" }, children: [
340
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "2rem", fontWeight: 700 }, children: price.contactSales ? "Custom" : price.headline }),
341
- price.caption ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--mk-muted)", fontSize: "0.875rem" }, children: price.caption }) : null
342
- ] }),
343
- plan.entitlements && plan.entitlements.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("ul", { style: { margin: 0, paddingLeft: "1rem", color: "var(--mk-fg)", fontSize: "0.875rem" }, children: plan.entitlements.slice(0, 6).map((e) => /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
344
- e.featureDisplayName,
345
- e.type !== "boolean" ? `: ${String(e.value)}` : ""
346
- ] }, e.featureKey)) }) : null,
347
- /* @__PURE__ */ jsxRuntime.jsx(
348
- "button",
349
- {
350
- type: "button",
351
- onClick: () => price.contactSales ? onContactSales?.(plan.id) : onSelectPlan?.(plan.id),
352
- style: {
353
- marginTop: "auto",
354
- background: "var(--mk-primary)",
355
- color: "var(--mk-primary-fg)",
356
- border: "none",
357
- borderRadius: "var(--mk-radius)",
358
- padding: "0.625rem 1rem",
359
- fontWeight: 600,
360
- cursor: "pointer"
361
- },
362
- children: price.contactSales ? "Contact Sales" : "Get started"
363
- }
364
- )
365
- ]
366
- },
367
- plan.id
368
- );
369
- }) });
560
+ "data-mk-plan": plan.name,
561
+ "data-mk-highlighted": highlighted ? "true" : void 0,
562
+ children: [
563
+ highlighted ? /* @__PURE__ */ jsxRuntime.jsx(
564
+ "span",
565
+ {
566
+ style: {
567
+ alignSelf: "flex-start",
568
+ background: "var(--mk-primary)",
569
+ color: "var(--mk-primary-fg)",
570
+ borderRadius: "var(--mk-radius)",
571
+ padding: "0.125rem 0.5rem",
572
+ fontSize: "0.75rem",
573
+ fontWeight: 600
574
+ },
575
+ children: "Most Popular"
576
+ }
577
+ ) : null,
578
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { margin: 0, fontSize: "1.25rem", fontWeight: 700 }, children: plan.name }),
579
+ plan.description ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, color: "var(--mk-muted)", fontSize: "0.875rem" }, children: plan.description }) : null,
580
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: "0.375rem" }, children: [
581
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "2rem", fontWeight: 700 }, children: price.contactSales ? "Custom" : price.headline }),
582
+ price.caption ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--mk-muted)", fontSize: "0.875rem" }, children: price.caption }) : null
583
+ ] }),
584
+ plan.entitlements && plan.entitlements.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("ul", { style: { margin: 0, paddingLeft: "1rem", color: "var(--mk-fg)", fontSize: "0.875rem" }, children: plan.entitlements.slice(0, 6).map((e) => /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
585
+ e.featureDisplayName,
586
+ e.type !== "boolean" ? `: ${String(e.value)}` : ""
587
+ ] }, e.featureKey)) }) : null,
588
+ /* @__PURE__ */ jsxRuntime.jsx(
589
+ "button",
590
+ {
591
+ type: "button",
592
+ onClick: () => price.contactSales ? onContactSales?.(plan.id) : onSelectPlan?.(plan.id),
593
+ style: {
594
+ marginTop: "auto",
595
+ background: "var(--mk-primary)",
596
+ color: "var(--mk-primary-fg)",
597
+ border: "none",
598
+ borderRadius: "var(--mk-radius)",
599
+ padding: "0.625rem 1rem",
600
+ fontWeight: 600,
601
+ cursor: "pointer"
602
+ },
603
+ children: price.contactSales ? "Contact Sales" : "Get started"
604
+ }
605
+ )
606
+ ]
607
+ },
608
+ plan.id
609
+ );
610
+ }) })
611
+ ]
612
+ }
613
+ );
370
614
  }
371
615
  var overlayStyle = {
372
616
  border: "1px solid var(--mk-border)",
@@ -445,7 +689,7 @@ function UsageBanner({
445
689
  const fraction = hasLimit ? Math.min(1, current / limit) : 0;
446
690
  const over = hasLimit && current > limit;
447
691
  const warn = hasLimit && fraction >= warnAt;
448
- const barColor = over || warn ? "var(--mk-primary)" : "var(--mk-accent)";
692
+ const barColor = over ? "var(--mk-danger)" : warn ? "var(--mk-warning)" : "var(--mk-accent)";
449
693
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { ...tokensToStyle(tokens), ...bannerStyle }, "data-mk-component": "usage-banner", children: [
450
694
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", fontSize: "0.875rem" }, children: [
451
695
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 600 }, children: label }),
@@ -470,73 +714,138 @@ function UsageBanner({
470
714
  children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: `${fraction * 100}%`, height: "100%", background: barColor } })
471
715
  }
472
716
  ) : null,
473
- over ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--mk-primary)", fontSize: "0.75rem" }, children: "Over included allotment \u2014 overage billed per usage pricing." }) : null
717
+ over ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--mk-danger)", fontSize: "0.75rem" }, children: "Over included allotment \u2014 overage billed per usage pricing." }) : null
474
718
  ] });
475
719
  }
476
720
  var containerStyle = {
477
721
  border: "1px solid var(--mk-border)",
478
722
  borderRadius: "var(--mk-radius)",
479
723
  padding: "1.25rem",
480
- background: "var(--mk-bg)",
481
- color: "var(--mk-fg)",
724
+ background: "var(--mk-card)",
725
+ color: "var(--mk-card-fg)",
726
+ boxShadow: "var(--mk-shadow)",
482
727
  fontFamily: "var(--mk-font)",
483
728
  display: "flex",
484
729
  flexDirection: "column",
485
730
  gap: "1rem",
486
731
  maxWidth: 480
487
732
  };
733
+ var cardStyle = {
734
+ border: "1px solid var(--mk-border)",
735
+ borderRadius: "var(--mk-radius)",
736
+ padding: "0.875rem 1rem",
737
+ display: "flex",
738
+ flexDirection: "column",
739
+ gap: "0.5rem"
740
+ };
741
+ function SampleUsageRow({
742
+ label,
743
+ current,
744
+ limit,
745
+ locale
746
+ }) {
747
+ const hasLimit = typeof limit === "number" && limit > 0;
748
+ const fraction = hasLimit ? Math.min(1, current / limit) : 0;
749
+ const barColor = fraction >= 0.8 ? "var(--mk-warning)" : "var(--mk-accent)";
750
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: cardStyle, children: [
751
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", fontSize: "0.875rem" }, children: [
752
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 600 }, children: label }),
753
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: "var(--mk-muted)" }, children: [
754
+ formatUnits(current, locale),
755
+ hasLimit ? ` / ${formatUnits(limit, locale)}` : ""
756
+ ] })
757
+ ] }),
758
+ hasLimit ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: 6, borderRadius: 999, background: "var(--mk-border)", overflow: "hidden" }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: `${fraction * 100}%`, height: "100%", background: barColor } }) }) : null
759
+ ] });
760
+ }
488
761
  function CustomerPortal({
489
- planName = "Current plan",
490
- meterIds = [],
762
+ planName,
763
+ meterIds,
491
764
  showCredits = true,
765
+ sample = false,
766
+ disclaimer,
767
+ showBranding = false,
492
768
  locale,
493
769
  currency = "USD",
494
770
  onManageBilling
495
771
  }) {
496
772
  const { tokens } = useMonetizeKit();
497
773
  const credits = useCredits();
498
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { ...tokensToStyle(tokens), ...containerStyle }, "data-mk-component": "customer-portal", children: [
499
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
500
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
501
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "0.75rem", color: "var(--mk-muted)" }, children: "Plan" }),
502
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "1.125rem", fontWeight: 700 }, children: planName })
503
- ] }),
504
- /* @__PURE__ */ jsxRuntime.jsx(
505
- "button",
506
- {
507
- type: "button",
508
- onClick: onManageBilling,
509
- style: {
510
- background: "var(--mk-primary)",
511
- color: "var(--mk-primary-fg)",
512
- border: "none",
513
- borderRadius: "var(--mk-radius)",
514
- padding: "0.5rem 0.875rem",
515
- fontWeight: 600,
516
- cursor: "pointer"
517
- },
518
- children: "Manage billing"
519
- }
520
- )
521
- ] }),
522
- meterIds.map((meterId) => /* @__PURE__ */ jsxRuntime.jsx(UsageBanner, { meterId, label: meterId, locale }, meterId)),
523
- showCredits ? /* @__PURE__ */ jsxRuntime.jsxs(
524
- "div",
525
- {
526
- style: {
527
- border: "1px solid var(--mk-border)",
528
- borderRadius: "var(--mk-radius)",
529
- padding: "0.875rem 1rem",
530
- display: "flex",
531
- justifyContent: "space-between"
532
- },
533
- children: [
774
+ const resolvedPlanName = planName ?? (sample ? SAMPLE_PORTAL.planName : "Current plan");
775
+ const resolvedMeterIds = meterIds ?? (sample ? [...SAMPLE_PORTAL.meterIds] : []);
776
+ const creditBalance = sample ? SAMPLE_CREDITS.balance : credits.balance;
777
+ const creditCurrency = sample ? SAMPLE_CREDITS.currency : credits.currency;
778
+ const creditLoading = sample ? false : credits.loading;
779
+ return /* @__PURE__ */ jsxRuntime.jsxs(
780
+ "div",
781
+ {
782
+ style: { ...tokensToStyle(tokens), ...containerStyle },
783
+ "data-mk-component": "customer-portal",
784
+ "data-mk-sample": sample ? "true" : void 0,
785
+ children: [
786
+ sample ? /* @__PURE__ */ jsxRuntime.jsx(SampleNotice, { children: disclaimer }) : null,
787
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", gap: "1rem" }, children: [
788
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
789
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "0.75rem", color: "var(--mk-muted)" }, children: "Plan" }),
790
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", marginTop: "0.125rem" }, children: [
791
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "1.125rem", fontWeight: 700 }, children: resolvedPlanName }),
792
+ /* @__PURE__ */ jsxRuntime.jsx(
793
+ "span",
794
+ {
795
+ style: {
796
+ fontSize: "0.6875rem",
797
+ fontWeight: 600,
798
+ color: "var(--mk-success)",
799
+ border: "1px solid var(--mk-success)",
800
+ borderRadius: 999,
801
+ padding: "0.0625rem 0.5rem"
802
+ },
803
+ children: "Active"
804
+ }
805
+ )
806
+ ] })
807
+ ] }),
808
+ /* @__PURE__ */ jsxRuntime.jsx(
809
+ "button",
810
+ {
811
+ type: "button",
812
+ onClick: onManageBilling,
813
+ style: {
814
+ background: "var(--mk-primary)",
815
+ color: "var(--mk-primary-fg)",
816
+ border: "none",
817
+ borderRadius: "var(--mk-radius)",
818
+ padding: "0.5rem 0.875rem",
819
+ fontWeight: 600,
820
+ cursor: "pointer",
821
+ whiteSpace: "nowrap"
822
+ },
823
+ children: "Manage billing"
824
+ }
825
+ )
826
+ ] }),
827
+ sample ? resolvedMeterIds.map((meterId) => {
828
+ const usage = SAMPLE_USAGE[meterId];
829
+ if (!usage) return null;
830
+ return /* @__PURE__ */ jsxRuntime.jsx(
831
+ SampleUsageRow,
832
+ {
833
+ label: meterId,
834
+ current: usage.current,
835
+ limit: usage.limit,
836
+ locale
837
+ },
838
+ meterId
839
+ );
840
+ }) : resolvedMeterIds.map((meterId) => /* @__PURE__ */ jsxRuntime.jsx(UsageBanner, { meterId, label: meterId, locale }, meterId)),
841
+ showCredits ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { ...cardStyle, flexDirection: "row", justifyContent: "space-between" }, children: [
534
842
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 600, fontSize: "0.875rem" }, children: "Credits" }),
535
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--mk-muted)" }, children: credits.loading ? "\u2026" : formatMoney(credits.balance, credits.currency ?? currency, locale) })
536
- ]
537
- }
538
- ) : null
539
- ] });
843
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--mk-muted)" }, children: creditLoading ? "\u2026" : formatMoney(creditBalance, creditCurrency ?? currency, locale) })
844
+ ] }) : null,
845
+ showBranding ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "center", fontSize: "0.625rem", color: "var(--mk-muted)" }, children: "Powered by MonetizeKit" }) : null
846
+ ]
847
+ }
848
+ );
540
849
  }
541
850
  function EntitlementGate({
542
851
  feature,
@@ -555,7 +864,14 @@ exports.MonetizeKitClient = MonetizeKitClient;
555
864
  exports.MonetizeKitProvider = MonetizeKitProvider;
556
865
  exports.Paywall = Paywall;
557
866
  exports.PricingTable = PricingTable;
867
+ exports.SAMPLE_CREDITS = SAMPLE_CREDITS;
868
+ exports.SAMPLE_NOTICE_TEXT = SAMPLE_NOTICE_TEXT;
869
+ exports.SAMPLE_PLANS = SAMPLE_PLANS;
870
+ exports.SAMPLE_PORTAL = SAMPLE_PORTAL;
871
+ exports.SAMPLE_USAGE = SAMPLE_USAGE;
872
+ exports.SampleNotice = SampleNotice;
558
873
  exports.THEME_PRESETS = THEME_PRESETS;
874
+ exports.THEME_PRESET_NAMES = THEME_PRESET_NAMES;
559
875
  exports.UsageBanner = UsageBanner;
560
876
  exports.describePlanPrice = describePlanPrice;
561
877
  exports.describeUsageTerm = describeUsageTerm;