@servicetitan/launchdarkly-service 34.3.0 → 35.0.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/dist/tests/with-feature-flag.test.d.ts.map +1 -1
- package/dist/tests/with-feature-flag.test.js +19 -9
- package/dist/tests/with-feature-flag.test.js.map +1 -1
- package/dist/with-feature-flag.d.ts +4 -4
- package/dist/with-feature-flag.d.ts.map +1 -1
- package/dist/with-feature-flag.js +7 -4
- package/dist/with-feature-flag.js.map +1 -1
- package/package.json +8 -6
- package/src/tests/with-feature-flag.test.tsx +14 -7
- package/src/with-feature-flag.tsx +20 -15
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"with-feature-flag.test.d.ts","sourceRoot":"","sources":["../../src/tests/with-feature-flag.test.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"with-feature-flag.test.d.ts","sourceRoot":"","sources":["../../src/tests/with-feature-flag.test.tsx"],"names":[],"mappings":"AACA,OAAO,2BAA2B,CAAC"}
|
|
@@ -1,27 +1,37 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Provider } from '@servicetitan/react-ioc';
|
|
2
3
|
import '@testing-library/jest-dom';
|
|
3
4
|
import { render, screen } from '@testing-library/react';
|
|
4
|
-
import {
|
|
5
|
+
import { FeatureFlagStore } from '../feature-flag-store';
|
|
5
6
|
import { WithFeatureFlag } from '../with-feature-flag';
|
|
6
|
-
jest.mock('launchdarkly-react-client-sdk', ()=>({
|
|
7
|
-
useFlags: jest.fn()
|
|
8
|
-
}));
|
|
9
7
|
describe(`[launchdarkly-service] ${WithFeatureFlag.name}`, ()=>{
|
|
10
8
|
const flagKey = 'foo';
|
|
11
9
|
const childContent = 'Flag is ON';
|
|
12
10
|
let props;
|
|
13
11
|
let flagValue;
|
|
12
|
+
const mockFeatureFlagStore = {
|
|
13
|
+
get flags () {
|
|
14
|
+
return {
|
|
15
|
+
[flagKey]: flagValue
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
};
|
|
14
19
|
beforeEach(()=>{
|
|
15
20
|
props = {
|
|
16
21
|
flagKey,
|
|
17
22
|
children: childContent
|
|
18
23
|
};
|
|
19
|
-
jest.mocked(useFlags).mockImplementation(()=>({
|
|
20
|
-
[flagKey]: flagValue
|
|
21
|
-
}));
|
|
22
24
|
});
|
|
23
|
-
const subject = ()=>render(/*#__PURE__*/ _jsx(
|
|
24
|
-
|
|
25
|
+
const subject = ()=>render(/*#__PURE__*/ _jsx(Provider, {
|
|
26
|
+
singletons: [
|
|
27
|
+
{
|
|
28
|
+
provide: FeatureFlagStore,
|
|
29
|
+
useValue: mockFeatureFlagStore
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
children: /*#__PURE__*/ _jsx(WithFeatureFlag, {
|
|
33
|
+
...props
|
|
34
|
+
})
|
|
25
35
|
}));
|
|
26
36
|
function itRendersNothing() {
|
|
27
37
|
test('renders nothing', ()=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/tests/with-feature-flag.test.tsx"],"sourcesContent":["import '@testing-library/jest-dom';\nimport { render, screen } from '@testing-library/react';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/tests/with-feature-flag.test.tsx"],"sourcesContent":["import { Provider } from '@servicetitan/react-ioc';\nimport '@testing-library/jest-dom';\nimport { render, screen } from '@testing-library/react';\nimport type { LDFlagSet, LDFlagValue } from 'launchdarkly-react-client-sdk';\nimport { FeatureFlagStore } from '../feature-flag-store';\nimport { WithFeatureFlag } from '../with-feature-flag';\n\ndescribe(`[launchdarkly-service] ${WithFeatureFlag.name}`, () => {\n const flagKey = 'foo';\n const childContent = 'Flag is ON';\n let props: Parameters<typeof WithFeatureFlag>[0];\n let flagValue: LDFlagValue;\n const mockFeatureFlagStore = {\n get flags(): LDFlagSet {\n return { [flagKey]: flagValue };\n },\n };\n\n beforeEach(() => {\n props = { flagKey, children: childContent };\n });\n\n const subject = () =>\n render(\n <Provider singletons={[{ provide: FeatureFlagStore, useValue: mockFeatureFlagStore }]}>\n <WithFeatureFlag {...props} />\n </Provider>\n );\n\n function itRendersNothing() {\n test('renders nothing', () => {\n subject();\n\n expect(screen.queryByText(childContent)).not.toBeInTheDocument();\n });\n }\n\n function itRendersChildren() {\n test('renders children', () => {\n subject();\n\n expect(screen.getByText(childContent)).toBeInTheDocument();\n });\n }\n\n itRendersNothing();\n\n describe('when flag is turned on', () => {\n beforeEach(() => (flagValue = true));\n\n itRendersChildren();\n\n describe('with on prop', () => {\n const onContent = 'Flag is ENABLED';\n\n beforeEach(() => (props.on = () => onContent));\n\n test('renders on content', () => {\n subject();\n\n expect(screen.getByText(onContent)).toBeInTheDocument();\n });\n });\n });\n\n describe('when flag is turned off', () => {\n beforeEach(() => (flagValue = false));\n\n itRendersNothing();\n\n describe('with off prop', () => {\n const offContent = 'flag is OFF';\n\n beforeEach(() => (props.off = () => offContent));\n\n test('renders off content', () => {\n subject();\n\n expect(screen.getByText(offContent)).toBeInTheDocument();\n });\n });\n });\n\n describe('with flag value', () => {\n beforeEach(() => (props.value = 'bar'));\n\n itRendersNothing();\n\n describe('when flag matches value', () => {\n beforeEach(() => (flagValue = props.value));\n\n itRendersChildren();\n });\n });\n});\n"],"names":["Provider","render","screen","FeatureFlagStore","WithFeatureFlag","describe","name","flagKey","childContent","props","flagValue","mockFeatureFlagStore","flags","beforeEach","children","subject","singletons","provide","useValue","itRendersNothing","test","expect","queryByText","not","toBeInTheDocument","itRendersChildren","getByText","onContent","on","offContent","off","value"],"mappings":";AAAA,SAASA,QAAQ,QAAQ,0BAA0B;AACnD,OAAO,4BAA4B;AACnC,SAASC,MAAM,EAAEC,MAAM,QAAQ,yBAAyB;AAExD,SAASC,gBAAgB,QAAQ,wBAAwB;AACzD,SAASC,eAAe,QAAQ,uBAAuB;AAEvDC,SAAS,CAAC,uBAAuB,EAAED,gBAAgBE,IAAI,EAAE,EAAE;IACvD,MAAMC,UAAU;IAChB,MAAMC,eAAe;IACrB,IAAIC;IACJ,IAAIC;IACJ,MAAMC,uBAAuB;QACzB,IAAIC,SAAmB;YACnB,OAAO;gBAAE,CAACL,QAAQ,EAAEG;YAAU;QAClC;IACJ;IAEAG,WAAW;QACPJ,QAAQ;YAAEF;YAASO,UAAUN;QAAa;IAC9C;IAEA,MAAMO,UAAU,IACZd,qBACI,KAACD;YAASgB,YAAY;gBAAC;oBAAEC,SAASd;oBAAkBe,UAAUP;gBAAqB;aAAE;sBACjF,cAAA,KAACP;gBAAiB,GAAGK,KAAK;;;IAItC,SAASU;QACLC,KAAK,mBAAmB;YACpBL;YAEAM,OAAOnB,OAAOoB,WAAW,CAACd,eAAee,GAAG,CAACC,iBAAiB;QAClE;IACJ;IAEA,SAASC;QACLL,KAAK,oBAAoB;YACrBL;YAEAM,OAAOnB,OAAOwB,SAAS,CAAClB,eAAegB,iBAAiB;QAC5D;IACJ;IAEAL;IAEAd,SAAS,0BAA0B;QAC/BQ,WAAW,IAAOH,YAAY;QAE9Be;QAEApB,SAAS,gBAAgB;YACrB,MAAMsB,YAAY;YAElBd,WAAW,IAAOJ,MAAMmB,EAAE,GAAG,IAAMD;YAEnCP,KAAK,sBAAsB;gBACvBL;gBAEAM,OAAOnB,OAAOwB,SAAS,CAACC,YAAYH,iBAAiB;YACzD;QACJ;IACJ;IAEAnB,SAAS,2BAA2B;QAChCQ,WAAW,IAAOH,YAAY;QAE9BS;QAEAd,SAAS,iBAAiB;YACtB,MAAMwB,aAAa;YAEnBhB,WAAW,IAAOJ,MAAMqB,GAAG,GAAG,IAAMD;YAEpCT,KAAK,uBAAuB;gBACxBL;gBAEAM,OAAOnB,OAAOwB,SAAS,CAACG,aAAaL,iBAAiB;YAC1D;QACJ;IACJ;IAEAnB,SAAS,mBAAmB;QACxBQ,WAAW,IAAOJ,MAAMsB,KAAK,GAAG;QAEhCZ;QAEAd,SAAS,2BAA2B;YAChCQ,WAAW,IAAOH,YAAYD,MAAMsB,KAAK;YAEzCN;QACJ;IACJ;AACJ"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { LDFlagSet } from 'launchdarkly-js-client-sdk';
|
|
2
|
-
import { ComponentType, ReactNode } from 'react';
|
|
3
|
-
import { FlagKey } from './types';
|
|
1
|
+
import type { LDFlagSet } from 'launchdarkly-js-client-sdk';
|
|
2
|
+
import type { ComponentType, ReactNode } from 'react';
|
|
3
|
+
import type { FlagKey } from './types';
|
|
4
4
|
interface BaseProps<S extends LDFlagSet, T extends keyof S> {
|
|
5
5
|
flagKey: FlagKey<S, T>;
|
|
6
6
|
off?: ComponentType;
|
|
@@ -13,6 +13,6 @@ export type WithFeatureFlagProps<S extends LDFlagSet, T extends keyof S = keyof
|
|
|
13
13
|
on?: ComponentType;
|
|
14
14
|
children?: never;
|
|
15
15
|
});
|
|
16
|
-
export declare
|
|
16
|
+
export declare const WithFeatureFlag: <S extends LDFlagSet, T extends keyof S = keyof S>(props: WithFeatureFlagProps<S, T>) => ReactNode;
|
|
17
17
|
export {};
|
|
18
18
|
//# sourceMappingURL=with-feature-flag.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"with-feature-flag.d.ts","sourceRoot":"","sources":["../src/with-feature-flag.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"with-feature-flag.d.ts","sourceRoot":"","sources":["../src/with-feature-flag.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,UAAU,SAAS,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,MAAM,CAAC;IACtD,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACvB,GAAG,CAAC,EAAE,aAAa,CAAC;IACpB,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;CAChB;AAED,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,CAAC,IAC3E,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,EAAE,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,GACxD,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IAAE,EAAE,CAAC,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,CAAC;AAEnE,eAAO,MAAM,eAAe,GACvB,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,MAAM,CAAC,mBAC5B,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,KAClC,SAYN,CAAC"}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { useDependencies } from '@servicetitan/react-ioc';
|
|
3
|
+
import { observer } from 'mobx-react';
|
|
4
|
+
import { FeatureFlagStore } from './feature-flag-store';
|
|
5
|
+
export const WithFeatureFlag = observer((props)=>{
|
|
4
6
|
const { flagKey, value } = props;
|
|
5
|
-
const
|
|
7
|
+
const [{ flags }] = useDependencies(FeatureFlagStore);
|
|
8
|
+
const flagValue = flags[flagKey];
|
|
6
9
|
const isEnabled = value !== undefined ? flagValue === value : !!flagValue;
|
|
7
10
|
if (isEnabled) {
|
|
8
11
|
return props.on ? /*#__PURE__*/ _jsx(props.on, {}) : props.children;
|
|
9
12
|
}
|
|
10
13
|
return props.off ? /*#__PURE__*/ _jsx(props.off, {}) : null;
|
|
11
|
-
}
|
|
14
|
+
});
|
|
12
15
|
|
|
13
16
|
//# sourceMappingURL=with-feature-flag.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/with-feature-flag.tsx"],"sourcesContent":["import { LDFlagSet } from 'launchdarkly-js-client-sdk';\nimport {
|
|
1
|
+
{"version":3,"sources":["../src/with-feature-flag.tsx"],"sourcesContent":["import { useDependencies } from '@servicetitan/react-ioc';\nimport type { LDFlagSet } from 'launchdarkly-js-client-sdk';\nimport { observer } from 'mobx-react';\nimport type { ComponentType, ReactNode } from 'react';\nimport { FeatureFlagStore } from './feature-flag-store';\nimport type { FlagKey } from './types';\n\ninterface BaseProps<S extends LDFlagSet, T extends keyof S> {\n flagKey: FlagKey<S, T>;\n off?: ComponentType;\n value?: S[T];\n}\n\nexport type WithFeatureFlagProps<S extends LDFlagSet, T extends keyof S = keyof S> =\n | (BaseProps<S, T> & { children?: ReactNode; on?: never })\n | (BaseProps<S, T> & { on?: ComponentType; children?: never });\n\nexport const WithFeatureFlag = observer(\n <S extends LDFlagSet, T extends keyof S = keyof S>(\n props: WithFeatureFlagProps<S, T>\n ): ReactNode => {\n const { flagKey, value } = props;\n const [{ flags }] = useDependencies(FeatureFlagStore<S>);\n const flagValue = flags[flagKey];\n\n const isEnabled = value !== undefined ? flagValue === value : !!flagValue;\n if (isEnabled) {\n return props.on ? <props.on /> : props.children;\n }\n\n return props.off ? <props.off /> : null;\n }\n);\n"],"names":["useDependencies","observer","FeatureFlagStore","WithFeatureFlag","props","flagKey","value","flags","flagValue","isEnabled","undefined","on","children","off"],"mappings":";AAAA,SAASA,eAAe,QAAQ,0BAA0B;AAE1D,SAASC,QAAQ,QAAQ,aAAa;AAEtC,SAASC,gBAAgB,QAAQ,uBAAuB;AAaxD,OAAO,MAAMC,kBAAkBF,SAC3B,CACIG;IAEA,MAAM,EAAEC,OAAO,EAAEC,KAAK,EAAE,GAAGF;IAC3B,MAAM,CAAC,EAAEG,KAAK,EAAE,CAAC,GAAGP,gBAAgBE;IACpC,MAAMM,YAAYD,KAAK,CAACF,QAAQ;IAEhC,MAAMI,YAAYH,UAAUI,YAAYF,cAAcF,QAAQ,CAAC,CAACE;IAChE,IAAIC,WAAW;QACX,OAAOL,MAAMO,EAAE,iBAAG,KAACP,MAAMO,EAAE,QAAMP,MAAMQ,QAAQ;IACnD;IAEA,OAAOR,MAAMS,GAAG,iBAAG,KAACT,MAAMS,GAAG,QAAM;AACvC,GACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@servicetitan/launchdarkly-service",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "35.0.0",
|
|
4
4
|
"description": "Service for creating and reusing client connections for LaunchDarkly",
|
|
5
5
|
"homepage": "https://docs.st.dev/docs/frontend/uikit/launchdarkly-service",
|
|
6
6
|
"repository": {
|
|
@@ -16,22 +16,24 @@
|
|
|
16
16
|
"src"
|
|
17
17
|
],
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@servicetitan/log-service": "
|
|
20
|
-
"@servicetitan/react-ioc": "
|
|
19
|
+
"@servicetitan/log-service": "35.0.0",
|
|
20
|
+
"@servicetitan/react-ioc": "35.0.0",
|
|
21
21
|
"@testing-library/dom": "^10.4.1",
|
|
22
22
|
"@testing-library/jest-dom": "^6.9.1",
|
|
23
23
|
"@testing-library/react": "^16.3.2",
|
|
24
24
|
"launchdarkly-js-client-sdk": "3.5.0",
|
|
25
25
|
"launchdarkly-react-client-sdk": "3.6.1",
|
|
26
26
|
"mobx": "~6.13.7",
|
|
27
|
+
"mobx-react": "~9.2.0",
|
|
27
28
|
"react": "~18.3.1"
|
|
28
29
|
},
|
|
29
30
|
"peerDependencies": {
|
|
30
|
-
"@servicetitan/log-service": "
|
|
31
|
-
"@servicetitan/react-ioc": "
|
|
31
|
+
"@servicetitan/log-service": "35.0.0",
|
|
32
|
+
"@servicetitan/react-ioc": "35.0.0",
|
|
32
33
|
"launchdarkly-js-client-sdk": "3.5.0",
|
|
33
34
|
"launchdarkly-react-client-sdk": "3.6.1",
|
|
34
35
|
"mobx": ">= 6.13.7",
|
|
36
|
+
"mobx-react": ">=9.2.0",
|
|
35
37
|
"react": ">=17.0.2"
|
|
36
38
|
},
|
|
37
39
|
"publishConfig": {
|
|
@@ -40,5 +42,5 @@
|
|
|
40
42
|
"cli": {
|
|
41
43
|
"webpack": false
|
|
42
44
|
},
|
|
43
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "3a5f2e6cad93c4e898091fb3d51310ccb26a91ee"
|
|
44
46
|
}
|
|
@@ -1,24 +1,31 @@
|
|
|
1
|
+
import { Provider } from '@servicetitan/react-ioc';
|
|
1
2
|
import '@testing-library/jest-dom';
|
|
2
3
|
import { render, screen } from '@testing-library/react';
|
|
3
|
-
import {
|
|
4
|
+
import type { LDFlagSet, LDFlagValue } from 'launchdarkly-react-client-sdk';
|
|
5
|
+
import { FeatureFlagStore } from '../feature-flag-store';
|
|
4
6
|
import { WithFeatureFlag } from '../with-feature-flag';
|
|
5
7
|
|
|
6
|
-
jest.mock('launchdarkly-react-client-sdk', () => ({
|
|
7
|
-
useFlags: jest.fn(),
|
|
8
|
-
}));
|
|
9
|
-
|
|
10
8
|
describe(`[launchdarkly-service] ${WithFeatureFlag.name}`, () => {
|
|
11
9
|
const flagKey = 'foo';
|
|
12
10
|
const childContent = 'Flag is ON';
|
|
13
11
|
let props: Parameters<typeof WithFeatureFlag>[0];
|
|
14
12
|
let flagValue: LDFlagValue;
|
|
13
|
+
const mockFeatureFlagStore = {
|
|
14
|
+
get flags(): LDFlagSet {
|
|
15
|
+
return { [flagKey]: flagValue };
|
|
16
|
+
},
|
|
17
|
+
};
|
|
15
18
|
|
|
16
19
|
beforeEach(() => {
|
|
17
20
|
props = { flagKey, children: childContent };
|
|
18
|
-
jest.mocked(useFlags).mockImplementation(() => ({ [flagKey]: flagValue }));
|
|
19
21
|
});
|
|
20
22
|
|
|
21
|
-
const subject = () =>
|
|
23
|
+
const subject = () =>
|
|
24
|
+
render(
|
|
25
|
+
<Provider singletons={[{ provide: FeatureFlagStore, useValue: mockFeatureFlagStore }]}>
|
|
26
|
+
<WithFeatureFlag {...props} />
|
|
27
|
+
</Provider>
|
|
28
|
+
);
|
|
22
29
|
|
|
23
30
|
function itRendersNothing() {
|
|
24
31
|
test('renders nothing', () => {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { useDependencies } from '@servicetitan/react-ioc';
|
|
2
|
+
import type { LDFlagSet } from 'launchdarkly-js-client-sdk';
|
|
3
|
+
import { observer } from 'mobx-react';
|
|
4
|
+
import type { ComponentType, ReactNode } from 'react';
|
|
5
|
+
import { FeatureFlagStore } from './feature-flag-store';
|
|
6
|
+
import type { FlagKey } from './types';
|
|
5
7
|
|
|
6
8
|
interface BaseProps<S extends LDFlagSet, T extends keyof S> {
|
|
7
9
|
flagKey: FlagKey<S, T>;
|
|
@@ -13,16 +15,19 @@ export type WithFeatureFlagProps<S extends LDFlagSet, T extends keyof S = keyof
|
|
|
13
15
|
| (BaseProps<S, T> & { children?: ReactNode; on?: never })
|
|
14
16
|
| (BaseProps<S, T> & { on?: ComponentType; children?: never });
|
|
15
17
|
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
export const WithFeatureFlag = observer(
|
|
19
|
+
<S extends LDFlagSet, T extends keyof S = keyof S>(
|
|
20
|
+
props: WithFeatureFlagProps<S, T>
|
|
21
|
+
): ReactNode => {
|
|
22
|
+
const { flagKey, value } = props;
|
|
23
|
+
const [{ flags }] = useDependencies(FeatureFlagStore<S>);
|
|
24
|
+
const flagValue = flags[flagKey];
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
const isEnabled = value !== undefined ? flagValue === value : !!flagValue;
|
|
27
|
+
if (isEnabled) {
|
|
28
|
+
return props.on ? <props.on /> : props.children;
|
|
29
|
+
}
|
|
26
30
|
|
|
27
|
-
|
|
28
|
-
}
|
|
31
|
+
return props.off ? <props.off /> : null;
|
|
32
|
+
}
|
|
33
|
+
);
|