@ai-matrx/media 0.13.0 → 0.15.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/react.d.cts CHANGED
@@ -1,7 +1,9 @@
1
1
  import * as react from 'react';
2
- import react__default, { SVGProps, HTMLAttributes, InputHTMLAttributes, ReactNode } from 'react';
2
+ import react__default, { SVGProps, HTMLAttributes, InputHTMLAttributes, ReactNode, ComponentProps } from 'react';
3
3
  import { MediaRefLike, DurableSrc, MediaUploadOptions, MediaActionKind } from './index.cjs';
4
4
  import { M as MediaUploadEntry } from './use-media-upload-v5Uq9Ruq.cjs';
5
+ import { Volume2TapButton } from '@ai-matrx/tap-target/buttons';
6
+ import { SpeakRequest, PlaybackItemStatus, PlaybackSnapshot, pausePlayback, resumePlayback, skipPlayback, removePlaybackItem, playPlaybackItem } from '@ai-matrx/media/speech';
5
7
 
6
8
  /**
7
9
  * src/react/cn.ts — conditional class join with last-wins Tailwind conflict
@@ -342,4 +344,59 @@ interface MediaLightboxProps {
342
344
  }
343
345
  declare function MediaLightbox({ open, onClose, mediaRef, fileName, alt, as, autoPlay, playsInline, poster, playbackLabel, actions, hideUnavailableActions, headerExtra, className, }: MediaLightboxProps): react.JSX.Element | null;
344
346
 
345
- export { AlertCircleIcon, ArchiveIcon, BracesIcon, CheckCircle2Icon, CheckIcon, CodeIcon, CopyIcon, DatabaseIcon, DownloadIcon, ExternalLinkIcon, FileAudioIcon, FileCodeIcon, FileIcon, type FileIconProps, FileJsonIcon, FileSpreadsheetIcon, FileTextIcon, FileTypeIcon, FileUploadDropzone, type FileUploadDropzoneActions, type FileUploadDropzoneProps, FileVideoIcon, FolderIcon, FolderOpenIcon, GlobeIcon, ImageIcon, ImageOffIcon, InlineMediaRef, type InlineMediaRefFit, type InlineMediaRefProps, type InlineMediaRefSize, Link2Icon, MediaActionToolbar, type MediaActionToolbarProps, type MediaDropzoneOptions, type MediaDropzoneState, type MediaIconProps, MediaLightbox, type MediaLightboxProps, MediaThumbnail, type MediaThumbnailProps, MusicIcon, PackageBoxIcon, PauseIcon, PenToolIcon, PlayIcon, PlusIcon, SearchIcon, Settings2Icon, Share2Icon, SpinnerIcon, SubtitlesIcon, UploadIcon, UploadProgressList, type UploadProgressListProps, VideoIcon, VideoOffIcon, VolumeXIcon, XIcon, cn, useMediaDropzone };
347
+ type ReadAloudStatus = "idle" | "loading" | "playing" | "paused" | "error";
348
+ type TapVariant = ComponentProps<typeof Volume2TapButton>["variant"];
349
+ type ReadAloudButtonSize = "default" | "compact";
350
+ interface ReadAloudButtonProps {
351
+ status: ReadAloudStatus;
352
+ onPress: () => void;
353
+ /** The host's sentence for the person when `status` is "error". */
354
+ error?: string | null;
355
+ /** Nothing to read (empty text) or the host forbids it right now. */
356
+ disabled?: boolean;
357
+ variant?: TapVariant;
358
+ /**
359
+ * "compact" is the message-footer size: the 32px cell (28px pill) every chat footer control uses,
360
+ * instead of the 38px default box. It sets the geometry only; it wins over `variant`.
361
+ */
362
+ size?: ReadAloudButtonSize;
363
+ className?: string;
364
+ /** Label for the idle state. Default "Read aloud". */
365
+ label?: string;
366
+ }
367
+ declare function ReadAloudButton({ status, onPress, error, disabled, variant: requestedVariant, size, className, label, }: ReadAloudButtonProps): react.JSX.Element;
368
+
369
+ declare function usePlaybackSnapshot(): PlaybackSnapshot;
370
+ type UseSpeechOptions = Omit<SpeakRequest, "text" | "sample"> & {
371
+ /** Re-adopt the queue's active item when it is speaking exactly this text. */
372
+ adoptText?: string;
373
+ };
374
+ declare function useSpeech({ adoptText, ...request }?: UseSpeechOptions): {
375
+ speak: (text: string) => string;
376
+ status: PlaybackItemStatus | null;
377
+ error: string | null;
378
+ itemId: string | null;
379
+ isMine: boolean;
380
+ pause: typeof pausePlayback;
381
+ resume: typeof resumePlayback;
382
+ skip: typeof skipPlayback;
383
+ remove: typeof removePlaybackItem;
384
+ playItem: typeof playPlaybackItem;
385
+ };
386
+ /** The queue's item status in the read-aloud button's vocabulary. */
387
+ declare function readAloudStatusOf(status: PlaybackItemStatus | null): ReadAloudStatus;
388
+ declare function useReadAloud(text: string, options?: UseSpeechOptions): {
389
+ status: ReadAloudStatus;
390
+ error: string | null;
391
+ onPress: () => void;
392
+ speak: (text: string) => string;
393
+ };
394
+
395
+ interface ReadAloudLanguagePickerProps {
396
+ value: string;
397
+ onChange: (code: string) => void;
398
+ className?: string;
399
+ }
400
+ declare function ReadAloudLanguagePicker({ value, onChange, className }: ReadAloudLanguagePickerProps): react.JSX.Element;
401
+
402
+ export { AlertCircleIcon, ArchiveIcon, BracesIcon, CheckCircle2Icon, CheckIcon, CodeIcon, CopyIcon, DatabaseIcon, DownloadIcon, ExternalLinkIcon, FileAudioIcon, FileCodeIcon, FileIcon, type FileIconProps, FileJsonIcon, FileSpreadsheetIcon, FileTextIcon, FileTypeIcon, FileUploadDropzone, type FileUploadDropzoneActions, type FileUploadDropzoneProps, FileVideoIcon, FolderIcon, FolderOpenIcon, GlobeIcon, ImageIcon, ImageOffIcon, InlineMediaRef, type InlineMediaRefFit, type InlineMediaRefProps, type InlineMediaRefSize, Link2Icon, MediaActionToolbar, type MediaActionToolbarProps, type MediaDropzoneOptions, type MediaDropzoneState, type MediaIconProps, MediaLightbox, type MediaLightboxProps, MediaThumbnail, type MediaThumbnailProps, MusicIcon, PackageBoxIcon, PauseIcon, PenToolIcon, PlayIcon, PlusIcon, ReadAloudButton, type ReadAloudButtonProps, type ReadAloudButtonSize, ReadAloudLanguagePicker, type ReadAloudLanguagePickerProps, type ReadAloudStatus, SearchIcon, Settings2Icon, Share2Icon, SpinnerIcon, SubtitlesIcon, UploadIcon, UploadProgressList, type UploadProgressListProps, type UseSpeechOptions, VideoIcon, VideoOffIcon, VolumeXIcon, XIcon, cn, readAloudStatusOf, useMediaDropzone, usePlaybackSnapshot, useReadAloud, useSpeech };
package/dist/react.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import * as react from 'react';
2
- import react__default, { SVGProps, HTMLAttributes, InputHTMLAttributes, ReactNode } from 'react';
2
+ import react__default, { SVGProps, HTMLAttributes, InputHTMLAttributes, ReactNode, ComponentProps } from 'react';
3
3
  import { MediaRefLike, DurableSrc, MediaUploadOptions, MediaActionKind } from './index.js';
