@gradual-so/sdk-react 0.0.1 → 0.1.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 +139 -0
- package/package.json +6 -2
package/README.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# @gradual-so/sdk-react
|
|
2
|
+
|
|
3
|
+
React SDK for [Gradual](https://gradual.so) feature flags. Provides a provider and hooks for evaluating flags in React components.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @gradual-so/sdk-react @gradual-so/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
Wrap your app with the provider:
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { GradualProvider } from '@gradual-so/sdk-react'
|
|
17
|
+
|
|
18
|
+
function App() {
|
|
19
|
+
return (
|
|
20
|
+
<GradualProvider apiKey="gra_xxx" environment="production">
|
|
21
|
+
<MyApp />
|
|
22
|
+
</GradualProvider>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Use flags in components:
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { useFlag } from '@gradual-so/sdk-react'
|
|
31
|
+
|
|
32
|
+
function MyComponent() {
|
|
33
|
+
const showBanner = useFlag('show-banner', { fallback: false })
|
|
34
|
+
const theme = useFlag('theme', { fallback: 'light' })
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<div data-theme={theme}>
|
|
38
|
+
{showBanner && <PromoBanner />}
|
|
39
|
+
</div>
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The return type is inferred from `fallback` -- `boolean` for `false`, `string` for `'light'`, etc.
|
|
45
|
+
|
|
46
|
+
## User targeting
|
|
47
|
+
|
|
48
|
+
Use `useGradual` to set user context. All flag evaluations will include this context:
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import { useGradual } from '@gradual-so/sdk-react'
|
|
52
|
+
import { useEffect } from 'react'
|
|
53
|
+
|
|
54
|
+
function AuthHandler({ user }) {
|
|
55
|
+
const { identify, reset } = useGradual()
|
|
56
|
+
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
if (user) {
|
|
59
|
+
identify({ userId: user.id, plan: user.plan })
|
|
60
|
+
} else {
|
|
61
|
+
reset()
|
|
62
|
+
}
|
|
63
|
+
}, [user])
|
|
64
|
+
|
|
65
|
+
return null
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Override context for a single flag:
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
const enabled = useFlag('feature', {
|
|
73
|
+
fallback: false,
|
|
74
|
+
context: { itemId: item.id },
|
|
75
|
+
})
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Loading states
|
|
79
|
+
|
|
80
|
+
By default, `useFlag` returns the fallback value while the SDK initializes and the resolved value once ready. To distinguish between these states, use `detail: true`:
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
const { value, isLoading, isReady } = useFlag('experiment', {
|
|
84
|
+
fallback: 'control',
|
|
85
|
+
detail: true,
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
if (isLoading) return <Skeleton />
|
|
89
|
+
return <Experiment variant={value} />
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## API
|
|
93
|
+
|
|
94
|
+
### `<GradualProvider>`
|
|
95
|
+
|
|
96
|
+
Initializes the Gradual SDK and provides it to child components.
|
|
97
|
+
|
|
98
|
+
| Prop | Type | Required | Description |
|
|
99
|
+
|---|---|---|---|
|
|
100
|
+
| `apiKey` | `string` | Yes | Your Gradual API key |
|
|
101
|
+
| `environment` | `string` | Yes | Environment slug (e.g. `production`) |
|
|
102
|
+
| `baseUrl` | `string` | No | Custom API base URL |
|
|
103
|
+
|
|
104
|
+
### `useFlag(key, options)`
|
|
105
|
+
|
|
106
|
+
Returns the flag value directly, or a detail object when `detail: true`.
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
// Returns T (type inferred from fallback)
|
|
110
|
+
const value = useFlag('key', { fallback: defaultValue })
|
|
111
|
+
|
|
112
|
+
// Returns { value: T, isLoading: boolean, isReady: boolean }
|
|
113
|
+
const detail = useFlag('key', { fallback: defaultValue, detail: true })
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
| Option | Type | Required | Description |
|
|
117
|
+
|---|---|---|---|
|
|
118
|
+
| `fallback` | `T` | Yes | Default value when flag is missing or SDK is loading |
|
|
119
|
+
| `context` | `Record<string, unknown>` | No | Evaluation context override for this flag |
|
|
120
|
+
| `detail` | `boolean` | No | Return `{ value, isLoading, isReady }` instead of just the value |
|
|
121
|
+
|
|
122
|
+
### `useGradual()`
|
|
123
|
+
|
|
124
|
+
Returns methods for managing user context and SDK state.
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
const { identify, reset, refresh, isReady } = useGradual()
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
| Property | Type | Description |
|
|
131
|
+
|---|---|---|
|
|
132
|
+
| `identify` | `(context) => void` | Set persistent user context for all evaluations |
|
|
133
|
+
| `reset` | `() => void` | Clear the identified user context |
|
|
134
|
+
| `refresh` | `() => Promise<void>` | Fetch the latest flag snapshot from the server |
|
|
135
|
+
| `isReady` | `boolean` | Whether the SDK has finished initializing |
|
|
136
|
+
|
|
137
|
+
## License
|
|
138
|
+
|
|
139
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradual-so/sdk-react",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Gradual feature flag SDK for React",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -22,6 +22,10 @@
|
|
|
22
22
|
"dist"
|
|
23
23
|
],
|
|
24
24
|
"sideEffects": false,
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public",
|
|
27
|
+
"provenance": true
|
|
28
|
+
},
|
|
25
29
|
"license": "MIT",
|
|
26
30
|
"keywords": [
|
|
27
31
|
"feature-flags",
|
|
@@ -33,7 +37,7 @@
|
|
|
33
37
|
],
|
|
34
38
|
"repository": {
|
|
35
39
|
"type": "git",
|
|
36
|
-
"url": "https://github.com/
|
|
40
|
+
"url": "https://github.com/elijahnikov/gradual",
|
|
37
41
|
"directory": "packages/sdk-react"
|
|
38
42
|
},
|
|
39
43
|
"scripts": {
|