@ews-admin/global-design-system 1.37.0 → 1.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AssistantChat/ActionTooltip.d.ts +12 -0
- package/dist/components/AssistantChat/ActionTooltip.d.ts.map +1 -0
- package/dist/components/AssistantChat/AssistantChat.d.ts.map +1 -1
- package/dist/components/AssistantChat/AssistantChat.types.d.ts +37 -1
- package/dist/components/AssistantChat/AssistantChat.types.d.ts.map +1 -1
- package/dist/components/AssistantChat/AssistantComposer.d.ts +16 -3
- package/dist/components/AssistantChat/AssistantComposer.d.ts.map +1 -1
- package/dist/components/AssistantChat/AssistantDictationBar.d.ts +28 -0
- package/dist/components/AssistantChat/AssistantDictationBar.d.ts.map +1 -0
- package/dist/components/AssistantChat/AssistantSuggestionCard.d.ts +1 -1
- package/dist/components/AssistantChat/AssistantSuggestionCard.d.ts.map +1 -1
- package/dist/components/AssistantChat/AssistantVoiceMode.d.ts +37 -0
- package/dist/components/AssistantChat/AssistantVoiceMode.d.ts.map +1 -0
- package/dist/components/AssistantChat/assistantMarkdown.d.ts.map +1 -1
- package/dist/components/AssistantChat/index.d.ts +4 -0
- package/dist/components/AssistantChat/index.d.ts.map +1 -1
- package/dist/components/AssistantLauncher/AssistantLauncher.d.ts +15 -0
- package/dist/components/AssistantLauncher/AssistantLauncher.d.ts.map +1 -1
- package/dist/components/AssistantLauncher/index.d.ts +1 -1
- package/dist/components/AssistantLauncher/index.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useSpeechRecognition.d.ts +2 -0
- package/dist/hooks/useSpeechRecognition.d.ts.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +133 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +435 -58
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +437 -56
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/AssistantChat/ActionTooltip.tsx +31 -0
- package/src/components/AssistantChat/AssistantChat.tsx +43 -5
- package/src/components/AssistantChat/AssistantChat.types.ts +27 -1
- package/src/components/AssistantChat/AssistantComposer.tsx +106 -68
- package/src/components/AssistantChat/AssistantDictationBar.tsx +268 -0
- package/src/components/AssistantChat/AssistantSuggestionCard.tsx +7 -6
- package/src/components/AssistantChat/AssistantVoiceMode.tsx +304 -0
- package/src/components/AssistantChat/assistantMarkdown.tsx +4 -1
- package/src/components/AssistantChat/index.ts +4 -0
- package/src/components/AssistantLauncher/AssistantLauncher.tsx +156 -79
- package/src/components/AssistantLauncher/index.ts +1 -1
- package/src/hooks/index.ts +1 -1
- package/src/hooks/useSpeechRecognition.ts +9 -0
- package/src/index.ts +9 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { ArrowUp, AudioLines, Maximize2, Mic, Minimize2, X } from "lucide-react";
|
|
1
|
+
import { ArrowLeft, ArrowUp, AudioLines, Maximize2, Mic, Minimize2, X } from "lucide-react";
|
|
2
2
|
import React, { useCallback, useEffect, useId, useRef, useState } from "react";
|
|
3
3
|
import { listAssistantConversations, saveAssistantConversation } from "../../assistant/store";
|
|
4
|
-
import {
|
|
4
|
+
import { useSpeechSupported } from "../../hooks/useSpeechRecognition";
|
|
5
|
+
import { ActionTooltip } from "../AssistantChat/ActionTooltip";
|
|
6
|
+
import { AssistantDictationBar } from "../AssistantChat/AssistantDictationBar";
|
|
5
7
|
import { cn, generateId } from "../../utils";
|
|
6
8
|
import { AssistantChat } from "../AssistantChat/AssistantChat";
|
|
7
9
|
import type {
|
|
@@ -23,6 +25,15 @@ export interface AssistantLauncherTexts {
|
|
|
23
25
|
collapse?: string;
|
|
24
26
|
/** The history button of the panel; falls back to `texts.recentConversations`. */
|
|
25
27
|
history?: string;
|
|
28
|
+
/** The back button of an embedded page (`embed`); falls back to `close`. */
|
|
29
|
+
backToConversation?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** A page shown in the panel in place of the conversation, e.g. a booking calendar. */
|
|
33
|
+
export interface AssistantEmbeddedPage {
|
|
34
|
+
url: string;
|
|
35
|
+
/** Header title and accessible name of the frame. */
|
|
36
|
+
title: string;
|
|
26
37
|
}
|
|
27
38
|
|
|
28
39
|
export interface AssistantLauncherProps
|
|
@@ -47,6 +58,13 @@ export interface AssistantLauncherProps
|
|
|
47
58
|
className?: string;
|
|
48
59
|
/** Extra classes on the panel (e.g. a wider max width). */
|
|
49
60
|
panelClassName?: string;
|
|
61
|
+
/**
|
|
62
|
+
* A page (iframe) shown in the panel over the conversation, which stays
|
|
63
|
+
* mounted underneath; the back button calls `onEmbedClose`. Null or absent
|
|
64
|
+
* shows the conversation.
|
|
65
|
+
*/
|
|
66
|
+
embed?: AssistantEmbeddedPage | null;
|
|
67
|
+
onEmbedClose?: () => void;
|
|
50
68
|
}
|
|
51
69
|
|
|
52
70
|
const DIRECTION: Record<AssistantChatProps["language"], "ltr" | "rtl"> = {
|
|
@@ -86,6 +104,8 @@ export const AssistantLauncher: React.FC<AssistantLauncherProps> = ({
|
|
|
86
104
|
hidden = false,
|
|
87
105
|
className,
|
|
88
106
|
panelClassName,
|
|
107
|
+
embed,
|
|
108
|
+
onEmbedClose,
|
|
89
109
|
headerAction,
|
|
90
110
|
voice = true,
|
|
91
111
|
conversations: hostConversations,
|
|
@@ -147,11 +167,18 @@ export const AssistantLauncher: React.FC<AssistantLauncherProps> = ({
|
|
|
147
167
|
[setOpen]
|
|
148
168
|
);
|
|
149
169
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
170
|
+
// One click on the bar mic (or the voice button) opens the panel straight in
|
|
171
|
+
// the voice conversation, listening at once.
|
|
172
|
+
const [voiceRequest, setVoiceRequest] = useState<{ id: string } | null>(null);
|
|
173
|
+
const openVoice = useCallback(() => {
|
|
174
|
+
setVoiceRequest({ id: generateId("v") });
|
|
175
|
+
setOpen(true);
|
|
176
|
+
}, [setOpen]);
|
|
177
|
+
const speechSupported = useSpeechSupported();
|
|
178
|
+
// The waveform button records a dictation in the bar itself (recording bar).
|
|
179
|
+
const [dictating, setDictating] = useState(false);
|
|
180
|
+
const [composerDraft, setComposerDraft] = useState<{ id: string; content: string } | null>(null);
|
|
181
|
+
const dictateLabel = chatProps.texts.dictate ?? launcherTexts.voice ?? "Dicter un message";
|
|
155
182
|
|
|
156
183
|
const handleConversationCreated = useCallback(
|
|
157
184
|
(conversation: AssistantConversationSummary) => {
|
|
@@ -218,7 +245,7 @@ export const AssistantLauncher: React.FC<AssistantLauncherProps> = ({
|
|
|
218
245
|
if (hidden) return null;
|
|
219
246
|
|
|
220
247
|
const dir = DIRECTION[chatProps.language];
|
|
221
|
-
const showMic = voice &&
|
|
248
|
+
const showMic = voice && speechSupported;
|
|
222
249
|
const expandLabel = launcherTexts.expand ?? launcherTexts.open;
|
|
223
250
|
const collapseLabel = launcherTexts.collapse ?? launcherTexts.close;
|
|
224
251
|
const texts = launcherTexts.history ? { ...chatProps.texts, history: launcherTexts.history } : chatProps.texts;
|
|
@@ -254,78 +281,89 @@ export const AssistantLauncher: React.FC<AssistantLauncherProps> = ({
|
|
|
254
281
|
>
|
|
255
282
|
{chatProps.texts.brandName.charAt(0)}
|
|
256
283
|
</button>
|
|
257
|
-
{
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
onFocus={() => setOpen(true)}
|
|
267
|
-
onKeyDown={(event) => {
|
|
268
|
-
if (event.key === "Enter" || event.key === " ") {
|
|
269
|
-
event.preventDefault();
|
|
284
|
+
{dictating ? (
|
|
285
|
+
<AssistantDictationBar
|
|
286
|
+
language={chatProps.language}
|
|
287
|
+
texts={chatProps.texts.dictation}
|
|
288
|
+
className="min-w-0 flex-1"
|
|
289
|
+
onCancel={() => setDictating(false)}
|
|
290
|
+
onDone={(text) => {
|
|
291
|
+
setDictating(false);
|
|
292
|
+
if (text) setComposerDraft({ id: generateId("d"), content: text });
|
|
270
293
|
setOpen(true);
|
|
271
|
-
}
|
|
272
|
-
}}
|
|
273
|
-
placeholder={speech.listening ? chatProps.texts.listening : launcherTexts.open}
|
|
274
|
-
aria-label={launcherTexts.open}
|
|
275
|
-
aria-haspopup="dialog"
|
|
276
|
-
aria-controls={panelId}
|
|
277
|
-
className="min-w-0 flex-1 cursor-text bg-transparent py-2 text-lg text-ews-gray-800 placeholder:text-ews-gray-400 focus:outline-none"
|
|
278
|
-
data-testid="assistant-launcher-input"
|
|
279
|
-
/>
|
|
280
|
-
{showMic && (
|
|
281
|
-
<button
|
|
282
|
-
type="button"
|
|
283
|
-
aria-label={chatProps.texts.holdToTalk}
|
|
284
|
-
aria-pressed={speech.listening}
|
|
285
|
-
title={chatProps.texts.holdToTalk}
|
|
286
|
-
onMouseDown={speech.start}
|
|
287
|
-
onMouseUp={speech.stop}
|
|
288
|
-
onMouseLeave={speech.listening ? speech.stop : undefined}
|
|
289
|
-
onTouchStart={speech.start}
|
|
290
|
-
onTouchEnd={speech.stop}
|
|
291
|
-
onKeyDown={(event) => {
|
|
292
|
-
if (event.key === " " || event.key === "Enter") {
|
|
293
|
-
event.preventDefault();
|
|
294
|
-
if (speech.listening) speech.stop();
|
|
295
|
-
else speech.start();
|
|
296
|
-
}
|
|
297
294
|
}}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
295
|
+
onSend={(text) => {
|
|
296
|
+
setDictating(false);
|
|
297
|
+
submitFromBar(text);
|
|
298
|
+
}}
|
|
299
|
+
/>
|
|
300
|
+
) : (
|
|
301
|
+
<>
|
|
302
|
+
{/* The field opens the panel: typing happens in the panel composer, which gets the focus. */}
|
|
303
|
+
<input
|
|
304
|
+
type="text"
|
|
305
|
+
readOnly
|
|
306
|
+
value={draft}
|
|
307
|
+
onMouseDown={(event) => {
|
|
308
|
+
event.preventDefault();
|
|
309
|
+
setOpen(true);
|
|
310
|
+
}}
|
|
311
|
+
onFocus={() => setOpen(true)}
|
|
312
|
+
onKeyDown={(event) => {
|
|
313
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
314
|
+
event.preventDefault();
|
|
315
|
+
setOpen(true);
|
|
316
|
+
}
|
|
317
|
+
}}
|
|
318
|
+
placeholder={launcherTexts.open}
|
|
319
|
+
aria-label={launcherTexts.open}
|
|
320
|
+
aria-haspopup="dialog"
|
|
321
|
+
aria-controls={panelId}
|
|
322
|
+
className="min-w-0 flex-1 cursor-text bg-transparent py-2 text-lg text-ews-gray-800 placeholder:text-ews-gray-400 focus:outline-none"
|
|
323
|
+
data-testid="assistant-launcher-input"
|
|
324
|
+
/>
|
|
325
|
+
{showMic && (
|
|
326
|
+
<ActionTooltip label={chatProps.texts.holdToTalk}>
|
|
327
|
+
{(describedBy) => (
|
|
328
|
+
<button
|
|
329
|
+
type="button"
|
|
330
|
+
aria-label={chatProps.texts.holdToTalk}
|
|
331
|
+
aria-describedby={describedBy}
|
|
332
|
+
onClick={openVoice}
|
|
333
|
+
className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full text-ews-gray-600 transition-colors hover:bg-ews-gray-100 hover:text-ews-primary focus:outline-none focus:ring-2 focus:ring-ews-primary"
|
|
334
|
+
data-testid="assistant-launcher-mic"
|
|
335
|
+
>
|
|
336
|
+
<Mic className="h-5 w-5" aria-hidden="true" />
|
|
337
|
+
</button>
|
|
338
|
+
)}
|
|
339
|
+
</ActionTooltip>
|
|
303
340
|
)}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
341
|
+
<ActionTooltip label={dictateLabel}>
|
|
342
|
+
{(describedBy) => (
|
|
343
|
+
<button
|
|
344
|
+
type="button"
|
|
345
|
+
onClick={speechSupported ? () => setDictating(true) : () => setOpen(true)}
|
|
346
|
+
aria-label={dictateLabel}
|
|
347
|
+
aria-describedby={describedBy}
|
|
348
|
+
className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-ews-gray-100 text-ews-gray-700 transition-colors hover:bg-ews-gray-200 focus:outline-none focus:ring-2 focus:ring-ews-primary"
|
|
349
|
+
data-testid="assistant-launcher-voice"
|
|
350
|
+
>
|
|
351
|
+
<AudioLines className="h-5 w-5" aria-hidden="true" />
|
|
352
|
+
</button>
|
|
353
|
+
)}
|
|
354
|
+
</ActionTooltip>
|
|
355
|
+
<button
|
|
356
|
+
type="button"
|
|
357
|
+
onClick={() => submitFromBar(draft)}
|
|
358
|
+
aria-label={chatProps.texts.send}
|
|
359
|
+
title={chatProps.texts.send}
|
|
360
|
+
className="flex h-11 w-11 shrink-0 items-center justify-center rounded-xl bg-ews-primary text-white shadow-sm transition-colors hover:bg-ews-primary-hover focus:outline-none focus:ring-2 focus:ring-ews-primary focus:ring-offset-1"
|
|
361
|
+
data-testid="assistant-launcher-send"
|
|
362
|
+
>
|
|
363
|
+
<ArrowUp className="h-5 w-5" aria-hidden="true" />
|
|
364
|
+
</button>
|
|
365
|
+
</>
|
|
308
366
|
)}
|
|
309
|
-
<button
|
|
310
|
-
type="button"
|
|
311
|
-
onClick={() => setOpen(true)}
|
|
312
|
-
aria-label={launcherTexts.voice ?? launcherTexts.open}
|
|
313
|
-
title={launcherTexts.voice ?? launcherTexts.open}
|
|
314
|
-
className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-ews-gray-100 text-ews-gray-700 transition-colors hover:bg-ews-gray-200 focus:outline-none focus:ring-2 focus:ring-ews-primary"
|
|
315
|
-
data-testid="assistant-launcher-voice"
|
|
316
|
-
>
|
|
317
|
-
<AudioLines className="h-5 w-5" aria-hidden="true" />
|
|
318
|
-
</button>
|
|
319
|
-
<button
|
|
320
|
-
type="button"
|
|
321
|
-
onClick={() => submitFromBar(draft)}
|
|
322
|
-
aria-label={chatProps.texts.send}
|
|
323
|
-
title={chatProps.texts.send}
|
|
324
|
-
className="flex h-11 w-11 shrink-0 items-center justify-center rounded-xl bg-ews-primary text-white shadow-sm transition-colors hover:bg-ews-primary-hover focus:outline-none focus:ring-2 focus:ring-ews-primary focus:ring-offset-1"
|
|
325
|
-
data-testid="assistant-launcher-send"
|
|
326
|
-
>
|
|
327
|
-
<ArrowUp className="h-5 w-5" aria-hidden="true" />
|
|
328
|
-
</button>
|
|
329
367
|
</div>
|
|
330
368
|
</div>
|
|
331
369
|
)}
|
|
@@ -337,7 +375,9 @@ export const AssistantLauncher: React.FC<AssistantLauncherProps> = ({
|
|
|
337
375
|
data-testid="assistant-launcher-panel"
|
|
338
376
|
>
|
|
339
377
|
<div
|
|
340
|
-
|
|
378
|
+
// Mobile: a dimmed page under a full-screen panel. From tablets up the panel floats over the
|
|
379
|
+
// page, which stays visible (no dimming); a click outside still closes it.
|
|
380
|
+
className="absolute inset-0 bg-black/40 sm:bg-transparent"
|
|
341
381
|
onClick={() => setOpen(false)}
|
|
342
382
|
data-testid="assistant-launcher-overlay"
|
|
343
383
|
/>
|
|
@@ -349,18 +389,55 @@ export const AssistantLauncher: React.FC<AssistantLauncherProps> = ({
|
|
|
349
389
|
aria-label={launcherTexts.open}
|
|
350
390
|
data-expanded={isExpanded}
|
|
351
391
|
className={cn(
|
|
352
|
-
"absolute inset-y-0 end-0 flex w-full flex-col bg-white shadow-2xl
|
|
392
|
+
"absolute inset-y-0 end-0 flex w-full flex-col bg-white shadow-2xl",
|
|
393
|
+
// From tablets up: a floating card (MED-1801, like the Notiwa widget), clear of the top,
|
|
394
|
+
// the bottom and the side of the screen, rounded, with a soft border and shadow.
|
|
395
|
+
"sm:inset-y-auto sm:bottom-6 sm:end-6 sm:overflow-hidden sm:rounded-3xl sm:border sm:border-ews-gray-100",
|
|
396
|
+
"sm:shadow-[0_24px_60px_rgba(15,23,42,0.22)]",
|
|
397
|
+
// Only fixed widths and heights, so expanding animates from one size to the other (a
|
|
398
|
+
// max-width switching to none jumped to full width first).
|
|
399
|
+
"sm:max-w-[calc(100vw-3rem)] sm:transition-[width,height] sm:duration-300 sm:ease-out",
|
|
400
|
+
isExpanded ? "sm:h-[calc(100vh-3rem)]" : "sm:h-[calc(100vh-6rem)]",
|
|
353
401
|
// Expanded: a dashboard reaching the middle of the screen (never full width), tablets and up.
|
|
354
|
-
isExpanded ? "sm:
|
|
402
|
+
isExpanded ? "sm:w-[32rem] md:w-[max(50vw,40rem)]" : "sm:w-[32rem]",
|
|
355
403
|
panelClassName
|
|
356
404
|
)}
|
|
357
405
|
>
|
|
406
|
+
{embed && (
|
|
407
|
+
<div className="absolute inset-0 z-20 flex flex-col bg-white" data-testid="assistant-launcher-embed">
|
|
408
|
+
<div className="flex items-center gap-2 border-b border-ews-gray-100 px-3 py-2">
|
|
409
|
+
<button
|
|
410
|
+
type="button"
|
|
411
|
+
onClick={onEmbedClose}
|
|
412
|
+
aria-label={launcherTexts.backToConversation ?? launcherTexts.close}
|
|
413
|
+
title={launcherTexts.backToConversation ?? launcherTexts.close}
|
|
414
|
+
className="rounded-full p-2 text-ews-gray-500 hover:bg-ews-gray-100 hover:text-ews-gray-900 focus:outline-none focus:ring-2 focus:ring-ews-primary"
|
|
415
|
+
data-testid="assistant-launcher-embed-back"
|
|
416
|
+
>
|
|
417
|
+
<ArrowLeft className="h-5 w-5 rtl:rotate-180" aria-hidden="true" />
|
|
418
|
+
</button>
|
|
419
|
+
<h2 className="min-w-0 flex-1 truncate text-base font-semibold text-ews-gray-900">{embed.title}</h2>
|
|
420
|
+
<button
|
|
421
|
+
type="button"
|
|
422
|
+
onClick={() => setOpen(false)}
|
|
423
|
+
aria-label={launcherTexts.close}
|
|
424
|
+
title={launcherTexts.close}
|
|
425
|
+
className="rounded-full p-2 text-ews-gray-500 hover:bg-ews-gray-100 hover:text-ews-gray-900 focus:outline-none focus:ring-2 focus:ring-ews-primary"
|
|
426
|
+
>
|
|
427
|
+
<X className="h-5 w-5" aria-hidden="true" />
|
|
428
|
+
</button>
|
|
429
|
+
</div>
|
|
430
|
+
<iframe title={embed.title} src={embed.url} className="block w-full flex-1 border-0" />
|
|
431
|
+
</div>
|
|
432
|
+
)}
|
|
358
433
|
<AssistantChat
|
|
359
434
|
{...chatProps}
|
|
360
435
|
texts={texts}
|
|
361
436
|
voice={voice}
|
|
362
437
|
layout={isExpanded ? "wide" : "panel"}
|
|
363
438
|
queuedPrompt={queuedPrompt}
|
|
439
|
+
voiceRequest={voiceRequest}
|
|
440
|
+
composerDraft={composerDraft}
|
|
364
441
|
conversations={hostManaged ? hostConversations : storedConversations}
|
|
365
442
|
activeConversationId={hostManaged ? hostActiveId : managedActiveId}
|
|
366
443
|
initialMessages={hostManaged ? hostInitialMessages : managedMessages}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { AssistantLauncher } from "./AssistantLauncher";
|
|
2
|
-
export type { AssistantLauncherProps, AssistantLauncherTexts } from "./AssistantLauncher";
|
|
2
|
+
export type { AssistantEmbeddedPage, AssistantLauncherProps, AssistantLauncherTexts } from "./AssistantLauncher";
|
package/src/hooks/index.ts
CHANGED
|
@@ -4,5 +4,5 @@ export { useIdleLock } from "./useIdleLock";
|
|
|
4
4
|
export type { UseIdleLockOptions, UseIdleLockResult } from "./useIdleLock";
|
|
5
5
|
export { useSelectField } from "./useSelectField";
|
|
6
6
|
export type { UseSelectFieldProps } from "./useSelectField";
|
|
7
|
-
export { useSpeechRecognition, getSpeechRecognition } from "./useSpeechRecognition";
|
|
7
|
+
export { useSpeechRecognition, useSpeechSupported, getSpeechRecognition } from "./useSpeechRecognition";
|
|
8
8
|
export type { UseSpeechRecognitionOptions } from "./useSpeechRecognition";
|
|
@@ -26,6 +26,15 @@ export function getSpeechRecognition(): SpeechRecognitionCtor | undefined {
|
|
|
26
26
|
return w.SpeechRecognition ?? w.webkitSpeechRecognition;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/** True once mounted in a browser that has the speech recognition API (false on the server). */
|
|
30
|
+
export function useSpeechSupported(): boolean {
|
|
31
|
+
const [supported, setSupported] = useState(false);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
setSupported(getSpeechRecognition() !== undefined);
|
|
34
|
+
}, []);
|
|
35
|
+
return supported;
|
|
36
|
+
}
|
|
37
|
+
|
|
29
38
|
export interface UseSpeechRecognitionOptions {
|
|
30
39
|
/** `fr`, `en`, `ar` or a BCP 47 tag. */
|
|
31
40
|
language: string;
|
package/src/index.ts
CHANGED
|
@@ -65,6 +65,9 @@ export type { PinCodeInputProps } from "./components/PinCodeInput";
|
|
|
65
65
|
export {
|
|
66
66
|
AssistantChat,
|
|
67
67
|
AssistantComposer,
|
|
68
|
+
AssistantVoiceMode,
|
|
69
|
+
AssistantDictationBar,
|
|
70
|
+
toSpokenText,
|
|
68
71
|
AssistantConfirmationCard,
|
|
69
72
|
AssistantConversationList,
|
|
70
73
|
AssistantMessages,
|
|
@@ -90,12 +93,16 @@ export type {
|
|
|
90
93
|
AssistantMessagesProps,
|
|
91
94
|
AssistantSuggestion,
|
|
92
95
|
AssistantSuggestionCardProps,
|
|
96
|
+
AssistantVoiceModeProps,
|
|
97
|
+
AssistantDictationBarProps,
|
|
98
|
+
AssistantDictationTexts,
|
|
99
|
+
AssistantVoiceModeTexts,
|
|
93
100
|
AssistantTransport,
|
|
94
101
|
} from "./components/AssistantChat";
|
|
95
102
|
|
|
96
103
|
// MED-1787: in-app launcher (bottom bar + slide-over) and the shared assistant client
|
|
97
104
|
export { AssistantLauncher } from "./components/AssistantLauncher";
|
|
98
|
-
export type { AssistantLauncherProps, AssistantLauncherTexts } from "./components/AssistantLauncher";
|
|
105
|
+
export type { AssistantEmbeddedPage, AssistantLauncherProps, AssistantLauncherTexts } from "./components/AssistantLauncher";
|
|
99
106
|
export {
|
|
100
107
|
ASSISTANT_CLIENT_ID_KEY,
|
|
101
108
|
ASSISTANT_CONVERSATIONS_KEY,
|
|
@@ -162,6 +169,7 @@ export {
|
|
|
162
169
|
useMediaQuery,
|
|
163
170
|
useSelectField,
|
|
164
171
|
useSpeechRecognition,
|
|
172
|
+
useSpeechSupported,
|
|
165
173
|
getSpeechRecognition,
|
|
166
174
|
} from "./hooks";
|
|
167
175
|
export type {
|