@mieweb/ui 0.10.0-dev.10 → 0.10.0-dev.12

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.
Files changed (113) hide show
  1. package/dist/Input-yN516s5_.d.cts +3 -0
  2. package/dist/Input-yN516s5_.d.ts +3 -0
  3. package/dist/ag-grid.d.cts +142 -1
  4. package/dist/ag-grid.d.ts +142 -1
  5. package/dist/components/Alert/index.d.cts +1 -1
  6. package/dist/components/Alert/index.d.ts +1 -1
  7. package/dist/components/AlertDialog/index.d.cts +28 -3
  8. package/dist/components/AlertDialog/index.d.ts +28 -3
  9. package/dist/components/AudioRecorder/index.d.cts +2 -2
  10. package/dist/components/AudioRecorder/index.d.ts +2 -2
  11. package/dist/components/Autocomplete/index.d.cts +8 -2
  12. package/dist/components/Autocomplete/index.d.ts +8 -2
  13. package/dist/components/Avatar/index.d.cts +1 -1
  14. package/dist/components/Avatar/index.d.ts +1 -1
  15. package/dist/components/Badge/index.d.cts +1 -1
  16. package/dist/components/Badge/index.d.ts +1 -1
  17. package/dist/components/BoardView/index.d.cts +91 -4
  18. package/dist/components/BoardView/index.d.ts +91 -4
  19. package/dist/components/Button/index.d.cts +1 -1
  20. package/dist/components/Button/index.d.ts +1 -1
  21. package/dist/components/CalendarView/index.d.cts +1 -2
  22. package/dist/components/CalendarView/index.d.ts +1 -2
  23. package/dist/components/Card/index.d.cts +3 -3
  24. package/dist/components/Card/index.d.ts +3 -3
  25. package/dist/components/Dropdown/index.d.cts +2 -1
  26. package/dist/components/Dropdown/index.d.ts +2 -1
  27. package/dist/components/GanttView/index.d.cts +1 -2
  28. package/dist/components/GanttView/index.d.ts +1 -2
  29. package/dist/components/ListView/index.d.cts +2 -3
  30. package/dist/components/ListView/index.d.ts +2 -3
  31. package/dist/components/MediaEditor/index.d.cts +91 -2
  32. package/dist/components/MediaEditor/index.d.ts +91 -2
  33. package/dist/components/MediaPlayer/index.d.cts +1 -1
  34. package/dist/components/MediaPlayer/index.d.ts +1 -1
  35. package/dist/components/Pagination/index.d.cts +1 -1
  36. package/dist/components/Pagination/index.d.ts +1 -1
  37. package/dist/components/PhoneInput/index.d.cts +36 -3
  38. package/dist/components/PhoneInput/index.d.ts +36 -3
  39. package/dist/components/Progress/index.d.cts +1 -1
  40. package/dist/components/Progress/index.d.ts +1 -1
  41. package/dist/components/Q/index.d.cts +2 -2
  42. package/dist/components/Q/index.d.ts +2 -2
  43. package/dist/components/QuickAction/index.d.cts +1 -1
  44. package/dist/components/QuickAction/index.d.ts +1 -1
  45. package/dist/components/RecordButton/index.d.cts +1 -1
  46. package/dist/components/RecordButton/index.d.ts +1 -1
  47. package/dist/components/RichTextEditor/index.d.cts +7 -2
  48. package/dist/components/RichTextEditor/index.d.ts +7 -2
  49. package/dist/components/ScrollArea/index.d.cts +1 -1
  50. package/dist/components/ScrollArea/index.d.ts +1 -1
  51. package/dist/components/Select/index.d.cts +1 -2
  52. package/dist/components/Select/index.d.ts +1 -2
  53. package/dist/components/Skeleton/index.d.cts +1 -1
  54. package/dist/components/Skeleton/index.d.ts +1 -1
  55. package/dist/components/Slider/index.d.cts +2 -2
  56. package/dist/components/Slider/index.d.ts +2 -2
  57. package/dist/components/Spinner/index.d.cts +2 -2
  58. package/dist/components/Spinner/index.d.ts +2 -2
  59. package/dist/components/SuperChat/index.d.cts +2 -4
  60. package/dist/components/SuperChat/index.d.ts +2 -4
  61. package/dist/components/SuperChat/plugins/index.d.cts +2 -3
  62. package/dist/components/SuperChat/plugins/index.d.ts +2 -3
  63. package/dist/components/Text/index.d.cts +3 -3
  64. package/dist/components/Text/index.d.ts +3 -3
  65. package/dist/components/Textarea/index.d.cts +1 -2
  66. package/dist/components/Textarea/index.d.ts +1 -2
  67. package/dist/components/ThemeProvider/index.d.cts +3 -1
  68. package/dist/components/ThemeProvider/index.d.ts +3 -1
  69. package/dist/components/TranscriptView/index.d.cts +85 -4
  70. package/dist/components/TranscriptView/index.d.ts +85 -4
  71. package/dist/components/ViewSet/index.d.cts +120 -9
  72. package/dist/components/ViewSet/index.d.ts +120 -9
  73. package/dist/components/ViewSwitcher/index.d.cts +4 -40
  74. package/dist/components/ViewSwitcher/index.d.ts +4 -40
  75. package/dist/datavis.d.cts +167 -13
  76. package/dist/datavis.d.ts +167 -13
  77. package/dist/esheet.d.cts +183 -1
  78. package/dist/esheet.d.ts +183 -1
  79. package/dist/hooks/index.d.cts +383 -31
  80. package/dist/hooks/index.d.ts +383 -31
  81. package/dist/index-DoYYWsNc.d.cts +127 -0
  82. package/dist/index-DoYYWsNc.d.ts +127 -0
  83. package/dist/index.d.cts +7592 -414
  84. package/dist/index.d.ts +7592 -414
  85. package/dist/motion.d.cts +186 -2
  86. package/dist/motion.d.ts +186 -2
  87. package/dist/q.d.cts +25 -3
  88. package/dist/q.d.ts +25 -3
  89. package/dist/{types-B97JNRNQ.d.cts → types-DOxdTwmq.d.cts} +170 -2
  90. package/dist/{types-gZXrfLj6.d.ts → types-DOxdTwmq.d.ts} +170 -2
  91. package/dist/{types-CbWXIKbe.d.cts → types-DsdZvEI1.d.cts} +1 -28
  92. package/dist/{types-CbWXIKbe.d.ts → types-DsdZvEI1.d.ts} +1 -28
  93. package/dist/utils/index.d.cts +13 -2
  94. package/dist/utils/index.d.ts +13 -2
  95. package/package.json +3 -2
  96. package/dist/Animated-XmH6k8pZ.d.cts +0 -188
  97. package/dist/Animated-XmH6k8pZ.d.ts +0 -188
  98. package/dist/MedicationEditor-Bp4NLy7y.d.cts +0 -352
  99. package/dist/MedicationEditor-Bp4NLy7y.d.ts +0 -352
  100. package/dist/html-MdxqSzjD.d.cts +0 -13
  101. package/dist/html-MdxqSzjD.d.ts +0 -13
  102. package/dist/orderRows-BUJYgSc7.d.cts +0 -221
  103. package/dist/orderRows-BUJYgSc7.d.ts +0 -221
  104. package/dist/transcript-Cg7uSW-C.d.cts +0 -84
  105. package/dist/transcript-Cg7uSW-C.d.ts +0 -84
  106. package/dist/types-CnPEwzlp.d.cts +0 -254
  107. package/dist/types-CnPEwzlp.d.ts +0 -254
  108. package/dist/useAnchoredPosition-CKwLSQW8.d.cts +0 -76
  109. package/dist/useAnchoredPosition-CKwLSQW8.d.ts +0 -76
  110. package/dist/useTheme-B9SWu6ui.d.cts +0 -24
  111. package/dist/useTheme-B9SWu6ui.d.ts +0 -24
  112. package/dist/useTranscriptEdits-CGzlemHT.d.cts +0 -182
  113. package/dist/useTranscriptEdits-D32bLs0l.d.ts +0 -182
