@servicetitan/docs-uikit 28.2.0 → 28.3.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/docs/launchdarkly-service.mdx +201 -7
- package/package.json +2 -2
|
@@ -9,7 +9,7 @@ each with its own set of feature flags and client-side IDs that authorize connec
|
|
|
9
9
|
|
|
10
10
|
LaunchDarkly's SDKs require applications to create a separate client connection to the LaunchDarkly backend for each project.
|
|
11
11
|
However, if applications and MFEs create multiple, independent connections to the same LaunchDarkly project, it can degrade performance
|
|
12
|
-
and cause the
|
|
12
|
+
and cause the UI to behave inconsistently. It also harms performance to teardown and recreate connections each time an
|
|
13
13
|
MFE is unloaded and reloaded.
|
|
14
14
|
|
|
15
15
|
To prevent these issues **@servicetitan/launchdarkly-service** implements a coordinated approach for creating
|
|
@@ -29,7 +29,8 @@ Instead of using **LDProvider**, **withLDProvider** or **withAsyncLDProvider** f
|
|
|
29
29
|
### LDProvider
|
|
30
30
|
|
|
31
31
|
`LDProvider` provides LaunchDarkly feature flags within hosts and MFEs.
|
|
32
|
-
It ensures that hosts and MFEs share one client connection to each LaunchDarkly project (as identified by the client-side ID)
|
|
32
|
+
It ensures that hosts and MFEs share one client connection to each LaunchDarkly project (as identified by the client-side ID)
|
|
33
|
+
and automatically [provides a store](#use-flags-in-mobx-store) that allows flag values to be used in MobX stores.
|
|
33
34
|
|
|
34
35
|
#### Props
|
|
35
36
|
|
|
@@ -47,11 +48,9 @@ This is typically only a problem when different code paths call `LDProvider` wit
|
|
|
47
48
|
If that isn't practical, you can use [`getContext`](https://launchdarkly.github.io/js-client-sdk/interfaces/LDClient.html#getContext) and [`identify`](https://launchdarkly.github.io/js-client-sdk/interfaces/LDClient.html#identify) to fetch and amend the active context.
|
|
48
49
|
:::
|
|
49
50
|
|
|
50
|
-
:::
|
|
51
|
-
When `waitForInitialization` is set to false,
|
|
52
|
-
|
|
53
|
-
If this is a problem, you can [subscribe to flag changes](https://docs.launchdarkly.com/sdk/features/flag-changes)
|
|
54
|
-
and manually trigger updates.
|
|
51
|
+
:::note
|
|
52
|
+
When `waitForInitialization` is set to false, `LDProvider` renders children immediately, possibly with no flag values,
|
|
53
|
+
then automatically re-renders when the flags become available.
|
|
55
54
|
:::
|
|
56
55
|
|
|
57
56
|
#### Examples
|
|
@@ -140,3 +139,198 @@ export const HostApp: FC = () => {
|
|
|
140
139
|
);
|
|
141
140
|
};
|
|
142
141
|
```
|
|
142
|
+
|
|
143
|
+
### FeatureFlagStore
|
|
144
|
+
|
|
145
|
+
`LDProvider` automatically provides a `FeatureFlagStore` that allows you to access
|
|
146
|
+
feature flags in MobX stores.
|
|
147
|
+
To use [@inject](./react-ioc#inject) where needed.
|
|
148
|
+
|
|
149
|
+
#### Props
|
|
150
|
+
|
|
151
|
+
| Name | Type | Description |
|
|
152
|
+
| :------ | :---------- | :------------------------------ |
|
|
153
|
+
| `flags` | `LDFlagSet` | The LaunchDarkly feature flags. |
|
|
154
|
+
|
|
155
|
+
#### Example
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
import { FeatureFlagStore } from '@servicetitan/launchdarkly-service';
|
|
159
|
+
|
|
160
|
+
class ConsumerStore {
|
|
161
|
+
constructor(@inject(FeatureFlagStore) private readonly featureFlagStore: FeatureFlagStore) {
|
|
162
|
+
// this.featureFlagStore.flags contains feature flags
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### WithFeatureFlag
|
|
168
|
+
|
|
169
|
+
`WithFeatureFlag` conditionally renders content depending on the value of a feature flag.
|
|
170
|
+
|
|
171
|
+
#### Props
|
|
172
|
+
|
|
173
|
+
| Name | Type | Description |
|
|
174
|
+
| :-------- | :-------------------- | :---------------------------------------------------------------------------------------------------------------------------------- |
|
|
175
|
+
| `flagKey` | `string` | The feature flag's key. To type check `flagKey`, pass a type argument that defines the flag set (see [below](#type-check-flag-key)) |
|
|
176
|
+
| `on` | `React.ComponentType` | (Optional) Component to render when the flag is turned on. Defaults to `children` prop. |
|
|
177
|
+
| `off` | `React.ComponentType` | (Optional) Component to render when the flag is turned off. Defaults to `null`. |
|
|
178
|
+
| `value` | `LDFlagValue` | (Optional) Flag value that indicates the flag is turned on. Defaults to treating any truthy value as "on". |
|
|
179
|
+
|
|
180
|
+
#### Examples
|
|
181
|
+
|
|
182
|
+
Render children when flag is turned on:
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
<WithFeatureFlag flagKey={flagKey}>
|
|
186
|
+
<Text>Flag is ON</Text>
|
|
187
|
+
</WithFeatureFlag>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Render children when flag has specific value:
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
<WithFeatureFlag flagKey={flagKey} value={false}>
|
|
194
|
+
<Text>Flag is false</Text>
|
|
195
|
+
</WithFeatureFlag>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Render children when flag is on, and render other component when flag is turned off:
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
<WithFeatureFlag flagKey={flagKey} off={ComponentV1}>
|
|
202
|
+
<ComponentV2 />
|
|
203
|
+
</WithFeatureFlag>
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Render component when flag is on, and render other component when flag is turned off:
|
|
207
|
+
|
|
208
|
+
```tsx
|
|
209
|
+
<WithFeatureFlag flagKey={flagKey} on={ComponentV2} off={ComponentV1} />
|
|
210
|
+
|
|
211
|
+
<WithFeatureFlag flagKey={flagKey} on={() => 'Flag is ON'} off={() => 'Flag is OFF'} />
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Examples
|
|
215
|
+
|
|
216
|
+
### Using flag values in React component
|
|
217
|
+
|
|
218
|
+
Use the `useFlags` hook from the LaunchDarkly React SDK to access flags in React components. E.g.,
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
import { useFlags } from 'launchdarkly-react-client-sdk';
|
|
222
|
+
|
|
223
|
+
export const Component: FC = () => {
|
|
224
|
+
const { enableRedesign } = useFlags();
|
|
225
|
+
return enableRedesign ? <NewDesign /> : <OldDesign />;
|
|
226
|
+
};
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Or, use this package's [WithFeatureFlag](#withfeatureflag) helper:
|
|
230
|
+
|
|
231
|
+
```tsx
|
|
232
|
+
import { WithFeatureFlag } from '@servicetitan/launchdarkly-service';
|
|
233
|
+
|
|
234
|
+
export const Component: FC = () => (
|
|
235
|
+
<WithFeatureFlag flagKey="enableRedesign" on={NewDesign} off={OldDesign} />
|
|
236
|
+
);
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Using flag values in MobX store {#use-flags-in-mobx-store}
|
|
240
|
+
|
|
241
|
+
To use flag values in MobX stores, inject the [FeatureFlagStore](#featureflagstore) provided by `LDProvider`.
|
|
242
|
+
For example,
|
|
243
|
+
|
|
244
|
+
```tsx
|
|
245
|
+
import { FeatureFlagStore } from '@servicetitan/launchdarkly-service';
|
|
246
|
+
|
|
247
|
+
@injectable()
|
|
248
|
+
export class DataStore extends Store {
|
|
249
|
+
constructor(@inject(FeatureFlagStore) private readonly featureFlagStore: FeatureFlagStore) {
|
|
250
|
+
// Use this.featureFlagStore.flags to access feature flags
|
|
251
|
+
if (this.featureFlagStore.flags.enableDataV2) {
|
|
252
|
+
this.initializeDataV2();
|
|
253
|
+
} else {
|
|
254
|
+
this.initializeData();
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Type checking WithFeatureFlag key {#type-check-flag-key}
|
|
261
|
+
|
|
262
|
+
To type check the `flagKey` passed to `WithFeatureFlag`, pass a type argument that defines the flag set.
|
|
263
|
+
For example,
|
|
264
|
+
|
|
265
|
+
```tsx title='fleet-flag-set.ts'
|
|
266
|
+
export interface FleetFlagSet {
|
|
267
|
+
enablePermissions: boolean;
|
|
268
|
+
enableBreadcrumbPage: boolean;
|
|
269
|
+
enableAlertsRedesign: boolean;
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
```tsx
|
|
274
|
+
<WithFeatureFlag<FleetFlagSet> flagKey={flagKey} /> // Enforces that flagKey is in FleetFlagSet
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Or, create a custom wrapper that does this automatically. For example,
|
|
278
|
+
|
|
279
|
+
```tsx title='with-fleet-feature-flag.tsx'
|
|
280
|
+
import { WithFeatureFlag, WithFeatureFlagProps } from '@servicetitan/launchdarkly-service';
|
|
281
|
+
import { FleetFlagSet } from './fleet-flag-set';
|
|
282
|
+
|
|
283
|
+
export const WithFleetFeatureFlag = <T extends keyof FleetFlagSet>(
|
|
284
|
+
props: WithFeatureFlagProps<FleetFlagSet, T>
|
|
285
|
+
) => <WithFeatureFlag<FleetFlagSet, T> {...props} />;
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
```tsx
|
|
289
|
+
<WithFleetFeatureFlag flagKey={flagKey} /> // Enforces that flagKey is in FleetFlagSet
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Type checking WithFeatureFlag value
|
|
293
|
+
|
|
294
|
+
To type check the `value` passed to `WithFeatureFlag`, use the `createFlagKeys` helper.
|
|
295
|
+
It returns an object with keys that enable type checking against the passed `value`. For example,
|
|
296
|
+
|
|
297
|
+
```tsx title='fleet-flag-set.ts'
|
|
298
|
+
import { createFlagKeys } from '@servicetitan/launchdarkly-service';
|
|
299
|
+
|
|
300
|
+
export interface FleetFlagSet {
|
|
301
|
+
enablePermissions: boolean;
|
|
302
|
+
enableBreadcrumbPage: boolean;
|
|
303
|
+
enableAlertsRedesign: boolean;
|
|
304
|
+
triStateFlag: 0 | 1 | 2; // flag has non-boolean value
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export const FleetFlagKeys = createFlagKeys<FleetFlagSet>( // generates type-aware keys
|
|
308
|
+
'enablePermissions',
|
|
309
|
+
'enableBreadcrumbPage',
|
|
310
|
+
'enableAlertsRedesign',
|
|
311
|
+
'triStateFlag'
|
|
312
|
+
);
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
```tsx
|
|
316
|
+
// Use generated key to enforce that value is correct type, in this case, 0, 1 or 2
|
|
317
|
+
<WithFeatureFlag flagKey={FleetFlagKeys.triStateFlag} value={2} />
|
|
318
|
+
|
|
319
|
+
// Use generated key to type check value passed to custom wrapper
|
|
320
|
+
<WithFleetFeatureFlag flagKey={FleetFlagKeys.triStateFlag} value={2} />
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Type checking FeatureFlagStore
|
|
324
|
+
|
|
325
|
+
To type check `FeatureFlagStore` keys, pass a type argument that defines the flag set.
|
|
326
|
+
For example,
|
|
327
|
+
|
|
328
|
+
```tsx title='consumer-store.ts'
|
|
329
|
+
class ConsumerStore {
|
|
330
|
+
constructor(
|
|
331
|
+
@inject(FeatureFlagStore)
|
|
332
|
+
// Establishes that type of this.featureFlagStore.flags is FleetFlagSet
|
|
333
|
+
private readonly featureFlagStore: FeatureFlagStore<FleetFlagSet>
|
|
334
|
+
) {}
|
|
335
|
+
}
|
|
336
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@servicetitan/docs-uikit",
|
|
3
|
-
"version": "28.
|
|
3
|
+
"version": "28.3.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -16,5 +16,5 @@
|
|
|
16
16
|
"cli": {
|
|
17
17
|
"webpack": false
|
|
18
18
|
},
|
|
19
|
-
"gitHead": "
|
|
19
|
+
"gitHead": "63ce3ca18966fc5522a3b61df5e4c55f82b4272e"
|
|
20
20
|
}
|