@launchdarkly/toolbar 0.25.0 → 1.0.0-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 +276 -161
- package/cdn/toolbar.min.js +25 -0
- package/cdn/toolbar.min.js.LICENSE.txt +59 -0
- package/cdn/toolbar.min.js.map +1 -0
- package/dist/core/context/Providers.d.ts +9 -0
- package/dist/core/context/ReactMountContext.d.ts +2 -0
- package/dist/core/context/ShadowRootContext.d.ts +2 -0
- package/dist/core/context/defaultConfig.d.ts +3 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/mount.d.ts +2 -0
- package/dist/{ui → core/ui}/Toolbar/LaunchDarklyToolbar.d.ts +3 -1
- package/dist/{ui → core/ui}/Toolbar/TabContent/EventsTabContent.d.ts +1 -1
- package/dist/core/ui/Toolbar/TabContent/FlagDevServerTabContent.d.ts +5 -0
- package/dist/{ui → core/ui}/Toolbar/TabContent/FlagSdkOverrideTabContent.d.ts +2 -1
- package/dist/{ui → core/ui}/Toolbar/TabContent/SettingsTab.css.d.ts +1 -0
- package/dist/{ui → core/ui}/Toolbar/TabContent/SettingsTabContent.d.ts +4 -2
- package/dist/{ui → core/ui}/Toolbar/components/ExpandedToolbarContent.d.ts +5 -3
- package/dist/{ui → core/ui}/Toolbar/components/TabContentRenderer.d.ts +5 -3
- package/dist/{ui → core/ui}/Toolbar/context/FlagSdkOverrideProvider.d.ts +1 -1
- package/dist/{ui → core/ui}/Toolbar/hooks/useEvents.d.ts +1 -2
- package/dist/{ui → core/ui}/Toolbar/hooks/useToolbarState.d.ts +5 -2
- package/dist/{ui → core/ui}/Toolbar/utils/localStorage.d.ts +6 -3
- package/dist/{utils → core/utils}/analytics.d.ts +7 -3
- package/dist/core/utils/hydrateConfig.d.ts +2 -0
- package/dist/{js/plugins/index.js → index.cjs} +278 -133
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +9 -10
- package/dist/js/index.js +226 -7681
- package/dist/js/index.js.map +1 -0
- package/dist/react/lazyLoadToolbar.d.ts +2 -0
- package/dist/react/useLaunchDarklyToolbar.d.ts +20 -0
- package/dist/types/analytics.d.ts +1 -0
- package/dist/types/config.d.ts +54 -0
- package/dist/{hooks → types/hooks}/AfterEvaluationHook.d.ts +1 -1
- package/dist/{hooks → types/hooks}/AfterIdentifyHook.d.ts +1 -1
- package/dist/{hooks → types/hooks}/AfterTrackHook.d.ts +1 -1
- package/dist/{hooks → types/hooks}/EventStore.d.ts +1 -1
- package/dist/types/index.d.ts +5 -0
- package/dist/{plugins/EventInterceptionPlugin.d.ts → types/plugins/eventInterceptionPlugin.d.ts} +2 -2
- package/dist/{plugins/FlagOverridePlugin.d.ts → types/plugins/flagOverridePlugin.d.ts} +1 -1
- package/dist/types/plugins/index.d.ts +3 -0
- package/dist/types/{plugin.d.ts → plugins/plugins.d.ts} +1 -4
- package/dist/types/position.d.ts +2 -0
- package/package.json +55 -45
- package/LICENSE +0 -13
- package/dist/plugins/index.d.ts +0 -4
- package/dist/tests/DevServerProvider.test.d.ts +0 -1
- package/dist/tests/ExpandedToolbarContent.test.d.ts +0 -1
- package/dist/tests/FlagSdkOverrideProvider.test.d.ts +0 -1
- package/dist/tests/LaunchDarklyToolbar.test.d.ts +0 -1
- package/dist/tests/Tabs.test.d.ts +0 -1
- package/dist/tests/hooks/AfterEvaluationHook.test.d.ts +0 -1
- package/dist/tests/hooks/AfterIdentifyHook.test.d.ts +0 -1
- package/dist/tests/hooks/AfterTrackHook.test.d.ts +0 -1
- package/dist/tests/hooks/EventStore.test.d.ts +0 -1
- package/dist/tests/plugins/EventInterceptionPlugin.test.d.ts +0 -1
- package/dist/ui/Toolbar/TabContent/FlagDevServerTabContent.d.ts +0 -1
- package/dist/vendor/launchpad/Button.d.ts +0 -19
- package/dist/vendor/launchpad/Group.d.ts +0 -11
- package/dist/vendor/launchpad/Input.d.ts +0 -15
- package/dist/vendor/launchpad/ListBox.d.ts +0 -15
- package/dist/vendor/launchpad/Popover.d.ts +0 -13
- package/dist/vendor/launchpad/SearchField.d.ts +0 -10
- package/dist/vendor/launchpad/Select.d.ts +0 -16
- package/dist/vendor/launchpad/Switch.d.ts +0 -10
- package/dist/vendor/launchpad/TextField.d.ts +0 -10
- package/dist/vendor/launchpad/index.d.ts +0 -18
- package/dist/vendor/launchpad/utils.d.ts +0 -4
- /package/dist/{services → core/services}/DevServerClient.d.ts +0 -0
- /package/dist/{services → core/services}/FlagStateManager.d.ts +0 -0
- /package/dist/{tests → core/tests}/mocks/flags.d.ts +0 -0
- /package/dist/{types → core/types}/devServer.d.ts +0 -0
- /package/dist/{ui → core/ui}/List/List.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/List/List.d.ts +0 -0
- /package/dist/{ui → core/ui}/List/ListItem.d.ts +0 -0
- /package/dist/{ui → core/ui}/Tabs/TabButton.d.ts +0 -0
- /package/dist/{ui → core/ui}/Tabs/Tabs.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/Tabs/Tabs.d.ts +0 -0
- /package/dist/{ui → core/ui}/Tabs/useTabsContext.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/Header/Header.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/Header/Header.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/Header/components/ActionButtons.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/Header/components/EnvironmentLabel.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/Header/components/LogoSection.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/Header/components/SearchSection.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/Header/components/index.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/LaunchDarklyToolbar.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/TabContent/EventsTabContent.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/TabContent/FlagDevServerTabContent.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/ActionButtonsContainer.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/ActionButtonsContainer.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/CircleLogo.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/ConnectionStatus.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/ConnectionStatus.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/DoNotTrackWarning.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/DoNotTrackWarning.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/ErrorMessage.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/ErrorMessage.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/FlagControls.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/FlagControls.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/GenericHelpText.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/GenericHelpText.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/IconButton.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/IconButton.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/IconLinkButton.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/LocalFlagControls.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/LocalFlagControls.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/OverrideIndicator.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/OverrideIndicator.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/Popover.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/StatusDot.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/StatusDot.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/icons/AddIcon.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/icons/ArrowUndoIcon.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/icons/CancelCircleIcon.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/icons/CheckIcon.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/icons/ChevronDownIcon.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/icons/ChevronUpIcon.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/icons/DeleteIcon.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/icons/EditIcon.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/icons/GearIcon.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/icons/Icon.css.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/icons/LaunchDarklyIcon.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/icons/LaunchDarklyLogo.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/icons/SearchIcon.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/icons/SyncIcon.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/icons/ToggleOffIcon.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/icons/XIcon.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/icons/index.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/components/index.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/constants/animations.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/constants/index.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/constants/virtualization.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/context/AnalyticsProvider.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/context/DevServerProvider.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/context/SearchProvider.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/context/ToolbarUIProvider.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/context/index.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/hooks/index.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/hooks/useCurrentDate.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/hooks/useToolbarAnimations.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/hooks/useToolbarDrag.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/hooks/useToolbarVisibility.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/types/index.d.ts +0 -0
- /package/dist/{ui → core/ui}/Toolbar/types/toolbar.d.ts +0 -0
- /package/dist/{ui → core/ui}/constants/zIndex.d.ts +0 -0
- /package/dist/{utils → core/utils}/browser.d.ts +0 -0
- /package/dist/{utils → core/utils}/deepEqual.d.ts +0 -0
- /package/dist/{utils → core/utils}/index.d.ts +0 -0
- /package/dist/{hooks → types/hooks}/index.d.ts +0 -0
package/README.md
CHANGED
|
@@ -1,238 +1,353 @@
|
|
|
1
1
|
# LaunchDarkly Toolbar
|
|
2
2
|
|
|
3
|
-
A React component that provides
|
|
3
|
+
A developer-friendly React component that provides real-time feature flag management and debugging capabilities during development. The toolbar integrates seamlessly with LaunchDarkly, allowing developers to inspect, override, and test feature flags without leaving their application.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🎯 **Dual Mode Operation**: Works with both LaunchDarkly Dev Server and SDK
|
|
8
|
+
- 🔄 **Real-time Flag Management**: View and toggle feature flags instantly
|
|
9
|
+
- 🎨 **Shadow DOM Isolation**: Zero CSS conflicts with your application
|
|
10
|
+
- 📍 **Flexible Positioning**: Place toolbar in any corner of your screen
|
|
11
|
+
- 🔌 **Plugin System**: Extend functionality with custom plugins
|
|
12
|
+
- 📊 **Event Monitoring**: Track and inspect LaunchDarkly events
|
|
13
|
+
- 🔍 **Search & Filter**: Quickly find flags in large projects
|
|
14
|
+
- ⚡ **Hot Reload Support**: Automatically reflects flag changes
|
|
7
15
|
|
|
8
16
|
## Installation
|
|
9
17
|
|
|
10
18
|
```bash
|
|
11
|
-
|
|
12
|
-
|
|
19
|
+
npm install @launchdarkly/toolbar
|
|
20
|
+
# or
|
|
21
|
+
pnpm add @launchdarkly/toolbar
|
|
22
|
+
# or
|
|
23
|
+
yarn add @launchdarkly/toolbar
|
|
24
|
+
```
|
|
13
25
|
|
|
14
|
-
|
|
15
|
-
yarn add @launchdarkly/toolbar@next
|
|
26
|
+
## Usage
|
|
16
27
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
```
|
|
28
|
+
The Developer Toolbar is intended for use during local development. As such, you should ensure that the way you are
|
|
29
|
+
instantiating it will keep it disabled in production environments.
|
|
20
30
|
|
|
21
|
-
|
|
31
|
+
The Developer Toolbar depends on your LaunchDarkly JS client having a reference to the same `FlagOverridePlugin` and
|
|
32
|
+
`EventInterceptionPlugin` that you pass into the Developer Toolbar. As such, ensure that you instantiate the Developer Toolbar at the same time or immediately after the LaunchDarkly JS client is instantiated.
|
|
33
|
+
Below are a few examples on how to instantiate the toolbar, one using the `useLaunchDarklyToolbar` react hook, and one using the CDN hosted toolbar script.
|
|
22
34
|
|
|
23
|
-
|
|
35
|
+
### React Hook (Recommended for React developers)
|
|
24
36
|
|
|
25
37
|
```tsx
|
|
26
|
-
import {
|
|
38
|
+
import { render } from 'react-dom';
|
|
27
39
|
import { asyncWithLDProvider } from 'launchdarkly-react-client-sdk';
|
|
28
|
-
import {
|
|
40
|
+
import { useLaunchDarklyToolbar, FlagOverridePlugin, EventInterceptionPlugin } from '@launchdarkly/toolbar';
|
|
29
41
|
|
|
30
|
-
// Create the plugin instances
|
|
31
42
|
const flagOverridePlugin = new FlagOverridePlugin();
|
|
32
43
|
const eventInterceptionPlugin = new EventInterceptionPlugin();
|
|
33
44
|
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
45
|
+
(async () => {
|
|
46
|
+
const LDProvider = await asyncWithLDProvider({
|
|
47
|
+
clientSideID: 'client-side-id-123abc',
|
|
48
|
+
context: {
|
|
49
|
+
kind: 'user',
|
|
50
|
+
key: 'user-key-123abc',
|
|
51
|
+
name: 'Sandy Smith',
|
|
52
|
+
email: 'sandy@example.com',
|
|
53
|
+
},
|
|
54
|
+
options: {
|
|
55
|
+
plugins: [
|
|
56
|
+
flagOverridePlugin,
|
|
57
|
+
eventInterceptionPlugin,
|
|
58
|
+
// other plugins...
|
|
59
|
+
],
|
|
60
|
+
// other options...
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
function App() {
|
|
65
|
+
// Initialize toolbar with the same plugin instances
|
|
66
|
+
useLaunchDarklyToolbar({
|
|
67
|
+
flagOverridePlugin, // For flag overrides (SDK Mode only)
|
|
68
|
+
eventInterceptionPlugin, // For event monitoring (works in both modes)
|
|
69
|
+
|
|
70
|
+
// OR Dev Server Mode: Connect to LaunchDarkly dev server
|
|
71
|
+
devServerUrl: 'http://localhost:8080',
|
|
72
|
+
projectKey: 'my-project', // Optional: auto-detects if not provided
|
|
73
|
+
|
|
74
|
+
// Common options
|
|
75
|
+
position: 'bottom-right',
|
|
76
|
+
enabled: process.env.NODE_ENV === 'development',
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
return <YourApp />;
|
|
55
80
|
}
|
|
56
81
|
|
|
57
|
-
|
|
82
|
+
render(
|
|
58
83
|
<LDProvider>
|
|
59
|
-
<
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
<LaunchDarklyToolbar
|
|
63
|
-
flagOverridePlugin={flagOverridePlugin}
|
|
64
|
-
eventInterceptionPlugin={eventInterceptionPlugin}
|
|
65
|
-
/>
|
|
66
|
-
</div>
|
|
67
|
-
</LDProvider>
|
|
84
|
+
<App />
|
|
85
|
+
</LDProvider>,
|
|
86
|
+
document.getElementById('root'),
|
|
68
87
|
);
|
|
69
|
-
}
|
|
88
|
+
})();
|
|
70
89
|
```
|
|
71
90
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
```tsx
|
|
75
|
-
import { LaunchDarklyToolbar } from '@launchdarkly/toolbar';
|
|
76
|
-
|
|
77
|
-
function App() {
|
|
78
|
-
return (
|
|
79
|
-
<div>
|
|
80
|
-
<h1>My App</h1>
|
|
81
|
-
<LaunchDarklyToolbar devServerUrl="http://localhost:8765" />
|
|
82
|
-
</div>
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
```
|
|
91
|
+
### CDN Script Tag
|
|
86
92
|
|
|
87
|
-
|
|
93
|
+
Add this script to your `index.html` file.
|
|
88
94
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
| `eventInterceptionPlugin` | `IEventInterceptionPlugin` | `undefined` | Event interception plugin for SDK Mode. Enables Events tab functionality |
|
|
93
|
-
| `devServerUrl` | `string` (optional) | `undefined` | URL of your LaunchDarkly dev server. If provided, enables Dev Server Mode |
|
|
94
|
-
| `position` | `"bottom-left" \| "bottom-right" \| "top-left" \| "top-right"` | `"bottom-right"` | Corner position of the toolbar |
|
|
95
|
-
| `projectKey` | `string` (optional) | `undefined` | Optional project key for multi-project setups (Dev Server Mode only) |
|
|
96
|
-
| `pollIntervalInMs` | `number` (optional) | `5000` | Polling interval for dev server updates (Dev Server Mode only) |
|
|
95
|
+
```html
|
|
96
|
+
<script src="https://unpkg.com/@launchdarkly/toolbar@latest/cdn/toolbar.min.js"></script>
|
|
97
|
+
```
|
|
97
98
|
|
|
98
|
-
|
|
99
|
+
In your corresponding code, wherever you instantiate your LaunchDarkly JS client, be sure to pass in the following plugins:
|
|
99
100
|
|
|
100
|
-
|
|
101
|
+
```typescript
|
|
102
|
+
import * as LDClient from 'launchdarkly-js-client-sdk';
|
|
103
|
+
import { FlagOverridePlugin, EventInterceptionPlugin } from '@launchdarkly/toolbar';
|
|
101
104
|
|
|
102
|
-
|
|
105
|
+
const flagOverridePlugin = new FlagOverridePlugin();
|
|
106
|
+
const eventInterceptionPlugin = new EventInterceptionPlugin();
|
|
103
107
|
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
const context: LDClient.LDContext = {
|
|
109
|
+
kind: 'user',
|
|
110
|
+
key: 'context-key-123abc',
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const client = LDClient.initialize('client-side-id-123abc', context, {
|
|
114
|
+
plugins: [
|
|
115
|
+
// any other plugins you might want
|
|
116
|
+
flagOverridePlugin,
|
|
117
|
+
eventInterceptionPlugin,
|
|
118
|
+
],
|
|
119
|
+
});
|
|
106
120
|
|
|
107
|
-
|
|
121
|
+
try {
|
|
122
|
+
await client.waitForInitialization(5);
|
|
123
|
+
// initialization succeeded, flag values are now available
|
|
124
|
+
handleInitializedClient(client);
|
|
125
|
+
} catch (err) {
|
|
126
|
+
// initialization failed or did not complete before timeout
|
|
127
|
+
}
|
|
108
128
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
129
|
+
if (process.env.NODE_ENV === 'development' && window.LaunchDarklyToolbar) {
|
|
130
|
+
window.LaunchDarklyToolbar.init({
|
|
131
|
+
flagOverridePlugin,
|
|
132
|
+
eventInterceptionPlugin,
|
|
133
|
+
position: 'bottom-right',
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
```
|
|
113
137
|
|
|
114
|
-
|
|
138
|
+
Note: if you are using typescript and want type safety for the `window.LaunchDarklyToolbar.init` call,
|
|
139
|
+
you can add a `window.d.ts` file to your application with the following:
|
|
115
140
|
|
|
116
|
-
|
|
141
|
+
```typescript
|
|
142
|
+
import type { LaunchDarklyToolbar } from '@launchdarkly/toolbar';
|
|
117
143
|
|
|
118
|
-
|
|
144
|
+
declare global {
|
|
145
|
+
interface Window {
|
|
146
|
+
LaunchDarklyToolbar?: LaunchDarklyToolbar;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
119
150
|
|
|
120
|
-
|
|
121
|
-
- Test different flag variations instantly
|
|
122
|
-
- Work offline or with any LaunchDarkly environment
|
|
123
|
-
- Maintain full type safety with your existing SDK setup
|
|
151
|
+
## Package Structure
|
|
124
152
|
|
|
125
|
-
|
|
153
|
+
```
|
|
154
|
+
@launchdarkly/toolbar/
|
|
155
|
+
├── src/
|
|
156
|
+
│ ├── core/ # Framework-agnostic toolbar implementation
|
|
157
|
+
│ │ ├── context/ # React context providers
|
|
158
|
+
│ │ ├── services/ # Business logic (DevServerClient, FlagStateManager)
|
|
159
|
+
│ │ ├── ui/ # UI components (Toolbar, Tabs, List, etc.)
|
|
160
|
+
│ │ ├── tests/ # Unit tests
|
|
161
|
+
│ │ └── index.ts # Core entry point (for CDN builds)
|
|
162
|
+
│ ├── react/ # React-specific integrations and utilities
|
|
163
|
+
│ │ ├── useLaunchDarklyToolbar.ts # Main React hook
|
|
164
|
+
│ │ └── lazyLoadToolbar.ts # Dynamic CDN loading
|
|
165
|
+
│ ├── types/ # TypeScript type definitions
|
|
166
|
+
│ │ ├── config.ts # Configuration types
|
|
167
|
+
│ │ ├── events.ts # Event types
|
|
168
|
+
│ │ ├── plugins.ts # Plugin interfaces
|
|
169
|
+
│ │ └── index.ts # Type exports
|
|
170
|
+
│ └── index.ts # Main entry point (NPM package)
|
|
171
|
+
├── dist/ # NPM package output
|
|
172
|
+
│ ├── index.js # ES module build
|
|
173
|
+
│ ├── index.cjs # CommonJS build
|
|
174
|
+
│ └── index.d.ts # TypeScript definitions
|
|
175
|
+
├── cdn/ # CDN bundle output
|
|
176
|
+
│ └── toolbar.min.js # IIFE bundle for script tags
|
|
177
|
+
├── .storybook/ # Storybook configuration
|
|
178
|
+
└── stories/ # Component documentation
|
|
179
|
+
```
|
|
126
180
|
|
|
127
|
-
|
|
128
|
-
2. Pass the plugin to your LaunchDarkly SDK's `plugins` array
|
|
129
|
-
3. Pass the same plugin instance to the toolbar component
|
|
130
|
-
4. Wrap your app with the LaunchDarkly provider
|
|
181
|
+
## Configuration Options
|
|
131
182
|
|
|
132
|
-
|
|
133
|
-
import { useEffect, useState } from 'react';
|
|
134
|
-
import { asyncWithLDProvider } from 'launchdarkly-react-client-sdk';
|
|
135
|
-
import { LaunchDarklyToolbar, FlagOverridePlugin } from '@launchdarkly/toolbar';
|
|
183
|
+
### Common Options
|
|
136
184
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
185
|
+
```typescript
|
|
186
|
+
interface ToolbarConfig {
|
|
187
|
+
// LaunchDarkly configuration
|
|
188
|
+
baseUrl?: string; // LaunchDarkly API base URL
|
|
189
|
+
projectKey?: string; // Project key (auto-detected if not provided)
|
|
141
190
|
|
|
142
|
-
|
|
143
|
-
|
|
191
|
+
// Dev Server Mode
|
|
192
|
+
devServerUrl?: string; // URL to LaunchDarkly dev server
|
|
144
193
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
clientSideID: 'your-client-side-id',
|
|
149
|
-
context: { key: 'user-key', name: 'User Name' },
|
|
150
|
-
options: {
|
|
151
|
-
plugins: [flagOverridePlugin], // Add plugin to SDK
|
|
152
|
-
},
|
|
153
|
-
});
|
|
154
|
-
setLDProvider(() => Provider);
|
|
155
|
-
};
|
|
194
|
+
// SDK Mode Plugins
|
|
195
|
+
flagOverridePlugin?: IFlagOverridePlugin; // Enable flag overrides
|
|
196
|
+
eventInterceptionPlugin?: IEventInterceptionPlugin; // Monitor events
|
|
156
197
|
|
|
157
|
-
|
|
158
|
-
|
|
198
|
+
// UI Configuration
|
|
199
|
+
position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
200
|
+
pollIntervalInMs?: number; // Polling interval (default: 1000ms)
|
|
201
|
+
}
|
|
202
|
+
```
|
|
159
203
|
|
|
160
|
-
|
|
204
|
+
### React Hook Options
|
|
161
205
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
</LDProvider>
|
|
167
|
-
);
|
|
206
|
+
```typescript
|
|
207
|
+
interface UseLaunchDarklyToolbarConfig extends ToolbarConfig {
|
|
208
|
+
toolbarBundleUrl?: string; // Custom CDN URL for local development
|
|
209
|
+
enabled?: boolean; // Toggle toolbar on/off (default: true)
|
|
168
210
|
}
|
|
169
211
|
```
|
|
170
212
|
|
|
171
|
-
|
|
213
|
+
## Modes
|
|
172
214
|
|
|
173
|
-
|
|
215
|
+
### Dev Server Mode
|
|
216
|
+
|
|
217
|
+
Connect directly to a LaunchDarkly dev server to manage server-side flags:
|
|
174
218
|
|
|
175
219
|
```tsx
|
|
176
|
-
|
|
220
|
+
useLaunchDarklyToolbar({
|
|
221
|
+
devServerUrl: 'http://localhost:8080',
|
|
222
|
+
projectKey: 'my-project', // Optional
|
|
223
|
+
position: 'bottom-right',
|
|
224
|
+
});
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
or if you are using the CDN script:
|
|
177
228
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
229
|
+
```typescript
|
|
230
|
+
window.LaunchDarklyToolbar.init({
|
|
231
|
+
devServerUrl: 'http://localhost:8080',
|
|
232
|
+
projectKey: 'my-project', // Optional
|
|
233
|
+
position: 'bottom-right',
|
|
182
234
|
});
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Features:**
|
|
238
|
+
|
|
239
|
+
- View all flags from your LaunchDarkly project
|
|
240
|
+
- Set flag overrides that persist in dev server
|
|
241
|
+
- Changes visible to all connected clients
|
|
242
|
+
- Ideal for backend/full-stack development
|
|
243
|
+
|
|
244
|
+
### SDK Mode
|
|
245
|
+
|
|
246
|
+
Integrate with LaunchDarkly React SDK for client-side flag management:
|
|
247
|
+
|
|
248
|
+
```tsx
|
|
249
|
+
import { useFlagOverridePlugin, useEventInterceptionPlugin } from './plugins';
|
|
183
250
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
plugins: [flagOverridePlugin, eventInterceptionPlugin],
|
|
189
|
-
},
|
|
251
|
+
useLaunchDarklyToolbar({
|
|
252
|
+
flagOverridePlugin: useFlagOverridePlugin(),
|
|
253
|
+
eventInterceptionPlugin: useEventInterceptionPlugin(),
|
|
254
|
+
position: 'bottom-right',
|
|
190
255
|
});
|
|
256
|
+
```
|
|
191
257
|
|
|
192
|
-
|
|
193
|
-
|
|
258
|
+
or if you are using the CDN script:
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
window.LaunchDarklyToolbar.init({
|
|
262
|
+
flagOverridePlugin: new FlagOverridePlugin(),
|
|
263
|
+
eventInterceptionPlugin: new EventInterceptionPlugin(),
|
|
264
|
+
position: 'bottom-right',
|
|
265
|
+
});
|
|
194
266
|
```
|
|
195
267
|
|
|
196
|
-
|
|
268
|
+
**Features:**
|
|
197
269
|
|
|
198
|
-
|
|
270
|
+
- Local flag overrides (client-side only)
|
|
271
|
+
- Event monitoring and inspection
|
|
272
|
+
- No dev server required
|
|
273
|
+
- Ideal for frontend development
|
|
199
274
|
|
|
200
|
-
|
|
201
|
-
|
|
275
|
+
## Plugin System
|
|
276
|
+
|
|
277
|
+
### Flag Override Plugin
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
interface IFlagOverridePlugin {
|
|
281
|
+
getAllFlags(): Record<string, any>;
|
|
282
|
+
setOverride(flagKey: string, value: any): void;
|
|
283
|
+
clearOverride(flagKey: string): void;
|
|
284
|
+
clearAllOverrides(): void;
|
|
285
|
+
onFlagsChange(callback: (flags: Record<string, any>) => void): () => void;
|
|
286
|
+
}
|
|
202
287
|
```
|
|
203
288
|
|
|
204
|
-
|
|
289
|
+
### Event Interception Plugin
|
|
205
290
|
|
|
206
|
-
```
|
|
207
|
-
|
|
291
|
+
```typescript
|
|
292
|
+
interface IEventInterceptionPlugin {
|
|
293
|
+
getEvents(): ProcessedEvent[];
|
|
294
|
+
clearEvents(): void;
|
|
295
|
+
onEvent(callback: (event: ProcessedEvent) => void): () => void;
|
|
296
|
+
}
|
|
208
297
|
```
|
|
209
298
|
|
|
210
|
-
##
|
|
299
|
+
## Development
|
|
300
|
+
|
|
301
|
+
### Building
|
|
211
302
|
|
|
212
|
-
|
|
303
|
+
```bash
|
|
304
|
+
# Build both NPM and CDN outputs
|
|
305
|
+
pnpm build
|
|
213
306
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
window.ldToolbar.toggle();
|
|
307
|
+
# Build only NPM package
|
|
308
|
+
pnpm build:lib
|
|
217
309
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
window.ldToolbar.disable();
|
|
310
|
+
# Build only CDN bundle
|
|
311
|
+
pnpm build:cdn
|
|
221
312
|
|
|
222
|
-
|
|
223
|
-
|
|
313
|
+
# Watch mode for development
|
|
314
|
+
pnpm dev
|
|
224
315
|
```
|
|
225
316
|
|
|
226
|
-
|
|
317
|
+
### Testing
|
|
227
318
|
|
|
228
|
-
|
|
319
|
+
```bash
|
|
320
|
+
# Run unit tests
|
|
321
|
+
pnpm test
|
|
229
322
|
|
|
230
|
-
|
|
323
|
+
# Run tests in watch mode
|
|
324
|
+
pnpm test:watch
|
|
325
|
+
```
|
|
231
326
|
|
|
232
|
-
|
|
233
|
-
|
|
327
|
+
### Storybook
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
# Start Storybook dev server
|
|
331
|
+
pnpm storybook
|
|
332
|
+
|
|
333
|
+
# Build Storybook for deployment
|
|
334
|
+
pnpm build:storybook
|
|
234
335
|
```
|
|
235
336
|
|
|
236
|
-
|
|
337
|
+
## Browser Support
|
|
338
|
+
|
|
339
|
+
- Chrome 90+
|
|
340
|
+
- Firefox 88+
|
|
341
|
+
- Safari 14+
|
|
342
|
+
- Edge 90+
|
|
343
|
+
|
|
344
|
+
## License
|
|
345
|
+
|
|
346
|
+
Apache-2.0
|
|
347
|
+
|
|
348
|
+
## Links
|
|
237
349
|
|
|
238
|
-
|
|
350
|
+
- [Documentation](https://launchdarkly.com/docs/home/getting-started/dev-toolbar)
|
|
351
|
+
- [GitHub Repository](https://github.com/launchdarkly/launchdarkly-toolbar)
|
|
352
|
+
- [npm Package](https://www.npmjs.com/package/@launchdarkly/toolbar)
|
|
353
|
+
- [Issue Tracker](https://github.com/launchdarkly/launchdarkly-toolbar/issues)
|