@launchdarkly/toolbar 0.11.0-beta.1 → 0.11.1-beta.1
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 +117 -20
- package/dist/js/index.js +8 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,46 +1,82 @@
|
|
|
1
1
|
# LaunchDarkly Toolbar
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> 🚧 **Beta:** This package is currently in beta. While functional and tested, APIs may still evolve based on feedback. Please report any issues or suggestions!
|
|
4
4
|
|
|
5
5
|
A React component that provides a developer-friendly toolbar for interacting with LaunchDarkly during development. The toolbar supports two modes:
|
|
6
6
|
|
|
7
|
+
- **SDK Mode**: Integrate with your LaunchDarkly SDK for local flag overrides and testing (recommended)
|
|
7
8
|
- **Dev Server Mode**: Connect to a LaunchDarkly CLI dev server for flag browsing and real-time updates
|
|
8
|
-
- **SDK Mode**: Integrate with flag override plugins for local flag testing
|
|
9
9
|
|
|
10
10
|
## Installation
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
npm
|
|
13
|
+
# npm
|
|
14
|
+
npm install @launchdarkly/toolbar@next
|
|
15
|
+
|
|
16
|
+
# yarn
|
|
17
|
+
yarn add @launchdarkly/toolbar@next
|
|
18
|
+
|
|
19
|
+
# pnpm
|
|
20
|
+
pnpm add @launchdarkly/toolbar@next
|
|
14
21
|
```
|
|
15
22
|
|
|
16
23
|
## Quick Start
|
|
17
24
|
|
|
18
|
-
**
|
|
25
|
+
**SDK Mode** (recommended - integrates with your LaunchDarkly SDK):
|
|
19
26
|
|
|
20
27
|
```tsx
|
|
21
|
-
import {
|
|
28
|
+
import { useEffect, useState } from 'react';
|
|
29
|
+
import { asyncWithLDProvider } from 'launchdarkly-react-client-sdk';
|
|
30
|
+
import { LaunchDarklyToolbar, FlagOverridePlugin } from '@launchdarkly/toolbar';
|
|
31
|
+
|
|
32
|
+
// Create the plugin instance
|
|
33
|
+
const flagOverridePlugin = new FlagOverridePlugin();
|
|
22
34
|
|
|
23
35
|
function App() {
|
|
36
|
+
const [LDProvider, setLDProvider] = useState(null);
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
const initializeLD = async () => {
|
|
40
|
+
const Provider = await asyncWithLDProvider({
|
|
41
|
+
clientSideID: 'your-client-side-id',
|
|
42
|
+
context: { key: 'user-key', name: 'User Name' },
|
|
43
|
+
options: {
|
|
44
|
+
// Pass the plugin to the SDK
|
|
45
|
+
plugins: [flagOverridePlugin],
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
setLDProvider(() => Provider);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
initializeLD();
|
|
52
|
+
}, []);
|
|
53
|
+
|
|
54
|
+
if (!LDProvider) {
|
|
55
|
+
return <div>Loading LaunchDarkly...</div>;
|
|
56
|
+
}
|
|
57
|
+
|
|
24
58
|
return (
|
|
25
|
-
<
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
59
|
+
<LDProvider>
|
|
60
|
+
<div>
|
|
61
|
+
<h1>My App</h1>
|
|
62
|
+
{/* Pass the same plugin instance to the toolbar */}
|
|
63
|
+
<LaunchDarklyToolbar flagOverridePlugin={flagOverridePlugin} />
|
|
64
|
+
</div>
|
|
65
|
+
</LDProvider>
|
|
29
66
|
);
|
|
30
67
|
}
|
|
31
68
|
```
|
|
32
69
|
|
|
33
|
-
**
|
|
70
|
+
**Dev Server Mode** (connects to LaunchDarkly CLI dev server):
|
|
34
71
|
|
|
35
72
|
```tsx
|
|
36
73
|
import { LaunchDarklyToolbar } from '@launchdarkly/toolbar';
|
|
37
|
-
import { flagOverridePlugin } from './your-flag-override-plugin';
|
|
38
74
|
|
|
39
75
|
function App() {
|
|
40
76
|
return (
|
|
41
77
|
<div>
|
|
42
78
|
<h1>My App</h1>
|
|
43
|
-
<LaunchDarklyToolbar
|
|
79
|
+
<LaunchDarklyToolbar devServerUrl="http://localhost:8765" />
|
|
44
80
|
</div>
|
|
45
81
|
);
|
|
46
82
|
}
|
|
@@ -50,8 +86,8 @@ function App() {
|
|
|
50
86
|
|
|
51
87
|
| Prop | Type | Default | Description |
|
|
52
88
|
| -------------------- | --------------------- | ----------- | ------------------------------------------------------------------------- |
|
|
89
|
+
| `flagOverridePlugin` | `IFlagOverridePlugin` | `undefined` | Flag override plugin for SDK Mode. Enables flag overrides and testing |
|
|
53
90
|
| `devServerUrl` | `string` (optional) | `undefined` | URL of your LaunchDarkly dev server. If provided, enables Dev Server Mode |
|
|
54
|
-
| `flagOverridePlugin` | `IFlagOverridePlugin` | `undefined` | Flag override plugin for SDK Mode. Shows Overrides tab when provided |
|
|
55
91
|
| `position` | `"left" \| "right"` | `"right"` | Position of the toolbar on screen |
|
|
56
92
|
| `projectKey` | `string` (optional) | `undefined` | Optional project key for multi-project setups (Dev Server Mode only) |
|
|
57
93
|
| `pollIntervalInMs` | `number` (optional) | `5000` | Polling interval for dev server updates (Dev Server Mode only) |
|
|
@@ -62,25 +98,86 @@ function App() {
|
|
|
62
98
|
|
|
63
99
|
The toolbar automatically determines its mode:
|
|
64
100
|
|
|
101
|
+
- **SDK Mode**: When `flagOverridePlugin` is provided (recommended for most use cases)
|
|
65
102
|
- **Dev Server Mode**: When `devServerUrl` is provided
|
|
66
|
-
- **SDK Mode**: When `devServerUrl` is omitted
|
|
67
103
|
|
|
68
104
|
### Available Features by Mode
|
|
69
105
|
|
|
70
|
-
| Mode | Available Tabs
|
|
71
|
-
| ------------------- |
|
|
72
|
-
| **
|
|
73
|
-
| **
|
|
106
|
+
| Mode | Available Tabs |
|
|
107
|
+
| ------------------- | ------------------- |
|
|
108
|
+
| **SDK Mode** | Overrides, Settings |
|
|
109
|
+
| **Dev Server Mode** | Flags, Settings |
|
|
74
110
|
|
|
75
111
|
## Setup
|
|
76
112
|
|
|
77
|
-
|
|
113
|
+
### SDK Mode (Recommended)
|
|
114
|
+
|
|
115
|
+
SDK Mode integrates directly with your LaunchDarkly client, allowing you to:
|
|
116
|
+
|
|
117
|
+
- Override flag values locally without affecting other users
|
|
118
|
+
- Test different flag variations instantly
|
|
119
|
+
- Work offline or with any LaunchDarkly environment
|
|
120
|
+
- Maintain full type safety with your existing SDK setup
|
|
121
|
+
|
|
122
|
+
Setup is straightforward:
|
|
123
|
+
|
|
124
|
+
1. Create a `FlagOverridePlugin` instance
|
|
125
|
+
2. Pass the plugin to your LaunchDarkly SDK's `plugins` array
|
|
126
|
+
3. Pass the same plugin instance to the toolbar component
|
|
127
|
+
4. Wrap your app with the LaunchDarkly provider
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
import { useEffect, useState } from 'react';
|
|
131
|
+
import { asyncWithLDProvider } from 'launchdarkly-react-client-sdk';
|
|
132
|
+
import { LaunchDarklyToolbar, FlagOverridePlugin } from '@launchdarkly/toolbar';
|
|
133
|
+
|
|
134
|
+
// Create the plugin instance (outside component to avoid recreating)
|
|
135
|
+
const flagOverridePlugin = new FlagOverridePlugin({
|
|
136
|
+
storageNamespace: 'my-app-overrides', // Optional: customize storage key
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
function App() {
|
|
140
|
+
const [LDProvider, setLDProvider] = useState(null);
|
|
141
|
+
|
|
142
|
+
useEffect(() => {
|
|
143
|
+
const initializeLD = async () => {
|
|
144
|
+
const Provider = await asyncWithLDProvider({
|
|
145
|
+
clientSideID: 'your-client-side-id',
|
|
146
|
+
context: { key: 'user-key', name: 'User Name' },
|
|
147
|
+
options: {
|
|
148
|
+
plugins: [flagOverridePlugin], // Add plugin to SDK
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
setLDProvider(() => Provider);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
initializeLD();
|
|
155
|
+
}, []);
|
|
156
|
+
|
|
157
|
+
if (!LDProvider) return <div>Loading...</div>;
|
|
158
|
+
|
|
159
|
+
return (
|
|
160
|
+
<LDProvider>
|
|
161
|
+
<YourAppContent />
|
|
162
|
+
<LaunchDarklyToolbar flagOverridePlugin={flagOverridePlugin} />
|
|
163
|
+
</LDProvider>
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Dev Server Mode
|
|
169
|
+
|
|
170
|
+
For teams using the LaunchDarkly CLI dev server, start it with CORS enabled:
|
|
78
171
|
|
|
79
172
|
```bash
|
|
80
173
|
ldcli dev-server start --project your-project --cors-enabled true
|
|
81
174
|
```
|
|
82
175
|
|
|
83
|
-
|
|
176
|
+
Then connect the toolbar:
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
<LaunchDarklyToolbar devServerUrl="http://localhost:8765" />
|
|
180
|
+
```
|
|
84
181
|
|
|
85
182
|
## Visibility Control
|
|
86
183
|
|
package/dist/js/index.js
CHANGED
|
@@ -4297,14 +4297,6 @@ function FlagSdkOverrideTabContentInner(props) {
|
|
|
4297
4297
|
estimateSize: ()=>VIRTUALIZATION.ITEM_HEIGHT,
|
|
4298
4298
|
overscan: VIRTUALIZATION.OVERSCAN
|
|
4299
4299
|
});
|
|
4300
|
-
if (!ldClient) return /*#__PURE__*/ jsx(GenericHelpText, {
|
|
4301
|
-
title: "LaunchDarkly client is not available",
|
|
4302
|
-
subtitle: "To use local flag overrides, ensure the LaunchDarkly client is initialized and available."
|
|
4303
|
-
});
|
|
4304
|
-
if (isLoading) return /*#__PURE__*/ jsx(GenericHelpText, {
|
|
4305
|
-
title: "Loading flags...",
|
|
4306
|
-
subtitle: "Please wait while we load your feature flags"
|
|
4307
|
-
});
|
|
4308
4300
|
const handleSetOverride = (flagKey, value)=>{
|
|
4309
4301
|
flagOverridePlugin.setOverride(flagKey, value);
|
|
4310
4302
|
};
|
|
@@ -4345,6 +4337,14 @@ function FlagSdkOverrideTabContentInner(props) {
|
|
|
4345
4337
|
});
|
|
4346
4338
|
}
|
|
4347
4339
|
};
|
|
4340
|
+
if (!ldClient) return /*#__PURE__*/ jsx(GenericHelpText, {
|
|
4341
|
+
title: "LaunchDarkly client is not available",
|
|
4342
|
+
subtitle: "To use local flag overrides, ensure the LaunchDarkly client is initialized and available."
|
|
4343
|
+
});
|
|
4344
|
+
if (isLoading) return /*#__PURE__*/ jsx(GenericHelpText, {
|
|
4345
|
+
title: "Loading flags...",
|
|
4346
|
+
subtitle: "Please wait while we load your feature flags"
|
|
4347
|
+
});
|
|
4348
4348
|
if (0 === flagEntries.length) return /*#__PURE__*/ jsx(GenericHelpText, {
|
|
4349
4349
|
title: "No flags available",
|
|
4350
4350
|
subtitle: "Make sure your LaunchDarkly client is properly initialized with flags"
|
package/package.json
CHANGED