4
4
  import { M as MediaUploadEntry } from './use-media-upload-Dg2HSvTq.js';
5
+ import { Volume2TapButton } from '@ai-matrx/tap-target/buttons';
6
+ import { SpeakRequest, PlaybackItemStatus, PlaybackSnapshot, pausePlayback, resumePlayback, skipPlayback, removePlaybackItem, playPlaybackItem } from '@ai-matrx/media/speech';
5
7
 
6
8
  /**
7
9
  * src/react/cn.ts — conditional class join with last-wins Tailwind conflict
@@ -342,4 +344,59 @@ interface MediaLightboxProps {
342
344
  }
343
345
  declare function MediaLightbox({ open, onClose, mediaRef, fileName, alt, as, autoPlay, playsInline, poster, playbackLabel, actions, hideUnavailableActions, headerExtra, className, }: MediaLightboxProps): react.JSX.Element | null;
344
346
 
345
- export { AlertCircleIcon, ArchiveIcon, BracesIcon, CheckCircle2Icon, CheckIcon, CodeIcon, CopyIcon, DatabaseIcon, DownloadIcon, ExternalLinkIcon, FileAudioIcon, FileCodeIcon, FileIcon, type FileIconProps, FileJsonIcon, FileSpreadsheetIcon, FileTextIcon, FileTypeIcon, FileUploadDropzone, type FileUploadDropzoneActions, type FileUploadDropzoneProps, FileVideoIcon, FolderIcon, FolderOpenIcon, GlobeIcon, ImageIcon, ImageOffIcon, InlineMediaRef, type InlineMediaRefFit, type InlineMediaRefProps, type InlineMediaRefSize, Link2Icon, MediaActionToolbar, type MediaActionToolbarProps, type MediaDropzoneOptions, type MediaDropzoneState, type MediaIconProps, MediaLightbox, type MediaLightboxProps, MediaThumbnail, type MediaThumbnailProps, MusicIcon, PackageBoxIcon, PauseIcon, PenToolIcon, PlayIcon, PlusIcon, SearchIcon, Settings2Icon, Share2Icon, SpinnerIcon, SubtitlesIcon, UploadIcon, UploadProgressList, type UploadProgressListProps, VideoIcon, VideoOffIcon, VolumeXIcon, XIcon, cn, useMediaDropzone };
347
+ type ReadAloudStatus = "idle" | "loading" | "playing" | "paused" | "error";
348
+ type TapVariant = ComponentProps<typeof Volume2TapButton>["variant"];
349
+ type ReadAloudButtonSize = "default" | "compact";
350
+ interface ReadAloudButtonProps {
351
+ status: ReadAloudStatus;
352
+ onPress: () => void;
353
+ /** The host's sentence for the person when `status` is "error". */
354
+ error?: string | null;
355
+ /** Nothing to read (empty text) or the host forbids it right now. */
356
+ disabled?: boolean;
357
+ variant?: TapVariant;
358
+ /**
359
+ * "compact" is the message-footer size: the 32px cell (28px pill) every chat footer control uses,
360
+ * instead of the 38px default box. It sets the geometry only; it wins over `variant`.
361
+ */
362
+ size?: ReadAloudButtonSize;
363
+ className?: string;
364
+ /** Label for the idle state. Default "Read aloud". */
365
+ label?: string;
366
+ }
367
+ declare function ReadAloudButton({ status, onPress, error, disabled, variant: requestedVariant, size, className, label, }: ReadAloudButtonProps): react.JSX.Element;
368
+
369
+ declare function usePlaybackSnapshot(): PlaybackSnapshot;
370
+ type UseSpeechOptions = Omit<SpeakRequest, "text" | "sample"> & {
371
+ /** Re-adopt the queue's active item when it is speaking exactly this text. */
372
+ adoptText?: string;
373
+ };
374
+ declare function useSpeech({ adoptText, ...request }?: UseSpeechOptions): {
375
+ speak: (text: string) => string;
376
+ status: PlaybackItemStatus | null;
377
+ error: string | null;
378
+ itemId: string | null;
379
+ isMine: boolean;
380
+ pause: typeof pausePlayback;
381
+ resume: typeof resumePlayback;
382
+ skip: typeof skipPlayback;
383
+ remove: typeof removePlaybackItem;
384
+ playItem: typeof playPlaybackItem;
385
+ };
386
+ /** The queue's item status in the read-aloud button's vocabulary. */
387
+ declare function readAloudStatusOf(status: PlaybackItemStatus | null): ReadAloudStatus;
388
+ declare function useReadAloud(text: string, options?: UseSpeechOptions): {
389
+ status: ReadAloudStatus;
390
+ error: string | null;
391
+ onPress: () => void;
392
+ speak: (text: string) => string;
393
+ };
394
+
395
+ interface ReadAloudLanguagePickerProps {
396
+ value: string;
397
+ onChange: (code: string) => void;
398
+ className?: string;
399
+ }
400
+ declare function ReadAloudLanguagePicker({ value, onChange, className }: ReadAloudLanguagePickerProps): react.JSX.Element;
401
+
402
+ export { AlertCircleIcon, ArchiveIcon, BracesIcon, CheckCircle2Icon, CheckIcon, CodeIcon, CopyIcon, DatabaseIcon, DownloadIcon, ExternalLinkIcon, FileAudioIcon, FileCodeIcon, FileIcon, type FileIconProps, FileJsonIcon, FileSpreadsheetIcon, FileTextIcon, FileTypeIcon, FileUploadDropzone, type FileUploadDropzoneActions, type FileUploadDropzoneProps, FileVideoIcon, FolderIcon, FolderOpenIcon, GlobeIcon, ImageIcon, ImageOffIcon, InlineMediaRef, type InlineMediaRefFit, type InlineMediaRefProps, type InlineMediaRefSize, Link2Icon, MediaActionToolbar, type MediaActionToolbarProps, type MediaDropzoneOptions, type MediaDropzoneState, type MediaIconProps, MediaLightbox, type MediaLightboxProps, MediaThumbnail, type MediaThumbnailProps, MusicIcon, PackageBoxIcon, PauseIcon, PenToolIcon, PlayIcon, PlusIcon, ReadAloudButton, type ReadAloudButtonProps, type ReadAloudButtonSize, ReadAloudLanguagePicker, type ReadAloudLanguagePickerProps, type ReadAloudStatus, SearchIcon, Settings2Icon, Share2Icon, SpinnerIcon, SubtitlesIcon, UploadIcon, UploadProgressList, type UploadProgressListProps, type UseSpeechOptions, VideoIcon, VideoOffIcon, VolumeXIcon, XIcon, cn, readAloudStatusOf, useMediaDropzone, usePlaybackSnapshot, useReadAloud, useSpeech };
package/dist/react.js CHANGED
@@ -2475,6 +2475,209 @@ function MediaLightbox({
2475
2475
  }
2476
2476
  );