@@ -1,45 +1,28 @@
1
- export { R as ResolvedTheme, T as Theme, u as useTheme } from '../useTheme-B9SWu6ui.cjs';
2
1
  import * as React from 'react';
3
2
  import { RefObject } from 'react';
4
- export { A as AnchoredPlacement, U as UseAnchoredPositionOptions, a as UseAnchoredPositionReturn, u as useAnchoredPosition } from '../useAnchoredPosition-CKwLSQW8.cjs';
5
- export { D as DEFAULT_FILLER_WORDS, a as DEFAULT_MIN_SILENCE_MS, b as DEFAULT_NL_SILENCE_MS, F as FillerAnalysis, S as SilenceThresholdCount, T as TranscriptClipboard, c as TranscriptEditStats, U as UseTranscriptEditsOptions, d as UseTranscriptEditsResult, e as buildPlaybackSegments, g as getSpeedAtIndex, i as initEditableWords, f as insertSilences, u as useTranscriptEdits } from '../useTranscriptEdits-CGzlemHT.cjs';
6
- import '../transcript-Cg7uSW-C.cjs';
7
3
 
8
- interface UseScrollSpyOptions {
9
- /** CSS selector for the elements to observe (e.g. 'h2, h3, h4') */
10
- selectors?: string;
11
- /** Explicit list of element IDs to observe (alternative to selectors) */
12
- ids?: string[];
13
- /** IntersectionObserver root margin (default: '0px 0px -60% 0px') */
14
- rootMargin?: string;
15
- /** IntersectionObserver threshold (default: 0) */
16
- threshold?: number | number[];
17
- /** Scroll container element ref. Defaults to document viewport. */
18
- root?: RefObject<HTMLElement | null>;
19
- /** Whether the hook is active (default: true) */
20
- enabled?: boolean;
21
- }
22
- interface UseScrollSpyReturn {
23
- /** The ID of the currently active (in-view) element */
24
- activeId: string | null;
25
- }
4
+ type Theme = 'light' | 'dark' | 'system';
5
+ type ResolvedTheme = 'light' | 'dark';
26
6
  /**
27
- * Tracks which section is currently in the viewport using IntersectionObserver.
28
- * Pairs naturally with `TableOfContents` to highlight the active heading.
7
+ * Hook for managing theme state with localStorage persistence and system preference support.
29
8
  *
30
9
  * @example
31
10
  * ```tsx
32
- * function DocsPage() {
33
- * const { activeId } = useScrollSpy({ selectors: 'h2, h3' });
11
+ * function ThemeToggle() {
12
+ * const { theme, setTheme, resolvedTheme } = useTheme();
34
13
  * return (
35
- * <aside>
36
- * <TableOfContents activeId={activeId} />
37
- * </aside>
14
+ * <button onClick={() => setTheme(resolvedTheme === 'dark' ? 'light' : 'dark')}>
15
+ * {resolvedTheme === 'dark' ? '☀️' : '🌙'}
16
+ * </button>
38
17
  * );
39
18
  * }
40
19
  * ```
41
20
  */
