@lorikeetai/react-native-sdk 2.0.0 → 2.1.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/README.md CHANGED
@@ -40,9 +40,6 @@ major. Widening them is a change that needs testing, not a version bump.
40
40
  - **`webviewProps` now reach the WebView.** The drop-in previously discarded
41
41
  them. If you were passing props that silently did nothing, they take effect
42
42
  now.
43
- - **Lazy ticket creation.** A ticket is no longer created when the widget opens,
44
- which changes when conversations appear in your Lorikeet queue and in anything
45
- counting them.
46
43
 
47
44
  ## Basic Usage
48
45
 
@@ -52,7 +49,7 @@ import { LorikeetWidgetView } from '@lorikeetai/react-native-sdk'
52
49
  export default function Screen() {
53
50
  return (
54
51
  <LorikeetWidgetView
55
- publicKey="wk_xxx"
52
+ publicKey="your-public-key"
56
53
  authToken="your-auth-token"
57
54
  onWebViewMessage={(event) => console.log(event.nativeEvent.data)}
58
55
  />
@@ -62,7 +59,9 @@ export default function Screen() {
62
59
 
63
60
  **Props:**
64
61
 
65
- - `publicKey` (required): The public key for your Lorikeet account
62
+ - `publicKey` (required): The public key issued for your Lorikeet account. Use the value you were
63
+ given rather than matching a shape: the format has changed over time, and keys issued under
64
+ earlier ones keep working
66
65
  - `authToken` (required): Authentication token for the user
67
66
  - `baseUrl` (optional): Base URL for the Lorikeet API (defaults to `https://chat.lorikeetcx.ai`)
68
67
  - `customisations` (optional): Widget customisation options. Exported as
@@ -79,6 +78,48 @@ export default function Screen() {
79
78
  defaults for media playback, scaling and the loading state can all be
80
79
  overridden; `onMessage` is additive, so the SDK reads the bridge first and
81
80
  then calls yours
81
+ - `avoidKeyboard` (optional): Pads the widget clear of the keyboard. Defaults to
82
+ `true`. See [The keyboard](#the-keyboard)
83
+
84
+ ## The keyboard
85
+
86
+ Android apps drawn edge to edge, the default for current Expo and React Native
87
+ apps, no longer resize their window for the keyboard. `adjustResize` in the
88
+ manifest does not change that. Nothing shrinks the WebView, so the keyboard
89
+ covers the composer and the page is never told the keyboard is there.
90
+
91
+ `LorikeetWidgetView` handles this itself: it wraps its content in a
92
+ `KeyboardAvoidingView` with `behavior="padding"` on both platforms, and measures
93
+ its own position so it works below a navigation header or tab bar. On iOS the
94
+ same padding keeps the page's header on screen. If your screen already makes
95
+ room for the keyboard, pass `avoidKeyboard={false}`, or the widget is padded
96
+ twice.
97
+
98
+ If you compose the parts yourself, the keyboard is yours. Wrap them in a
99
+ `KeyboardAvoidingView` with `behavior="padding"` on both platforms, and set
100
+ `keyboardVerticalOffset` to their distance from the top of the screen.
101
+ `apps/rn-widget-demo/src/components/WidgetPane.tsx` measures it with
102
+ `measureInWindow`. Check it on an Android device: an iOS simulator will not
103
+ show the problem.
104
+
105
+ ## Which header you get
106
+
107
+ `hideHeader` decides whose header the customer sees, not whether there is one.
108
+ `LorikeetWidgetView` defaults it to `true`.
109
+
110
+ | Value | The chat page's header | The SDK's own header |
111
+ | ------------------------------ | ---------------------- | -------------------------------------------------- |
112
+ | `false` | Shown | Not rendered |
113
+ | `true` (the drop-in's default) | Hidden | Rendered, with a new-chat control and nothing else |
114
+
115
+ The page's header is the one carrying the controls for leaving a conversation.
116
+ The SDK's carries a new-chat control and nothing else, so under the drop-in's
117
+ default a host that neither sets `hideHeader: false` nor builds its own header
118
+ leaves the customer no way out of the chat.
119
+
120
+ Which controls the page's header offers, and what they are called, depends on
121
+ the account. Build against "the page's own controls" rather than a fixed set,
122
+ and ask us what your account serves before reproducing them.
82
123
 
83
124
  ## Resuming a conversation
84
125
 
@@ -101,7 +142,7 @@ useEffect(() => {
101
142
 
102
143
  return (
103
144
  <LorikeetWidgetView
104
- publicKey="wk_xxx"
145
+ publicKey="your-public-key"
105
146
  authToken={token}
106
147
  ticketId={resume.ticketId}
107
148
  session={resume.session}
@@ -154,6 +195,43 @@ not learn two vocabularies.
154
195
  `preload_complete` is in the union but cannot reach React Native: the preload
155
196
  page posts it to a web parent only. Do not wait on it.
156
197
 
198
+ ## Minimise, end and new chat
199
+
200
+ `close` means the page hid itself. It may carry a `reason`: a minimise keeps the
201
+ conversation and offers a control that reopens it, an end offers one that starts a
202
+ replacement. Treat an absent reason as an end, because that is what the widget
203
+ does.
204
+
205
+ Do not unmount on `close`. The end and any CSAT rating are still in flight, and
206
+ tearing the page down cancels them. The widget hides the chat itself.
207
+
208
+ While `ticketId` is set, the new-chat control reloads that conversation rather
209
+ than replacing it. To start a new conversation, clear your stored `ticketId` and
210
+ `session` and stop passing them, so the next load falls back to `/widget`.
211
+
212
+ ## The widget handle
213
+
214
+ Pass a `ref` to `LorikeetWidgetView` to reach these.
215
+
216
+ ```tsx
217
+ const widget = useRef<LorikeetWidgetHandle>(null)
218
+
219
+ widget.current?.getConversation() // { minimised, ticketId?, session? } | null
220
+ widget.current?.logout()
221
+ widget.current?.reopen()
222
+ ```
223
+
224
+ - `getConversation()` reports the conversation the widget is on, which is not
225
+ always the one the host passed in: a refused resume is replaced, and a new chat
226
+ replaces the conversation before it. It returns `null` until the page has
227
+ reported a ticket, and it can report a ticket with no session, so it supplements
228
+ the persistence events rather than replacing them.
229
+ - `logout()` clears this customer's chat from the device. See
230
+ [Logging out](#logging-out).
231
+ - `reopen()` shows a minimised conversation again, exactly as the customer left
232
+ it. Nothing reloads and nothing is reported. A no-op unless the widget is
233
+ minimised, so a host with its own launcher can call it unconditionally.
234
+
157
235
  ## Logging out
158
236
 
159
237
  Clearing your own stored `ticketId` and `session` is not enough. The chat keeps
@@ -194,11 +272,26 @@ previous customer's credentials still unlock. Call `logout()` again to retry.
194
272
  That obligation outlives the component. The SDK stores nothing, so a widget
195
273
  unmounted before the clear confirmed, by a screen change or an app restart,
196
274
  comes back with no memory of it and opens a chat normally, on a device whose
197
- cookies were never cleared. Record the failure alongside the conversation you
198
- already store, and call `logout()` again before mounting a chat for anyone
199
- else. We would rather own this than ask you to, and
200
- [ADP-3160](https://linear.app/lorikeet/issue/ADP-3160) is where that storage
201
- layer belongs.
275
+ cookies were never cleared.
276
+
277
+ So persist the logout before you start it, rather than recording that it failed.
278
+ Write down the `baseUrl`, `publicKey` and cookie-store `webviewProps` you are
279
+ clearing, read it at launch, and delete it only once `logged_out` has arrived.
280
+ Waiting for `logout_failed` is not enough on its own: unmounting cancels its
281
+ timer, so an app that dies inside the ten seconds reports nothing at all.
282
+
283
+ Recovery then has to clear that recorded target rather than whatever the next
284
+ launch happens to configure. The page drops only that public key's entry, and
285
+ settings such as `sharedCookiesEnabled` decide which cookie store it reaches, so
286
+ clearing another account or another store reports `logged_out` just the same.
287
+
288
+ It does not need the customer who left, though. The page needs no `authToken`, so
289
+ a host that no longer holds the departed customer's, which after a restart is the
290
+ normal case, can still clear the device by navigating a WebView to
291
+ `getLogoutUrl()` and waiting for its confirmation, as below. Do not reach for the
292
+ drop-in's `logout()` here: it clears for whichever credentials are in props and
293
+ then will not open a chat for them until they change, so calling it with the next
294
+ customer's props locks that customer out instead of the last one.
202
295
 
203
296
  If you compose the parts yourself, build the URL and navigate to it:
204
297
 
@@ -215,8 +308,7 @@ The anonymous customer's long-lived token is deliberately not among these
215
308
  events. It identifies the same anonymous customer for a year, this SDK offers
216
309
  no way to hand one back, and the web SDK keeps the same message inside the
217
310
  frame. A host that genuinely needs it can read the raw bridge, but storing it
218
- is storing a credential, and [ADP-3160](https://linear.app/lorikeet/issue/ADP-3160)
219
- is the work that should remove the need.
311
+ is storing a credential.
220
312
 
221
313
  ## Identity
222
314
 
@@ -307,8 +399,14 @@ WebView component that handles the widget content.
307
399
 
308
400
  ## Development
309
401
 
310
- - Build: `pnpm -w turbo build --filter=@lorikeetai/react-native-sdk`
311
- - Lint: `pnpm --filter=@lorikeetai/react-native-sdk lint`
402
+ This package is outside the root pnpm workspace, on its own lockfile, so run these from `packages/react-native-widget` after `pnpm install` there.
403
+
404
+ - Build: `pnpm build`
405
+ - Test: `pnpm test`
406
+ - Typecheck: `pnpm typecheck`
407
+ - Lint: `pnpm lint`. It uses the root's oxlint and oxfmt, so run `pnpm install` at the repository root first.
408
+
409
+ To release, bump `version` in `package.json` and add its `CHANGELOG.md` section in the same pull request. See `docs/engineering/sdk-releases.md`.
312
410
 
313
411
  ## License
314
412
 
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- //#region \0rolldown/runtime.js
2
+ // \0rolldown/runtime.js
3
3
  var __create = Object.create;
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -25,7 +25,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
25
25
  enumerable: true
26
26
  }) : target, mod));
27
27
 
28
- //#endregion
29
28
  let react = require("react");
30
29
  let react_native = require("react-native");
31
30
  let react_native_safe_area_context = require("react-native-safe-area-context");
@@ -34,7 +33,7 @@ let react_native_svg = require("react-native-svg");
34
33
  react_native_svg = __toESM(react_native_svg, 1);
35
34
  let react_jsx_runtime = require("react/jsx-runtime");
36
35
 
37
- //#region src/bridge.ts
36
+ // src/bridge.ts
38
37
  /**
39
38
  * The public key, base URL and token are one unit, and a conversation belongs to
40
39
  * the credentials that created it. Stamping an observation with them is what
@@ -54,8 +53,7 @@ const resumableConversation = (observed, identity, intendedTicketId) => {
54
53
  };
55
54
  };
56
55
 
57
- //#endregion
58
- //#region src/encode.ts
56
+ // src/encode.ts
59
57
  const BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
60
58
  /**
61
59
  * Base64 of a string's UTF-8 bytes.
@@ -82,8 +80,7 @@ function base64EncodeUtf8(value) {
82
80
  return encoded;
83
81
  }
84
82
 
85
- //#endregion
86
- //#region \0@oxc-project+runtime@0.147.0/helpers/esm/typeof.js
83
+ // \0@oxc-project+runtime@0.156.0/helpers/esm/typeof.js
87
84
  function _typeof(o) {
88
85
  "@babel/helpers - typeof";
89
86
  return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
@@ -93,8 +90,7 @@ function _typeof(o) {
93
90
  }, _typeof(o);
94
91
  }
95
92
 
96
- //#endregion
97
- //#region \0@oxc-project+runtime@0.147.0/helpers/esm/toPrimitive.js
93
+ // \0@oxc-project+runtime@0.156.0/helpers/esm/toPrimitive.js
98
94
  function toPrimitive(t, r) {
99
95
  if ("object" != _typeof(t) || !t) return t;
100
96
  var e = t[Symbol.toPrimitive];
@@ -106,15 +102,13 @@ function toPrimitive(t, r) {
106
102
  return ("string" === r ? String : Number)(t);
107
103
  }
108
104
 
109
- //#endregion
110
- //#region \0@oxc-project+runtime@0.147.0/helpers/esm/toPropertyKey.js
105
+ // \0@oxc-project+runtime@0.156.0/helpers/esm/toPropertyKey.js
111
106
  function toPropertyKey(t) {
112
107
  var i = toPrimitive(t, "string");
113
108
  return "symbol" == _typeof(i) ? i : i + "";
114
109
  }
115
110
 
116
- //#endregion
117
- //#region \0@oxc-project+runtime@0.147.0/helpers/esm/defineProperty.js
111
+ // \0@oxc-project+runtime@0.156.0/helpers/esm/defineProperty.js
118
112
  function _defineProperty(e, r, t) {
119
113
  return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
120
114
  value: t,
@@ -124,8 +118,7 @@ function _defineProperty(e, r, t) {
124
118
  }) : e[r] = t, e;
125
119
  }
126
120
 
127
- //#endregion
128
- //#region src/client.ts
121
+ // src/client.ts
129
122
  var LorikeetClient = class {
130
123
  constructor({ customisations, api_base, metadata, public_key }) {
131
124
  _defineProperty(this, "baseUrl", "https://chat.lorikeetcx.ai");
@@ -171,8 +164,7 @@ var LorikeetClient = class {
171
164
  }
172
165
  };
173
166
 
174
- //#endregion
175
- //#region src/errors.ts
167
+ // src/errors.ts
176
168
  /**
177
169
  * The chat page's error vocabulary, as it reaches a host in
178
170
  * `{ type: 'error', error: CODE }`. Mirrored here because the page publishes it
@@ -219,8 +211,7 @@ function isUnusableConversation(message) {
219
211
  return type === "error" && typeof error === "string" ? isUnusableConversationCode(error) : false;
220
212
  }
221
213
 
222
- //#endregion
223
- //#region src/events.ts
214
+ // src/events.ts
224
215
  const asRecord = (message) => typeof message === "object" && message !== null && !Array.isArray(message) ? message : null;
225
216
  const asNonEmptyString = (value) => typeof value === "string" && value !== "" ? value : null;
226
217
  /**
@@ -298,8 +289,7 @@ const resumedTicketIdFromUri = (uri) => {
298
289
  return (_segments$ = segments[2]) !== null && _segments$ !== void 0 ? _segments$ : null;
299
290
  };
300
291
 
301
- //#endregion
302
- //#region src/lifecycle.ts
292
+ // src/lifecycle.ts
303
293
  /**
304
294
  * The page gives its message stream ten attempts with exponential backoff
305
295
  * capped at 30s (`message-stream-utils.tsx`), so the budget runs out roughly
@@ -336,8 +326,7 @@ const shouldReloadAfterBackground = (backgroundedAt, now, thresholdMs = BACKGROU
336
326
  return elapsed >= thresholdMs;
337
327
  };
338
328
 
339
- //#endregion
340
- //#region src/links.ts
329
+ // src/links.ts
341
330
  /**
342
331
  * Schemes the WebView resolves for itself. None of them is a page the customer
343
332
  * asked to leave the app for, and the OS cannot open them anyway.
@@ -382,8 +371,7 @@ const isInternalNavigation = (url, baseUrl) => {
382
371
  return target.origin === base.origin;
383
372
  };
384
373
 
385
- //#endregion
386
- //#region src/message-circle-plus-icon.tsx
374
+ // src/message-circle-plus-icon.tsx
387
375
  const MessageCirclePlusIcon = ({ size = 24, color = "currentColor", strokeWidth = 2 }) => {
388
376
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native_svg.default, {
389
377
  fill: "none",
@@ -420,13 +408,13 @@ const MessageCirclePlusIcon = ({ size = 24, color = "currentColor", strokeWidth
420
408
  });
421
409
  };
422
410
 
423
- //#endregion
424
- //#region src/widget.tsx
411
+ // src/widget.tsx
425
412
  const stylesheet = react_native.StyleSheet.create({
426
413
  root: {
427
414
  flex: 1,
428
415
  backgroundColor: "#fff"
429
416
  },
417
+ keyboardAvoiding: { flex: 1 },
430
418
  container: {
431
419
  flex: 1,
432
420
  borderRadius: 8,
@@ -530,7 +518,7 @@ const LorikeetWidgetHeader = ({ title, style, icon = /* @__PURE__ */ (0, react_j
530
518
  ]
531
519
  });
532
520
  };
533
- const LorikeetWidgetView = (0, react.forwardRef)(function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, styles, onEvent, onWebViewMessage, ticketId, session, metadata, webviewProps }, ref) {
521
+ const LorikeetWidgetView = (0, react.forwardRef)(function LorikeetWidgetView({ publicKey, baseUrl, authToken, customisations, styles, onEvent, onWebViewMessage, ticketId, session, metadata, webviewProps, avoidKeyboard = true }, ref) {
534
522
  var _customisations$hideH, _customisations$title;
535
523
  const [lorikeetClient, setLorikeetClient] = (0, react.useState)(null);
536
524
  const [loaded, setLoaded] = (0, react.useState)(null);
@@ -541,6 +529,15 @@ const LorikeetWidgetView = (0, react.forwardRef)(function LorikeetWidgetView({ p
541
529
  setGeneration((previous) => previous + 1);
542
530
  }, []);
543
531
  const webViewRef = (0, react.useRef)(null);
532
+ const containerRef = (0, react.useRef)(null);
533
+ const [keyboardOffset, setKeyboardOffset] = (0, react.useState)(0);
534
+ const measureKeyboardOffset = (0, react.useCallback)((event) => {
535
+ var _containerRef$current;
536
+ const { y } = event.nativeEvent.layout;
537
+ (_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 || _containerRef$current.measureInWindow((_x, windowY) => {
538
+ setKeyboardOffset(windowY - y);
539
+ });
540
+ }, []);
544
541
  const [refusedTicketId, setRefusedTicketId] = (0, react.useState)(null);
545
542
  const observedRef = (0, react.useRef)(null);
546
543
  const backgroundedAtRef = (0, react.useRef)(null);
@@ -828,68 +825,75 @@ const LorikeetWidgetView = (0, react.forwardRef)(function LorikeetWidgetView({ p
828
825
  "right"
829
826
  ],
830
827
  style: stylesheet.root,
831
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
832
- style: stylesheet.container,
833
- children: [
834
- hideHeader && closed !== "minimised" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LorikeetWidgetHeader, {
835
- onIconPress: startNewChat,
836
- style: styles === null || styles === void 0 ? void 0 : styles.header,
837
- title: (_customisations$title = customisations === null || customisations === void 0 ? void 0 : customisations.title) !== null && _customisations$title !== void 0 ? _customisations$title : "Lorikeet AI Agent"
838
- }) : null,
839
- closed === "minimised" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableOpacity, {
840
- onPress: reopen,
841
- style: stylesheet.closedControl,
842
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
843
- style: stylesheet.headerText,
844
- children: "Reopen chat"
845
- })
846
- }) : null,
847
- !hideHeader && closed === "ended" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableOpacity, {
848
- onPress: startNewChat,
849
- style: stylesheet.closedControl,
850
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
851
- style: stylesheet.headerText,
852
- children: "Start new chat"
853
- })
854
- }) : null,
855
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
856
- accessibilityElementsHidden: isClosed,
857
- importantForAccessibility: isClosed ? "no-hide-descendants" : "auto",
858
- pointerEvents: isClosed ? "none" : "auto",
859
- style: isClosed ? stylesheet.closed : stylesheet.webView,
860
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LorikeetWidgetWebView, {
861
- baseUrl: lorikeetClient.baseUrl,
862
- onEvent: handleEvent,
863
- ref: webViewRef,
864
- uri: loaded.uri,
865
- webviewProps: {
866
- allowsInlineMediaPlayback: true,
867
- mediaPlaybackRequiresUserAction: false,
868
- scalesPageToFit: true,
869
- startInLoadingState: true,
870
- style: stylesheet.webView,
871
- ...webviewProps,
872
- onMessage: handleMessage,
873
- onRenderProcessGone: (event) => {
874
- var _webviewProps$onRende;
875
- if (generation === generationRef.current) reload();
876
- webviewProps === null || webviewProps === void 0 || (_webviewProps$onRende = webviewProps.onRenderProcessGone) === null || _webviewProps$onRende === void 0 || _webviewProps$onRende.call(webviewProps, event);
877
- },
878
- onContentProcessDidTerminate: (event) => {
879
- var _webviewProps$onConte;
880
- if (generation === generationRef.current) reload();
881
- webviewProps === null || webviewProps === void 0 || (_webviewProps$onConte = webviewProps.onContentProcessDidTerminate) === null || _webviewProps$onConte === void 0 || _webviewProps$onConte.call(webviewProps, event);
828
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.KeyboardAvoidingView, {
829
+ behavior: "padding",
830
+ enabled: avoidKeyboard,
831
+ keyboardVerticalOffset: keyboardOffset,
832
+ onLayout: measureKeyboardOffset,
833
+ style: stylesheet.keyboardAvoiding,
834
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
835
+ ref: containerRef,
836
+ style: stylesheet.container,
837
+ children: [
838
+ hideHeader && closed !== "minimised" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LorikeetWidgetHeader, {
839
+ onIconPress: startNewChat,
840
+ style: styles === null || styles === void 0 ? void 0 : styles.header,
841
+ title: (_customisations$title = customisations === null || customisations === void 0 ? void 0 : customisations.title) !== null && _customisations$title !== void 0 ? _customisations$title : "Lorikeet AI Agent"
842
+ }) : null,
843
+ closed === "minimised" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableOpacity, {
844
+ onPress: reopen,
845
+ style: stylesheet.closedControl,
846
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
847
+ style: stylesheet.headerText,
848
+ children: "Reopen chat"
849
+ })
850
+ }) : null,
851
+ !hideHeader && closed === "ended" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TouchableOpacity, {
852
+ onPress: startNewChat,
853
+ style: stylesheet.closedControl,
854
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
855
+ style: stylesheet.headerText,
856
+ children: "Start new chat"
857
+ })
858
+ }) : null,
859
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
860
+ accessibilityElementsHidden: isClosed,
861
+ importantForAccessibility: isClosed ? "no-hide-descendants" : "auto",
862
+ pointerEvents: isClosed ? "none" : "auto",
863
+ style: isClosed ? stylesheet.closed : stylesheet.webView,
864
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LorikeetWidgetWebView, {
865
+ baseUrl: lorikeetClient.baseUrl,
866
+ onEvent: handleEvent,
867
+ ref: webViewRef,
868
+ uri: loaded.uri,
869
+ webviewProps: {
870
+ allowsInlineMediaPlayback: true,
871
+ mediaPlaybackRequiresUserAction: false,
872
+ scalesPageToFit: true,
873
+ startInLoadingState: true,
874
+ style: stylesheet.webView,
875
+ ...webviewProps,
876
+ onMessage: handleMessage,
877
+ onRenderProcessGone: (event) => {
878
+ var _webviewProps$onRende;
879
+ if (generation === generationRef.current) reload();
880
+ webviewProps === null || webviewProps === void 0 || (_webviewProps$onRende = webviewProps.onRenderProcessGone) === null || _webviewProps$onRende === void 0 || _webviewProps$onRende.call(webviewProps, event);
881
+ },
882
+ onContentProcessDidTerminate: (event) => {
883
+ var _webviewProps$onConte;
884
+ if (generation === generationRef.current) reload();
885
+ webviewProps === null || webviewProps === void 0 || (_webviewProps$onConte = webviewProps.onContentProcessDidTerminate) === null || _webviewProps$onConte === void 0 || _webviewProps$onConte.call(webviewProps, event);
886
+ }
882
887
  }
883
- }
884
- }, `${identity}|${resumingTicketId !== null && resumingTicketId !== void 0 ? resumingTicketId : ""}|${generation}`)
885
- })
886
- ]
888
+ }, `${identity}|${resumingTicketId !== null && resumingTicketId !== void 0 ? resumingTicketId : ""}|${generation}`)
889
+ })
890
+ ]
891
+ })
887
892
  })
888
893
  });
889
894
  });
890
895
  LorikeetWidgetView.displayName = "LorikeetWidgetView";
891
896
 
892
- //#endregion
893
897
  exports.LOGOUT_CONFIRMATION_TIMEOUT_MS = LOGOUT_CONFIRMATION_TIMEOUT_MS;
894
898
  exports.LORIKEET_ERROR_CODES = LORIKEET_ERROR_CODES;
895
899
  exports.LorikeetClient = LorikeetClient;