@lorikeetai/react-native-sdk 2.1.0 → 2.2.0-beta.2
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 +213 -0
- package/dist/customisations-BTaJ84md.d.cts +137 -0
- package/dist/customisations-BTaJ84md.d.cts.map +1 -0
- package/dist/customisations-BTaJ84md.d.ts +137 -0
- package/dist/customisations-BTaJ84md.d.ts.map +1 -0
- package/dist/index.cjs +2 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -135
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +1 -135
- package/dist/index.d.ts.map +1 -1
- package/dist/rolldown-runtime-xuxB8TGW.cjs +32 -0
- package/dist/voice.cjs +772 -0
- package/dist/voice.cjs.map +1 -0
- package/dist/voice.d.cts +83 -0
- package/dist/voice.d.cts.map +1 -0
- package/dist/voice.d.ts +83 -0
- package/dist/voice.d.ts.map +1 -0
- package/dist/voice.js +768 -0
- package/dist/voice.js.map +1 -0
- package/package.json +32 -3
package/README.md
CHANGED
|
@@ -397,6 +397,219 @@ WebView component that handles the widget content.
|
|
|
397
397
|
- `webviewProps` (optional): Passed through to the webview component. The SDK
|
|
398
398
|
adds external-link handling on `onNavigationStateChange` and then calls yours
|
|
399
399
|
|
|
400
|
+
## Voice calls (beta)
|
|
401
|
+
|
|
402
|
+
`@lorikeetai/react-native-sdk/voice` runs a Lorikeet voice call inside your
|
|
403
|
+
app with native audio, so the customer can keep talking while the app is in
|
|
404
|
+
the background. It is a beta. Install it from the `beta` tag, and expect its
|
|
405
|
+
API to change before it is stable.
|
|
406
|
+
|
|
407
|
+
Nothing here touches the chat widget. Only the `voice` entry point loads
|
|
408
|
+
LiveKit, so an app that never imports it installs nothing new and needs no
|
|
409
|
+
native rebuild.
|
|
410
|
+
|
|
411
|
+
### Install
|
|
412
|
+
|
|
413
|
+
The LiveKit packages are optional peer dependencies, so install them yourself:
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
pnpm add @lorikeetai/react-native-sdk@beta \
|
|
417
|
+
@livekit/react-native@^3.1.0 \
|
|
418
|
+
@livekit/react-native-webrtc@^150.1.0 \
|
|
419
|
+
livekit-client@^2.20.0
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
`@livekit/react-native` depends on `@livekit/components-react`, which needs
|
|
423
|
+
`react-dom`. Install the `react-dom` version that matches your `react`, or the
|
|
424
|
+
package manager may pick a newer one that your `react` does not satisfy.
|
|
425
|
+
|
|
426
|
+
Do not install `@livekit/krisp-noise-filter`. The call does not use it, and
|
|
427
|
+
its license is not open source.
|
|
428
|
+
|
|
429
|
+
Voice requires React Native 0.79 or later, though the chat widget's peer range
|
|
430
|
+
is unchanged. The `voice` subpath is in the package's `exports` map, and 0.79
|
|
431
|
+
ships the first Metro (0.82) that reads that map by default. TypeScript reads
|
|
432
|
+
it with `moduleResolution` set to `bundler` or `node16`, and Expo's base
|
|
433
|
+
`tsconfig` uses `bundler`.
|
|
434
|
+
|
|
435
|
+
### Native setup
|
|
436
|
+
|
|
437
|
+
These are native modules. Expo Go does not include them, so use a
|
|
438
|
+
[development build](https://docs.expo.dev/develop/development-builds/introduction/)
|
|
439
|
+
on Expo, and rebuild native code after installing.
|
|
440
|
+
|
|
441
|
+
With Expo SDK 56 or later, add the two config plugins, the iOS microphone
|
|
442
|
+
string and audio background mode, and the Android audio permissions to
|
|
443
|
+
`app.json`, then run `expo prebuild`:
|
|
444
|
+
|
|
445
|
+
```bash
|
|
446
|
+
npx expo install @livekit/react-native-expo-plugin @config-plugins/react-native-webrtc
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
```json
|
|
450
|
+
{
|
|
451
|
+
"expo": {
|
|
452
|
+
"platforms": ["ios", "android"],
|
|
453
|
+
"plugins": [
|
|
454
|
+
"@livekit/react-native-expo-plugin",
|
|
455
|
+
"@config-plugins/react-native-webrtc"
|
|
456
|
+
],
|
|
457
|
+
"ios": {
|
|
458
|
+
"infoPlist": {
|
|
459
|
+
"NSMicrophoneUsageDescription": "Talk to our support team.",
|
|
460
|
+
"UIBackgroundModes": ["audio"]
|
|
461
|
+
}
|
|
462
|
+
},
|
|
463
|
+
"android": {
|
|
464
|
+
"permissions": [
|
|
465
|
+
"android.permission.RECORD_AUDIO",
|
|
466
|
+
"android.permission.MODIFY_AUDIO_SETTINGS"
|
|
467
|
+
]
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
Set `platforms` to iOS and Android. Expo treats an app with `react-dom`
|
|
474
|
+
installed as web-capable, so `expo export` would also try a web bundle, which
|
|
475
|
+
LiveKit's native modules cannot build.
|
|
476
|
+
|
|
477
|
+
Use version 1.1.0 or later of `@livekit/react-native-expo-plugin`. It adds the
|
|
478
|
+
`livekit/podspecs` CocoaPods source, which LiveKit's iOS pods need once
|
|
479
|
+
CocoaPods trunk stops accepting new pods on 2 December 2026.
|
|
480
|
+
|
|
481
|
+
Without Expo, follow LiveKit's
|
|
482
|
+
[installation steps](https://github.com/livekit/client-sdk-react-native#installation).
|
|
483
|
+
Add the `livekit/podspecs` source to your `Podfile`, call
|
|
484
|
+
`LiveKitReactNative.setup` in `MainApplication` and `LivekitReactNative.setup`
|
|
485
|
+
in `AppDelegate`, and add the same permissions and background mode as above.
|
|
486
|
+
|
|
487
|
+
On Android, the microphone keeps working in the background only while your
|
|
488
|
+
app runs a foreground service of type `microphone`, which the SDK does not
|
|
489
|
+
start for you. Without one, the agent can still be heard, but the customer's
|
|
490
|
+
microphone goes silent when the app leaves the foreground.
|
|
491
|
+
|
|
492
|
+
### Usage
|
|
493
|
+
|
|
494
|
+
Your backend creates the session with
|
|
495
|
+
`POST /v1/conversation/voice/web/create`, using your API credentials, and
|
|
496
|
+
returns its `{ conversationId, wsUrl, token }` to the app. Never put your API
|
|
497
|
+
credentials in the app.
|
|
498
|
+
|
|
499
|
+
### Call screen
|
|
500
|
+
|
|
501
|
+
`LorikeetCallView` draws the web Voice Widget's call screen, with its copy.
|
|
502
|
+
It shows the logo, the title, the call status and clock, the call wave, and
|
|
503
|
+
the start, mute, speaker and end buttons. Every control has an accessibility
|
|
504
|
+
label, and screen readers hear each change in the call.
|
|
505
|
+
|
|
506
|
+
```tsx
|
|
507
|
+
import { LorikeetCallView } from '@lorikeetai/react-native-sdk/voice'
|
|
508
|
+
|
|
509
|
+
const getSession = async () => {
|
|
510
|
+
const response = await fetch('https://api.example.com/support/call', {
|
|
511
|
+
method: 'POST',
|
|
512
|
+
})
|
|
513
|
+
if (response.status === 404) return null
|
|
514
|
+
if (!response.ok) throw new Error(`Call session: ${response.status}`)
|
|
515
|
+
return response.json()
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
export function SupportCallScreen() {
|
|
519
|
+
return (
|
|
520
|
+
<LorikeetCallView
|
|
521
|
+
customisations={{
|
|
522
|
+
title: 'Acme support',
|
|
523
|
+
theme: { brandColor: '214 100% 50%' },
|
|
524
|
+
}}
|
|
525
|
+
getSession={getSession}
|
|
526
|
+
/>
|
|
527
|
+
)
|
|
528
|
+
}
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
The view runs the call itself, so the call ends when the view unmounts. To
|
|
532
|
+
keep a call going across screens, run `useLorikeetCall` above them and build
|
|
533
|
+
the screen yourself.
|
|
534
|
+
|
|
535
|
+
It takes the hook's `getSession` and `onError`, a `style` for its outer view,
|
|
536
|
+
and these `customisations`, as the chat widget reads them:
|
|
537
|
+
|
|
538
|
+
- `title`: the heading. Defaults to "Lorikeet AI Agent".
|
|
539
|
+
- `logoUrl`: the image above the heading, PNG, JPEG or SVG. Defaults to the
|
|
540
|
+
Lorikeet mark. An SVG is drawn only when the URL's path ends in `.svg`.
|
|
541
|
+
- `useSubtleBranding`: hides "Powered by Lorikeet".
|
|
542
|
+
- `theme`: `colorMode`, `brandColor`, `brandAccentColor`, `subtleBrandColor`,
|
|
543
|
+
`backgroundColor`, `textColor` and `inverseTextColor`, as the web Voice
|
|
544
|
+
Widget reads them. `background` and `headerBackground` apply when they are
|
|
545
|
+
plain colours. React Native cannot draw a CSS gradient, so a gradient falls
|
|
546
|
+
back to `backgroundColor` or `brandAccentColor`. `fontFamily` and `fontUrl`
|
|
547
|
+
do not apply.
|
|
548
|
+
|
|
549
|
+
### Your own call screen
|
|
550
|
+
|
|
551
|
+
`useLorikeetCall` runs the call without any UI.
|
|
552
|
+
|
|
553
|
+
```tsx
|
|
554
|
+
import { Button, Text, View } from 'react-native'
|
|
555
|
+
|
|
556
|
+
import { useLorikeetCall } from '@lorikeetai/react-native-sdk/voice'
|
|
557
|
+
|
|
558
|
+
export function SupportCall() {
|
|
559
|
+
const call = useLorikeetCall({
|
|
560
|
+
getSession: async () => {
|
|
561
|
+
const response = await fetch('https://api.example.com/support/call', {
|
|
562
|
+
method: 'POST',
|
|
563
|
+
})
|
|
564
|
+
if (response.status === 404) return null
|
|
565
|
+
if (!response.ok) throw new Error(`Call session: ${response.status}`)
|
|
566
|
+
return response.json()
|
|
567
|
+
},
|
|
568
|
+
onError: (cause) => console.warn('Support call failed', cause),
|
|
569
|
+
})
|
|
570
|
+
|
|
571
|
+
return (
|
|
572
|
+
<View>
|
|
573
|
+
<Text>{call.state}</Text>
|
|
574
|
+
{call.state === 'idle' || call.state === 'error' ? (
|
|
575
|
+
<Button title="Start call" onPress={() => void call.start()} />
|
|
576
|
+
) : (
|
|
577
|
+
<Button title="End call" onPress={call.end} />
|
|
578
|
+
)}
|
|
579
|
+
</View>
|
|
580
|
+
)
|
|
581
|
+
}
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
`useLorikeetCall({ getSession, onError })` returns:
|
|
585
|
+
|
|
586
|
+
- `state`: `idle`, `starting`, `connecting`, `active` or `error`, as in the web
|
|
587
|
+
Voice Widget. `starting` covers asking for the microphone and fetching the
|
|
588
|
+
session, and `connecting` covers joining the call.
|
|
589
|
+
- `error`: why the call is in `error`. `microphone_denied` means the customer
|
|
590
|
+
refused the microphone, or it is off for the app in the device's settings.
|
|
591
|
+
`not_available` means `getSession` returned `null`. `failed` is anything
|
|
592
|
+
else, and `onError` receives its cause. `microphone_system_denied` is the web
|
|
593
|
+
Voice Widget's code for a browser blocked by the operating system, and a
|
|
594
|
+
mobile device never reports it.
|
|
595
|
+
- `start()`: start a call from `idle` or `error`. The hook asks for microphone
|
|
596
|
+
access before it calls `getSession`, so a refusal starts no conversation.
|
|
597
|
+
- `end()`: hang up, or abandon a call still starting. The call also ends, and
|
|
598
|
+
returns to `idle`, when the agent leaves.
|
|
599
|
+
- `ended`: whether the last call ended after it began connecting.
|
|
600
|
+
- `microphoneMuted` and `setMicrophoneMuted(muted)`: mute the customer.
|
|
601
|
+
- `speakerMuted` and `setSpeakerMuted(muted)`: mute the agent.
|
|
602
|
+
|
|
603
|
+
The call has no live transcript. The conversation is in Lorikeet under its
|
|
604
|
+
`conversationId`.
|
|
605
|
+
|
|
606
|
+
If your app already calls LiveKit's `registerGlobals()`, the hook leaves your
|
|
607
|
+
configuration alone. Otherwise the hook calls it when the first call starts.
|
|
608
|
+
|
|
609
|
+
The hook owns the native audio session for the length of a call and stops it
|
|
610
|
+
when the call ends. An app that runs its own LiveKit call at the same time
|
|
611
|
+
should not use the hook.
|
|
612
|
+
|
|
400
613
|
## Development
|
|
401
614
|
|
|
402
615
|
This package is outside the root pnpm workspace, on its own lockfile, so run these from `packages/react-native-widget` after `pnpm install` there.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the chat page accepts as `customisations`, as the SDK's own types.
|
|
3
|
+
*
|
|
4
|
+
* A copy of the web SDK's shape rather than an import of it. The web SDK is a
|
|
5
|
+
* browser bundle an app has no reason to install, and importing a type from it
|
|
6
|
+
* left the published `dist/index.d.ts` referencing a module consumers do not
|
|
7
|
+
* have: `Customisations` then degraded to `any` and typed nothing.
|
|
8
|
+
* `ConversationMetadata` is duplicated here for the same reason.
|
|
9
|
+
*
|
|
10
|
+
* `src/customisations.web-sdk-parity.ts` fails `typecheck` if the two drift. Not
|
|
11
|
+
* the build: that file is unreachable from `index.ts`, so the declaration build
|
|
12
|
+
* never sees it.
|
|
13
|
+
*
|
|
14
|
+
* Fields that only mean something on a web page are kept so the page's behaviour
|
|
15
|
+
* is unchanged and so a host sharing one configuration object with its web
|
|
16
|
+
* widget still type-checks. The viewport sizes, the launcher button and `mode`
|
|
17
|
+
* are all read by the web SDK rather than by the page, so none of them reaches
|
|
18
|
+
* anything this SDK renders.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Sizing for one viewport. Mostly desktop: the page is full-screen on mobile, so
|
|
22
|
+
* `height`, `width` and `borderRadius` are read for `desktop` alone, while
|
|
23
|
+
* `topClearance` and `default_open` are read for whichever viewport applies.
|
|
24
|
+
*/
|
|
25
|
+
interface ViewportCustomisations {
|
|
26
|
+
/** Clamped to a 2rem maximum. */
|
|
27
|
+
borderRadius?: string;
|
|
28
|
+
default_open?: boolean;
|
|
29
|
+
/** Clamped to the viewport minus `topClearance`, and to a 20rem minimum. */
|
|
30
|
+
height?: string;
|
|
31
|
+
/** Reserved space above the widget. Desktop default 6.5rem. */
|
|
32
|
+
topClearance?: string;
|
|
33
|
+
width?: string;
|
|
34
|
+
}
|
|
35
|
+
interface Customisations {
|
|
36
|
+
/** Falls back to the logo image. */
|
|
37
|
+
avatarUrl?: string;
|
|
38
|
+
botName?: string;
|
|
39
|
+
desktop?: ViewportCustomisations;
|
|
40
|
+
/**
|
|
41
|
+
* Which header the customer gets, not whether there is one. `true` hides the
|
|
42
|
+
* page's own; `false` keeps it, and with it the page's way out of a
|
|
43
|
+
* conversation. Ending and minimising are what that header is for, and which
|
|
44
|
+
* controls it offers depends on the subscriber's configuration, so hiding it
|
|
45
|
+
* leaves the customer no way to end or minimise unless the host supplies one.
|
|
46
|
+
*
|
|
47
|
+
* What replaces a hidden one is the host's business, so there is no one
|
|
48
|
+
* default to quote. `LorikeetWidgetView` substitutes its own header, a title
|
|
49
|
+
* and new chat, and does so when this is omitted. `LorikeetClient` only
|
|
50
|
+
* serialises the flag and renders nothing, so a composed host keeps the page's
|
|
51
|
+
* header unless it asks for it to go, and must render `LorikeetWidgetHeader`
|
|
52
|
+
* itself when it does.
|
|
53
|
+
*/
|
|
54
|
+
hideHeader?: boolean;
|
|
55
|
+
/** @default '_blank' */
|
|
56
|
+
linkTarget?: '_blank' | '_parent';
|
|
57
|
+
logoUrl?: string;
|
|
58
|
+
messages?: {
|
|
59
|
+
/** Shown when the widget is in an unexpectedly failed state. */
|
|
60
|
+
failOver?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Shown when live chat has been switched off deliberately. Reachable only
|
|
63
|
+
* where the live agent bridge is on for the subscriber; without it the widget
|
|
64
|
+
* has no unavailable state for this to label.
|
|
65
|
+
*/
|
|
66
|
+
unavailable?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Replaces the line under "Someone is taking a look", for a conversation
|
|
69
|
+
* handed to a person. Say where the reply will come from when the default
|
|
70
|
+
* should not promise it. Shown only where the live chat experience is on,
|
|
71
|
+
* which is what puts the notice on screen in the first place.
|
|
72
|
+
*/
|
|
73
|
+
escalated?: string;
|
|
74
|
+
};
|
|
75
|
+
mobile?: ViewportCustomisations;
|
|
76
|
+
mode?: 'controlled' | 'uncontrolled';
|
|
77
|
+
/**
|
|
78
|
+
* Styling for the launcher button the web widget renders. The React Native
|
|
79
|
+
* SDK renders no launcher, so this reaches the page and does nothing.
|
|
80
|
+
*
|
|
81
|
+
* @danger Experimental and may change.
|
|
82
|
+
*/
|
|
83
|
+
rootElement?: {
|
|
84
|
+
border?: string;
|
|
85
|
+
borderRadius?: string;
|
|
86
|
+
zIndex?: number;
|
|
87
|
+
bottom?: string;
|
|
88
|
+
right?: string;
|
|
89
|
+
/** Any CSS size value. Defaults to 3rem. */
|
|
90
|
+
size?: string;
|
|
91
|
+
};
|
|
92
|
+
/** Show dates as well as times, on every message. */
|
|
93
|
+
showVerboseTimestamps?: boolean;
|
|
94
|
+
theme?: CustomisationTheme;
|
|
95
|
+
title?: string;
|
|
96
|
+
/** @default false */
|
|
97
|
+
useSubtleBranding?: boolean;
|
|
98
|
+
}
|
|
99
|
+
interface CustomisationTheme {
|
|
100
|
+
/**
|
|
101
|
+
* Colour or gradient for the main area. Any colour value, and any gradient
|
|
102
|
+
* function including multiple layers. Image-based backgrounds are not
|
|
103
|
+
* supported. Takes precedence over `backgroundColor`.
|
|
104
|
+
*/
|
|
105
|
+
background?: string;
|
|
106
|
+
backgroundColor?: string;
|
|
107
|
+
/** Accent fill, currently the header. Resolves to a neutral when unset. */
|
|
108
|
+
brandAccentColor?: string;
|
|
109
|
+
brandColor?: string;
|
|
110
|
+
/** @default 'light' */
|
|
111
|
+
colorMode?: 'light' | 'dark';
|
|
112
|
+
fontFamily?: string;
|
|
113
|
+
/**
|
|
114
|
+
* Google Fonts CSS URL declaring the `@font-face` rules for `fontFamily`.
|
|
115
|
+
* The page ships Inter only, so a brand font the device lacks falls back
|
|
116
|
+
* unless its files are loaded. Must be https, host `fonts.googleapis.com`,
|
|
117
|
+
* path `/css` or `/css2`, and carry `family` plus at most a standard
|
|
118
|
+
* `display`. A URL failing any of that is dropped whole rather than trimmed,
|
|
119
|
+
* so one stray query param means no font loads at all.
|
|
120
|
+
*/
|
|
121
|
+
fontUrl?: string;
|
|
122
|
+
/**
|
|
123
|
+
* Colour or gradient for the header, on the same terms as `background`.
|
|
124
|
+
* Takes precedence over `brandAccentColor`.
|
|
125
|
+
*/
|
|
126
|
+
headerBackground?: string;
|
|
127
|
+
/** For text on a dark background. */
|
|
128
|
+
inverseTextColor?: string;
|
|
129
|
+
/** Falls back to the brand colour. */
|
|
130
|
+
linkColor?: string;
|
|
131
|
+
linkHoverColor?: string;
|
|
132
|
+
secondaryBrandColor?: string;
|
|
133
|
+
subtleBrandColor?: string;
|
|
134
|
+
textColor?: string;
|
|
135
|
+
}
|
|
136
|
+
export { Customisations as n, CustomisationTheme as t };
|
|
137
|
+
//# sourceMappingURL=customisations-BTaJ84md.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"customisations-BTaJ84md.d.cts","names":[],"sources":["../src/customisations.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;UAyBU;;EAER;EACA;;EAEA;;EAEA;EACA;;UAGe;;EAEf;EACA;EACA,UAAU;;;;;;;;;;;;;;;EAeV;;EAEA;EACA;EACA;;IAEE;;;;;;IAMA;;;;;;;IAOA;;EAEF,SAAS;EACT;;;;;;;EAOA;IACE;IACA;IACA;IACA;IACA;;IAEA;;;EAGF;EACA,QAAQ;EACR;;EAEA;;UAGe;;;;;;EAMf;EACA;;EAEA;EACA;;EAEA;EACA;;;;;;;;;EASA;;;;;EAKA;;EAEA;;EAEA;EACA;EACA;EACA;EACA"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the chat page accepts as `customisations`, as the SDK's own types.
|
|
3
|
+
*
|
|
4
|
+
* A copy of the web SDK's shape rather than an import of it. The web SDK is a
|
|
5
|
+
* browser bundle an app has no reason to install, and importing a type from it
|
|
6
|
+
* left the published `dist/index.d.ts` referencing a module consumers do not
|
|
7
|
+
* have: `Customisations` then degraded to `any` and typed nothing.
|
|
8
|
+
* `ConversationMetadata` is duplicated here for the same reason.
|
|
9
|
+
*
|
|
10
|
+
* `src/customisations.web-sdk-parity.ts` fails `typecheck` if the two drift. Not
|
|
11
|
+
* the build: that file is unreachable from `index.ts`, so the declaration build
|
|
12
|
+
* never sees it.
|
|
13
|
+
*
|
|
14
|
+
* Fields that only mean something on a web page are kept so the page's behaviour
|
|
15
|
+
* is unchanged and so a host sharing one configuration object with its web
|
|
16
|
+
* widget still type-checks. The viewport sizes, the launcher button and `mode`
|
|
17
|
+
* are all read by the web SDK rather than by the page, so none of them reaches
|
|
18
|
+
* anything this SDK renders.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Sizing for one viewport. Mostly desktop: the page is full-screen on mobile, so
|
|
22
|
+
* `height`, `width` and `borderRadius` are read for `desktop` alone, while
|
|
23
|
+
* `topClearance` and `default_open` are read for whichever viewport applies.
|
|
24
|
+
*/
|
|
25
|
+
interface ViewportCustomisations {
|
|
26
|
+
/** Clamped to a 2rem maximum. */
|
|
27
|
+
borderRadius?: string;
|
|
28
|
+
default_open?: boolean;
|
|
29
|
+
/** Clamped to the viewport minus `topClearance`, and to a 20rem minimum. */
|
|
30
|
+
height?: string;
|
|
31
|
+
/** Reserved space above the widget. Desktop default 6.5rem. */
|
|
32
|
+
topClearance?: string;
|
|
33
|
+
width?: string;
|
|
34
|
+
}
|
|
35
|
+
interface Customisations {
|
|
36
|
+
/** Falls back to the logo image. */
|
|
37
|
+
avatarUrl?: string;
|
|
38
|
+
botName?: string;
|
|
39
|
+
desktop?: ViewportCustomisations;
|
|
40
|
+
/**
|
|
41
|
+
* Which header the customer gets, not whether there is one. `true` hides the
|
|
42
|
+
* page's own; `false` keeps it, and with it the page's way out of a
|
|
43
|
+
* conversation. Ending and minimising are what that header is for, and which
|
|
44
|
+
* controls it offers depends on the subscriber's configuration, so hiding it
|
|
45
|
+
* leaves the customer no way to end or minimise unless the host supplies one.
|
|
46
|
+
*
|
|
47
|
+
* What replaces a hidden one is the host's business, so there is no one
|
|
48
|
+
* default to quote. `LorikeetWidgetView` substitutes its own header, a title
|
|
49
|
+
* and new chat, and does so when this is omitted. `LorikeetClient` only
|
|
50
|
+
* serialises the flag and renders nothing, so a composed host keeps the page's
|
|
51
|
+
* header unless it asks for it to go, and must render `LorikeetWidgetHeader`
|
|
52
|
+
* itself when it does.
|
|
53
|
+
*/
|
|
54
|
+
hideHeader?: boolean;
|
|
55
|
+
/** @default '_blank' */
|
|
56
|
+
linkTarget?: '_blank' | '_parent';
|
|
57
|
+
logoUrl?: string;
|
|
58
|
+
messages?: {
|
|
59
|
+
/** Shown when the widget is in an unexpectedly failed state. */
|
|
60
|
+
failOver?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Shown when live chat has been switched off deliberately. Reachable only
|
|
63
|
+
* where the live agent bridge is on for the subscriber; without it the widget
|
|
64
|
+
* has no unavailable state for this to label.
|
|
65
|
+
*/
|
|
66
|
+
unavailable?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Replaces the line under "Someone is taking a look", for a conversation
|
|
69
|
+
* handed to a person. Say where the reply will come from when the default
|
|
70
|
+
* should not promise it. Shown only where the live chat experience is on,
|
|
71
|
+
* which is what puts the notice on screen in the first place.
|
|
72
|
+
*/
|
|
73
|
+
escalated?: string;
|
|
74
|
+
};
|
|
75
|
+
mobile?: ViewportCustomisations;
|
|
76
|
+
mode?: 'controlled' | 'uncontrolled';
|
|
77
|
+
/**
|
|
78
|
+
* Styling for the launcher button the web widget renders. The React Native
|
|
79
|
+
* SDK renders no launcher, so this reaches the page and does nothing.
|
|
80
|
+
*
|
|
81
|
+
* @danger Experimental and may change.
|
|
82
|
+
*/
|
|
83
|
+
rootElement?: {
|
|
84
|
+
border?: string;
|
|
85
|
+
borderRadius?: string;
|
|
86
|
+
zIndex?: number;
|
|
87
|
+
bottom?: string;
|
|
88
|
+
right?: string;
|
|
89
|
+
/** Any CSS size value. Defaults to 3rem. */
|
|
90
|
+
size?: string;
|
|
91
|
+
};
|
|
92
|
+
/** Show dates as well as times, on every message. */
|
|
93
|
+
showVerboseTimestamps?: boolean;
|
|
94
|
+
theme?: CustomisationTheme;
|
|
95
|
+
title?: string;
|
|
96
|
+
/** @default false */
|
|
97
|
+
useSubtleBranding?: boolean;
|
|
98
|
+
}
|
|
99
|
+
interface CustomisationTheme {
|
|
100
|
+
/**
|
|
101
|
+
* Colour or gradient for the main area. Any colour value, and any gradient
|
|
102
|
+
* function including multiple layers. Image-based backgrounds are not
|
|
103
|
+
* supported. Takes precedence over `backgroundColor`.
|
|
104
|
+
*/
|
|
105
|
+
background?: string;
|
|
106
|
+
backgroundColor?: string;
|
|
107
|
+
/** Accent fill, currently the header. Resolves to a neutral when unset. */
|
|
108
|
+
brandAccentColor?: string;
|
|
109
|
+
brandColor?: string;
|
|
110
|
+
/** @default 'light' */
|
|
111
|
+
colorMode?: 'light' | 'dark';
|
|
112
|
+
fontFamily?: string;
|
|
113
|
+
/**
|
|
114
|
+
* Google Fonts CSS URL declaring the `@font-face` rules for `fontFamily`.
|
|
115
|
+
* The page ships Inter only, so a brand font the device lacks falls back
|
|
116
|
+
* unless its files are loaded. Must be https, host `fonts.googleapis.com`,
|
|
117
|
+
* path `/css` or `/css2`, and carry `family` plus at most a standard
|
|
118
|
+
* `display`. A URL failing any of that is dropped whole rather than trimmed,
|
|
119
|
+
* so one stray query param means no font loads at all.
|
|
120
|
+
*/
|
|
121
|
+
fontUrl?: string;
|
|
122
|
+
/**
|
|
123
|
+
* Colour or gradient for the header, on the same terms as `background`.
|
|
124
|
+
* Takes precedence over `brandAccentColor`.
|
|
125
|
+
*/
|
|
126
|
+
headerBackground?: string;
|
|
127
|
+
/** For text on a dark background. */
|
|
128
|
+
inverseTextColor?: string;
|
|
129
|
+
/** Falls back to the brand colour. */
|
|
130
|
+
linkColor?: string;
|
|
131
|
+
linkHoverColor?: string;
|
|
132
|
+
secondaryBrandColor?: string;
|
|
133
|
+
subtleBrandColor?: string;
|
|
134
|
+
textColor?: string;
|
|
135
|
+
}
|
|
136
|
+
export { Customisations as n, CustomisationTheme as t };
|
|
137
|
+
//# sourceMappingURL=customisations-BTaJ84md.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"customisations-BTaJ84md.d.ts","names":[],"sources":["../src/customisations.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;UAyBU;;EAER;EACA;;EAEA;;EAEA;EACA;;UAGe;;EAEf;EACA;EACA,UAAU;;;;;;;;;;;;;;;EAeV;;EAEA;EACA;EACA;;IAEE;;;;;;IAMA;;;;;;;IAOA;;EAEF,SAAS;EACT;;;;;;;EAOA;IACE;IACA;IACA;IACA;IACA;;IAEA;;;EAGF;EACA,QAAQ;EACR;;EAEA;;UAGe;;;;;;EAMf;EACA;;EAEA;EACA;;EAEA;EACA;;;;;;;;;EASA;;;;;EAKA;;EAEA;;EAEA;EACA;EACA;EACA;EACA"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,36 +1,11 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
|
|
3
|
-
var __create = Object.create;
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
5
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
12
|
-
key = keys[i];
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
14
|
-
__defProp(to, key, {
|
|
15
|
-
get: ((k) => from[k]).bind(null, key),
|
|
16
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
return to;
|
|
22
|
-
};
|
|
23
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
24
|
-
value: mod,
|
|
25
|
-
enumerable: true
|
|
26
|
-
}) : target, mod));
|
|
27
|
-
|
|
2
|
+
const require_rolldown_runtime = require("./rolldown-runtime-xuxB8TGW.cjs");
|
|
28
3
|
let react = require("react");
|
|
29
4
|
let react_native = require("react-native");
|
|
30
5
|
let react_native_safe_area_context = require("react-native-safe-area-context");
|
|
31
6
|
let react_native_webview = require("react-native-webview");
|
|
32
7
|
let react_native_svg = require("react-native-svg");
|
|
33
|
-
react_native_svg = __toESM(react_native_svg, 1);
|
|
8
|
+
react_native_svg = require_rolldown_runtime.__toESM(react_native_svg, 1);
|
|
34
9
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
35
10
|
|
|
36
11
|
// src/bridge.ts
|