42
- declare function useScrollSpy({ selectors, ids, rootMargin, threshold, root, enabled, }?: UseScrollSpyOptions): UseScrollSpyReturn;
21
+ declare function useTheme(): {
22
+ theme: Theme;
23
+ setTheme: (newTheme: Theme) => void;
24
+ resolvedTheme: ResolvedTheme;
25
+ };
43
26
 
44
27
  /** Read the current dark-mode state from the document root. */
45
28
  declare function isDarkMode(): boolean;
@@ -125,6 +108,79 @@ declare function usePrefersReducedMotion(): boolean;
125
108
  */
126
109
  declare function useClickOutside<T extends HTMLElement>(ref: RefObject<T | null> | ReadonlyArray<RefObject<HTMLElement | null>>, callback: () => void, enabled?: boolean): void;
127
110
 
111
+ type AnchoredPlacement = 'bottom-start' | 'bottom-end' | 'bottom' | 'top-start' | 'top-end' | 'top' | 'right-start' | 'right-end' | 'right' | 'left-start' | 'left-end' | 'left';
112
+ type AnchoredSide = 'top' | 'bottom' | 'left' | 'right';
113
+ interface UseAnchoredPositionOptions {
114
+ /** Whether the floating element is currently shown */
115
+ open: boolean;
116
+ /** Preferred placement relative to the anchor (flips when out of space) */
117
+ placement?: AnchoredPlacement;
118
+ /** Gap between the anchor and the floating element, in px */
119
+ offset?: number;
120
+ /** Force the floating element to the anchor's width */
121
+ matchWidth?: boolean;
122
+ /** Use the anchor's width as the floating element's minimum width */
123
+ matchMinWidth?: boolean;
124
+ /** Minimum distance from the viewport edges, in px */
125
+ viewportPadding?: number;
126
+ /** Flip to the opposite vertical side when the preferred side is cramped */
127
+ allowFlip?: boolean;
128
+ /** Optional element whose visible rectangle also constrains the popup */
129
+ boundaryRef?: React.RefObject<HTMLElement | null>;
130
+ /**
131
+ * Additional cap on the floating element's height, in px. The height is
132
+ * always clamped to the available viewport space; this only lowers that
133
+ * limit further (omitting it does not remove the viewport constraint).
134
+ */
135
+ maxHeight?: number;
136
+ }
137
+ interface UseAnchoredPositionReturn<TAnchor extends HTMLElement, TFloating extends HTMLElement> {
138
+ /** Attach to the element the popup is anchored to (trigger/input) */
139
+ anchorRef: React.RefObject<TAnchor | null>;
140
+ /** Attach to the floating element (menu/listbox/panel) */
141
+ floatingRef: React.RefObject<TFloating | null>;
142
+ /** Fixed-position style for the floating element — spread onto it */
143
+ style: React.CSSProperties;
144
+ /**
145
+ * Side of the anchor in use after flipping.
146
+ *
147
+ * Widened from `'top' | 'bottom'` to {@link AnchoredSide} in 0.8.0 alongside
148
+ * the new horizontal (`left*` / `right*`) placements — consumers that
149
+ * annotate this as `'top' | 'bottom'` need to widen their annotation.
150
+ */
151
+ actualSide: AnchoredSide;
152
+ /** Recompute the position (e.g. after async content loads) */
153
+ update: () => void;
154
+ }
155
+ /**
156
+ * Positions a floating element (dropdown menu, autocomplete listbox,
157
+ * date-picker calendar, …) relative to an anchor using `position: fixed`,
158
+ * so it is never clipped by `overflow: hidden` ancestors.
159
+ *
160
+ * Render the floating element through `createPortal(..., document.body)`
161
+ * and spread the returned `style` onto it. The hook:
162
+ * - flips vertically when there is not enough space on the preferred side
163
+ * - clamps horizontally to the viewport or optional boundary element
164
+ * - constrains `maxHeight` to the available space (add `overflow-auto`)
165
+ * - tracks scroll, resize, and anchor/content size changes while open
166
+ *
167
+ * @example
168
+ * ```tsx
169
+ * const { anchorRef, floatingRef, style } = useAnchoredPosition<
170
+ * HTMLButtonElement,
171
+ * HTMLDivElement
172
+ * >({ open, placement: 'bottom-start' });
173
+ *
174
+ * <button ref={anchorRef} onClick={() => setOpen(!open)}>Open</button>
175
+ * {open &&
176
+ * createPortal(
177
+ * <div ref={floatingRef} style={style} className="overflow-auto …">…</div>,
178
+ * document.body
179
+ * )}
180
+ * ```
181
+ */
182
+ declare function useAnchoredPosition<TAnchor extends HTMLElement = HTMLElement, TFloating extends HTMLElement = HTMLElement>({ open, placement, offset, matchWidth, matchMinWidth, viewportPadding, allowFlip, boundaryRef, maxHeight, }: UseAnchoredPositionOptions): UseAnchoredPositionReturn<TAnchor, TFloating>;
183
+
128
184
  /**
129
185
  * Hook that triggers a callback when the Escape key is pressed.
130
186
  * Useful for closing modals, dropdowns, and other overlays.
@@ -259,6 +315,42 @@ declare function useIsLargeDesktop(): boolean;
259
315
  /** Returns true when viewport is smaller than 1024px (mobile/tablet) */
