@thoughtspot/visual-embed-sdk 1.10.0-alpha.0 → 1.10.0-alpha.3
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/CHANGELOG.md +48 -0
- package/README.md +50 -20
- package/dist/src/embed/app.d.ts +13 -1
- package/dist/src/embed/base.d.ts +1 -1
- package/dist/src/embed/liveboard.d.ts +15 -0
- package/dist/src/embed/pinboard.d.ts +91 -0
- package/dist/src/embed/ts-embed.d.ts +33 -4
- package/dist/src/react/index.d.ts +7 -5
- package/dist/src/react/util.d.ts +1 -1
- package/dist/src/types.d.ts +201 -7
- package/dist/src/utils/plugin.d.ts +0 -0
- package/dist/src/utils.d.ts +7 -0
- package/dist/src/v1/api.d.ts +19 -0
- package/dist/tsembed.es.js +262 -20
- package/dist/tsembed.js +262 -20
- package/lib/package.json +2 -2
- package/lib/src/embed/app.d.ts +13 -1
- package/lib/src/embed/app.js +11 -2
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +11 -10
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/base.d.ts +1 -1
- package/lib/src/embed/base.js +1 -1
- package/lib/src/embed/base.spec.js +13 -1
- package/lib/src/embed/base.spec.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +15 -0
- package/lib/src/embed/liveboard.js +7 -1
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +12 -1
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/pinboard.d.ts +91 -0
- package/lib/src/embed/pinboard.js +110 -0
- package/lib/src/embed/pinboard.js.map +1 -0
- package/lib/src/embed/pinboard.spec.js +1 -1
- package/lib/src/embed/pinboard.spec.js.map +1 -1
- package/lib/src/embed/search.js +2 -1
- package/lib/src/embed/search.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +33 -4
- package/lib/src/embed/ts-embed.js +61 -11
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +162 -8
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/react/index.d.ts +7 -5
- package/lib/src/react/index.js +10 -3
- package/lib/src/react/index.js.map +1 -1
- package/lib/src/react/index.spec.js +36 -6
- package/lib/src/react/index.spec.js.map +1 -1
- package/lib/src/react/util.d.ts +1 -1
- package/lib/src/react/util.js.map +1 -1
- package/lib/src/types.d.ts +201 -7
- package/lib/src/types.js +171 -4
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/plugin.d.ts +0 -0
- package/lib/src/utils/plugin.js +1 -0
- package/lib/src/utils/plugin.js.map +1 -0
- package/lib/src/utils.d.ts +7 -0
- package/lib/src/utils.js +9 -0
- package/lib/src/utils.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +263 -13
- package/package.json +2 -2
- package/src/embed/app.spec.ts +11 -10
- package/src/embed/app.ts +20 -2
- package/src/embed/base.spec.ts +14 -0
- package/src/embed/base.ts +1 -1
- package/src/embed/liveboard.spec.ts +14 -1
- package/src/embed/liveboard.ts +24 -0
- package/src/embed/pinboard.spec.ts +1 -1
- package/src/embed/search.ts +4 -1
- package/src/embed/ts-embed.spec.ts +228 -8
- package/src/embed/ts-embed.ts +97 -13
- package/src/react/index.spec.tsx +52 -5
- package/src/react/index.tsx +39 -22
- package/src/react/util.ts +2 -1
- package/src/types.ts +211 -5
- package/src/utils.ts +14 -0
package/src/embed/ts-embed.ts
CHANGED
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
getEncodedQueryParamsString,
|
|
12
12
|
getCssDimension,
|
|
13
13
|
getOffsetTop,
|
|
14
|
+
embedEventStatus,
|
|
15
|
+
setAttributes,
|
|
14
16
|
} from '../utils';
|
|
15
17
|
import {
|
|
16
18
|
getThoughtSpotHost,
|
|
@@ -28,6 +30,8 @@ import {
|
|
|
28
30
|
RuntimeFilter,
|
|
29
31
|
Param,
|
|
30
32
|
EmbedConfig,
|
|
33
|
+
MessageOptions,
|
|
34
|
+
MessageCallbackObj,
|
|
31
35
|
} from '../types';
|
|
32
36
|
import { uploadMixpanelEvent, MIXPANEL_EVENT } from '../mixpanel-service';
|
|
33
37
|
import { getProcessData } from '../utils/processData';
|
|
@@ -37,6 +41,11 @@ import { getAuthPromise, getEmbedConfig, renderInQueue } from './base';
|
|
|
37
41
|
|
|
38
42
|
const { version } = pkgInfo;
|
|
39
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Global prefix for all Thoughtspot postHash Params.
|
|
46
|
+
*/
|
|
47
|
+
export const THOUGHTSPOT_PARAM_PREFIX = 'ts-';
|
|
48
|
+
|
|
40
49
|
/**
|
|
41
50
|
* The event id map from v2 event names to v1 event id
|
|
42
51
|
* v1 events are the classic embed events implemented in Blink v1
|
|
@@ -62,6 +71,11 @@ export interface FrameParams {
|
|
|
62
71
|
* The height of the iFrame (unit is pixels if numeric).
|
|
63
72
|
*/
|
|
64
73
|
height?: number | string;
|
|
74
|
+
/**
|
|
75
|
+
* This parameters will be passed on the iframe
|
|
76
|
+
* as is.
|
|
77
|
+
*/
|
|
78
|
+
[key: string]: string | number | boolean;
|
|
65
79
|
}
|
|
66
80
|
|
|
67
81
|
/**
|
|
@@ -105,15 +119,28 @@ export interface ViewConfig {
|
|
|
105
119
|
* @version 1.6.0 or later
|
|
106
120
|
*/
|
|
107
121
|
visibleActions?: Action[];
|
|
122
|
+
/**
|
|
123
|
+
* Show alert messages and toast messages in the embedded view.
|
|
124
|
+
* @version 1.11.0 | ThoughtSpot: 8.3.0.cl
|
|
125
|
+
*/
|
|
126
|
+
showAlerts?: boolean;
|
|
108
127
|
/**
|
|
109
128
|
* The list of runtime filters to apply to a search answer,
|
|
110
129
|
* visualization, or Liveboard.
|
|
111
130
|
*/
|
|
112
131
|
runtimeFilters?: RuntimeFilter[];
|
|
132
|
+
/**
|
|
133
|
+
* The locale/language to use for the embedded view.
|
|
134
|
+
* @version 1.9.4 or later
|
|
135
|
+
*/
|
|
136
|
+
locale?: string;
|
|
113
137
|
/**
|
|
114
138
|
* This is an object (key/val) of override flags which will be applied
|
|
115
139
|
* to the internal embedded object. This can be used to add any
|
|
116
140
|
* URL flag.
|
|
141
|
+
* Warning: This option is for advanced use only and is used internally
|
|
142
|
+
* to control embed behavior in non-regular ways. We do not publish the
|
|
143
|
+
* list of supported keys and values associated with each.
|
|
117
144
|
* @version SDK: 1.9.0 | ThoughtSpot: 8.1.0.cl
|
|
118
145
|
*/
|
|
119
146
|
additionalFlags?: { [key: string]: string | number | boolean };
|
|
@@ -155,7 +182,7 @@ export class TsEmbed {
|
|
|
155
182
|
* by the embedded app; multiple event handlers can be registered
|
|
156
183
|
* against a particular message type.
|
|
157
184
|
*/
|
|
158
|
-
private eventHandlerMap: Map<string,
|
|
185
|
+
private eventHandlerMap: Map<string, MessageCallbackObj[]>;
|
|
159
186
|
|
|
160
187
|
/**
|
|
161
188
|
* A flag that is set to true post render.
|
|
@@ -324,7 +351,12 @@ export class TsEmbed {
|
|
|
324
351
|
queryParams[Param.ViewPortHeight] = window.innerHeight;
|
|
325
352
|
queryParams[Param.ViewPortWidth] = window.innerWidth;
|
|
326
353
|
queryParams[Param.Version] = version;
|
|
327
|
-
|
|
354
|
+
if (
|
|
355
|
+
this.embedConfig.disableLoginRedirect === true ||
|
|
356
|
+
this.embedConfig.autoLogin === true
|
|
357
|
+
) {
|
|
358
|
+
queryParams[Param.DisableLoginRedirect] = true;
|
|
359
|
+
}
|
|
328
360
|
if (this.embedConfig.customCssUrl) {
|
|
329
361
|
queryParams[Param.CustomCSSUrl] = this.embedConfig.customCssUrl;
|
|
330
362
|
}
|
|
@@ -334,7 +366,9 @@ export class TsEmbed {
|
|
|
334
366
|
disabledActionReason,
|
|
335
367
|
hiddenActions,
|
|
336
368
|
visibleActions,
|
|
369
|
+
showAlerts,
|
|
337
370
|
additionalFlags,
|
|
371
|
+
locale,
|
|
338
372
|
} = this.viewConfig;
|
|
339
373
|
|
|
340
374
|
if (Array.isArray(visibleActions) && Array.isArray(hiddenActions)) {
|
|
@@ -356,6 +390,12 @@ export class TsEmbed {
|
|
|
356
390
|
if (Array.isArray(visibleActions)) {
|
|
357
391
|
queryParams[Param.VisibleActions] = visibleActions;
|
|
358
392
|
}
|
|
393
|
+
if (showAlerts !== undefined) {
|
|
394
|
+
queryParams[Param.ShowAlerts] = showAlerts;
|
|
395
|
+
}
|
|
396
|
+
if (locale !== undefined) {
|
|
397
|
+
queryParams[Param.Locale] = locale;
|
|
398
|
+
}
|
|
359
399
|
if (additionalFlags && additionalFlags.constructor.name === 'Object') {
|
|
360
400
|
Object.assign(queryParams, additionalFlags);
|
|
361
401
|
}
|
|
@@ -399,7 +439,7 @@ export class TsEmbed {
|
|
|
399
439
|
* @param url
|
|
400
440
|
* @param frameOptions
|
|
401
441
|
*/
|
|
402
|
-
protected renderIFrame(url: string, frameOptions: FrameParams): void {
|
|
442
|
+
protected renderIFrame(url: string, frameOptions: FrameParams = {}): void {
|
|
403
443
|
if (this.isError) {
|
|
404
444
|
return;
|
|
405
445
|
}
|
|
@@ -441,12 +481,19 @@ export class TsEmbed {
|
|
|
441
481
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
442
482
|
// @ts-ignore
|
|
443
483
|
this.iFrame.mozallowfullscreen = true;
|
|
484
|
+
const {
|
|
485
|
+
height: frameHeight,
|
|
486
|
+
width: frameWidth,
|
|
487
|
+
...restParams
|
|
488
|
+
} = frameOptions;
|
|
444
489
|
const width = getCssDimension(
|
|
445
|
-
|
|
490
|
+
frameWidth || DEFAULT_EMBED_WIDTH,
|
|
446
491
|
);
|
|
447
492
|
const height = getCssDimension(
|
|
448
|
-
|
|
493
|
+
frameWidth || DEFAULT_EMBED_HEIGHT,
|
|
449
494
|
);
|
|
495
|
+
setAttributes(this.iFrame, restParams);
|
|
496
|
+
|
|
450
497
|
this.iFrame.style.width = `${width}`;
|
|
451
498
|
this.iFrame.style.height = `${height}`;
|
|
452
499
|
this.iFrame.style.border = '0';
|
|
@@ -511,11 +558,19 @@ export class TsEmbed {
|
|
|
511
558
|
eventPort?: MessagePort | void,
|
|
512
559
|
): void {
|
|
513
560
|
const callbacks = this.eventHandlerMap.get(eventType) || [];
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
561
|
+
const dataStatus = data?.status || embedEventStatus.END;
|
|
562
|
+
callbacks.forEach((callbackObj) => {
|
|
563
|
+
if (
|
|
564
|
+
(callbackObj.options.start &&
|
|
565
|
+
dataStatus === embedEventStatus.START) || // When start status is true it trigger only start releated payload
|
|
566
|
+
(!callbackObj.options.start &&
|
|
567
|
+
dataStatus === embedEventStatus.END) // When start status is false it trigger only end releated payload
|
|
568
|
+
) {
|
|
569
|
+
callbackObj.callback(data, (payload) => {
|
|
570
|
+
this.triggerEventOnPort(eventPort, payload);
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
});
|
|
519
574
|
}
|
|
520
575
|
|
|
521
576
|
/**
|
|
@@ -582,20 +637,21 @@ export class TsEmbed {
|
|
|
582
637
|
* sends an event of a particular message type to the host application.
|
|
583
638
|
*
|
|
584
639
|
* @param messageType The message type
|
|
585
|
-
* @param callback A callback function
|
|
640
|
+
* @param callback A callback as a function
|
|
641
|
+
* @param options The message options
|
|
586
642
|
*/
|
|
587
643
|
public on(
|
|
588
644
|
messageType: EmbedEvent,
|
|
589
645
|
callback: MessageCallback,
|
|
646
|
+
options: MessageOptions = { start: false },
|
|
590
647
|
): typeof TsEmbed.prototype {
|
|
591
648
|
if (this.isRendered) {
|
|
592
649
|
this.handleError(
|
|
593
650
|
'Please register event handlers before calling render',
|
|
594
651
|
);
|
|
595
652
|
}
|
|
596
|
-
|
|
597
653
|
const callbacks = this.eventHandlerMap.get(messageType) || [];
|
|
598
|
-
callbacks.push(callback);
|
|
654
|
+
callbacks.push({ options, callback });
|
|
599
655
|
this.eventHandlerMap.set(messageType, callbacks);
|
|
600
656
|
return this;
|
|
601
657
|
}
|
|
@@ -649,6 +705,34 @@ export class TsEmbed {
|
|
|
649
705
|
|
|
650
706
|
return this;
|
|
651
707
|
}
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Get the Post Url Params for THOUGHTSPOT from the current
|
|
711
|
+
* host app URL.
|
|
712
|
+
* THOUGHTSPOT URL params starts with a prefix "ts-"
|
|
713
|
+
*/
|
|
714
|
+
public getThoughtSpotPostUrlParams(): string {
|
|
715
|
+
const urlHash = window.location.hash;
|
|
716
|
+
const queryParams = window.location.search;
|
|
717
|
+
const postHashParams = urlHash.split('?');
|
|
718
|
+
const postURLParams = postHashParams[postHashParams.length - 1];
|
|
719
|
+
const queryParamsObj = new URLSearchParams(queryParams);
|
|
720
|
+
const postURLParamsObj = new URLSearchParams(postURLParams);
|
|
721
|
+
const params = new URLSearchParams();
|
|
722
|
+
|
|
723
|
+
const addKeyValuePairCb = (value: string, key: string): void => {
|
|
724
|
+
if (key.startsWith(THOUGHTSPOT_PARAM_PREFIX)) {
|
|
725
|
+
params.append(key, value);
|
|
726
|
+
}
|
|
727
|
+
};
|
|
728
|
+
queryParamsObj.forEach(addKeyValuePairCb);
|
|
729
|
+
postURLParamsObj.forEach(addKeyValuePairCb);
|
|
730
|
+
|
|
731
|
+
let tsParams = params.toString();
|
|
732
|
+
tsParams = tsParams ? `?${tsParams}` : '';
|
|
733
|
+
|
|
734
|
+
return tsParams;
|
|
735
|
+
}
|
|
652
736
|
}
|
|
653
737
|
|
|
654
738
|
/**
|
package/src/react/index.spec.tsx
CHANGED
|
@@ -3,13 +3,14 @@ import '@testing-library/jest-dom';
|
|
|
3
3
|
import '@testing-library/jest-dom/extend-expect';
|
|
4
4
|
import { cleanup, fireEvent, render, waitFor } from '@testing-library/react';
|
|
5
5
|
import {
|
|
6
|
+
executeAfterWait,
|
|
6
7
|
getIFrameEl,
|
|
7
8
|
getIFrameSrc,
|
|
8
9
|
postMessageToParent,
|
|
9
10
|
} from '../test/test-utils';
|
|
10
|
-
import { SearchEmbed, AppEmbed,
|
|
11
|
+
import { SearchEmbed, AppEmbed, LiveboardEmbed, useEmbedRef } from './index';
|
|
11
12
|
import { AuthType, init } from '../index';
|
|
12
|
-
import { EmbedEvent } from '../types';
|
|
13
|
+
import { EmbedEvent, HostEvent } from '../types';
|
|
13
14
|
import { version } from '../../package.json';
|
|
14
15
|
|
|
15
16
|
const thoughtSpotHost = 'localhost';
|
|
@@ -25,17 +26,22 @@ describe('React Components', () => {
|
|
|
25
26
|
describe('SearchEmbed', () => {
|
|
26
27
|
it('Should Render the Iframe with props', async () => {
|
|
27
28
|
const { container } = render(
|
|
28
|
-
<SearchEmbed hideDataSources={true} />,
|
|
29
|
+
<SearchEmbed hideDataSources={true} className="embedClass" />,
|
|
29
30
|
);
|
|
30
31
|
|
|
31
32
|
await waitFor(() => getIFrameEl(container));
|
|
32
33
|
|
|
34
|
+
expect(
|
|
35
|
+
getIFrameEl(container).parentElement.classList.contains(
|
|
36
|
+
'embedClass',
|
|
37
|
+
),
|
|
38
|
+
).toBe(true);
|
|
33
39
|
expect(getIFrameSrc(container)).toBe(
|
|
34
40
|
`http://${thoughtSpotHost}/?hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&hideAction=[%22editACopy%22,%22saveAsView%22,%22updateTSL%22,%22editTSL%22,%22onDeleteAnswer%22]&dataSourceMode=hide&useLastSelectedSources=false&isSearchEmbed=true#/embed/answer`,
|
|
35
41
|
);
|
|
36
42
|
});
|
|
37
43
|
|
|
38
|
-
it('Should attach event listeners', async () => {
|
|
44
|
+
it('Should attach event listeners', async (done) => {
|
|
39
45
|
const userGUID = 'absfdfgd';
|
|
40
46
|
const { container } = render(
|
|
41
47
|
<SearchEmbed
|
|
@@ -44,6 +50,7 @@ describe('React Components', () => {
|
|
|
44
50
|
}}
|
|
45
51
|
onAuthInit={(e) => {
|
|
46
52
|
expect(e.data.userGUID).toEqual(userGUID);
|
|
53
|
+
done();
|
|
47
54
|
}}
|
|
48
55
|
/>,
|
|
49
56
|
);
|
|
@@ -63,7 +70,47 @@ describe('React Components', () => {
|
|
|
63
70
|
//
|
|
64
71
|
});
|
|
65
72
|
|
|
66
|
-
describe('
|
|
73
|
+
describe('LiveboardEmbed', () => {
|
|
67
74
|
//
|
|
75
|
+
it('Should be able to trigger events on the embed using refs', async () => {
|
|
76
|
+
const TestComponent = () => {
|
|
77
|
+
const embedRef = useEmbedRef();
|
|
78
|
+
const onLiveboardRendered = () => {
|
|
79
|
+
embedRef.current.trigger(HostEvent.SetVisibleVizs, [
|
|
80
|
+
'viz1',
|
|
81
|
+
'viz2',
|
|
82
|
+
]);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<LiveboardEmbed
|
|
87
|
+
ref={embedRef}
|
|
88
|
+
liveboardId="abcd"
|
|
89
|
+
onLiveboardRendered={onLiveboardRendered}
|
|
90
|
+
/>
|
|
91
|
+
);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const { container } = render(<TestComponent />);
|
|
95
|
+
|
|
96
|
+
await waitFor(() => getIFrameEl(container));
|
|
97
|
+
const iframe = getIFrameEl(container);
|
|
98
|
+
jest.spyOn(iframe.contentWindow, 'postMessage');
|
|
99
|
+
postMessageToParent(iframe.contentWindow, {
|
|
100
|
+
type: EmbedEvent.LiveboardRendered,
|
|
101
|
+
data: {
|
|
102
|
+
userGUID: 'abcd',
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
await executeAfterWait(() => {
|
|
106
|
+
expect(iframe.contentWindow.postMessage).toHaveBeenCalledWith(
|
|
107
|
+
{
|
|
108
|
+
type: HostEvent.SetVisibleVizs,
|
|
109
|
+
data: ['viz1', 'viz2'],
|
|
110
|
+
},
|
|
111
|
+
`http://${thoughtSpotHost}`,
|
|
112
|
+
);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
68
115
|
});
|
|
69
116
|
});
|
package/src/react/index.tsx
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from '../embed/liveboard';
|
|
8
8
|
import { TsEmbed, ViewConfig } from '../embed/ts-embed';
|
|
9
9
|
|
|
10
|
-
import { EmbedEvent
|
|
10
|
+
import { EmbedEvent } from '../types';
|
|
11
11
|
import { EmbedProps, getViewPropsAndListeners } from './util';
|
|
12
12
|
|
|
13
13
|
const componentFactory = <
|
|
@@ -16,28 +16,41 @@ const componentFactory = <
|
|
|
16
16
|
V extends ViewConfig
|
|
17
17
|
>(
|
|
18
18
|
EmbedConstructor: T,
|
|
19
|
-
) =>
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
eventName
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
19
|
+
) =>
|
|
20
|
+
React.forwardRef<TsEmbed, U>(
|
|
21
|
+
(props: U, forwardedRef: React.MutableRefObject<TsEmbed>) => {
|
|
22
|
+
const ref = React.useRef<HTMLDivElement>(null);
|
|
23
|
+
const { className, ...embedProps } = props;
|
|
24
|
+
const { viewConfig, listeners } = getViewPropsAndListeners<
|
|
25
|
+
Omit<U, 'className'>,
|
|
26
|
+
V
|
|
27
|
+
>(embedProps);
|
|
28
|
+
React.useEffect(() => {
|
|
29
|
+
const tsEmbed = new EmbedConstructor(ref!.current, {
|
|
30
|
+
...viewConfig,
|
|
31
|
+
});
|
|
32
|
+
Object.keys(listeners).forEach((eventName) => {
|
|
33
|
+
tsEmbed.on(
|
|
34
|
+
eventName as EmbedEvent,
|
|
35
|
+
listeners[eventName as EmbedEvent],
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
tsEmbed.render();
|
|
39
|
+
if (forwardedRef) {
|
|
40
|
+
// eslint-disable-next-line no-param-reassign
|
|
41
|
+
forwardedRef.current = tsEmbed;
|
|
42
|
+
}
|
|
43
|
+
}, [embedProps]);
|
|
38
44
|
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
return (
|
|
46
|
+
<div
|
|
47
|
+
data-testid="tsEmbed"
|
|
48
|
+
ref={ref}
|
|
49
|
+
className={className}
|
|
50
|
+
></div>
|
|
51
|
+
);
|
|
52
|
+
},
|
|
53
|
+
);
|
|
41
54
|
|
|
42
55
|
interface SearchProps extends EmbedProps, SearchViewConfig {}
|
|
43
56
|
|
|
@@ -68,3 +81,7 @@ export const PinboardEmbed = componentFactory<
|
|
|
68
81
|
LiveboardProps,
|
|
69
82
|
LiveboardViewConfig
|
|
70
83
|
>(_LiveboardEmbed);
|
|
84
|
+
|
|
85
|
+
export const useEmbedRef = (): React.MutableRefObject<TsEmbed> => {
|
|
86
|
+
return React.useRef<TsEmbed>(null);
|
|
87
|
+
};
|
package/src/react/util.ts
CHANGED
|
@@ -2,7 +2,8 @@ import { EmbedEvent, MessageCallback } from '../types';
|
|
|
2
2
|
import { ViewConfig } from '../embed/ts-embed';
|
|
3
3
|
|
|
4
4
|
// eslint-disable-next-line prettier/prettier
|
|
5
|
-
export type EmbedEventHandlers = { [key in EmbedEvent as `on${Capitalize<key>}`]?: MessageCallback };
|
|
5
|
+
export type EmbedEventHandlers = { [key in keyof typeof EmbedEvent as `on${Capitalize<key>}`]?: MessageCallback };
|
|
6
|
+
|
|
6
7
|
|
|
7
8
|
export interface EmbedProps extends ViewConfig, EmbedEventHandlers {
|
|
8
9
|
className?: string;
|