@nozle-js/react 0.3.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/README.md +241 -0
- package/dist/index.cjs +2773 -897
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +603 -117
- package/dist/index.d.ts +603 -117
- package/dist/index.js +2741 -894
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# @nozle-js/react
|
|
2
|
+
|
|
3
|
+
React SDK for usage-based billing. Hooks and components for entitlements, real-time usage tracking, plan management, and Stripe checkout.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @nozle-js/react
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Peer dependencies:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install react react-dom @stripe/stripe-js @stripe/react-stripe-js
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
Wrap your app with `BillingProvider`:
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { BillingProvider } from "@nozle-js/react";
|
|
23
|
+
|
|
24
|
+
function App() {
|
|
25
|
+
return (
|
|
26
|
+
<BillingProvider
|
|
27
|
+
apiKey="pk_live_..."
|
|
28
|
+
customerId="cust_123"
|
|
29
|
+
baseUrl="https://your-api.example.com"
|
|
30
|
+
wsUrl="wss://your-ws.example.com/connection/websocket"
|
|
31
|
+
stripeKey="pk_test_..."
|
|
32
|
+
features={["tokens_used", "code_completions"]}
|
|
33
|
+
>
|
|
34
|
+
<YourApp />
|
|
35
|
+
</BillingProvider>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Hooks
|
|
41
|
+
|
|
42
|
+
### `useCan(feature)`
|
|
43
|
+
|
|
44
|
+
Check if a customer has access to a feature.
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
import { useCan } from "@nozle-js/react";
|
|
48
|
+
|
|
49
|
+
function MyFeature() {
|
|
50
|
+
const { allowed, isLoading, error } = useCan("advanced_analytics");
|
|
51
|
+
|
|
52
|
+
if (isLoading) return <p>Loading...</p>;
|
|
53
|
+
if (!allowed) return <p>Upgrade to access this feature.</p>;
|
|
54
|
+
|
|
55
|
+
return <div>Feature content here</div>;
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### `useUsage(metric)`
|
|
60
|
+
|
|
61
|
+
Get real-time usage data for a metric. Updates automatically via WebSocket.
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
import { useUsage } from "@nozle-js/react";
|
|
65
|
+
|
|
66
|
+
function TokenCounter() {
|
|
67
|
+
const { data, isLoading } = useUsage("tokens_used");
|
|
68
|
+
|
|
69
|
+
if (isLoading || !data) return null;
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<p>
|
|
73
|
+
{data.used.toLocaleString()} / {data.limit.toLocaleString()} tokens used
|
|
74
|
+
</p>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### `usePlan()`
|
|
80
|
+
|
|
81
|
+
Get the customer's current plan and subscription status.
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
import { usePlan } from "@nozle-js/react";
|
|
85
|
+
|
|
86
|
+
function CurrentPlan() {
|
|
87
|
+
const { data } = usePlan();
|
|
88
|
+
|
|
89
|
+
if (!data) return null;
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<p>
|
|
93
|
+
Plan: {data.plan_slug} ({data.subscription_status})
|
|
94
|
+
</p>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### `usePlans()`
|
|
100
|
+
|
|
101
|
+
Fetch all available plans.
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
import { usePlans } from "@nozle-js/react";
|
|
105
|
+
|
|
106
|
+
function PlanList() {
|
|
107
|
+
const { plans, isLoading } = usePlans();
|
|
108
|
+
|
|
109
|
+
if (isLoading) return <p>Loading plans...</p>;
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<ul>
|
|
113
|
+
{plans.map((plan) => (
|
|
114
|
+
<li key={plan.code}>
|
|
115
|
+
{plan.name} — ${(plan.amount_cents / 100).toFixed(2)}/{plan.interval}
|
|
116
|
+
</li>
|
|
117
|
+
))}
|
|
118
|
+
</ul>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### `useCheckout()`
|
|
124
|
+
|
|
125
|
+
Create a Stripe checkout session and render embedded checkout.
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
import { useCheckout } from "@nozle-js/react";
|
|
129
|
+
|
|
130
|
+
function UpgradeButton({ planCode }: { planCode: string }) {
|
|
131
|
+
const { fetchClientSecret, isLoading } = useCheckout();
|
|
132
|
+
|
|
133
|
+
const handleUpgrade = async () => {
|
|
134
|
+
const clientSecret = await fetchClientSecret(planCode);
|
|
135
|
+
// Use clientSecret with Stripe EmbeddedCheckout
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<button onClick={handleUpgrade} disabled={isLoading}>
|
|
140
|
+
Upgrade
|
|
141
|
+
</button>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### `useSubscribe()`
|
|
147
|
+
|
|
148
|
+
Create a subscription after successful payment.
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
import { useSubscribe } from "@nozle-js/react";
|
|
152
|
+
|
|
153
|
+
function AfterPayment({ planCode }: { planCode: string }) {
|
|
154
|
+
const { subscribe, isLoading } = useSubscribe();
|
|
155
|
+
|
|
156
|
+
const handleComplete = async () => {
|
|
157
|
+
await subscribe(planCode);
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
return (
|
|
161
|
+
<button onClick={handleComplete} disabled={isLoading}>
|
|
162
|
+
Activate Subscription
|
|
163
|
+
</button>
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Components
|
|
169
|
+
|
|
170
|
+
Pre-built UI components with built-in styling. No CSS imports needed.
|
|
171
|
+
|
|
172
|
+
### `UsageMeter`
|
|
173
|
+
|
|
174
|
+
Displays usage with bar, ring, or minimal variants.
|
|
175
|
+
|
|
176
|
+
```tsx
|
|
177
|
+
import { UsageMeter } from "@nozle-js/react";
|
|
178
|
+
|
|
179
|
+
<UsageMeter metric="tokens_used" variant="bar" />
|
|
180
|
+
<UsageMeter metric="tokens_used" variant="ring" />
|
|
181
|
+
<UsageMeter metric="tokens_used" variant="minimal" />
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### `PlanBadge`
|
|
185
|
+
|
|
186
|
+
Shows the current plan with status indicator.
|
|
187
|
+
|
|
188
|
+
```tsx
|
|
189
|
+
import { PlanBadge } from "@nozle-js/react";
|
|
190
|
+
|
|
191
|
+
<PlanBadge variant="pill" />
|
|
192
|
+
<PlanBadge variant="text" />
|
|
193
|
+
<PlanBadge variant="icon" />
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### `UpgradePrompt`
|
|
197
|
+
|
|
198
|
+
Conditionally renders an upgrade prompt when a feature is gated.
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
import { UpgradePrompt } from "@nozle-js/react";
|
|
202
|
+
|
|
203
|
+
<UpgradePrompt feature="advanced_analytics" variant="card" upgradeUrl="/upgrade" />
|
|
204
|
+
<UpgradePrompt feature="advanced_analytics" variant="banner" />
|
|
205
|
+
<UpgradePrompt feature="advanced_analytics" variant="inline" />
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Tailwind CSS Preset
|
|
209
|
+
|
|
210
|
+
Optional Tailwind preset for styling the `data-nozle` attributes on components.
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
// tailwind.config.ts
|
|
214
|
+
import { nozlePreset } from "@nozle-js/react/styles/preset";
|
|
215
|
+
|
|
216
|
+
export default {
|
|
217
|
+
presets: [nozlePreset],
|
|
218
|
+
};
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## TypeScript
|
|
222
|
+
|
|
223
|
+
All hooks and components are fully typed. Exported types:
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
import type {
|
|
227
|
+
BillingState,
|
|
228
|
+
UseCanResult,
|
|
229
|
+
UseUsageResult,
|
|
230
|
+
UsePlanResult,
|
|
231
|
+
UseCheckoutResult,
|
|
232
|
+
Plan,
|
|
233
|
+
UsageMeterProps,
|
|
234
|
+
PlanBadgeProps,
|
|
235
|
+
UpgradePromptProps,
|
|
236
|
+
} from "@nozle-js/react";
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## License
|
|
240
|
+
|
|
241
|
+
Proprietary
|