260
316
  declare function useIsMobileOrTablet(): boolean;
261
317
 
318
+ interface UseScrollSpyOptions {
319
+ /** CSS selector for the elements to observe (e.g. 'h2, h3, h4') */
320
+ selectors?: string;
321
+ /** Explicit list of element IDs to observe (alternative to selectors) */
322
+ ids?: string[];
323
+ /** IntersectionObserver root margin (default: '0px 0px -60% 0px') */
324
+ rootMargin?: string;
325
+ /** IntersectionObserver threshold (default: 0) */
326
+ threshold?: number | number[];
327
+ /** Scroll container element ref. Defaults to document viewport. */
328
+ root?: RefObject<HTMLElement | null>;
329
+ /** Whether the hook is active (default: true) */
330
+ enabled?: boolean;
331
+ }
332
+ interface UseScrollSpyReturn {
333
+ /** The ID of the currently active (in-view) element */
334
+ activeId: string | null;
335
+ }
336
+ /**
337
+ * Tracks which section is currently in the viewport using IntersectionObserver.
338
+ * Pairs naturally with `TableOfContents` to highlight the active heading.
339
+ *
340
+ * @example
341
+ * ```tsx
342
+ * function DocsPage() {
343
+ * const { activeId } = useScrollSpy({ selectors: 'h2, h3' });
344
+ * return (
345
+ * <aside>
346
+ * <TableOfContents activeId={activeId} />
347
+ * </aside>
348
+ * );
349
+ * }
350
+ * ```
351
+ */
352
+ declare function useScrollSpy({ selectors, ids, rootMargin, threshold, root, enabled, }?: UseScrollSpyOptions): UseScrollSpyReturn;
353
+
262
354
  /** Insert `draggedId` before/after `targetId` in `ids`. */
