@nozle-js/react 0.4.0 → 0.5.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.d.cts CHANGED
@@ -1,157 +1,636 @@
1
+ import React, { ReactNode } from 'react';
1
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ReactNode, HTMLAttributes } from 'react';
3
- import * as _stripe_stripe_js from '@stripe/stripe-js';
4
- import { Stripe } from '@stripe/stripe-js';
5
-
6
- interface EntitlementsResponse {
7
- plan_slug: string;
8
- subscription_status: string;
9
- features: Record<string, {
10
- enabled: boolean;
11
- }>;
12
- limits: Record<string, {
13
- limit: number;
14
- used: number;
15
- source?: string;
16
- }>;
17
- }
18
- interface BillingState {
19
- entitlements: EntitlementsResponse | null;
20
- credits: null;
21
- usage: Record<string, {
22
- used: number;
23
- limit: number;
24
- remaining: number;
25
- }>;
26
- connectionState: "connecting" | "connected" | "disconnected";
27
- error: Error | null;
28
- }
29
- interface UseCanResult {
3
+
4
+ interface CanResult {
30
5
  allowed: boolean;
31
- isLoading: boolean;
32
- error: Error | null;
6
+ remaining: number | null;
7
+ limit: number | null;
8
+ used: number;
9
+ error?: string | null;
33
10
  }
34
- interface UseUsageResult {
35
- data: {
36
- used: number;
37
- limit: number;
38
- remaining: number;
39
- } | null;
40
- isLoading: boolean;
41
- error: Error | null;
11
+ interface NozleClient {
12
+ apiKey: string;
13
+ baseUrl: string;
14
+ fetch(path: string, init?: RequestInit): Promise<Response>;
15
+ can(customerId: string, feature: string): Promise<CanResult>;
42
16
  }
43
- interface UsePlanResult {
44
- data: {
45
- plan_slug: string;
46
- subscription_status: string;
47
- } | null;
48
- isLoading: boolean;
49
- error: Error | null;
17
+ interface BillingContextValue {
18
+ client: NozleClient | null;
19
+ workspaceId: string;
20
+ centrifugoUrl: string;
21
+ centrifugoToken: string | null;
50
22
  }
51
- interface CheckoutResult {
52
- client_secret: string;
53
- invoice_id: string;
54
- amount_cents: number;
55
- currency: string;
23
+ declare const BillingContext: React.Context<BillingContextValue>;
24
+ interface BillingProviderProps {
25
+ apiKey: string;
26
+ baseUrl?: string;
27
+ workspaceId?: string;
28
+ centrifugoUrl?: string;
29
+ children: ReactNode;
56
30
  }
31
+ declare function BillingProvider({ apiKey, baseUrl, workspaceId, centrifugoUrl, children, }: BillingProviderProps): React.ReactElement;
32
+ declare function useBillingContext(): BillingContextValue;
33
+ declare function useNozleClient(): NozleClient;
57
34
 
58
- declare class BillingStore {
59
- readonly baseUrl: string;
60
- readonly apiKey: string;
61
- readonly customerId: string;
62
- private state;
63
- private listeners;
64
- constructor(baseUrl: string, apiKey: string, customerId: string);
65
- getSnapshot: () => BillingState;
66
- getServerSnapshot: () => BillingState;
67
- subscribe: (listener: () => void) => (() => void);
68
- private emit;
69
- setConnectionState(state: BillingState["connectionState"]): void;
70
- setError(error: Error | null): void;
71
- updateUsage(metric: string, used: number, limit: number, remaining: number): void;
72
- fetchUsage(feature: string): Promise<void>;
73
- fetchCheckoutSecret(planCode: string, successUrl?: string): Promise<CheckoutResult>;
74
- fetchPlans(): Promise<Array<{
75
- code: string;
76
- name: string;
77
- amount_cents: number;
78
- amount_currency: string;
79
- interval: string;
80
- }>>;
81
- handleEvent(event: {
82
- type: string;
83
- [key: string]: unknown;
84
- }): void;
35
+ /**
36
+ * useCan hook — check whether a customer can use a feature.
37
+ * SDK-03: Calls client.can() for initial state, then subscribes to Centrifugo
38
+ * workspace:{id}:entitlements channel for live updates.
39
+ *
40
+ * CONTEXT.md hard requirement: NO setInterval polling — Centrifugo WebSocket only.
41
+ */
42
+ interface CanState {
43
+ allowed: boolean;
44
+ remaining: number | null;
45
+ limit: number | null;
46
+ loading: boolean;
47
+ error: string | null;
85
48
  }
49
+ /**
50
+ * Check whether a customer is entitled to a feature.
51
+ * Subscribes to Centrifugo workspace:{workspaceId}:entitlements channel for live updates.
52
+ * No polling — WebSocket only per CONTEXT.md locked decision.
53
+ *
54
+ * @param customerId - Customer ID to check entitlement for
55
+ * @param featureKey - Feature key to check
56
+ * @returns CanState with allowed, remaining, limit, loading, error
57
+ */
58
+ declare function useCan(customerId: string, featureKey: string): CanState;
86
59
 
87
- interface BillingContextValue {
88
- store: BillingStore;
89
- stripePromise: Promise<Stripe | null> | null;
60
+ /**
61
+ * useUsage hook — fetch usage data for a customer metric.
62
+ * Calls GET /api/v1/usage/:customerId/:metricKey via client's fetch wrapper.
63
+ */
64
+ interface UsageState {
65
+ value: number | null;
66
+ loading: boolean;
67
+ error: string | null;
90
68
  }
91
- interface BillingProviderProps {
69
+ /**
70
+ * Fetch usage for a customer metric.
71
+ *
72
+ * @param customerId - Customer ID to fetch usage for
73
+ * @param metricKey - Metric key to fetch
74
+ * @returns UsageState with value, loading, error
75
+ */
76
+ declare function useUsage(customerId: string, metricKey: string): UsageState;
77
+
78
+ /**
79
+ * useCredits hook — fetch credit balance for a customer.
80
+ * Calls GET /api/v1/credits/:customerId/balance via client's fetch wrapper.
81
+ */
82
+ interface CreditsState {
83
+ balance: number | null;
84
+ loading: boolean;
85
+ error: string | null;
86
+ }
87
+ /**
88
+ * Fetch credit balance for a customer.
89
+ *
90
+ * @param customerId - Customer ID to fetch credit balance for
91
+ * @returns CreditsState with balance, loading, error
92
+ */
93
+ declare function useCredits(customerId: string): CreditsState;
94
+
95
+ /**
96
+ * BillingPortalProvider — Context wrapper for embeddable SDK components.
97
+ * UI-01: Wraps children and exposes a React context with { customerId, apiKey }.
98
+ * Components inside can consume this via the useBillingPortal() hook.
99
+ *
100
+ * Internally renders BillingProvider so all billing hooks work inside.
101
+ */
102
+
103
+ interface BillingPortalContextValue {
104
+ customerId: string;
92
105
  apiKey: string;
106
+ }
107
+ declare function useBillingPortal(): BillingPortalContextValue;
108
+ interface BillingPortalProviderProps {
93
109
  customerId: string;
94
- baseUrl?: string;
95
- wsUrl?: string;
96
- stripeKey?: string;
97
- features?: string[];
110
+ apiKey: string;
98
111
  children: ReactNode;
99
112
  }
100
- declare function BillingProvider({ apiKey, customerId, baseUrl, wsUrl, stripeKey, features, children, }: BillingProviderProps): react_jsx_runtime.JSX.Element;
101
- declare function useBillingContext(): BillingContextValue;
113
+ /**
114
+ * BillingPortalProvider wraps your embedded billing UI and provides
115
+ * { customerId, apiKey } context to all nested SDK components.
116
+ *
117
+ * Usage:
118
+ * ```tsx
119
+ * <BillingPortalProvider customerId="cus_xxx" apiKey="bsr_pk_xxx">
120
+ * <PricingTable plans={plans} />
121
+ * <FeatureGate feature="analytics" />
122
+ * </BillingPortalProvider>
123
+ * ```
124
+ */
125
+ declare function BillingPortalProvider({ customerId, apiKey, children, }: BillingPortalProviderProps): React.ReactElement;
102
126
 
103
- declare function useCan(feature: string): UseCanResult;
127
+ /**
128
+ * PlanCard — Individual pricing plan card component.
129
+ * UI-01: Shows plan name, price, interval, features list, and CTA button.
130
+ * Uses CSS variable theming with --nozle-* namespace.
131
+ */
104
132
 
105
- declare function useUsage(metric: string): UseUsageResult;
133
+ interface Plan {
134
+ id: string;
135
+ name: string;
136
+ monthlyPrice: number;
137
+ annualPrice: number;
138
+ features: string[];
139
+ description?: string;
140
+ }
141
+ interface PlanCardProps extends Plan {
142
+ isAnnual: boolean;
143
+ isCurrent: boolean;
144
+ onSelect?: () => void;
145
+ children?: ReactNode;
146
+ }
147
+ /**
148
+ * PlanCard renders a single pricing plan.
149
+ * Highlighted with aria-current="true" when isCurrent=true.
150
+ */
151
+ declare function PlanCard({ id, name, monthlyPrice, annualPrice, features, description, isAnnual, isCurrent, onSelect, }: PlanCardProps): React.ReactElement;
152
+
153
+ /**
154
+ * PricingTable — Renders plan cards with monthly/annual toggle.
155
+ * UI-01: Responsive grid, monthly/annual toggle, highlights currentPlanId.
156
+ * Uses CSS variable theming with --nozle-* namespace.
157
+ */
158
+
159
+ interface PricingTableProps {
160
+ plans: Plan[];
161
+ currentPlanId?: string;
162
+ onSelect?: (planId: string) => void;
163
+ }
164
+ /**
165
+ * PricingTable renders plan cards in a responsive grid with monthly/annual toggle.
166
+ * The current plan is highlighted with aria-current="true" and border-primary class.
167
+ *
168
+ * Usage:
169
+ * ```tsx
170
+ * <PricingTable
171
+ * plans={plans}
172
+ * currentPlanId="pro"
173
+ * onSelect={(planId) => handleUpgrade(planId)}
174
+ * />
175
+ * ```
176
+ */
177
+ declare function PricingTable({ plans, currentPlanId, onSelect, }: PricingTableProps): React.ReactElement;
178
+
179
+ /**
180
+ * PlanComparison — Side-by-side feature comparison table.
181
+ * UI-01: Renders shadcn-style table with plan names as headers and features as rows.
182
+ * Check/cross icons for boolean values. Uses CSS variable theming.
183
+ */
184
+
185
+ interface ComparisonFeature {
186
+ key: string;
187
+ label: string;
188
+ values: Record<string, string | boolean>;
189
+ }
190
+ interface PlanComparisonProps {
191
+ plans: Plan[];
192
+ features: ComparisonFeature[];
193
+ }
194
+ /**
195
+ * PlanComparison renders a side-by-side feature comparison table.
196
+ *
197
+ * Usage:
198
+ * ```tsx
199
+ * <PlanComparison
200
+ * plans={plans}
201
+ * features={[
202
+ * { key: 'api_calls', label: 'API Calls', values: { starter: '10K', pro: '100K' } },
203
+ * { key: 'analytics', label: 'Analytics', values: { starter: false, pro: true } },
204
+ * ]}
205
+ * />
206
+ * ```
207
+ */
208
+ declare function PlanComparison({ plans, features, }: PlanComparisonProps): React.ReactElement;
106
209
 
107
- declare function usePlan(): UsePlanResult;
210
+ /**
211
+ * CheckoutButton — Initiates checkout for a plan.
212
+ * UI-02: Calls POST /api/v1/checkout, detects processor type from the response,
213
+ * and branches to the appropriate payment flow:
214
+ * - Stripe hosted checkout: redirect to url
215
+ * - Stripe embedded Elements: emit clientSecret via onStripeClientSecret callback
216
+ * - Razorpay: inject Razorpay.js and open the checkout modal
217
+ * - Legacy (no type): redirect to url for backwards compatibility
218
+ * Uses CSS variable theming with --nozle-* namespace.
219
+ */
108
220
 
221
+ interface CheckoutButtonProps {
222
+ planId: string;
223
+ label?: string;
224
+ apiBaseUrl?: string;
225
+ className?: string;
226
+ style?: React.CSSProperties;
227
+ onError?: (error: Error) => void;
228
+ /** Required for Razorpay checkout path — the Razorpay publishable key (key_id). */
229
+ razorpayKeyId?: string;
230
+ /** Called with the Stripe Payment Intent / Checkout Session client secret
231
+ * when the BFF returns type:'stripe' without a hosted url.
232
+ * The host app is responsible for mounting Stripe Elements. */
233
+ onStripeClientSecret?: (clientSecret: string) => void;
234
+ /** Called with the Razorpay payment ID after a successful Razorpay payment. */
235
+ onSuccess?: (paymentId: string) => void;
236
+ }
237
+ interface RazorpayOptions {
238
+ key: string;
239
+ order_id: string;
240
+ name?: string;
241
+ description?: string;
242
+ handler: (response: {
243
+ razorpay_payment_id: string;
244
+ }) => void;
245
+ modal?: {
246
+ ondismiss?: () => void;
247
+ };
248
+ }
249
+ declare global {
250
+ interface Window {
251
+ Razorpay: new (opts: RazorpayOptions) => {
252
+ open(): void;
253
+ };
254
+ }
255
+ }
256
+ /**
257
+ * CheckoutButton initiates a checkout session and routes to the appropriate
258
+ * payment processor path.
259
+ *
260
+ * Must be used inside a BillingPortalProvider.
261
+ */
262
+ declare function CheckoutButton({ planId, label, apiBaseUrl, className, style, onError, razorpayKeyId, onStripeClientSecret, onSuccess, }: CheckoutButtonProps): React.ReactElement;
263
+
264
+ interface CheckoutProps {
265
+ /** Stripe PaymentIntent client secret */
266
+ clientSecret: string;
267
+ /** Stripe publishable key */
268
+ publishableKey: string;
269
+ /** Optional Stripe Connect account ID */
270
+ stripeAccount?: string;
271
+ /** Custom label for the submit button (default: "Pay now") */
272
+ submitLabel?: string;
273
+ /** Called with the paymentIntentId when payment succeeds without redirect */
274
+ onSuccess?: (paymentIntentId: string) => void;
275
+ /** Called with the error when payment fails */
276
+ onError?: (error: Error) => void;
277
+ /** Called when the PaymentElement becomes interactive */
278
+ onReady?: () => void;
279
+ /** Additional CSS class for the outer wrapper */
280
+ className?: string;
281
+ /** Inline styles for the outer wrapper */
282
+ style?: React.CSSProperties;
283
+ }
109
284
  interface UseCheckoutResult {
110
- fetchClientSecret: (planCode: string, successUrl?: string) => Promise<string>;
111
- checkout: CheckoutResult | null;
112
- stripePromise: ReturnType<typeof _stripe_stripe_js.loadStripe> | null;
113
- isLoading: boolean;
285
+ /** Trigger payment confirmation programmatically */
286
+ confirmPayment: () => Promise<void>;
287
+ /** True while a payment confirmation is in-flight */
288
+ isProcessing: boolean;
289
+ /** Last payment error, or null if no error */
114
290
  error: Error | null;
115
291
  }
116
292
  declare function useCheckout(): UseCheckoutResult;
293
+ declare function Checkout({ clientSecret, publishableKey, stripeAccount, submitLabel, onSuccess, onError, onReady, className, style, }: CheckoutProps): react_jsx_runtime.JSX.Element;
117
294
 
118
- interface UseSubscribeResult {
119
- subscribe: (planCode: string) => Promise<any>;
120
- isLoading: boolean;
121
- error: Error | null;
295
+ /**
296
+ * UpgradeButton — Opens UpgradeModal on click.
297
+ * UI-02: Triggers plan upgrade flow with proration preview.
298
+ * Uses CSS variable theming with --nozle-* namespace.
299
+ */
300
+
301
+ interface UpgradeButtonProps {
302
+ targetPlanId: string;
303
+ label?: string;
304
+ apiBaseUrl?: string;
305
+ className?: string;
306
+ style?: React.CSSProperties;
307
+ onUpgraded?: () => void;
122
308
  }
123
- declare function useSubscribe(): UseSubscribeResult;
309
+ /**
310
+ * UpgradeButton opens an UpgradeModal with live proration preview.
311
+ * Must be used inside a BillingPortalProvider.
312
+ */
313
+ declare function UpgradeButton({ targetPlanId, label, apiBaseUrl, className, style, onUpgraded, }: UpgradeButtonProps): React.ReactElement;
124
314
 
125
- interface Plan {
126
- code: string;
127
- name: string;
128
- amount_cents: number;
129
- amount_currency: string;
130
- interval: string;
315
+ /**
316
+ * CreditTopUpButton — Opens a dialog for purchasing credits.
317
+ * UI-02: Allows customers to top up their credit balance.
318
+ * Uses CSS variable theming with --nozle-* namespace.
319
+ */
320
+
321
+ interface CreditTopUpButtonProps {
322
+ label?: string;
323
+ apiBaseUrl?: string;
324
+ className?: string;
325
+ style?: React.CSSProperties;
326
+ onSuccess?: (amount: number) => void;
327
+ onError?: (error: Error) => void;
131
328
  }
132
- declare function usePlans(): {
133
- plans: Plan[];
134
- isLoading: boolean;
135
- };
329
+ /**
330
+ * CreditTopUpButton opens a dialog to purchase credits.
331
+ * Must be used inside a BillingPortalProvider.
332
+ */
333
+ declare function CreditTopUpButton({ label, apiBaseUrl, className, style, onSuccess, onError, }: CreditTopUpButtonProps): React.ReactElement;
334
+
335
+ /**
336
+ * UpgradeModal — Shows live proration preview before confirming plan upgrade.
337
+ * UI-02: Fetches proration preview from POST /api/v1/subscriptions/preview.
338
+ * Shows credit, debit, net, and next billing date before confirming.
339
+ * Uses CSS variable theming with --nozle-* namespace.
340
+ */
136
341
 
137
- interface UsageMeterProps extends HTMLAttributes<HTMLDivElement> {
138
- metric: string;
139
- variant?: "bar" | "ring" | "minimal";
342
+ interface ProrationPreview {
343
+ credit: number;
344
+ debit: number;
345
+ net: number;
346
+ nextBillingDate: string;
140
347
  }
141
- interface PlanBadgeProps extends HTMLAttributes<HTMLSpanElement> {
142
- variant?: "pill" | "text" | "icon";
348
+ interface UpgradeModalProps {
349
+ isOpen: boolean;
350
+ targetPlanId: string;
351
+ customerId: string;
352
+ apiBaseUrl?: string;
353
+ apiKey?: string;
354
+ onConfirm?: () => void;
355
+ onCancel?: () => void;
356
+ }
357
+ /**
358
+ * UpgradeModal shows proration preview from POST /api/v1/subscriptions/preview
359
+ * before the customer confirms a plan upgrade.
360
+ */
361
+ declare function UpgradeModal({ isOpen, targetPlanId, customerId, apiBaseUrl, apiKey, onConfirm, onCancel, }: UpgradeModalProps): React.ReactElement | null;
362
+
363
+ /**
364
+ * FeatureGate — Renders children if customer has access to a feature.
365
+ * UI-03: Uses useCan hook; renders fallback when allowed=false.
366
+ * Renders null while loading to avoid layout shift.
367
+ */
368
+
369
+ interface FeatureGateProps {
370
+ /** Customer ID to check entitlement for */
371
+ customerId: string;
372
+ /** Feature key to check */
373
+ feature: string;
374
+ /** Rendered when customer does not have access. Defaults to null. */
375
+ fallback?: ReactNode;
376
+ /** Content to show when customer has access */
377
+ children: ReactNode;
378
+ }
379
+ /**
380
+ * FeatureGate renders children only when the customer is entitled to the feature.
381
+ * Returns null while the entitlement check is loading.
382
+ *
383
+ * Usage:
384
+ * ```tsx
385
+ * <FeatureGate customerId="cus_123" feature="analytics" fallback={<UpgradePrompt />}>
386
+ * <AnalyticsDashboard />
387
+ * </FeatureGate>
388
+ * ```
389
+ */
390
+ declare function FeatureGate({ customerId, feature, fallback, children, }: FeatureGateProps): React.ReactElement | null;
391
+
392
+ /**
393
+ * UsageGate — Renders children if usage is below limit.
394
+ * UI-03: Renders fallback when usage >= limit.
395
+ * Pure render logic — caller provides usage and limit values.
396
+ */
397
+
398
+ interface UsageGateProps {
399
+ /** Current usage value */
400
+ usage: number;
401
+ /** Usage limit */
402
+ limit: number;
403
+ /** Rendered when usage is at or above limit. Defaults to null. */
404
+ fallback?: ReactNode;
405
+ /** Content to show when usage is below limit */
406
+ children: ReactNode;
407
+ }
408
+ /**
409
+ * UsageGate renders children only when current usage is below the limit.
410
+ * When usage >= limit, renders fallback.
411
+ *
412
+ * Usage:
413
+ * ```tsx
414
+ * <UsageGate usage={currentUsage} limit={plan.apiCallLimit} fallback={<UpgradePrompt />}>
415
+ * <ApiCallButton />
416
+ * </UsageGate>
417
+ * ```
418
+ */
419
+ declare function UsageGate({ usage, limit, fallback, children, }: UsageGateProps): React.ReactElement;
420
+
421
+ /**
422
+ * PlanGate — Renders children if customer's plan is in the allowed list.
423
+ * UI-03: Pure render logic — caller provides currentPlan and allowedPlans.
424
+ * Renders fallback when customer is not on an allowed plan tier.
425
+ */
426
+
427
+ interface PlanGateProps {
428
+ /** The customer's current plan identifier */
429
+ currentPlan: string;
430
+ /** List of plan identifiers that are allowed to see the children */
431
+ allowedPlans: string[];
432
+ /** Rendered when customer is not on an allowed plan. Defaults to null. */
433
+ fallback?: ReactNode;
434
+ /** Content to show when customer is on an allowed plan */
435
+ children: ReactNode;
436
+ }
437
+ /**
438
+ * PlanGate renders children only when the customer's currentPlan is in allowedPlans.
439
+ * When not on an allowed plan, renders fallback.
440
+ *
441
+ * Usage:
442
+ * ```tsx
443
+ * <PlanGate
444
+ * currentPlan={customer.plan}
445
+ * allowedPlans={['pro', 'enterprise']}
446
+ * fallback={<UpgradePrompt planName="Pro" />}
447
+ * >
448
+ * <ProFeature />
449
+ * </PlanGate>
450
+ * ```
451
+ */
452
+ declare function PlanGate({ currentPlan, allowedPlans, fallback, children, }: PlanGateProps): React.ReactElement;
453
+
454
+ /**
455
+ * UpgradePrompt — Reusable upgrade message component.
456
+ * UI-03: Shows plan name + upgrade button; used as default fallback for LockedOverlay.
457
+ * Uses CSS variable theming with --nozle-* namespace.
458
+ */
459
+
460
+ interface UpgradePromptProps {
461
+ text?: string;
462
+ planName?: string;
463
+ onUpgrade?: () => void;
464
+ }
465
+ /**
466
+ * UpgradePrompt renders an upgrade call-to-action with a message and button.
467
+ * Used as default fallback in LockedOverlay and gate components.
468
+ */
469
+ declare function UpgradePrompt({ text, planName, onUpgrade, }: UpgradePromptProps): React.ReactElement;
470
+
471
+ /**
472
+ * LockedOverlay — Wraps children with a blur filter + upgrade CTA overlay when locked.
473
+ * UI-03: Applies CSS blur(4px) to children with an upgrade prompt overlay.
474
+ * Uses CSS variable theming with --nozle-* namespace.
475
+ */
476
+
477
+ interface LockedOverlayProps {
478
+ /** Whether to apply the locked blur + overlay state */
479
+ locked: boolean;
480
+ /** Text to show in the upgrade prompt */
481
+ upgradeText?: string;
482
+ /** Plan name to show in the upgrade prompt */
483
+ upgradePlanName?: string;
484
+ /** Called when the upgrade button is clicked */
485
+ onUpgrade?: () => void;
486
+ /** Content to blur when locked */
487
+ children: ReactNode;
488
+ }
489
+ /**
490
+ * LockedOverlay wraps children in a relative container.
491
+ * When locked=true:
492
+ * - Children receive CSS blur(4px) and pointer-events: none
493
+ * - An upgrade CTA overlay is positioned on top
494
+ *
495
+ * When locked=false, children render normally without any overlay.
496
+ *
497
+ * Usage:
498
+ * ```tsx
499
+ * <LockedOverlay locked={!canAccessFeature} upgradeText="Upgrade to Pro" onUpgrade={openUpgradeModal}>
500
+ * <FeatureContent />
501
+ * </LockedOverlay>
502
+ * ```
503
+ */
504
+ declare function LockedOverlay({ locked, upgradeText, upgradePlanName, onUpgrade, children, }: LockedOverlayProps): React.ReactElement;
505
+
506
+ /**
507
+ * UsageMeter — embeddable usage progress bar with automatic color thresholds.
508
+ * Uses --nozle-* CSS variables for theming (customer-facing portal layer).
509
+ *
510
+ * Color thresholds:
511
+ * < 80% → primary (normal)
512
+ * 80-94% → warning (amber)
513
+ * ≥ 95% → destructive (red)
514
+ */
515
+ declare function getUsageMeterColor(percentage: number): string;
516
+ interface UsageMeterProps {
517
+ used: number;
518
+ limit: number;
519
+ label?: string;
520
+ showText?: boolean;
521
+ }
522
+ declare function UsageMeter({ used, limit, label, showText, }: UsageMeterProps): react_jsx_runtime.JSX.Element;
523
+
524
+ interface UsageDashboardFeature {
525
+ key: string;
526
+ label: string;
527
+ used: number;
528
+ limit: number;
529
+ }
530
+ interface UsageDashboardProps {
531
+ features?: UsageDashboardFeature[];
532
+ loading?: boolean;
143
533
  }
144
- interface UpgradePromptProps extends HTMLAttributes<HTMLDivElement> {
145
- feature?: string;
146
- variant?: "card" | "banner" | "inline";
147
- upgradeUrl?: string;
148
- message?: string;
534
+ declare function UsageDashboard({ features, loading, }: UsageDashboardProps): react_jsx_runtime.JSX.Element;
535
+
536
+ interface UsageAlertFeature {
537
+ key: string;
538
+ label: string;
539
+ percentage: number;
540
+ }
541
+ interface UsageAlertProps {
542
+ features: UsageAlertFeature[];
543
+ threshold?: number;
544
+ upgradeHref?: string;
545
+ }
546
+ declare function UsageAlert({ features, threshold, upgradeHref, }: UsageAlertProps): react_jsx_runtime.JSX.Element | null;
547
+
548
+ interface CreditBalanceProps {
549
+ customerId: string;
550
+ currency?: string;
551
+ }
552
+ declare function CreditBalance({ customerId, currency, }: CreditBalanceProps): react_jsx_runtime.JSX.Element;
553
+
554
+ interface CreditTransaction {
555
+ id: string;
556
+ amount: number;
557
+ type: string;
558
+ description: string;
559
+ createdAt: string;
560
+ }
561
+ interface CreditHistoryProps {
562
+ customerId: string;
563
+ viewAllHref?: string;
564
+ }
565
+ declare function CreditHistory({ customerId, viewAllHref, }: CreditHistoryProps): react_jsx_runtime.JSX.Element;
566
+
567
+ interface PlanBadgeProps {
568
+ plan: string;
569
+ tier?: "free" | "starter" | "pro" | "enterprise";
570
+ }
571
+ declare function PlanBadge({ plan, tier }: PlanBadgeProps): react_jsx_runtime.JSX.Element;
572
+
573
+ interface BillingPortalProps {
574
+ customerId: string;
575
+ usageFeatures?: UsageDashboardFeature[];
576
+ usageLoading?: boolean;
577
+ onChangePlan?: () => void;
578
+ subscriptionId?: string;
579
+ onCancelled?: () => void;
149
580
  }
581
+ declare function BillingPortal({ customerId, usageFeatures, usageLoading, onChangePlan, }: BillingPortalProps): react_jsx_runtime.JSX.Element;
150
582
 
151
- declare function UsageMeter({ metric, variant, className, style, ...props }: UsageMeterProps): react_jsx_runtime.JSX.Element | null;
583
+ interface CurrentPlanData {
584
+ id: string;
585
+ planName: string;
586
+ interval: string;
587
+ status: string;
588
+ nextBillingDate?: string;
589
+ tier?: "free" | "starter" | "pro" | "enterprise";
590
+ }
591
+ interface CurrentPlanProps {
592
+ customerId: string;
593
+ onChangePlan?: () => void;
594
+ changePlanHref?: string;
595
+ }
596
+ declare function CurrentPlan({ customerId, onChangePlan, changePlanHref, }: CurrentPlanProps): react_jsx_runtime.JSX.Element;
152
597
 
153
- declare function PlanBadge({ variant, className, style, ...props }: PlanBadgeProps): react_jsx_runtime.JSX.Element | null;
598
+ interface Invoice {
599
+ id: string;
600
+ number: string;
601
+ date: string;
602
+ amount: number;
603
+ currency: string;
604
+ status: "draft" | "open" | "paid" | "void" | "uncollectible";
605
+ pdf_url?: string;
606
+ }
607
+ interface InvoiceListProps {
608
+ customerId: string;
609
+ }
610
+ declare function InvoiceList({ customerId }: InvoiceListProps): react_jsx_runtime.JSX.Element;
611
+
612
+ /**
613
+ * PaymentMethodDisplay — shows saved payment method details.
614
+ * Displays last4, brand, expiry. "Update Payment Method" button opens checkout.
615
+ */
616
+ interface PaymentMethod {
617
+ last4: string;
618
+ brand: string;
619
+ expMonth: number;
620
+ expYear: number;
621
+ }
622
+ interface PaymentMethodDisplayProps {
623
+ paymentMethod?: PaymentMethod;
624
+ onUpdatePaymentMethod?: () => void;
625
+ updateHref?: string;
626
+ }
627
+ declare function PaymentMethodDisplay({ paymentMethod, onUpdatePaymentMethod, updateHref, }: PaymentMethodDisplayProps): react_jsx_runtime.JSX.Element;
154
628
 
155
- declare function UpgradePrompt({ feature, variant, upgradeUrl, message, className, style, ...props }: UpgradePromptProps): react_jsx_runtime.JSX.Element | null;
629
+ declare const CANCEL_REASONS: readonly ["Too expensive", "Missing features", "Switching to competitor", "Not using it enough", "Other"];
630
+ interface CancelSubscriptionButtonProps {
631
+ subscriptionId: string;
632
+ onCancelled?: () => void;
633
+ }
634
+ declare function CancelSubscriptionButton({ subscriptionId, onCancelled, }: CancelSubscriptionButtonProps): react_jsx_runtime.JSX.Element;
156
635
 
157
- export { BillingProvider, type BillingState, type CheckoutResult, type Plan, PlanBadge, type PlanBadgeProps, UpgradePrompt, type UpgradePromptProps, UsageMeter, type UsageMeterProps, type UseCanResult, type UseCheckoutResult, type UsePlanResult, type UseUsageResult, useBillingContext, useCan, useCheckout, usePlan, usePlans, useSubscribe, useUsage };
636
+ export { BillingContext, type BillingContextValue, BillingPortal, type BillingPortalContextValue, type BillingPortalProps, BillingPortalProvider, type BillingPortalProviderProps, BillingProvider, type BillingProviderProps, CANCEL_REASONS, type CanState, CancelSubscriptionButton, type CancelSubscriptionButtonProps, Checkout, CheckoutButton, type CheckoutButtonProps, type CheckoutProps, type ComparisonFeature, CreditBalance, type CreditBalanceProps, CreditHistory, type CreditHistoryProps, CreditTopUpButton, type CreditTopUpButtonProps, type CreditTransaction, type CreditsState, CurrentPlan, type CurrentPlanData, type CurrentPlanProps, FeatureGate, type FeatureGateProps, type Invoice, InvoiceList, type InvoiceListProps, LockedOverlay, type LockedOverlayProps, type NozleClient, type PaymentMethod, PaymentMethodDisplay, type PaymentMethodDisplayProps, type Plan, PlanBadge, type PlanBadgeProps, PlanCard, type PlanCardProps, PlanComparison, type PlanComparisonProps, PlanGate, type PlanGateProps, PricingTable, type PricingTableProps, type ProrationPreview, UpgradeButton, type UpgradeButtonProps, UpgradeModal, type UpgradeModalProps, UpgradePrompt, type UpgradePromptProps, UsageAlert, type UsageAlertFeature, type UsageAlertProps, UsageDashboard, type UsageDashboardFeature, type UsageDashboardProps, UsageGate, type UsageGateProps, UsageMeter, type UsageMeterProps, type UsageState, type UseCheckoutResult, getUsageMeterColor, useBillingContext, useBillingPortal, useCan, useCheckout, useCredits, useNozleClient, useUsage };