@botpress/webchat 0.2.0 → 0.2.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.
@@ -1,27 +1,9 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
- Object.defineProperty(o, "default", { enumerable: true, value: v });
11
- }) : function(o, v) {
12
- o["default"] = v;
13
- });
14
- var __importStar = (this && this.__importStar) || function (mod) {
15
- if (mod && mod.__esModule) return mod;
16
- var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
- __setModuleDefault(result, mod);
19
- return result;
20
- };
21
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
22
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
23
4
  };
24
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ const messaging_components_1 = require("@botpress/messaging-components");
25
7
  const classnames_1 = __importDefault(require("classnames"));
26
8
  const mobx_react_1 = require("mobx-react");
27
9
  const react_1 = __importDefault(require("react"));
@@ -31,7 +13,6 @@ const Composer_1 = __importDefault(require("./Composer"));
31
13
  const ConversationList_1 = __importDefault(require("./ConversationList"));
32
14
  const Footer_1 = __importDefault(require("./Footer"));
33
15
  const Header_1 = __importDefault(require("./Header"));
34
- const Keyboard = __importStar(require("./Keyboard"));
35
16
  const MessageList_1 = __importDefault(require("./messages/MessageList"));
36
17
  const OverridableComponent_1 = __importDefault(require("./OverridableComponent"));
37
18
  class Container extends react_1.default.Component {
@@ -52,7 +33,7 @@ class Container extends react_1.default.Component {
52
33
  'bpw-rtl': this.props.rtl
53
34
  }) },
54
35
  react_1.default.createElement(MessageList_1.default, null),
55
- react_1.default.createElement(Keyboard.Default, null,
36
+ react_1.default.createElement(messaging_components_1.Keyboard, null,
56
37
  react_1.default.createElement(OverridableComponent_1.default, { name: 'composer', original: Composer_1.default }))));
57
38
  }
58
39
  }
@@ -11,7 +11,7 @@ const Add_1 = __importDefault(require("../icons/Add"));
11
11
  const ConversationListItem = (0, react_intl_1.injectIntl)(({ conversation, onClick, hasFocus, intl }) => {
12
12
  var _a, _b, _c;
13
13
  const title = intl.formatMessage({ id: 'conversationList.title' }, { id: conversation.id });
14
- const { value, unit } = (0, intl_utils_1.selectUnit)(((_a = conversation.lastMessage) === null || _a === void 0 ? void 0 : _a.sentOn) || conversation.createdOn);
14
+ const { value, unit } = (0, intl_utils_1.selectUnit)(new Date(((_a = conversation.lastMessage) === null || _a === void 0 ? void 0 : _a.sentOn) || conversation.createdOn));
15
15
  const date = intl.formatRelativeTime(value, unit);
16
16
  const message = ((_c = (_b = conversation.lastMessage) === null || _b === void 0 ? void 0 : _b.payload) === null || _c === void 0 ? void 0 : _c.text) || '...';
17
17
  return (react_1.default.createElement("div", { className: 'bpw-convo-item', onClick: onClick },
@@ -77,13 +77,9 @@ class MessageGroup extends react_1.default.Component {
77
77
  react_1.default.createElement("span", { "data-from": fromLabel, className: "from hidden", "aria-hidden": "true" }, fromLabel),
78
78
  (0, sortBy_1.default)(messages, ['sent_on', 'eventId']).map((message, i, messages) => {
79
79
  const isLastMsg = i === messages.length - 1;
80
- let payload = this.convertPayloadFromOldFormat(message);
81
- // TODO: remove this. quick_reply should be single-choice
82
- if (payload.type === 'single-choice') {
83
- payload = Object.assign(Object.assign({}, payload), { type: 'quick_reply' });
84
- }
80
+ const payload = this.convertPayloadFromOldFormat(message);
85
81
  const showInlineFeedback = isBot && isLastMsg && (payload.wrapped ? payload.wrapped.collectFeedback : payload.collectFeedback);
86
- return (react_1.default.createElement(Message_1.default, { key: message.id, isHighlighted: this.props.highlightedMessages && this.props.highlightedMessages.includes(message.id), inlineFeedback: showInlineFeedback && (react_1.default.createElement(InlineFeedback_1.InlineFeedback, { intl: this.props.store.intl, messageId: message.id, onFeedback: this.props.onFeedback, messageFeedbacks: this.props.store.messageFeedbacks })), messageId: message.id, noBubble: !!payload.noBubble, fromLabel: fromLabel, isLastOfGroup: i >= this.props.messages.length - 1, isLastGroup: this.props.isLastGroup, isBotMessage: !message.authorId, payload: payload, sentOn: message.sentOn, onSendData: this.props.onSendData, onFileUpload: this.props.onFileUpload, store: this.props.store, onAudioEnded: this.onAudioEnded, shouldPlay: this.state.audioPlayingIndex === i }));
82
+ return (react_1.default.createElement(Message_1.default, { key: `${message.id}-${message.payload.type}`, isHighlighted: this.props.highlightedMessages && this.props.highlightedMessages.includes(message.id), inlineFeedback: showInlineFeedback && (react_1.default.createElement(InlineFeedback_1.InlineFeedback, { intl: this.props.store.intl, messageId: message.id, onFeedback: this.props.onFeedback, messageFeedbacks: this.props.store.messageFeedbacks })), messageId: message.id, noBubble: !!payload.noBubble, fromLabel: fromLabel, isLastOfGroup: i >= this.props.messages.length - 1, isLastGroup: this.props.isLastGroup, isBotMessage: !message.authorId, payload: payload, sentOn: message.sentOn, onSendData: this.props.onSendData, onFileUpload: this.props.onFileUpload, store: this.props.store, onAudioEnded: this.onAudioEnded, shouldPlay: this.state.audioPlayingIndex === i }));
87
83
  })))));
88
84
  }