263
355
  declare function reorderIds(ids: string[], draggedId: string, targetId: string, after: boolean): string[];
264
356
  interface UseDragReorderOptions {
@@ -544,4 +636,264 @@ interface UseMediaTransportReturn {
544
636
  */
545
637
  declare function useMediaTransport(options?: UseMediaTransportOptions): UseMediaTransportReturn;
546
638
 
547
- export { type Direction, type DragOverState, type HoverPreviewState, type KeyboardShortcutOptions, type MediaTransportState, RTL_LOCALES, type UseDragReorderOptions, type UseDragReorderReturn, type UseMediaTransportOptions, type UseMediaTransportReturn, type UseScrollSpyOptions, type UseScrollSpyReturn, type UseStickToBottomOptions, type UseStickToBottomReturn, type UseYouTubeHoverPreviewOptions, type UseYouTubeHoverPreviewReturn, dragIndicatorClasses, isDarkMode, isRtlLocale, reorderIds, useClickOutside, useCommandK, useDirection, useDragReorder, useEscapeKey, useFocusTrap, useIsDarkMode, useIsDesktop, useIsLargeDesktop, useIsMobile, useIsMobileOrTablet, useIsSmallTablet, useIsTablet, useKeyboardShortcut, useLiveAnnouncement, useMediaQuery, useMediaTransport, usePrefersReducedMotion, useScrollSpy, useStickToBottom, useStreamEndedBelowFold, useYouTubeHoverPreview };
639
+ /**
640
+ * Transcript schema for @mieweb/ui media components.
641
+ *
642
+ * Provider-agnostic and persistence-agnostic. Canonical time unit is
643
+ * **milliseconds** (consumers with seconds-based data, e.g. osheet, adapt
644
+ * at the boundary).
645
+ *
646
+ * Shared by TranscriptView, MediaEditor, and useTranscriptEdits.
647
+ */
648
+ /** Type of transcript word - 'word' for spoken content, 'silence' for detected gaps, 'silence-newline' for longer pauses */
649
+ type WordType = 'word' | 'silence' | 'silence-newline';
650
+ interface TranscriptWord {
651
+ text: string;
652
+ startMs: number;
653
+ endMs: number;
654
+ /** References Speaker.id when diarization is available */
655
+ speakerId?: string;
656
+ confidence?: number;
657
+ /** Type of word: 'word' for spoken content, 'silence' for detected gaps. Defaults to 'word' */
658
+ wordType?: WordType;
659
+ }
660
+ /** A diarized segment of contiguous speech (osheet-style granularity) */
661
+ interface TranscriptSegment {
662
+ text: string;
663
+ startMs: number;
664
+ endMs: number;
665
+ /** References Speaker.id when diarization is available */
666
+ speakerId?: string;
667
+ words: TranscriptWord[];
668
+ }
669
+ interface Speaker {
670
+ id: string;
671
+ /** Display name (e.g. 'Clinician', 'Patient'). Hosts may remap via speakerLabels props. */
672
+ name?: string;
673
+ }
674
+ interface Transcript {
675
+ durationMs: number;
676
+ speakers?: Speaker[];
677
+ words: TranscriptWord[];
678
+ segments?: TranscriptSegment[];
679
+ }
680
+ /**
681
+ * An editable word that references the original transcript word.
682
+ * Used in the edited timeline to track deletions and reordering.
683
+ */
684
+ interface EditableWord {
685
+ /** Index into the SILENCE-INSERTED baseline timeline (transcript.words
686
+ * with detected silence pseudo-words interleaved) — NOT into
687
+ * transcript.words. -1 for split/inserted entries with no baseline slot.
688
+ * Consumers persisting edits should key by this timeline. */
689
+ originalIndex: number;
690
+ /** The word data (from original transcript) */
691
+ word: TranscriptWord;
692
+ /** Whether this word is marked as deleted */
693
+ deleted: boolean;
694
+ /** Whether this word was inserted (pasted from clipboard) */
695
+ inserted?: boolean;
696
+ }
697
+ /**
698
+ * Represents a contiguous segment of playback from the original media.
699
+ * Used when playing back an edited timeline with potentially reordered/deleted words.
700
+ */
701
+ interface PlaybackSegment {
702
+ startMs: number;
703
+ endMs: number;
704
+ /** Indices into the editedWords array that this segment covers */
705
+ editedIndices: number[];
706
+ }
707
+ /** Available playback speed multipliers */
708
+ type PlaybackSpeed = 0.5 | 0.75 | 1 | 1.25 | 1.5 | 1.75 | 2;
709
+ /**
710
+ * A speed marker applied to a word in the transcript.
711
+ * The speed applies from this word until the next speed marker or end of transcript.
712
+ */
713
+ interface SpeedMarker {
714
+ /** Index in the editedWords array where the speed marker is placed */
715
+ wordIndex: number;
716
+ /** The playback speed multiplier */
717
+ speed: PlaybackSpeed;
718
+ }
719
+
720
+ /**
721
+ * useTranscriptEdits — headless transcript-editing state hook.
722
+ *
723
+ * Extracted from pulseclip's TranscriptViewer for @mieweb/ui. Holds the
724
+ * edited word timeline (deletions, insertions, text edits, silence
725
+ * splitting), a single-level undo stack, an internal clipboard, speed
726
+ * markers, and derived playback/statistics data.
727
+ *
728
+ * Controlled + persistence-agnostic: no DOM, no fetches. Selection lives in
729
+ * the UI layer — mutations take explicit indices. State flows out via
730
+ * `onChange` and back in via `initialEditedWords` / `initialUndoStack`.
731
+ */
732
+
733
+ /** Default filler words offered for removal */
734
+ declare const DEFAULT_FILLER_WORDS: string[];
735
+ /** Default minimum silence duration in milliseconds to detect and insert */
736
+ declare const DEFAULT_MIN_SILENCE_MS = 400;
737
+ /** Default threshold for "newline" silences - longer pauses that indicate paragraph breaks */
738
+ declare const DEFAULT_NL_SILENCE_MS = 1500;
739
+ /** Clipboard data for cut/copy/paste operations */
740
+ interface TranscriptClipboard {
741
+ words: EditableWord[];
742
+ operation: 'cut' | 'copy';
743
+ }
744
+ /** Count and total duration of silences above a given threshold (seconds) */
745
+ interface SilenceThresholdCount {
746
+ threshold: number;
747
+ count: number;
748
+ durationMs: number;
749
+ }
750
+ /**
751
+ * Builds playback segments from the edited word list.
752
+ * Consecutive words in original order are merged into single segments.
753
+ * Inserted (pasted) words each get their own segment since they may be duplicates.
754
+ */
755
+ declare function buildPlaybackSegments(editedWords: EditableWord[]): PlaybackSegment[];
756
+ /**
757
+ * Get the effective playback speed at a given word index.
758
+ * Finds the most recent speed marker at or before the word index,
759
+ * or returns the default speed if no marker applies.
760
+ */
761
+ declare function getSpeedAtIndex(wordIndex: number, speedMarkers: SpeedMarker[], defaultSpeed: PlaybackSpeed): PlaybackSpeed;
762
+ /**
763
+ * Detect silences between words and return a new array with silence pseudo-words inserted.
764
+ * Silences are detected as gaps between the endMs of one word and startMs of the next.
765
+ * Silences >= nlSilenceMs are marked as 'silence-newline' for visual line breaks.
766
+ */
767
+ declare function insertSilences(words: TranscriptWord[], minSilenceMs?: number, nlSilenceMs?: number): TranscriptWord[];
768
+ /** Initialize editable words from transcript, inserting detected silences */
769
+ declare function initEditableWords(transcript: Transcript, minSilenceMs?: number, nlSilenceMs?: number): EditableWord[];
770
+ interface UseTranscriptEditsOptions {
771
+ /** The source transcript (canonical, immutable) */
772
+ transcript: Transcript;
773
+ /** Initial edited words (from saved edits) */
774
+ initialEditedWords?: EditableWord[];
775
+ /** Initial undo stack (from saved edits) */
776
+ initialUndoStack?: EditableWord[][];
777
+ /** Fired after every mutation (for persistence) */
778
+ onChange?: (editedWords: EditableWord[], undoStack: EditableWord[][]) => void;
779
+ /** Minimum silence duration (ms) to detect and insert. Default 400 */
780
+ minSilenceMs?: number;
781
+ /** Threshold (ms) for "newline" silences (paragraph breaks). Default 1500 */
782
+ nlSilenceMs?: number;
783
+ /** Initial speed markers (from saved edits) */
784
+ initialSpeedMarkers?: SpeedMarker[];
785
+ /** Initial default playback speed (from saved edits). Default 1 */
786
+ initialDefaultSpeed?: PlaybackSpeed;
787
+ }
788
+ interface TranscriptEditStats {
789
+ /** Non-deleted spoken words (silences excluded) */
790
+ activeWordCount: number;
791
+ /** Non-deleted silence entries */
792
+ activeSilenceCount: number;
793
+ /** Deleted spoken words */
794
+ deletedWordCount: number;
795
+ /** Deleted silence entries */
796
+ deletedSilenceCount: number;
797
+ /** Total duration of non-deleted entries, adjusted for speed markers */
798
+ editedDurationMs: number;
799
+ }
800
+ interface FillerAnalysis {
801
+ /** Occurrence count per normalized word (fillers and every active word) */
802
+ matchCounts: Map<string, number>;
803
+ /** Total duration (ms) per normalized word */
804
+ durations: Map<string, number>;
805
+ /** Count + total duration of active silences above each analysis threshold */
806
+ silenceCounts: SilenceThresholdCount[];
807
+ /** The built-in filler word list */
808
+ defaultFillerWords: string[];
809
+ }
810
+ interface UseTranscriptEditsResult {
811
+ /** The edited timeline (words + silence pseudo-words) */
812
+ editedWords: EditableWord[];
813
+ /** Undo snapshots, oldest first */
814
+ undoStack: EditableWord[][];
815
+ /** Internal clipboard from the last cut/copy, or null */
816
+ clipboard: TranscriptClipboard | null;
817
+ /** Whether any edit has been made (deletions, insertions, text edits, speed markers) */
818
+ hasEdits: boolean;
819
+ /** Push the current editedWords onto the undo stack (call before external batch mutations) */
820
+ pushUndo: () => void;
821
+ /** Restore the most recent undo snapshot */
822
+ undo: () => void;
823
+ /** Step forward again after an undo. Cleared by any new edit. */
824
+ redo: () => void;
825
+ /** Whether there is anything to redo */
826
+ canRedo: boolean;
827
+ /** Toggle the deleted flag on a single word */
828
+ toggleWordDeleted: (index: number) => void;
829
+ /**
830
+ * Toggle the deleted state of a contiguous range. The first index acts as
831
+ * the anchor: all words are set to the opposite of the anchor's state
832
+ * (delete all if anchor active, restore all if anchor deleted).
833
+ */
834
+ deleteRange: (indices: number[]) => void;
835
+ /** Cut words at the given indices into the clipboard (marks them deleted) */
836
+ cut: (indices: number[]) => void;
837
+ /** Copy non-deleted words at the given indices into the clipboard */
838
+ copy: (indices: number[]) => void;
839
+ /**
840
+ * Paste the clipboard at a word index. `before` (default true) inserts
841
+ * before the word at `atIndex`; false inserts after it. Returns the index
842
+ * where the first pasted word landed, or null if the clipboard was empty.
843
+ */
844
+ paste: (atIndex: number, before?: boolean) => number | null;
845
+ /** Replace a word's text (no-op if unchanged) */
846
+ setWordText: (index: number, text: string) => void;
847
+ /** Split a silence at the given index into segments with the given durations (seconds) */
848
+ splitSilence: (index: number, durationsSec: number[]) => void;
849
+ /** Toggle the word at the index deleted (editor "delete" action) */
850
+ deleteWord: (index: number) => void;
851
+ /** Replace the entire edit state from an external source (e.g. an editable script view); undo-safe */
852
+ replaceEditedWords: (next: EditableWord[]) => void;
853
+ /** Mark matching filler words (and silences above the given seconds threshold) deleted */
854
+ removeFillers: (fillerWords: string[], removeSilenceAboveSec: number | null) => void;
855
+ /** Rebuild silence detection with new thresholds, preserving word deletions.
856
+ * Not undoable — clears the undo stack (prior snapshots reference the old silence layout). */
857
+ setSilenceThresholds: (minMs: number, nlMs: number) => void;
858
+ /** Current silence detection thresholds (ms) */
859
+ silenceThresholds: {
860
+ minSilenceMs: number;
861
+ nlSilenceMs: number;
862
+ };
863
+ /** Speed markers, sorted by word index */
864
+ speedMarkers: SpeedMarker[];
865
+ /** Default playback speed when no marker applies */
866
+ defaultSpeed: PlaybackSpeed;
867
+ /** Set the default playback speed (undoable) */
868
+ setDefaultSpeed: (speed: PlaybackSpeed) => void;
869
+ /** Add/update/remove a speed marker (re-selecting the same speed removes it; undoable) */
870
+ toggleSpeedMarker: (index: number, speed: PlaybackSpeed) => void;
871
+ /** Remove the speed marker at a word index, if any (undoable) */
872
+ removeSpeedMarker: (index: number) => void;
873
+ /**
874
+ * Apply one speed across an index range (typically the selection): marks the
875
+ * start, restores the prior effective speed after the end. One undo step.
876
+ */
877
+ setSpeedForRange: (startIndex: number, endIndex: number, speed: PlaybackSpeed) => void;
878
+ /** Effective playback speed at a word index */
879
+ getSpeedAtIndex: (index: number) => PlaybackSpeed;
880
+ /** The speed marker at a word index, if any */
881
+ getSpeedMarkerAtIndex: (index: number) => SpeedMarker | undefined;
882
+ /** Contiguous playback segments built from the edited timeline */
883
+ playbackSegments: PlaybackSegment[];
884
+ /** Word/silence counts and speed-adjusted edited duration */
885
+ stats: TranscriptEditStats;
886
+ /** Filler word and silence analysis for removal UIs */
887
+ fillerAnalysis: FillerAnalysis;
888
+ }
889
+ /**
890
+ * Headless transcript-editing hook. See module docs for scope.
891
+ *
892
+ * Undo semantics: each mutation snapshots the full `editedWords` array onto
893
+ * a single-level stack before applying; `undo` pops one snapshot. Speed
894
+ * markers and silence-threshold changes are NOT part of the undo stack
895
+ * (matching the source component).
896
+ */
897
+ declare function useTranscriptEdits(options: UseTranscriptEditsOptions): UseTranscriptEditsResult;
898
+
899
+ export { type AnchoredPlacement, DEFAULT_FILLER_WORDS, DEFAULT_MIN_SILENCE_MS, DEFAULT_NL_SILENCE_MS, type Direction, type DragOverState, type FillerAnalysis, type HoverPreviewState, type KeyboardShortcutOptions, type MediaTransportState, RTL_LOCALES, type ResolvedTheme, type SilenceThresholdCount, type Theme, type TranscriptClipboard, type TranscriptEditStats, type UseAnchoredPositionOptions, type UseAnchoredPositionReturn, type UseDragReorderOptions, type UseDragReorderReturn, type UseMediaTransportOptions, type UseMediaTransportReturn, type UseScrollSpyOptions, type UseScrollSpyReturn, type UseStickToBottomOptions, type UseStickToBottomReturn, type UseTranscriptEditsOptions, type UseTranscriptEditsResult, type UseYouTubeHoverPreviewOptions, type UseYouTubeHoverPreviewReturn, buildPlaybackSegments, dragIndicatorClasses, getSpeedAtIndex, initEditableWords, insertSilences, isDarkMode, isRtlLocale, reorderIds, useAnchoredPosition, useClickOutside, useCommandK, useDirection, useDragReorder, useEscapeKey, useFocusTrap, useIsDarkMode, useIsDesktop, useIsLargeDesktop, useIsMobile, useIsMobileOrTablet, useIsSmallTablet, useIsTablet, useKeyboardShortcut, useLiveAnnouncement, useMediaQuery, useMediaTransport, usePrefersReducedMotion, useScrollSpy, useStickToBottom, useStreamEndedBelowFold, useTheme, useTranscriptEdits, useYouTubeHoverPreview };