2477
2477
  }
2478
+
2479
+ // src/react/read-aloud-button.tsx
2480
+ import { PauseTapButton, TriangleAlertTapButton, Volume2TapButton } from "@ai-matrx/tap-target/buttons";
2481
+ import { jsx as jsx9 } from "react/jsx-runtime";
2482
+ function ReadAloudButton({
2483
+ status,
2484
+ onPress,
2485
+ error,
2486
+ disabled = false,
2487
+ variant: requestedVariant,
2488
+ size = "default",
2489
+ className,
2490
+ label = "Read aloud"
2491
+ }) {
2492
+ const variant = size === "compact" ? "group" : requestedVariant;
2493
+ if (status === "playing") {
2494
+ return /* @__PURE__ */ jsx9(PauseTapButton, { variant, onClick: onPress, disabled, ariaLabel: "Pause", className });
2495
+ }
2496
+ if (status === "error") {
2497
+ return /* @__PURE__ */ jsx9(
2498
+ TriangleAlertTapButton,
2499
+ {
2500
+ variant,
2501
+ onClick: onPress,
2502
+ disabled,
2503
+ ariaLabel: error || "Read aloud failed. Press to try again.",
2504
+ className
2505
+ }
2506
+ );
2507
+ }
2508
+ const loading = status === "loading";
2509
+ return /* @__PURE__ */ jsx9(
2510
+ Volume2TapButton,
2511
+ {
2512
+ variant,
2513
+ onClick: onPress,
2514
+ disabled: disabled || loading,
2515
+ ariaLabel: loading ? "Connecting\u2026" : status === "paused" ? "Resume" : label,
2516
+ className
2517
+ }
2518
+ );
2519
+ }
2520
+
2521
+ // src/react/use-speech.ts
2522
+ import { useCallback as useCallback8, useState as useState10, useSyncExternalStore } from "react";
2523
+ import {
2524
+ getPlaybackSnapshot,
2525
+ pausePlayback,
2526
+ playPlaybackItem,
2527
+ removePlaybackItem,
2528
+ resumePlayback,
2529
+ skipPlayback,
2530
+ subscribePlayback,
2531
+ speak as speakText
2532
+ } from "@ai-matrx/media/speech";
2533
+ var cached = getPlaybackSnapshot();
2534
+ function subscribe(onChange) {
2535
+ return subscribePlayback((snapshot) => {
2536
+ cached = snapshot;
2537
+ onChange();
2538
+ });
2539
+ }
2540
+ var read = () => cached;
2541
+ function usePlaybackSnapshot() {
2542
+ return useSyncExternalStore(subscribe, read, read);
2543
+ }
2544
+ function useSpeech({ adoptText, ...request } = {}) {
2545
+ const { items, currentId } = usePlaybackSnapshot();
2546
+ const [itemId, setItemId] = useState10(null);
2547
+ const adoptedId = !itemId && adoptText && currentId ? items.find(
2548
+ (i) => i.id === currentId && i.text === adoptText && (i.status === "playing" || i.status === "paused" || i.status === "loading")
2549
+ )?.id ?? null : null;
2550
+ const effectiveId = itemId ?? adoptedId;
2551
+ const { engine, voice, purpose, processMarkdown = true, label, dictionarySurfaceKey, language, speed } = request;
2552
+ const speak = useCallback8(
2553
+ (text) => {
2554
+ const { id } = speakText({
2555
+ text,
2556
+ engine,
2557
+ voice,
2558
+ purpose,
2559
+ processMarkdown,
2560
+ label,
2561
+ dictionarySurfaceKey,
2562
+ language,
2563
+ speed
2564
+ });
2565
+ setItemId(id);
2566
+ return id;
2567
+ },
2568
+ [engine, voice, purpose, processMarkdown, label, dictionarySurfaceKey, language, speed]
2569
+ );
2570
+ const item = effectiveId ? items.find((i) => i.id === effectiveId) : void 0;
2571
+ const status = item?.status ?? null;
2572
+ return {
2573
+ speak,
2574
+ status,
2575
+ error: item?.error ?? null,
2576
+ itemId,
2577
+ isMine: effectiveId !== null && effectiveId === currentId,
2578
+ pause: pausePlayback,
2579
+ resume: resumePlayback,
2580
+ skip: skipPlayback,
2581
+ remove: removePlaybackItem,
2582
+ playItem: playPlaybackItem
2583
+ };
2584
+ }
2585
+ function readAloudStatusOf(status) {
2586
+ if (status === "playing") return "playing";
2587
+ if (status === "paused") return "paused";
2588
+ if (status === "loading" || status === "queued") return "loading";
2589
+ if (status === "error") return "error";
2590
+ return "idle";
2591
+ }
2592
+ function useReadAloud(text, options = {}) {
2593
+ const { speak, status, error, pause, resume } = useSpeech({ adoptText: text, ...options });
2594
+ const state = readAloudStatusOf(status);
2595
+ const onPress = useCallback8(() => {
2596
+ if (state === "loading") return;
2597
+ if (state === "playing") void pause();
2598
+ else if (state === "paused") void resume();
2599
+ else if (text.trim()) speak(text);
2600
+ }, [state, text, speak, pause, resume]);
2601
+ return { status: state, error, onPress, speak };
2602
+ }
2603
+
2604
+ // src/react/read-aloud-language-picker.tsx
2605
+ import { Button, Popover, PopoverContent, PopoverTrigger } from "@ai-matrx/design-system";
2606
+ import { Check, Languages } from "lucide-react";
2607
+ import { useState as useState11 } from "react";
2608
+
2609
+ // src/voices/read-aloud-languages.ts
2610
+ var READ_ALOUD_LANGUAGES = [
2611
+ { code: "en", englishName: "English", nativeName: "English" },
2612
+ { code: "es", englishName: "Spanish", nativeName: "Espa\xF1ol" },
2613
+ { code: "fr", englishName: "French", nativeName: "Fran\xE7ais" },
2614
+ { code: "de", englishName: "German", nativeName: "Deutsch" },
2615
+ { code: "it", englishName: "Italian", nativeName: "Italiano" },
2616
+ { code: "pt", englishName: "Portuguese", nativeName: "Portugu\xEAs" },
2617
+ { code: "zh", englishName: "Chinese", nativeName: "\u4E2D\u6587" },
2618
+ { code: "ja", englishName: "Japanese", nativeName: "\u65E5\u672C\u8A9E" },
2619
+ { code: "ko", englishName: "Korean", nativeName: "\uD55C\uAD6D\uC5B4" },
2620
+ { code: "ru", englishName: "Russian", nativeName: "\u0420\u0443\u0441\u0441\u043A\u0438\u0439" },
2621
+ { code: "hi", englishName: "Hindi", nativeName: "\u0939\u093F\u0928\u094D\u0926\u0940" },
2622
+ { code: "nl", englishName: "Dutch", nativeName: "Nederlands" },
2623
+ { code: "pl", englishName: "Polish", nativeName: "Polski" },
2624
+ { code: "sv", englishName: "Swedish", nativeName: "Svenska" },
2625
+ { code: "tr", englishName: "Turkish", nativeName: "T\xFCrk\xE7e" },
2626
+ { code: "fa", englishName: "Persian", nativeName: "\u0641\u0627\u0631\u0633\u06CC" }
2627
+ ];
2628
+ function readAloudLanguage(code) {
2629
+ return READ_ALOUD_LANGUAGES.find((l) => l.code === code) ?? READ_ALOUD_LANGUAGES[0];
2630
+ }
2631
+
2632
+ // src/react/read-aloud-language-picker.tsx
2633
+ import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
2634
+ function ReadAloudLanguagePicker({ value, onChange, className }) {
2635
+ const [open, setOpen] = useState11(false);
2636
+ const selected = readAloudLanguage(value);
2637
+ return /* @__PURE__ */ jsxs7(Popover, { open, onOpenChange: setOpen, children: [
2638
+ /* @__PURE__ */ jsx10(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx10(
2639
+ Button,
2640
+ {
2641
+ variant: "ghost",
2642
+ size: "icon",
2643
+ className: cn("size-7 text-muted-foreground", className),
2644
+ title: `Voice language: ${selected.englishName}`,
2645
+ "aria-label": `Voice language, currently ${selected.englishName}`,
2646
+ children: /* @__PURE__ */ jsx10(Languages, { className: "size-3.5" })
2647
+ }
2648
+ ) }),
2649
+ /* @__PURE__ */ jsxs7(PopoverContent, { className: "max-h-80 w-56 overflow-y-auto p-1", align: "end", children: [
2650
+ /* @__PURE__ */ jsx10("div", { className: "px-2.5 py-1.5 text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: "Voice language" }),
2651
+ READ_ALOUD_LANGUAGES.map((option) => {
2652
+ const isSelected = option.code === selected.code;
2653
+ return /* @__PURE__ */ jsxs7(
2654
+ "button",
2655
+ {
2656
+ type: "button",
2657
+ role: "menuitemradio",
2658
+ "aria-checked": isSelected,
2659
+ onClick: () => {
2660
+ onChange(option.code);
2661
+ setOpen(false);
2662
+ },
2663
+ className: cn(
2664
+ "flex w-full items-center gap-2.5 rounded-md px-2.5 py-1.5 text-left transition-colors hover:bg-accent",
2665
+ isSelected && "bg-accent"
2666
+ ),
2667
+ children: [
2668
+ /* @__PURE__ */ jsxs7("span", { className: "min-w-0 flex-1", children: [
2669
+ /* @__PURE__ */ jsx10("span", { className: "block text-sm", children: option.nativeName }),
2670
+ option.nativeName !== option.englishName ? /* @__PURE__ */ jsx10("span", { className: "block text-[11px] text-muted-foreground", children: option.englishName }) : null
2671
+ ] }),
2672
+ isSelected ? /* @__PURE__ */ jsx10(Check, { className: "size-3.5 shrink-0 text-primary" }) : null
2673
+ ]
2674
+ },
2675
+ option.code
2676
+ );
2677
+ })
2678
+ ] })
2679
+ ] });
2680
+ }
2478
2681
  export {
2479
2682
  AlertCircleIcon,
2480
2683
  ArchiveIcon,
@@ -2511,6 +2714,8 @@ export {
2511
2714
  PenToolIcon,
2512
2715
  PlayIcon,
2513
2716
  PlusIcon,
2717
+ ReadAloudButton,
2718
+ ReadAloudLanguagePicker,
2514
2719
  SearchIcon,
2515
2720
  Settings2Icon,
2516
2721
  Share2Icon,
@@ -2523,6 +2728,10 @@ export {
2523
2728
  VolumeXIcon,
2524
2729
  XIcon,
2525
2730
  cn,
2526
- useMediaDropzone
2731
+ readAloudStatusOf,
2732
+ useMediaDropzone,
2733
+ usePlaybackSnapshot,
2734
+ useReadAloud,
2735
+ useSpeech
2527
2736
  };
2528
2737
  //# sourceMappingURL=react.js.map