89
85
  }
package/dist/core/api.js CHANGED
@@ -67,7 +67,16 @@ class WebchatApi {
67
67
  fetchConversations() {
68
68
  return __awaiter(this, void 0, void 0, function* () {
69
69
  try {
70
- const convos = yield this.socket.socket.listConversations();
70
+ const convos = (yield this.socket.socket.listConversations());
71
+ // Add the last message of each conversation
72
+ for (const convo of convos) {
73
+ const limit = 1;
74
+ yield this.socket.socket.switchConversation(convo.id);
75
+ const lastMessages = yield this.socket.socket.listMessages(limit);
76
+ if (lastMessages.length >= limit) {
77
+ convo.lastMessage = lastMessages[0];
78
+ }
79
+ }
71
80
  return convos;
72
81
  }
73
82
  catch (err) {
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ import '../../assets/fonts/roboto.css';
3
+ declare const Font: () => JSX.Element;
4
+ export default Font;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ require("../../assets/fonts/roboto.css");
8
+ const Font = () => react_1.default.createElement(react_1.default.Fragment, null);
9
+ exports.default = Font;
package/dist/main.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { WrappedComponentProps } from 'react-intl';
3
3
  import { RootStore, StoreDef } from './store';
4
+ export declare const DEFAULT_TYPING_DELAY = 1000;
4
5
  declare const _default: React.ForwardRefExoticComponent<import("react-intl").Omit<MainProps, "intl"> & {
5
6
  forwardedRef?: React.Ref<any> | undefined;
6
7
  } & React.RefAttributes<any>> & {
@@ -9,4 +10,4 @@ declare const _default: React.ForwardRefExoticComponent<import("react-intl").Omi
9
10
  export default _default;
10
11
  declare type MainProps = {
11
12
  store: RootStore;
12
- } & WrappedComponentProps & Pick<StoreDef, 'config' | 'initializeChat' | 'botInfo' | 'fetchBotInfo' | 'sendMessage' | 'setUserId' | 'sendData' | 'intl' | 'isEmulator' | 'updateTyping' | 'setReference' | 'updateBotUILanguage' | 'hideChat' | 'showChat' | 'toggleBotInfo' | 'widgetTransition' | 'activeView' | 'isFullscreen' | 'unreadCount' | 'hasUnreadMessages' | 'showWidgetButton' | 'addEventToConversation' | 'clearMessages' | 'updateConfig' | 'mergeConfig' | 'isWebchatReady' | 'incrementUnread' | 'displayWidgetView' | 'resetUnread' | 'setLoadingCompleted' | 'dimensions'>;
13
+ } & WrappedComponentProps & Pick<StoreDef, 'config' | 'initializeChat' | 'botInfo' | 'fetchBotInfo' | 'sendMessage' | 'setUserId' | 'sendData' | 'intl' | 'isEmulator' | 'updateTyping' | 'setReference' | 'updateBotUILanguage' | 'hideChat' | 'showChat' | 'toggleBotInfo' | 'widgetTransition' | 'activeView' | 'isFullscreen' | 'unreadCount' | 'hasUnreadMessages' | 'showWidgetButton' | 'addEventToConversation' | 'clearMessages' | 'updateConfig' | 'mergeConfig' | 'isWebchatReady' | 'incrementUnread' | 'displayWidgetView' | 'resetUnread' | 'setLoadingCompleted' | 'dimensions' | 'updateLastMessage'>;
package/dist/main.js CHANGED
@@ -1,4 +1,23 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
2
21
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
22
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
23
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -12,6 +31,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
31
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
32
  };
14
33
  Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.DEFAULT_TYPING_DELAY = void 0;
15
35
  const classnames_1 = __importDefault(require("classnames"));
16
36
  const debounce_1 = __importDefault(require("lodash/debounce"));
17
37
  const set_1 = __importDefault(require("lodash/set"));
@@ -26,8 +46,7 @@ const constants_1 = __importDefault(require("./core/constants"));
26
46
  const socket_1 = __importDefault(require("./core/socket"));
27
47
  const Chat_1 = __importDefault(require("./icons/Chat"));
28
48
  const utils_1 = require("./utils");
29
- const _values = (obj) => Object.keys(obj).map((x) => obj[x]);
30
- const DEFAULT_TYPING_DELAY = 1000;
49
+ exports.DEFAULT_TYPING_DELAY = 1000;
31
50
  class Web extends react_1.default.Component {
32
51
  constructor(props) {
33
52
  super(props);
@@ -86,7 +105,7 @@ class Web extends react_1.default.Component {
86
105
  this.handleNewMessage = (event) => __awaiter(this, void 0, void 0, function* () {
87
106
  var _a;
88
107
  if (event.authorId === undefined) {
89
- const value = (event.payload.type === 'typing' ? event.payload.value : undefined) || DEFAULT_TYPING_DELAY;
108
+ const value = (event.payload.type === 'typing' ? event.payload.value : undefined) || exports.DEFAULT_TYPING_DELAY;
90
109
  yield this.handleTyping(Object.assign(Object.assign({}, event), { timeInMs: value }));
91
110
  }
92
111
  if (((_a = event.payload) === null || _a === void 0 ? void 0 : _a.type) === 'visit') {
@@ -98,6 +117,7 @@ class Web extends react_1.default.Component {
98
117
  return;
99
118
  }
100
119
  (0, utils_1.trackMessage)('received');
120
+ this.props.updateLastMessage(event.conversationId, event);
101
121
  yield this.props.addEventToConversation(event);
102
122
  // there's no focus on the actual conversation
103
123
  if ((document.hasFocus && !document.hasFocus()) || this.props.activeView !== 'side') {
@@ -148,8 +168,7 @@ class Web extends react_1.default.Component {
148
168
  }
149
169
  componentDidMount() {
150
170
  return __awaiter(this, void 0, void 0, function* () {
151
- // TODO: serve this from cdn
152
- this.audio = new Audio(`${window.ROOT_PATH}/assets/modules/channel-web/notification.mp3`);
171
+ this.audio = new Audio(require('url:../assets/notification.mp3'));
153
172
  this.props.store.setIntlProvider(this.props.intl);
154
173
  window.store = this.props.store;
155
174
  window.addEventListener('message', this.handleIframeApi);
@@ -256,7 +275,7 @@ class Web extends react_1.default.Component {
256
275
  }
257
276
  loadOverrides(overrides) {
258
277
  try {
259
- for (const override of _values(overrides)) {
278
+ for (const override of Object.values(overrides)) {
260
279
  // TODO: load module view this can't work
261
280
  // override.map(({ module }) => this.props.bp!.loadModuleView(module, true))
262
281
  }
@@ -314,11 +333,11 @@ class Web extends react_1.default.Component {
314
333
  this.postMessageToParent('setClass', parentClass);
315
334
  this.parentClass = parentClass;
316
335
  }
317
- const { isEmulator, stylesheet, extraStylesheet } = this.props.config;
336
+ const { stylesheet, extraStylesheet } = this.props.config;
337
+ const RobotoFont = react_1.default.lazy(() => Promise.resolve().then(() => __importStar(require('./fonts/roboto'))));
318
338
  return (react_1.default.createElement(react_1.default.Fragment, null,
319
339
  !!(stylesheet === null || stylesheet === void 0 ? void 0 : stylesheet.length) && react_1.default.createElement(Stylesheet_1.default, { href: stylesheet }),
320
- !stylesheet && react_1.default.createElement(Stylesheet_1.default, { href: `assets/modules/channel-web/default${isEmulator ? '-emulator' : ''}.css` }),
321
- !utils_1.isIE && react_1.default.createElement(Stylesheet_1.default, { href: 'assets/modules/channel-web/font.css' }),
340
+ react_1.default.createElement(react_1.default.Suspense, { fallback: react_1.default.createElement(react_1.default.Fragment, null) }, !utils_1.isIE && react_1.default.createElement(RobotoFont, null)),
322
341
  !!(extraStylesheet === null || extraStylesheet === void 0 ? void 0 : extraStylesheet.length) && react_1.default.createElement(Stylesheet_1.default, { href: extraStylesheet })));
323
342
  }
324
343
  render() {
@@ -366,5 +385,6 @@ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
366
385
  widgetTransition: store.view.widgetTransition,
367
386
  displayWidgetView: store.view.displayWidgetView,
368
387
  setLoadingCompleted: store.view.setLoadingCompleted,
369
- sendFeedback: store.sendFeedback
388
+ sendFeedback: store.sendFeedback,
389
+ updateLastMessage: store.updateLastMessage
370
390
  }))((0, react_intl_1.injectIntl)((0, mobx_react_1.observer)(Web)));
@@ -40,6 +40,7 @@ declare class RootStore {
40
40
  get currentConversationId(): uuid;
41
41
  postMessage(name: string, payload?: any): void;
42
42
  updateMessages(messages: Message[]): void;
43
+ updateLastMessage(conversationId: string, message?: Message): void;
43
44
  clearMessages(): void;
44
45
  deleteConversation(): Promise<void>;
45
46
  loadEventInDebugger(messageId: uuid, isManual?: boolean): Promise<void>;
@@ -24,6 +24,7 @@ const is_valid_1 = __importDefault(require("date-fns/is_valid"));
24
24
  const merge_1 = __importDefault(require("lodash/merge"));
25
25
  const mobx_1 = require("mobx");
26
26
  const api_1 = __importDefault(require("../core/api"));
27
+ const main_1 = require("../main");
27
28
  const translations_1 = require("../translations");
28
29
  const utils_1 = require("../utils");
29
30
  const composer_1 = __importDefault(require("./composer"));
@@ -65,11 +66,7 @@ class RootStore {
65
66
  }
66
67
  get botAvatarUrl() {
67
68
  var _a, _b, _c;
68
- return (((_b = (_a = this.botInfo) === null || _a === void 0 ? void 0 : _a.details) === null || _b === void 0 ? void 0 : _b.avatarUrl) ||
69
- ((_c = this.config) === null || _c === void 0 ? void 0 : _c.avatarUrl) ||
70
- (this.config.isEmulator
71
- ? `${window.ROOT_PATH}/assets/modules/channel-web/images/emulator-default.svg`
72
- : undefined));
69
+ return ((_b = (_a = this.botInfo) === null || _a === void 0 ? void 0 : _a.details) === null || _b === void 0 ? void 0 : _b.avatarUrl) || ((_c = this.config) === null || _c === void 0 ? void 0 : _c.avatarUrl) || undefined;
73
70
  }
74
71
  get rtl() {
75
72
  return (0, utils_1.isRTLLocale)(this.preferredLanguage);
@@ -93,6 +90,14 @@ class RootStore {
93
90
  updateMessages(messages) {
94
91
  this.currentConversation.messages = messages;
95
92
  }
93
+ updateLastMessage(conversationId, message) {
94
+ for (const conversation of this.conversations) {
95
+ if (conversation.id === conversationId) {
96
+ conversation.lastMessage = message;
97
+ return;
98
+ }
99
+ }
100
+ }
96
101
  clearMessages() {
97
102
  this.currentConversation.messages = [];
98
103
  }
@@ -146,7 +151,7 @@ class RootStore {
146
151
  if ((0, is_before_1.default)(start, this.currentConversation.typingUntil)) {
147
152
  start = this.currentConversation.typingUntil;
148
153
  }
149
- this.currentConversation.typingUntil = new Date(+start + event.timeInMs);
154
+ this.currentConversation.typingUntil = new Date(+start + (event.timeInMs || main_1.DEFAULT_TYPING_DELAY));
150
155
  this._startTypingTimer();
151
156
  });
152
157
  }
@@ -278,7 +283,8 @@ class RootStore {
278
283
  extractFeedback(messages) {
279
284
  return __awaiter(this, void 0, void 0, function* () {
280
285
  const feedbackMessageIds = messages.filter((x) => x.payload && x.payload.collectFeedback).map((x) => x.id);
281
- const feedbackInfo = yield this.api.getMessageIdsFeedbackInfo(feedbackMessageIds);
286
+ // TODO: store feedback somewhere
287
+ const feedbackInfo = feedbackMessageIds.map((x) => ({ messageId: x, feedback: 1 }));
282
288
  (0, mobx_1.runInAction)('-> setFeedbackInfo', () => {
283
289
  this.messageFeedbacks = feedbackInfo;
284
290
  });
@@ -314,7 +320,8 @@ class RootStore {
314
320
  return this.api.sendEvent(data, this.currentConversationId)
315
321
  }
316
322
  */
317
- yield this.api.sendMessage(data, this.currentConversationId);
323
+ const message = yield this.api.sendMessage(data, this.currentConversationId);
324
+ this.updateLastMessage(this.currentConversationId, message);
318
325
  });
319
326
  }
320
327
  uploadFile(title, payload, file) {
@@ -506,6 +513,9 @@ __decorate([
506
513
  __decorate([
507
514
  mobx_1.action.bound
508
515
  ], RootStore.prototype, "updateMessages", null);
516
+ __decorate([
517
+ mobx_1.action.bound
518
+ ], RootStore.prototype, "updateLastMessage", null);
509
519
  __decorate([
510
520
  mobx_1.action.bound
511
521
  ], RootStore.prototype, "clearMessages", null);
package/dist/typings.d.ts CHANGED
@@ -260,7 +260,7 @@ export interface Message {
260
260
  authorId: uuid | undefined;
261
261
  sentOn: Date;
262
262
  payload: any;
263
- timeInMs: number;
263
+ timeInMs?: number;
264
264
  }
265
265
  export interface QueuedMessage {
266
266
  message: Message;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botpress/webchat",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "source": "src/index.tsx",
@@ -1,22 +0,0 @@
1
- import * as React from 'react';
2
- export declare class Prepend extends React.Component<Partial<KeyboardElementsProps>> {
3
- render(): JSX.Element;
4
- }
5
- export declare class Append extends React.Component<Partial<KeyboardElementsProps>> {
6
- render(): JSX.Element;
7
- }
8
- export declare class Default extends React.Component<Partial<KeyboardElementsProps>> {
9
- static prependRef: React.RefObject<HTMLDivElement>;
10
- static appendRef: React.RefObject<HTMLDivElement>;
11
- static isReady: () => boolean;
12
- render(): JSX.Element;
13
- }
14
- interface KeyboardElementsProps {
15
- /** When true, the keyboard is appended at the end. Otherwise, it is prepended */
16
- append?: boolean;
17
- index?: number;
18
- visible?: boolean;
19
- /** A keyboard can be any kind of element */
20
- keyboard?: any;
21
- }
22
- export {};
@@ -1,86 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
- Object.defineProperty(o, "default", { enumerable: true, value: v });
11
- }) : function(o, v) {
12
- o["default"] = v;
13
- });
14
- var __importStar = (this && this.__importStar) || function (mod) {
15
- if (mod && mod.__esModule) return mod;
16
- var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
- __setModuleDefault(result, mod);
19
- return result;
20
- };
21
- Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.Default = exports.Append = exports.Prepend = void 0;
23
- const React = __importStar(require("react"));
24
- const ReactDOM = __importStar(require("react-dom"));
25
- class KeyboardElements extends React.Component {
26
- constructor(props) {
27
- super(props);
28
- this.container = document.createElement('div');
29
- }
30
- insertChildAt(child, index = 0, parent) {
31
- if (index >= parent.children.length) {
32
- parent.appendChild(child);
33
- }
34
- else {
35
- parent.insertBefore(child, parent.children[index]);
36
- }
37
- }
38
- componentDidMount() {
39
- if (this.props.append) {
40
- this.insertChildAt(this.container, this.props.index, Default.appendRef.current);
41
- }
42
- else {
43
- this.insertChildAt(this.container, this.props.index, Default.prependRef.current);
44
- }
45
- }
46
- componentWillUnmount() {
47
- var _a, _b;
48
- if (this.props.append) {
49
- (_a = Default.appendRef.current) === null || _a === void 0 ? void 0 : _a.removeChild(this.container);
50
- }
51
- else {
52
- (_b = Default.prependRef.current) === null || _b === void 0 ? void 0 : _b.removeChild(this.container);
53
- }
54
- }
55
- render() {
56
- return ReactDOM.createPortal(this.props.children, this.container);
57
- }
58
- }
59
- class Prepend extends React.Component {
60
- render() {
61
- return (React.createElement("div", null,
62
- this.props.visible && React.createElement(KeyboardElements, { index: this.props.index }, this.props.keyboard),
63
- this.props.children));
64
- }
65
- }
66
- exports.Prepend = Prepend;
67
- class Append extends React.Component {
68
- render() {
69
- return (React.createElement("div", null,
70
- this.props.visible && React.createElement(KeyboardElements, { append: true }, this.props.keyboard),
71
- this.props.children));
72
- }
73
- }
74
- exports.Append = Append;
75
- class Default extends React.Component {
76
- render() {
77
- return (React.createElement("div", { className: 'bpw-keyboard' },
78
- React.createElement("div", { ref: Default.prependRef }),
79
- this.props.children,
80
- React.createElement("div", { ref: Default.appendRef })));
81
- }
82
- }
83
- exports.Default = Default;
84
- Default.prependRef = React.createRef();
85
- Default.appendRef = React.createRef();
86
- Default.isReady = () => Default.appendRef.current !== null;