@waveform-playlist/annotations 5.3.2 → 6.0.1

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/index.d.mts CHANGED
@@ -1,29 +1,7 @@
1
+ import { AnnotationData, AnnotationAction, AnnotationActionOptions, RenderAnnotationItemProps } from '@waveform-playlist/core';
2
+ export { AnnotationAction, AnnotationActionOptions, AnnotationData, AnnotationEventMap, AnnotationFormat, AnnotationListOptions, RenderAnnotationItemProps } from '@waveform-playlist/core';
1
3
  import React, { FunctionComponent } from 'react';
2
4
 
3
- interface Annotation$1 {
4
- id: string;
5
- start: number;
6
- end: number;
7
- lines: string[];
8
- lang?: string;
9
- }
10
- interface AnnotationFormat {
11
- name: string;
12
- parse: (data: unknown) => Annotation$1[];
13
- serialize: (annotations: Annotation$1[]) => unknown;
14
- }
15
- interface AnnotationListOptions {
16
- editable?: boolean;
17
- linkEndpoints?: boolean;
18
- isContinuousPlay?: boolean;
19
- }
20
- interface AnnotationEventMap {
21
- 'annotation-select': (annotation: Annotation$1) => void;
22
- 'annotation-update': (annotation: Annotation$1) => void;
23
- 'annotation-delete': (id: string) => void;
24
- 'annotation-create': (annotation: Annotation$1) => void;
25
- }
26
-
27
5
  interface AeneasFragment {
28
6
  begin: string;
29
7
  end: string;
@@ -31,33 +9,9 @@ interface AeneasFragment {
31
9
  language: string;
32
10
  lines: string[];
33
11
  }
34
- declare function parseAeneas(data: AeneasFragment): Annotation$1;
35
- declare function serializeAeneas(annotation: Annotation$1): AeneasFragment;
12
+ declare function parseAeneas(data: AeneasFragment): AnnotationData;
13
+ declare function serializeAeneas(annotation: AnnotationData): AeneasFragment;
36
14
 
37
- /**
38
- * Configuration options passed to annotation action handlers
39
- */
40
- interface AnnotationActionOptions {
41
- /** Whether annotation endpoints are linked (moving one endpoint moves the other) */
42
- linkEndpoints?: boolean;
43
- /** Whether to continue playing after an annotation ends */
44
- continuousPlay?: boolean;
45
- /** Additional custom properties */
46
- [key: string]: unknown;
47
- }
48
- interface AnnotationAction {
49
- class?: string;
50
- text?: string;
51
- title: string;
52
- action: (annotation: AnnotationData, index: number, annotations: AnnotationData[], opts: AnnotationActionOptions) => void;
53
- }
54
- interface AnnotationData {
55
- id: string;
56
- start: number;
57
- end: number;
58
- lines: string[];
59
- language?: string;
60
- }
61
15
  interface AnnotationProps {
62
16
  annotation: AnnotationData;
63
17
  index: number;
@@ -104,16 +58,6 @@ interface AnnotationsTrackProps {
104
58
  }
105
59
  declare const AnnotationsTrack: FunctionComponent<AnnotationsTrackProps>;
106
60
 
107
- /**
108
- * Props passed to the renderAnnotationItem function for custom rendering
109
- */
110
- interface RenderAnnotationItemProps {
111
- annotation: AnnotationData;
112
- index: number;
113
- isActive: boolean;
114
- onClick: () => void;
115
- formatTime: (seconds: number) => string;
116
- }
117
61
  interface AnnotationTextProps {
118
62
  annotations: AnnotationData[];
119
63
  activeAnnotationId?: string;
@@ -169,7 +113,7 @@ interface EditableCheckboxProps {
169
113
  declare const EditableCheckbox: React.FC<EditableCheckboxProps>;
170
114
 
171
115
  interface DownloadAnnotationsButtonProps {
172
- annotations: Annotation$1[];
116
+ annotations: AnnotationData[];
173
117
  filename?: string;
174
118
  disabled?: boolean;
175
119
  className?: string;
@@ -177,6 +121,10 @@ interface DownloadAnnotationsButtonProps {
177
121
  }
178
122
  declare const DownloadAnnotationsButton: React.FC<DownloadAnnotationsButtonProps>;
179
123
 
124
+ declare const AnnotationProvider: React.FC<{
125
+ children: React.ReactNode;
126
+ }>;
127
+
180
128
  interface UseAnnotationControlsOptions {
181
129
  initialContinuousPlay?: boolean;
182
130
  initialLinkEndpoints?: boolean;
@@ -185,7 +133,7 @@ interface AnnotationUpdateParams {
185
133
  annotationIndex: number;
186
134
  newTime: number;
187
135
  isDraggingStart: boolean;
188
- annotations: Annotation$1[];
136
+ annotations: AnnotationData[];
189
137
  duration: number;
190
138
  linkEndpoints: boolean;
191
139
  }
@@ -194,7 +142,7 @@ interface UseAnnotationControlsReturn {
194
142
  linkEndpoints: boolean;
195
143
  setContinuousPlay: (value: boolean) => void;
196
144
  setLinkEndpoints: (value: boolean) => void;
197
- updateAnnotationBoundaries: (params: AnnotationUpdateParams) => Annotation$1[];
145
+ updateAnnotationBoundaries: (params: AnnotationUpdateParams) => AnnotationData[];
198
146
  }
199
147
  /**
200
148
  * Hook for managing annotation control state and boundary logic.
@@ -202,4 +150,4 @@ interface UseAnnotationControlsReturn {
202
150
  */
203
151
  declare const useAnnotationControls: (options?: UseAnnotationControlsOptions) => UseAnnotationControlsReturn;
204
152
 
205
- export { type AeneasFragment, Annotation, type AnnotationAction, type AnnotationActionOptions, AnnotationBox, type AnnotationBoxComponentProps, AnnotationBoxesWrapper, type AnnotationBoxesWrapperProps, type AnnotationData, type AnnotationEventMap, type AnnotationFormat, type AnnotationListOptions, type AnnotationProps, AnnotationText, type AnnotationTextProps, type Annotation$1 as AnnotationType, type AnnotationUpdateParams, AnnotationsTrack, type AnnotationsTrackProps, ContinuousPlayCheckbox, type ContinuousPlayCheckboxProps, DownloadAnnotationsButton, type DownloadAnnotationsButtonProps, EditableCheckbox, type EditableCheckboxProps, LinkEndpointsCheckbox, type LinkEndpointsCheckboxProps, type RenderAnnotationItemProps, type UseAnnotationControlsOptions, type UseAnnotationControlsReturn, parseAeneas, serializeAeneas, useAnnotationControls };
153
+ export { type AeneasFragment, Annotation, AnnotationBox, type AnnotationBoxComponentProps, AnnotationBoxesWrapper, type AnnotationBoxesWrapperProps, type AnnotationProps, AnnotationProvider, AnnotationText, type AnnotationTextProps, type AnnotationUpdateParams, AnnotationsTrack, type AnnotationsTrackProps, ContinuousPlayCheckbox, type ContinuousPlayCheckboxProps, DownloadAnnotationsButton, type DownloadAnnotationsButtonProps, EditableCheckbox, type EditableCheckboxProps, LinkEndpointsCheckbox, type LinkEndpointsCheckboxProps, type UseAnnotationControlsOptions, type UseAnnotationControlsReturn, parseAeneas, serializeAeneas, useAnnotationControls };
package/dist/index.d.ts CHANGED
@@ -1,29 +1,7 @@
1
+ import { AnnotationData, AnnotationAction, AnnotationActionOptions, RenderAnnotationItemProps } from '@waveform-playlist/core';
2
+ export { AnnotationAction, AnnotationActionOptions, AnnotationData, AnnotationEventMap, AnnotationFormat, AnnotationListOptions, RenderAnnotationItemProps } from '@waveform-playlist/core';
1
3
  import React, { FunctionComponent } from 'react';
2
4
 
3
- interface Annotation$1 {
4
- id: string;
5
- start: number;
6
- end: number;
7
- lines: string[];
8
- lang?: string;
9
- }
10
- interface AnnotationFormat {
11
- name: string;
12
- parse: (data: unknown) => Annotation$1[];
13
- serialize: (annotations: Annotation$1[]) => unknown;
14
- }
15
- interface AnnotationListOptions {
16
- editable?: boolean;
17
- linkEndpoints?: boolean;
18
- isContinuousPlay?: boolean;
19
- }
20
- interface AnnotationEventMap {
21
- 'annotation-select': (annotation: Annotation$1) => void;
22
- 'annotation-update': (annotation: Annotation$1) => void;
23
- 'annotation-delete': (id: string) => void;
24
- 'annotation-create': (annotation: Annotation$1) => void;
25
- }
26
-
27
5
  interface AeneasFragment {
28
6
  begin: string;
29
7
  end: string;
@@ -31,33 +9,9 @@ interface AeneasFragment {
31
9
  language: string;
32
10
  lines: string[];
33
11
  }
34
- declare function parseAeneas(data: AeneasFragment): Annotation$1;
35
- declare function serializeAeneas(annotation: Annotation$1): AeneasFragment;
12
+ declare function parseAeneas(data: AeneasFragment): AnnotationData;
13
+ declare function serializeAeneas(annotation: AnnotationData): AeneasFragment;
36
14
 
37
- /**
38
- * Configuration options passed to annotation action handlers
39
- */
40
- interface AnnotationActionOptions {
41
- /** Whether annotation endpoints are linked (moving one endpoint moves the other) */
42
- linkEndpoints?: boolean;
43
- /** Whether to continue playing after an annotation ends */
44
- continuousPlay?: boolean;
45
- /** Additional custom properties */
46
- [key: string]: unknown;
47
- }
48
- interface AnnotationAction {
49
- class?: string;
50
- text?: string;
51
- title: string;
52
- action: (annotation: AnnotationData, index: number, annotations: AnnotationData[], opts: AnnotationActionOptions) => void;
53
- }
54
- interface AnnotationData {
55
- id: string;
56
- start: number;
57
- end: number;
58
- lines: string[];
59
- language?: string;
60
- }
61
15
  interface AnnotationProps {
62
16
  annotation: AnnotationData;
63
17
  index: number;
@@ -104,16 +58,6 @@ interface AnnotationsTrackProps {
104
58
  }
105
59
  declare const AnnotationsTrack: FunctionComponent<AnnotationsTrackProps>;
106
60
 
107
- /**
108
- * Props passed to the renderAnnotationItem function for custom rendering
109
- */
110
- interface RenderAnnotationItemProps {
111
- annotation: AnnotationData;
112
- index: number;
113
- isActive: boolean;
114
- onClick: () => void;
115
- formatTime: (seconds: number) => string;
116
- }
117
61
  interface AnnotationTextProps {
118
62
  annotations: AnnotationData[];
119
63
  activeAnnotationId?: string;
@@ -169,7 +113,7 @@ interface EditableCheckboxProps {
169
113
  declare const EditableCheckbox: React.FC<EditableCheckboxProps>;
170
114
 
171
115
  interface DownloadAnnotationsButtonProps {
172
- annotations: Annotation$1[];
116
+ annotations: AnnotationData[];
173
117
  filename?: string;
174
118
  disabled?: boolean;
175
119
  className?: string;
@@ -177,6 +121,10 @@ interface DownloadAnnotationsButtonProps {
177
121
  }
178
122
  declare const DownloadAnnotationsButton: React.FC<DownloadAnnotationsButtonProps>;
179
123
 
124
+ declare const AnnotationProvider: React.FC<{
125
+ children: React.ReactNode;
126
+ }>;
127
+
180
128
  interface UseAnnotationControlsOptions {
181
129
  initialContinuousPlay?: boolean;
182
130
  initialLinkEndpoints?: boolean;
@@ -185,7 +133,7 @@ interface AnnotationUpdateParams {
185
133
  annotationIndex: number;
186
134
  newTime: number;
187
135
  isDraggingStart: boolean;
188
- annotations: Annotation$1[];
136
+ annotations: AnnotationData[];
189
137
  duration: number;
190
138
  linkEndpoints: boolean;
191
139
  }
@@ -194,7 +142,7 @@ interface UseAnnotationControlsReturn {
194
142
  linkEndpoints: boolean;
195
143
  setContinuousPlay: (value: boolean) => void;
196
144
  setLinkEndpoints: (value: boolean) => void;
197
- updateAnnotationBoundaries: (params: AnnotationUpdateParams) => Annotation$1[];
145
+ updateAnnotationBoundaries: (params: AnnotationUpdateParams) => AnnotationData[];
198
146
  }
199
147
  /**
200
148
  * Hook for managing annotation control state and boundary logic.
@@ -202,4 +150,4 @@ interface UseAnnotationControlsReturn {
202
150
  */
203
151
  declare const useAnnotationControls: (options?: UseAnnotationControlsOptions) => UseAnnotationControlsReturn;
204
152
 
205
- export { type AeneasFragment, Annotation, type AnnotationAction, type AnnotationActionOptions, AnnotationBox, type AnnotationBoxComponentProps, AnnotationBoxesWrapper, type AnnotationBoxesWrapperProps, type AnnotationData, type AnnotationEventMap, type AnnotationFormat, type AnnotationListOptions, type AnnotationProps, AnnotationText, type AnnotationTextProps, type Annotation$1 as AnnotationType, type AnnotationUpdateParams, AnnotationsTrack, type AnnotationsTrackProps, ContinuousPlayCheckbox, type ContinuousPlayCheckboxProps, DownloadAnnotationsButton, type DownloadAnnotationsButtonProps, EditableCheckbox, type EditableCheckboxProps, LinkEndpointsCheckbox, type LinkEndpointsCheckboxProps, type RenderAnnotationItemProps, type UseAnnotationControlsOptions, type UseAnnotationControlsReturn, parseAeneas, serializeAeneas, useAnnotationControls };
153
+ export { type AeneasFragment, Annotation, AnnotationBox, type AnnotationBoxComponentProps, AnnotationBoxesWrapper, type AnnotationBoxesWrapperProps, type AnnotationProps, AnnotationProvider, AnnotationText, type AnnotationTextProps, type AnnotationUpdateParams, AnnotationsTrack, type AnnotationsTrackProps, ContinuousPlayCheckbox, type ContinuousPlayCheckboxProps, DownloadAnnotationsButton, type DownloadAnnotationsButtonProps, EditableCheckbox, type EditableCheckboxProps, LinkEndpointsCheckbox, type LinkEndpointsCheckboxProps, type UseAnnotationControlsOptions, type UseAnnotationControlsReturn, parseAeneas, serializeAeneas, useAnnotationControls };
package/dist/index.js CHANGED
@@ -33,6 +33,7 @@ __export(index_exports, {
33
33
  Annotation: () => Annotation,
34
34
  AnnotationBox: () => AnnotationBox,
35
35
  AnnotationBoxesWrapper: () => AnnotationBoxesWrapper,
36
+ AnnotationProvider: () => AnnotationProvider,
36
37
  AnnotationText: () => AnnotationText2,
37
38
  AnnotationsTrack: () => AnnotationsTrack,
38
39
  ContinuousPlayCheckbox: () => ContinuousPlayCheckbox,
@@ -52,7 +53,7 @@ function parseAeneas(data) {
52
53
  start: parseFloat(data.begin),
53
54
  end: parseFloat(data.end),
54
55
  lines: data.lines,
55
- lang: data.language
56
+ language: data.language
56
57
  };
57
58
  }
58
59
  function serializeAeneas(annotation) {
@@ -61,7 +62,7 @@ function serializeAeneas(annotation) {
61
62
  begin: annotation.start.toFixed(3),
62
63
  end: annotation.end.toFixed(3),
63
64
  lines: annotation.lines,
64
- language: annotation.lang || "en"
65
+ language: annotation.language || "en"
65
66
  };
66
67
  }
67
68
 
@@ -941,6 +942,24 @@ var DownloadAnnotationsButton = ({
941
942
  );
942
943
  };
943
944
 
945
+ // src/AnnotationProvider.tsx
946
+ var import_browser = require("@waveform-playlist/browser");
947
+ var import_jsx_runtime10 = require("react/jsx-runtime");
948
+ var annotationIntegration = {
949
+ parseAeneas,
950
+ serializeAeneas,
951
+ AnnotationText: AnnotationText2,
952
+ AnnotationBox,
953
+ AnnotationBoxesWrapper,
954
+ ContinuousPlayCheckbox,
955
+ LinkEndpointsCheckbox,
956
+ EditableCheckbox,
957
+ DownloadAnnotationsButton
958
+ };
959
+ var AnnotationProvider = ({ children }) => {
960
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_browser.AnnotationIntegrationProvider, { value: annotationIntegration, children });
961
+ };
962
+
944
963
  // src/hooks/useAnnotationControls.ts
945
964
  var import_react3 = require("react");
946
965
  var LINK_THRESHOLD = 0.01;
@@ -1063,6 +1082,7 @@ var useAnnotationControls = (options = {}) => {
1063
1082
  Annotation,
1064
1083
  AnnotationBox,
1065
1084
  AnnotationBoxesWrapper,
1085
+ AnnotationProvider,
1066
1086
  AnnotationText,
1067
1087
  AnnotationsTrack,
1068
1088
  ContinuousPlayCheckbox,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/parsers/aeneas.ts","../src/components/Annotation.tsx","../src/components/AnnotationBox.tsx","../src/components/AnnotationBoxesWrapper.tsx","../src/components/AnnotationsTrack.tsx","../src/components/AnnotationText.tsx","../src/components/ContinuousPlayCheckbox.tsx","../src/components/LinkEndpointsCheckbox.tsx","../src/components/EditableCheckbox.tsx","../src/components/DownloadAnnotationsButton.tsx","../src/hooks/useAnnotationControls.ts"],"sourcesContent":["// Types\nexport type {\n Annotation as AnnotationType,\n AnnotationFormat,\n AnnotationListOptions,\n AnnotationEventMap\n} from './types';\n\n// Parsers\nexport { parseAeneas, serializeAeneas } from './parsers/aeneas';\nexport type { AeneasFragment } from './parsers/aeneas';\n\n// Components\nexport { Annotation } from './components/Annotation';\nexport type { AnnotationProps, AnnotationData, AnnotationAction, AnnotationActionOptions } from './components/Annotation';\n\nexport { AnnotationBox } from './components/AnnotationBox';\nexport type { AnnotationBoxComponentProps } from './components/AnnotationBox';\n\nexport { AnnotationBoxesWrapper } from './components/AnnotationBoxesWrapper';\nexport type { AnnotationBoxesWrapperProps } from './components/AnnotationBoxesWrapper';\n\nexport { AnnotationsTrack } from './components/AnnotationsTrack';\nexport type { AnnotationsTrackProps } from './components/AnnotationsTrack';\n\nexport { AnnotationText } from './components/AnnotationText';\nexport type { AnnotationTextProps, RenderAnnotationItemProps } from './components/AnnotationText';\n\nexport { ContinuousPlayCheckbox } from './components/ContinuousPlayCheckbox';\nexport type { ContinuousPlayCheckboxProps } from './components/ContinuousPlayCheckbox';\n\nexport { LinkEndpointsCheckbox } from './components/LinkEndpointsCheckbox';\nexport type { LinkEndpointsCheckboxProps } from './components/LinkEndpointsCheckbox';\n\nexport { EditableCheckbox } from './components/EditableCheckbox';\nexport type { EditableCheckboxProps } from './components/EditableCheckbox';\n\nexport { DownloadAnnotationsButton } from './components/DownloadAnnotationsButton';\nexport type { DownloadAnnotationsButtonProps } from './components/DownloadAnnotationsButton';\n\n// Hooks\nexport { useAnnotationControls } from './hooks/useAnnotationControls';\nexport type {\n UseAnnotationControlsOptions,\n UseAnnotationControlsReturn,\n AnnotationUpdateParams,\n} from './hooks/useAnnotationControls';\n","import { Annotation } from '../types';\n\nexport interface AeneasFragment {\n begin: string;\n end: string;\n id: string;\n language: string;\n lines: string[];\n}\n\nexport function parseAeneas(data: AeneasFragment): Annotation {\n return {\n id: data.id,\n start: parseFloat(data.begin),\n end: parseFloat(data.end),\n lines: data.lines,\n lang: data.language,\n };\n}\n\nexport function serializeAeneas(annotation: Annotation): AeneasFragment {\n return {\n id: annotation.id,\n begin: annotation.start.toFixed(3),\n end: annotation.end.toFixed(3),\n lines: annotation.lines,\n language: annotation.lang || 'en',\n };\n}\n","import React, { FunctionComponent, useState } from 'react';\nimport styled from 'styled-components';\n\ninterface AnnotationOverlayProps {\n readonly $left: number;\n readonly $width: number;\n readonly $color: string;\n}\n\nconst AnnotationOverlay = styled.div.attrs<AnnotationOverlayProps>((props) => ({\n style: {\n left: `${props.$left}px`,\n width: `${props.$width}px`,\n },\n}))<AnnotationOverlayProps>`\n position: absolute;\n top: 0;\n background: ${(props) => props.$color};\n height: 100%;\n z-index: 10;\n pointer-events: auto;\n opacity: 0.3;\n border: 2px solid ${(props) => props.$color};\n border-radius: 4px;\n cursor: pointer;\n\n &:hover {\n opacity: 0.5;\n border-color: ${(props) => props.$color};\n }\n`;\n\nconst AnnotationText = styled.div`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.7);\n color: white;\n padding: 4px 8px;\n font-size: 12px;\n line-height: 1.3;\n max-height: 60%;\n overflow: hidden;\n text-overflow: ellipsis;\n pointer-events: none;\n white-space: pre-wrap;\n word-break: break-word;\n`;\n\nconst EditableText = styled.textarea`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.9);\n color: white;\n padding: 4px 8px;\n font-size: 12px;\n line-height: 1.3;\n max-height: 60%;\n overflow: auto;\n border: 1px solid #fff;\n resize: none;\n font-family: inherit;\n\n &:focus {\n outline: none;\n border-color: #4CAF50;\n }\n`;\n\nconst ControlsBar = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.8);\n display: flex;\n gap: 4px;\n padding: 4px;\n justify-content: flex-start;\n align-items: center;\n`;\n\nconst ControlButton = styled.button`\n background: transparent;\n border: 1px solid rgba(255, 255, 255, 0.5);\n color: white;\n padding: 4px 8px;\n font-size: 10px;\n cursor: pointer;\n border-radius: 3px;\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n\n &:hover {\n background: rgba(255, 255, 255, 0.2);\n border-color: white;\n }\n\n &:active {\n background: rgba(255, 255, 255, 0.3);\n }\n`;\n\n/**\n * Configuration options passed to annotation action handlers\n */\nexport interface AnnotationActionOptions {\n /** Whether annotation endpoints are linked (moving one endpoint moves the other) */\n linkEndpoints?: boolean;\n /** Whether to continue playing after an annotation ends */\n continuousPlay?: boolean;\n /** Additional custom properties */\n [key: string]: unknown;\n}\n\nexport interface AnnotationAction {\n class?: string;\n text?: string;\n title: string;\n action: (annotation: AnnotationData, index: number, annotations: AnnotationData[], opts: AnnotationActionOptions) => void;\n}\n\nexport interface AnnotationData {\n id: string;\n start: number;\n end: number;\n lines: string[];\n language?: string;\n}\n\nexport interface AnnotationProps {\n annotation: AnnotationData;\n index: number;\n allAnnotations: AnnotationData[];\n startPosition: number; // Start position in pixels\n endPosition: number; // End position in pixels\n color?: string;\n editable?: boolean;\n controls?: AnnotationAction[];\n onAnnotationUpdate?: (updatedAnnotations: AnnotationData[]) => void;\n annotationListConfig?: AnnotationActionOptions;\n onClick?: (annotation: AnnotationData) => void;\n}\n\nexport const Annotation: FunctionComponent<AnnotationProps> = ({\n annotation,\n index,\n allAnnotations,\n startPosition,\n endPosition,\n color = '#ff9800',\n editable = false,\n controls = [],\n onAnnotationUpdate,\n annotationListConfig,\n onClick,\n}) => {\n const [isEditing, setIsEditing] = useState(false);\n const [editedText, setEditedText] = useState(annotation.lines.join('\\n'));\n const width = Math.max(0, endPosition - startPosition);\n\n if (width <= 0) {\n return null;\n }\n\n const handleClick = () => {\n if (onClick) {\n onClick(annotation);\n }\n };\n\n const handleDoubleClick = () => {\n if (editable) {\n setIsEditing(true);\n }\n };\n\n const handleTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setEditedText(e.target.value);\n };\n\n const handleTextBlur = () => {\n setIsEditing(false);\n const newLines = editedText.split('\\n');\n if (newLines.join('\\n') !== annotation.lines.join('\\n')) {\n const updatedAnnotations = [...allAnnotations];\n updatedAnnotations[index] = { ...annotation, lines: newLines };\n if (onAnnotationUpdate) {\n onAnnotationUpdate(updatedAnnotations);\n }\n }\n };\n\n const handleControlClick = (control: AnnotationAction) => {\n const annotationsCopy = [...allAnnotations];\n control.action(annotationsCopy[index], index, annotationsCopy, annotationListConfig || {});\n if (onAnnotationUpdate) {\n onAnnotationUpdate(annotationsCopy);\n }\n };\n\n const getIconClass = (classString: string) => {\n // Convert \"fas.fa-minus\" to \"fas fa-minus\"\n return classString.replace(/\\./g, ' ');\n };\n\n return (\n <AnnotationOverlay\n $left={startPosition}\n $width={width}\n $color={color}\n onClick={handleClick}\n onDoubleClick={handleDoubleClick}\n >\n {controls.length > 0 && (\n <ControlsBar>\n {controls.map((control, idx) => (\n <ControlButton\n key={idx}\n title={control.title}\n onClick={(e) => {\n e.stopPropagation();\n handleControlClick(control);\n }}\n >\n {control.text ? control.text : <i className={getIconClass(control.class || '')} />}\n </ControlButton>\n ))}\n </ControlsBar>\n )}\n {isEditing ? (\n <EditableText\n value={editedText}\n onChange={handleTextChange}\n onBlur={handleTextBlur}\n autoFocus\n onClick={(e) => e.stopPropagation()}\n onDoubleClick={(e) => e.stopPropagation()}\n />\n ) : (\n <AnnotationText>\n {annotation.lines.join('\\n')}\n </AnnotationText>\n )}\n </AnnotationOverlay>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { useDraggable } from '@dnd-kit/core';\nimport type { DraggableAttributes } from '@dnd-kit/core';\nimport type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';\n\ninterface WrapperProps {\n readonly $left: number;\n readonly $width: number;\n}\n\n// Wrapper positions the annotation and contains both Box and ResizeHandles as siblings\nconst Wrapper = styled.div.attrs<WrapperProps>((props) => ({\n style: {\n left: `${props.$left}px`,\n width: `${props.$width}px`,\n },\n}))<WrapperProps>`\n position: absolute;\n top: 0;\n height: 100%;\n pointer-events: none; /* Let events pass through to children */\n`;\n\ninterface BoxProps {\n readonly $color: string;\n readonly $isActive?: boolean;\n}\n\nconst Box = styled.div<BoxProps>`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 100%;\n background: ${(props) => props.$isActive\n ? (props.theme?.annotationBoxActiveBackground || 'rgba(255, 200, 100, 0.95)')\n : (props.theme?.annotationBoxBackground || 'rgba(255, 255, 255, 0.85)')};\n border: ${(props) => props.$isActive ? '3px' : '2px'} solid ${(props) => props.$isActive\n ? (props.theme?.annotationBoxActiveBorder || '#ff9800')\n : props.$color};\n border-radius: 4px;\n cursor: pointer;\n pointer-events: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: ${(props) => props.$isActive\n ? '0 2px 8px rgba(255, 152, 0, 0.4), inset 0 0 0 1px rgba(255, 152, 0, 0.2)'\n : '0 1px 3px rgba(0, 0, 0, 0.1)'};\n\n &:hover {\n background: ${(props) => props.theme?.annotationBoxHoverBackground || 'rgba(255, 255, 255, 0.98)'};\n border-color: ${(props) => props.theme?.annotationBoxActiveBorder || '#ff9800'};\n border-width: 3px;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);\n }\n`;\n\nconst Label = styled.span`\n font-size: 12px;\n font-weight: 600;\n color: ${(props) => props.theme?.annotationLabelColor || '#2a2a2a'};\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n padding: 0 6px;\n letter-spacing: 0.3px;\n user-select: none;\n`;\n\ninterface ResizeHandleStyledProps {\n $position: 'left' | 'right';\n $isDragging?: boolean;\n}\n\n// ResizeHandles sit inside their annotation's bounds so adjacent annotations'\n// handles never overlap — each handle is independently grabbable.\nconst ResizeHandle = styled.div<ResizeHandleStyledProps>`\n position: absolute;\n top: 0;\n ${(props) => props.$position === 'left' ? 'left: 0' : 'right: 0'};\n width: 8px;\n height: 100%;\n cursor: ew-resize;\n z-index: 120;\n background: ${(props) => props.$isDragging\n ? (props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.2)')\n : 'transparent'};\n border-radius: 4px;\n touch-action: none; /* Important for @dnd-kit on touch devices */\n pointer-events: auto;\n\n &::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 4px;\n height: 60%;\n background: ${(props) => props.$isDragging\n ? (props.theme?.annotationResizeHandleActiveColor || 'rgba(0, 0, 0, 0.8)')\n : (props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.4)')};\n border-radius: 2px;\n opacity: ${(props) => props.$isDragging ? 1 : 0.6};\n transition: opacity 0.2s, background 0.2s;\n }\n\n &:hover {\n background: ${(props) => props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.1)'};\n }\n\n &:hover::before {\n opacity: 1;\n background: ${(props) => props.theme?.annotationResizeHandleActiveColor || 'rgba(0, 0, 0, 0.7)'};\n }\n`;\n\nexport interface DragHandleProps {\n attributes: DraggableAttributes;\n listeners: SyntheticListenerMap | undefined;\n setActivatorNodeRef: (element: HTMLElement | null) => void;\n isDragging: boolean;\n}\n\nexport interface AnnotationBoxComponentProps {\n annotationId: string;\n annotationIndex: number;\n startPosition: number;\n endPosition: number;\n label?: string;\n color?: string;\n isActive?: boolean;\n onClick?: () => void;\n editable?: boolean; // Whether to show drag handles\n}\n\nexport const AnnotationBox: FunctionComponent<AnnotationBoxComponentProps> = ({\n annotationId,\n annotationIndex,\n startPosition,\n endPosition,\n label,\n color = '#ff9800',\n isActive = false,\n onClick,\n editable = true,\n}) => {\n const width = Math.max(0, endPosition - startPosition);\n\n // Left (start) boundary draggable\n const leftBoundaryId = `annotation-boundary-start-${annotationIndex}`;\n const {\n attributes: leftAttributes,\n listeners: leftListeners,\n setActivatorNodeRef: setLeftActivatorRef,\n isDragging: isLeftDragging,\n } = useDraggable({\n id: leftBoundaryId,\n data: { annotationId, annotationIndex, edge: 'start' as const },\n disabled: !editable,\n });\n\n // Right (end) boundary draggable\n const rightBoundaryId = `annotation-boundary-end-${annotationIndex}`;\n const {\n attributes: rightAttributes,\n listeners: rightListeners,\n setActivatorNodeRef: setRightActivatorRef,\n isDragging: isRightDragging,\n } = useDraggable({\n id: rightBoundaryId,\n data: { annotationId, annotationIndex, edge: 'end' as const },\n disabled: !editable,\n });\n\n if (width <= 0) {\n return null;\n }\n\n // Wrap @dnd-kit pointer handlers to also stop propagation\n // This prevents the ClickOverlay from capturing the event\n const createPointerDownHandler = (dndKitHandler?: (e: React.PointerEvent) => void) => {\n return (e: React.PointerEvent) => {\n e.stopPropagation();\n dndKitHandler?.(e);\n };\n };\n\n const handleHandleClick = (e: React.MouseEvent) => {\n // Prevent clicks on resize handles from bubbling to annotation box\n e.stopPropagation();\n };\n\n return (\n <Wrapper $left={startPosition} $width={width}>\n <Box\n $color={color}\n $isActive={isActive}\n onClick={onClick}\n >\n {label && <Label>{label}</Label>}\n </Box>\n {editable && (\n <ResizeHandle\n ref={setLeftActivatorRef}\n $position=\"left\"\n $isDragging={isLeftDragging}\n onClick={handleHandleClick}\n {...leftListeners}\n onPointerDown={createPointerDownHandler(leftListeners?.onPointerDown as ((e: React.PointerEvent) => void) | undefined)}\n {...leftAttributes}\n />\n )}\n {editable && (\n <ResizeHandle\n ref={setRightActivatorRef}\n $position=\"right\"\n $isDragging={isRightDragging}\n onClick={handleHandleClick}\n {...rightListeners}\n onPointerDown={createPointerDownHandler(rightListeners?.onPointerDown as ((e: React.PointerEvent) => void) | undefined)}\n {...rightAttributes}\n />\n )}\n </Wrapper>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { usePlaylistInfo } from '@waveform-playlist/ui-components';\n\ninterface ContainerProps {\n readonly $height: number;\n readonly $controlWidth: number;\n readonly $width?: number;\n}\n\nconst Container = styled.div.attrs<ContainerProps>((props) => ({\n style: {\n height: `${props.$height}px`,\n },\n}))<ContainerProps>`\n position: relative;\n display: flex;\n ${(props) => props.$width !== undefined && `width: ${props.$width}px;`}\n background: transparent;\n z-index: 110;\n`;\n\nconst ControlsPlaceholder = styled.div<{ $controlWidth: number }>`\n position: sticky;\n z-index: 200;\n left: 0;\n height: 100%;\n width: ${(props) => props.$controlWidth}px;\n flex-shrink: 0;\n background: transparent;\n`;\n\nconst BoxesContainer = styled.div<{ $offset?: number }>`\n position: relative;\n flex: 1;\n padding-left: ${(props) => props.$offset || 0}px;\n`;\n\nexport interface AnnotationBoxesWrapperProps {\n className?: string;\n children?: React.ReactNode;\n height?: number;\n offset?: number;\n width?: number;\n}\n\nexport const AnnotationBoxesWrapper: FunctionComponent<AnnotationBoxesWrapperProps> = ({\n children,\n className,\n height = 30,\n offset = 0,\n width,\n}) => {\n const {\n controls: { show, width: controlWidth },\n } = usePlaylistInfo();\n\n return (\n <Container\n className={className}\n $height={height}\n $controlWidth={show ? controlWidth : 0}\n $width={width}\n >\n <ControlsPlaceholder $controlWidth={show ? controlWidth : 0} />\n <BoxesContainer $offset={offset}>\n {children}\n </BoxesContainer>\n </Container>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { usePlaylistInfo } from '@waveform-playlist/ui-components';\n\ninterface ContainerProps {\n readonly $height: number;\n readonly $controlWidth: number;\n readonly $width?: number;\n}\n\nconst Container = styled.div.attrs<ContainerProps>((props) => ({\n style: {\n height: `${props.$height}px`,\n },\n}))<ContainerProps>`\n position: relative;\n display: flex;\n ${(props) => props.$width !== undefined && `width: ${props.$width}px;`}\n background: transparent;\n`;\n\nconst ControlsPlaceholder = styled.div<{ $controlWidth: number }>`\n position: sticky;\n z-index: 200;\n left: 0;\n height: 100%;\n width: ${(props) => props.$controlWidth}px;\n flex-shrink: 0;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n color: ${(props) => props.theme?.textColorMuted || '#666'};\n font-weight: bold;\n`;\n\nconst AnnotationsContainer = styled.div<{ $offset?: number }>`\n position: relative;\n flex: 1;\n padding-left: ${(props) => props.$offset || 0}px;\n`;\n\nexport interface AnnotationsTrackProps {\n className?: string;\n children?: React.ReactNode;\n height?: number;\n offset?: number;\n width?: number;\n}\n\nexport const AnnotationsTrack: FunctionComponent<AnnotationsTrackProps> = ({\n children,\n className,\n height = 100,\n offset = 0,\n width,\n}) => {\n const {\n controls: { show, width: controlWidth },\n } = usePlaylistInfo();\n\n return (\n <Container\n className={className}\n $height={height}\n $controlWidth={show ? controlWidth : 0}\n $width={width}\n >\n <ControlsPlaceholder $controlWidth={show ? controlWidth : 0}>\n Annotations\n </ControlsPlaceholder>\n <AnnotationsContainer $offset={offset}>\n {children}\n </AnnotationsContainer>\n </Container>\n );\n};\n","import React, { FunctionComponent, useRef, useEffect } from 'react';\nimport styled from 'styled-components';\nimport type { AnnotationData, AnnotationAction, AnnotationActionOptions } from './Annotation';\n\ninterface ContainerProps {\n $height?: number;\n}\n\nconst Container = styled.div<ContainerProps>`\n background: ${(props) => props.theme?.backgroundColor || '#fff'};\n ${(props) => props.$height ? `height: ${props.$height}px;` : 'max-height: 200px;'}\n overflow-y: auto;\n padding: 8px;\n`;\n\nconst AnnotationItem = styled.div<{ $isActive?: boolean }>`\n padding: 12px;\n margin-bottom: 6px;\n border-left: 4px solid ${(props) => (props.$isActive ? '#ff9800' : 'transparent')};\n background: ${(props) => (props.$isActive ? 'rgba(255, 152, 0, 0.15)' : 'transparent')};\n border-radius: 4px;\n transition: all 0.2s;\n cursor: pointer;\n box-shadow: ${(props) => (props.$isActive ? '0 2px 8px rgba(255, 152, 0, 0.25), inset 0 0 0 1px rgba(255, 152, 0, 0.3)' : 'none')};\n\n &:hover {\n background: ${(props) => (props.$isActive ? 'rgba(255, 152, 0, 0.2)' : props.theme?.annotationTextItemHoverBackground || 'rgba(0, 0, 0, 0.05)')};\n border-left-color: ${(props) => (props.$isActive ? '#ff9800' : props.theme?.borderColor || '#ddd')};\n }\n\n &:focus-visible {\n outline: 2px solid #ff9800;\n outline-offset: 2px;\n }\n`;\n\nconst AnnotationHeader = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n`;\n\nconst AnnotationInfo = styled.div`\n display: flex;\n align-items: center;\n gap: 8px;\n`;\n\nconst AnnotationIdLabel = styled.span<{ $isEditable?: boolean }>`\n font-size: 11px;\n font-weight: 600;\n color: ${(props) => props.theme?.textColorMuted || '#666'};\n background: transparent;\n padding: 2px 6px;\n border-radius: 3px;\n min-width: 20px;\n outline: ${(props) => (props.$isEditable ? `1px dashed ${props.theme?.borderColor || '#ddd'}` : 'none')};\n\n &[contenteditable='true']:focus {\n outline: 2px solid #ff9800;\n background: rgba(255, 152, 0, 0.1);\n }\n`;\n\nconst TimeRange = styled.span`\n font-size: 12px;\n font-weight: 500;\n color: ${(props) => props.theme?.textColorMuted || '#555'};\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n letter-spacing: 0.5px;\n`;\n\nconst AnnotationControls = styled.div`\n display: flex;\n gap: 6px;\n`;\n\nconst ControlButton = styled.button`\n background: ${(props) => props.theme?.surfaceColor || '#f5f5f5'};\n border: 1px solid ${(props) => props.theme?.borderColor || '#ccc'};\n color: ${(props) => props.theme?.textColor || '#333'};\n padding: 4px 8px;\n font-size: 14px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s ease;\n\n &:hover {\n background: ${(props) => props.theme?.inputBackground || '#3d3d3d'};\n border-color: ${(props) => props.theme?.textColorMuted || '#999'};\n transform: scale(1.05);\n }\n\n &:active {\n transform: scale(0.95);\n }\n`;\n\nconst AnnotationTextContent = styled.div<{ $isEditable?: boolean }>`\n font-size: 14px;\n line-height: 1.6;\n color: ${(props) => props.theme?.textColor || '#2a2a2a'};\n white-space: pre-wrap;\n word-break: break-word;\n outline: ${(props) => (props.$isEditable ? `1px dashed ${props.theme?.borderColor || '#ddd'}` : 'none')};\n padding: ${(props) => (props.$isEditable ? '6px' : '0')};\n border-radius: 3px;\n min-height: 20px;\n\n &[contenteditable='true']:focus {\n outline: 2px solid #ff9800;\n background: rgba(255, 152, 0, 0.1);\n }\n`;\n\n/**\n * Props passed to the renderAnnotationItem function for custom rendering\n */\nexport interface RenderAnnotationItemProps {\n annotation: AnnotationData;\n index: number;\n isActive: boolean;\n onClick: () => void;\n formatTime: (seconds: number) => string;\n}\n\nexport interface AnnotationTextProps {\n annotations: AnnotationData[];\n activeAnnotationId?: string;\n shouldScrollToActive?: boolean;\n /** Where to position the active annotation when scrolling: 'center', 'start', 'end', or 'nearest'. Defaults to 'center'. */\n scrollActivePosition?: ScrollLogicalPosition;\n /** Which scrollable containers to scroll: 'nearest' (only the annotation list) or 'all' (including viewport). Defaults to 'nearest'. */\n scrollActiveContainer?: 'nearest' | 'all';\n editable?: boolean;\n controls?: AnnotationAction[];\n annotationListConfig?: AnnotationActionOptions;\n height?: number;\n onAnnotationClick?: (annotation: AnnotationData) => void;\n onAnnotationUpdate?: (updatedAnnotations: AnnotationData[]) => void;\n /**\n * Custom render function for annotation items.\n * When provided, completely replaces the default annotation item rendering.\n * Use this to customize the appearance of each annotation in the list.\n */\n renderAnnotationItem?: (props: RenderAnnotationItemProps) => React.ReactNode;\n}\n\nconst AnnotationTextComponent: FunctionComponent<AnnotationTextProps> = ({\n annotations,\n activeAnnotationId,\n shouldScrollToActive = false,\n scrollActivePosition = 'center',\n scrollActiveContainer = 'nearest',\n editable = false,\n controls = [],\n annotationListConfig,\n height,\n onAnnotationClick,\n onAnnotationUpdate,\n renderAnnotationItem,\n}) => {\n const activeAnnotationRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const prevActiveIdRef = useRef<string | undefined>(undefined);\n\n // Track component renders and scroll position\n useEffect(() => {\n // Render tracking removed\n });\n\n // Track scroll changes\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handleScroll = () => {\n // Scroll tracking removed\n };\n\n container.addEventListener('scroll', handleScroll);\n return () => container.removeEventListener('scroll', handleScroll);\n }, []);\n\n // Auto-scroll to active annotation when it changes\n useEffect(() => {\n // Only scroll if parent says we should (prevents scrolling on remount after pause)\n if (activeAnnotationId && activeAnnotationRef.current && shouldScrollToActive) {\n activeAnnotationRef.current.scrollIntoView({\n behavior: 'smooth',\n block: scrollActivePosition,\n container: scrollActiveContainer,\n } as ScrollIntoViewOptions);\n }\n\n prevActiveIdRef.current = activeAnnotationId;\n }, [activeAnnotationId, shouldScrollToActive, scrollActivePosition, scrollActiveContainer]);\n\n const formatTime = (seconds: number): string => {\n if (isNaN(seconds) || !isFinite(seconds)) {\n return '0:00.000';\n }\n const mins = Math.floor(seconds / 60);\n const secs = (seconds % 60).toFixed(3);\n return `${mins}:${secs.padStart(6, '0')}`;\n };\n\n const handleTextEdit = (index: number, newText: string) => {\n if (!editable || !onAnnotationUpdate) return;\n\n const updatedAnnotations = [...annotations];\n updatedAnnotations[index] = {\n ...updatedAnnotations[index],\n lines: newText.split('\\n'),\n };\n onAnnotationUpdate(updatedAnnotations);\n };\n\n const handleIdEdit = (index: number, newId: string) => {\n if (!editable || !onAnnotationUpdate) return;\n\n const trimmedId = newId.trim();\n if (!trimmedId) return; // Don't allow empty IDs\n\n const updatedAnnotations = [...annotations];\n updatedAnnotations[index] = {\n ...updatedAnnotations[index],\n id: trimmedId,\n };\n onAnnotationUpdate(updatedAnnotations);\n };\n\n const handleControlClick = (control: AnnotationAction, annotation: AnnotationData, index: number) => {\n if (!onAnnotationUpdate) return;\n\n const annotationsCopy = [...annotations];\n control.action(annotationsCopy[index], index, annotationsCopy, annotationListConfig || {});\n onAnnotationUpdate(annotationsCopy);\n };\n\n const getIconClass = (classString: string) => {\n return classString.replace(/\\./g, ' ');\n };\n\n return (\n <Container ref={containerRef} $height={height}>\n {annotations.map((annotation, index) => {\n const isActive = annotation.id === activeAnnotationId;\n const handleClick = () => onAnnotationClick?.(annotation);\n\n // Use custom render function if provided\n if (renderAnnotationItem) {\n return (\n <div\n key={annotation.id}\n ref={isActive ? activeAnnotationRef : null}\n >\n {renderAnnotationItem({\n annotation,\n index,\n isActive,\n onClick: handleClick,\n formatTime,\n })}\n </div>\n );\n }\n\n // Default rendering\n return (\n <AnnotationItem\n key={annotation.id}\n ref={isActive ? activeAnnotationRef : null}\n $isActive={isActive}\n onClick={handleClick}\n >\n <AnnotationHeader>\n <AnnotationInfo>\n <AnnotationIdLabel\n $isEditable={editable}\n contentEditable={editable}\n suppressContentEditableWarning\n onBlur={(e) => handleIdEdit(index, e.currentTarget.textContent || '')}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n (e.currentTarget as HTMLElement).blur();\n }\n }}\n >\n {annotation.id}\n </AnnotationIdLabel>\n <TimeRange>\n {formatTime(annotation.start)} - {formatTime(annotation.end)}\n </TimeRange>\n </AnnotationInfo>\n {controls.length > 0 && (\n <AnnotationControls onClick={(e) => e.stopPropagation()}>\n {controls.map((control, idx) => (\n <ControlButton\n key={idx}\n title={control.title}\n onClick={() => handleControlClick(control, annotation, index)}\n >\n {control.text ? control.text : <i className={getIconClass(control.class || '')} />}\n </ControlButton>\n ))}\n </AnnotationControls>\n )}\n </AnnotationHeader>\n <AnnotationTextContent\n $isEditable={editable}\n contentEditable={editable}\n suppressContentEditableWarning\n onBlur={(e) => handleTextEdit(index, e.currentTarget.textContent || '')}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n (e.currentTarget as HTMLElement).blur();\n }\n }}\n >\n {annotation.lines.join('\\n')}\n </AnnotationTextContent>\n </AnnotationItem>\n );\n })}\n </Container>\n );\n};\n\n// Memoize to prevent unnecessary remounting when parent re-renders\nexport const AnnotationText = React.memo(AnnotationTextComponent);\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface ContinuousPlayCheckboxProps {\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Checkbox control for enabling/disabling continuous play of annotations.\n * When enabled, playback continues from one annotation to the next without stopping.\n */\nexport const ContinuousPlayCheckbox: React.FC<ContinuousPlayCheckboxProps> = ({\n checked,\n onChange,\n disabled = false,\n className,\n}) => {\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked);\n };\n\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"continuous-play\"\n className=\"continuous-play\"\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n />\n <BaseCheckboxLabel htmlFor=\"continuous-play\">Continuous Play</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface LinkEndpointsCheckboxProps {\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Checkbox control for enabling/disabling linked endpoints between annotations.\n * When enabled, the end time of one annotation is automatically linked to the start time of the next.\n */\nexport const LinkEndpointsCheckbox: React.FC<LinkEndpointsCheckboxProps> = ({\n checked,\n onChange,\n disabled = false,\n className,\n}) => {\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked);\n };\n\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"link-endpoints\"\n className=\"link-endpoints\"\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n />\n <BaseCheckboxLabel htmlFor=\"link-endpoints\">Link Endpoints</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface EditableCheckboxProps {\n checked: boolean;\n onChange: (enabled: boolean) => void;\n className?: string;\n}\n\nexport const EditableCheckbox: React.FC<EditableCheckboxProps> = ({\n checked,\n onChange,\n className,\n}) => {\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"editable-annotations\"\n checked={checked}\n onChange={(e) => onChange(e.target.checked)}\n />\n <BaseCheckboxLabel htmlFor=\"editable-annotations\">Editable Annotations</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport styled from 'styled-components';\nimport { serializeAeneas } from '../parsers/aeneas';\nimport type { Annotation } from '../types';\n\nconst StyledButton = styled.button`\n padding: 0.5rem 1rem;\n background: ${(props) => props.theme?.surfaceColor || '#f5f5f5'};\n color: ${(props) => props.theme?.textColor || '#333'};\n border: 1px solid ${(props) => props.theme?.borderColor || '#ccc'};\n border-radius: ${(props) => props.theme?.borderRadius || '4px'};\n cursor: pointer;\n font-family: ${(props) => props.theme?.fontFamily || 'inherit'};\n font-size: ${(props) => props.theme?.fontSize || '14px'};\n font-weight: 500;\n transition: all 0.15s ease;\n\n &:hover:not(:disabled) {\n background: ${(props) => props.theme?.inputBackground || '#3d3d3d'};\n border-color: ${(props) => props.theme?.textColorMuted || '#999'};\n }\n\n &:focus {\n outline: none;\n box-shadow: 0 0 0 2px ${(props) => props.theme?.inputFocusBorder || '#007bff'}44;\n }\n\n &:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n`;\n\nexport interface DownloadAnnotationsButtonProps {\n annotations: Annotation[];\n filename?: string;\n disabled?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nexport const DownloadAnnotationsButton: React.FC<DownloadAnnotationsButtonProps> = ({\n annotations,\n filename = 'annotations.json',\n disabled = false,\n className,\n children = 'Download JSON',\n}) => {\n const handleDownload = () => {\n if (annotations.length === 0) {\n return;\n }\n\n // Serialize annotations to Aeneas JSON format\n const jsonData = annotations.map(annotation => serializeAeneas(annotation));\n const jsonString = JSON.stringify(jsonData, null, 2);\n\n // Create a blob and download link\n const blob = new Blob([jsonString], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n\n // Trigger download\n document.body.appendChild(link);\n link.click();\n\n // Cleanup\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n };\n\n return (\n <StyledButton\n onClick={handleDownload}\n disabled={disabled || annotations.length === 0}\n className={className}\n title={annotations.length === 0 ? 'No annotations to download' : 'Download the annotations as JSON'}\n >\n {children}\n </StyledButton>\n );\n};\n","import { useState, useCallback } from 'react';\nimport type { Annotation, AnnotationListOptions } from '../types';\n\nconst LINK_THRESHOLD = 0.01; // Consider edges \"linked\" if within 10ms\n\nexport interface UseAnnotationControlsOptions {\n initialContinuousPlay?: boolean;\n initialLinkEndpoints?: boolean;\n}\n\nexport interface AnnotationUpdateParams {\n annotationIndex: number;\n newTime: number;\n isDraggingStart: boolean;\n annotations: Annotation[];\n duration: number;\n linkEndpoints: boolean;\n}\n\nexport interface UseAnnotationControlsReturn {\n continuousPlay: boolean;\n linkEndpoints: boolean;\n setContinuousPlay: (value: boolean) => void;\n setLinkEndpoints: (value: boolean) => void;\n updateAnnotationBoundaries: (params: AnnotationUpdateParams) => Annotation[];\n}\n\n/**\n * Hook for managing annotation control state and boundary logic.\n * Handles continuous play mode and linked endpoints behavior.\n */\nexport const useAnnotationControls = (\n options: UseAnnotationControlsOptions = {}\n): UseAnnotationControlsReturn => {\n const {\n initialContinuousPlay = false,\n initialLinkEndpoints = true,\n } = options;\n\n const [continuousPlay, setContinuousPlay] = useState(initialContinuousPlay);\n const [linkEndpoints, setLinkEndpoints] = useState(initialLinkEndpoints);\n\n /**\n * Updates annotation boundaries based on drag operations.\n * Handles linked endpoints and collision detection.\n * Note: linkEndpoints is passed as a parameter to ensure it uses the current value from context.\n */\n const updateAnnotationBoundaries = useCallback(\n ({\n annotationIndex,\n newTime,\n isDraggingStart,\n annotations,\n duration,\n linkEndpoints: shouldLinkEndpoints,\n }: AnnotationUpdateParams): Annotation[] => {\n const updatedAnnotations = [...annotations];\n const annotation = annotations[annotationIndex];\n\n if (isDraggingStart) {\n // Dragging start edge\n const constrainedStart = Math.min(annotation.end - 0.1, Math.max(0, newTime));\n const delta = constrainedStart - annotation.start;\n\n updatedAnnotations[annotationIndex] = {\n ...annotation,\n start: constrainedStart,\n };\n\n if (shouldLinkEndpoints && annotationIndex > 0) {\n // Link Endpoints mode: handle both already-linked and collision scenarios\n const prevAnnotation = updatedAnnotations[annotationIndex - 1];\n\n if (Math.abs(prevAnnotation.end - annotation.start) < LINK_THRESHOLD) {\n // Already linked: move previous annotation's end together with this start\n updatedAnnotations[annotationIndex - 1] = {\n ...prevAnnotation,\n end: Math.max(prevAnnotation.start + 0.1, prevAnnotation.end + delta),\n };\n } else if (constrainedStart <= prevAnnotation.end) {\n // Dragged past previous annotation: snap to link them together\n updatedAnnotations[annotationIndex] = {\n ...updatedAnnotations[annotationIndex],\n start: prevAnnotation.end,\n };\n }\n } else if (!shouldLinkEndpoints && annotationIndex > 0 && constrainedStart < updatedAnnotations[annotationIndex - 1].end) {\n // Collision detection: push previous annotation's end back\n updatedAnnotations[annotationIndex - 1] = {\n ...updatedAnnotations[annotationIndex - 1],\n end: constrainedStart,\n };\n }\n } else {\n // Dragging end edge\n const constrainedEnd = Math.max(annotation.start + 0.1, Math.min(newTime, duration));\n const delta = constrainedEnd - annotation.end;\n\n updatedAnnotations[annotationIndex] = {\n ...annotation,\n end: constrainedEnd,\n };\n\n if (shouldLinkEndpoints && annotationIndex < updatedAnnotations.length - 1) {\n // Link Endpoints mode: handle both already-linked and collision scenarios\n const nextAnnotation = updatedAnnotations[annotationIndex + 1];\n\n if (Math.abs(nextAnnotation.start - annotation.end) < LINK_THRESHOLD) {\n // Already linked: move next annotation's start together with this end\n const newStart = nextAnnotation.start + delta;\n updatedAnnotations[annotationIndex + 1] = {\n ...nextAnnotation,\n start: Math.min(nextAnnotation.end - 0.1, newStart),\n };\n\n // Cascade linked endpoints\n let currentIndex = annotationIndex + 1;\n while (currentIndex < updatedAnnotations.length - 1) {\n const current = updatedAnnotations[currentIndex];\n const next = updatedAnnotations[currentIndex + 1];\n\n if (Math.abs(next.start - current.end) < LINK_THRESHOLD) {\n const nextDelta = current.end - annotations[currentIndex].end;\n updatedAnnotations[currentIndex + 1] = {\n ...next,\n start: Math.min(next.end - 0.1, next.start + nextDelta),\n };\n currentIndex++;\n } else {\n break; // No more linked endpoints\n }\n }\n } else if (constrainedEnd >= nextAnnotation.start) {\n // Dragged past next annotation: snap to link them together\n updatedAnnotations[annotationIndex] = {\n ...updatedAnnotations[annotationIndex],\n end: nextAnnotation.start,\n };\n }\n } else if (!shouldLinkEndpoints && annotationIndex < updatedAnnotations.length - 1 && constrainedEnd > updatedAnnotations[annotationIndex + 1].start) {\n // Collision detection: push next annotation's start forward\n const nextAnnotation = updatedAnnotations[annotationIndex + 1];\n\n updatedAnnotations[annotationIndex + 1] = {\n ...nextAnnotation,\n start: constrainedEnd,\n };\n\n // Cascade collisions\n let currentIndex = annotationIndex + 1;\n while (currentIndex < updatedAnnotations.length - 1) {\n const current = updatedAnnotations[currentIndex];\n const next = updatedAnnotations[currentIndex + 1];\n\n if (current.end > next.start) {\n updatedAnnotations[currentIndex + 1] = {\n ...next,\n start: current.end,\n };\n currentIndex++;\n } else {\n break; // No more collisions\n }\n }\n }\n }\n\n return updatedAnnotations;\n },\n []\n );\n\n return {\n continuousPlay,\n linkEndpoints,\n setContinuousPlay,\n setLinkEndpoints,\n updateAnnotationBoundaries,\n };\n};\n"],"mappings":"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","names":["AnnotationText","styled","import_styled_components","import_jsx_runtime","styled","import_styled_components","import_jsx_runtime","styled","import_styled_components","import_ui_components","import_jsx_runtime","Container","styled","ControlsPlaceholder","import_react","import_styled_components","import_jsx_runtime","Container","styled","ControlButton","AnnotationText","React","import_ui_components","import_jsx_runtime","import_ui_components","import_jsx_runtime","import_ui_components","import_jsx_runtime","import_styled_components","import_jsx_runtime","styled","import_react"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/parsers/aeneas.ts","../src/components/Annotation.tsx","../src/components/AnnotationBox.tsx","../src/components/AnnotationBoxesWrapper.tsx","../src/components/AnnotationsTrack.tsx","../src/components/AnnotationText.tsx","../src/components/ContinuousPlayCheckbox.tsx","../src/components/LinkEndpointsCheckbox.tsx","../src/components/EditableCheckbox.tsx","../src/components/DownloadAnnotationsButton.tsx","../src/AnnotationProvider.tsx","../src/hooks/useAnnotationControls.ts"],"sourcesContent":["// Types from core\nexport type {\n AnnotationData,\n AnnotationFormat,\n AnnotationListOptions,\n AnnotationEventMap,\n AnnotationAction,\n AnnotationActionOptions,\n RenderAnnotationItemProps,\n} from '@waveform-playlist/core';\n\n// Parsers\nexport { parseAeneas, serializeAeneas } from './parsers/aeneas';\nexport type { AeneasFragment } from './parsers/aeneas';\n\n// Components\nexport { Annotation } from './components/Annotation';\nexport type { AnnotationProps } from './components/Annotation';\n\nexport { AnnotationBox } from './components/AnnotationBox';\nexport type { AnnotationBoxComponentProps } from './components/AnnotationBox';\n\nexport { AnnotationBoxesWrapper } from './components/AnnotationBoxesWrapper';\nexport type { AnnotationBoxesWrapperProps } from './components/AnnotationBoxesWrapper';\n\nexport { AnnotationsTrack } from './components/AnnotationsTrack';\nexport type { AnnotationsTrackProps } from './components/AnnotationsTrack';\n\nexport { AnnotationText } from './components/AnnotationText';\nexport type { AnnotationTextProps } from './components/AnnotationText';\n\nexport { ContinuousPlayCheckbox } from './components/ContinuousPlayCheckbox';\nexport type { ContinuousPlayCheckboxProps } from './components/ContinuousPlayCheckbox';\n\nexport { LinkEndpointsCheckbox } from './components/LinkEndpointsCheckbox';\nexport type { LinkEndpointsCheckboxProps } from './components/LinkEndpointsCheckbox';\n\nexport { EditableCheckbox } from './components/EditableCheckbox';\nexport type { EditableCheckboxProps } from './components/EditableCheckbox';\n\nexport { DownloadAnnotationsButton } from './components/DownloadAnnotationsButton';\nexport type { DownloadAnnotationsButtonProps } from './components/DownloadAnnotationsButton';\n\n// Provider (registers annotation components with browser package)\nexport { AnnotationProvider } from './AnnotationProvider';\n\n// Hooks\nexport { useAnnotationControls } from './hooks/useAnnotationControls';\nexport type {\n UseAnnotationControlsOptions,\n UseAnnotationControlsReturn,\n AnnotationUpdateParams,\n} from './hooks/useAnnotationControls';\n","import type { AnnotationData } from '@waveform-playlist/core';\n\nexport interface AeneasFragment {\n begin: string;\n end: string;\n id: string;\n language: string;\n lines: string[];\n}\n\nexport function parseAeneas(data: AeneasFragment): AnnotationData {\n return {\n id: data.id,\n start: parseFloat(data.begin),\n end: parseFloat(data.end),\n lines: data.lines,\n language: data.language,\n };\n}\n\nexport function serializeAeneas(annotation: AnnotationData): AeneasFragment {\n return {\n id: annotation.id,\n begin: annotation.start.toFixed(3),\n end: annotation.end.toFixed(3),\n lines: annotation.lines,\n language: annotation.language || 'en',\n };\n}\n","import React, { FunctionComponent, useState } from 'react';\nimport styled from 'styled-components';\nimport type { AnnotationData, AnnotationAction, AnnotationActionOptions } from '@waveform-playlist/core';\n\ninterface AnnotationOverlayProps {\n readonly $left: number;\n readonly $width: number;\n readonly $color: string;\n}\n\nconst AnnotationOverlay = styled.div.attrs<AnnotationOverlayProps>((props) => ({\n style: {\n left: `${props.$left}px`,\n width: `${props.$width}px`,\n },\n}))<AnnotationOverlayProps>`\n position: absolute;\n top: 0;\n background: ${(props) => props.$color};\n height: 100%;\n z-index: 10;\n pointer-events: auto;\n opacity: 0.3;\n border: 2px solid ${(props) => props.$color};\n border-radius: 4px;\n cursor: pointer;\n\n &:hover {\n opacity: 0.5;\n border-color: ${(props) => props.$color};\n }\n`;\n\nconst AnnotationText = styled.div`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.7);\n color: white;\n padding: 4px 8px;\n font-size: 12px;\n line-height: 1.3;\n max-height: 60%;\n overflow: hidden;\n text-overflow: ellipsis;\n pointer-events: none;\n white-space: pre-wrap;\n word-break: break-word;\n`;\n\nconst EditableText = styled.textarea`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.9);\n color: white;\n padding: 4px 8px;\n font-size: 12px;\n line-height: 1.3;\n max-height: 60%;\n overflow: auto;\n border: 1px solid #fff;\n resize: none;\n font-family: inherit;\n\n &:focus {\n outline: none;\n border-color: #4CAF50;\n }\n`;\n\nconst ControlsBar = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.8);\n display: flex;\n gap: 4px;\n padding: 4px;\n justify-content: flex-start;\n align-items: center;\n`;\n\nconst ControlButton = styled.button`\n background: transparent;\n border: 1px solid rgba(255, 255, 255, 0.5);\n color: white;\n padding: 4px 8px;\n font-size: 10px;\n cursor: pointer;\n border-radius: 3px;\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n\n &:hover {\n background: rgba(255, 255, 255, 0.2);\n border-color: white;\n }\n\n &:active {\n background: rgba(255, 255, 255, 0.3);\n }\n`;\n\n// Re-export shared annotation types from core\nexport type { AnnotationData, AnnotationAction, AnnotationActionOptions } from '@waveform-playlist/core';\n\nexport interface AnnotationProps {\n annotation: AnnotationData;\n index: number;\n allAnnotations: AnnotationData[];\n startPosition: number; // Start position in pixels\n endPosition: number; // End position in pixels\n color?: string;\n editable?: boolean;\n controls?: AnnotationAction[];\n onAnnotationUpdate?: (updatedAnnotations: AnnotationData[]) => void;\n annotationListConfig?: AnnotationActionOptions;\n onClick?: (annotation: AnnotationData) => void;\n}\n\nexport const Annotation: FunctionComponent<AnnotationProps> = ({\n annotation,\n index,\n allAnnotations,\n startPosition,\n endPosition,\n color = '#ff9800',\n editable = false,\n controls = [],\n onAnnotationUpdate,\n annotationListConfig,\n onClick,\n}) => {\n const [isEditing, setIsEditing] = useState(false);\n const [editedText, setEditedText] = useState(annotation.lines.join('\\n'));\n const width = Math.max(0, endPosition - startPosition);\n\n if (width <= 0) {\n return null;\n }\n\n const handleClick = () => {\n if (onClick) {\n onClick(annotation);\n }\n };\n\n const handleDoubleClick = () => {\n if (editable) {\n setIsEditing(true);\n }\n };\n\n const handleTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setEditedText(e.target.value);\n };\n\n const handleTextBlur = () => {\n setIsEditing(false);\n const newLines = editedText.split('\\n');\n if (newLines.join('\\n') !== annotation.lines.join('\\n')) {\n const updatedAnnotations = [...allAnnotations];\n updatedAnnotations[index] = { ...annotation, lines: newLines };\n if (onAnnotationUpdate) {\n onAnnotationUpdate(updatedAnnotations);\n }\n }\n };\n\n const handleControlClick = (control: AnnotationAction) => {\n const annotationsCopy = [...allAnnotations];\n control.action(annotationsCopy[index], index, annotationsCopy, annotationListConfig || {});\n if (onAnnotationUpdate) {\n onAnnotationUpdate(annotationsCopy);\n }\n };\n\n const getIconClass = (classString: string) => {\n // Convert \"fas.fa-minus\" to \"fas fa-minus\"\n return classString.replace(/\\./g, ' ');\n };\n\n return (\n <AnnotationOverlay\n $left={startPosition}\n $width={width}\n $color={color}\n onClick={handleClick}\n onDoubleClick={handleDoubleClick}\n >\n {controls.length > 0 && (\n <ControlsBar>\n {controls.map((control, idx) => (\n <ControlButton\n key={idx}\n title={control.title}\n onClick={(e) => {\n e.stopPropagation();\n handleControlClick(control);\n }}\n >\n {control.text ? control.text : <i className={getIconClass(control.class || '')} />}\n </ControlButton>\n ))}\n </ControlsBar>\n )}\n {isEditing ? (\n <EditableText\n value={editedText}\n onChange={handleTextChange}\n onBlur={handleTextBlur}\n autoFocus\n onClick={(e) => e.stopPropagation()}\n onDoubleClick={(e) => e.stopPropagation()}\n />\n ) : (\n <AnnotationText>\n {annotation.lines.join('\\n')}\n </AnnotationText>\n )}\n </AnnotationOverlay>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { useDraggable } from '@dnd-kit/core';\nimport type { DraggableAttributes } from '@dnd-kit/core';\nimport type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';\n\ninterface WrapperProps {\n readonly $left: number;\n readonly $width: number;\n}\n\n// Wrapper positions the annotation and contains both Box and ResizeHandles as siblings\nconst Wrapper = styled.div.attrs<WrapperProps>((props) => ({\n style: {\n left: `${props.$left}px`,\n width: `${props.$width}px`,\n },\n}))<WrapperProps>`\n position: absolute;\n top: 0;\n height: 100%;\n pointer-events: none; /* Let events pass through to children */\n`;\n\ninterface BoxProps {\n readonly $color: string;\n readonly $isActive?: boolean;\n}\n\nconst Box = styled.div<BoxProps>`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 100%;\n background: ${(props) => props.$isActive\n ? (props.theme?.annotationBoxActiveBackground || 'rgba(255, 200, 100, 0.95)')\n : (props.theme?.annotationBoxBackground || 'rgba(255, 255, 255, 0.85)')};\n border: ${(props) => props.$isActive ? '3px' : '2px'} solid ${(props) => props.$isActive\n ? (props.theme?.annotationBoxActiveBorder || '#ff9800')\n : props.$color};\n border-radius: 4px;\n cursor: pointer;\n pointer-events: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: ${(props) => props.$isActive\n ? '0 2px 8px rgba(255, 152, 0, 0.4), inset 0 0 0 1px rgba(255, 152, 0, 0.2)'\n : '0 1px 3px rgba(0, 0, 0, 0.1)'};\n\n &:hover {\n background: ${(props) => props.theme?.annotationBoxHoverBackground || 'rgba(255, 255, 255, 0.98)'};\n border-color: ${(props) => props.theme?.annotationBoxActiveBorder || '#ff9800'};\n border-width: 3px;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);\n }\n`;\n\nconst Label = styled.span`\n font-size: 12px;\n font-weight: 600;\n color: ${(props) => props.theme?.annotationLabelColor || '#2a2a2a'};\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n padding: 0 6px;\n letter-spacing: 0.3px;\n user-select: none;\n`;\n\ninterface ResizeHandleStyledProps {\n $position: 'left' | 'right';\n $isDragging?: boolean;\n}\n\n// ResizeHandles sit inside their annotation's bounds so adjacent annotations'\n// handles never overlap — each handle is independently grabbable.\nconst ResizeHandle = styled.div<ResizeHandleStyledProps>`\n position: absolute;\n top: 0;\n ${(props) => props.$position === 'left' ? 'left: 0' : 'right: 0'};\n width: 8px;\n height: 100%;\n cursor: ew-resize;\n z-index: 120;\n background: ${(props) => props.$isDragging\n ? (props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.2)')\n : 'transparent'};\n border-radius: 4px;\n touch-action: none; /* Important for @dnd-kit on touch devices */\n pointer-events: auto;\n\n &::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 4px;\n height: 60%;\n background: ${(props) => props.$isDragging\n ? (props.theme?.annotationResizeHandleActiveColor || 'rgba(0, 0, 0, 0.8)')\n : (props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.4)')};\n border-radius: 2px;\n opacity: ${(props) => props.$isDragging ? 1 : 0.6};\n transition: opacity 0.2s, background 0.2s;\n }\n\n &:hover {\n background: ${(props) => props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.1)'};\n }\n\n &:hover::before {\n opacity: 1;\n background: ${(props) => props.theme?.annotationResizeHandleActiveColor || 'rgba(0, 0, 0, 0.7)'};\n }\n`;\n\nexport interface DragHandleProps {\n attributes: DraggableAttributes;\n listeners: SyntheticListenerMap | undefined;\n setActivatorNodeRef: (element: HTMLElement | null) => void;\n isDragging: boolean;\n}\n\nexport interface AnnotationBoxComponentProps {\n annotationId: string;\n annotationIndex: number;\n startPosition: number;\n endPosition: number;\n label?: string;\n color?: string;\n isActive?: boolean;\n onClick?: () => void;\n editable?: boolean; // Whether to show drag handles\n}\n\nexport const AnnotationBox: FunctionComponent<AnnotationBoxComponentProps> = ({\n annotationId,\n annotationIndex,\n startPosition,\n endPosition,\n label,\n color = '#ff9800',\n isActive = false,\n onClick,\n editable = true,\n}) => {\n const width = Math.max(0, endPosition - startPosition);\n\n // Left (start) boundary draggable\n const leftBoundaryId = `annotation-boundary-start-${annotationIndex}`;\n const {\n attributes: leftAttributes,\n listeners: leftListeners,\n setActivatorNodeRef: setLeftActivatorRef,\n isDragging: isLeftDragging,\n } = useDraggable({\n id: leftBoundaryId,\n data: { annotationId, annotationIndex, edge: 'start' as const },\n disabled: !editable,\n });\n\n // Right (end) boundary draggable\n const rightBoundaryId = `annotation-boundary-end-${annotationIndex}`;\n const {\n attributes: rightAttributes,\n listeners: rightListeners,\n setActivatorNodeRef: setRightActivatorRef,\n isDragging: isRightDragging,\n } = useDraggable({\n id: rightBoundaryId,\n data: { annotationId, annotationIndex, edge: 'end' as const },\n disabled: !editable,\n });\n\n if (width <= 0) {\n return null;\n }\n\n // Wrap @dnd-kit pointer handlers to also stop propagation\n // This prevents the ClickOverlay from capturing the event\n const createPointerDownHandler = (dndKitHandler?: (e: React.PointerEvent) => void) => {\n return (e: React.PointerEvent) => {\n e.stopPropagation();\n dndKitHandler?.(e);\n };\n };\n\n const handleHandleClick = (e: React.MouseEvent) => {\n // Prevent clicks on resize handles from bubbling to annotation box\n e.stopPropagation();\n };\n\n return (\n <Wrapper $left={startPosition} $width={width}>\n <Box\n $color={color}\n $isActive={isActive}\n onClick={onClick}\n >\n {label && <Label>{label}</Label>}\n </Box>\n {editable && (\n <ResizeHandle\n ref={setLeftActivatorRef}\n $position=\"left\"\n $isDragging={isLeftDragging}\n onClick={handleHandleClick}\n {...leftListeners}\n onPointerDown={createPointerDownHandler(leftListeners?.onPointerDown as ((e: React.PointerEvent) => void) | undefined)}\n {...leftAttributes}\n />\n )}\n {editable && (\n <ResizeHandle\n ref={setRightActivatorRef}\n $position=\"right\"\n $isDragging={isRightDragging}\n onClick={handleHandleClick}\n {...rightListeners}\n onPointerDown={createPointerDownHandler(rightListeners?.onPointerDown as ((e: React.PointerEvent) => void) | undefined)}\n {...rightAttributes}\n />\n )}\n </Wrapper>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { usePlaylistInfo } from '@waveform-playlist/ui-components';\n\ninterface ContainerProps {\n readonly $height: number;\n readonly $controlWidth: number;\n readonly $width?: number;\n}\n\nconst Container = styled.div.attrs<ContainerProps>((props) => ({\n style: {\n height: `${props.$height}px`,\n },\n}))<ContainerProps>`\n position: relative;\n display: flex;\n ${(props) => props.$width !== undefined && `width: ${props.$width}px;`}\n background: transparent;\n z-index: 110;\n`;\n\nconst ControlsPlaceholder = styled.div<{ $controlWidth: number }>`\n position: sticky;\n z-index: 200;\n left: 0;\n height: 100%;\n width: ${(props) => props.$controlWidth}px;\n flex-shrink: 0;\n background: transparent;\n`;\n\nconst BoxesContainer = styled.div<{ $offset?: number }>`\n position: relative;\n flex: 1;\n padding-left: ${(props) => props.$offset || 0}px;\n`;\n\nexport interface AnnotationBoxesWrapperProps {\n className?: string;\n children?: React.ReactNode;\n height?: number;\n offset?: number;\n width?: number;\n}\n\nexport const AnnotationBoxesWrapper: FunctionComponent<AnnotationBoxesWrapperProps> = ({\n children,\n className,\n height = 30,\n offset = 0,\n width,\n}) => {\n const {\n controls: { show, width: controlWidth },\n } = usePlaylistInfo();\n\n return (\n <Container\n className={className}\n $height={height}\n $controlWidth={show ? controlWidth : 0}\n $width={width}\n >\n <ControlsPlaceholder $controlWidth={show ? controlWidth : 0} />\n <BoxesContainer $offset={offset}>\n {children}\n </BoxesContainer>\n </Container>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { usePlaylistInfo } from '@waveform-playlist/ui-components';\n\ninterface ContainerProps {\n readonly $height: number;\n readonly $controlWidth: number;\n readonly $width?: number;\n}\n\nconst Container = styled.div.attrs<ContainerProps>((props) => ({\n style: {\n height: `${props.$height}px`,\n },\n}))<ContainerProps>`\n position: relative;\n display: flex;\n ${(props) => props.$width !== undefined && `width: ${props.$width}px;`}\n background: transparent;\n`;\n\nconst ControlsPlaceholder = styled.div<{ $controlWidth: number }>`\n position: sticky;\n z-index: 200;\n left: 0;\n height: 100%;\n width: ${(props) => props.$controlWidth}px;\n flex-shrink: 0;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n color: ${(props) => props.theme?.textColorMuted || '#666'};\n font-weight: bold;\n`;\n\nconst AnnotationsContainer = styled.div<{ $offset?: number }>`\n position: relative;\n flex: 1;\n padding-left: ${(props) => props.$offset || 0}px;\n`;\n\nexport interface AnnotationsTrackProps {\n className?: string;\n children?: React.ReactNode;\n height?: number;\n offset?: number;\n width?: number;\n}\n\nexport const AnnotationsTrack: FunctionComponent<AnnotationsTrackProps> = ({\n children,\n className,\n height = 100,\n offset = 0,\n width,\n}) => {\n const {\n controls: { show, width: controlWidth },\n } = usePlaylistInfo();\n\n return (\n <Container\n className={className}\n $height={height}\n $controlWidth={show ? controlWidth : 0}\n $width={width}\n >\n <ControlsPlaceholder $controlWidth={show ? controlWidth : 0}>\n Annotations\n </ControlsPlaceholder>\n <AnnotationsContainer $offset={offset}>\n {children}\n </AnnotationsContainer>\n </Container>\n );\n};\n","import React, { FunctionComponent, useRef, useEffect } from 'react';\nimport styled from 'styled-components';\nimport type { AnnotationData, AnnotationAction, AnnotationActionOptions, RenderAnnotationItemProps } from '@waveform-playlist/core';\n\ninterface ContainerProps {\n $height?: number;\n}\n\nconst Container = styled.div<ContainerProps>`\n background: ${(props) => props.theme?.backgroundColor || '#fff'};\n ${(props) => props.$height ? `height: ${props.$height}px;` : 'max-height: 200px;'}\n overflow-y: auto;\n padding: 8px;\n`;\n\nconst AnnotationItem = styled.div<{ $isActive?: boolean }>`\n padding: 12px;\n margin-bottom: 6px;\n border-left: 4px solid ${(props) => (props.$isActive ? '#ff9800' : 'transparent')};\n background: ${(props) => (props.$isActive ? 'rgba(255, 152, 0, 0.15)' : 'transparent')};\n border-radius: 4px;\n transition: all 0.2s;\n cursor: pointer;\n box-shadow: ${(props) => (props.$isActive ? '0 2px 8px rgba(255, 152, 0, 0.25), inset 0 0 0 1px rgba(255, 152, 0, 0.3)' : 'none')};\n\n &:hover {\n background: ${(props) => (props.$isActive ? 'rgba(255, 152, 0, 0.2)' : props.theme?.annotationTextItemHoverBackground || 'rgba(0, 0, 0, 0.05)')};\n border-left-color: ${(props) => (props.$isActive ? '#ff9800' : props.theme?.borderColor || '#ddd')};\n }\n\n &:focus-visible {\n outline: 2px solid #ff9800;\n outline-offset: 2px;\n }\n`;\n\nconst AnnotationHeader = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n`;\n\nconst AnnotationInfo = styled.div`\n display: flex;\n align-items: center;\n gap: 8px;\n`;\n\nconst AnnotationIdLabel = styled.span<{ $isEditable?: boolean }>`\n font-size: 11px;\n font-weight: 600;\n color: ${(props) => props.theme?.textColorMuted || '#666'};\n background: transparent;\n padding: 2px 6px;\n border-radius: 3px;\n min-width: 20px;\n outline: ${(props) => (props.$isEditable ? `1px dashed ${props.theme?.borderColor || '#ddd'}` : 'none')};\n\n &[contenteditable='true']:focus {\n outline: 2px solid #ff9800;\n background: rgba(255, 152, 0, 0.1);\n }\n`;\n\nconst TimeRange = styled.span`\n font-size: 12px;\n font-weight: 500;\n color: ${(props) => props.theme?.textColorMuted || '#555'};\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n letter-spacing: 0.5px;\n`;\n\nconst AnnotationControls = styled.div`\n display: flex;\n gap: 6px;\n`;\n\nconst ControlButton = styled.button`\n background: ${(props) => props.theme?.surfaceColor || '#f5f5f5'};\n border: 1px solid ${(props) => props.theme?.borderColor || '#ccc'};\n color: ${(props) => props.theme?.textColor || '#333'};\n padding: 4px 8px;\n font-size: 14px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s ease;\n\n &:hover {\n background: ${(props) => props.theme?.inputBackground || '#3d3d3d'};\n border-color: ${(props) => props.theme?.textColorMuted || '#999'};\n transform: scale(1.05);\n }\n\n &:active {\n transform: scale(0.95);\n }\n`;\n\nconst AnnotationTextContent = styled.div<{ $isEditable?: boolean }>`\n font-size: 14px;\n line-height: 1.6;\n color: ${(props) => props.theme?.textColor || '#2a2a2a'};\n white-space: pre-wrap;\n word-break: break-word;\n outline: ${(props) => (props.$isEditable ? `1px dashed ${props.theme?.borderColor || '#ddd'}` : 'none')};\n padding: ${(props) => (props.$isEditable ? '6px' : '0')};\n border-radius: 3px;\n min-height: 20px;\n\n &[contenteditable='true']:focus {\n outline: 2px solid #ff9800;\n background: rgba(255, 152, 0, 0.1);\n }\n`;\n\n// Re-export from core\nexport type { RenderAnnotationItemProps } from '@waveform-playlist/core';\n\nexport interface AnnotationTextProps {\n annotations: AnnotationData[];\n activeAnnotationId?: string;\n shouldScrollToActive?: boolean;\n /** Where to position the active annotation when scrolling: 'center', 'start', 'end', or 'nearest'. Defaults to 'center'. */\n scrollActivePosition?: ScrollLogicalPosition;\n /** Which scrollable containers to scroll: 'nearest' (only the annotation list) or 'all' (including viewport). Defaults to 'nearest'. */\n scrollActiveContainer?: 'nearest' | 'all';\n editable?: boolean;\n controls?: AnnotationAction[];\n annotationListConfig?: AnnotationActionOptions;\n height?: number;\n onAnnotationClick?: (annotation: AnnotationData) => void;\n onAnnotationUpdate?: (updatedAnnotations: AnnotationData[]) => void;\n /**\n * Custom render function for annotation items.\n * When provided, completely replaces the default annotation item rendering.\n * Use this to customize the appearance of each annotation in the list.\n */\n renderAnnotationItem?: (props: RenderAnnotationItemProps) => React.ReactNode;\n}\n\nconst AnnotationTextComponent: FunctionComponent<AnnotationTextProps> = ({\n annotations,\n activeAnnotationId,\n shouldScrollToActive = false,\n scrollActivePosition = 'center',\n scrollActiveContainer = 'nearest',\n editable = false,\n controls = [],\n annotationListConfig,\n height,\n onAnnotationClick,\n onAnnotationUpdate,\n renderAnnotationItem,\n}) => {\n const activeAnnotationRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const prevActiveIdRef = useRef<string | undefined>(undefined);\n\n // Track component renders and scroll position\n useEffect(() => {\n // Render tracking removed\n });\n\n // Track scroll changes\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handleScroll = () => {\n // Scroll tracking removed\n };\n\n container.addEventListener('scroll', handleScroll);\n return () => container.removeEventListener('scroll', handleScroll);\n }, []);\n\n // Auto-scroll to active annotation when it changes\n useEffect(() => {\n // Only scroll if parent says we should (prevents scrolling on remount after pause)\n if (activeAnnotationId && activeAnnotationRef.current && shouldScrollToActive) {\n activeAnnotationRef.current.scrollIntoView({\n behavior: 'smooth',\n block: scrollActivePosition,\n container: scrollActiveContainer,\n } as ScrollIntoViewOptions);\n }\n\n prevActiveIdRef.current = activeAnnotationId;\n }, [activeAnnotationId, shouldScrollToActive, scrollActivePosition, scrollActiveContainer]);\n\n const formatTime = (seconds: number): string => {\n if (isNaN(seconds) || !isFinite(seconds)) {\n return '0:00.000';\n }\n const mins = Math.floor(seconds / 60);\n const secs = (seconds % 60).toFixed(3);\n return `${mins}:${secs.padStart(6, '0')}`;\n };\n\n const handleTextEdit = (index: number, newText: string) => {\n if (!editable || !onAnnotationUpdate) return;\n\n const updatedAnnotations = [...annotations];\n updatedAnnotations[index] = {\n ...updatedAnnotations[index],\n lines: newText.split('\\n'),\n };\n onAnnotationUpdate(updatedAnnotations);\n };\n\n const handleIdEdit = (index: number, newId: string) => {\n if (!editable || !onAnnotationUpdate) return;\n\n const trimmedId = newId.trim();\n if (!trimmedId) return; // Don't allow empty IDs\n\n const updatedAnnotations = [...annotations];\n updatedAnnotations[index] = {\n ...updatedAnnotations[index],\n id: trimmedId,\n };\n onAnnotationUpdate(updatedAnnotations);\n };\n\n const handleControlClick = (control: AnnotationAction, annotation: AnnotationData, index: number) => {\n if (!onAnnotationUpdate) return;\n\n const annotationsCopy = [...annotations];\n control.action(annotationsCopy[index], index, annotationsCopy, annotationListConfig || {});\n onAnnotationUpdate(annotationsCopy);\n };\n\n const getIconClass = (classString: string) => {\n return classString.replace(/\\./g, ' ');\n };\n\n return (\n <Container ref={containerRef} $height={height}>\n {annotations.map((annotation, index) => {\n const isActive = annotation.id === activeAnnotationId;\n const handleClick = () => onAnnotationClick?.(annotation);\n\n // Use custom render function if provided\n if (renderAnnotationItem) {\n return (\n <div\n key={annotation.id}\n ref={isActive ? activeAnnotationRef : null}\n >\n {renderAnnotationItem({\n annotation,\n index,\n isActive,\n onClick: handleClick,\n formatTime,\n })}\n </div>\n );\n }\n\n // Default rendering\n return (\n <AnnotationItem\n key={annotation.id}\n ref={isActive ? activeAnnotationRef : null}\n $isActive={isActive}\n onClick={handleClick}\n >\n <AnnotationHeader>\n <AnnotationInfo>\n <AnnotationIdLabel\n $isEditable={editable}\n contentEditable={editable}\n suppressContentEditableWarning\n onBlur={(e) => handleIdEdit(index, e.currentTarget.textContent || '')}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n (e.currentTarget as HTMLElement).blur();\n }\n }}\n >\n {annotation.id}\n </AnnotationIdLabel>\n <TimeRange>\n {formatTime(annotation.start)} - {formatTime(annotation.end)}\n </TimeRange>\n </AnnotationInfo>\n {controls.length > 0 && (\n <AnnotationControls onClick={(e) => e.stopPropagation()}>\n {controls.map((control, idx) => (\n <ControlButton\n key={idx}\n title={control.title}\n onClick={() => handleControlClick(control, annotation, index)}\n >\n {control.text ? control.text : <i className={getIconClass(control.class || '')} />}\n </ControlButton>\n ))}\n </AnnotationControls>\n )}\n </AnnotationHeader>\n <AnnotationTextContent\n $isEditable={editable}\n contentEditable={editable}\n suppressContentEditableWarning\n onBlur={(e) => handleTextEdit(index, e.currentTarget.textContent || '')}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n (e.currentTarget as HTMLElement).blur();\n }\n }}\n >\n {annotation.lines.join('\\n')}\n </AnnotationTextContent>\n </AnnotationItem>\n );\n })}\n </Container>\n );\n};\n\n// Memoize to prevent unnecessary remounting when parent re-renders\nexport const AnnotationText = React.memo(AnnotationTextComponent);\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface ContinuousPlayCheckboxProps {\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Checkbox control for enabling/disabling continuous play of annotations.\n * When enabled, playback continues from one annotation to the next without stopping.\n */\nexport const ContinuousPlayCheckbox: React.FC<ContinuousPlayCheckboxProps> = ({\n checked,\n onChange,\n disabled = false,\n className,\n}) => {\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked);\n };\n\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"continuous-play\"\n className=\"continuous-play\"\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n />\n <BaseCheckboxLabel htmlFor=\"continuous-play\">Continuous Play</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface LinkEndpointsCheckboxProps {\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Checkbox control for enabling/disabling linked endpoints between annotations.\n * When enabled, the end time of one annotation is automatically linked to the start time of the next.\n */\nexport const LinkEndpointsCheckbox: React.FC<LinkEndpointsCheckboxProps> = ({\n checked,\n onChange,\n disabled = false,\n className,\n}) => {\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked);\n };\n\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"link-endpoints\"\n className=\"link-endpoints\"\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n />\n <BaseCheckboxLabel htmlFor=\"link-endpoints\">Link Endpoints</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface EditableCheckboxProps {\n checked: boolean;\n onChange: (enabled: boolean) => void;\n className?: string;\n}\n\nexport const EditableCheckbox: React.FC<EditableCheckboxProps> = ({\n checked,\n onChange,\n className,\n}) => {\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"editable-annotations\"\n checked={checked}\n onChange={(e) => onChange(e.target.checked)}\n />\n <BaseCheckboxLabel htmlFor=\"editable-annotations\">Editable Annotations</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport styled from 'styled-components';\nimport { serializeAeneas } from '../parsers/aeneas';\nimport type { AnnotationData } from '../types';\n\nconst StyledButton = styled.button`\n padding: 0.5rem 1rem;\n background: ${(props) => props.theme?.surfaceColor || '#f5f5f5'};\n color: ${(props) => props.theme?.textColor || '#333'};\n border: 1px solid ${(props) => props.theme?.borderColor || '#ccc'};\n border-radius: ${(props) => props.theme?.borderRadius || '4px'};\n cursor: pointer;\n font-family: ${(props) => props.theme?.fontFamily || 'inherit'};\n font-size: ${(props) => props.theme?.fontSize || '14px'};\n font-weight: 500;\n transition: all 0.15s ease;\n\n &:hover:not(:disabled) {\n background: ${(props) => props.theme?.inputBackground || '#3d3d3d'};\n border-color: ${(props) => props.theme?.textColorMuted || '#999'};\n }\n\n &:focus {\n outline: none;\n box-shadow: 0 0 0 2px ${(props) => props.theme?.inputFocusBorder || '#007bff'}44;\n }\n\n &:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n`;\n\nexport interface DownloadAnnotationsButtonProps {\n annotations: AnnotationData[];\n filename?: string;\n disabled?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nexport const DownloadAnnotationsButton: React.FC<DownloadAnnotationsButtonProps> = ({\n annotations,\n filename = 'annotations.json',\n disabled = false,\n className,\n children = 'Download JSON',\n}) => {\n const handleDownload = () => {\n if (annotations.length === 0) {\n return;\n }\n\n // Serialize annotations to Aeneas JSON format\n const jsonData = annotations.map(annotation => serializeAeneas(annotation));\n const jsonString = JSON.stringify(jsonData, null, 2);\n\n // Create a blob and download link\n const blob = new Blob([jsonString], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n\n // Trigger download\n document.body.appendChild(link);\n link.click();\n\n // Cleanup\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n };\n\n return (\n <StyledButton\n onClick={handleDownload}\n disabled={disabled || annotations.length === 0}\n className={className}\n title={annotations.length === 0 ? 'No annotations to download' : 'Download the annotations as JSON'}\n >\n {children}\n </StyledButton>\n );\n};\n","import React from 'react';\nimport { AnnotationIntegrationProvider } from '@waveform-playlist/browser';\nimport type { AnnotationIntegration } from '@waveform-playlist/browser';\nimport { parseAeneas, serializeAeneas } from './parsers/aeneas';\nimport { AnnotationText } from './components/AnnotationText';\nimport { AnnotationBox } from './components/AnnotationBox';\nimport { AnnotationBoxesWrapper } from './components/AnnotationBoxesWrapper';\nimport { ContinuousPlayCheckbox } from './components/ContinuousPlayCheckbox';\nimport { LinkEndpointsCheckbox } from './components/LinkEndpointsCheckbox';\nimport { EditableCheckbox } from './components/EditableCheckbox';\nimport { DownloadAnnotationsButton } from './components/DownloadAnnotationsButton';\n\nconst annotationIntegration: AnnotationIntegration = {\n parseAeneas: parseAeneas as (data: unknown) => import('@waveform-playlist/core').AnnotationData,\n serializeAeneas: serializeAeneas as (annotation: import('@waveform-playlist/core').AnnotationData) => unknown,\n AnnotationText,\n AnnotationBox,\n AnnotationBoxesWrapper,\n ContinuousPlayCheckbox,\n LinkEndpointsCheckbox,\n EditableCheckbox,\n DownloadAnnotationsButton,\n};\n\nexport const AnnotationProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n return (\n <AnnotationIntegrationProvider value={annotationIntegration}>\n {children}\n </AnnotationIntegrationProvider>\n );\n};\n","import { useState, useCallback } from 'react';\nimport type { AnnotationData, AnnotationListOptions } from '../types';\n\nconst LINK_THRESHOLD = 0.01; // Consider edges \"linked\" if within 10ms\n\nexport interface UseAnnotationControlsOptions {\n initialContinuousPlay?: boolean;\n initialLinkEndpoints?: boolean;\n}\n\nexport interface AnnotationUpdateParams {\n annotationIndex: number;\n newTime: number;\n isDraggingStart: boolean;\n annotations: AnnotationData[];\n duration: number;\n linkEndpoints: boolean;\n}\n\nexport interface UseAnnotationControlsReturn {\n continuousPlay: boolean;\n linkEndpoints: boolean;\n setContinuousPlay: (value: boolean) => void;\n setLinkEndpoints: (value: boolean) => void;\n updateAnnotationBoundaries: (params: AnnotationUpdateParams) => AnnotationData[];\n}\n\n/**\n * Hook for managing annotation control state and boundary logic.\n * Handles continuous play mode and linked endpoints behavior.\n */\nexport const useAnnotationControls = (\n options: UseAnnotationControlsOptions = {}\n): UseAnnotationControlsReturn => {\n const {\n initialContinuousPlay = false,\n initialLinkEndpoints = true,\n } = options;\n\n const [continuousPlay, setContinuousPlay] = useState(initialContinuousPlay);\n const [linkEndpoints, setLinkEndpoints] = useState(initialLinkEndpoints);\n\n /**\n * Updates annotation boundaries based on drag operations.\n * Handles linked endpoints and collision detection.\n * Note: linkEndpoints is passed as a parameter to ensure it uses the current value from context.\n */\n const updateAnnotationBoundaries = useCallback(\n ({\n annotationIndex,\n newTime,\n isDraggingStart,\n annotations,\n duration,\n linkEndpoints: shouldLinkEndpoints,\n }: AnnotationUpdateParams): AnnotationData[] => {\n const updatedAnnotations = [...annotations];\n const annotation = annotations[annotationIndex];\n\n if (isDraggingStart) {\n // Dragging start edge\n const constrainedStart = Math.min(annotation.end - 0.1, Math.max(0, newTime));\n const delta = constrainedStart - annotation.start;\n\n updatedAnnotations[annotationIndex] = {\n ...annotation,\n start: constrainedStart,\n };\n\n if (shouldLinkEndpoints && annotationIndex > 0) {\n // Link Endpoints mode: handle both already-linked and collision scenarios\n const prevAnnotation = updatedAnnotations[annotationIndex - 1];\n\n if (Math.abs(prevAnnotation.end - annotation.start) < LINK_THRESHOLD) {\n // Already linked: move previous annotation's end together with this start\n updatedAnnotations[annotationIndex - 1] = {\n ...prevAnnotation,\n end: Math.max(prevAnnotation.start + 0.1, prevAnnotation.end + delta),\n };\n } else if (constrainedStart <= prevAnnotation.end) {\n // Dragged past previous annotation: snap to link them together\n updatedAnnotations[annotationIndex] = {\n ...updatedAnnotations[annotationIndex],\n start: prevAnnotation.end,\n };\n }\n } else if (!shouldLinkEndpoints && annotationIndex > 0 && constrainedStart < updatedAnnotations[annotationIndex - 1].end) {\n // Collision detection: push previous annotation's end back\n updatedAnnotations[annotationIndex - 1] = {\n ...updatedAnnotations[annotationIndex - 1],\n end: constrainedStart,\n };\n }\n } else {\n // Dragging end edge\n const constrainedEnd = Math.max(annotation.start + 0.1, Math.min(newTime, duration));\n const delta = constrainedEnd - annotation.end;\n\n updatedAnnotations[annotationIndex] = {\n ...annotation,\n end: constrainedEnd,\n };\n\n if (shouldLinkEndpoints && annotationIndex < updatedAnnotations.length - 1) {\n // Link Endpoints mode: handle both already-linked and collision scenarios\n const nextAnnotation = updatedAnnotations[annotationIndex + 1];\n\n if (Math.abs(nextAnnotation.start - annotation.end) < LINK_THRESHOLD) {\n // Already linked: move next annotation's start together with this end\n const newStart = nextAnnotation.start + delta;\n updatedAnnotations[annotationIndex + 1] = {\n ...nextAnnotation,\n start: Math.min(nextAnnotation.end - 0.1, newStart),\n };\n\n // Cascade linked endpoints\n let currentIndex = annotationIndex + 1;\n while (currentIndex < updatedAnnotations.length - 1) {\n const current = updatedAnnotations[currentIndex];\n const next = updatedAnnotations[currentIndex + 1];\n\n if (Math.abs(next.start - current.end) < LINK_THRESHOLD) {\n const nextDelta = current.end - annotations[currentIndex].end;\n updatedAnnotations[currentIndex + 1] = {\n ...next,\n start: Math.min(next.end - 0.1, next.start + nextDelta),\n };\n currentIndex++;\n } else {\n break; // No more linked endpoints\n }\n }\n } else if (constrainedEnd >= nextAnnotation.start) {\n // Dragged past next annotation: snap to link them together\n updatedAnnotations[annotationIndex] = {\n ...updatedAnnotations[annotationIndex],\n end: nextAnnotation.start,\n };\n }\n } else if (!shouldLinkEndpoints && annotationIndex < updatedAnnotations.length - 1 && constrainedEnd > updatedAnnotations[annotationIndex + 1].start) {\n // Collision detection: push next annotation's start forward\n const nextAnnotation = updatedAnnotations[annotationIndex + 1];\n\n updatedAnnotations[annotationIndex + 1] = {\n ...nextAnnotation,\n start: constrainedEnd,\n };\n\n // Cascade collisions\n let currentIndex = annotationIndex + 1;\n while (currentIndex < updatedAnnotations.length - 1) {\n const current = updatedAnnotations[currentIndex];\n const next = updatedAnnotations[currentIndex + 1];\n\n if (current.end > next.start) {\n updatedAnnotations[currentIndex + 1] = {\n ...next,\n start: current.end,\n };\n currentIndex++;\n } else {\n break; // No more collisions\n }\n }\n }\n }\n\n return updatedAnnotations;\n },\n []\n );\n\n return {\n continuousPlay,\n linkEndpoints,\n setContinuousPlay,\n setLinkEndpoints,\n updateAnnotationBoundaries,\n };\n};\n"],"mappings":"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","names":["AnnotationText","styled","import_styled_components","import_jsx_runtime","styled","import_styled_components","import_jsx_runtime","styled","import_styled_components","import_ui_components","import_jsx_runtime","Container","styled","ControlsPlaceholder","import_react","import_styled_components","import_jsx_runtime","Container","styled","ControlButton","AnnotationText","React","import_ui_components","import_jsx_runtime","import_ui_components","import_jsx_runtime","import_ui_components","import_jsx_runtime","import_styled_components","import_jsx_runtime","styled","import_jsx_runtime","AnnotationText","import_react"]}
package/dist/index.mjs CHANGED
@@ -5,7 +5,7 @@ function parseAeneas(data) {
5
5
  start: parseFloat(data.begin),
6
6
  end: parseFloat(data.end),
7
7
  lines: data.lines,
8
- lang: data.language
8
+ language: data.language
9
9
  };
10
10
  }
11
11
  function serializeAeneas(annotation) {
@@ -14,7 +14,7 @@ function serializeAeneas(annotation) {
14
14
  begin: annotation.start.toFixed(3),
15
15
  end: annotation.end.toFixed(3),
16
16
  lines: annotation.lines,
17
- language: annotation.lang || "en"
17
+ language: annotation.language || "en"
18
18
  };
19
19
  }
20
20
 
@@ -894,6 +894,24 @@ var DownloadAnnotationsButton = ({
894
894
  );
895
895
  };
896
896
 
897
+ // src/AnnotationProvider.tsx
898
+ import { AnnotationIntegrationProvider } from "@waveform-playlist/browser";
899
+ import { jsx as jsx10 } from "react/jsx-runtime";
900
+ var annotationIntegration = {
901
+ parseAeneas,
902
+ serializeAeneas,
903
+ AnnotationText: AnnotationText2,
904
+ AnnotationBox,
905
+ AnnotationBoxesWrapper,
906
+ ContinuousPlayCheckbox,
907
+ LinkEndpointsCheckbox,
908
+ EditableCheckbox,
909
+ DownloadAnnotationsButton
910
+ };
911
+ var AnnotationProvider = ({ children }) => {
912
+ return /* @__PURE__ */ jsx10(AnnotationIntegrationProvider, { value: annotationIntegration, children });
913
+ };
914
+
897
915
  // src/hooks/useAnnotationControls.ts
898
916
  import { useState as useState2, useCallback } from "react";
899
917
  var LINK_THRESHOLD = 0.01;
@@ -1015,6 +1033,7 @@ export {
1015
1033
  Annotation,
1016
1034
  AnnotationBox,
1017
1035
  AnnotationBoxesWrapper,
1036
+ AnnotationProvider,
1018
1037
  AnnotationText2 as AnnotationText,
1019
1038
  AnnotationsTrack,
1020
1039
  ContinuousPlayCheckbox,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/parsers/aeneas.ts","../src/components/Annotation.tsx","../src/components/AnnotationBox.tsx","../src/components/AnnotationBoxesWrapper.tsx","../src/components/AnnotationsTrack.tsx","../src/components/AnnotationText.tsx","../src/components/ContinuousPlayCheckbox.tsx","../src/components/LinkEndpointsCheckbox.tsx","../src/components/EditableCheckbox.tsx","../src/components/DownloadAnnotationsButton.tsx","../src/hooks/useAnnotationControls.ts"],"sourcesContent":["import { Annotation } from '../types';\n\nexport interface AeneasFragment {\n begin: string;\n end: string;\n id: string;\n language: string;\n lines: string[];\n}\n\nexport function parseAeneas(data: AeneasFragment): Annotation {\n return {\n id: data.id,\n start: parseFloat(data.begin),\n end: parseFloat(data.end),\n lines: data.lines,\n lang: data.language,\n };\n}\n\nexport function serializeAeneas(annotation: Annotation): AeneasFragment {\n return {\n id: annotation.id,\n begin: annotation.start.toFixed(3),\n end: annotation.end.toFixed(3),\n lines: annotation.lines,\n language: annotation.lang || 'en',\n };\n}\n","import React, { FunctionComponent, useState } from 'react';\nimport styled from 'styled-components';\n\ninterface AnnotationOverlayProps {\n readonly $left: number;\n readonly $width: number;\n readonly $color: string;\n}\n\nconst AnnotationOverlay = styled.div.attrs<AnnotationOverlayProps>((props) => ({\n style: {\n left: `${props.$left}px`,\n width: `${props.$width}px`,\n },\n}))<AnnotationOverlayProps>`\n position: absolute;\n top: 0;\n background: ${(props) => props.$color};\n height: 100%;\n z-index: 10;\n pointer-events: auto;\n opacity: 0.3;\n border: 2px solid ${(props) => props.$color};\n border-radius: 4px;\n cursor: pointer;\n\n &:hover {\n opacity: 0.5;\n border-color: ${(props) => props.$color};\n }\n`;\n\nconst AnnotationText = styled.div`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.7);\n color: white;\n padding: 4px 8px;\n font-size: 12px;\n line-height: 1.3;\n max-height: 60%;\n overflow: hidden;\n text-overflow: ellipsis;\n pointer-events: none;\n white-space: pre-wrap;\n word-break: break-word;\n`;\n\nconst EditableText = styled.textarea`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.9);\n color: white;\n padding: 4px 8px;\n font-size: 12px;\n line-height: 1.3;\n max-height: 60%;\n overflow: auto;\n border: 1px solid #fff;\n resize: none;\n font-family: inherit;\n\n &:focus {\n outline: none;\n border-color: #4CAF50;\n }\n`;\n\nconst ControlsBar = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.8);\n display: flex;\n gap: 4px;\n padding: 4px;\n justify-content: flex-start;\n align-items: center;\n`;\n\nconst ControlButton = styled.button`\n background: transparent;\n border: 1px solid rgba(255, 255, 255, 0.5);\n color: white;\n padding: 4px 8px;\n font-size: 10px;\n cursor: pointer;\n border-radius: 3px;\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n\n &:hover {\n background: rgba(255, 255, 255, 0.2);\n border-color: white;\n }\n\n &:active {\n background: rgba(255, 255, 255, 0.3);\n }\n`;\n\n/**\n * Configuration options passed to annotation action handlers\n */\nexport interface AnnotationActionOptions {\n /** Whether annotation endpoints are linked (moving one endpoint moves the other) */\n linkEndpoints?: boolean;\n /** Whether to continue playing after an annotation ends */\n continuousPlay?: boolean;\n /** Additional custom properties */\n [key: string]: unknown;\n}\n\nexport interface AnnotationAction {\n class?: string;\n text?: string;\n title: string;\n action: (annotation: AnnotationData, index: number, annotations: AnnotationData[], opts: AnnotationActionOptions) => void;\n}\n\nexport interface AnnotationData {\n id: string;\n start: number;\n end: number;\n lines: string[];\n language?: string;\n}\n\nexport interface AnnotationProps {\n annotation: AnnotationData;\n index: number;\n allAnnotations: AnnotationData[];\n startPosition: number; // Start position in pixels\n endPosition: number; // End position in pixels\n color?: string;\n editable?: boolean;\n controls?: AnnotationAction[];\n onAnnotationUpdate?: (updatedAnnotations: AnnotationData[]) => void;\n annotationListConfig?: AnnotationActionOptions;\n onClick?: (annotation: AnnotationData) => void;\n}\n\nexport const Annotation: FunctionComponent<AnnotationProps> = ({\n annotation,\n index,\n allAnnotations,\n startPosition,\n endPosition,\n color = '#ff9800',\n editable = false,\n controls = [],\n onAnnotationUpdate,\n annotationListConfig,\n onClick,\n}) => {\n const [isEditing, setIsEditing] = useState(false);\n const [editedText, setEditedText] = useState(annotation.lines.join('\\n'));\n const width = Math.max(0, endPosition - startPosition);\n\n if (width <= 0) {\n return null;\n }\n\n const handleClick = () => {\n if (onClick) {\n onClick(annotation);\n }\n };\n\n const handleDoubleClick = () => {\n if (editable) {\n setIsEditing(true);\n }\n };\n\n const handleTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setEditedText(e.target.value);\n };\n\n const handleTextBlur = () => {\n setIsEditing(false);\n const newLines = editedText.split('\\n');\n if (newLines.join('\\n') !== annotation.lines.join('\\n')) {\n const updatedAnnotations = [...allAnnotations];\n updatedAnnotations[index] = { ...annotation, lines: newLines };\n if (onAnnotationUpdate) {\n onAnnotationUpdate(updatedAnnotations);\n }\n }\n };\n\n const handleControlClick = (control: AnnotationAction) => {\n const annotationsCopy = [...allAnnotations];\n control.action(annotationsCopy[index], index, annotationsCopy, annotationListConfig || {});\n if (onAnnotationUpdate) {\n onAnnotationUpdate(annotationsCopy);\n }\n };\n\n const getIconClass = (classString: string) => {\n // Convert \"fas.fa-minus\" to \"fas fa-minus\"\n return classString.replace(/\\./g, ' ');\n };\n\n return (\n <AnnotationOverlay\n $left={startPosition}\n $width={width}\n $color={color}\n onClick={handleClick}\n onDoubleClick={handleDoubleClick}\n >\n {controls.length > 0 && (\n <ControlsBar>\n {controls.map((control, idx) => (\n <ControlButton\n key={idx}\n title={control.title}\n onClick={(e) => {\n e.stopPropagation();\n handleControlClick(control);\n }}\n >\n {control.text ? control.text : <i className={getIconClass(control.class || '')} />}\n </ControlButton>\n ))}\n </ControlsBar>\n )}\n {isEditing ? (\n <EditableText\n value={editedText}\n onChange={handleTextChange}\n onBlur={handleTextBlur}\n autoFocus\n onClick={(e) => e.stopPropagation()}\n onDoubleClick={(e) => e.stopPropagation()}\n />\n ) : (\n <AnnotationText>\n {annotation.lines.join('\\n')}\n </AnnotationText>\n )}\n </AnnotationOverlay>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { useDraggable } from '@dnd-kit/core';\nimport type { DraggableAttributes } from '@dnd-kit/core';\nimport type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';\n\ninterface WrapperProps {\n readonly $left: number;\n readonly $width: number;\n}\n\n// Wrapper positions the annotation and contains both Box and ResizeHandles as siblings\nconst Wrapper = styled.div.attrs<WrapperProps>((props) => ({\n style: {\n left: `${props.$left}px`,\n width: `${props.$width}px`,\n },\n}))<WrapperProps>`\n position: absolute;\n top: 0;\n height: 100%;\n pointer-events: none; /* Let events pass through to children */\n`;\n\ninterface BoxProps {\n readonly $color: string;\n readonly $isActive?: boolean;\n}\n\nconst Box = styled.div<BoxProps>`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 100%;\n background: ${(props) => props.$isActive\n ? (props.theme?.annotationBoxActiveBackground || 'rgba(255, 200, 100, 0.95)')\n : (props.theme?.annotationBoxBackground || 'rgba(255, 255, 255, 0.85)')};\n border: ${(props) => props.$isActive ? '3px' : '2px'} solid ${(props) => props.$isActive\n ? (props.theme?.annotationBoxActiveBorder || '#ff9800')\n : props.$color};\n border-radius: 4px;\n cursor: pointer;\n pointer-events: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: ${(props) => props.$isActive\n ? '0 2px 8px rgba(255, 152, 0, 0.4), inset 0 0 0 1px rgba(255, 152, 0, 0.2)'\n : '0 1px 3px rgba(0, 0, 0, 0.1)'};\n\n &:hover {\n background: ${(props) => props.theme?.annotationBoxHoverBackground || 'rgba(255, 255, 255, 0.98)'};\n border-color: ${(props) => props.theme?.annotationBoxActiveBorder || '#ff9800'};\n border-width: 3px;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);\n }\n`;\n\nconst Label = styled.span`\n font-size: 12px;\n font-weight: 600;\n color: ${(props) => props.theme?.annotationLabelColor || '#2a2a2a'};\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n padding: 0 6px;\n letter-spacing: 0.3px;\n user-select: none;\n`;\n\ninterface ResizeHandleStyledProps {\n $position: 'left' | 'right';\n $isDragging?: boolean;\n}\n\n// ResizeHandles sit inside their annotation's bounds so adjacent annotations'\n// handles never overlap — each handle is independently grabbable.\nconst ResizeHandle = styled.div<ResizeHandleStyledProps>`\n position: absolute;\n top: 0;\n ${(props) => props.$position === 'left' ? 'left: 0' : 'right: 0'};\n width: 8px;\n height: 100%;\n cursor: ew-resize;\n z-index: 120;\n background: ${(props) => props.$isDragging\n ? (props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.2)')\n : 'transparent'};\n border-radius: 4px;\n touch-action: none; /* Important for @dnd-kit on touch devices */\n pointer-events: auto;\n\n &::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 4px;\n height: 60%;\n background: ${(props) => props.$isDragging\n ? (props.theme?.annotationResizeHandleActiveColor || 'rgba(0, 0, 0, 0.8)')\n : (props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.4)')};\n border-radius: 2px;\n opacity: ${(props) => props.$isDragging ? 1 : 0.6};\n transition: opacity 0.2s, background 0.2s;\n }\n\n &:hover {\n background: ${(props) => props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.1)'};\n }\n\n &:hover::before {\n opacity: 1;\n background: ${(props) => props.theme?.annotationResizeHandleActiveColor || 'rgba(0, 0, 0, 0.7)'};\n }\n`;\n\nexport interface DragHandleProps {\n attributes: DraggableAttributes;\n listeners: SyntheticListenerMap | undefined;\n setActivatorNodeRef: (element: HTMLElement | null) => void;\n isDragging: boolean;\n}\n\nexport interface AnnotationBoxComponentProps {\n annotationId: string;\n annotationIndex: number;\n startPosition: number;\n endPosition: number;\n label?: string;\n color?: string;\n isActive?: boolean;\n onClick?: () => void;\n editable?: boolean; // Whether to show drag handles\n}\n\nexport const AnnotationBox: FunctionComponent<AnnotationBoxComponentProps> = ({\n annotationId,\n annotationIndex,\n startPosition,\n endPosition,\n label,\n color = '#ff9800',\n isActive = false,\n onClick,\n editable = true,\n}) => {\n const width = Math.max(0, endPosition - startPosition);\n\n // Left (start) boundary draggable\n const leftBoundaryId = `annotation-boundary-start-${annotationIndex}`;\n const {\n attributes: leftAttributes,\n listeners: leftListeners,\n setActivatorNodeRef: setLeftActivatorRef,\n isDragging: isLeftDragging,\n } = useDraggable({\n id: leftBoundaryId,\n data: { annotationId, annotationIndex, edge: 'start' as const },\n disabled: !editable,\n });\n\n // Right (end) boundary draggable\n const rightBoundaryId = `annotation-boundary-end-${annotationIndex}`;\n const {\n attributes: rightAttributes,\n listeners: rightListeners,\n setActivatorNodeRef: setRightActivatorRef,\n isDragging: isRightDragging,\n } = useDraggable({\n id: rightBoundaryId,\n data: { annotationId, annotationIndex, edge: 'end' as const },\n disabled: !editable,\n });\n\n if (width <= 0) {\n return null;\n }\n\n // Wrap @dnd-kit pointer handlers to also stop propagation\n // This prevents the ClickOverlay from capturing the event\n const createPointerDownHandler = (dndKitHandler?: (e: React.PointerEvent) => void) => {\n return (e: React.PointerEvent) => {\n e.stopPropagation();\n dndKitHandler?.(e);\n };\n };\n\n const handleHandleClick = (e: React.MouseEvent) => {\n // Prevent clicks on resize handles from bubbling to annotation box\n e.stopPropagation();\n };\n\n return (\n <Wrapper $left={startPosition} $width={width}>\n <Box\n $color={color}\n $isActive={isActive}\n onClick={onClick}\n >\n {label && <Label>{label}</Label>}\n </Box>\n {editable && (\n <ResizeHandle\n ref={setLeftActivatorRef}\n $position=\"left\"\n $isDragging={isLeftDragging}\n onClick={handleHandleClick}\n {...leftListeners}\n onPointerDown={createPointerDownHandler(leftListeners?.onPointerDown as ((e: React.PointerEvent) => void) | undefined)}\n {...leftAttributes}\n />\n )}\n {editable && (\n <ResizeHandle\n ref={setRightActivatorRef}\n $position=\"right\"\n $isDragging={isRightDragging}\n onClick={handleHandleClick}\n {...rightListeners}\n onPointerDown={createPointerDownHandler(rightListeners?.onPointerDown as ((e: React.PointerEvent) => void) | undefined)}\n {...rightAttributes}\n />\n )}\n </Wrapper>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { usePlaylistInfo } from '@waveform-playlist/ui-components';\n\ninterface ContainerProps {\n readonly $height: number;\n readonly $controlWidth: number;\n readonly $width?: number;\n}\n\nconst Container = styled.div.attrs<ContainerProps>((props) => ({\n style: {\n height: `${props.$height}px`,\n },\n}))<ContainerProps>`\n position: relative;\n display: flex;\n ${(props) => props.$width !== undefined && `width: ${props.$width}px;`}\n background: transparent;\n z-index: 110;\n`;\n\nconst ControlsPlaceholder = styled.div<{ $controlWidth: number }>`\n position: sticky;\n z-index: 200;\n left: 0;\n height: 100%;\n width: ${(props) => props.$controlWidth}px;\n flex-shrink: 0;\n background: transparent;\n`;\n\nconst BoxesContainer = styled.div<{ $offset?: number }>`\n position: relative;\n flex: 1;\n padding-left: ${(props) => props.$offset || 0}px;\n`;\n\nexport interface AnnotationBoxesWrapperProps {\n className?: string;\n children?: React.ReactNode;\n height?: number;\n offset?: number;\n width?: number;\n}\n\nexport const AnnotationBoxesWrapper: FunctionComponent<AnnotationBoxesWrapperProps> = ({\n children,\n className,\n height = 30,\n offset = 0,\n width,\n}) => {\n const {\n controls: { show, width: controlWidth },\n } = usePlaylistInfo();\n\n return (\n <Container\n className={className}\n $height={height}\n $controlWidth={show ? controlWidth : 0}\n $width={width}\n >\n <ControlsPlaceholder $controlWidth={show ? controlWidth : 0} />\n <BoxesContainer $offset={offset}>\n {children}\n </BoxesContainer>\n </Container>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { usePlaylistInfo } from '@waveform-playlist/ui-components';\n\ninterface ContainerProps {\n readonly $height: number;\n readonly $controlWidth: number;\n readonly $width?: number;\n}\n\nconst Container = styled.div.attrs<ContainerProps>((props) => ({\n style: {\n height: `${props.$height}px`,\n },\n}))<ContainerProps>`\n position: relative;\n display: flex;\n ${(props) => props.$width !== undefined && `width: ${props.$width}px;`}\n background: transparent;\n`;\n\nconst ControlsPlaceholder = styled.div<{ $controlWidth: number }>`\n position: sticky;\n z-index: 200;\n left: 0;\n height: 100%;\n width: ${(props) => props.$controlWidth}px;\n flex-shrink: 0;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n color: ${(props) => props.theme?.textColorMuted || '#666'};\n font-weight: bold;\n`;\n\nconst AnnotationsContainer = styled.div<{ $offset?: number }>`\n position: relative;\n flex: 1;\n padding-left: ${(props) => props.$offset || 0}px;\n`;\n\nexport interface AnnotationsTrackProps {\n className?: string;\n children?: React.ReactNode;\n height?: number;\n offset?: number;\n width?: number;\n}\n\nexport const AnnotationsTrack: FunctionComponent<AnnotationsTrackProps> = ({\n children,\n className,\n height = 100,\n offset = 0,\n width,\n}) => {\n const {\n controls: { show, width: controlWidth },\n } = usePlaylistInfo();\n\n return (\n <Container\n className={className}\n $height={height}\n $controlWidth={show ? controlWidth : 0}\n $width={width}\n >\n <ControlsPlaceholder $controlWidth={show ? controlWidth : 0}>\n Annotations\n </ControlsPlaceholder>\n <AnnotationsContainer $offset={offset}>\n {children}\n </AnnotationsContainer>\n </Container>\n );\n};\n","import React, { FunctionComponent, useRef, useEffect } from 'react';\nimport styled from 'styled-components';\nimport type { AnnotationData, AnnotationAction, AnnotationActionOptions } from './Annotation';\n\ninterface ContainerProps {\n $height?: number;\n}\n\nconst Container = styled.div<ContainerProps>`\n background: ${(props) => props.theme?.backgroundColor || '#fff'};\n ${(props) => props.$height ? `height: ${props.$height}px;` : 'max-height: 200px;'}\n overflow-y: auto;\n padding: 8px;\n`;\n\nconst AnnotationItem = styled.div<{ $isActive?: boolean }>`\n padding: 12px;\n margin-bottom: 6px;\n border-left: 4px solid ${(props) => (props.$isActive ? '#ff9800' : 'transparent')};\n background: ${(props) => (props.$isActive ? 'rgba(255, 152, 0, 0.15)' : 'transparent')};\n border-radius: 4px;\n transition: all 0.2s;\n cursor: pointer;\n box-shadow: ${(props) => (props.$isActive ? '0 2px 8px rgba(255, 152, 0, 0.25), inset 0 0 0 1px rgba(255, 152, 0, 0.3)' : 'none')};\n\n &:hover {\n background: ${(props) => (props.$isActive ? 'rgba(255, 152, 0, 0.2)' : props.theme?.annotationTextItemHoverBackground || 'rgba(0, 0, 0, 0.05)')};\n border-left-color: ${(props) => (props.$isActive ? '#ff9800' : props.theme?.borderColor || '#ddd')};\n }\n\n &:focus-visible {\n outline: 2px solid #ff9800;\n outline-offset: 2px;\n }\n`;\n\nconst AnnotationHeader = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n`;\n\nconst AnnotationInfo = styled.div`\n display: flex;\n align-items: center;\n gap: 8px;\n`;\n\nconst AnnotationIdLabel = styled.span<{ $isEditable?: boolean }>`\n font-size: 11px;\n font-weight: 600;\n color: ${(props) => props.theme?.textColorMuted || '#666'};\n background: transparent;\n padding: 2px 6px;\n border-radius: 3px;\n min-width: 20px;\n outline: ${(props) => (props.$isEditable ? `1px dashed ${props.theme?.borderColor || '#ddd'}` : 'none')};\n\n &[contenteditable='true']:focus {\n outline: 2px solid #ff9800;\n background: rgba(255, 152, 0, 0.1);\n }\n`;\n\nconst TimeRange = styled.span`\n font-size: 12px;\n font-weight: 500;\n color: ${(props) => props.theme?.textColorMuted || '#555'};\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n letter-spacing: 0.5px;\n`;\n\nconst AnnotationControls = styled.div`\n display: flex;\n gap: 6px;\n`;\n\nconst ControlButton = styled.button`\n background: ${(props) => props.theme?.surfaceColor || '#f5f5f5'};\n border: 1px solid ${(props) => props.theme?.borderColor || '#ccc'};\n color: ${(props) => props.theme?.textColor || '#333'};\n padding: 4px 8px;\n font-size: 14px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s ease;\n\n &:hover {\n background: ${(props) => props.theme?.inputBackground || '#3d3d3d'};\n border-color: ${(props) => props.theme?.textColorMuted || '#999'};\n transform: scale(1.05);\n }\n\n &:active {\n transform: scale(0.95);\n }\n`;\n\nconst AnnotationTextContent = styled.div<{ $isEditable?: boolean }>`\n font-size: 14px;\n line-height: 1.6;\n color: ${(props) => props.theme?.textColor || '#2a2a2a'};\n white-space: pre-wrap;\n word-break: break-word;\n outline: ${(props) => (props.$isEditable ? `1px dashed ${props.theme?.borderColor || '#ddd'}` : 'none')};\n padding: ${(props) => (props.$isEditable ? '6px' : '0')};\n border-radius: 3px;\n min-height: 20px;\n\n &[contenteditable='true']:focus {\n outline: 2px solid #ff9800;\n background: rgba(255, 152, 0, 0.1);\n }\n`;\n\n/**\n * Props passed to the renderAnnotationItem function for custom rendering\n */\nexport interface RenderAnnotationItemProps {\n annotation: AnnotationData;\n index: number;\n isActive: boolean;\n onClick: () => void;\n formatTime: (seconds: number) => string;\n}\n\nexport interface AnnotationTextProps {\n annotations: AnnotationData[];\n activeAnnotationId?: string;\n shouldScrollToActive?: boolean;\n /** Where to position the active annotation when scrolling: 'center', 'start', 'end', or 'nearest'. Defaults to 'center'. */\n scrollActivePosition?: ScrollLogicalPosition;\n /** Which scrollable containers to scroll: 'nearest' (only the annotation list) or 'all' (including viewport). Defaults to 'nearest'. */\n scrollActiveContainer?: 'nearest' | 'all';\n editable?: boolean;\n controls?: AnnotationAction[];\n annotationListConfig?: AnnotationActionOptions;\n height?: number;\n onAnnotationClick?: (annotation: AnnotationData) => void;\n onAnnotationUpdate?: (updatedAnnotations: AnnotationData[]) => void;\n /**\n * Custom render function for annotation items.\n * When provided, completely replaces the default annotation item rendering.\n * Use this to customize the appearance of each annotation in the list.\n */\n renderAnnotationItem?: (props: RenderAnnotationItemProps) => React.ReactNode;\n}\n\nconst AnnotationTextComponent: FunctionComponent<AnnotationTextProps> = ({\n annotations,\n activeAnnotationId,\n shouldScrollToActive = false,\n scrollActivePosition = 'center',\n scrollActiveContainer = 'nearest',\n editable = false,\n controls = [],\n annotationListConfig,\n height,\n onAnnotationClick,\n onAnnotationUpdate,\n renderAnnotationItem,\n}) => {\n const activeAnnotationRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const prevActiveIdRef = useRef<string | undefined>(undefined);\n\n // Track component renders and scroll position\n useEffect(() => {\n // Render tracking removed\n });\n\n // Track scroll changes\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handleScroll = () => {\n // Scroll tracking removed\n };\n\n container.addEventListener('scroll', handleScroll);\n return () => container.removeEventListener('scroll', handleScroll);\n }, []);\n\n // Auto-scroll to active annotation when it changes\n useEffect(() => {\n // Only scroll if parent says we should (prevents scrolling on remount after pause)\n if (activeAnnotationId && activeAnnotationRef.current && shouldScrollToActive) {\n activeAnnotationRef.current.scrollIntoView({\n behavior: 'smooth',\n block: scrollActivePosition,\n container: scrollActiveContainer,\n } as ScrollIntoViewOptions);\n }\n\n prevActiveIdRef.current = activeAnnotationId;\n }, [activeAnnotationId, shouldScrollToActive, scrollActivePosition, scrollActiveContainer]);\n\n const formatTime = (seconds: number): string => {\n if (isNaN(seconds) || !isFinite(seconds)) {\n return '0:00.000';\n }\n const mins = Math.floor(seconds / 60);\n const secs = (seconds % 60).toFixed(3);\n return `${mins}:${secs.padStart(6, '0')}`;\n };\n\n const handleTextEdit = (index: number, newText: string) => {\n if (!editable || !onAnnotationUpdate) return;\n\n const updatedAnnotations = [...annotations];\n updatedAnnotations[index] = {\n ...updatedAnnotations[index],\n lines: newText.split('\\n'),\n };\n onAnnotationUpdate(updatedAnnotations);\n };\n\n const handleIdEdit = (index: number, newId: string) => {\n if (!editable || !onAnnotationUpdate) return;\n\n const trimmedId = newId.trim();\n if (!trimmedId) return; // Don't allow empty IDs\n\n const updatedAnnotations = [...annotations];\n updatedAnnotations[index] = {\n ...updatedAnnotations[index],\n id: trimmedId,\n };\n onAnnotationUpdate(updatedAnnotations);\n };\n\n const handleControlClick = (control: AnnotationAction, annotation: AnnotationData, index: number) => {\n if (!onAnnotationUpdate) return;\n\n const annotationsCopy = [...annotations];\n control.action(annotationsCopy[index], index, annotationsCopy, annotationListConfig || {});\n onAnnotationUpdate(annotationsCopy);\n };\n\n const getIconClass = (classString: string) => {\n return classString.replace(/\\./g, ' ');\n };\n\n return (\n <Container ref={containerRef} $height={height}>\n {annotations.map((annotation, index) => {\n const isActive = annotation.id === activeAnnotationId;\n const handleClick = () => onAnnotationClick?.(annotation);\n\n // Use custom render function if provided\n if (renderAnnotationItem) {\n return (\n <div\n key={annotation.id}\n ref={isActive ? activeAnnotationRef : null}\n >\n {renderAnnotationItem({\n annotation,\n index,\n isActive,\n onClick: handleClick,\n formatTime,\n })}\n </div>\n );\n }\n\n // Default rendering\n return (\n <AnnotationItem\n key={annotation.id}\n ref={isActive ? activeAnnotationRef : null}\n $isActive={isActive}\n onClick={handleClick}\n >\n <AnnotationHeader>\n <AnnotationInfo>\n <AnnotationIdLabel\n $isEditable={editable}\n contentEditable={editable}\n suppressContentEditableWarning\n onBlur={(e) => handleIdEdit(index, e.currentTarget.textContent || '')}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n (e.currentTarget as HTMLElement).blur();\n }\n }}\n >\n {annotation.id}\n </AnnotationIdLabel>\n <TimeRange>\n {formatTime(annotation.start)} - {formatTime(annotation.end)}\n </TimeRange>\n </AnnotationInfo>\n {controls.length > 0 && (\n <AnnotationControls onClick={(e) => e.stopPropagation()}>\n {controls.map((control, idx) => (\n <ControlButton\n key={idx}\n title={control.title}\n onClick={() => handleControlClick(control, annotation, index)}\n >\n {control.text ? control.text : <i className={getIconClass(control.class || '')} />}\n </ControlButton>\n ))}\n </AnnotationControls>\n )}\n </AnnotationHeader>\n <AnnotationTextContent\n $isEditable={editable}\n contentEditable={editable}\n suppressContentEditableWarning\n onBlur={(e) => handleTextEdit(index, e.currentTarget.textContent || '')}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n (e.currentTarget as HTMLElement).blur();\n }\n }}\n >\n {annotation.lines.join('\\n')}\n </AnnotationTextContent>\n </AnnotationItem>\n );\n })}\n </Container>\n );\n};\n\n// Memoize to prevent unnecessary remounting when parent re-renders\nexport const AnnotationText = React.memo(AnnotationTextComponent);\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface ContinuousPlayCheckboxProps {\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Checkbox control for enabling/disabling continuous play of annotations.\n * When enabled, playback continues from one annotation to the next without stopping.\n */\nexport const ContinuousPlayCheckbox: React.FC<ContinuousPlayCheckboxProps> = ({\n checked,\n onChange,\n disabled = false,\n className,\n}) => {\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked);\n };\n\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"continuous-play\"\n className=\"continuous-play\"\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n />\n <BaseCheckboxLabel htmlFor=\"continuous-play\">Continuous Play</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface LinkEndpointsCheckboxProps {\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Checkbox control for enabling/disabling linked endpoints between annotations.\n * When enabled, the end time of one annotation is automatically linked to the start time of the next.\n */\nexport const LinkEndpointsCheckbox: React.FC<LinkEndpointsCheckboxProps> = ({\n checked,\n onChange,\n disabled = false,\n className,\n}) => {\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked);\n };\n\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"link-endpoints\"\n className=\"link-endpoints\"\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n />\n <BaseCheckboxLabel htmlFor=\"link-endpoints\">Link Endpoints</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface EditableCheckboxProps {\n checked: boolean;\n onChange: (enabled: boolean) => void;\n className?: string;\n}\n\nexport const EditableCheckbox: React.FC<EditableCheckboxProps> = ({\n checked,\n onChange,\n className,\n}) => {\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"editable-annotations\"\n checked={checked}\n onChange={(e) => onChange(e.target.checked)}\n />\n <BaseCheckboxLabel htmlFor=\"editable-annotations\">Editable Annotations</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport styled from 'styled-components';\nimport { serializeAeneas } from '../parsers/aeneas';\nimport type { Annotation } from '../types';\n\nconst StyledButton = styled.button`\n padding: 0.5rem 1rem;\n background: ${(props) => props.theme?.surfaceColor || '#f5f5f5'};\n color: ${(props) => props.theme?.textColor || '#333'};\n border: 1px solid ${(props) => props.theme?.borderColor || '#ccc'};\n border-radius: ${(props) => props.theme?.borderRadius || '4px'};\n cursor: pointer;\n font-family: ${(props) => props.theme?.fontFamily || 'inherit'};\n font-size: ${(props) => props.theme?.fontSize || '14px'};\n font-weight: 500;\n transition: all 0.15s ease;\n\n &:hover:not(:disabled) {\n background: ${(props) => props.theme?.inputBackground || '#3d3d3d'};\n border-color: ${(props) => props.theme?.textColorMuted || '#999'};\n }\n\n &:focus {\n outline: none;\n box-shadow: 0 0 0 2px ${(props) => props.theme?.inputFocusBorder || '#007bff'}44;\n }\n\n &:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n`;\n\nexport interface DownloadAnnotationsButtonProps {\n annotations: Annotation[];\n filename?: string;\n disabled?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nexport const DownloadAnnotationsButton: React.FC<DownloadAnnotationsButtonProps> = ({\n annotations,\n filename = 'annotations.json',\n disabled = false,\n className,\n children = 'Download JSON',\n}) => {\n const handleDownload = () => {\n if (annotations.length === 0) {\n return;\n }\n\n // Serialize annotations to Aeneas JSON format\n const jsonData = annotations.map(annotation => serializeAeneas(annotation));\n const jsonString = JSON.stringify(jsonData, null, 2);\n\n // Create a blob and download link\n const blob = new Blob([jsonString], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n\n // Trigger download\n document.body.appendChild(link);\n link.click();\n\n // Cleanup\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n };\n\n return (\n <StyledButton\n onClick={handleDownload}\n disabled={disabled || annotations.length === 0}\n className={className}\n title={annotations.length === 0 ? 'No annotations to download' : 'Download the annotations as JSON'}\n >\n {children}\n </StyledButton>\n );\n};\n","import { useState, useCallback } from 'react';\nimport type { Annotation, AnnotationListOptions } from '../types';\n\nconst LINK_THRESHOLD = 0.01; // Consider edges \"linked\" if within 10ms\n\nexport interface UseAnnotationControlsOptions {\n initialContinuousPlay?: boolean;\n initialLinkEndpoints?: boolean;\n}\n\nexport interface AnnotationUpdateParams {\n annotationIndex: number;\n newTime: number;\n isDraggingStart: boolean;\n annotations: Annotation[];\n duration: number;\n linkEndpoints: boolean;\n}\n\nexport interface UseAnnotationControlsReturn {\n continuousPlay: boolean;\n linkEndpoints: boolean;\n setContinuousPlay: (value: boolean) => void;\n setLinkEndpoints: (value: boolean) => void;\n updateAnnotationBoundaries: (params: AnnotationUpdateParams) => Annotation[];\n}\n\n/**\n * Hook for managing annotation control state and boundary logic.\n * Handles continuous play mode and linked endpoints behavior.\n */\nexport const useAnnotationControls = (\n options: UseAnnotationControlsOptions = {}\n): UseAnnotationControlsReturn => {\n const {\n initialContinuousPlay = false,\n initialLinkEndpoints = true,\n } = options;\n\n const [continuousPlay, setContinuousPlay] = useState(initialContinuousPlay);\n const [linkEndpoints, setLinkEndpoints] = useState(initialLinkEndpoints);\n\n /**\n * Updates annotation boundaries based on drag operations.\n * Handles linked endpoints and collision detection.\n * Note: linkEndpoints is passed as a parameter to ensure it uses the current value from context.\n */\n const updateAnnotationBoundaries = useCallback(\n ({\n annotationIndex,\n newTime,\n isDraggingStart,\n annotations,\n duration,\n linkEndpoints: shouldLinkEndpoints,\n }: AnnotationUpdateParams): Annotation[] => {\n const updatedAnnotations = [...annotations];\n const annotation = annotations[annotationIndex];\n\n if (isDraggingStart) {\n // Dragging start edge\n const constrainedStart = Math.min(annotation.end - 0.1, Math.max(0, newTime));\n const delta = constrainedStart - annotation.start;\n\n updatedAnnotations[annotationIndex] = {\n ...annotation,\n start: constrainedStart,\n };\n\n if (shouldLinkEndpoints && annotationIndex > 0) {\n // Link Endpoints mode: handle both already-linked and collision scenarios\n const prevAnnotation = updatedAnnotations[annotationIndex - 1];\n\n if (Math.abs(prevAnnotation.end - annotation.start) < LINK_THRESHOLD) {\n // Already linked: move previous annotation's end together with this start\n updatedAnnotations[annotationIndex - 1] = {\n ...prevAnnotation,\n end: Math.max(prevAnnotation.start + 0.1, prevAnnotation.end + delta),\n };\n } else if (constrainedStart <= prevAnnotation.end) {\n // Dragged past previous annotation: snap to link them together\n updatedAnnotations[annotationIndex] = {\n ...updatedAnnotations[annotationIndex],\n start: prevAnnotation.end,\n };\n }\n } else if (!shouldLinkEndpoints && annotationIndex > 0 && constrainedStart < updatedAnnotations[annotationIndex - 1].end) {\n // Collision detection: push previous annotation's end back\n updatedAnnotations[annotationIndex - 1] = {\n ...updatedAnnotations[annotationIndex - 1],\n end: constrainedStart,\n };\n }\n } else {\n // Dragging end edge\n const constrainedEnd = Math.max(annotation.start + 0.1, Math.min(newTime, duration));\n const delta = constrainedEnd - annotation.end;\n\n updatedAnnotations[annotationIndex] = {\n ...annotation,\n end: constrainedEnd,\n };\n\n if (shouldLinkEndpoints && annotationIndex < updatedAnnotations.length - 1) {\n // Link Endpoints mode: handle both already-linked and collision scenarios\n const nextAnnotation = updatedAnnotations[annotationIndex + 1];\n\n if (Math.abs(nextAnnotation.start - annotation.end) < LINK_THRESHOLD) {\n // Already linked: move next annotation's start together with this end\n const newStart = nextAnnotation.start + delta;\n updatedAnnotations[annotationIndex + 1] = {\n ...nextAnnotation,\n start: Math.min(nextAnnotation.end - 0.1, newStart),\n };\n\n // Cascade linked endpoints\n let currentIndex = annotationIndex + 1;\n while (currentIndex < updatedAnnotations.length - 1) {\n const current = updatedAnnotations[currentIndex];\n const next = updatedAnnotations[currentIndex + 1];\n\n if (Math.abs(next.start - current.end) < LINK_THRESHOLD) {\n const nextDelta = current.end - annotations[currentIndex].end;\n updatedAnnotations[currentIndex + 1] = {\n ...next,\n start: Math.min(next.end - 0.1, next.start + nextDelta),\n };\n currentIndex++;\n } else {\n break; // No more linked endpoints\n }\n }\n } else if (constrainedEnd >= nextAnnotation.start) {\n // Dragged past next annotation: snap to link them together\n updatedAnnotations[annotationIndex] = {\n ...updatedAnnotations[annotationIndex],\n end: nextAnnotation.start,\n };\n }\n } else if (!shouldLinkEndpoints && annotationIndex < updatedAnnotations.length - 1 && constrainedEnd > updatedAnnotations[annotationIndex + 1].start) {\n // Collision detection: push next annotation's start forward\n const nextAnnotation = updatedAnnotations[annotationIndex + 1];\n\n updatedAnnotations[annotationIndex + 1] = {\n ...nextAnnotation,\n start: constrainedEnd,\n };\n\n // Cascade collisions\n let currentIndex = annotationIndex + 1;\n while (currentIndex < updatedAnnotations.length - 1) {\n const current = updatedAnnotations[currentIndex];\n const next = updatedAnnotations[currentIndex + 1];\n\n if (current.end > next.start) {\n updatedAnnotations[currentIndex + 1] = {\n ...next,\n start: current.end,\n };\n currentIndex++;\n } else {\n break; // No more collisions\n }\n }\n }\n }\n\n return updatedAnnotations;\n },\n []\n );\n\n return {\n continuousPlay,\n linkEndpoints,\n setContinuousPlay,\n setLinkEndpoints,\n updateAnnotationBoundaries,\n };\n};\n"],"mappings":"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","names":["styled","jsx","jsxs","styled","jsx","jsxs","styled","usePlaylistInfo","jsx","jsxs","Container","ControlsPlaceholder","React","styled","jsx","jsxs","Container","ControlButton","AnnotationText","jsx","jsxs","BaseCheckboxWrapper","BaseCheckbox","BaseCheckboxLabel","jsx","jsxs","BaseCheckboxWrapper","BaseCheckbox","BaseCheckboxLabel","jsx","jsxs","styled","jsx","styled","useState"]}
1
+ {"version":3,"sources":["../src/parsers/aeneas.ts","../src/components/Annotation.tsx","../src/components/AnnotationBox.tsx","../src/components/AnnotationBoxesWrapper.tsx","../src/components/AnnotationsTrack.tsx","../src/components/AnnotationText.tsx","../src/components/ContinuousPlayCheckbox.tsx","../src/components/LinkEndpointsCheckbox.tsx","../src/components/EditableCheckbox.tsx","../src/components/DownloadAnnotationsButton.tsx","../src/AnnotationProvider.tsx","../src/hooks/useAnnotationControls.ts"],"sourcesContent":["import type { AnnotationData } from '@waveform-playlist/core';\n\nexport interface AeneasFragment {\n begin: string;\n end: string;\n id: string;\n language: string;\n lines: string[];\n}\n\nexport function parseAeneas(data: AeneasFragment): AnnotationData {\n return {\n id: data.id,\n start: parseFloat(data.begin),\n end: parseFloat(data.end),\n lines: data.lines,\n language: data.language,\n };\n}\n\nexport function serializeAeneas(annotation: AnnotationData): AeneasFragment {\n return {\n id: annotation.id,\n begin: annotation.start.toFixed(3),\n end: annotation.end.toFixed(3),\n lines: annotation.lines,\n language: annotation.language || 'en',\n };\n}\n","import React, { FunctionComponent, useState } from 'react';\nimport styled from 'styled-components';\nimport type { AnnotationData, AnnotationAction, AnnotationActionOptions } from '@waveform-playlist/core';\n\ninterface AnnotationOverlayProps {\n readonly $left: number;\n readonly $width: number;\n readonly $color: string;\n}\n\nconst AnnotationOverlay = styled.div.attrs<AnnotationOverlayProps>((props) => ({\n style: {\n left: `${props.$left}px`,\n width: `${props.$width}px`,\n },\n}))<AnnotationOverlayProps>`\n position: absolute;\n top: 0;\n background: ${(props) => props.$color};\n height: 100%;\n z-index: 10;\n pointer-events: auto;\n opacity: 0.3;\n border: 2px solid ${(props) => props.$color};\n border-radius: 4px;\n cursor: pointer;\n\n &:hover {\n opacity: 0.5;\n border-color: ${(props) => props.$color};\n }\n`;\n\nconst AnnotationText = styled.div`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.7);\n color: white;\n padding: 4px 8px;\n font-size: 12px;\n line-height: 1.3;\n max-height: 60%;\n overflow: hidden;\n text-overflow: ellipsis;\n pointer-events: none;\n white-space: pre-wrap;\n word-break: break-word;\n`;\n\nconst EditableText = styled.textarea`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.9);\n color: white;\n padding: 4px 8px;\n font-size: 12px;\n line-height: 1.3;\n max-height: 60%;\n overflow: auto;\n border: 1px solid #fff;\n resize: none;\n font-family: inherit;\n\n &:focus {\n outline: none;\n border-color: #4CAF50;\n }\n`;\n\nconst ControlsBar = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.8);\n display: flex;\n gap: 4px;\n padding: 4px;\n justify-content: flex-start;\n align-items: center;\n`;\n\nconst ControlButton = styled.button`\n background: transparent;\n border: 1px solid rgba(255, 255, 255, 0.5);\n color: white;\n padding: 4px 8px;\n font-size: 10px;\n cursor: pointer;\n border-radius: 3px;\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n\n &:hover {\n background: rgba(255, 255, 255, 0.2);\n border-color: white;\n }\n\n &:active {\n background: rgba(255, 255, 255, 0.3);\n }\n`;\n\n// Re-export shared annotation types from core\nexport type { AnnotationData, AnnotationAction, AnnotationActionOptions } from '@waveform-playlist/core';\n\nexport interface AnnotationProps {\n annotation: AnnotationData;\n index: number;\n allAnnotations: AnnotationData[];\n startPosition: number; // Start position in pixels\n endPosition: number; // End position in pixels\n color?: string;\n editable?: boolean;\n controls?: AnnotationAction[];\n onAnnotationUpdate?: (updatedAnnotations: AnnotationData[]) => void;\n annotationListConfig?: AnnotationActionOptions;\n onClick?: (annotation: AnnotationData) => void;\n}\n\nexport const Annotation: FunctionComponent<AnnotationProps> = ({\n annotation,\n index,\n allAnnotations,\n startPosition,\n endPosition,\n color = '#ff9800',\n editable = false,\n controls = [],\n onAnnotationUpdate,\n annotationListConfig,\n onClick,\n}) => {\n const [isEditing, setIsEditing] = useState(false);\n const [editedText, setEditedText] = useState(annotation.lines.join('\\n'));\n const width = Math.max(0, endPosition - startPosition);\n\n if (width <= 0) {\n return null;\n }\n\n const handleClick = () => {\n if (onClick) {\n onClick(annotation);\n }\n };\n\n const handleDoubleClick = () => {\n if (editable) {\n setIsEditing(true);\n }\n };\n\n const handleTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setEditedText(e.target.value);\n };\n\n const handleTextBlur = () => {\n setIsEditing(false);\n const newLines = editedText.split('\\n');\n if (newLines.join('\\n') !== annotation.lines.join('\\n')) {\n const updatedAnnotations = [...allAnnotations];\n updatedAnnotations[index] = { ...annotation, lines: newLines };\n if (onAnnotationUpdate) {\n onAnnotationUpdate(updatedAnnotations);\n }\n }\n };\n\n const handleControlClick = (control: AnnotationAction) => {\n const annotationsCopy = [...allAnnotations];\n control.action(annotationsCopy[index], index, annotationsCopy, annotationListConfig || {});\n if (onAnnotationUpdate) {\n onAnnotationUpdate(annotationsCopy);\n }\n };\n\n const getIconClass = (classString: string) => {\n // Convert \"fas.fa-minus\" to \"fas fa-minus\"\n return classString.replace(/\\./g, ' ');\n };\n\n return (\n <AnnotationOverlay\n $left={startPosition}\n $width={width}\n $color={color}\n onClick={handleClick}\n onDoubleClick={handleDoubleClick}\n >\n {controls.length > 0 && (\n <ControlsBar>\n {controls.map((control, idx) => (\n <ControlButton\n key={idx}\n title={control.title}\n onClick={(e) => {\n e.stopPropagation();\n handleControlClick(control);\n }}\n >\n {control.text ? control.text : <i className={getIconClass(control.class || '')} />}\n </ControlButton>\n ))}\n </ControlsBar>\n )}\n {isEditing ? (\n <EditableText\n value={editedText}\n onChange={handleTextChange}\n onBlur={handleTextBlur}\n autoFocus\n onClick={(e) => e.stopPropagation()}\n onDoubleClick={(e) => e.stopPropagation()}\n />\n ) : (\n <AnnotationText>\n {annotation.lines.join('\\n')}\n </AnnotationText>\n )}\n </AnnotationOverlay>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { useDraggable } from '@dnd-kit/core';\nimport type { DraggableAttributes } from '@dnd-kit/core';\nimport type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';\n\ninterface WrapperProps {\n readonly $left: number;\n readonly $width: number;\n}\n\n// Wrapper positions the annotation and contains both Box and ResizeHandles as siblings\nconst Wrapper = styled.div.attrs<WrapperProps>((props) => ({\n style: {\n left: `${props.$left}px`,\n width: `${props.$width}px`,\n },\n}))<WrapperProps>`\n position: absolute;\n top: 0;\n height: 100%;\n pointer-events: none; /* Let events pass through to children */\n`;\n\ninterface BoxProps {\n readonly $color: string;\n readonly $isActive?: boolean;\n}\n\nconst Box = styled.div<BoxProps>`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 100%;\n background: ${(props) => props.$isActive\n ? (props.theme?.annotationBoxActiveBackground || 'rgba(255, 200, 100, 0.95)')\n : (props.theme?.annotationBoxBackground || 'rgba(255, 255, 255, 0.85)')};\n border: ${(props) => props.$isActive ? '3px' : '2px'} solid ${(props) => props.$isActive\n ? (props.theme?.annotationBoxActiveBorder || '#ff9800')\n : props.$color};\n border-radius: 4px;\n cursor: pointer;\n pointer-events: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: ${(props) => props.$isActive\n ? '0 2px 8px rgba(255, 152, 0, 0.4), inset 0 0 0 1px rgba(255, 152, 0, 0.2)'\n : '0 1px 3px rgba(0, 0, 0, 0.1)'};\n\n &:hover {\n background: ${(props) => props.theme?.annotationBoxHoverBackground || 'rgba(255, 255, 255, 0.98)'};\n border-color: ${(props) => props.theme?.annotationBoxActiveBorder || '#ff9800'};\n border-width: 3px;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);\n }\n`;\n\nconst Label = styled.span`\n font-size: 12px;\n font-weight: 600;\n color: ${(props) => props.theme?.annotationLabelColor || '#2a2a2a'};\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n padding: 0 6px;\n letter-spacing: 0.3px;\n user-select: none;\n`;\n\ninterface ResizeHandleStyledProps {\n $position: 'left' | 'right';\n $isDragging?: boolean;\n}\n\n// ResizeHandles sit inside their annotation's bounds so adjacent annotations'\n// handles never overlap — each handle is independently grabbable.\nconst ResizeHandle = styled.div<ResizeHandleStyledProps>`\n position: absolute;\n top: 0;\n ${(props) => props.$position === 'left' ? 'left: 0' : 'right: 0'};\n width: 8px;\n height: 100%;\n cursor: ew-resize;\n z-index: 120;\n background: ${(props) => props.$isDragging\n ? (props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.2)')\n : 'transparent'};\n border-radius: 4px;\n touch-action: none; /* Important for @dnd-kit on touch devices */\n pointer-events: auto;\n\n &::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 4px;\n height: 60%;\n background: ${(props) => props.$isDragging\n ? (props.theme?.annotationResizeHandleActiveColor || 'rgba(0, 0, 0, 0.8)')\n : (props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.4)')};\n border-radius: 2px;\n opacity: ${(props) => props.$isDragging ? 1 : 0.6};\n transition: opacity 0.2s, background 0.2s;\n }\n\n &:hover {\n background: ${(props) => props.theme?.annotationResizeHandleColor || 'rgba(0, 0, 0, 0.1)'};\n }\n\n &:hover::before {\n opacity: 1;\n background: ${(props) => props.theme?.annotationResizeHandleActiveColor || 'rgba(0, 0, 0, 0.7)'};\n }\n`;\n\nexport interface DragHandleProps {\n attributes: DraggableAttributes;\n listeners: SyntheticListenerMap | undefined;\n setActivatorNodeRef: (element: HTMLElement | null) => void;\n isDragging: boolean;\n}\n\nexport interface AnnotationBoxComponentProps {\n annotationId: string;\n annotationIndex: number;\n startPosition: number;\n endPosition: number;\n label?: string;\n color?: string;\n isActive?: boolean;\n onClick?: () => void;\n editable?: boolean; // Whether to show drag handles\n}\n\nexport const AnnotationBox: FunctionComponent<AnnotationBoxComponentProps> = ({\n annotationId,\n annotationIndex,\n startPosition,\n endPosition,\n label,\n color = '#ff9800',\n isActive = false,\n onClick,\n editable = true,\n}) => {\n const width = Math.max(0, endPosition - startPosition);\n\n // Left (start) boundary draggable\n const leftBoundaryId = `annotation-boundary-start-${annotationIndex}`;\n const {\n attributes: leftAttributes,\n listeners: leftListeners,\n setActivatorNodeRef: setLeftActivatorRef,\n isDragging: isLeftDragging,\n } = useDraggable({\n id: leftBoundaryId,\n data: { annotationId, annotationIndex, edge: 'start' as const },\n disabled: !editable,\n });\n\n // Right (end) boundary draggable\n const rightBoundaryId = `annotation-boundary-end-${annotationIndex}`;\n const {\n attributes: rightAttributes,\n listeners: rightListeners,\n setActivatorNodeRef: setRightActivatorRef,\n isDragging: isRightDragging,\n } = useDraggable({\n id: rightBoundaryId,\n data: { annotationId, annotationIndex, edge: 'end' as const },\n disabled: !editable,\n });\n\n if (width <= 0) {\n return null;\n }\n\n // Wrap @dnd-kit pointer handlers to also stop propagation\n // This prevents the ClickOverlay from capturing the event\n const createPointerDownHandler = (dndKitHandler?: (e: React.PointerEvent) => void) => {\n return (e: React.PointerEvent) => {\n e.stopPropagation();\n dndKitHandler?.(e);\n };\n };\n\n const handleHandleClick = (e: React.MouseEvent) => {\n // Prevent clicks on resize handles from bubbling to annotation box\n e.stopPropagation();\n };\n\n return (\n <Wrapper $left={startPosition} $width={width}>\n <Box\n $color={color}\n $isActive={isActive}\n onClick={onClick}\n >\n {label && <Label>{label}</Label>}\n </Box>\n {editable && (\n <ResizeHandle\n ref={setLeftActivatorRef}\n $position=\"left\"\n $isDragging={isLeftDragging}\n onClick={handleHandleClick}\n {...leftListeners}\n onPointerDown={createPointerDownHandler(leftListeners?.onPointerDown as ((e: React.PointerEvent) => void) | undefined)}\n {...leftAttributes}\n />\n )}\n {editable && (\n <ResizeHandle\n ref={setRightActivatorRef}\n $position=\"right\"\n $isDragging={isRightDragging}\n onClick={handleHandleClick}\n {...rightListeners}\n onPointerDown={createPointerDownHandler(rightListeners?.onPointerDown as ((e: React.PointerEvent) => void) | undefined)}\n {...rightAttributes}\n />\n )}\n </Wrapper>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { usePlaylistInfo } from '@waveform-playlist/ui-components';\n\ninterface ContainerProps {\n readonly $height: number;\n readonly $controlWidth: number;\n readonly $width?: number;\n}\n\nconst Container = styled.div.attrs<ContainerProps>((props) => ({\n style: {\n height: `${props.$height}px`,\n },\n}))<ContainerProps>`\n position: relative;\n display: flex;\n ${(props) => props.$width !== undefined && `width: ${props.$width}px;`}\n background: transparent;\n z-index: 110;\n`;\n\nconst ControlsPlaceholder = styled.div<{ $controlWidth: number }>`\n position: sticky;\n z-index: 200;\n left: 0;\n height: 100%;\n width: ${(props) => props.$controlWidth}px;\n flex-shrink: 0;\n background: transparent;\n`;\n\nconst BoxesContainer = styled.div<{ $offset?: number }>`\n position: relative;\n flex: 1;\n padding-left: ${(props) => props.$offset || 0}px;\n`;\n\nexport interface AnnotationBoxesWrapperProps {\n className?: string;\n children?: React.ReactNode;\n height?: number;\n offset?: number;\n width?: number;\n}\n\nexport const AnnotationBoxesWrapper: FunctionComponent<AnnotationBoxesWrapperProps> = ({\n children,\n className,\n height = 30,\n offset = 0,\n width,\n}) => {\n const {\n controls: { show, width: controlWidth },\n } = usePlaylistInfo();\n\n return (\n <Container\n className={className}\n $height={height}\n $controlWidth={show ? controlWidth : 0}\n $width={width}\n >\n <ControlsPlaceholder $controlWidth={show ? controlWidth : 0} />\n <BoxesContainer $offset={offset}>\n {children}\n </BoxesContainer>\n </Container>\n );\n};\n","import React, { FunctionComponent } from 'react';\nimport styled from 'styled-components';\nimport { usePlaylistInfo } from '@waveform-playlist/ui-components';\n\ninterface ContainerProps {\n readonly $height: number;\n readonly $controlWidth: number;\n readonly $width?: number;\n}\n\nconst Container = styled.div.attrs<ContainerProps>((props) => ({\n style: {\n height: `${props.$height}px`,\n },\n}))<ContainerProps>`\n position: relative;\n display: flex;\n ${(props) => props.$width !== undefined && `width: ${props.$width}px;`}\n background: transparent;\n`;\n\nconst ControlsPlaceholder = styled.div<{ $controlWidth: number }>`\n position: sticky;\n z-index: 200;\n left: 0;\n height: 100%;\n width: ${(props) => props.$controlWidth}px;\n flex-shrink: 0;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n color: ${(props) => props.theme?.textColorMuted || '#666'};\n font-weight: bold;\n`;\n\nconst AnnotationsContainer = styled.div<{ $offset?: number }>`\n position: relative;\n flex: 1;\n padding-left: ${(props) => props.$offset || 0}px;\n`;\n\nexport interface AnnotationsTrackProps {\n className?: string;\n children?: React.ReactNode;\n height?: number;\n offset?: number;\n width?: number;\n}\n\nexport const AnnotationsTrack: FunctionComponent<AnnotationsTrackProps> = ({\n children,\n className,\n height = 100,\n offset = 0,\n width,\n}) => {\n const {\n controls: { show, width: controlWidth },\n } = usePlaylistInfo();\n\n return (\n <Container\n className={className}\n $height={height}\n $controlWidth={show ? controlWidth : 0}\n $width={width}\n >\n <ControlsPlaceholder $controlWidth={show ? controlWidth : 0}>\n Annotations\n </ControlsPlaceholder>\n <AnnotationsContainer $offset={offset}>\n {children}\n </AnnotationsContainer>\n </Container>\n );\n};\n","import React, { FunctionComponent, useRef, useEffect } from 'react';\nimport styled from 'styled-components';\nimport type { AnnotationData, AnnotationAction, AnnotationActionOptions, RenderAnnotationItemProps } from '@waveform-playlist/core';\n\ninterface ContainerProps {\n $height?: number;\n}\n\nconst Container = styled.div<ContainerProps>`\n background: ${(props) => props.theme?.backgroundColor || '#fff'};\n ${(props) => props.$height ? `height: ${props.$height}px;` : 'max-height: 200px;'}\n overflow-y: auto;\n padding: 8px;\n`;\n\nconst AnnotationItem = styled.div<{ $isActive?: boolean }>`\n padding: 12px;\n margin-bottom: 6px;\n border-left: 4px solid ${(props) => (props.$isActive ? '#ff9800' : 'transparent')};\n background: ${(props) => (props.$isActive ? 'rgba(255, 152, 0, 0.15)' : 'transparent')};\n border-radius: 4px;\n transition: all 0.2s;\n cursor: pointer;\n box-shadow: ${(props) => (props.$isActive ? '0 2px 8px rgba(255, 152, 0, 0.25), inset 0 0 0 1px rgba(255, 152, 0, 0.3)' : 'none')};\n\n &:hover {\n background: ${(props) => (props.$isActive ? 'rgba(255, 152, 0, 0.2)' : props.theme?.annotationTextItemHoverBackground || 'rgba(0, 0, 0, 0.05)')};\n border-left-color: ${(props) => (props.$isActive ? '#ff9800' : props.theme?.borderColor || '#ddd')};\n }\n\n &:focus-visible {\n outline: 2px solid #ff9800;\n outline-offset: 2px;\n }\n`;\n\nconst AnnotationHeader = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n`;\n\nconst AnnotationInfo = styled.div`\n display: flex;\n align-items: center;\n gap: 8px;\n`;\n\nconst AnnotationIdLabel = styled.span<{ $isEditable?: boolean }>`\n font-size: 11px;\n font-weight: 600;\n color: ${(props) => props.theme?.textColorMuted || '#666'};\n background: transparent;\n padding: 2px 6px;\n border-radius: 3px;\n min-width: 20px;\n outline: ${(props) => (props.$isEditable ? `1px dashed ${props.theme?.borderColor || '#ddd'}` : 'none')};\n\n &[contenteditable='true']:focus {\n outline: 2px solid #ff9800;\n background: rgba(255, 152, 0, 0.1);\n }\n`;\n\nconst TimeRange = styled.span`\n font-size: 12px;\n font-weight: 500;\n color: ${(props) => props.theme?.textColorMuted || '#555'};\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n letter-spacing: 0.5px;\n`;\n\nconst AnnotationControls = styled.div`\n display: flex;\n gap: 6px;\n`;\n\nconst ControlButton = styled.button`\n background: ${(props) => props.theme?.surfaceColor || '#f5f5f5'};\n border: 1px solid ${(props) => props.theme?.borderColor || '#ccc'};\n color: ${(props) => props.theme?.textColor || '#333'};\n padding: 4px 8px;\n font-size: 14px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s ease;\n\n &:hover {\n background: ${(props) => props.theme?.inputBackground || '#3d3d3d'};\n border-color: ${(props) => props.theme?.textColorMuted || '#999'};\n transform: scale(1.05);\n }\n\n &:active {\n transform: scale(0.95);\n }\n`;\n\nconst AnnotationTextContent = styled.div<{ $isEditable?: boolean }>`\n font-size: 14px;\n line-height: 1.6;\n color: ${(props) => props.theme?.textColor || '#2a2a2a'};\n white-space: pre-wrap;\n word-break: break-word;\n outline: ${(props) => (props.$isEditable ? `1px dashed ${props.theme?.borderColor || '#ddd'}` : 'none')};\n padding: ${(props) => (props.$isEditable ? '6px' : '0')};\n border-radius: 3px;\n min-height: 20px;\n\n &[contenteditable='true']:focus {\n outline: 2px solid #ff9800;\n background: rgba(255, 152, 0, 0.1);\n }\n`;\n\n// Re-export from core\nexport type { RenderAnnotationItemProps } from '@waveform-playlist/core';\n\nexport interface AnnotationTextProps {\n annotations: AnnotationData[];\n activeAnnotationId?: string;\n shouldScrollToActive?: boolean;\n /** Where to position the active annotation when scrolling: 'center', 'start', 'end', or 'nearest'. Defaults to 'center'. */\n scrollActivePosition?: ScrollLogicalPosition;\n /** Which scrollable containers to scroll: 'nearest' (only the annotation list) or 'all' (including viewport). Defaults to 'nearest'. */\n scrollActiveContainer?: 'nearest' | 'all';\n editable?: boolean;\n controls?: AnnotationAction[];\n annotationListConfig?: AnnotationActionOptions;\n height?: number;\n onAnnotationClick?: (annotation: AnnotationData) => void;\n onAnnotationUpdate?: (updatedAnnotations: AnnotationData[]) => void;\n /**\n * Custom render function for annotation items.\n * When provided, completely replaces the default annotation item rendering.\n * Use this to customize the appearance of each annotation in the list.\n */\n renderAnnotationItem?: (props: RenderAnnotationItemProps) => React.ReactNode;\n}\n\nconst AnnotationTextComponent: FunctionComponent<AnnotationTextProps> = ({\n annotations,\n activeAnnotationId,\n shouldScrollToActive = false,\n scrollActivePosition = 'center',\n scrollActiveContainer = 'nearest',\n editable = false,\n controls = [],\n annotationListConfig,\n height,\n onAnnotationClick,\n onAnnotationUpdate,\n renderAnnotationItem,\n}) => {\n const activeAnnotationRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const prevActiveIdRef = useRef<string | undefined>(undefined);\n\n // Track component renders and scroll position\n useEffect(() => {\n // Render tracking removed\n });\n\n // Track scroll changes\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handleScroll = () => {\n // Scroll tracking removed\n };\n\n container.addEventListener('scroll', handleScroll);\n return () => container.removeEventListener('scroll', handleScroll);\n }, []);\n\n // Auto-scroll to active annotation when it changes\n useEffect(() => {\n // Only scroll if parent says we should (prevents scrolling on remount after pause)\n if (activeAnnotationId && activeAnnotationRef.current && shouldScrollToActive) {\n activeAnnotationRef.current.scrollIntoView({\n behavior: 'smooth',\n block: scrollActivePosition,\n container: scrollActiveContainer,\n } as ScrollIntoViewOptions);\n }\n\n prevActiveIdRef.current = activeAnnotationId;\n }, [activeAnnotationId, shouldScrollToActive, scrollActivePosition, scrollActiveContainer]);\n\n const formatTime = (seconds: number): string => {\n if (isNaN(seconds) || !isFinite(seconds)) {\n return '0:00.000';\n }\n const mins = Math.floor(seconds / 60);\n const secs = (seconds % 60).toFixed(3);\n return `${mins}:${secs.padStart(6, '0')}`;\n };\n\n const handleTextEdit = (index: number, newText: string) => {\n if (!editable || !onAnnotationUpdate) return;\n\n const updatedAnnotations = [...annotations];\n updatedAnnotations[index] = {\n ...updatedAnnotations[index],\n lines: newText.split('\\n'),\n };\n onAnnotationUpdate(updatedAnnotations);\n };\n\n const handleIdEdit = (index: number, newId: string) => {\n if (!editable || !onAnnotationUpdate) return;\n\n const trimmedId = newId.trim();\n if (!trimmedId) return; // Don't allow empty IDs\n\n const updatedAnnotations = [...annotations];\n updatedAnnotations[index] = {\n ...updatedAnnotations[index],\n id: trimmedId,\n };\n onAnnotationUpdate(updatedAnnotations);\n };\n\n const handleControlClick = (control: AnnotationAction, annotation: AnnotationData, index: number) => {\n if (!onAnnotationUpdate) return;\n\n const annotationsCopy = [...annotations];\n control.action(annotationsCopy[index], index, annotationsCopy, annotationListConfig || {});\n onAnnotationUpdate(annotationsCopy);\n };\n\n const getIconClass = (classString: string) => {\n return classString.replace(/\\./g, ' ');\n };\n\n return (\n <Container ref={containerRef} $height={height}>\n {annotations.map((annotation, index) => {\n const isActive = annotation.id === activeAnnotationId;\n const handleClick = () => onAnnotationClick?.(annotation);\n\n // Use custom render function if provided\n if (renderAnnotationItem) {\n return (\n <div\n key={annotation.id}\n ref={isActive ? activeAnnotationRef : null}\n >\n {renderAnnotationItem({\n annotation,\n index,\n isActive,\n onClick: handleClick,\n formatTime,\n })}\n </div>\n );\n }\n\n // Default rendering\n return (\n <AnnotationItem\n key={annotation.id}\n ref={isActive ? activeAnnotationRef : null}\n $isActive={isActive}\n onClick={handleClick}\n >\n <AnnotationHeader>\n <AnnotationInfo>\n <AnnotationIdLabel\n $isEditable={editable}\n contentEditable={editable}\n suppressContentEditableWarning\n onBlur={(e) => handleIdEdit(index, e.currentTarget.textContent || '')}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n (e.currentTarget as HTMLElement).blur();\n }\n }}\n >\n {annotation.id}\n </AnnotationIdLabel>\n <TimeRange>\n {formatTime(annotation.start)} - {formatTime(annotation.end)}\n </TimeRange>\n </AnnotationInfo>\n {controls.length > 0 && (\n <AnnotationControls onClick={(e) => e.stopPropagation()}>\n {controls.map((control, idx) => (\n <ControlButton\n key={idx}\n title={control.title}\n onClick={() => handleControlClick(control, annotation, index)}\n >\n {control.text ? control.text : <i className={getIconClass(control.class || '')} />}\n </ControlButton>\n ))}\n </AnnotationControls>\n )}\n </AnnotationHeader>\n <AnnotationTextContent\n $isEditable={editable}\n contentEditable={editable}\n suppressContentEditableWarning\n onBlur={(e) => handleTextEdit(index, e.currentTarget.textContent || '')}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n (e.currentTarget as HTMLElement).blur();\n }\n }}\n >\n {annotation.lines.join('\\n')}\n </AnnotationTextContent>\n </AnnotationItem>\n );\n })}\n </Container>\n );\n};\n\n// Memoize to prevent unnecessary remounting when parent re-renders\nexport const AnnotationText = React.memo(AnnotationTextComponent);\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface ContinuousPlayCheckboxProps {\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Checkbox control for enabling/disabling continuous play of annotations.\n * When enabled, playback continues from one annotation to the next without stopping.\n */\nexport const ContinuousPlayCheckbox: React.FC<ContinuousPlayCheckboxProps> = ({\n checked,\n onChange,\n disabled = false,\n className,\n}) => {\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked);\n };\n\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"continuous-play\"\n className=\"continuous-play\"\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n />\n <BaseCheckboxLabel htmlFor=\"continuous-play\">Continuous Play</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface LinkEndpointsCheckboxProps {\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Checkbox control for enabling/disabling linked endpoints between annotations.\n * When enabled, the end time of one annotation is automatically linked to the start time of the next.\n */\nexport const LinkEndpointsCheckbox: React.FC<LinkEndpointsCheckboxProps> = ({\n checked,\n onChange,\n disabled = false,\n className,\n}) => {\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked);\n };\n\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"link-endpoints\"\n className=\"link-endpoints\"\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n />\n <BaseCheckboxLabel htmlFor=\"link-endpoints\">Link Endpoints</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport { BaseCheckboxWrapper, BaseCheckbox, BaseCheckboxLabel } from '@waveform-playlist/ui-components';\n\nexport interface EditableCheckboxProps {\n checked: boolean;\n onChange: (enabled: boolean) => void;\n className?: string;\n}\n\nexport const EditableCheckbox: React.FC<EditableCheckboxProps> = ({\n checked,\n onChange,\n className,\n}) => {\n return (\n <BaseCheckboxWrapper className={className}>\n <BaseCheckbox\n type=\"checkbox\"\n id=\"editable-annotations\"\n checked={checked}\n onChange={(e) => onChange(e.target.checked)}\n />\n <BaseCheckboxLabel htmlFor=\"editable-annotations\">Editable Annotations</BaseCheckboxLabel>\n </BaseCheckboxWrapper>\n );\n};\n","import React from 'react';\nimport styled from 'styled-components';\nimport { serializeAeneas } from '../parsers/aeneas';\nimport type { AnnotationData } from '../types';\n\nconst StyledButton = styled.button`\n padding: 0.5rem 1rem;\n background: ${(props) => props.theme?.surfaceColor || '#f5f5f5'};\n color: ${(props) => props.theme?.textColor || '#333'};\n border: 1px solid ${(props) => props.theme?.borderColor || '#ccc'};\n border-radius: ${(props) => props.theme?.borderRadius || '4px'};\n cursor: pointer;\n font-family: ${(props) => props.theme?.fontFamily || 'inherit'};\n font-size: ${(props) => props.theme?.fontSize || '14px'};\n font-weight: 500;\n transition: all 0.15s ease;\n\n &:hover:not(:disabled) {\n background: ${(props) => props.theme?.inputBackground || '#3d3d3d'};\n border-color: ${(props) => props.theme?.textColorMuted || '#999'};\n }\n\n &:focus {\n outline: none;\n box-shadow: 0 0 0 2px ${(props) => props.theme?.inputFocusBorder || '#007bff'}44;\n }\n\n &:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n`;\n\nexport interface DownloadAnnotationsButtonProps {\n annotations: AnnotationData[];\n filename?: string;\n disabled?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nexport const DownloadAnnotationsButton: React.FC<DownloadAnnotationsButtonProps> = ({\n annotations,\n filename = 'annotations.json',\n disabled = false,\n className,\n children = 'Download JSON',\n}) => {\n const handleDownload = () => {\n if (annotations.length === 0) {\n return;\n }\n\n // Serialize annotations to Aeneas JSON format\n const jsonData = annotations.map(annotation => serializeAeneas(annotation));\n const jsonString = JSON.stringify(jsonData, null, 2);\n\n // Create a blob and download link\n const blob = new Blob([jsonString], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n\n // Trigger download\n document.body.appendChild(link);\n link.click();\n\n // Cleanup\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n };\n\n return (\n <StyledButton\n onClick={handleDownload}\n disabled={disabled || annotations.length === 0}\n className={className}\n title={annotations.length === 0 ? 'No annotations to download' : 'Download the annotations as JSON'}\n >\n {children}\n </StyledButton>\n );\n};\n","import React from 'react';\nimport { AnnotationIntegrationProvider } from '@waveform-playlist/browser';\nimport type { AnnotationIntegration } from '@waveform-playlist/browser';\nimport { parseAeneas, serializeAeneas } from './parsers/aeneas';\nimport { AnnotationText } from './components/AnnotationText';\nimport { AnnotationBox } from './components/AnnotationBox';\nimport { AnnotationBoxesWrapper } from './components/AnnotationBoxesWrapper';\nimport { ContinuousPlayCheckbox } from './components/ContinuousPlayCheckbox';\nimport { LinkEndpointsCheckbox } from './components/LinkEndpointsCheckbox';\nimport { EditableCheckbox } from './components/EditableCheckbox';\nimport { DownloadAnnotationsButton } from './components/DownloadAnnotationsButton';\n\nconst annotationIntegration: AnnotationIntegration = {\n parseAeneas: parseAeneas as (data: unknown) => import('@waveform-playlist/core').AnnotationData,\n serializeAeneas: serializeAeneas as (annotation: import('@waveform-playlist/core').AnnotationData) => unknown,\n AnnotationText,\n AnnotationBox,\n AnnotationBoxesWrapper,\n ContinuousPlayCheckbox,\n LinkEndpointsCheckbox,\n EditableCheckbox,\n DownloadAnnotationsButton,\n};\n\nexport const AnnotationProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n return (\n <AnnotationIntegrationProvider value={annotationIntegration}>\n {children}\n </AnnotationIntegrationProvider>\n );\n};\n","import { useState, useCallback } from 'react';\nimport type { AnnotationData, AnnotationListOptions } from '../types';\n\nconst LINK_THRESHOLD = 0.01; // Consider edges \"linked\" if within 10ms\n\nexport interface UseAnnotationControlsOptions {\n initialContinuousPlay?: boolean;\n initialLinkEndpoints?: boolean;\n}\n\nexport interface AnnotationUpdateParams {\n annotationIndex: number;\n newTime: number;\n isDraggingStart: boolean;\n annotations: AnnotationData[];\n duration: number;\n linkEndpoints: boolean;\n}\n\nexport interface UseAnnotationControlsReturn {\n continuousPlay: boolean;\n linkEndpoints: boolean;\n setContinuousPlay: (value: boolean) => void;\n setLinkEndpoints: (value: boolean) => void;\n updateAnnotationBoundaries: (params: AnnotationUpdateParams) => AnnotationData[];\n}\n\n/**\n * Hook for managing annotation control state and boundary logic.\n * Handles continuous play mode and linked endpoints behavior.\n */\nexport const useAnnotationControls = (\n options: UseAnnotationControlsOptions = {}\n): UseAnnotationControlsReturn => {\n const {\n initialContinuousPlay = false,\n initialLinkEndpoints = true,\n } = options;\n\n const [continuousPlay, setContinuousPlay] = useState(initialContinuousPlay);\n const [linkEndpoints, setLinkEndpoints] = useState(initialLinkEndpoints);\n\n /**\n * Updates annotation boundaries based on drag operations.\n * Handles linked endpoints and collision detection.\n * Note: linkEndpoints is passed as a parameter to ensure it uses the current value from context.\n */\n const updateAnnotationBoundaries = useCallback(\n ({\n annotationIndex,\n newTime,\n isDraggingStart,\n annotations,\n duration,\n linkEndpoints: shouldLinkEndpoints,\n }: AnnotationUpdateParams): AnnotationData[] => {\n const updatedAnnotations = [...annotations];\n const annotation = annotations[annotationIndex];\n\n if (isDraggingStart) {\n // Dragging start edge\n const constrainedStart = Math.min(annotation.end - 0.1, Math.max(0, newTime));\n const delta = constrainedStart - annotation.start;\n\n updatedAnnotations[annotationIndex] = {\n ...annotation,\n start: constrainedStart,\n };\n\n if (shouldLinkEndpoints && annotationIndex > 0) {\n // Link Endpoints mode: handle both already-linked and collision scenarios\n const prevAnnotation = updatedAnnotations[annotationIndex - 1];\n\n if (Math.abs(prevAnnotation.end - annotation.start) < LINK_THRESHOLD) {\n // Already linked: move previous annotation's end together with this start\n updatedAnnotations[annotationIndex - 1] = {\n ...prevAnnotation,\n end: Math.max(prevAnnotation.start + 0.1, prevAnnotation.end + delta),\n };\n } else if (constrainedStart <= prevAnnotation.end) {\n // Dragged past previous annotation: snap to link them together\n updatedAnnotations[annotationIndex] = {\n ...updatedAnnotations[annotationIndex],\n start: prevAnnotation.end,\n };\n }\n } else if (!shouldLinkEndpoints && annotationIndex > 0 && constrainedStart < updatedAnnotations[annotationIndex - 1].end) {\n // Collision detection: push previous annotation's end back\n updatedAnnotations[annotationIndex - 1] = {\n ...updatedAnnotations[annotationIndex - 1],\n end: constrainedStart,\n };\n }\n } else {\n // Dragging end edge\n const constrainedEnd = Math.max(annotation.start + 0.1, Math.min(newTime, duration));\n const delta = constrainedEnd - annotation.end;\n\n updatedAnnotations[annotationIndex] = {\n ...annotation,\n end: constrainedEnd,\n };\n\n if (shouldLinkEndpoints && annotationIndex < updatedAnnotations.length - 1) {\n // Link Endpoints mode: handle both already-linked and collision scenarios\n const nextAnnotation = updatedAnnotations[annotationIndex + 1];\n\n if (Math.abs(nextAnnotation.start - annotation.end) < LINK_THRESHOLD) {\n // Already linked: move next annotation's start together with this end\n const newStart = nextAnnotation.start + delta;\n updatedAnnotations[annotationIndex + 1] = {\n ...nextAnnotation,\n start: Math.min(nextAnnotation.end - 0.1, newStart),\n };\n\n // Cascade linked endpoints\n let currentIndex = annotationIndex + 1;\n while (currentIndex < updatedAnnotations.length - 1) {\n const current = updatedAnnotations[currentIndex];\n const next = updatedAnnotations[currentIndex + 1];\n\n if (Math.abs(next.start - current.end) < LINK_THRESHOLD) {\n const nextDelta = current.end - annotations[currentIndex].end;\n updatedAnnotations[currentIndex + 1] = {\n ...next,\n start: Math.min(next.end - 0.1, next.start + nextDelta),\n };\n currentIndex++;\n } else {\n break; // No more linked endpoints\n }\n }\n } else if (constrainedEnd >= nextAnnotation.start) {\n // Dragged past next annotation: snap to link them together\n updatedAnnotations[annotationIndex] = {\n ...updatedAnnotations[annotationIndex],\n end: nextAnnotation.start,\n };\n }\n } else if (!shouldLinkEndpoints && annotationIndex < updatedAnnotations.length - 1 && constrainedEnd > updatedAnnotations[annotationIndex + 1].start) {\n // Collision detection: push next annotation's start forward\n const nextAnnotation = updatedAnnotations[annotationIndex + 1];\n\n updatedAnnotations[annotationIndex + 1] = {\n ...nextAnnotation,\n start: constrainedEnd,\n };\n\n // Cascade collisions\n let currentIndex = annotationIndex + 1;\n while (currentIndex < updatedAnnotations.length - 1) {\n const current = updatedAnnotations[currentIndex];\n const next = updatedAnnotations[currentIndex + 1];\n\n if (current.end > next.start) {\n updatedAnnotations[currentIndex + 1] = {\n ...next,\n start: current.end,\n };\n currentIndex++;\n } else {\n break; // No more collisions\n }\n }\n }\n }\n\n return updatedAnnotations;\n },\n []\n );\n\n return {\n continuousPlay,\n linkEndpoints,\n setContinuousPlay,\n setLinkEndpoints,\n updateAnnotationBoundaries,\n };\n};\n"],"mappings":"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","names":["styled","jsx","jsxs","styled","jsx","jsxs","styled","usePlaylistInfo","jsx","jsxs","Container","ControlsPlaceholder","React","styled","jsx","jsxs","Container","ControlButton","AnnotationText","jsx","jsxs","BaseCheckboxWrapper","BaseCheckbox","BaseCheckboxLabel","jsx","jsxs","BaseCheckboxWrapper","BaseCheckbox","BaseCheckboxLabel","jsx","jsxs","styled","jsx","styled","jsx","AnnotationText","useState"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waveform-playlist/annotations",
3
- "version": "5.3.2",
3
+ "version": "6.0.1",
4
4
  "description": "Annotation support for waveform-playlist",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -38,17 +38,19 @@
38
38
  "@types/react": "^18.2.45",
39
39
  "@types/styled-components": "^5.1.26",
40
40
  "tsup": "^8.0.1",
41
- "typescript": "^5.3.3"
41
+ "typescript": "^5.3.3",
42
+ "@waveform-playlist/browser": "6.0.1"
42
43
  },
43
44
  "dependencies": {
44
- "@waveform-playlist/ui-components": "5.3.2",
45
- "@waveform-playlist/core": "5.3.2"
45
+ "@waveform-playlist/core": "6.0.1",
46
+ "@waveform-playlist/ui-components": "6.0.1"
46
47
  },
47
48
  "peerDependencies": {
48
49
  "@dnd-kit/core": "^6.0.0",
49
50
  "@dnd-kit/modifiers": "^9.0.0",
50
51
  "react": "^18.0.0",
51
- "styled-components": "^6.0.0"
52
+ "styled-components": "^6.0.0",
53
+ "@waveform-playlist/browser": "6.0.1"
52
54
  },
53
55
  "scripts": {
54
56
  "build": "tsup",