fluxo-ui 0.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.
Files changed (853) hide show
  1. package/README.md +237 -0
  2. package/chunk-Do9eywBl.cjs +35 -0
  3. package/classnames-B4qHndiD.cjs +48 -0
  4. package/classnames-CEAOwX3h.js +66 -0
  5. package/components-C_HbdZhO.js +22556 -0
  6. package/components-DdojqcZ7.cjs +23236 -0
  7. package/dnd.cjs +6 -0
  8. package/dnd.d.ts +1 -0
  9. package/dnd.js +2 -0
  10. package/drag-drop-BF3uukc4.cjs +258 -0
  11. package/drag-drop-UWg0agsw.js +233 -0
  12. package/draw.cjs +3156 -0
  13. package/draw.d.ts +1 -0
  14. package/draw.js +3147 -0
  15. package/favicon.svg +14 -0
  16. package/hooks-BLbZ4aKB.cjs +137 -0
  17. package/hooks-D0CAM9v9.js +107 -0
  18. package/hooks.cjs +7 -0
  19. package/hooks.d.ts +1 -0
  20. package/hooks.js +2 -0
  21. package/icons-BRgMxTPy.js +1641 -0
  22. package/icons-CNooH6LA.cjs +2038 -0
  23. package/icons.cjs +85 -0
  24. package/icons.d.ts +1 -0
  25. package/icons.js +2 -0
  26. package/index.cjs +115 -0
  27. package/index.d.ts +1 -0
  28. package/index.js +2 -0
  29. package/kanban.cjs +969 -0
  30. package/kanban.d.ts +1 -0
  31. package/kanban.js +967 -0
  32. package/logo.svg +26 -0
  33. package/package.json +110 -0
  34. package/services.cjs +331 -0
  35. package/services.d.ts +1 -0
  36. package/services.js +321 -0
  37. package/src/assets/icons.d.ts +86 -0
  38. package/src/components/Autocomplete.d.ts +22 -0
  39. package/src/components/AutocompleteMulti.d.ts +24 -0
  40. package/src/components/Breadcrumb.d.ts +17 -0
  41. package/src/components/Button.d.ts +26 -0
  42. package/src/components/Checkbox.d.ts +12 -0
  43. package/src/components/Chips.d.ts +16 -0
  44. package/src/components/DeferredView.d.ts +13 -0
  45. package/src/components/Dropdown.d.ts +22 -0
  46. package/src/components/Fab.d.ts +23 -0
  47. package/src/components/FieldLabel.d.ts +15 -0
  48. package/src/components/Icon.d.ts +6 -0
  49. package/src/components/InfiniteScroll.d.ts +19 -0
  50. package/src/components/InputGroup.d.ts +7 -0
  51. package/src/components/InputSwitch.d.ts +12 -0
  52. package/src/components/Link.d.ts +5 -0
  53. package/src/components/ListBox.d.ts +38 -0
  54. package/src/components/MaskedInput.d.ts +28 -0
  55. package/src/components/Modal.d.ts +12 -0
  56. package/src/components/MultiStateCheckbox.d.ts +11 -0
  57. package/src/components/Multiselect.d.ts +25 -0
  58. package/src/components/NumericInput.d.ts +16 -0
  59. package/src/components/Password.d.ts +18 -0
  60. package/src/components/Popover.d.ts +20 -0
  61. package/src/components/ProgressBar.d.ts +31 -0
  62. package/src/components/RadioButton.d.ts +20 -0
  63. package/src/components/SelectButton.d.ts +20 -0
  64. package/src/components/SpeedDial.d.ts +40 -0
  65. package/src/components/Stepper.d.ts +41 -0
  66. package/src/components/TextArea.d.ts +19 -0
  67. package/src/components/TextInput.d.ts +19 -0
  68. package/src/components/ToggleButton.d.ts +12 -0
  69. package/src/components/animate-on-view/AnimateOnView.d.ts +23 -0
  70. package/src/components/animate-on-view/index.d.ts +2 -0
  71. package/src/components/calendar/Calendar.d.ts +4 -0
  72. package/src/components/calendar/CalendarContext.d.ts +4 -0
  73. package/src/components/calendar/calendar-constants.d.ts +8 -0
  74. package/src/components/calendar/calendar-types.d.ts +413 -0
  75. package/src/components/calendar/calendar-utils.d.ts +61 -0
  76. package/src/components/calendar/entries/CalendarEntry.d.ts +20 -0
  77. package/src/components/calendar/entries/DefaultEntry.d.ts +8 -0
  78. package/src/components/calendar/entries/EntryContainer.d.ts +19 -0
  79. package/src/components/calendar/entries/OverflowPopover.d.ts +12 -0
  80. package/src/components/calendar/entries/index.d.ts +4 -0
  81. package/src/components/calendar/hooks/index.d.ts +4 -0
  82. package/src/components/calendar/hooks/useCalendarEntries.d.ts +8 -0
  83. package/src/components/calendar/hooks/useCalendarNavigation.d.ts +24 -0
  84. package/src/components/calendar/hooks/useNowIndicator.d.ts +10 -0
  85. package/src/components/calendar/hooks/useViewTitle.d.ts +2 -0
  86. package/src/components/calendar/index.d.ts +9 -0
  87. package/src/components/calendar/interactions/index.d.ts +3 -0
  88. package/src/components/calendar/interactions/useDragMove.d.ts +11 -0
  89. package/src/components/calendar/interactions/useDragResize.d.ts +11 -0
  90. package/src/components/calendar/interactions/useSelection.d.ts +11 -0
  91. package/src/components/calendar/plugin-registry.d.ts +17 -0
  92. package/src/components/calendar/plugins/agenda-plugin.d.ts +6 -0
  93. package/src/components/calendar/plugins/create-plugin.d.ts +20 -0
  94. package/src/components/calendar/plugins/day-grid-plugin.d.ts +2 -0
  95. package/src/components/calendar/plugins/default-plugins.d.ts +2 -0
  96. package/src/components/calendar/plugins/index.d.ts +14 -0
  97. package/src/components/calendar/plugins/list-view-plugin.d.ts +2 -0
  98. package/src/components/calendar/plugins/month-grid-plugin.d.ts +2 -0
  99. package/src/components/calendar/plugins/multi-month-plugin.d.ts +2 -0
  100. package/src/components/calendar/plugins/scroll-month-plugin.d.ts +2 -0
  101. package/src/components/calendar/plugins/time-grid-custom-plugin.d.ts +6 -0
  102. package/src/components/calendar/plugins/time-grid-plugin.d.ts +2 -0
  103. package/src/components/calendar/plugins/year-grid-plugin.d.ts +2 -0
  104. package/src/components/calendar/toolbar/CalendarToolbar.d.ts +27 -0
  105. package/src/components/calendar/toolbar/ToolbarNavigation.d.ts +8 -0
  106. package/src/components/calendar/toolbar/ToolbarTitle.d.ts +6 -0
  107. package/src/components/calendar/toolbar/ToolbarViewSwitcher.d.ts +9 -0
  108. package/src/components/calendar/toolbar/index.d.ts +4 -0
  109. package/src/components/calendar/views/ViewRenderer.d.ts +7 -0
  110. package/src/components/calendar/views/agenda/AgendaView.d.ts +6 -0
  111. package/src/components/calendar/views/agenda/index.d.ts +1 -0
  112. package/src/components/calendar/views/day-grid/DayGrid.d.ts +9 -0
  113. package/src/components/calendar/views/day-grid/DayGridCell.d.ts +15 -0
  114. package/src/components/calendar/views/day-grid/index.d.ts +2 -0
  115. package/src/components/calendar/views/index.d.ts +10 -0
  116. package/src/components/calendar/views/list-view/ListView.d.ts +7 -0
  117. package/src/components/calendar/views/list-view/ListViewGroup.d.ts +11 -0
  118. package/src/components/calendar/views/list-view/ListViewItem.d.ts +10 -0
  119. package/src/components/calendar/views/list-view/index.d.ts +3 -0
  120. package/src/components/calendar/views/month-grid/MonthGrid.d.ts +5 -0
  121. package/src/components/calendar/views/month-grid/MonthGridCell.d.ts +22 -0
  122. package/src/components/calendar/views/month-grid/MonthGridHeader.d.ts +8 -0
  123. package/src/components/calendar/views/month-grid/index.d.ts +3 -0
  124. package/src/components/calendar/views/multi-month/MultiMonthGrid.d.ts +5 -0
  125. package/src/components/calendar/views/multi-month/index.d.ts +1 -0
  126. package/src/components/calendar/views/scroll-month/ScrollMonthView.d.ts +5 -0
  127. package/src/components/calendar/views/scroll-month/index.d.ts +1 -0
  128. package/src/components/calendar/views/time-grid/NowIndicator.d.ts +9 -0
  129. package/src/components/calendar/views/time-grid/TimeGrid.d.ts +9 -0
  130. package/src/components/calendar/views/time-grid/TimeGridAllDay.d.ts +14 -0
  131. package/src/components/calendar/views/time-grid/TimeGridBody.d.ts +21 -0
  132. package/src/components/calendar/views/time-grid/TimeGridColumn.d.ts +22 -0
  133. package/src/components/calendar/views/time-grid/TimeGridHeader.d.ts +9 -0
  134. package/src/components/calendar/views/time-grid/TimeGridSlot.d.ts +12 -0
  135. package/src/components/calendar/views/time-grid/index.d.ts +7 -0
  136. package/src/components/calendar/views/time-grid-custom/TimeGridCustomDays.d.ts +7 -0
  137. package/src/components/calendar/views/time-grid-custom/index.d.ts +1 -0
  138. package/src/components/calendar/views/year-grid/YearGrid.d.ts +5 -0
  139. package/src/components/calendar/views/year-grid/index.d.ts +1 -0
  140. package/src/components/canvas-draw/CanvasDraw.d.ts +18 -0
  141. package/src/components/canvas-draw/CanvasDrawOverlay.d.ts +27 -0
  142. package/src/components/canvas-draw/CanvasDrawToolbar.d.ts +32 -0
  143. package/src/components/canvas-draw/MediaTimeline.d.ts +36 -0
  144. package/src/components/canvas-draw/canvas-draw-types.d.ts +200 -0
  145. package/src/components/canvas-draw/index.d.ts +10 -0
  146. package/src/components/carousel/Carousel.d.ts +35 -0
  147. package/src/components/carousel/CarouselSlide.d.ts +22 -0
  148. package/src/components/carousel/CarouselThumbnails.d.ts +10 -0
  149. package/src/components/carousel/index.d.ts +2 -0
  150. package/src/components/collapsible-panel/CollapsiblePanel.d.ts +45 -0
  151. package/src/components/collapsible-panel/CollapsibleTabs.d.ts +24 -0
  152. package/src/components/collapsible-panel/index.d.ts +4 -0
  153. package/src/components/confirm-popover/ConfirmPopoverManager.d.ts +18 -0
  154. package/src/components/confirm-popover/ConfirmPopoverPanel.d.ts +7 -0
  155. package/src/components/confirm-popover/index.d.ts +3 -0
  156. package/src/components/confirm-popover/types.d.ts +20 -0
  157. package/src/components/confirm-popover/useConfirmPopoverPosition.d.ts +10 -0
  158. package/src/components/context/ThemeContext.d.ts +24 -0
  159. package/src/components/context-menu/ContextMenuManager.d.ts +3 -0
  160. package/src/components/context-menu/index.d.ts +2 -0
  161. package/src/components/context-menu/types.d.ts +28 -0
  162. package/src/components/context-menu/utils.d.ts +3 -0
  163. package/src/components/date-range/Calendar.d.ts +15 -0
  164. package/src/components/date-range/CustomDatePicker.d.ts +2 -0
  165. package/src/components/date-range/DatePopover.d.ts +5 -0
  166. package/src/components/date-range/DateRangePicker.d.ts +3 -0
  167. package/src/components/date-range/Footer.d.ts +2 -0
  168. package/src/components/date-range/MonthPicker.d.ts +10 -0
  169. package/src/components/date-range/QuickRangeDropdown.d.ts +2 -0
  170. package/src/components/date-range/QuickRangeList.d.ts +2 -0
  171. package/src/components/date-range/YearPicker.d.ts +11 -0
  172. package/src/components/date-range/index.d.ts +2 -0
  173. package/src/components/date-range/types.d.ts +65 -0
  174. package/src/components/date-range/utils.d.ts +6 -0
  175. package/src/components/drag-drop/DragDropProvider.d.ts +33 -0
  176. package/src/components/drag-drop/Draggable.d.ts +86 -0
  177. package/src/components/drag-drop/Droppable.d.ts +60 -0
  178. package/src/components/drag-drop/Sortable.d.ts +98 -0
  179. package/src/components/drag-drop/index.d.ts +9 -0
  180. package/src/components/drawer/Drawer.d.ts +19 -0
  181. package/src/components/drawer/index.d.ts +2 -0
  182. package/src/components/file-upload/FilePreview.d.ts +9 -0
  183. package/src/components/file-upload/FileUpload.d.ts +4 -0
  184. package/src/components/file-upload/file-upload-types.d.ts +23 -0
  185. package/src/components/file-upload/index.d.ts +2 -0
  186. package/src/components/gantt-chart/DependencyLines.d.ts +4 -0
  187. package/src/components/gantt-chart/FieldsPanel.d.ts +11 -0
  188. package/src/components/gantt-chart/GanttChart.d.ts +3 -0
  189. package/src/components/gantt-chart/GanttContext.d.ts +4 -0
  190. package/src/components/gantt-chart/Markers.d.ts +4 -0
  191. package/src/components/gantt-chart/TaskBar.d.ts +9 -0
  192. package/src/components/gantt-chart/TimelineGrid.d.ts +4 -0
  193. package/src/components/gantt-chart/TimelineHeader.d.ts +8 -0
  194. package/src/components/gantt-chart/TimelinePanel.d.ts +10 -0
  195. package/src/components/gantt-chart/gantt-types.d.ts +191 -0
  196. package/src/components/gantt-chart/gantt-utils.d.ts +27 -0
  197. package/src/components/gantt-chart/index.d.ts +2 -0
  198. package/src/components/image-editor/ImageEditor.d.ts +5 -0
  199. package/src/components/image-editor/image-editor-types.d.ts +51 -0
  200. package/src/components/image-editor/index.d.ts +2 -0
  201. package/src/components/index.d.ts +75 -0
  202. package/src/components/json-editor/AddEntry.d.ts +10 -0
  203. package/src/components/json-editor/ArrayEditor.d.ts +4 -0
  204. package/src/components/json-editor/ItemNameDisplay.d.ts +4 -0
  205. package/src/components/json-editor/ItemValueDisplay.d.ts +4 -0
  206. package/src/components/json-editor/JsonEditor.d.ts +5 -0
  207. package/src/components/json-editor/NodeSelector.d.ts +6 -0
  208. package/src/components/json-editor/ObjectEditor.d.ts +4 -0
  209. package/src/components/json-editor/SimpleEditor.d.ts +4 -0
  210. package/src/components/json-editor/Toolbar.d.ts +14 -0
  211. package/src/components/json-editor/index.d.ts +2 -0
  212. package/src/components/json-editor/json-editor-types.d.ts +83 -0
  213. package/src/components/json-editor/json-editor-utils.d.ts +11 -0
  214. package/src/components/kanban-board/KanbanBoard.d.ts +3 -0
  215. package/src/components/kanban-board/KanbanCard.d.ts +3 -0
  216. package/src/components/kanban-board/KanbanColumn.d.ts +3 -0
  217. package/src/components/kanban-board/KanbanColumnHeader.d.ts +8 -0
  218. package/src/components/kanban-board/KanbanContext.d.ts +5 -0
  219. package/src/components/kanban-board/index.d.ts +2 -0
  220. package/src/components/kanban-board/kanban-types.d.ts +152 -0
  221. package/src/components/kanban-board/kanban-utils.d.ts +14 -0
  222. package/src/components/lightbox/Lightbox.d.ts +32 -0
  223. package/src/components/lightbox/index.d.ts +2 -0
  224. package/src/components/menu-nav/MenuNav.d.ts +5 -0
  225. package/src/components/menu-nav/MenuNavItem.d.ts +18 -0
  226. package/src/components/menu-nav/index.d.ts +2 -0
  227. package/src/components/menu-nav/menu-nav-types.d.ts +49 -0
  228. package/src/components/notification-center/NotificationCenter.d.ts +3 -0
  229. package/src/components/notification-center/NotificationItemRow.d.ts +10 -0
  230. package/src/components/notification-center/index.d.ts +2 -0
  231. package/src/components/notification-center/notification-center-types.d.ts +32 -0
  232. package/src/components/page-banner/PageBanner.d.ts +23 -0
  233. package/src/components/page-banner/index.d.ts +2 -0
  234. package/src/components/pivot-table/PivotCellEditor.d.ts +14 -0
  235. package/src/components/pivot-table/PivotConfigPanel.d.ts +23 -0
  236. package/src/components/pivot-table/PivotFilterEditor.d.ts +12 -0
  237. package/src/components/pivot-table/PivotTable.d.ts +4 -0
  238. package/src/components/pivot-table/index.d.ts +2 -0
  239. package/src/components/pivot-table/pivot-engine.d.ts +23 -0
  240. package/src/components/pivot-table/pivot-table-types.d.ts +166 -0
  241. package/src/components/shimmer/ShimmerBarChart.d.ts +12 -0
  242. package/src/components/shimmer/ShimmerDiv.d.ts +5 -0
  243. package/src/components/shimmer/ShimmerFeed.d.ts +14 -0
  244. package/src/components/shimmer/ShimmerLegends.d.ts +8 -0
  245. package/src/components/shimmer/ShimmerPieChart.d.ts +10 -0
  246. package/src/components/shimmer/ShimmerTable.d.ts +12 -0
  247. package/src/components/shimmer/SkeletonAvatar.d.ts +8 -0
  248. package/src/components/shimmer/SkeletonButton.d.ts +9 -0
  249. package/src/components/shimmer/SkeletonCard.d.ts +15 -0
  250. package/src/components/shimmer/SkeletonImage.d.ts +10 -0
  251. package/src/components/shimmer/SkeletonText.d.ts +11 -0
  252. package/src/components/shimmer/index.d.ts +10 -0
  253. package/src/components/slider/Slider.d.ts +45 -0
  254. package/src/components/slider/index.d.ts +2 -0
  255. package/src/components/snackbar/Snackbar.d.ts +3 -0
  256. package/src/components/snackbar/SnackbarManager.d.ts +6 -0
  257. package/src/components/snackbar/constants.d.ts +4 -0
  258. package/src/components/snackbar/index.d.ts +1 -0
  259. package/src/components/snackbar/types.d.ts +30 -0
  260. package/src/components/splitter/Splitter.d.ts +20 -0
  261. package/src/components/splitter/index.d.ts +4 -0
  262. package/src/components/tab-view/TabHeader.d.ts +19 -0
  263. package/src/components/tab-view/TabNav.d.ts +15 -0
  264. package/src/components/tab-view/TabPage.d.ts +13 -0
  265. package/src/components/tab-view/TabView.d.ts +28 -0
  266. package/src/components/tab-view/index.d.ts +4 -0
  267. package/src/components/tab-view/tabview-utils.d.ts +5 -0
  268. package/src/components/table/Table.d.ts +35 -0
  269. package/src/components/table/TableBody.d.ts +13 -0
  270. package/src/components/table/TableFooter.d.ts +12 -0
  271. package/src/components/table/TableHeader.d.ts +9 -0
  272. package/src/components/table/table-types.d.ts +16 -0
  273. package/src/components/table/useSortedData.d.ts +2 -0
  274. package/src/components/timeline/Timeline.d.ts +27 -0
  275. package/src/components/timeline/TimelineItem.d.ts +11 -0
  276. package/src/components/timeline/index.d.ts +2 -0
  277. package/src/components/tooltip/Tooltip.d.ts +17 -0
  278. package/src/components/tooltip/TooltipManager.d.ts +3 -0
  279. package/src/components/tooltip/utils.d.ts +6 -0
  280. package/src/components/tour/StepTour.d.ts +18 -0
  281. package/src/components/tour/TourTooltip.d.ts +18 -0
  282. package/src/components/tour/types.d.ts +12 -0
  283. package/src/components/tour/useWindowResize.d.ts +4 -0
  284. package/src/components/tour/utils.d.ts +10 -0
  285. package/src/components/tree-view/TreeNodeComponent.d.ts +4 -0
  286. package/src/components/tree-view/TreeView.d.ts +4 -0
  287. package/src/components/tree-view/index.d.ts +2 -0
  288. package/src/components/tree-view/tree-view-types.d.ts +55 -0
  289. package/src/hooks/index.d.ts +5 -0
  290. package/src/hooks/useClickOutside.d.ts +1 -0
  291. package/src/hooks/useDebounce.d.ts +1 -0
  292. package/src/hooks/useKeyboard.d.ts +1 -0
  293. package/src/hooks/useMobile.d.ts +1 -0
  294. package/src/hooks/usePosition.d.ts +8 -0
  295. package/src/plugins/vite/index.d.ts +8 -0
  296. package/src/services/container.d.ts +29 -0
  297. package/src/services/index.d.ts +3 -0
  298. package/src/services/react.d.ts +23 -0
  299. package/src/services/types.d.ts +36 -0
  300. package/src/store/core/model.d.ts +2 -0
  301. package/src/store/core/state.d.ts +2 -0
  302. package/src/store/factory/react-hooks.d.ts +19 -0
  303. package/src/store/index.d.ts +4 -0
  304. package/src/store/middlewares/broadcast.d.ts +6 -0
  305. package/src/store/middlewares/debounce.d.ts +2 -0
  306. package/src/store/middlewares/devtools.d.ts +4 -0
  307. package/src/store/middlewares/immer.d.ts +2 -0
  308. package/src/store/middlewares/index.d.ts +11 -0
  309. package/src/store/middlewares/logging.d.ts +2 -0
  310. package/src/store/middlewares/persist.d.ts +2 -0
  311. package/src/store/middlewares/throttle.d.ts +2 -0
  312. package/src/store/middlewares/undo-redo.d.ts +13 -0
  313. package/src/store/middlewares/validation.d.ts +2 -0
  314. package/src/store/types.d.ts +99 -0
  315. package/src/story/CodeBlock.d.ts +9 -0
  316. package/src/story/ComponentDemo.d.ts +10 -0
  317. package/src/story/FeatureCard.d.ts +16 -0
  318. package/src/story/IconShowcase.d.ts +6 -0
  319. package/src/story/Layout.d.ts +6 -0
  320. package/src/story/Navigation.d.ts +6 -0
  321. package/src/story/PageLayout.d.ts +8 -0
  322. package/src/story/PropsTable.d.ts +13 -0
  323. package/src/story/SectionNav.d.ts +11 -0
  324. package/src/story/StoryThemeContext.d.ts +16 -0
  325. package/src/story/pages/HomePage.d.ts +3 -0
  326. package/src/story/pages/IconsPage.d.ts +2 -0
  327. package/src/story/pages/InstallationPage.d.ts +3 -0
  328. package/src/story/pages/animate-on-view/AllAnimations.d.ts +3 -0
  329. package/src/story/pages/animate-on-view/AnimateOnViewPage.d.ts +3 -0
  330. package/src/story/pages/animate-on-view/BasicUsage.d.ts +3 -0
  331. package/src/story/pages/animate-on-view/ConfigOptions.d.ts +3 -0
  332. package/src/story/pages/animate-on-view/ScrollDemo.d.ts +3 -0
  333. package/src/story/pages/animate-on-view/StaggeredAnimations.d.ts +3 -0
  334. package/src/story/pages/autocomplete/AutocompletePage.d.ts +3 -0
  335. package/src/story/pages/autocomplete/BasicUsage.d.ts +3 -0
  336. package/src/story/pages/autocomplete/CustomConfiguration.d.ts +3 -0
  337. package/src/story/pages/autocomplete/DisabledState.d.ts +3 -0
  338. package/src/story/pages/autocomplete/UsageExamples.d.ts +3 -0
  339. package/src/story/pages/autocomplete/autocomplete-story-data.d.ts +6 -0
  340. package/src/story/pages/autocomplete-multi/AutocompleteMultiPage.d.ts +3 -0
  341. package/src/story/pages/autocomplete-multi/BasicUsage.d.ts +3 -0
  342. package/src/story/pages/autocomplete-multi/DisabledState.d.ts +3 -0
  343. package/src/story/pages/autocomplete-multi/LimitedSelections.d.ts +3 -0
  344. package/src/story/pages/autocomplete-multi/PresetValues.d.ts +3 -0
  345. package/src/story/pages/autocomplete-multi/UsageExamples.d.ts +3 -0
  346. package/src/story/pages/autocomplete-multi/autocomplete-multi-story-data.d.ts +6 -0
  347. package/src/story/pages/breadcrumb/BasicUsage.d.ts +3 -0
  348. package/src/story/pages/breadcrumb/BreadcrumbPage.d.ts +3 -0
  349. package/src/story/pages/breadcrumb/CollapsedItems.d.ts +3 -0
  350. package/src/story/pages/breadcrumb/CustomSeparator.d.ts +3 -0
  351. package/src/story/pages/button/AsLink.d.ts +3 -0
  352. package/src/story/pages/button/AsyncAction.d.ts +3 -0
  353. package/src/story/pages/button/BasicUsage.d.ts +3 -0
  354. package/src/story/pages/button/ButtonPage.d.ts +3 -0
  355. package/src/story/pages/button/Combinations.d.ts +3 -0
  356. package/src/story/pages/button/CountdownTimer.d.ts +3 -0
  357. package/src/story/pages/button/FullWidth.d.ts +3 -0
  358. package/src/story/pages/button/Layouts.d.ts +3 -0
  359. package/src/story/pages/button/Sizes.d.ts +3 -0
  360. package/src/story/pages/button/States.d.ts +3 -0
  361. package/src/story/pages/button/Variants.d.ts +3 -0
  362. package/src/story/pages/button/WithIcons.d.ts +3 -0
  363. package/src/story/pages/calendar/BasicUsage.d.ts +3 -0
  364. package/src/story/pages/calendar/CalendarPage.d.ts +3 -0
  365. package/src/story/pages/calendar/CompactMode.d.ts +3 -0
  366. package/src/story/pages/calendar/CustomRendering.d.ts +3 -0
  367. package/src/story/pages/calendar/CustomToolbarEnd.d.ts +3 -0
  368. package/src/story/pages/calendar/DateBackgrounds.d.ts +3 -0
  369. package/src/story/pages/calendar/DragDropResize.d.ts +3 -0
  370. package/src/story/pages/calendar/ExternalDragDrop.d.ts +3 -0
  371. package/src/story/pages/calendar/ImperativeApi.d.ts +3 -0
  372. package/src/story/pages/calendar/NavigationPickerDemo.d.ts +3 -0
  373. package/src/story/pages/calendar/PluginSystem.d.ts +3 -0
  374. package/src/story/pages/calendar/PluginViews.d.ts +3 -0
  375. package/src/story/pages/calendar/TimeGridConfig.d.ts +3 -0
  376. package/src/story/pages/calendar/ViewModes.d.ts +3 -0
  377. package/src/story/pages/calendar/calendar-story-data.d.ts +18 -0
  378. package/src/story/pages/calendar-playground/CalendarPlaygroundPage.d.ts +3 -0
  379. package/src/story/pages/calendar-playground/PlaygroundSettings.d.ts +65 -0
  380. package/src/story/pages/canvas-draw/CanvasDrawPage.d.ts +3 -0
  381. package/src/story/pages/canvas-draw/ControlledMode.d.ts +3 -0
  382. package/src/story/pages/canvas-draw/DrawingCanvas.d.ts +3 -0
  383. package/src/story/pages/canvas-draw/ExportDemo.d.ts +3 -0
  384. package/src/story/pages/canvas-draw/FeatureFlags.d.ts +3 -0
  385. package/src/story/pages/canvas-draw/ImageAnnotation.d.ts +3 -0
  386. package/src/story/pages/canvas-draw/MediaTimelineDemo.d.ts +3 -0
  387. package/src/story/pages/canvas-draw/ReadOnlyMode.d.ts +3 -0
  388. package/src/story/pages/canvas-draw/TimedAnnotations.d.ts +3 -0
  389. package/src/story/pages/canvas-draw/ToolSubset.d.ts +3 -0
  390. package/src/story/pages/canvas-draw/ToolbarPlacement.d.ts +3 -0
  391. package/src/story/pages/canvas-draw/canvas-draw-story-data.d.ts +7 -0
  392. package/src/story/pages/carousel/Autoplay.d.ts +3 -0
  393. package/src/story/pages/carousel/BasicUsage.d.ts +3 -0
  394. package/src/story/pages/carousel/CarouselPage.d.ts +3 -0
  395. package/src/story/pages/carousel/ThumbnailNav.d.ts +3 -0
  396. package/src/story/pages/checkbox/BasicUsage.d.ts +3 -0
  397. package/src/story/pages/checkbox/CheckboxGroup.d.ts +3 -0
  398. package/src/story/pages/checkbox/CheckboxPage.d.ts +3 -0
  399. package/src/story/pages/checkbox/IndeterminateState.d.ts +3 -0
  400. package/src/story/pages/checkbox/States.d.ts +3 -0
  401. package/src/story/pages/chips/BasicUsage.d.ts +3 -0
  402. package/src/story/pages/chips/ChipsPage.d.ts +3 -0
  403. package/src/story/pages/chips/LimitedChips.d.ts +3 -0
  404. package/src/story/pages/chips/States.d.ts +3 -0
  405. package/src/story/pages/chips/chips-story-data.d.ts +2 -0
  406. package/src/story/pages/collapsible-panel/AccordionGroup.d.ts +3 -0
  407. package/src/story/pages/collapsible-panel/BasicUsage.d.ts +3 -0
  408. package/src/story/pages/collapsible-panel/CollapsiblePanelPage.d.ts +3 -0
  409. package/src/story/pages/collapsible-panel/Controlled.d.ts +3 -0
  410. package/src/story/pages/collapsible-panel/CustomHeaderTemplate.d.ts +3 -0
  411. package/src/story/pages/collapsible-panel/DisabledState.d.ts +3 -0
  412. package/src/story/pages/collapsible-panel/HeaderActions.d.ts +3 -0
  413. package/src/story/pages/collapsible-panel/HorizontalTabs.d.ts +3 -0
  414. package/src/story/pages/collapsible-panel/HorizontalTabsVariants.d.ts +3 -0
  415. package/src/story/pages/collapsible-panel/IconPositions.d.ts +3 -0
  416. package/src/story/pages/collapsible-panel/MultiOpenGroup.d.ts +3 -0
  417. package/src/story/pages/collapsible-panel/Sizes.d.ts +3 -0
  418. package/src/story/pages/collapsible-panel/Variants.d.ts +3 -0
  419. package/src/story/pages/collapsible-panel/WithIcons.d.ts +3 -0
  420. package/src/story/pages/confirm-popover/ConfirmCustomDemo.d.ts +3 -0
  421. package/src/story/pages/confirm-popover/ConfirmPopoverPage.d.ts +3 -0
  422. package/src/story/pages/confirm-popover/CustomActionsDemo.d.ts +3 -0
  423. package/src/story/pages/confirm-popover/InfoOkDemo.d.ts +3 -0
  424. package/src/story/pages/confirm-popover/RichJsxDemo.d.ts +3 -0
  425. package/src/story/pages/confirm-popover/SetupSection.d.ts +3 -0
  426. package/src/story/pages/confirm-popover/YesNoDemo.d.ts +3 -0
  427. package/src/story/pages/context-menu/ButtonTriggered.d.ts +3 -0
  428. package/src/story/pages/context-menu/ContextMenuPage.d.ts +3 -0
  429. package/src/story/pages/context-menu/NestedSubmenus.d.ts +3 -0
  430. package/src/story/pages/context-menu/RightClickMenu.d.ts +3 -0
  431. package/src/story/pages/context-menu/ScrollableMenu.d.ts +3 -0
  432. package/src/story/pages/context-menu/SetupSection.d.ts +3 -0
  433. package/src/story/pages/context-menu/TableRowMenu.d.ts +3 -0
  434. package/src/story/pages/context-menu/context-menu-story-data.d.ts +52 -0
  435. package/src/story/pages/date-range-picker/BasicUsage.d.ts +3 -0
  436. package/src/story/pages/date-range-picker/Constraints.d.ts +3 -0
  437. package/src/story/pages/date-range-picker/CustomFormat.d.ts +3 -0
  438. package/src/story/pages/date-range-picker/DateRangePickerPage.d.ts +3 -0
  439. package/src/story/pages/date-range-picker/DisabledState.d.ts +3 -0
  440. package/src/story/pages/date-range-picker/FirstDayOfWeek.d.ts +3 -0
  441. package/src/story/pages/date-range-picker/PositionDemo.d.ts +3 -0
  442. package/src/story/pages/date-range-picker/PresetDates.d.ts +3 -0
  443. package/src/story/pages/date-range-picker/QuickSelect.d.ts +3 -0
  444. package/src/story/pages/date-range-picker/SelectionModes.d.ts +3 -0
  445. package/src/story/pages/date-range-picker/SingleDatePicker.d.ts +3 -0
  446. package/src/story/pages/date-range-picker/TodayButton.d.ts +3 -0
  447. package/src/story/pages/date-range-picker/date-range-picker-story-data.d.ts +8 -0
  448. package/src/story/pages/deferred-view/BasicUsageDemo.d.ts +3 -0
  449. package/src/story/pages/deferred-view/DeferredViewPage.d.ts +3 -0
  450. package/src/story/pages/deferred-view/KeepMountedDemo.d.ts +3 -0
  451. package/src/story/pages/deferred-view/LazyImageDemo.d.ts +3 -0
  452. package/src/story/pages/deferred-view/PlaceholderDemo.d.ts +3 -0
  453. package/src/story/pages/deferred-view/RootMarginDemo.d.ts +3 -0
  454. package/src/story/pages/demo-showcase/DemoShowcasePage.d.ts +3 -0
  455. package/src/story/pages/demo-showcase/FormSection.d.ts +8 -0
  456. package/src/story/pages/demo-showcase/TableSection.d.ts +6 -0
  457. package/src/story/pages/demo-showcase/TabsAndProgressSection.d.ts +6 -0
  458. package/src/story/pages/drag-drop/BasicDragDrop.d.ts +3 -0
  459. package/src/story/pages/drag-drop/DragDropPage.d.ts +3 -0
  460. package/src/story/pages/drag-drop/MultiContainer.d.ts +3 -0
  461. package/src/story/pages/drag-drop/RenderProps.d.ts +3 -0
  462. package/src/story/pages/drag-drop/SetupSection.d.ts +3 -0
  463. package/src/story/pages/drag-drop/TypeBasedDragDrop.d.ts +3 -0
  464. package/src/story/pages/drag-drop/drag-drop-story-data.d.ts +6 -0
  465. package/src/story/pages/drawer/BasicUsage.d.ts +3 -0
  466. package/src/story/pages/drawer/CustomContent.d.ts +3 -0
  467. package/src/story/pages/drawer/DrawerPage.d.ts +3 -0
  468. package/src/story/pages/drawer/Positions.d.ts +3 -0
  469. package/src/story/pages/dropdown/BasicUsage.d.ts +3 -0
  470. package/src/story/pages/dropdown/ClearableDropdown.d.ts +3 -0
  471. package/src/story/pages/dropdown/CustomFieldMapping.d.ts +3 -0
  472. package/src/story/pages/dropdown/DropdownPage.d.ts +3 -0
  473. package/src/story/pages/dropdown/DropdownStates.d.ts +3 -0
  474. package/src/story/pages/dropdown/GroupedOptions.d.ts +3 -0
  475. package/src/story/pages/dropdown/SearchableDropdown.d.ts +3 -0
  476. package/src/story/pages/dropdown/dropdown-story-data.d.ts +33 -0
  477. package/src/story/pages/fab-speed-dial/FabBasic.d.ts +3 -0
  478. package/src/story/pages/fab-speed-dial/FabExtended.d.ts +3 -0
  479. package/src/story/pages/fab-speed-dial/FabSizes.d.ts +3 -0
  480. package/src/story/pages/fab-speed-dial/FabSpeedDialPage.d.ts +3 -0
  481. package/src/story/pages/fab-speed-dial/SpeedDialBasic.d.ts +3 -0
  482. package/src/story/pages/fab-speed-dial/SpeedDialClick.d.ts +3 -0
  483. package/src/story/pages/fab-speed-dial/SpeedDialDirections.d.ts +3 -0
  484. package/src/story/pages/fab-speed-dial/SpeedDialSizes.d.ts +3 -0
  485. package/src/story/pages/fab-speed-dial/SpeedDialVariants.d.ts +3 -0
  486. package/src/story/pages/fab-speed-dial/fab-story-icons.d.ts +11 -0
  487. package/src/story/pages/field-label/BasicLabel.d.ts +3 -0
  488. package/src/story/pages/field-label/CombinedStates.d.ts +3 -0
  489. package/src/story/pages/field-label/DisabledState.d.ts +3 -0
  490. package/src/story/pages/field-label/ErrorState.d.ts +3 -0
  491. package/src/story/pages/field-label/FieldLabelPage.d.ts +3 -0
  492. package/src/story/pages/field-label/OptionalField.d.ts +3 -0
  493. package/src/story/pages/field-label/RequiredField.d.ts +3 -0
  494. package/src/story/pages/file-upload/BasicUsage.d.ts +3 -0
  495. package/src/story/pages/file-upload/FileUploadPage.d.ts +3 -0
  496. package/src/story/pages/file-upload/ImagePreview.d.ts +3 -0
  497. package/src/story/pages/file-upload/Validation.d.ts +3 -0
  498. package/src/story/pages/gantt-chart/BasicUsage.d.ts +3 -0
  499. package/src/story/pages/gantt-chart/CustomColumns.d.ts +3 -0
  500. package/src/story/pages/gantt-chart/DateMarkers.d.ts +3 -0
  501. package/src/story/pages/gantt-chart/Dependencies.d.ts +3 -0
  502. package/src/story/pages/gantt-chart/DragAndDrop.d.ts +3 -0
  503. package/src/story/pages/gantt-chart/GanttChartPage.d.ts +3 -0
  504. package/src/story/pages/gantt-chart/HierarchicalTasks.d.ts +3 -0
  505. package/src/story/pages/gantt-chart/QuarterlyView.d.ts +3 -0
  506. package/src/story/pages/gantt-chart/ReadOnly.d.ts +3 -0
  507. package/src/story/pages/gantt-chart/SprintPlanning.d.ts +3 -0
  508. package/src/story/pages/gantt-chart/TaskCreation.d.ts +3 -0
  509. package/src/story/pages/gantt-chart/TimelineOnly.d.ts +3 -0
  510. package/src/story/pages/gantt-chart/ViewModes.d.ts +3 -0
  511. package/src/story/pages/gantt-chart/gantt-chart-story-data.d.ts +10 -0
  512. package/src/story/pages/hooks-utils/HooksUtilsPage.d.ts +3 -0
  513. package/src/story/pages/hooks-utils/UseClickOutsideDemo.d.ts +3 -0
  514. package/src/story/pages/hooks-utils/UseDebounceDemo.d.ts +3 -0
  515. package/src/story/pages/hooks-utils/UseKeyboardDemo.d.ts +3 -0
  516. package/src/story/pages/hooks-utils/UseMobileDemo.d.ts +3 -0
  517. package/src/story/pages/hooks-utils/UtilFunctionsDemo.d.ts +3 -0
  518. package/src/story/pages/hooks-utils/WithFieldLabelDemo.d.ts +3 -0
  519. package/src/story/pages/image-editor/BasicUsage.d.ts +3 -0
  520. package/src/story/pages/image-editor/CropOnly.d.ts +3 -0
  521. package/src/story/pages/image-editor/CustomTools.d.ts +3 -0
  522. package/src/story/pages/image-editor/ExportOptions.d.ts +3 -0
  523. package/src/story/pages/image-editor/ImageEditorPage.d.ts +3 -0
  524. package/src/story/pages/infinite-scroll/BasicUsage.d.ts +3 -0
  525. package/src/story/pages/infinite-scroll/ErrorHandling.d.ts +3 -0
  526. package/src/story/pages/infinite-scroll/InfiniteScrollPage.d.ts +3 -0
  527. package/src/story/pages/input-group/EmailInput.d.ts +3 -0
  528. package/src/story/pages/input-group/FileUpload.d.ts +3 -0
  529. package/src/story/pages/input-group/InputGroupPage.d.ts +3 -0
  530. package/src/story/pages/input-group/PhoneNumber.d.ts +3 -0
  531. package/src/story/pages/input-group/PriceInput.d.ts +3 -0
  532. package/src/story/pages/input-group/SearchInput.d.ts +3 -0
  533. package/src/story/pages/input-group/UrlInput.d.ts +3 -0
  534. package/src/story/pages/input-switch/BasicUsage.d.ts +3 -0
  535. package/src/story/pages/input-switch/CustomLabels.d.ts +3 -0
  536. package/src/story/pages/input-switch/DisabledStates.d.ts +3 -0
  537. package/src/story/pages/input-switch/FormIntegration.d.ts +3 -0
  538. package/src/story/pages/input-switch/InputSwitchPage.d.ts +3 -0
  539. package/src/story/pages/input-switch/SettingsPanel.d.ts +3 -0
  540. package/src/story/pages/json-editor/ArrayEditing.d.ts +3 -0
  541. package/src/story/pages/json-editor/BasicUsage.d.ts +3 -0
  542. package/src/story/pages/json-editor/ComplexData.d.ts +3 -0
  543. package/src/story/pages/json-editor/JsonEditorPage.d.ts +3 -0
  544. package/src/story/pages/json-editor/NestedObjects.d.ts +3 -0
  545. package/src/story/pages/json-editor/PermissionControls.d.ts +3 -0
  546. package/src/story/pages/json-editor/ReadOnlyMode.d.ts +3 -0
  547. package/src/story/pages/json-editor/SizeVariants.d.ts +3 -0
  548. package/src/story/pages/json-editor/SortedKeys.d.ts +3 -0
  549. package/src/story/pages/json-editor/TypeShowcase.d.ts +3 -0
  550. package/src/story/pages/json-editor/json-editor-story-data.d.ts +8 -0
  551. package/src/story/pages/kanban-board/BasicUsage.d.ts +3 -0
  552. package/src/story/pages/kanban-board/BlockedCards.d.ts +3 -0
  553. package/src/story/pages/kanban-board/CardActions.d.ts +3 -0
  554. package/src/story/pages/kanban-board/CollapsibleColumns.d.ts +3 -0
  555. package/src/story/pages/kanban-board/ColumnLimits.d.ts +3 -0
  556. package/src/story/pages/kanban-board/CompactMode.d.ts +3 -0
  557. package/src/story/pages/kanban-board/CustomColumnHeader.d.ts +3 -0
  558. package/src/story/pages/kanban-board/CustomTemplates.d.ts +3 -0
  559. package/src/story/pages/kanban-board/DetailedCards.d.ts +3 -0
  560. package/src/story/pages/kanban-board/InteractiveBoard.d.ts +3 -0
  561. package/src/story/pages/kanban-board/KanbanBoardPage.d.ts +3 -0
  562. package/src/story/pages/kanban-board/LockedColumns.d.ts +3 -0
  563. package/src/story/pages/kanban-board/StickyHeaders.d.ts +3 -0
  564. package/src/story/pages/kanban-board/VerticalLayout.d.ts +3 -0
  565. package/src/story/pages/kanban-board/kanban-story-data.d.ts +19 -0
  566. package/src/story/pages/lightbox/BasicUsage.d.ts +3 -0
  567. package/src/story/pages/lightbox/LightboxPage.d.ts +3 -0
  568. package/src/story/pages/list-box/DisabledState.d.ts +3 -0
  569. package/src/story/pages/list-box/GroupedList.d.ts +3 -0
  570. package/src/story/pages/list-box/ListBoxPage.d.ts +3 -0
  571. package/src/story/pages/list-box/MultipleSelection.d.ts +3 -0
  572. package/src/story/pages/list-box/SearchableList.d.ts +3 -0
  573. package/src/story/pages/list-box/SingleSelection.d.ts +3 -0
  574. package/src/story/pages/list-box/list-box-story-data.d.ts +4 -0
  575. package/src/story/pages/masked-input/CustomSlotChar.d.ts +3 -0
  576. package/src/story/pages/masked-input/IncludeLiterals.d.ts +3 -0
  577. package/src/story/pages/masked-input/InputStates.d.ts +3 -0
  578. package/src/story/pages/masked-input/KeyboardNavigation.d.ts +3 -0
  579. package/src/story/pages/masked-input/MaskExamples.d.ts +8 -0
  580. package/src/story/pages/masked-input/MaskSyntax.d.ts +3 -0
  581. package/src/story/pages/masked-input/MaskedInputPage.d.ts +3 -0
  582. package/src/story/pages/masked-input/PrefilledValue.d.ts +3 -0
  583. package/src/story/pages/menu-nav/BasicUsage.d.ts +3 -0
  584. package/src/story/pages/menu-nav/Collapsible.d.ts +3 -0
  585. package/src/story/pages/menu-nav/CustomSlots.d.ts +3 -0
  586. package/src/story/pages/menu-nav/GroupedMenus.d.ts +3 -0
  587. package/src/story/pages/menu-nav/Horizontal.d.ts +3 -0
  588. package/src/story/pages/menu-nav/MenuNavPage.d.ts +3 -0
  589. package/src/story/pages/menu-nav/NestedMenus.d.ts +3 -0
  590. package/src/story/pages/menu-nav/SelectionStyles.d.ts +3 -0
  591. package/src/story/pages/menu-nav/Sizes.d.ts +3 -0
  592. package/src/story/pages/menu-nav/ToolbarMode.d.ts +3 -0
  593. package/src/story/pages/menu-nav/menu-nav-story-data.d.ts +7 -0
  594. package/src/story/pages/modal/BasicUsage.d.ts +3 -0
  595. package/src/story/pages/modal/CustomLayout.d.ts +3 -0
  596. package/src/story/pages/modal/FormExample.d.ts +3 -0
  597. package/src/story/pages/modal/ModalPage.d.ts +3 -0
  598. package/src/story/pages/modal/NestedModals.d.ts +3 -0
  599. package/src/story/pages/modal/NonClosable.d.ts +3 -0
  600. package/src/story/pages/modal/ScrollableContent.d.ts +3 -0
  601. package/src/story/pages/modal/Sizes.d.ts +3 -0
  602. package/src/story/pages/modal/WithoutTitle.d.ts +3 -0
  603. package/src/story/pages/multi-state-checkbox/BasicUsage.d.ts +3 -0
  604. package/src/story/pages/multi-state-checkbox/ControlledState.d.ts +3 -0
  605. package/src/story/pages/multi-state-checkbox/CustomStates.d.ts +3 -0
  606. package/src/story/pages/multi-state-checkbox/MultiStateCheckboxPage.d.ts +3 -0
  607. package/src/story/pages/multi-state-checkbox/multi-state-checkbox-story-data.d.ts +4 -0
  608. package/src/story/pages/multiselect/BasicUsage.d.ts +3 -0
  609. package/src/story/pages/multiselect/CustomFieldMapping.d.ts +3 -0
  610. package/src/story/pages/multiselect/GroupedOptions.d.ts +3 -0
  611. package/src/story/pages/multiselect/MultiselectPage.d.ts +3 -0
  612. package/src/story/pages/multiselect/MultiselectStates.d.ts +3 -0
  613. package/src/story/pages/multiselect/SelectAll.d.ts +3 -0
  614. package/src/story/pages/multiselect/SelectionLimit.d.ts +3 -0
  615. package/src/story/pages/multiselect/WithoutSearch.d.ts +3 -0
  616. package/src/story/pages/multiselect/multiselect-story-data.d.ts +28 -0
  617. package/src/story/pages/notification-center/BasicUsage.d.ts +3 -0
  618. package/src/story/pages/notification-center/Categories.d.ts +3 -0
  619. package/src/story/pages/notification-center/CustomTrigger.d.ts +3 -0
  620. package/src/story/pages/notification-center/NotificationCenterPage.d.ts +3 -0
  621. package/src/story/pages/numeric-input/BasicUsage.d.ts +3 -0
  622. package/src/story/pages/numeric-input/DecimalPrecision.d.ts +3 -0
  623. package/src/story/pages/numeric-input/MinMaxRange.d.ts +3 -0
  624. package/src/story/pages/numeric-input/NumericInputPage.d.ts +3 -0
  625. package/src/story/pages/numeric-input/NumericInputStates.d.ts +3 -0
  626. package/src/story/pages/page-banner/BasicUsage.d.ts +3 -0
  627. package/src/story/pages/page-banner/CustomContent.d.ts +3 -0
  628. package/src/story/pages/page-banner/Dismissible.d.ts +3 -0
  629. package/src/story/pages/page-banner/PageBannerPage.d.ts +3 -0
  630. package/src/story/pages/page-banner/PageLevel.d.ts +3 -0
  631. package/src/story/pages/page-banner/WithActions.d.ts +3 -0
  632. package/src/story/pages/password/BasicUsage.d.ts +3 -0
  633. package/src/story/pages/password/PasswordPage.d.ts +3 -0
  634. package/src/story/pages/password/PasswordStates.d.ts +3 -0
  635. package/src/story/pages/pivot-table/BasicUsage.d.ts +3 -0
  636. package/src/story/pages/pivot-table/ColumnPivot.d.ts +3 -0
  637. package/src/story/pages/pivot-table/Filtering.d.ts +3 -0
  638. package/src/story/pages/pivot-table/InteractiveDemo.d.ts +3 -0
  639. package/src/story/pages/pivot-table/MultiLevelPivot.d.ts +3 -0
  640. package/src/story/pages/pivot-table/MultipleFunctions.d.ts +3 -0
  641. package/src/story/pages/pivot-table/PivotTablePage.d.ts +3 -0
  642. package/src/story/pages/pivot-table/pivot-table-story-data.d.ts +17 -0
  643. package/src/story/pages/pivot-table-playground/PivotTablePlaygroundPage.d.ts +3 -0
  644. package/src/story/pages/popover/BasicUsage.d.ts +3 -0
  645. package/src/story/pages/popover/ControlledPopover.d.ts +3 -0
  646. package/src/story/pages/popover/CustomContent.d.ts +3 -0
  647. package/src/story/pages/popover/FilterablePopover.d.ts +3 -0
  648. package/src/story/pages/popover/GroupedItems.d.ts +3 -0
  649. package/src/story/pages/popover/PopoverPage.d.ts +3 -0
  650. package/src/story/pages/popover/popover-story-data.d.ts +5 -0
  651. package/src/story/pages/progress-bar/BasicUsage.d.ts +3 -0
  652. package/src/story/pages/progress-bar/BufferProgress.d.ts +3 -0
  653. package/src/story/pages/progress-bar/DynamicProgress.d.ts +3 -0
  654. package/src/story/pages/progress-bar/Indeterminate.d.ts +3 -0
  655. package/src/story/pages/progress-bar/LabelsAndValues.d.ts +3 -0
  656. package/src/story/pages/progress-bar/Layouts.d.ts +3 -0
  657. package/src/story/pages/progress-bar/MultiSegment.d.ts +3 -0
  658. package/src/story/pages/progress-bar/ProgressBarPage.d.ts +3 -0
  659. package/src/story/pages/progress-bar/Sizes.d.ts +3 -0
  660. package/src/story/pages/progress-bar/Variants.d.ts +3 -0
  661. package/src/story/pages/radio-button/BasicUsage.d.ts +3 -0
  662. package/src/story/pages/radio-button/ControlledUncontrolled.d.ts +3 -0
  663. package/src/story/pages/radio-button/HorizontalLayout.d.ts +3 -0
  664. package/src/story/pages/radio-button/RadioButtonPage.d.ts +3 -0
  665. package/src/story/pages/radio-button/States.d.ts +3 -0
  666. package/src/story/pages/radio-button/radio-button-story-data.d.ts +13 -0
  667. package/src/story/pages/select-button/BasicUsage.d.ts +3 -0
  668. package/src/story/pages/select-button/DisabledItems.d.ts +3 -0
  669. package/src/story/pages/select-button/DisabledState.d.ts +3 -0
  670. package/src/story/pages/select-button/MultipleSelection.d.ts +3 -0
  671. package/src/story/pages/select-button/RealWorldExamples.d.ts +3 -0
  672. package/src/story/pages/select-button/SelectButtonPage.d.ts +3 -0
  673. package/src/story/pages/select-button/SizeVariants.d.ts +3 -0
  674. package/src/story/pages/select-button/ThemeVariants.d.ts +3 -0
  675. package/src/story/pages/select-button/UsageNotes.d.ts +3 -0
  676. package/src/story/pages/select-button/VerticalDirection.d.ts +3 -0
  677. package/src/story/pages/select-button/WithIcons.d.ts +3 -0
  678. package/src/story/pages/select-button/select-button-story-data.d.ts +30 -0
  679. package/src/story/pages/services/BasicUsage.d.ts +3 -0
  680. package/src/story/pages/services/Lifetimes.d.ts +3 -0
  681. package/src/story/pages/services/Parameterized.d.ts +3 -0
  682. package/src/story/pages/services/ReactIntegration.d.ts +3 -0
  683. package/src/story/pages/services/ServicesPage.d.ts +3 -0
  684. package/src/story/pages/services/SwappingImplementations.d.ts +3 -0
  685. package/src/story/pages/services/services-story-data.d.ts +92 -0
  686. package/src/story/pages/shimmer/ProfileCard.d.ts +3 -0
  687. package/src/story/pages/shimmer/ShimmerBarChartDemo.d.ts +3 -0
  688. package/src/story/pages/shimmer/ShimmerDivDemo.d.ts +3 -0
  689. package/src/story/pages/shimmer/ShimmerFeedDemo.d.ts +3 -0
  690. package/src/story/pages/shimmer/ShimmerPage.d.ts +3 -0
  691. package/src/story/pages/shimmer/ShimmerPieChartDemo.d.ts +3 -0
  692. package/src/story/pages/shimmer/ShimmerTableDemo.d.ts +3 -0
  693. package/src/story/pages/slider/BasicUsage.d.ts +3 -0
  694. package/src/story/pages/slider/Formatting.d.ts +3 -0
  695. package/src/story/pages/slider/GridSnap.d.ts +3 -0
  696. package/src/story/pages/slider/RangeSlider.d.ts +3 -0
  697. package/src/story/pages/slider/Sizes.d.ts +3 -0
  698. package/src/story/pages/slider/SliderPage.d.ts +3 -0
  699. package/src/story/pages/slider/StringValues.d.ts +3 -0
  700. package/src/story/pages/slider/Variants.d.ts +3 -0
  701. package/src/story/pages/slider/VerticalSlider.d.ts +3 -0
  702. package/src/story/pages/slider/WithMarks.d.ts +3 -0
  703. package/src/story/pages/snackbar/AnimationsDemo.d.ts +3 -0
  704. package/src/story/pages/snackbar/ClickCallback.d.ts +3 -0
  705. package/src/story/pages/snackbar/LightBackground.d.ts +3 -0
  706. package/src/story/pages/snackbar/PersistentTimeout.d.ts +3 -0
  707. package/src/story/pages/snackbar/PositionsDemo.d.ts +3 -0
  708. package/src/story/pages/snackbar/SetupSection.d.ts +3 -0
  709. package/src/story/pages/snackbar/SnackbarPage.d.ts +3 -0
  710. package/src/story/pages/snackbar/TypesDemo.d.ts +3 -0
  711. package/src/story/pages/sortable/BasicSortable.d.ts +3 -0
  712. package/src/story/pages/sortable/ComplexItems.d.ts +3 -0
  713. package/src/story/pages/sortable/DragHandles.d.ts +3 -0
  714. package/src/story/pages/sortable/MultipleLists.d.ts +3 -0
  715. package/src/story/pages/sortable/SetupSection.d.ts +3 -0
  716. package/src/story/pages/sortable/SortablePage.d.ts +3 -0
  717. package/src/story/pages/sortable/TypeBasedSortable.d.ts +3 -0
  718. package/src/story/pages/sortable/sortable-story-data.d.ts +15 -0
  719. package/src/story/pages/splitter/DefaultSizePct.d.ts +3 -0
  720. package/src/story/pages/splitter/DefaultSizePx.d.ts +3 -0
  721. package/src/story/pages/splitter/FixedPanel.d.ts +3 -0
  722. package/src/story/pages/splitter/GutterSize.d.ts +3 -0
  723. package/src/story/pages/splitter/HorizontalSplit.d.ts +3 -0
  724. package/src/story/pages/splitter/KeyboardNavigation.d.ts +3 -0
  725. package/src/story/pages/splitter/MinSize.d.ts +3 -0
  726. package/src/story/pages/splitter/NestedSplitters.d.ts +3 -0
  727. package/src/story/pages/splitter/OnResizeEnd.d.ts +3 -0
  728. package/src/story/pages/splitter/PersistingLayout.d.ts +3 -0
  729. package/src/story/pages/splitter/SplitterPage.d.ts +3 -0
  730. package/src/story/pages/splitter/VerticalSplit.d.ts +3 -0
  731. package/src/story/pages/stepper/BasicUsage.d.ts +3 -0
  732. package/src/story/pages/stepper/ColorVariants.d.ts +3 -0
  733. package/src/story/pages/stepper/InteractiveSteps.d.ts +3 -0
  734. package/src/story/pages/stepper/LabelPlacement.d.ts +3 -0
  735. package/src/story/pages/stepper/LayoutShapes.d.ts +3 -0
  736. package/src/story/pages/stepper/SizeOptions.d.ts +3 -0
  737. package/src/story/pages/stepper/StepStatus.d.ts +3 -0
  738. package/src/story/pages/stepper/StepperPage.d.ts +3 -0
  739. package/src/story/pages/stepper/TextOnly.d.ts +3 -0
  740. package/src/story/pages/stepper/VerticalOrientation.d.ts +3 -0
  741. package/src/story/pages/stepper/WithIcons.d.ts +3 -0
  742. package/src/story/pages/stepper/stepper-story-data.d.ts +7 -0
  743. package/src/story/pages/store-basic/BasicUsage.d.ts +3 -0
  744. package/src/story/pages/store-basic/BatchedUpdates.d.ts +3 -0
  745. package/src/story/pages/store-basic/ComputedProperties.d.ts +3 -0
  746. package/src/story/pages/store-basic/MiddlewareDemo.d.ts +3 -0
  747. package/src/story/pages/store-basic/MultipleStores.d.ts +3 -0
  748. package/src/story/pages/store-basic/PathSubscriptions.d.ts +3 -0
  749. package/src/story/pages/store-basic/StoreBasicPage.d.ts +3 -0
  750. package/src/story/pages/store-middleware/BroadcastDemo.d.ts +3 -0
  751. package/src/story/pages/store-middleware/DebounceDemo.d.ts +3 -0
  752. package/src/story/pages/store-middleware/LoggingDemo.d.ts +3 -0
  753. package/src/story/pages/store-middleware/PersistDemo.d.ts +3 -0
  754. package/src/story/pages/store-middleware/StoreMiddlewarePage.d.ts +3 -0
  755. package/src/story/pages/store-middleware/ThrottleDemo.d.ts +3 -0
  756. package/src/story/pages/store-middleware/UndoRedoDemo.d.ts +3 -0
  757. package/src/story/pages/store-middleware/ValidationDemo.d.ts +3 -0
  758. package/src/story/pages/store-model/BasicCRUD.d.ts +3 -0
  759. package/src/story/pages/store-model/CombinedDemo.d.ts +3 -0
  760. package/src/story/pages/store-model/ListManagement.d.ts +3 -0
  761. package/src/story/pages/store-model/PersistenceDemo.d.ts +3 -0
  762. package/src/story/pages/store-model/StoreModelPage.d.ts +3 -0
  763. package/src/story/pages/store-model/ValidationDemo.d.ts +3 -0
  764. package/src/story/pages/tab-view/BasicUsage.d.ts +3 -0
  765. package/src/story/pages/tab-view/ClosableTabs.d.ts +3 -0
  766. package/src/story/pages/tab-view/EventHandling.d.ts +3 -0
  767. package/src/story/pages/tab-view/HeaderEnd.d.ts +3 -0
  768. package/src/story/pages/tab-view/Positions.d.ts +3 -0
  769. package/src/story/pages/tab-view/ScrollableTabs.d.ts +3 -0
  770. package/src/story/pages/tab-view/StyleVariants.d.ts +3 -0
  771. package/src/story/pages/tab-view/TabViewPage.d.ts +3 -0
  772. package/src/story/pages/tab-view/WithIcons.d.ts +3 -0
  773. package/src/story/pages/table/BasicUsage.d.ts +3 -0
  774. package/src/story/pages/table/CustomRendering.d.ts +3 -0
  775. package/src/story/pages/table/LoadingAndEmpty.d.ts +3 -0
  776. package/src/story/pages/table/ResponsiveColumns.d.ts +3 -0
  777. package/src/story/pages/table/RowSelection.d.ts +3 -0
  778. package/src/story/pages/table/SortableColumns.d.ts +3 -0
  779. package/src/story/pages/table/StyleVariants.d.ts +3 -0
  780. package/src/story/pages/table/TablePage.d.ts +3 -0
  781. package/src/story/pages/table/WithActions.d.ts +3 -0
  782. package/src/story/pages/table/WithPagination.d.ts +3 -0
  783. package/src/story/pages/table/table-story-data.d.ts +13 -0
  784. package/src/story/pages/text-input/BasicUsage.d.ts +3 -0
  785. package/src/story/pages/text-input/TextInputPage.d.ts +3 -0
  786. package/src/story/pages/text-input/TextInputStates.d.ts +3 -0
  787. package/src/story/pages/text-input/Validation.d.ts +3 -0
  788. package/src/story/pages/text-input/WithIcons.d.ts +3 -0
  789. package/src/story/pages/text-input/WithLabel.d.ts +3 -0
  790. package/src/story/pages/textarea/AutoResize.d.ts +3 -0
  791. package/src/story/pages/textarea/BasicUsage.d.ts +3 -0
  792. package/src/story/pages/textarea/CharacterLimit.d.ts +3 -0
  793. package/src/story/pages/textarea/RowHeights.d.ts +3 -0
  794. package/src/story/pages/textarea/TextAreaPage.d.ts +3 -0
  795. package/src/story/pages/textarea/TextAreaStates.d.ts +3 -0
  796. package/src/story/pages/timeline/AlternateAlignment.d.ts +3 -0
  797. package/src/story/pages/timeline/BasicUsage.d.ts +3 -0
  798. package/src/story/pages/timeline/CustomMarkers.d.ts +3 -0
  799. package/src/story/pages/timeline/HorizontalLayout.d.ts +3 -0
  800. package/src/story/pages/timeline/TimelinePage.d.ts +3 -0
  801. package/src/story/pages/toggle-button/BasicUsage.d.ts +3 -0
  802. package/src/story/pages/toggle-button/CustomLabels.d.ts +3 -0
  803. package/src/story/pages/toggle-button/CustomStyling.d.ts +3 -0
  804. package/src/story/pages/toggle-button/EventHandling.d.ts +3 -0
  805. package/src/story/pages/toggle-button/FormIntegration.d.ts +3 -0
  806. package/src/story/pages/toggle-button/MultipleToggles.d.ts +3 -0
  807. package/src/story/pages/toggle-button/Sizes.d.ts +3 -0
  808. package/src/story/pages/toggle-button/States.d.ts +3 -0
  809. package/src/story/pages/toggle-button/ToggleButtonPage.d.ts +3 -0
  810. package/src/story/pages/toggle-button/Variants.d.ts +3 -0
  811. package/src/story/pages/tooltip/BasicUsage.d.ts +3 -0
  812. package/src/story/pages/tooltip/CustomTimeout.d.ts +3 -0
  813. package/src/story/pages/tooltip/OnAnyElement.d.ts +3 -0
  814. package/src/story/pages/tooltip/Placements.d.ts +3 -0
  815. package/src/story/pages/tooltip/RichContent.d.ts +3 -0
  816. package/src/story/pages/tooltip/SetupSection.d.ts +3 -0
  817. package/src/story/pages/tooltip/TooltipPage.d.ts +3 -0
  818. package/src/story/pages/tour/BasicTour.d.ts +3 -0
  819. package/src/story/pages/tour/DarkModeSection.d.ts +3 -0
  820. package/src/story/pages/tour/PlacementOptions.d.ts +3 -0
  821. package/src/story/pages/tour/RichContent.d.ts +3 -0
  822. package/src/story/pages/tour/StartAtStep.d.ts +3 -0
  823. package/src/story/pages/tour/StepCallbacks.d.ts +3 -0
  824. package/src/story/pages/tour/TourPage.d.ts +3 -0
  825. package/src/story/pages/tour/tour-story-data.d.ts +13 -0
  826. package/src/story/pages/tree-view/AsyncLoading.d.ts +3 -0
  827. package/src/story/pages/tree-view/BasicUsage.d.ts +3 -0
  828. package/src/story/pages/tree-view/CheckboxMode.d.ts +3 -0
  829. package/src/story/pages/tree-view/DragDrop.d.ts +3 -0
  830. package/src/story/pages/tree-view/TreeViewPage.d.ts +3 -0
  831. package/src/themes/index.d.ts +2 -0
  832. package/src/types/index.d.ts +97 -0
  833. package/src/utils/common-fns.d.ts +8 -0
  834. package/src/utils/field-label.d.ts +12 -0
  835. package/src/utils/index.d.ts +10 -0
  836. package/src/utils/layout.d.ts +1 -0
  837. package/src/utils/lib.d.ts +2 -0
  838. package/store-middlewares.cjs +299 -0
  839. package/store-middlewares.d.ts +1 -0
  840. package/store-middlewares.js +290 -0
  841. package/store.cjs +683 -0
  842. package/store.d.ts +1 -0
  843. package/store.js +675 -0
  844. package/styles/components.css +16368 -0
  845. package/styles/drag-drop.css +88 -0
  846. package/styles/draw.css +994 -0
  847. package/styles/kanban.css +814 -0
  848. package/utils.cjs +25 -0
  849. package/utils.d.ts +1 -0
  850. package/utils.js +23 -0
  851. package/vite-plugin.cjs +42 -0
  852. package/vite-plugin.d.ts +1 -0
  853. package/vite-plugin.js +38 -0
package/draw.js ADDED
@@ -0,0 +1,3147 @@
1
+ import { n as __toESM, t as require_classnames } from "./classnames-CEAOwX3h.js";
2
+ import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ import './styles/draw.css';//#region src/components/canvas-draw/canvas-draw-types.ts
5
+ var import_classnames = /* @__PURE__ */ __toESM(require_classnames(), 1);
6
+ var colorMap = {
7
+ red: "#e63946",
8
+ orange: "#f4a261",
9
+ yellow: "#f9c74f",
10
+ green: "#52b788",
11
+ teal: "#2a9d8f",
12
+ blue: "#4361ee",
13
+ purple: "#7209b7",
14
+ black: "#1a1a2e",
15
+ white: "#ffffff"
16
+ };
17
+ var defaultToolDefaults = {
18
+ strokeColor: "red",
19
+ fillColor: "transparent",
20
+ strokeWidth: 2,
21
+ fontFamily: "sans-serif",
22
+ fontSize: 14,
23
+ fontColor: "black",
24
+ fontBold: false,
25
+ fontItalic: false,
26
+ fontUnderline: false,
27
+ rounded: false,
28
+ arrowheadStyle: "single"
29
+ };
30
+ function contrastColor(hex) {
31
+ const h = hex.replace("#", "");
32
+ const r = parseInt(h.substring(0, 2), 16);
33
+ const g = parseInt(h.substring(2, 4), 16);
34
+ const b = parseInt(h.substring(4, 6), 16);
35
+ return (.299 * r + .587 * g + .114 * b) / 255 > .55 ? "#1a1a2e" : "#ffffff";
36
+ }
37
+ function autoFontColor(fillColor, explicitFontColor) {
38
+ if (fillColor === "transparent" || fillColor === "none") return colorMap[explicitFontColor] ?? explicitFontColor;
39
+ const hex = (colorMap[fillColor] ?? fillColor).replace("#", "");
40
+ const r = parseInt(hex.substring(0, 2), 16);
41
+ const g = parseInt(hex.substring(2, 4), 16);
42
+ const b = parseInt(hex.substring(4, 6), 16);
43
+ return (.299 * r + .587 * g + .114 * b) / 255 > .55 ? "#1a1a2e" : "#ffffff";
44
+ }
45
+ //#endregion
46
+ //#region src/components/canvas-draw/CanvasDrawOverlay.tsx
47
+ var svgNs = "http://www.w3.org/2000/svg";
48
+ function uid() {
49
+ return `cd-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
50
+ }
51
+ function svgEl(tag) {
52
+ return document.createElementNS(svgNs, tag);
53
+ }
54
+ function clr(c) {
55
+ return colorMap[c] ?? c;
56
+ }
57
+ function fontStyleStr(obj) {
58
+ let s = "";
59
+ if (obj.fontBold) s += "font-weight:700;";
60
+ if (obj.fontItalic) s += "font-style:italic;";
61
+ if (obj.fontUnderline) s += "text-decoration:underline;";
62
+ return s;
63
+ }
64
+ function getVideoBounds(videoEl) {
65
+ const rect = videoEl.getBoundingClientRect();
66
+ const vw = videoEl.videoWidth;
67
+ const vh = videoEl.videoHeight;
68
+ if (!vw || !vh) return {
69
+ x: 0,
70
+ y: 0,
71
+ w: rect.width,
72
+ h: rect.height
73
+ };
74
+ const containerAspect = rect.width / rect.height;
75
+ const videoAspect = vw / vh;
76
+ let renderedW;
77
+ let renderedH;
78
+ if (containerAspect > videoAspect) {
79
+ renderedH = rect.height;
80
+ renderedW = renderedH * videoAspect;
81
+ } else {
82
+ renderedW = rect.width;
83
+ renderedH = renderedW / videoAspect;
84
+ }
85
+ return {
86
+ x: (rect.width - renderedW) / 2,
87
+ y: (rect.height - renderedH) / 2,
88
+ w: renderedW,
89
+ h: renderedH
90
+ };
91
+ }
92
+ var handleSz = 7;
93
+ var rotateHandleOffset = 24;
94
+ function appendBoxHandles(parent, x, y, w, h, showRotate = false) {
95
+ const border = svgEl("rect");
96
+ border.setAttribute("x", String(x - 1));
97
+ border.setAttribute("y", String(y - 1));
98
+ border.setAttribute("width", String(w + 2));
99
+ border.setAttribute("height", String(h + 2));
100
+ border.setAttribute("fill", "none");
101
+ border.setAttribute("stroke", "var(--eui-primary, #3b82f6)");
102
+ border.setAttribute("stroke-width", "1");
103
+ border.setAttribute("stroke-dasharray", "4,3");
104
+ border.setAttribute("pointer-events", "none");
105
+ parent.appendChild(border);
106
+ const positions = [
107
+ {
108
+ pos: "nw",
109
+ cx: x,
110
+ cy: y
111
+ },
112
+ {
113
+ pos: "n",
114
+ cx: x + w / 2,
115
+ cy: y
116
+ },
117
+ {
118
+ pos: "ne",
119
+ cx: x + w,
120
+ cy: y
121
+ },
122
+ {
123
+ pos: "e",
124
+ cx: x + w,
125
+ cy: y + h / 2
126
+ },
127
+ {
128
+ pos: "se",
129
+ cx: x + w,
130
+ cy: y + h
131
+ },
132
+ {
133
+ pos: "s",
134
+ cx: x + w / 2,
135
+ cy: y + h
136
+ },
137
+ {
138
+ pos: "sw",
139
+ cx: x,
140
+ cy: y + h
141
+ },
142
+ {
143
+ pos: "w",
144
+ cx: x,
145
+ cy: y + h / 2
146
+ }
147
+ ];
148
+ for (const { pos, cx, cy } of positions) {
149
+ const handle = svgEl("rect");
150
+ handle.setAttribute("x", String(cx - handleSz / 2));
151
+ handle.setAttribute("y", String(cy - handleSz / 2));
152
+ handle.setAttribute("width", String(handleSz));
153
+ handle.setAttribute("height", String(handleSz));
154
+ handle.setAttribute("fill", "#ffffff");
155
+ handle.setAttribute("stroke", "var(--eui-primary, #3b82f6)");
156
+ handle.setAttribute("stroke-width", "1.5");
157
+ handle.setAttribute("rx", "1");
158
+ handle.dataset.handle = pos;
159
+ handle.style.cursor = getCursorForHandle(pos);
160
+ parent.appendChild(handle);
161
+ }
162
+ if (showRotate) {
163
+ const cx = x + w / 2;
164
+ const cy = y - rotateHandleOffset;
165
+ const stem = svgEl("line");
166
+ stem.setAttribute("x1", String(cx));
167
+ stem.setAttribute("y1", String(y - 1));
168
+ stem.setAttribute("x2", String(cx));
169
+ stem.setAttribute("y2", String(cy + 5));
170
+ stem.setAttribute("stroke", "var(--eui-primary, #3b82f6)");
171
+ stem.setAttribute("stroke-width", "1");
172
+ stem.setAttribute("pointer-events", "none");
173
+ parent.appendChild(stem);
174
+ const circle = svgEl("circle");
175
+ circle.setAttribute("cx", String(cx));
176
+ circle.setAttribute("cy", String(cy));
177
+ circle.setAttribute("r", "5");
178
+ circle.setAttribute("fill", "#ffffff");
179
+ circle.setAttribute("stroke", "var(--eui-primary, #3b82f6)");
180
+ circle.setAttribute("stroke-width", "1.5");
181
+ circle.dataset.handle = "rotate";
182
+ circle.style.cursor = "grab";
183
+ parent.appendChild(circle);
184
+ }
185
+ }
186
+ function appendLineHandles(parent, x1, y1, x2, y2) {
187
+ for (const [hx, hy, pos] of [[
188
+ x1,
189
+ y1,
190
+ "start"
191
+ ], [
192
+ x2,
193
+ y2,
194
+ "end"
195
+ ]]) {
196
+ const c = svgEl("circle");
197
+ c.setAttribute("cx", String(hx));
198
+ c.setAttribute("cy", String(hy));
199
+ c.setAttribute("r", String(handleSz / 2 + 1));
200
+ c.setAttribute("fill", "#ffffff");
201
+ c.setAttribute("stroke", "var(--eui-primary, #3b82f6)");
202
+ c.setAttribute("stroke-width", "1.5");
203
+ c.dataset.handle = pos;
204
+ c.style.cursor = "crosshair";
205
+ parent.appendChild(c);
206
+ }
207
+ }
208
+ function appendCurvedArrowHandles(parent, x1, y1, x2, y2, cpx, cpy) {
209
+ const cpLine1 = svgEl("line");
210
+ cpLine1.setAttribute("x1", String(x1));
211
+ cpLine1.setAttribute("y1", String(y1));
212
+ cpLine1.setAttribute("x2", String(cpx));
213
+ cpLine1.setAttribute("y2", String(cpy));
214
+ cpLine1.setAttribute("stroke", "var(--eui-primary, #3b82f6)");
215
+ cpLine1.setAttribute("stroke-width", "0.5");
216
+ cpLine1.setAttribute("stroke-dasharray", "3,3");
217
+ cpLine1.setAttribute("pointer-events", "none");
218
+ parent.appendChild(cpLine1);
219
+ const cpLine2 = svgEl("line");
220
+ cpLine2.setAttribute("x1", String(x2));
221
+ cpLine2.setAttribute("y1", String(y2));
222
+ cpLine2.setAttribute("x2", String(cpx));
223
+ cpLine2.setAttribute("y2", String(cpy));
224
+ cpLine2.setAttribute("stroke", "var(--eui-primary, #3b82f6)");
225
+ cpLine2.setAttribute("stroke-width", "0.5");
226
+ cpLine2.setAttribute("stroke-dasharray", "3,3");
227
+ cpLine2.setAttribute("pointer-events", "none");
228
+ parent.appendChild(cpLine2);
229
+ for (const [hx, hy, pos] of [
230
+ [
231
+ x1,
232
+ y1,
233
+ "start"
234
+ ],
235
+ [
236
+ x2,
237
+ y2,
238
+ "end"
239
+ ],
240
+ [
241
+ cpx,
242
+ cpy,
243
+ "cp"
244
+ ]
245
+ ]) {
246
+ const c = svgEl("circle");
247
+ c.setAttribute("cx", String(hx));
248
+ c.setAttribute("cy", String(hy));
249
+ c.setAttribute("r", String(pos === "cp" ? handleSz / 2 + 2 : handleSz / 2 + 1));
250
+ c.setAttribute("fill", pos === "cp" ? "var(--eui-primary, #3b82f6)" : "#ffffff");
251
+ c.setAttribute("stroke", "var(--eui-primary, #3b82f6)");
252
+ c.setAttribute("stroke-width", "1.5");
253
+ c.dataset.handle = pos;
254
+ c.style.cursor = "crosshair";
255
+ parent.appendChild(c);
256
+ }
257
+ }
258
+ function getCursorForHandle(pos) {
259
+ return {
260
+ nw: "nw-resize",
261
+ n: "n-resize",
262
+ ne: "ne-resize",
263
+ e: "e-resize",
264
+ se: "se-resize",
265
+ s: "s-resize",
266
+ sw: "sw-resize",
267
+ w: "w-resize"
268
+ }[pos] ?? "pointer";
269
+ }
270
+ function renderObjectToSvg(parent, obj, selected, scaleX, scaleY, defsEl, rotation = 0) {
271
+ const g = svgEl("g");
272
+ g.dataset.objId = obj.id;
273
+ const sx = (v) => v * scaleX;
274
+ const sy = (v) => v * scaleY;
275
+ const sw = (v) => Math.max(1, v * Math.min(scaleX, scaleY));
276
+ switch (obj.type) {
277
+ case "arrow":
278
+ case "line": {
279
+ const line = svgEl("line");
280
+ line.setAttribute("x1", String(sx(obj.x1)));
281
+ line.setAttribute("y1", String(sy(obj.y1)));
282
+ line.setAttribute("x2", String(sx(obj.x2)));
283
+ line.setAttribute("y2", String(sy(obj.y2)));
284
+ line.setAttribute("stroke", clr(obj.strokeColor));
285
+ line.setAttribute("stroke-width", String(sw(obj.strokeWidth)));
286
+ if (obj.type === "arrow") {
287
+ const markerId = `cd-ah-${obj.id}`;
288
+ const marker = svgEl("marker");
289
+ marker.setAttribute("id", markerId);
290
+ marker.setAttribute("markerWidth", "10");
291
+ marker.setAttribute("markerHeight", "7");
292
+ marker.setAttribute("refX", "10");
293
+ marker.setAttribute("refY", "3.5");
294
+ marker.setAttribute("orient", "auto");
295
+ const poly = svgEl("polygon");
296
+ poly.setAttribute("points", "0 0, 10 3.5, 0 7");
297
+ poly.setAttribute("fill", clr(obj.strokeColor));
298
+ marker.appendChild(poly);
299
+ defsEl.appendChild(marker);
300
+ line.setAttribute("marker-end", `url(#${markerId})`);
301
+ }
302
+ g.appendChild(line);
303
+ const hit = svgEl("line");
304
+ hit.setAttribute("x1", String(sx(obj.x1)));
305
+ hit.setAttribute("y1", String(sy(obj.y1)));
306
+ hit.setAttribute("x2", String(sx(obj.x2)));
307
+ hit.setAttribute("y2", String(sy(obj.y2)));
308
+ hit.setAttribute("stroke", "transparent");
309
+ hit.setAttribute("stroke-width", "12");
310
+ hit.style.cursor = selected ? "move" : "pointer";
311
+ hit.dataset.objId = obj.id;
312
+ g.appendChild(hit);
313
+ if (selected) appendLineHandles(g, sx(obj.x1), sy(obj.y1), sx(obj.x2), sy(obj.y2));
314
+ break;
315
+ }
316
+ case "rect": {
317
+ const rect = svgEl("rect");
318
+ rect.setAttribute("x", String(sx(obj.x)));
319
+ rect.setAttribute("y", String(sy(obj.y)));
320
+ rect.setAttribute("width", String(sx(obj.width)));
321
+ rect.setAttribute("height", String(sy(obj.height)));
322
+ rect.setAttribute("stroke", clr(obj.strokeColor));
323
+ rect.setAttribute("stroke-width", String(sw(obj.strokeWidth)));
324
+ rect.setAttribute("fill", obj.fillColor === "transparent" ? "none" : clr(obj.fillColor));
325
+ if (obj.rounded) {
326
+ rect.setAttribute("rx", String(sw(8)));
327
+ rect.setAttribute("ry", String(sw(8)));
328
+ }
329
+ rect.style.cursor = selected ? "move" : "pointer";
330
+ rect.dataset.objId = obj.id;
331
+ g.appendChild(rect);
332
+ if (selected) appendBoxHandles(g, sx(obj.x), sy(obj.y), sx(obj.width), sy(obj.height), true);
333
+ break;
334
+ }
335
+ case "circle": {
336
+ const el = svgEl("ellipse");
337
+ el.setAttribute("cx", String(sx(obj.x + obj.width / 2)));
338
+ el.setAttribute("cy", String(sy(obj.y + obj.height / 2)));
339
+ el.setAttribute("rx", String(Math.abs(sx(obj.width)) / 2));
340
+ el.setAttribute("ry", String(Math.abs(sy(obj.height)) / 2));
341
+ el.setAttribute("stroke", clr(obj.strokeColor));
342
+ el.setAttribute("stroke-width", String(sw(obj.strokeWidth)));
343
+ el.setAttribute("fill", obj.fillColor === "transparent" ? "none" : clr(obj.fillColor));
344
+ el.style.cursor = selected ? "move" : "pointer";
345
+ el.dataset.objId = obj.id;
346
+ g.appendChild(el);
347
+ if (selected) appendBoxHandles(g, sx(obj.x), sy(obj.y), sx(obj.width), sy(obj.height), true);
348
+ break;
349
+ }
350
+ case "freehand": {
351
+ if (obj.points.length < 2) break;
352
+ const d = obj.points.map((p, i) => `${i === 0 ? "M" : "L"}${sx(p.x)},${sy(p.y)}`).join(" ");
353
+ const path = svgEl("path");
354
+ path.setAttribute("d", d);
355
+ path.setAttribute("stroke", clr(obj.strokeColor));
356
+ path.setAttribute("stroke-width", String(sw(obj.strokeWidth)));
357
+ path.setAttribute("fill", "none");
358
+ path.setAttribute("stroke-linecap", "round");
359
+ path.setAttribute("stroke-linejoin", "round");
360
+ path.style.cursor = selected ? "move" : "pointer";
361
+ path.dataset.objId = obj.id;
362
+ g.appendChild(path);
363
+ if (selected) {
364
+ const xs = obj.points.map((p) => p.x);
365
+ const ys = obj.points.map((p) => p.y);
366
+ appendBoxHandles(g, sx(Math.min(...xs)), sy(Math.min(...ys)), sx(Math.max(...xs) - Math.min(...xs)), sy(Math.max(...ys) - Math.min(...ys)), true);
367
+ }
368
+ break;
369
+ }
370
+ case "text": {
371
+ const fo = svgEl("foreignObject");
372
+ fo.setAttribute("x", String(sx(obj.x)));
373
+ fo.setAttribute("y", String(sy(obj.y)));
374
+ fo.setAttribute("width", String(sx(obj.width)));
375
+ fo.setAttribute("height", String(sy(obj.height)));
376
+ fo.style.overflow = "visible";
377
+ fo.style.cursor = selected ? "move" : "pointer";
378
+ fo.dataset.objId = obj.id;
379
+ const div = document.createElement("div");
380
+ const textBg = "fillColor" in obj && obj.fillColor !== "transparent" ? `background:${clr(obj.fillColor)};border-radius:4px;` : "";
381
+ div.style.cssText = `width:100%;height:100%;padding:4px;box-sizing:border-box;font-family:${obj.fontFamily};font-size:${sw(obj.fontSize)}px;color:${clr(obj.fontColor)};word-wrap:break-word;white-space:pre-wrap;pointer-events:none;user-select:none;${textBg}${fontStyleStr(obj)}`;
382
+ div.textContent = obj.text;
383
+ fo.appendChild(div);
384
+ g.appendChild(fo);
385
+ if (selected) appendBoxHandles(g, sx(obj.x), sy(obj.y), sx(obj.width), sy(obj.height), true);
386
+ break;
387
+ }
388
+ case "balloon": {
389
+ const { x, y, width: bw, height: bh } = obj;
390
+ const rx2 = sw(8);
391
+ const tailW = sw(16);
392
+ const tailH = sw(14);
393
+ const tailX = sx(x + bw / 2);
394
+ const balloonPath = `M ${sx(x) + rx2} ${sy(y)} H ${sx(x + bw) - rx2} Q ${sx(x + bw)} ${sy(y)} ${sx(x + bw)} ${sy(y) + rx2} V ${sy(y + bh) - rx2} Q ${sx(x + bw)} ${sy(y + bh)} ${sx(x + bw) - rx2} ${sy(y + bh)} H ${tailX + tailW / 2} L ${tailX} ${sy(y + bh) + tailH} L ${tailX - tailW / 2} ${sy(y + bh)} H ${sx(x) + rx2} Q ${sx(x)} ${sy(y + bh)} ${sx(x)} ${sy(y + bh) - rx2} V ${sy(y) + rx2} Q ${sx(x)} ${sy(y)} ${sx(x) + rx2} ${sy(y)} Z`;
395
+ const path = svgEl("path");
396
+ path.setAttribute("d", balloonPath);
397
+ path.setAttribute("stroke", clr(obj.strokeColor));
398
+ path.setAttribute("stroke-width", String(sw(obj.strokeWidth)));
399
+ path.setAttribute("fill", obj.fillColor === "transparent" ? "none" : clr(obj.fillColor));
400
+ path.style.cursor = selected ? "move" : "pointer";
401
+ path.dataset.objId = obj.id;
402
+ g.appendChild(path);
403
+ const fo = svgEl("foreignObject");
404
+ fo.setAttribute("x", String(sx(x) + sw(6)));
405
+ fo.setAttribute("y", String(sy(y) + sw(4)));
406
+ fo.setAttribute("width", String(Math.max(sx(bw) - sw(12), 20)));
407
+ fo.setAttribute("height", String(Math.max(sy(bh) - sw(8), 20)));
408
+ fo.style.overflow = "visible";
409
+ fo.style.pointerEvents = "none";
410
+ const fc = autoFontColor(obj.fillColor, obj.fontColor);
411
+ const div = document.createElement("div");
412
+ div.style.cssText = `width:100%;height:100%;box-sizing:border-box;font-family:${obj.fontFamily};font-size:${sw(obj.fontSize)}px;color:${fc};word-wrap:break-word;white-space:pre-wrap;user-select:none;${fontStyleStr(obj)}`;
413
+ div.textContent = obj.text;
414
+ fo.appendChild(div);
415
+ g.appendChild(fo);
416
+ if (selected) appendBoxHandles(g, sx(x), sy(y), sx(bw), sy(bh), true);
417
+ break;
418
+ }
419
+ case "step": {
420
+ const circle = svgEl("circle");
421
+ circle.setAttribute("cx", String(sx(obj.x)));
422
+ circle.setAttribute("cy", String(sy(obj.y)));
423
+ circle.setAttribute("r", String(sw(obj.radius)));
424
+ circle.setAttribute("fill", clr(obj.fillColor));
425
+ circle.setAttribute("stroke", clr(obj.strokeColor));
426
+ circle.setAttribute("stroke-width", String(sw(obj.strokeWidth)));
427
+ circle.style.cursor = selected ? "move" : "pointer";
428
+ circle.dataset.objId = obj.id;
429
+ g.appendChild(circle);
430
+ const fc2 = autoFontColor(obj.fillColor, obj.fontColor);
431
+ const txt = svgEl("text");
432
+ txt.setAttribute("x", String(sx(obj.x)));
433
+ txt.setAttribute("y", String(sy(obj.y) + 1));
434
+ txt.setAttribute("text-anchor", "middle");
435
+ txt.setAttribute("dominant-baseline", "middle");
436
+ txt.setAttribute("fill", fc2);
437
+ txt.setAttribute("font-size", String(Math.max(sw(obj.radius) * .9, 10)));
438
+ txt.setAttribute("font-weight", "700");
439
+ txt.setAttribute("font-family", "sans-serif");
440
+ txt.setAttribute("pointer-events", "none");
441
+ txt.textContent = String(obj.stepNumber);
442
+ g.appendChild(txt);
443
+ if (selected) {
444
+ const r = sw(obj.radius);
445
+ appendBoxHandles(g, sx(obj.x) - r, sy(obj.y) - r, r * 2, r * 2, true);
446
+ }
447
+ break;
448
+ }
449
+ case "highlighter": {
450
+ if (obj.points.length < 2) break;
451
+ const d = obj.points.map((p, i) => `${i === 0 ? "M" : "L"}${sx(p.x)},${sy(p.y)}`).join(" ");
452
+ const path = svgEl("path");
453
+ path.setAttribute("d", d);
454
+ path.setAttribute("stroke", clr(obj.strokeColor));
455
+ path.setAttribute("stroke-width", String(Math.max(sw(obj.strokeWidth) * 6, 12)));
456
+ path.setAttribute("fill", "none");
457
+ path.setAttribute("stroke-linecap", "round");
458
+ path.setAttribute("stroke-linejoin", "round");
459
+ path.setAttribute("opacity", "0.35");
460
+ path.style.cursor = selected ? "move" : "pointer";
461
+ path.dataset.objId = obj.id;
462
+ g.appendChild(path);
463
+ if (selected) {
464
+ const xs2 = obj.points.map((p) => p.x);
465
+ const ys2 = obj.points.map((p) => p.y);
466
+ appendBoxHandles(g, sx(Math.min(...xs2)), sy(Math.min(...ys2)), sx(Math.max(...xs2) - Math.min(...xs2)), sy(Math.max(...ys2) - Math.min(...ys2)), true);
467
+ }
468
+ break;
469
+ }
470
+ case "callout": {
471
+ const lineEl = svgEl("line");
472
+ lineEl.setAttribute("x1", String(sx(obj.x1)));
473
+ lineEl.setAttribute("y1", String(sy(obj.y1)));
474
+ lineEl.setAttribute("x2", String(sx(obj.x2)));
475
+ lineEl.setAttribute("y2", String(sy(obj.y2)));
476
+ lineEl.setAttribute("stroke", clr(obj.strokeColor));
477
+ lineEl.setAttribute("stroke-width", String(sw(obj.strokeWidth)));
478
+ g.appendChild(lineEl);
479
+ const hitLine = svgEl("line");
480
+ hitLine.setAttribute("x1", String(sx(obj.x1)));
481
+ hitLine.setAttribute("y1", String(sy(obj.y1)));
482
+ hitLine.setAttribute("x2", String(sx(obj.x2)));
483
+ hitLine.setAttribute("y2", String(sy(obj.y2)));
484
+ hitLine.setAttribute("stroke", "transparent");
485
+ hitLine.setAttribute("stroke-width", "12");
486
+ hitLine.style.cursor = selected ? "move" : "pointer";
487
+ hitLine.dataset.objId = obj.id;
488
+ g.appendChild(hitLine);
489
+ const dotR = sw(obj.radius);
490
+ const dotEl = svgEl("circle");
491
+ dotEl.setAttribute("cx", String(sx(obj.x1)));
492
+ dotEl.setAttribute("cy", String(sy(obj.y1)));
493
+ dotEl.setAttribute("r", String(Math.max(dotR * .15, 4)));
494
+ dotEl.setAttribute("fill", clr(obj.strokeColor));
495
+ g.appendChild(dotEl);
496
+ const circleEl = svgEl("circle");
497
+ circleEl.setAttribute("cx", String(sx(obj.x2)));
498
+ circleEl.setAttribute("cy", String(sy(obj.y2)));
499
+ circleEl.setAttribute("r", String(dotR));
500
+ circleEl.setAttribute("fill", clr(obj.fillColor));
501
+ circleEl.setAttribute("stroke", clr(obj.strokeColor));
502
+ circleEl.setAttribute("stroke-width", String(sw(obj.strokeWidth)));
503
+ circleEl.style.cursor = selected ? "move" : "pointer";
504
+ circleEl.dataset.objId = obj.id;
505
+ g.appendChild(circleEl);
506
+ const fc3 = autoFontColor(obj.fillColor, obj.fontColor);
507
+ const numTxt = svgEl("text");
508
+ numTxt.setAttribute("x", String(sx(obj.x2)));
509
+ numTxt.setAttribute("y", String(sy(obj.y2) + 1));
510
+ numTxt.setAttribute("text-anchor", "middle");
511
+ numTxt.setAttribute("dominant-baseline", "middle");
512
+ numTxt.setAttribute("fill", fc3);
513
+ numTxt.setAttribute("font-size", String(Math.max(dotR * .75, 12)));
514
+ numTxt.setAttribute("font-weight", "700");
515
+ numTxt.setAttribute("font-family", "sans-serif");
516
+ numTxt.setAttribute("pointer-events", "none");
517
+ numTxt.textContent = String(obj.stepNumber);
518
+ g.appendChild(numTxt);
519
+ if (selected) {
520
+ const selLine = svgEl("line");
521
+ selLine.setAttribute("x1", String(sx(obj.x1)));
522
+ selLine.setAttribute("y1", String(sy(obj.y1)));
523
+ selLine.setAttribute("x2", String(sx(obj.x2)));
524
+ selLine.setAttribute("y2", String(sy(obj.y2)));
525
+ selLine.setAttribute("stroke", "var(--eui-primary, #3b82f6)");
526
+ selLine.setAttribute("stroke-width", "1");
527
+ selLine.setAttribute("stroke-dasharray", "4,3");
528
+ selLine.setAttribute("pointer-events", "none");
529
+ g.appendChild(selLine);
530
+ appendLineHandles(g, sx(obj.x1), sy(obj.y1), sx(obj.x2), sy(obj.y2));
531
+ }
532
+ break;
533
+ }
534
+ case "dimension": {
535
+ const dx = sx(obj.x2) - sx(obj.x1);
536
+ const dy = sy(obj.y2) - sy(obj.y1);
537
+ const len = Math.sqrt(dx * dx + dy * dy);
538
+ const perpX = len > 0 ? -dy / len : 0;
539
+ const perpY = len > 0 ? dx / len : 1;
540
+ const capLen = 6;
541
+ const line2 = svgEl("line");
542
+ line2.setAttribute("x1", String(sx(obj.x1)));
543
+ line2.setAttribute("y1", String(sy(obj.y1)));
544
+ line2.setAttribute("x2", String(sx(obj.x2)));
545
+ line2.setAttribute("y2", String(sy(obj.y2)));
546
+ line2.setAttribute("stroke", clr(obj.strokeColor));
547
+ line2.setAttribute("stroke-width", String(sw(obj.strokeWidth)));
548
+ g.appendChild(line2);
549
+ for (const [ex, ey] of [[sx(obj.x1), sy(obj.y1)], [sx(obj.x2), sy(obj.y2)]]) {
550
+ const cap = svgEl("line");
551
+ cap.setAttribute("x1", String(ex + perpX * capLen));
552
+ cap.setAttribute("y1", String(ey + perpY * capLen));
553
+ cap.setAttribute("x2", String(ex - perpX * capLen));
554
+ cap.setAttribute("y2", String(ey - perpY * capLen));
555
+ cap.setAttribute("stroke", clr(obj.strokeColor));
556
+ cap.setAttribute("stroke-width", String(sw(obj.strokeWidth)));
557
+ g.appendChild(cap);
558
+ }
559
+ const midX = (sx(obj.x1) + sx(obj.x2)) / 2;
560
+ const midY = (sy(obj.y1) + sy(obj.y2)) / 2;
561
+ const dimLabel = svgEl("text");
562
+ dimLabel.setAttribute("x", String(midX + perpX * 12));
563
+ dimLabel.setAttribute("y", String(midY + perpY * 12));
564
+ dimLabel.setAttribute("text-anchor", "middle");
565
+ dimLabel.setAttribute("dominant-baseline", "middle");
566
+ dimLabel.setAttribute("fill", clr(obj.strokeColor));
567
+ dimLabel.setAttribute("font-size", "11");
568
+ dimLabel.setAttribute("font-family", "sans-serif");
569
+ dimLabel.setAttribute("font-weight", "600");
570
+ dimLabel.setAttribute("pointer-events", "none");
571
+ dimLabel.textContent = obj.customLabel ?? `${Math.round(len)}px`;
572
+ g.appendChild(dimLabel);
573
+ const hitLine2 = svgEl("line");
574
+ hitLine2.setAttribute("x1", String(sx(obj.x1)));
575
+ hitLine2.setAttribute("y1", String(sy(obj.y1)));
576
+ hitLine2.setAttribute("x2", String(sx(obj.x2)));
577
+ hitLine2.setAttribute("y2", String(sy(obj.y2)));
578
+ hitLine2.setAttribute("stroke", "transparent");
579
+ hitLine2.setAttribute("stroke-width", "12");
580
+ hitLine2.style.cursor = selected ? "move" : "pointer";
581
+ hitLine2.dataset.objId = obj.id;
582
+ g.appendChild(hitLine2);
583
+ if (selected) appendLineHandles(g, sx(obj.x1), sy(obj.y1), sx(obj.x2), sy(obj.y2));
584
+ break;
585
+ }
586
+ case "curvedArrow": {
587
+ const markerId = `cd-cah-${obj.id}`;
588
+ const marker = svgEl("marker");
589
+ marker.setAttribute("id", markerId);
590
+ marker.setAttribute("markerWidth", "10");
591
+ marker.setAttribute("markerHeight", "7");
592
+ marker.setAttribute("refX", "10");
593
+ marker.setAttribute("refY", "3.5");
594
+ marker.setAttribute("orient", "auto");
595
+ const poly = svgEl("polygon");
596
+ poly.setAttribute("points", "0 0, 10 3.5, 0 7");
597
+ poly.setAttribute("fill", clr(obj.strokeColor));
598
+ marker.appendChild(poly);
599
+ defsEl.appendChild(marker);
600
+ const pathD = `M ${sx(obj.x1)} ${sy(obj.y1)} Q ${sx(obj.cpx)} ${sy(obj.cpy)} ${sx(obj.x2)} ${sy(obj.y2)}`;
601
+ const curvePath = svgEl("path");
602
+ curvePath.setAttribute("d", pathD);
603
+ curvePath.setAttribute("stroke", clr(obj.strokeColor));
604
+ curvePath.setAttribute("stroke-width", String(sw(obj.strokeWidth)));
605
+ curvePath.setAttribute("fill", "none");
606
+ curvePath.setAttribute("marker-end", `url(#${markerId})`);
607
+ g.appendChild(curvePath);
608
+ const hitPath = svgEl("path");
609
+ hitPath.setAttribute("d", pathD);
610
+ hitPath.setAttribute("stroke", "transparent");
611
+ hitPath.setAttribute("stroke-width", "12");
612
+ hitPath.setAttribute("fill", "none");
613
+ hitPath.style.cursor = selected ? "move" : "pointer";
614
+ hitPath.dataset.objId = obj.id;
615
+ g.appendChild(hitPath);
616
+ if (selected) appendCurvedArrowHandles(g, sx(obj.x1), sy(obj.y1), sx(obj.x2), sy(obj.y2), sx(obj.cpx), sy(obj.cpy));
617
+ break;
618
+ }
619
+ }
620
+ const isLineType = obj.type === "arrow" || obj.type === "line" || obj.type === "dimension" || obj.type === "callout" || obj.type === "curvedArrow";
621
+ if (rotation && !isLineType) {
622
+ const bbox = getObjectCenter(obj, sx, sy);
623
+ g.setAttribute("transform", `rotate(${rotation} ${bbox.cx} ${bbox.cy})`);
624
+ }
625
+ parent.appendChild(g);
626
+ }
627
+ function getObjectCenter(obj, sx, sy) {
628
+ if ("width" in obj && "height" in obj && "x" in obj && "y" in obj) {
629
+ const o = obj;
630
+ return {
631
+ cx: sx(o.x) + sx(o.width) / 2,
632
+ cy: sy(o.y) + sy(o.height) / 2
633
+ };
634
+ }
635
+ if (obj.type === "step") return {
636
+ cx: sx(obj.x),
637
+ cy: sy(obj.y)
638
+ };
639
+ if (obj.type === "freehand") {
640
+ const xs = obj.points.map((p) => p.x);
641
+ const ys = obj.points.map((p) => p.y);
642
+ const minX = Math.min(...xs);
643
+ const maxX = Math.max(...xs);
644
+ const minY = Math.min(...ys);
645
+ const maxY = Math.max(...ys);
646
+ return {
647
+ cx: sx((minX + maxX) / 2),
648
+ cy: sy((minY + maxY) / 2)
649
+ };
650
+ }
651
+ return {
652
+ cx: 0,
653
+ cy: 0
654
+ };
655
+ }
656
+ function applyDrag(item, dxPct, dyPct) {
657
+ const obj = item.object;
658
+ if (obj.type === "freehand" || obj.type === "highlighter") {
659
+ const pts = obj.points;
660
+ return {
661
+ ...item,
662
+ xPct: item.xPct + dxPct,
663
+ yPct: item.yPct + dyPct,
664
+ object: {
665
+ ...obj,
666
+ points: pts.map((p) => ({
667
+ x: p.x + dxPct,
668
+ y: p.y + dyPct
669
+ }))
670
+ }
671
+ };
672
+ }
673
+ if (obj.type === "arrow" || obj.type === "line" || obj.type === "dimension") return {
674
+ ...item,
675
+ xPct: item.xPct + dxPct,
676
+ yPct: item.yPct + dyPct,
677
+ object: {
678
+ ...obj,
679
+ x1: obj.x1 + dxPct,
680
+ y1: obj.y1 + dyPct,
681
+ x2: obj.x2 + dxPct,
682
+ y2: obj.y2 + dyPct
683
+ }
684
+ };
685
+ if (obj.type === "callout") return {
686
+ ...item,
687
+ xPct: item.xPct + dxPct,
688
+ yPct: item.yPct + dyPct,
689
+ object: {
690
+ ...obj,
691
+ x1: obj.x1 + dxPct,
692
+ y1: obj.y1 + dyPct,
693
+ x2: obj.x2 + dxPct,
694
+ y2: obj.y2 + dyPct
695
+ }
696
+ };
697
+ if (obj.type === "curvedArrow") return {
698
+ ...item,
699
+ xPct: item.xPct + dxPct,
700
+ yPct: item.yPct + dyPct,
701
+ object: {
702
+ ...obj,
703
+ x1: obj.x1 + dxPct,
704
+ y1: obj.y1 + dyPct,
705
+ x2: obj.x2 + dxPct,
706
+ y2: obj.y2 + dyPct,
707
+ cpx: obj.cpx + dxPct,
708
+ cpy: obj.cpy + dyPct
709
+ }
710
+ };
711
+ if ("x" in obj && "y" in obj) return {
712
+ ...item,
713
+ xPct: item.xPct + dxPct,
714
+ yPct: item.yPct + dyPct,
715
+ object: {
716
+ ...obj,
717
+ x: obj.x + dxPct,
718
+ y: obj.y + dyPct
719
+ }
720
+ };
721
+ return item;
722
+ }
723
+ function applyResize(item, handle, dxPct, dyPct) {
724
+ const obj = item.object;
725
+ if (obj.type === "arrow" || obj.type === "line" || obj.type === "dimension") {
726
+ if (handle === "end") return {
727
+ ...item,
728
+ wPct: (item.wPct ?? 0) + dxPct,
729
+ hPct: (item.hPct ?? 0) + dyPct,
730
+ object: {
731
+ ...obj,
732
+ x2: obj.x2 + dxPct,
733
+ y2: obj.y2 + dyPct
734
+ }
735
+ };
736
+ if (handle === "start") return {
737
+ ...item,
738
+ xPct: item.xPct + dxPct,
739
+ yPct: item.yPct + dyPct,
740
+ object: {
741
+ ...obj,
742
+ x1: obj.x1 + dxPct,
743
+ y1: obj.y1 + dyPct
744
+ }
745
+ };
746
+ }
747
+ if (obj.type === "callout") {
748
+ if (handle === "end") return {
749
+ ...item,
750
+ object: {
751
+ ...obj,
752
+ x2: obj.x2 + dxPct,
753
+ y2: obj.y2 + dyPct
754
+ }
755
+ };
756
+ if (handle === "start") return {
757
+ ...item,
758
+ object: {
759
+ ...obj,
760
+ x1: obj.x1 + dxPct,
761
+ y1: obj.y1 + dyPct
762
+ }
763
+ };
764
+ }
765
+ if (obj.type === "curvedArrow") {
766
+ if (handle === "end") return {
767
+ ...item,
768
+ wPct: (item.wPct ?? 0) + dxPct,
769
+ hPct: (item.hPct ?? 0) + dyPct,
770
+ object: {
771
+ ...obj,
772
+ x2: obj.x2 + dxPct,
773
+ y2: obj.y2 + dyPct
774
+ }
775
+ };
776
+ if (handle === "start") return {
777
+ ...item,
778
+ xPct: item.xPct + dxPct,
779
+ yPct: item.yPct + dyPct,
780
+ object: {
781
+ ...obj,
782
+ x1: obj.x1 + dxPct,
783
+ y1: obj.y1 + dyPct
784
+ }
785
+ };
786
+ if (handle === "cp") return {
787
+ ...item,
788
+ object: {
789
+ ...obj,
790
+ cpx: obj.cpx + dxPct,
791
+ cpy: obj.cpy + dyPct
792
+ }
793
+ };
794
+ }
795
+ if (obj.type === "step") {
796
+ const currentR = (item.wPct ?? .04) / 2;
797
+ const delta = Math.max(Math.abs(dxPct), Math.abs(dyPct));
798
+ const expanding = handle.includes("e") && dxPct > 0 || handle.includes("s") && dyPct > 0 || handle.includes("w") && dxPct < 0 || handle.includes("n") && dyPct < 0;
799
+ const newR = Math.max(.008, currentR + (expanding ? delta : -delta));
800
+ return {
801
+ ...item,
802
+ wPct: newR * 2,
803
+ hPct: newR * 2,
804
+ object: {
805
+ ...obj,
806
+ radius: newR
807
+ }
808
+ };
809
+ }
810
+ if (obj.type === "freehand" || obj.type === "highlighter") {
811
+ const pts = obj.points;
812
+ const xs = pts.map((p) => p.x);
813
+ const ys = pts.map((p) => p.y);
814
+ const minX = Math.min(...xs);
815
+ const minY = Math.min(...ys);
816
+ const maxX = Math.max(...xs);
817
+ const maxY = Math.max(...ys);
818
+ const origW = maxX - minX || .001;
819
+ const origH = maxY - minY || .001;
820
+ let newMinX = minX, newMinY = minY, newW = origW, newH = origH;
821
+ if (handle.includes("e")) newW += dxPct;
822
+ if (handle.includes("s")) newH += dyPct;
823
+ if (handle.includes("w")) {
824
+ newMinX += dxPct;
825
+ newW -= dxPct;
826
+ }
827
+ if (handle.includes("n")) {
828
+ newMinY += dyPct;
829
+ newH -= dyPct;
830
+ }
831
+ if (newW < .001) newW = .001;
832
+ if (newH < .001) newH = .001;
833
+ const scaleXf = newW / origW;
834
+ const scaleYf = newH / origH;
835
+ const newPts = pts.map((p) => ({
836
+ x: newMinX + (p.x - minX) * scaleXf,
837
+ y: newMinY + (p.y - minY) * scaleYf
838
+ }));
839
+ return {
840
+ ...item,
841
+ xPct: newMinX,
842
+ yPct: newMinY,
843
+ wPct: newW,
844
+ hPct: newH,
845
+ object: {
846
+ ...obj,
847
+ points: newPts
848
+ }
849
+ };
850
+ }
851
+ if ("width" in obj && "height" in obj && "x" in obj && "y" in obj) {
852
+ let { x, y, width: w, height: h } = obj;
853
+ if (handle.includes("e")) w += dxPct;
854
+ if (handle.includes("s")) h += dyPct;
855
+ if (handle.includes("w")) {
856
+ x += dxPct;
857
+ w -= dxPct;
858
+ }
859
+ if (handle.includes("n")) {
860
+ y += dyPct;
861
+ h -= dyPct;
862
+ }
863
+ return {
864
+ ...item,
865
+ xPct: x,
866
+ yPct: y,
867
+ wPct: w,
868
+ hPct: h,
869
+ object: {
870
+ ...obj,
871
+ x,
872
+ y,
873
+ width: w,
874
+ height: h
875
+ }
876
+ };
877
+ }
878
+ return item;
879
+ }
880
+ var CanvasDrawOverlay = forwardRef(function CanvasDrawOverlay(props, ref) {
881
+ const { background, currentMs, isEditing, items, groups, selectedItemId, defaults, activeTool, currentDrawShowAt, currentDrawHideAt, currentDrawTransition, currentDrawGroupId, onItemsChange, onItemsCommit, onSelectItem, onDrawComplete } = props;
882
+ const svgRef = useRef(null);
883
+ const boundsRef = useRef(null);
884
+ const [boundsVersion, setBoundsVersion] = useState(0);
885
+ const drawingRef = useRef(false);
886
+ const startPctRef = useRef({
887
+ x: 0,
888
+ y: 0
889
+ });
890
+ const currentObjRef = useRef(null);
891
+ const dragRef = useRef(null);
892
+ const resizeRef = useRef(null);
893
+ const rotateRef = useRef(null);
894
+ const itemsRef = useRef(items);
895
+ itemsRef.current = items;
896
+ const activeToolRef = useRef(activeTool);
897
+ activeToolRef.current = activeTool;
898
+ useImperativeHandle(ref, () => ({
899
+ getItems: () => items,
900
+ getGroups: () => groups,
901
+ exportSvgString: () => svgRef.current?.outerHTML ?? ""
902
+ }));
903
+ const updateBounds = useCallback(() => {
904
+ const svg = svgRef.current;
905
+ if (!svg) return;
906
+ let boundsW;
907
+ let boundsH;
908
+ let offsetX = 0;
909
+ let offsetY = 0;
910
+ if (background.type === "video") {
911
+ const video = background.videoRef.current;
912
+ if (!video) return;
913
+ const b = getVideoBounds(video);
914
+ boundsW = b.w;
915
+ boundsH = b.h;
916
+ offsetX = b.x;
917
+ offsetY = b.y;
918
+ const videoRect = video.getBoundingClientRect();
919
+ const wrapEl = svg.parentElement;
920
+ if (!wrapEl) return;
921
+ const wrapRect = wrapEl.getBoundingClientRect();
922
+ svg.style.left = `${videoRect.left - wrapRect.left + offsetX}px`;
923
+ svg.style.top = `${videoRect.top - wrapRect.top + offsetY}px`;
924
+ } else {
925
+ const parent = svg.parentElement;
926
+ if (!parent) return;
927
+ boundsW = parent.clientWidth;
928
+ boundsH = parent.clientHeight;
929
+ svg.style.left = "0px";
930
+ svg.style.top = "0px";
931
+ }
932
+ const prev = boundsRef.current;
933
+ boundsRef.current = {
934
+ x: offsetX,
935
+ y: offsetY,
936
+ w: boundsW,
937
+ h: boundsH
938
+ };
939
+ svg.style.width = `${boundsW}px`;
940
+ svg.style.height = `${boundsH}px`;
941
+ svg.setAttribute("viewBox", `0 0 ${boundsW} ${boundsH}`);
942
+ if (!prev || prev.w !== boundsW || prev.h !== boundsH) setBoundsVersion((v) => v + 1);
943
+ }, [background]);
944
+ useEffect(() => {
945
+ if (background.type === "video") {
946
+ const video = background.videoRef.current;
947
+ if (!video) return;
948
+ const update = () => updateBounds();
949
+ video.addEventListener("loadedmetadata", update);
950
+ video.addEventListener("resize", update);
951
+ const ro = new ResizeObserver(() => updateBounds());
952
+ ro.observe(video);
953
+ if (video.parentElement) ro.observe(video.parentElement);
954
+ updateBounds();
955
+ return () => {
956
+ video.removeEventListener("loadedmetadata", update);
957
+ video.removeEventListener("resize", update);
958
+ ro.disconnect();
959
+ };
960
+ } else {
961
+ const parent = svgRef.current?.parentElement;
962
+ if (!parent) return;
963
+ const ro = new ResizeObserver(() => updateBounds());
964
+ ro.observe(parent);
965
+ updateBounds();
966
+ return () => ro.disconnect();
967
+ }
968
+ }, [background, updateBounds]);
969
+ useEffect(() => {
970
+ const onFullscreen = () => setTimeout(() => updateBounds(), 100);
971
+ document.addEventListener("fullscreenchange", onFullscreen);
972
+ document.addEventListener("webkitfullscreenchange", onFullscreen);
973
+ return () => {
974
+ document.removeEventListener("fullscreenchange", onFullscreen);
975
+ document.removeEventListener("webkitfullscreenchange", onFullscreen);
976
+ };
977
+ }, [updateBounds]);
978
+ const getItemVisible = useCallback((item, ms) => {
979
+ if (item.showAtMs > ms) return false;
980
+ if (item.hideAtMs !== null && ms >= item.hideAtMs) return false;
981
+ if (item.groupId) {
982
+ const group = groups.find((g) => g.id === item.groupId);
983
+ if (group) {
984
+ if (group.showAtMs > ms) return false;
985
+ if (group.hideAtMs !== null && ms >= group.hideAtMs) return false;
986
+ }
987
+ }
988
+ return true;
989
+ }, [groups]);
990
+ const svgPxToPct = useCallback((svgX, svgY) => {
991
+ const b = boundsRef.current;
992
+ if (!b || b.w === 0 || b.h === 0) return {
993
+ xPct: 0,
994
+ yPct: 0
995
+ };
996
+ return {
997
+ xPct: svgX / b.w,
998
+ yPct: svgY / b.h
999
+ };
1000
+ }, []);
1001
+ const eventToSvgPx = useCallback((e) => {
1002
+ const svg = svgRef.current;
1003
+ if (!svg) return null;
1004
+ const svgRect = svg.getBoundingClientRect();
1005
+ return {
1006
+ x: e.clientX - svgRect.left,
1007
+ y: e.clientY - svgRect.top
1008
+ };
1009
+ }, []);
1010
+ const itemObjectToScaled = useCallback((item) => {
1011
+ const b = boundsRef.current;
1012
+ if (!b) return item.object;
1013
+ const sX = b.w;
1014
+ const sY = b.h;
1015
+ const obj = { ...item.object };
1016
+ if (obj.type === "curvedArrow") return {
1017
+ ...obj,
1018
+ x1: obj.x1 * sX,
1019
+ y1: obj.y1 * sY,
1020
+ x2: obj.x2 * sX,
1021
+ y2: obj.y2 * sY,
1022
+ cpx: obj.cpx * sX,
1023
+ cpy: obj.cpy * sY
1024
+ };
1025
+ if (obj.type === "callout") return {
1026
+ ...obj,
1027
+ x1: obj.x1 * sX,
1028
+ y1: obj.y1 * sY,
1029
+ x2: obj.x2 * sX,
1030
+ y2: obj.y2 * sY,
1031
+ radius: obj.radius * Math.min(sX, sY)
1032
+ };
1033
+ if ("x1" in obj) return {
1034
+ ...obj,
1035
+ x1: item.xPct * sX,
1036
+ y1: item.yPct * sY,
1037
+ x2: (item.xPct + (item.wPct ?? 0)) * sX,
1038
+ y2: (item.yPct + (item.hPct ?? 0)) * sY
1039
+ };
1040
+ if ("points" in obj) {
1041
+ const pts = obj.points;
1042
+ return {
1043
+ ...obj,
1044
+ points: pts.map((p) => ({
1045
+ x: p.x * sX,
1046
+ y: p.y * sY
1047
+ }))
1048
+ };
1049
+ }
1050
+ if ("x" in obj && "y" in obj) {
1051
+ const o2 = obj;
1052
+ return {
1053
+ ...obj,
1054
+ x: item.xPct * sX,
1055
+ y: item.yPct * sY,
1056
+ ...o2.width !== void 0 ? {
1057
+ width: (item.wPct ?? 0) * sX,
1058
+ height: (item.hPct ?? 0) * sY
1059
+ } : {},
1060
+ ...o2.radius !== void 0 ? { radius: (item.wPct ?? .05) * Math.min(sX, sY) / 2 } : {}
1061
+ };
1062
+ }
1063
+ return obj;
1064
+ }, []);
1065
+ const rebuildSvg = useCallback(() => {
1066
+ const svg = svgRef.current;
1067
+ if (!svg || !boundsRef.current) return;
1068
+ while (svg.lastChild) svg.removeChild(svg.lastChild);
1069
+ const defs = svgEl("defs");
1070
+ svg.appendChild(defs);
1071
+ for (const item of items) {
1072
+ const scaledObj = itemObjectToScaled(item);
1073
+ const selected = isEditing && item.id === selectedItemId;
1074
+ const groupEl = svgEl("g");
1075
+ groupEl.dataset.cdItemId = item.id;
1076
+ if (!isEditing && item.transition !== "none") groupEl.style.transition = "opacity 0.35s ease, transform 0.35s ease";
1077
+ renderObjectToSvg(groupEl, scaledObj, selected, 1, 1, defs, item.rotation ?? 0);
1078
+ svg.appendChild(groupEl);
1079
+ }
1080
+ }, [
1081
+ items,
1082
+ isEditing,
1083
+ selectedItemId,
1084
+ itemObjectToScaled,
1085
+ boundsVersion
1086
+ ]);
1087
+ const updateVisibility = useCallback(() => {
1088
+ const svg = svgRef.current;
1089
+ const b = boundsRef.current;
1090
+ if (!svg || !b) return;
1091
+ svg.querySelectorAll(":scope > g[data-cd-item-id]").forEach((groupEl) => {
1092
+ const itemId = groupEl.dataset.cdItemId;
1093
+ const item = items.find((it) => it.id === itemId);
1094
+ if (!item) {
1095
+ groupEl.style.display = "none";
1096
+ return;
1097
+ }
1098
+ const visible = getItemVisible(item, currentMs);
1099
+ if (isEditing) {
1100
+ groupEl.style.display = "";
1101
+ groupEl.style.opacity = visible ? "1" : "0.3";
1102
+ groupEl.style.transform = "";
1103
+ } else {
1104
+ const transition = item.transition;
1105
+ if (transition !== "none") {
1106
+ groupEl.style.display = "";
1107
+ groupEl.style.opacity = visible ? "1" : "0";
1108
+ if (transition === "scale") {
1109
+ groupEl.style.transform = visible ? "scale(1)" : "scale(0.5)";
1110
+ groupEl.style.transformOrigin = `${item.xPct * b.w + (item.wPct ?? .05) * b.w / 2}px ${item.yPct * b.h + (item.hPct ?? .05) * b.h / 2}px`;
1111
+ } else if (transition === "slide-up") groupEl.style.transform = visible ? "translateY(0)" : "translateY(20px)";
1112
+ else if (transition === "slide-down") groupEl.style.transform = visible ? "translateY(0)" : "translateY(-20px)";
1113
+ else if (transition === "slide-left") groupEl.style.transform = visible ? "translateX(0)" : "translateX(20px)";
1114
+ else if (transition === "slide-right") groupEl.style.transform = visible ? "translateX(0)" : "translateX(-20px)";
1115
+ else groupEl.style.transform = "";
1116
+ } else {
1117
+ groupEl.style.display = visible ? "" : "none";
1118
+ groupEl.style.opacity = "";
1119
+ groupEl.style.transform = "";
1120
+ }
1121
+ }
1122
+ });
1123
+ }, [
1124
+ items,
1125
+ currentMs,
1126
+ isEditing,
1127
+ getItemVisible
1128
+ ]);
1129
+ useEffect(() => {
1130
+ rebuildSvg();
1131
+ updateVisibility();
1132
+ }, [rebuildSvg]);
1133
+ useEffect(() => {
1134
+ updateVisibility();
1135
+ }, [updateVisibility]);
1136
+ const openInlineTextEditor = useCallback((itemId, obj, svgX, svgY, isExisting = false) => {
1137
+ const svg = svgRef.current;
1138
+ if (!svg) return;
1139
+ const svgRect = svg.getBoundingClientRect();
1140
+ const existingText = obj.text ?? "";
1141
+ const inputEl = document.createElement("textarea");
1142
+ inputEl.value = isExisting ? existingText : "";
1143
+ inputEl.style.cssText = `
1144
+ position:fixed;
1145
+ left:${svgRect.left + svgX}px;
1146
+ top:${svgRect.top + svgY}px;
1147
+ width:160px;height:60px;
1148
+ font-size:13px;font-family:sans-serif;
1149
+ background:#fff;color:#111;border:2px solid var(--eui-primary, #3b82f6);
1150
+ border-radius:4px;padding:4px;outline:none;resize:both;z-index:9999;
1151
+ `;
1152
+ document.body.appendChild(inputEl);
1153
+ inputEl.focus();
1154
+ if (isExisting) inputEl.select();
1155
+ let committed = false;
1156
+ const commit = () => {
1157
+ if (committed) return;
1158
+ committed = true;
1159
+ const text = inputEl.value.trim();
1160
+ inputEl.remove();
1161
+ if (isExisting) {
1162
+ if (text) {
1163
+ const updated = {
1164
+ ...obj,
1165
+ text
1166
+ };
1167
+ onItemsChange(itemsRef.current.map((it) => it.id === itemId ? {
1168
+ ...it,
1169
+ object: updated
1170
+ } : it));
1171
+ }
1172
+ } else {
1173
+ const newItem = {
1174
+ id: itemId,
1175
+ object: {
1176
+ ...obj,
1177
+ text
1178
+ },
1179
+ showAtMs: currentDrawShowAt,
1180
+ hideAtMs: currentDrawHideAt,
1181
+ transition: currentDrawTransition,
1182
+ groupId: currentDrawGroupId,
1183
+ xPct: obj.x,
1184
+ yPct: obj.y,
1185
+ wPct: .15,
1186
+ hPct: .06
1187
+ };
1188
+ if (text) {
1189
+ onItemsChange([...itemsRef.current, newItem]);
1190
+ onSelectItem(itemId);
1191
+ }
1192
+ }
1193
+ };
1194
+ inputEl.addEventListener("blur", commit);
1195
+ inputEl.addEventListener("keydown", (ev) => {
1196
+ if (ev.key === "Escape") {
1197
+ inputEl.value = isExisting ? existingText : "";
1198
+ inputEl.blur();
1199
+ }
1200
+ if (ev.key === "Enter" && !ev.shiftKey) {
1201
+ ev.preventDefault();
1202
+ commit();
1203
+ }
1204
+ });
1205
+ }, [
1206
+ currentDrawShowAt,
1207
+ currentDrawHideAt,
1208
+ currentDrawTransition,
1209
+ currentDrawGroupId,
1210
+ onItemsChange,
1211
+ onSelectItem
1212
+ ]);
1213
+ const openDimensionLabelEditor = useCallback((itemId, obj, svgX, svgY) => {
1214
+ const svg = svgRef.current;
1215
+ if (!svg || obj.type !== "dimension") return;
1216
+ const svgRect = svg.getBoundingClientRect();
1217
+ const currentLabel = obj.customLabel ?? "";
1218
+ const inputEl = document.createElement("input");
1219
+ inputEl.type = "text";
1220
+ inputEl.value = currentLabel;
1221
+ inputEl.placeholder = "auto";
1222
+ inputEl.style.cssText = `
1223
+ position:fixed;
1224
+ left:${svgRect.left + svgX - 50}px;
1225
+ top:${svgRect.top + svgY - 14}px;
1226
+ width:100px;height:28px;
1227
+ font-size:12px;font-family:sans-serif;
1228
+ background:#fff;color:#111;border:2px solid var(--eui-primary, #3b82f6);
1229
+ border-radius:4px;padding:2px 6px;outline:none;text-align:center;z-index:9999;
1230
+ `;
1231
+ document.body.appendChild(inputEl);
1232
+ inputEl.focus();
1233
+ inputEl.select();
1234
+ let committed = false;
1235
+ const commit = () => {
1236
+ if (committed) return;
1237
+ committed = true;
1238
+ const val = inputEl.value.trim();
1239
+ inputEl.remove();
1240
+ const updated = {
1241
+ ...obj,
1242
+ customLabel: val || void 0
1243
+ };
1244
+ onItemsChange(itemsRef.current.map((it) => it.id === itemId ? {
1245
+ ...it,
1246
+ object: updated
1247
+ } : it));
1248
+ };
1249
+ inputEl.addEventListener("blur", commit);
1250
+ inputEl.addEventListener("keydown", (ev) => {
1251
+ if (ev.key === "Escape") {
1252
+ inputEl.value = currentLabel;
1253
+ inputEl.blur();
1254
+ }
1255
+ if (ev.key === "Enter") {
1256
+ ev.preventDefault();
1257
+ commit();
1258
+ }
1259
+ });
1260
+ }, [onItemsChange]);
1261
+ const onDoubleClick = useCallback((e) => {
1262
+ if (!isEditing || activeTool !== "select") return;
1263
+ const cdItemId = e.target.closest("[data-cd-item-id]")?.getAttribute("data-cd-item-id");
1264
+ if (!cdItemId) return;
1265
+ const item = itemsRef.current.find((it) => it.id === cdItemId);
1266
+ if (!item) return;
1267
+ e.preventDefault();
1268
+ e.stopPropagation();
1269
+ const pos = eventToSvgPx(e);
1270
+ if (!pos) return;
1271
+ if (item.object.type === "dimension") {
1272
+ openDimensionLabelEditor(cdItemId, item.object, pos.x, pos.y);
1273
+ return;
1274
+ }
1275
+ if (item.object.type !== "text" && item.object.type !== "balloon") return;
1276
+ openInlineTextEditor(cdItemId, item.object, pos.x, pos.y, true);
1277
+ }, [
1278
+ isEditing,
1279
+ activeTool,
1280
+ eventToSvgPx,
1281
+ openInlineTextEditor,
1282
+ openDimensionLabelEditor
1283
+ ]);
1284
+ const completeDrawing = useCallback(() => {
1285
+ activeToolRef.current = "select";
1286
+ onDrawComplete?.();
1287
+ }, [onDrawComplete]);
1288
+ const onMouseDown = useCallback((e) => {
1289
+ if (!isEditing) return;
1290
+ e.preventDefault();
1291
+ e.stopPropagation();
1292
+ const pos = eventToSvgPx(e);
1293
+ if (!pos) return;
1294
+ const b = boundsRef.current;
1295
+ if (!b) return;
1296
+ if (pos.x < 0 || pos.y < 0 || pos.x > b.w || pos.y > b.h) return;
1297
+ const { x, y } = pos;
1298
+ const currentItems = itemsRef.current;
1299
+ const target = e.target;
1300
+ const objId = target.dataset?.objId ?? target.closest("[data-obj-id]")?.getAttribute("data-obj-id");
1301
+ const cdItemId = target.closest("[data-cd-item-id]")?.getAttribute("data-cd-item-id");
1302
+ const handlePos = target.dataset?.handle;
1303
+ const tool = activeToolRef.current;
1304
+ if (tool === "select") {
1305
+ if (handlePos === "rotate" && cdItemId) {
1306
+ const item = currentItems.find((it) => it.id === cdItemId);
1307
+ if (item) {
1308
+ const scaledObj = itemObjectToScaled(item);
1309
+ const identity = (v) => v;
1310
+ const center = getObjectCenter(scaledObj, identity, identity);
1311
+ rotateRef.current = {
1312
+ itemId: cdItemId,
1313
+ centerPx: center,
1314
+ startAngle: Math.atan2(y - center.cy, x - center.cx) * (180 / Math.PI),
1315
+ origRotation: item.rotation ?? 0
1316
+ };
1317
+ }
1318
+ return;
1319
+ }
1320
+ if (handlePos && cdItemId) {
1321
+ const item = currentItems.find((it) => it.id === cdItemId);
1322
+ if (item) resizeRef.current = {
1323
+ itemId: cdItemId,
1324
+ handle: handlePos,
1325
+ startPx: {
1326
+ x,
1327
+ y
1328
+ },
1329
+ origItem: {
1330
+ ...item,
1331
+ object: { ...item.object }
1332
+ }
1333
+ };
1334
+ return;
1335
+ }
1336
+ if (cdItemId || objId) {
1337
+ const id = cdItemId ?? objId;
1338
+ onSelectItem(id);
1339
+ const item = currentItems.find((it) => it.id === id);
1340
+ if (item) dragRef.current = {
1341
+ itemId: id,
1342
+ startPx: {
1343
+ x,
1344
+ y
1345
+ },
1346
+ origItem: {
1347
+ ...item,
1348
+ object: { ...item.object }
1349
+ }
1350
+ };
1351
+ return;
1352
+ }
1353
+ onSelectItem(null);
1354
+ return;
1355
+ }
1356
+ const { xPct, yPct } = svgPxToPct(x, y);
1357
+ const newId = uid();
1358
+ drawingRef.current = true;
1359
+ startPctRef.current = {
1360
+ x: xPct,
1361
+ y: yPct
1362
+ };
1363
+ let newObj;
1364
+ const strokeW = defaults.strokeWidth;
1365
+ const sc = defaults.strokeColor;
1366
+ if (tool === "freehand") newObj = {
1367
+ id: newId,
1368
+ type: "freehand",
1369
+ strokeColor: sc,
1370
+ strokeWidth: strokeW,
1371
+ points: [{
1372
+ x: xPct,
1373
+ y: yPct
1374
+ }]
1375
+ };
1376
+ else if (tool === "arrow") newObj = {
1377
+ id: newId,
1378
+ type: "arrow",
1379
+ strokeColor: sc,
1380
+ strokeWidth: strokeW,
1381
+ x1: xPct,
1382
+ y1: yPct,
1383
+ x2: xPct,
1384
+ y2: yPct,
1385
+ arrowheadStyle: defaults.arrowheadStyle
1386
+ };
1387
+ else if (tool === "line") newObj = {
1388
+ id: newId,
1389
+ type: "line",
1390
+ strokeColor: sc,
1391
+ strokeWidth: strokeW,
1392
+ x1: xPct,
1393
+ y1: yPct,
1394
+ x2: xPct,
1395
+ y2: yPct
1396
+ };
1397
+ else if (tool === "rect") newObj = {
1398
+ id: newId,
1399
+ type: "rect",
1400
+ strokeColor: sc,
1401
+ strokeWidth: strokeW,
1402
+ x: xPct,
1403
+ y: yPct,
1404
+ width: 0,
1405
+ height: 0,
1406
+ fillColor: defaults.fillColor,
1407
+ rounded: defaults.rounded
1408
+ };
1409
+ else if (tool === "circle") newObj = {
1410
+ id: newId,
1411
+ type: "circle",
1412
+ strokeColor: sc,
1413
+ strokeWidth: strokeW,
1414
+ x: xPct,
1415
+ y: yPct,
1416
+ width: 0,
1417
+ height: 0,
1418
+ fillColor: defaults.fillColor
1419
+ };
1420
+ else if (tool === "text") {
1421
+ newObj = {
1422
+ id: newId,
1423
+ type: "text",
1424
+ strokeColor: sc,
1425
+ strokeWidth: strokeW,
1426
+ x: xPct,
1427
+ y: yPct,
1428
+ width: .15,
1429
+ height: .06,
1430
+ text: "",
1431
+ fontFamily: defaults.fontFamily,
1432
+ fontSize: defaults.fontSize,
1433
+ fontColor: defaults.fontColor,
1434
+ fillColor: defaults.fillColor,
1435
+ fontBold: defaults.fontBold,
1436
+ fontItalic: defaults.fontItalic,
1437
+ fontUnderline: defaults.fontUnderline
1438
+ };
1439
+ drawingRef.current = false;
1440
+ openInlineTextEditor(newId, newObj, x, y);
1441
+ completeDrawing();
1442
+ return;
1443
+ } else if (tool === "balloon") {
1444
+ newObj = {
1445
+ id: newId,
1446
+ type: "balloon",
1447
+ strokeColor: sc,
1448
+ strokeWidth: strokeW,
1449
+ x: xPct,
1450
+ y: yPct,
1451
+ width: .12,
1452
+ height: .08,
1453
+ text: "",
1454
+ fontFamily: defaults.fontFamily,
1455
+ fontSize: defaults.fontSize,
1456
+ fontColor: defaults.fontColor,
1457
+ fillColor: defaults.fillColor,
1458
+ tailDirection: "down",
1459
+ fontBold: defaults.fontBold,
1460
+ fontItalic: defaults.fontItalic,
1461
+ fontUnderline: defaults.fontUnderline
1462
+ };
1463
+ drawingRef.current = false;
1464
+ openInlineTextEditor(newId, newObj, x, y);
1465
+ completeDrawing();
1466
+ return;
1467
+ } else if (tool === "step") {
1468
+ const maxStep = currentItems.reduce((m, it) => it.object.type === "step" ? Math.max(m, it.object.stepNumber) : m, 0);
1469
+ const stepFill = defaults.fillColor === "transparent" ? "blue" : defaults.fillColor;
1470
+ newObj = {
1471
+ id: newId,
1472
+ type: "step",
1473
+ strokeColor: sc,
1474
+ strokeWidth: strokeW,
1475
+ x: xPct,
1476
+ y: yPct,
1477
+ radius: .02,
1478
+ stepNumber: maxStep + 1,
1479
+ fillColor: stepFill,
1480
+ fontColor: defaults.fontColor
1481
+ };
1482
+ drawingRef.current = false;
1483
+ const stepItem = {
1484
+ id: newId,
1485
+ object: newObj,
1486
+ showAtMs: currentDrawShowAt,
1487
+ hideAtMs: currentDrawHideAt,
1488
+ transition: currentDrawTransition,
1489
+ groupId: currentDrawGroupId,
1490
+ xPct,
1491
+ yPct,
1492
+ wPct: .04,
1493
+ hPct: .04
1494
+ };
1495
+ onItemsChange([...currentItems, stepItem]);
1496
+ onSelectItem(newId);
1497
+ completeDrawing();
1498
+ return;
1499
+ } else if (tool === "highlighter") newObj = {
1500
+ id: newId,
1501
+ type: "highlighter",
1502
+ strokeColor: sc,
1503
+ strokeWidth: strokeW,
1504
+ points: [{
1505
+ x: xPct,
1506
+ y: yPct
1507
+ }]
1508
+ };
1509
+ else if (tool === "callout") {
1510
+ const maxCallout = currentItems.reduce((m, it) => it.object.type === "callout" || it.object.type === "step" ? Math.max(m, it.object.stepNumber) : m, 0);
1511
+ const calloutFill = defaults.fillColor === "transparent" ? "blue" : defaults.fillColor;
1512
+ newObj = {
1513
+ id: newId,
1514
+ type: "callout",
1515
+ strokeColor: sc,
1516
+ strokeWidth: strokeW,
1517
+ x1: xPct,
1518
+ y1: yPct,
1519
+ x2: xPct,
1520
+ y2: yPct,
1521
+ stepNumber: maxCallout + 1,
1522
+ fillColor: calloutFill,
1523
+ fontColor: defaults.fontColor,
1524
+ radius: .06
1525
+ };
1526
+ } else if (tool === "dimension") newObj = {
1527
+ id: newId,
1528
+ type: "dimension",
1529
+ strokeColor: sc,
1530
+ strokeWidth: strokeW,
1531
+ x1: xPct,
1532
+ y1: yPct,
1533
+ x2: xPct,
1534
+ y2: yPct
1535
+ };
1536
+ else if (tool === "curvedArrow") newObj = {
1537
+ id: newId,
1538
+ type: "curvedArrow",
1539
+ strokeColor: sc,
1540
+ strokeWidth: strokeW,
1541
+ x1: xPct,
1542
+ y1: yPct,
1543
+ x2: xPct,
1544
+ y2: yPct,
1545
+ cpx: xPct,
1546
+ cpy: yPct
1547
+ };
1548
+ else return;
1549
+ const newItem = {
1550
+ id: newId,
1551
+ object: newObj,
1552
+ showAtMs: currentDrawShowAt,
1553
+ hideAtMs: currentDrawHideAt,
1554
+ transition: currentDrawTransition,
1555
+ groupId: currentDrawGroupId,
1556
+ xPct,
1557
+ yPct,
1558
+ wPct: 0,
1559
+ hPct: 0
1560
+ };
1561
+ currentObjRef.current = newItem;
1562
+ onItemsChange([...currentItems, newItem]);
1563
+ onSelectItem(newId);
1564
+ }, [
1565
+ isEditing,
1566
+ defaults,
1567
+ currentDrawShowAt,
1568
+ currentDrawHideAt,
1569
+ currentDrawTransition,
1570
+ currentDrawGroupId,
1571
+ svgPxToPct,
1572
+ eventToSvgPx,
1573
+ onItemsChange,
1574
+ onSelectItem,
1575
+ openInlineTextEditor,
1576
+ completeDrawing,
1577
+ itemObjectToScaled
1578
+ ]);
1579
+ const onMouseMove = useCallback((e) => {
1580
+ if (!isEditing) return;
1581
+ const pos = eventToSvgPx(e);
1582
+ if (!pos) return;
1583
+ const b = boundsRef.current;
1584
+ if (!b) return;
1585
+ const { x, y } = pos;
1586
+ const currentItems = itemsRef.current;
1587
+ if (rotateRef.current) {
1588
+ const { itemId, centerPx, startAngle, origRotation } = rotateRef.current;
1589
+ let delta = Math.atan2(y - centerPx.cy, x - centerPx.cx) * (180 / Math.PI) - startAngle;
1590
+ if (e.shiftKey) delta = Math.round(delta / 15) * 15;
1591
+ const newRotation = origRotation + delta;
1592
+ onItemsChange(currentItems.map((it) => it.id === itemId ? {
1593
+ ...it,
1594
+ rotation: newRotation
1595
+ } : it));
1596
+ return;
1597
+ }
1598
+ if (resizeRef.current) {
1599
+ const { itemId, handle, startPx, origItem } = resizeRef.current;
1600
+ const dx = x - startPx.x;
1601
+ const dy = y - startPx.y;
1602
+ const updated = applyResize(origItem, handle, dx / b.w, dy / b.h);
1603
+ onItemsChange(currentItems.map((it) => it.id === itemId ? updated : it));
1604
+ return;
1605
+ }
1606
+ if (dragRef.current) {
1607
+ const { itemId, startPx, origItem } = dragRef.current;
1608
+ const updated = applyDrag(origItem, (x - startPx.x) / b.w, (y - startPx.y) / b.h);
1609
+ onItemsChange(currentItems.map((it) => it.id === itemId ? updated : it));
1610
+ return;
1611
+ }
1612
+ if (!drawingRef.current || !currentObjRef.current) return;
1613
+ const { x: sx2, y: sy2 } = startPctRef.current;
1614
+ const { xPct, yPct } = svgPxToPct(x, y);
1615
+ const item = currentObjRef.current;
1616
+ let updatedItem;
1617
+ if (item.object.type === "freehand") {
1618
+ const pts = [...item.object.points, {
1619
+ x: xPct,
1620
+ y: yPct
1621
+ }];
1622
+ updatedItem = {
1623
+ ...item,
1624
+ object: {
1625
+ ...item.object,
1626
+ points: pts
1627
+ },
1628
+ wPct: null,
1629
+ hPct: null
1630
+ };
1631
+ } else if (item.object.type === "highlighter") {
1632
+ const pts = [...item.object.points, {
1633
+ x: xPct,
1634
+ y: yPct
1635
+ }];
1636
+ updatedItem = {
1637
+ ...item,
1638
+ object: {
1639
+ ...item.object,
1640
+ points: pts
1641
+ },
1642
+ wPct: null,
1643
+ hPct: null
1644
+ };
1645
+ } else if (item.object.type === "arrow" || item.object.type === "line" || item.object.type === "dimension") updatedItem = {
1646
+ ...item,
1647
+ object: {
1648
+ ...item.object,
1649
+ x2: xPct,
1650
+ y2: yPct
1651
+ },
1652
+ wPct: xPct - sx2,
1653
+ hPct: yPct - sy2
1654
+ };
1655
+ else if (item.object.type === "callout") updatedItem = {
1656
+ ...item,
1657
+ object: {
1658
+ ...item.object,
1659
+ x2: xPct,
1660
+ y2: yPct
1661
+ }
1662
+ };
1663
+ else if (item.object.type === "curvedArrow") {
1664
+ const midX = (sx2 + xPct) / 2;
1665
+ const midY = (sy2 + yPct) / 2;
1666
+ const dx2 = xPct - sx2;
1667
+ const cpx2 = midX - (yPct - sy2) * .3;
1668
+ const cpy2 = midY + dx2 * .3;
1669
+ updatedItem = {
1670
+ ...item,
1671
+ object: {
1672
+ ...item.object,
1673
+ x2: xPct,
1674
+ y2: yPct,
1675
+ cpx: cpx2,
1676
+ cpy: cpy2
1677
+ },
1678
+ wPct: xPct - sx2,
1679
+ hPct: yPct - sy2
1680
+ };
1681
+ } else if (item.object.type === "rect" || item.object.type === "circle" || item.object.type === "text" || item.object.type === "balloon") {
1682
+ const minX = Math.min(sx2, xPct);
1683
+ const minY = Math.min(sy2, yPct);
1684
+ const w = Math.abs(xPct - sx2);
1685
+ const h = Math.abs(yPct - sy2);
1686
+ updatedItem = {
1687
+ ...item,
1688
+ xPct: minX,
1689
+ yPct: minY,
1690
+ object: {
1691
+ ...item.object,
1692
+ x: minX,
1693
+ y: minY,
1694
+ width: w,
1695
+ height: h
1696
+ },
1697
+ wPct: w,
1698
+ hPct: h
1699
+ };
1700
+ } else updatedItem = item;
1701
+ currentObjRef.current = updatedItem;
1702
+ onItemsChange(currentItems.map((it) => it.id === item.id ? updatedItem : it));
1703
+ }, [
1704
+ isEditing,
1705
+ svgPxToPct,
1706
+ eventToSvgPx,
1707
+ onItemsChange
1708
+ ]);
1709
+ const onMouseUp = useCallback(() => {
1710
+ if (!isEditing) return;
1711
+ const wasDrawing = drawingRef.current;
1712
+ const drawnItemId = currentObjRef.current?.id ?? null;
1713
+ const hadInteraction = wasDrawing || dragRef.current !== null || resizeRef.current !== null || rotateRef.current !== null;
1714
+ drawingRef.current = false;
1715
+ currentObjRef.current = null;
1716
+ dragRef.current = null;
1717
+ resizeRef.current = null;
1718
+ rotateRef.current = null;
1719
+ if (hadInteraction) onItemsCommit();
1720
+ if (wasDrawing) {
1721
+ if (drawnItemId) onSelectItem(drawnItemId);
1722
+ completeDrawing();
1723
+ }
1724
+ }, [
1725
+ isEditing,
1726
+ onItemsCommit,
1727
+ completeDrawing,
1728
+ onSelectItem
1729
+ ]);
1730
+ const cursor = isEditing ? activeToolRef.current === "select" ? "default" : "crosshair" : "default";
1731
+ return /* @__PURE__ */ jsx("svg", {
1732
+ ref: svgRef,
1733
+ style: {
1734
+ position: "absolute",
1735
+ left: 0,
1736
+ top: 0,
1737
+ overflow: "visible",
1738
+ pointerEvents: isEditing ? "all" : "none",
1739
+ cursor,
1740
+ userSelect: "none",
1741
+ zIndex: 10
1742
+ },
1743
+ onMouseDown,
1744
+ onMouseMove,
1745
+ onMouseUp,
1746
+ onMouseLeave: onMouseUp,
1747
+ onDoubleClick
1748
+ });
1749
+ });
1750
+ //#endregion
1751
+ //#region src/components/canvas-draw/CanvasDrawToolbar.tsx
1752
+ var allTools = [
1753
+ {
1754
+ id: "select",
1755
+ label: "Select",
1756
+ icon: "↖"
1757
+ },
1758
+ {
1759
+ id: "arrow",
1760
+ label: "Arrow",
1761
+ icon: "→"
1762
+ },
1763
+ {
1764
+ id: "curvedArrow",
1765
+ label: "Curved Arrow",
1766
+ icon: "↝"
1767
+ },
1768
+ {
1769
+ id: "line",
1770
+ label: "Line",
1771
+ icon: "╱"
1772
+ },
1773
+ {
1774
+ id: "dimension",
1775
+ label: "Dimension",
1776
+ icon: "⟷"
1777
+ },
1778
+ {
1779
+ id: "rect",
1780
+ label: "Rectangle",
1781
+ icon: "▭"
1782
+ },
1783
+ {
1784
+ id: "circle",
1785
+ label: "Ellipse",
1786
+ icon: "◯"
1787
+ },
1788
+ {
1789
+ id: "freehand",
1790
+ label: "Freehand",
1791
+ icon: "✏"
1792
+ },
1793
+ {
1794
+ id: "highlighter",
1795
+ label: "Highlighter",
1796
+ icon: "🖍"
1797
+ },
1798
+ {
1799
+ id: "text",
1800
+ label: "Text",
1801
+ icon: "T"
1802
+ },
1803
+ {
1804
+ id: "balloon",
1805
+ label: "Balloon",
1806
+ icon: "💬"
1807
+ },
1808
+ {
1809
+ id: "step",
1810
+ label: "Step",
1811
+ icon: "①"
1812
+ },
1813
+ {
1814
+ id: "callout",
1815
+ label: "Callout",
1816
+ icon: "❶"
1817
+ }
1818
+ ];
1819
+ var strokeWidthOptions = [
1820
+ 1,
1821
+ 2,
1822
+ 3,
1823
+ 5,
1824
+ 8
1825
+ ];
1826
+ var fontSizeOptions = [
1827
+ 10,
1828
+ 12,
1829
+ 14,
1830
+ 16,
1831
+ 20,
1832
+ 24,
1833
+ 32
1834
+ ];
1835
+ var fontFamilyOptions = [
1836
+ {
1837
+ id: "sans-serif",
1838
+ label: "Sans"
1839
+ },
1840
+ {
1841
+ id: "serif",
1842
+ label: "Serif"
1843
+ },
1844
+ {
1845
+ id: "monospace",
1846
+ label: "Mono"
1847
+ },
1848
+ {
1849
+ id: "cursive",
1850
+ label: "Cursive"
1851
+ }
1852
+ ];
1853
+ var allColors = [
1854
+ "red",
1855
+ "orange",
1856
+ "yellow",
1857
+ "green",
1858
+ "teal",
1859
+ "blue",
1860
+ "purple",
1861
+ "black",
1862
+ "white"
1863
+ ];
1864
+ var transitionOptions$1 = [
1865
+ {
1866
+ id: "none",
1867
+ label: "None"
1868
+ },
1869
+ {
1870
+ id: "fade",
1871
+ label: "Fade"
1872
+ },
1873
+ {
1874
+ id: "scale",
1875
+ label: "Scale"
1876
+ },
1877
+ {
1878
+ id: "slide-up",
1879
+ label: "Slide Up"
1880
+ },
1881
+ {
1882
+ id: "slide-down",
1883
+ label: "Slide Down"
1884
+ },
1885
+ {
1886
+ id: "slide-left",
1887
+ label: "Slide Left"
1888
+ },
1889
+ {
1890
+ id: "slide-right",
1891
+ label: "Slide Right"
1892
+ }
1893
+ ];
1894
+ var textToolSet = new Set(["text", "balloon"]);
1895
+ var fillToolSet = new Set([
1896
+ "rect",
1897
+ "circle",
1898
+ "balloon",
1899
+ "step",
1900
+ "callout",
1901
+ "text"
1902
+ ]);
1903
+ var strokeToolSet = new Set([
1904
+ "arrow",
1905
+ "line",
1906
+ "rect",
1907
+ "circle",
1908
+ "freehand",
1909
+ "highlighter",
1910
+ "dimension",
1911
+ "curvedArrow",
1912
+ "balloon",
1913
+ "step",
1914
+ "callout"
1915
+ ]);
1916
+ function hasTextProps(obj) {
1917
+ return obj.type === "text" || obj.type === "balloon";
1918
+ }
1919
+ function hasFillProp(obj) {
1920
+ return obj.type === "rect" || obj.type === "circle" || obj.type === "balloon" || obj.type === "step" || obj.type === "callout" || obj.type === "text";
1921
+ }
1922
+ function formatTime$1(ms) {
1923
+ const s = Math.floor(ms / 1e3);
1924
+ const m = Math.floor(s / 60);
1925
+ const sec = s % 60;
1926
+ const milli = ms % 1e3;
1927
+ return `${m}:${sec.toString().padStart(2, "0")}.${Math.floor(milli / 100)}`;
1928
+ }
1929
+ function parseMsInput(val) {
1930
+ const trimmed = val.trim();
1931
+ const parts = trimmed.split(":");
1932
+ if (parts.length === 2) {
1933
+ const mins = parseInt(parts[0], 10);
1934
+ const secParts = parts[1].split(".");
1935
+ const secs = parseInt(secParts[0], 10);
1936
+ const frac = secParts[1] ? parseInt(secParts[1].padEnd(3, "0").slice(0, 3), 10) : 0;
1937
+ if (!isNaN(mins) && !isNaN(secs)) return (mins * 60 + secs) * 1e3 + frac;
1938
+ }
1939
+ const n = parseFloat(trimmed);
1940
+ if (!isNaN(n)) return Math.round(n * 1e3);
1941
+ return null;
1942
+ }
1943
+ function resolveToolConfig(config) {
1944
+ if (!config) return new Set(allTools.map((t) => t.id));
1945
+ const enabled = /* @__PURE__ */ new Set();
1946
+ for (const tool of allTools) {
1947
+ const val = config[tool.id];
1948
+ if (val === void 0 || val === true) enabled.add(tool.id);
1949
+ }
1950
+ return enabled;
1951
+ }
1952
+ function CanvasDrawToolbar({ activeTool, defaults, mediaDurationMs, showAtMs, hideAtMs, transition, selectedItem, groups, features, onToolChange, onDefaultsChange, onShowAtChange, onHideAtChange, onTransitionChange, onDeleteSelected, onDuplicateSelected, onUndo, onRedo, onClearAll, onSetCurrentAsShowAt, onSetCurrentAsHideAt, onUpdateSelectedTiming, onAssignGroup, onUpdateStepNumber, canUndo, canRedo, onExport }) {
1953
+ const [showAtInput, setShowAtInput] = useState("");
1954
+ const [hideAtInput, setHideAtInput] = useState("");
1955
+ const [editingShowAt, setEditingShowAt] = useState(false);
1956
+ const [editingHideAt, setEditingHideAt] = useState(false);
1957
+ const enabledTools = resolveToolConfig(features.tools);
1958
+ const visibleTools = allTools.filter((t) => enabledTools.has(t.id));
1959
+ const setColor = (c) => onDefaultsChange({
1960
+ ...defaults,
1961
+ strokeColor: c
1962
+ });
1963
+ const setFill = (c) => onDefaultsChange({
1964
+ ...defaults,
1965
+ fillColor: c
1966
+ });
1967
+ const setWidth = (w) => onDefaultsChange({
1968
+ ...defaults,
1969
+ strokeWidth: w
1970
+ });
1971
+ const setFontSize = (s) => onDefaultsChange({
1972
+ ...defaults,
1973
+ fontSize: s
1974
+ });
1975
+ const setFontColor = (c) => onDefaultsChange({
1976
+ ...defaults,
1977
+ fontColor: c
1978
+ });
1979
+ const setFontFamily = (f) => onDefaultsChange({
1980
+ ...defaults,
1981
+ fontFamily: f
1982
+ });
1983
+ const toggleBold = () => onDefaultsChange({
1984
+ ...defaults,
1985
+ fontBold: !defaults.fontBold
1986
+ });
1987
+ const toggleItalic = () => onDefaultsChange({
1988
+ ...defaults,
1989
+ fontItalic: !defaults.fontItalic
1990
+ });
1991
+ const toggleUnderline = () => onDefaultsChange({
1992
+ ...defaults,
1993
+ fontUnderline: !defaults.fontUnderline
1994
+ });
1995
+ const toggleRounded = () => onDefaultsChange({
1996
+ ...defaults,
1997
+ rounded: !defaults.rounded
1998
+ });
1999
+ const handleShowAtCommit = () => {
2000
+ const ms = parseMsInput(showAtInput);
2001
+ if (ms !== null) {
2002
+ const clamped = Math.max(0, Math.min(ms, mediaDurationMs));
2003
+ onShowAtChange(clamped);
2004
+ if (selectedItem) onUpdateSelectedTiming(clamped, selectedItem.hideAtMs, selectedItem.transition);
2005
+ }
2006
+ setEditingShowAt(false);
2007
+ };
2008
+ const handleHideAtCommit = () => {
2009
+ if (hideAtInput.trim() === "" || hideAtInput.trim() === "—") {
2010
+ onHideAtChange(null);
2011
+ if (selectedItem) onUpdateSelectedTiming(selectedItem.showAtMs, null, selectedItem.transition);
2012
+ } else {
2013
+ const ms = parseMsInput(hideAtInput);
2014
+ if (ms !== null) {
2015
+ const clamped = Math.max(0, Math.min(ms, mediaDurationMs));
2016
+ onHideAtChange(clamped);
2017
+ if (selectedItem) onUpdateSelectedTiming(selectedItem.showAtMs, clamped, selectedItem.transition);
2018
+ }
2019
+ }
2020
+ setEditingHideAt(false);
2021
+ };
2022
+ const handleTransitionChange = (t) => {
2023
+ onTransitionChange(t);
2024
+ if (selectedItem) onUpdateSelectedTiming(selectedItem.showAtMs, selectedItem.hideAtMs, t);
2025
+ };
2026
+ const effectiveShowAt = selectedItem ? selectedItem.showAtMs : showAtMs;
2027
+ const effectiveHideAt = selectedItem ? selectedItem.hideAtMs : hideAtMs;
2028
+ const effectiveTransition = selectedItem ? selectedItem.transition : transition;
2029
+ const showStrokeSection = features.strokeColor !== false && (selectedItem != null ? selectedItem.object.type !== "text" : strokeToolSet.has(activeTool) || activeTool === "select");
2030
+ const showStrokeWidthSection = features.strokeWidth !== false && (selectedItem != null ? selectedItem.object.type !== "text" : strokeToolSet.has(activeTool) || activeTool === "select");
2031
+ const showFontSection = features.fontControls !== false && (textToolSet.has(activeTool) || selectedItem != null && hasTextProps(selectedItem.object));
2032
+ const showFillSection = features.fillColor !== false && (fillToolSet.has(activeTool) || selectedItem != null && hasFillProp(selectedItem.object));
2033
+ const showRounded = features.roundedCorners !== false && (activeTool === "rect" || selectedItem != null && selectedItem.object.type === "rect");
2034
+ const showStepNumber = selectedItem != null && (selectedItem.object.type === "step" || selectedItem.object.type === "callout");
2035
+ const showTiming = features.timing !== false;
2036
+ const showTransitions = features.transitions !== false;
2037
+ const showGroups = features.groups !== false && selectedItem != null && groups.length > 0;
2038
+ const showUndo = features.undo !== false;
2039
+ const showExport = features.export !== false;
2040
+ const showClear = features.clearAll !== false;
2041
+ return /* @__PURE__ */ jsxs("div", {
2042
+ className: "eui-canvas-draw-toolbar",
2043
+ children: [
2044
+ /* @__PURE__ */ jsx("div", {
2045
+ className: "eui-cdt-section eui-cdt-section--tools",
2046
+ children: visibleTools.map((t) => /* @__PURE__ */ jsx("button", {
2047
+ className: (0, import_classnames.default)("eui-cdt-tool", { "eui-cdt-tool--active": activeTool === t.id }),
2048
+ title: t.label,
2049
+ onClick: () => onToolChange(t.id),
2050
+ "aria-pressed": activeTool === t.id,
2051
+ "aria-label": t.label,
2052
+ children: t.icon
2053
+ }, t.id))
2054
+ }),
2055
+ /* @__PURE__ */ jsx("div", { className: "eui-cdt-divider" }),
2056
+ showStrokeSection && /* @__PURE__ */ jsxs("div", {
2057
+ className: "eui-cdt-section",
2058
+ children: [/* @__PURE__ */ jsx("span", {
2059
+ className: "eui-cdt-label",
2060
+ children: "Color"
2061
+ }), /* @__PURE__ */ jsx("div", {
2062
+ className: "eui-cdt-colors",
2063
+ children: allColors.map((c) => /* @__PURE__ */ jsx("button", {
2064
+ className: (0, import_classnames.default)("eui-cdt-color", {
2065
+ "eui-cdt-color--active": defaults.strokeColor === c,
2066
+ "eui-cdt-color--white": c === "white"
2067
+ }),
2068
+ style: { background: colorMap[c] },
2069
+ title: c,
2070
+ "aria-label": `Stroke: ${c}`,
2071
+ "aria-pressed": defaults.strokeColor === c,
2072
+ onClick: () => setColor(c)
2073
+ }, c))
2074
+ })]
2075
+ }),
2076
+ (showStrokeWidthSection || showRounded) && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", { className: "eui-cdt-divider" }), /* @__PURE__ */ jsxs("div", {
2077
+ className: "eui-cdt-section",
2078
+ children: [
2079
+ /* @__PURE__ */ jsx("span", {
2080
+ className: "eui-cdt-label",
2081
+ children: "Stroke"
2082
+ }),
2083
+ showStrokeWidthSection && /* @__PURE__ */ jsx("div", {
2084
+ className: "eui-cdt-widths",
2085
+ children: strokeWidthOptions.map((w) => /* @__PURE__ */ jsx("button", {
2086
+ className: (0, import_classnames.default)("eui-cdt-width", { "eui-cdt-width--active": defaults.strokeWidth === w }),
2087
+ title: `${w}px`,
2088
+ "aria-pressed": defaults.strokeWidth === w,
2089
+ onClick: () => setWidth(w),
2090
+ children: /* @__PURE__ */ jsx("span", { style: {
2091
+ display: "block",
2092
+ height: Math.max(w, 1),
2093
+ background: "currentColor",
2094
+ borderRadius: 2,
2095
+ width: "100%"
2096
+ } })
2097
+ }, w))
2098
+ }),
2099
+ showRounded && /* @__PURE__ */ jsxs("button", {
2100
+ className: (0, import_classnames.default)("eui-cdt-rounded-toggle", { "eui-cdt-rounded-toggle--active": defaults.rounded }),
2101
+ title: "Rounded corners",
2102
+ "aria-pressed": defaults.rounded,
2103
+ onClick: toggleRounded,
2104
+ children: [/* @__PURE__ */ jsx("span", { children: "◰" }), /* @__PURE__ */ jsx("span", { children: "Rounded" })]
2105
+ })
2106
+ ]
2107
+ })] }),
2108
+ showFillSection && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", { className: "eui-cdt-divider" }), /* @__PURE__ */ jsxs("div", {
2109
+ className: "eui-cdt-section",
2110
+ children: [
2111
+ /* @__PURE__ */ jsx("span", {
2112
+ className: "eui-cdt-label",
2113
+ children: "Fill"
2114
+ }),
2115
+ /* @__PURE__ */ jsxs("button", {
2116
+ className: (0, import_classnames.default)("eui-cdt-fill-none", { "eui-cdt-fill-none--active": defaults.fillColor === "transparent" }),
2117
+ title: "Transparent",
2118
+ "aria-label": "Fill: transparent",
2119
+ "aria-pressed": defaults.fillColor === "transparent",
2120
+ onClick: () => setFill("transparent"),
2121
+ children: [/* @__PURE__ */ jsx("span", {
2122
+ className: "eui-cdt-fill-none-icon",
2123
+ children: "∅"
2124
+ }), /* @__PURE__ */ jsx("span", { children: "No fill" })]
2125
+ }),
2126
+ /* @__PURE__ */ jsx("div", {
2127
+ className: "eui-cdt-colors",
2128
+ children: allColors.map((c) => /* @__PURE__ */ jsx("button", {
2129
+ className: (0, import_classnames.default)("eui-cdt-color", {
2130
+ "eui-cdt-color--active": defaults.fillColor === c,
2131
+ "eui-cdt-color--white": c === "white"
2132
+ }),
2133
+ style: { background: colorMap[c] },
2134
+ title: c,
2135
+ "aria-label": `Fill: ${c}`,
2136
+ "aria-pressed": defaults.fillColor === c,
2137
+ onClick: () => setFill(c)
2138
+ }, c))
2139
+ })
2140
+ ]
2141
+ })] }),
2142
+ showStepNumber && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", { className: "eui-cdt-divider" }), /* @__PURE__ */ jsxs("div", {
2143
+ className: "eui-cdt-section",
2144
+ children: [/* @__PURE__ */ jsx("span", {
2145
+ className: "eui-cdt-label",
2146
+ children: "Number"
2147
+ }), /* @__PURE__ */ jsxs("div", {
2148
+ className: "eui-cdt-step-number",
2149
+ children: [
2150
+ /* @__PURE__ */ jsx("button", {
2151
+ className: "eui-cdt-step-number-btn",
2152
+ onClick: () => {
2153
+ const obj = selectedItem.object;
2154
+ if ("stepNumber" in obj) onUpdateStepNumber?.(Math.max(1, obj.stepNumber - 1));
2155
+ },
2156
+ "aria-label": "Decrease step number",
2157
+ children: "−"
2158
+ }),
2159
+ /* @__PURE__ */ jsx("input", {
2160
+ className: "eui-cdt-step-number-input",
2161
+ type: "number",
2162
+ min: 1,
2163
+ value: "stepNumber" in selectedItem.object ? selectedItem.object.stepNumber : 1,
2164
+ onChange: (e) => {
2165
+ const val = parseInt(e.target.value, 10);
2166
+ if (!isNaN(val) && val >= 1) onUpdateStepNumber?.(val);
2167
+ },
2168
+ "aria-label": "Step number"
2169
+ }),
2170
+ /* @__PURE__ */ jsx("button", {
2171
+ className: "eui-cdt-step-number-btn",
2172
+ onClick: () => {
2173
+ const obj = selectedItem.object;
2174
+ if ("stepNumber" in obj) onUpdateStepNumber?.(obj.stepNumber + 1);
2175
+ },
2176
+ "aria-label": "Increase step number",
2177
+ children: "+"
2178
+ })
2179
+ ]
2180
+ })]
2181
+ })] }),
2182
+ showFontSection && /* @__PURE__ */ jsxs(Fragment, { children: [
2183
+ /* @__PURE__ */ jsx("div", { className: "eui-cdt-divider" }),
2184
+ /* @__PURE__ */ jsxs("div", {
2185
+ className: "eui-cdt-section",
2186
+ children: [
2187
+ /* @__PURE__ */ jsx("span", {
2188
+ className: "eui-cdt-label",
2189
+ children: "Font"
2190
+ }),
2191
+ /* @__PURE__ */ jsxs("div", {
2192
+ className: "eui-cdt-font-selects",
2193
+ children: [/* @__PURE__ */ jsx("select", {
2194
+ className: "eui-cdt-select",
2195
+ value: defaults.fontFamily,
2196
+ onChange: (e) => setFontFamily(e.target.value),
2197
+ title: "Font family",
2198
+ "aria-label": "Font family",
2199
+ children: fontFamilyOptions.map((f) => /* @__PURE__ */ jsx("option", {
2200
+ value: f.id,
2201
+ children: f.label
2202
+ }, f.id))
2203
+ }), /* @__PURE__ */ jsx("select", {
2204
+ className: "eui-cdt-select",
2205
+ value: defaults.fontSize,
2206
+ onChange: (e) => setFontSize(Number(e.target.value)),
2207
+ title: "Font size",
2208
+ "aria-label": "Font size",
2209
+ children: fontSizeOptions.map((s) => /* @__PURE__ */ jsxs("option", {
2210
+ value: s,
2211
+ children: [s, "px"]
2212
+ }, s))
2213
+ })]
2214
+ }),
2215
+ /* @__PURE__ */ jsxs("div", {
2216
+ className: "eui-cdt-biu",
2217
+ children: [
2218
+ /* @__PURE__ */ jsx("button", {
2219
+ className: (0, import_classnames.default)("eui-cdt-biu-btn", { "eui-cdt-biu-btn--active": defaults.fontBold }),
2220
+ title: "Bold",
2221
+ "aria-pressed": defaults.fontBold,
2222
+ onClick: toggleBold,
2223
+ children: /* @__PURE__ */ jsx("strong", { children: "B" })
2224
+ }),
2225
+ /* @__PURE__ */ jsx("button", {
2226
+ className: (0, import_classnames.default)("eui-cdt-biu-btn", { "eui-cdt-biu-btn--active": defaults.fontItalic }),
2227
+ title: "Italic",
2228
+ "aria-pressed": defaults.fontItalic,
2229
+ onClick: toggleItalic,
2230
+ children: /* @__PURE__ */ jsx("em", { children: "I" })
2231
+ }),
2232
+ /* @__PURE__ */ jsx("button", {
2233
+ className: (0, import_classnames.default)("eui-cdt-biu-btn", { "eui-cdt-biu-btn--active": defaults.fontUnderline }),
2234
+ title: "Underline",
2235
+ "aria-pressed": defaults.fontUnderline,
2236
+ onClick: toggleUnderline,
2237
+ children: /* @__PURE__ */ jsx("span", {
2238
+ style: { textDecoration: "underline" },
2239
+ children: "U"
2240
+ })
2241
+ })
2242
+ ]
2243
+ })
2244
+ ]
2245
+ }),
2246
+ /* @__PURE__ */ jsx("div", { className: "eui-cdt-divider" }),
2247
+ /* @__PURE__ */ jsxs("div", {
2248
+ className: "eui-cdt-section",
2249
+ children: [/* @__PURE__ */ jsx("span", {
2250
+ className: "eui-cdt-label",
2251
+ children: "Font Color"
2252
+ }), /* @__PURE__ */ jsx("div", {
2253
+ className: "eui-cdt-colors",
2254
+ children: allColors.map((c) => /* @__PURE__ */ jsx("button", {
2255
+ className: (0, import_classnames.default)("eui-cdt-color", {
2256
+ "eui-cdt-color--active": defaults.fontColor === c,
2257
+ "eui-cdt-color--white": c === "white"
2258
+ }),
2259
+ style: { background: colorMap[c] },
2260
+ title: `Font: ${c}`,
2261
+ "aria-label": `Font color: ${c}`,
2262
+ "aria-pressed": defaults.fontColor === c,
2263
+ onClick: () => setFontColor(c)
2264
+ }, c))
2265
+ })]
2266
+ })
2267
+ ] }),
2268
+ showTiming && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", { className: "eui-cdt-divider" }), /* @__PURE__ */ jsxs("div", {
2269
+ className: "eui-cdt-section eui-cdt-section--timing",
2270
+ children: [
2271
+ /* @__PURE__ */ jsx("span", {
2272
+ className: "eui-cdt-label",
2273
+ children: "Timing"
2274
+ }),
2275
+ /* @__PURE__ */ jsxs("div", {
2276
+ className: "eui-cdt-timing-row",
2277
+ children: [
2278
+ /* @__PURE__ */ jsx("span", {
2279
+ className: "eui-cdt-timing-label",
2280
+ children: "Show at"
2281
+ }),
2282
+ editingShowAt ? /* @__PURE__ */ jsx("input", {
2283
+ className: "eui-cdt-timing-input",
2284
+ value: showAtInput,
2285
+ autoFocus: true,
2286
+ onChange: (e) => setShowAtInput(e.target.value),
2287
+ onBlur: handleShowAtCommit,
2288
+ onKeyDown: (e) => {
2289
+ if (e.key === "Enter") handleShowAtCommit();
2290
+ if (e.key === "Escape") setEditingShowAt(false);
2291
+ },
2292
+ placeholder: "0:00.0",
2293
+ "aria-label": "Show at time"
2294
+ }) : /* @__PURE__ */ jsx("button", {
2295
+ className: "eui-cdt-timing-val",
2296
+ onClick: () => {
2297
+ setShowAtInput(formatTime$1(effectiveShowAt));
2298
+ setEditingShowAt(true);
2299
+ },
2300
+ "aria-label": `Show at ${formatTime$1(effectiveShowAt)}`,
2301
+ children: formatTime$1(effectiveShowAt)
2302
+ }),
2303
+ /* @__PURE__ */ jsx("button", {
2304
+ className: "eui-cdt-timing-now",
2305
+ title: "Set to current time",
2306
+ "aria-label": "Set show time to current",
2307
+ onClick: onSetCurrentAsShowAt,
2308
+ children: "▸"
2309
+ })
2310
+ ]
2311
+ }),
2312
+ /* @__PURE__ */ jsxs("div", {
2313
+ className: "eui-cdt-timing-row",
2314
+ children: [
2315
+ /* @__PURE__ */ jsx("span", {
2316
+ className: "eui-cdt-timing-label",
2317
+ children: "Hide at"
2318
+ }),
2319
+ editingHideAt ? /* @__PURE__ */ jsx("input", {
2320
+ className: "eui-cdt-timing-input",
2321
+ value: hideAtInput,
2322
+ autoFocus: true,
2323
+ onChange: (e) => setHideAtInput(e.target.value),
2324
+ onBlur: handleHideAtCommit,
2325
+ onKeyDown: (e) => {
2326
+ if (e.key === "Enter") handleHideAtCommit();
2327
+ if (e.key === "Escape") setEditingHideAt(false);
2328
+ },
2329
+ placeholder: "never",
2330
+ "aria-label": "Hide at time"
2331
+ }) : /* @__PURE__ */ jsx("button", {
2332
+ className: "eui-cdt-timing-val",
2333
+ onClick: () => {
2334
+ setHideAtInput(effectiveHideAt !== null ? formatTime$1(effectiveHideAt) : "");
2335
+ setEditingHideAt(true);
2336
+ },
2337
+ "aria-label": effectiveHideAt !== null ? `Hide at ${formatTime$1(effectiveHideAt)}` : "No hide time set",
2338
+ children: effectiveHideAt !== null ? formatTime$1(effectiveHideAt) : "—"
2339
+ }),
2340
+ /* @__PURE__ */ jsx("button", {
2341
+ className: "eui-cdt-timing-now",
2342
+ title: "Set to current time",
2343
+ "aria-label": "Set hide time to current",
2344
+ onClick: onSetCurrentAsHideAt,
2345
+ children: "▸"
2346
+ })
2347
+ ]
2348
+ }),
2349
+ showTransitions && /* @__PURE__ */ jsxs("div", {
2350
+ className: "eui-cdt-timing-row",
2351
+ children: [/* @__PURE__ */ jsx("span", {
2352
+ className: "eui-cdt-timing-label",
2353
+ children: "Transition"
2354
+ }), /* @__PURE__ */ jsx("select", {
2355
+ className: "eui-cdt-select",
2356
+ value: effectiveTransition,
2357
+ onChange: (e) => handleTransitionChange(e.target.value),
2358
+ "aria-label": "Transition type",
2359
+ children: transitionOptions$1.map((t) => /* @__PURE__ */ jsx("option", {
2360
+ value: t.id,
2361
+ children: t.label
2362
+ }, t.id))
2363
+ })]
2364
+ })
2365
+ ]
2366
+ })] }),
2367
+ showGroups && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", { className: "eui-cdt-divider" }), /* @__PURE__ */ jsxs("div", {
2368
+ className: "eui-cdt-section eui-cdt-section--timing",
2369
+ children: [/* @__PURE__ */ jsx("span", {
2370
+ className: "eui-cdt-label",
2371
+ children: "Group"
2372
+ }), /* @__PURE__ */ jsxs("select", {
2373
+ className: "eui-cdt-select",
2374
+ value: selectedItem.groupId ?? "",
2375
+ onChange: (e) => onAssignGroup(e.target.value || null),
2376
+ "aria-label": "Assign group",
2377
+ children: [/* @__PURE__ */ jsx("option", {
2378
+ value: "",
2379
+ children: "No group"
2380
+ }), groups.map((g) => /* @__PURE__ */ jsx("option", {
2381
+ value: g.id,
2382
+ children: g.label
2383
+ }, g.id))]
2384
+ })]
2385
+ })] }),
2386
+ /* @__PURE__ */ jsx("div", { className: "eui-cdt-divider" }),
2387
+ /* @__PURE__ */ jsxs("div", {
2388
+ className: "eui-cdt-section eui-cdt-section--actions",
2389
+ children: [
2390
+ showUndo && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("button", {
2391
+ className: "eui-cdt-action",
2392
+ title: "Undo (Ctrl+Z)",
2393
+ "aria-label": "Undo",
2394
+ onClick: onUndo,
2395
+ disabled: !canUndo,
2396
+ children: "↩"
2397
+ }), /* @__PURE__ */ jsx("button", {
2398
+ className: "eui-cdt-action",
2399
+ title: "Redo (Ctrl+Y)",
2400
+ "aria-label": "Redo",
2401
+ onClick: onRedo,
2402
+ disabled: !canRedo,
2403
+ children: "↪"
2404
+ })] }),
2405
+ /* @__PURE__ */ jsx("button", {
2406
+ className: "eui-cdt-action",
2407
+ title: "Duplicate selected",
2408
+ "aria-label": "Duplicate selected",
2409
+ onClick: onDuplicateSelected,
2410
+ disabled: !selectedItem,
2411
+ children: "⧉"
2412
+ }),
2413
+ /* @__PURE__ */ jsx("button", {
2414
+ className: "eui-cdt-action eui-cdt-action--danger",
2415
+ title: "Delete selected (Del)",
2416
+ "aria-label": "Delete selected",
2417
+ onClick: onDeleteSelected,
2418
+ disabled: !selectedItem,
2419
+ children: "✕"
2420
+ }),
2421
+ showClear && /* @__PURE__ */ jsx("button", {
2422
+ className: "eui-cdt-action eui-cdt-action--danger",
2423
+ title: "Clear all",
2424
+ "aria-label": "Clear all drawings",
2425
+ onClick: onClearAll,
2426
+ children: "🗑"
2427
+ }),
2428
+ showExport && onExport && /* @__PURE__ */ jsx("button", {
2429
+ className: "eui-cdt-action eui-cdt-action--export",
2430
+ title: "Export",
2431
+ "aria-label": "Export as image",
2432
+ onClick: () => onExport("png"),
2433
+ children: "⬇"
2434
+ })
2435
+ ]
2436
+ })
2437
+ ]
2438
+ });
2439
+ }
2440
+ //#endregion
2441
+ //#region src/components/canvas-draw/CanvasDraw.tsx
2442
+ var maxUndoHistory = 50;
2443
+ function CanvasDraw({ background, items: controlledItems, groups: controlledGroups, currentMs = 0, mediaDurationMs = 0, isEditing = true, toolbarPlacement = "top", defaultTool = "select", defaultToolDefaults: partialDefaults, features = {}, className, style, onItemsChange, onExport }) {
2444
+ const mergedDefaults = useMemo(() => ({
2445
+ ...defaultToolDefaults,
2446
+ ...partialDefaults
2447
+ }), [partialDefaults]);
2448
+ const isControlled = controlledItems !== void 0;
2449
+ const [internalItems, setInternalItems] = useState([]);
2450
+ const [internalGroups] = useState(controlledGroups ?? []);
2451
+ const [activeTool, setActiveTool] = useState(defaultTool);
2452
+ const [toolDefaults, setToolDefaults] = useState(mergedDefaults);
2453
+ const [selectedItemId, setSelectedItemId] = useState(null);
2454
+ const [showAtMs, setShowAtMs] = useState(0);
2455
+ const [hideAtMs, setHideAtMs] = useState(null);
2456
+ const [drawTransition, setDrawTransition] = useState("none");
2457
+ const [drawGroupId] = useState(null);
2458
+ const items = isControlled ? controlledItems ?? [] : internalItems;
2459
+ const groups = controlledGroups ?? internalGroups;
2460
+ const undoStackRef = useRef([]);
2461
+ const redoStackRef = useRef([]);
2462
+ const [canUndo, setCanUndo] = useState(false);
2463
+ const [canRedo, setCanRedo] = useState(false);
2464
+ const preDrawSnapshotRef = useRef(null);
2465
+ const overlayRef = useRef(null);
2466
+ const setItems = useCallback((next) => {
2467
+ if (!isControlled) setInternalItems(next);
2468
+ onItemsChange?.(next);
2469
+ }, [isControlled, onItemsChange]);
2470
+ const handleItemsChange = useCallback((next) => {
2471
+ if (preDrawSnapshotRef.current === null) preDrawSnapshotRef.current = items.slice();
2472
+ setItems(next);
2473
+ }, [items, setItems]);
2474
+ const handleItemsCommit = useCallback(() => {
2475
+ if (preDrawSnapshotRef.current !== null) {
2476
+ undoStackRef.current = [...undoStackRef.current.slice(-maxUndoHistory + 1), preDrawSnapshotRef.current];
2477
+ redoStackRef.current = [];
2478
+ preDrawSnapshotRef.current = null;
2479
+ setCanUndo(true);
2480
+ setCanRedo(false);
2481
+ }
2482
+ }, []);
2483
+ const handleUndo = useCallback(() => {
2484
+ if (undoStackRef.current.length === 0) return;
2485
+ const prev = undoStackRef.current[undoStackRef.current.length - 1];
2486
+ undoStackRef.current = undoStackRef.current.slice(0, -1);
2487
+ redoStackRef.current = [...redoStackRef.current, items.slice()];
2488
+ setItems(prev);
2489
+ setSelectedItemId(null);
2490
+ setCanUndo(undoStackRef.current.length > 0);
2491
+ setCanRedo(true);
2492
+ }, [items, setItems]);
2493
+ const handleRedo = useCallback(() => {
2494
+ if (redoStackRef.current.length === 0) return;
2495
+ const next = redoStackRef.current[redoStackRef.current.length - 1];
2496
+ redoStackRef.current = redoStackRef.current.slice(0, -1);
2497
+ undoStackRef.current = [...undoStackRef.current, items.slice()];
2498
+ setItems(next);
2499
+ setSelectedItemId(null);
2500
+ setCanUndo(true);
2501
+ setCanRedo(redoStackRef.current.length > 0);
2502
+ }, [items, setItems]);
2503
+ const handleDeleteSelected = useCallback(() => {
2504
+ if (!selectedItemId) return;
2505
+ undoStackRef.current = [...undoStackRef.current.slice(-maxUndoHistory + 1), items.slice()];
2506
+ redoStackRef.current = [];
2507
+ setItems(items.filter((it) => it.id !== selectedItemId));
2508
+ setSelectedItemId(null);
2509
+ setCanUndo(true);
2510
+ setCanRedo(false);
2511
+ }, [
2512
+ selectedItemId,
2513
+ items,
2514
+ setItems
2515
+ ]);
2516
+ const handleDuplicateSelected = useCallback(() => {
2517
+ if (!selectedItemId) return;
2518
+ const original = items.find((it) => it.id === selectedItemId);
2519
+ if (!original) return;
2520
+ const copy = {
2521
+ ...original,
2522
+ id: `cd-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
2523
+ xPct: original.xPct + .02,
2524
+ yPct: original.yPct + .02,
2525
+ object: {
2526
+ ...original.object,
2527
+ id: `cd-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`
2528
+ }
2529
+ };
2530
+ undoStackRef.current = [...undoStackRef.current.slice(-maxUndoHistory + 1), items.slice()];
2531
+ redoStackRef.current = [];
2532
+ setItems([...items, copy]);
2533
+ setSelectedItemId(copy.id);
2534
+ setCanUndo(true);
2535
+ setCanRedo(false);
2536
+ }, [
2537
+ selectedItemId,
2538
+ items,
2539
+ setItems
2540
+ ]);
2541
+ const handleClearAll = useCallback(() => {
2542
+ undoStackRef.current = [...undoStackRef.current.slice(-maxUndoHistory + 1), items.slice()];
2543
+ redoStackRef.current = [];
2544
+ setItems([]);
2545
+ setSelectedItemId(null);
2546
+ setCanUndo(true);
2547
+ setCanRedo(false);
2548
+ }, [items, setItems]);
2549
+ const handleDefaultsChange = useCallback((d) => {
2550
+ setToolDefaults(d);
2551
+ if (selectedItemId) setItems(items.map((it) => {
2552
+ if (it.id !== selectedItemId) return it;
2553
+ const obj = it.object;
2554
+ const base = {
2555
+ strokeColor: d.strokeColor,
2556
+ strokeWidth: d.strokeWidth
2557
+ };
2558
+ if (obj.type === "rect" || obj.type === "circle") return {
2559
+ ...it,
2560
+ object: {
2561
+ ...obj,
2562
+ ...base,
2563
+ fillColor: d.fillColor,
2564
+ ...obj.type === "rect" ? { rounded: d.rounded } : {}
2565
+ }
2566
+ };
2567
+ if (obj.type === "text") return {
2568
+ ...it,
2569
+ object: {
2570
+ ...obj,
2571
+ ...base,
2572
+ fillColor: d.fillColor,
2573
+ fontFamily: d.fontFamily,
2574
+ fontSize: d.fontSize,
2575
+ fontColor: d.fontColor,
2576
+ fontBold: d.fontBold,
2577
+ fontItalic: d.fontItalic,
2578
+ fontUnderline: d.fontUnderline
2579
+ }
2580
+ };
2581
+ if (obj.type === "balloon") return {
2582
+ ...it,
2583
+ object: {
2584
+ ...obj,
2585
+ ...base,
2586
+ fillColor: d.fillColor,
2587
+ fontFamily: d.fontFamily,
2588
+ fontSize: d.fontSize,
2589
+ fontColor: d.fontColor,
2590
+ fontBold: d.fontBold,
2591
+ fontItalic: d.fontItalic,
2592
+ fontUnderline: d.fontUnderline
2593
+ }
2594
+ };
2595
+ if (obj.type === "step") {
2596
+ const stepFill = d.fillColor === "transparent" ? obj.fillColor : d.fillColor;
2597
+ return {
2598
+ ...it,
2599
+ object: {
2600
+ ...obj,
2601
+ ...base,
2602
+ fillColor: stepFill,
2603
+ fontColor: d.fontColor
2604
+ }
2605
+ };
2606
+ }
2607
+ if (obj.type === "callout") {
2608
+ const calloutFill = d.fillColor === "transparent" ? obj.fillColor : d.fillColor;
2609
+ return {
2610
+ ...it,
2611
+ object: {
2612
+ ...obj,
2613
+ ...base,
2614
+ fillColor: calloutFill,
2615
+ fontColor: d.fontColor
2616
+ }
2617
+ };
2618
+ }
2619
+ return {
2620
+ ...it,
2621
+ object: {
2622
+ ...obj,
2623
+ ...base
2624
+ }
2625
+ };
2626
+ }));
2627
+ }, [
2628
+ selectedItemId,
2629
+ items,
2630
+ setItems
2631
+ ]);
2632
+ const handleUpdateSelectedTiming = useCallback((newShowAt, newHideAt, newTransition) => {
2633
+ if (!selectedItemId) return;
2634
+ setItems(items.map((it) => it.id !== selectedItemId ? it : {
2635
+ ...it,
2636
+ showAtMs: newShowAt,
2637
+ hideAtMs: newHideAt,
2638
+ transition: newTransition
2639
+ }));
2640
+ }, [
2641
+ selectedItemId,
2642
+ items,
2643
+ setItems
2644
+ ]);
2645
+ const handleAssignGroup = useCallback((groupId) => {
2646
+ if (!selectedItemId) return;
2647
+ setItems(items.map((it) => it.id !== selectedItemId ? it : {
2648
+ ...it,
2649
+ groupId
2650
+ }));
2651
+ }, [
2652
+ selectedItemId,
2653
+ items,
2654
+ setItems
2655
+ ]);
2656
+ const handleUpdateStepNumber = useCallback((stepNumber) => {
2657
+ if (!selectedItemId) return;
2658
+ setItems(items.map((it) => {
2659
+ if (it.id !== selectedItemId) return it;
2660
+ const obj = it.object;
2661
+ if (obj.type === "step" || obj.type === "callout") return {
2662
+ ...it,
2663
+ object: {
2664
+ ...obj,
2665
+ stepNumber
2666
+ }
2667
+ };
2668
+ return it;
2669
+ }));
2670
+ }, [
2671
+ selectedItemId,
2672
+ items,
2673
+ setItems
2674
+ ]);
2675
+ const handleExport = useCallback(async (format) => {
2676
+ if (!onExport) return;
2677
+ if (format === "svg") {
2678
+ const svgStr = overlayRef.current?.exportSvgString() ?? "";
2679
+ const blob = new Blob([svgStr], { type: "image/svg+xml" });
2680
+ onExport(URL.createObjectURL(blob), "svg");
2681
+ return;
2682
+ }
2683
+ const wrapper = document.querySelector(".eui-canvas-draw__canvas");
2684
+ if (!wrapper) return;
2685
+ try {
2686
+ const { default: renderToCanvas } = await import(
2687
+ /* @vite-ignore */
2688
+ "html2canvas"
2689
+ );
2690
+ const canvas = await renderToCanvas(wrapper, {
2691
+ useCORS: true,
2692
+ scale: 2
2693
+ });
2694
+ const mime = format === "jpg" ? "image/jpeg" : format === "webp" ? "image/webp" : "image/png";
2695
+ onExport(canvas.toDataURL(mime, .92), format);
2696
+ } catch (err) {
2697
+ console.error("[CanvasDraw] Export requires \"html2canvas\" package. Install it with: npm install html2canvas", err);
2698
+ }
2699
+ }, [onExport]);
2700
+ const handleDrawComplete = useCallback(() => {
2701
+ setActiveTool("select");
2702
+ }, []);
2703
+ const wrapRef = useRef(null);
2704
+ const handleUndoRef = useRef(handleUndo);
2705
+ handleUndoRef.current = handleUndo;
2706
+ const handleRedoRef = useRef(handleRedo);
2707
+ handleRedoRef.current = handleRedo;
2708
+ const handleDeleteSelectedRef = useRef(handleDeleteSelected);
2709
+ handleDeleteSelectedRef.current = handleDeleteSelected;
2710
+ useEffect(() => {
2711
+ if (!isEditing) return;
2712
+ const el = wrapRef.current;
2713
+ if (!el) return;
2714
+ const onKeyDown = (e) => {
2715
+ if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement || e.target instanceof HTMLSelectElement) return;
2716
+ if (e.key === "Delete" || e.key === "Backspace") {
2717
+ e.preventDefault();
2718
+ handleDeleteSelectedRef.current();
2719
+ } else if (e.key === "z" && (e.ctrlKey || e.metaKey) && !e.shiftKey) {
2720
+ e.preventDefault();
2721
+ handleUndoRef.current();
2722
+ } else if (e.key === "y" && (e.ctrlKey || e.metaKey) || e.key === "z" && (e.ctrlKey || e.metaKey) && e.shiftKey) {
2723
+ e.preventDefault();
2724
+ handleRedoRef.current();
2725
+ }
2726
+ };
2727
+ el.addEventListener("keydown", onKeyDown);
2728
+ return () => el.removeEventListener("keydown", onKeyDown);
2729
+ }, [isEditing]);
2730
+ const selectedItem = useMemo(() => items.find((it) => it.id === selectedItemId) ?? null, [items, selectedItemId]);
2731
+ const toolbarVisible = isEditing && toolbarPlacement !== "none";
2732
+ const isVerticalToolbar = toolbarPlacement === "left" || toolbarPlacement === "right";
2733
+ const wrapClass = (0, import_classnames.default)("eui-canvas-draw", {
2734
+ [`eui-canvas-draw--tb-${toolbarPlacement}`]: toolbarVisible,
2735
+ "eui-canvas-draw--vertical-tb": isVerticalToolbar,
2736
+ "eui-canvas-draw--editing": isEditing
2737
+ }, className);
2738
+ const backgroundEl = useMemo(() => {
2739
+ if (background.type === "image") return /* @__PURE__ */ jsx("img", {
2740
+ src: background.src,
2741
+ className: "eui-canvas-draw__bg-img",
2742
+ alt: "",
2743
+ draggable: false
2744
+ });
2745
+ if (background.type === "color") return /* @__PURE__ */ jsx("div", {
2746
+ className: "eui-canvas-draw__bg-color",
2747
+ style: { background: background.color }
2748
+ });
2749
+ return null;
2750
+ }, [background]);
2751
+ return /* @__PURE__ */ jsxs("div", {
2752
+ ref: wrapRef,
2753
+ className: wrapClass,
2754
+ style,
2755
+ tabIndex: -1,
2756
+ children: [
2757
+ toolbarVisible && (toolbarPlacement === "top" || toolbarPlacement === "left") && /* @__PURE__ */ jsx(CanvasDrawToolbar, {
2758
+ activeTool,
2759
+ defaults: toolDefaults,
2760
+ currentMs,
2761
+ mediaDurationMs,
2762
+ showAtMs,
2763
+ hideAtMs,
2764
+ transition: drawTransition,
2765
+ selectedItem,
2766
+ groups,
2767
+ features,
2768
+ onToolChange: setActiveTool,
2769
+ onDefaultsChange: handleDefaultsChange,
2770
+ onShowAtChange: setShowAtMs,
2771
+ onHideAtChange: setHideAtMs,
2772
+ onTransitionChange: setDrawTransition,
2773
+ onDeleteSelected: handleDeleteSelected,
2774
+ onDuplicateSelected: handleDuplicateSelected,
2775
+ onUndo: handleUndo,
2776
+ onRedo: handleRedo,
2777
+ onClearAll: handleClearAll,
2778
+ onSetCurrentAsShowAt: () => setShowAtMs(currentMs),
2779
+ onSetCurrentAsHideAt: () => setHideAtMs(currentMs),
2780
+ onUpdateSelectedTiming: handleUpdateSelectedTiming,
2781
+ onAssignGroup: handleAssignGroup,
2782
+ onUpdateStepNumber: handleUpdateStepNumber,
2783
+ canUndo,
2784
+ canRedo,
2785
+ onExport: onExport ? handleExport : void 0
2786
+ }),
2787
+ /* @__PURE__ */ jsxs("div", {
2788
+ className: "eui-canvas-draw__canvas",
2789
+ children: [
2790
+ backgroundEl,
2791
+ /* @__PURE__ */ jsx(CanvasDrawOverlay, {
2792
+ ref: overlayRef,
2793
+ background,
2794
+ currentMs,
2795
+ isEditing,
2796
+ items,
2797
+ groups,
2798
+ selectedItemId,
2799
+ defaults: toolDefaults,
2800
+ activeTool,
2801
+ currentDrawShowAt: showAtMs,
2802
+ currentDrawHideAt: hideAtMs,
2803
+ currentDrawTransition: drawTransition,
2804
+ currentDrawGroupId: drawGroupId,
2805
+ onItemsChange: handleItemsChange,
2806
+ onItemsCommit: handleItemsCommit,
2807
+ onSelectItem: setSelectedItemId,
2808
+ onDrawComplete: handleDrawComplete
2809
+ }),
2810
+ features.export !== false && onExport && /* @__PURE__ */ jsx("div", {
2811
+ className: "eui-canvas-draw__export-bar",
2812
+ children: [
2813
+ "png",
2814
+ "jpg",
2815
+ "webp",
2816
+ "svg"
2817
+ ].map((fmt) => /* @__PURE__ */ jsx("button", {
2818
+ className: "eui-canvas-draw__export-btn",
2819
+ onClick: () => handleExport(fmt),
2820
+ "aria-label": `Export as ${fmt.toUpperCase()}`,
2821
+ children: fmt.toUpperCase()
2822
+ }, fmt))
2823
+ })
2824
+ ]
2825
+ }),
2826
+ toolbarVisible && (toolbarPlacement === "bottom" || toolbarPlacement === "right") && /* @__PURE__ */ jsx(CanvasDrawToolbar, {
2827
+ activeTool,
2828
+ defaults: toolDefaults,
2829
+ currentMs,
2830
+ mediaDurationMs,
2831
+ showAtMs,
2832
+ hideAtMs,
2833
+ transition: drawTransition,
2834
+ selectedItem,
2835
+ groups,
2836
+ features,
2837
+ onToolChange: setActiveTool,
2838
+ onDefaultsChange: handleDefaultsChange,
2839
+ onShowAtChange: setShowAtMs,
2840
+ onHideAtChange: setHideAtMs,
2841
+ onTransitionChange: setDrawTransition,
2842
+ onDeleteSelected: handleDeleteSelected,
2843
+ onDuplicateSelected: handleDuplicateSelected,
2844
+ onUndo: handleUndo,
2845
+ onRedo: handleRedo,
2846
+ onClearAll: handleClearAll,
2847
+ onSetCurrentAsShowAt: () => setShowAtMs(currentMs),
2848
+ onSetCurrentAsHideAt: () => setHideAtMs(currentMs),
2849
+ onUpdateSelectedTiming: handleUpdateSelectedTiming,
2850
+ onAssignGroup: handleAssignGroup,
2851
+ onUpdateStepNumber: handleUpdateStepNumber,
2852
+ canUndo,
2853
+ canRedo,
2854
+ onExport: onExport ? handleExport : void 0
2855
+ })
2856
+ ]
2857
+ });
2858
+ }
2859
+ //#endregion
2860
+ //#region src/components/canvas-draw/MediaTimeline.tsx
2861
+ var groupPalette = [
2862
+ "#4361ee",
2863
+ "#7209b7",
2864
+ "#2a9d8f",
2865
+ "#f4a261",
2866
+ "#e63946",
2867
+ "#52b788"
2868
+ ];
2869
+ var transitionOptions = [
2870
+ {
2871
+ id: "none",
2872
+ label: "None"
2873
+ },
2874
+ {
2875
+ id: "fade",
2876
+ label: "Fade"
2877
+ },
2878
+ {
2879
+ id: "scale",
2880
+ label: "Scale"
2881
+ },
2882
+ {
2883
+ id: "slide-up",
2884
+ label: "↑ Slide"
2885
+ },
2886
+ {
2887
+ id: "slide-down",
2888
+ label: "↓ Slide"
2889
+ },
2890
+ {
2891
+ id: "slide-left",
2892
+ label: "← Slide"
2893
+ },
2894
+ {
2895
+ id: "slide-right",
2896
+ label: "→ Slide"
2897
+ }
2898
+ ];
2899
+ function msToPercent(ms, durationMs) {
2900
+ if (durationMs === 0) return 0;
2901
+ return Math.min(100, Math.max(0, ms / durationMs * 100));
2902
+ }
2903
+ function xToMs(x, durationMs, width) {
2904
+ return Math.round(x / width * durationMs);
2905
+ }
2906
+ function formatTime(ms) {
2907
+ const s = Math.floor(ms / 1e3);
2908
+ return `${Math.floor(s / 60)}:${(s % 60).toString().padStart(2, "0")}`;
2909
+ }
2910
+ function MediaTimeline({ items, groups, durationMs, currentMs, selectedItemId, tickCount = 10, defaultItemColor = "#89b4fa", onSelectItem, onUpdateItem, onUpdateGroup, onAddGroup, onDeleteGroup, onSeek, zoomLevel: controlledZoom, onZoomChange }) {
2911
+ const trackRef = useRef(null);
2912
+ const [dragState, setDragState] = useState(null);
2913
+ const [expandedGroupId, setExpandedGroupId] = useState(null);
2914
+ const [internalZoom, setInternalZoom] = useState(1);
2915
+ const zoom = controlledZoom ?? internalZoom;
2916
+ const getTrackWidth = useCallback(() => trackRef.current?.clientWidth ?? 600, []);
2917
+ const handleWheel = useCallback((e) => {
2918
+ if (!e.ctrlKey && !e.metaKey) return;
2919
+ e.preventDefault();
2920
+ const delta = e.deltaY > 0 ? -.1 : .1;
2921
+ const newZoom = Math.max(.1, Math.min(10, zoom + delta));
2922
+ if (onZoomChange) onZoomChange(newZoom);
2923
+ else setInternalZoom(newZoom);
2924
+ }, [zoom, onZoomChange]);
2925
+ const selectedItem = selectedItemId ? items.find((it) => it.id === selectedItemId) : null;
2926
+ const onTrackMouseDown = useCallback((e) => {
2927
+ if (e.target === trackRef.current) {
2928
+ const rect = trackRef.current.getBoundingClientRect();
2929
+ onSeek(xToMs(e.clientX - rect.left, durationMs, getTrackWidth()));
2930
+ }
2931
+ }, [
2932
+ durationMs,
2933
+ getTrackWidth,
2934
+ onSeek
2935
+ ]);
2936
+ const startDrag = useCallback((type, id, e, origShowAt, origHideAt) => {
2937
+ e.stopPropagation();
2938
+ e.preventDefault();
2939
+ setDragState({
2940
+ type,
2941
+ id,
2942
+ startX: e.clientX,
2943
+ origShowAt,
2944
+ origHideAt
2945
+ });
2946
+ }, []);
2947
+ const onMouseMove = useCallback((e) => {
2948
+ if (!dragState) return;
2949
+ const dx = e.clientX - dragState.startX;
2950
+ const dMs = Math.round(dx / getTrackWidth() * durationMs);
2951
+ const { type, id, origShowAt, origHideAt } = dragState;
2952
+ if (type === "item-move") {
2953
+ const newShow = Math.max(0, Math.min(origShowAt + dMs, durationMs));
2954
+ const dur = origHideAt !== null ? origHideAt - origShowAt : null;
2955
+ onUpdateItem(id, {
2956
+ showAtMs: newShow,
2957
+ hideAtMs: dur !== null ? Math.min(newShow + dur, durationMs) : null
2958
+ });
2959
+ } else if (type === "item-resize-end") {
2960
+ const base = origHideAt ?? origShowAt;
2961
+ onUpdateItem(id, { hideAtMs: Math.max(origShowAt + 100, Math.min(base + dMs, durationMs)) });
2962
+ } else if (type === "group-move") {
2963
+ const newShow = Math.max(0, Math.min(origShowAt + dMs, durationMs));
2964
+ const dur = origHideAt !== null ? origHideAt - origShowAt : null;
2965
+ onUpdateGroup(id, {
2966
+ showAtMs: newShow,
2967
+ hideAtMs: dur !== null ? Math.min(newShow + dur, durationMs) : null
2968
+ });
2969
+ } else if (type === "group-resize-end") {
2970
+ const base = origHideAt ?? origShowAt;
2971
+ onUpdateGroup(id, { hideAtMs: Math.max(origShowAt + 100, Math.min(base + dMs, durationMs)) });
2972
+ } else if (type === "group-resize-start") onUpdateGroup(id, { showAtMs: Math.max(0, Math.min(origShowAt + dMs, (origHideAt ?? durationMs) - 100)) });
2973
+ }, [
2974
+ dragState,
2975
+ durationMs,
2976
+ getTrackWidth,
2977
+ onUpdateItem,
2978
+ onUpdateGroup
2979
+ ]);
2980
+ const onMouseUp = useCallback(() => setDragState(null), []);
2981
+ const ticks = Array.from({ length: tickCount + 1 }, (_, i) => Math.round(i / tickCount * durationMs));
2982
+ return /* @__PURE__ */ jsxs("div", {
2983
+ className: "eui-media-timeline",
2984
+ onMouseMove,
2985
+ onMouseUp,
2986
+ onMouseLeave: onMouseUp,
2987
+ children: [/* @__PURE__ */ jsxs("div", {
2988
+ className: "eui-mt-header",
2989
+ children: [
2990
+ /* @__PURE__ */ jsx("span", {
2991
+ className: "eui-mt-title",
2992
+ children: "Timeline"
2993
+ }),
2994
+ selectedItem && /* @__PURE__ */ jsxs("span", {
2995
+ className: "eui-mt-selected-info",
2996
+ children: [formatTime(selectedItem.showAtMs), selectedItem.hideAtMs !== null ? ` – ${formatTime(selectedItem.hideAtMs)}` : " – end"]
2997
+ }),
2998
+ /* @__PURE__ */ jsxs("span", {
2999
+ className: "eui-mt-zoom-label",
3000
+ children: [Math.round(zoom * 100), "%"]
3001
+ }),
3002
+ /* @__PURE__ */ jsx("button", {
3003
+ className: "eui-mt-add-group",
3004
+ onClick: onAddGroup,
3005
+ "aria-label": "Add group",
3006
+ children: "+ Group"
3007
+ })
3008
+ ]
3009
+ }), /* @__PURE__ */ jsxs("div", {
3010
+ className: "eui-mt-track-wrap",
3011
+ ref: trackRef,
3012
+ onMouseDown: onTrackMouseDown,
3013
+ onWheel: handleWheel,
3014
+ style: {
3015
+ width: `${zoom * 100}%`,
3016
+ minWidth: "100%"
3017
+ },
3018
+ children: [
3019
+ /* @__PURE__ */ jsx("div", {
3020
+ className: "eui-mt-ticks",
3021
+ children: ticks.map((ms) => /* @__PURE__ */ jsx("div", {
3022
+ className: "eui-mt-tick",
3023
+ style: { left: `${msToPercent(ms, durationMs)}%` },
3024
+ children: /* @__PURE__ */ jsx("span", {
3025
+ className: "eui-mt-tick-label",
3026
+ children: formatTime(ms)
3027
+ })
3028
+ }, ms))
3029
+ }),
3030
+ /* @__PURE__ */ jsx("div", {
3031
+ className: "eui-mt-playhead",
3032
+ style: { left: `${msToPercent(currentMs, durationMs)}%` },
3033
+ "aria-hidden": "true"
3034
+ }),
3035
+ groups.map((group, gi) => {
3036
+ const gColor = group.color ?? groupPalette[gi % groupPalette.length];
3037
+ const startPct = msToPercent(group.showAtMs, durationMs);
3038
+ const endPct = group.hideAtMs !== null ? msToPercent(group.hideAtMs, durationMs) : 100;
3039
+ const wPct = Math.max(endPct - startPct, .3);
3040
+ const isExpanded = expandedGroupId === group.id;
3041
+ return /* @__PURE__ */ jsxs("div", {
3042
+ className: "eui-mt-group-row",
3043
+ children: [/* @__PURE__ */ jsxs("div", {
3044
+ className: "eui-mt-group-block",
3045
+ style: {
3046
+ left: `${startPct}%`,
3047
+ width: `${wPct}%`,
3048
+ borderColor: gColor,
3049
+ background: `${gColor}22`
3050
+ },
3051
+ onMouseDown: (e) => startDrag("group-move", group.id, e, group.showAtMs, group.hideAtMs),
3052
+ onClick: () => setExpandedGroupId(isExpanded ? null : group.id),
3053
+ title: group.label,
3054
+ role: "button",
3055
+ "aria-label": `Group: ${group.label}`,
3056
+ children: [
3057
+ /* @__PURE__ */ jsx("div", {
3058
+ className: "eui-mt-resize-handle eui-mt-resize-handle--start",
3059
+ onMouseDown: (e) => startDrag("group-resize-start", group.id, e, group.showAtMs, group.hideAtMs),
3060
+ "aria-hidden": "true"
3061
+ }),
3062
+ /* @__PURE__ */ jsx("span", {
3063
+ className: "eui-mt-group-label",
3064
+ style: { color: gColor },
3065
+ children: group.label
3066
+ }),
3067
+ /* @__PURE__ */ jsx("div", {
3068
+ className: "eui-mt-resize-handle eui-mt-resize-handle--end",
3069
+ onMouseDown: (e) => startDrag("group-resize-end", group.id, e, group.showAtMs, group.hideAtMs),
3070
+ "aria-hidden": "true"
3071
+ })
3072
+ ]
3073
+ }), isExpanded && /* @__PURE__ */ jsxs("div", {
3074
+ className: "eui-mt-group-props",
3075
+ children: [
3076
+ /* @__PURE__ */ jsx("input", {
3077
+ className: "eui-mt-group-name-input",
3078
+ value: group.label,
3079
+ onChange: (e) => onUpdateGroup(group.id, { label: e.target.value }),
3080
+ placeholder: "Group name",
3081
+ "aria-label": "Group name"
3082
+ }),
3083
+ /* @__PURE__ */ jsx("select", {
3084
+ className: "eui-mt-select",
3085
+ value: group.transition,
3086
+ onChange: (e) => onUpdateGroup(group.id, { transition: e.target.value }),
3087
+ "aria-label": "Group transition",
3088
+ children: transitionOptions.map((t) => /* @__PURE__ */ jsx("option", {
3089
+ value: t.id,
3090
+ children: t.label
3091
+ }, t.id))
3092
+ }),
3093
+ /* @__PURE__ */ jsx("button", {
3094
+ className: "eui-mt-delete-group",
3095
+ onClick: () => {
3096
+ onDeleteGroup(group.id);
3097
+ setExpandedGroupId(null);
3098
+ },
3099
+ "aria-label": `Delete group ${group.label}`,
3100
+ children: "Delete group"
3101
+ })
3102
+ ]
3103
+ })]
3104
+ }, group.id);
3105
+ }),
3106
+ /* @__PURE__ */ jsx("div", {
3107
+ className: "eui-mt-items-row",
3108
+ children: items.map((item) => {
3109
+ const startPct = msToPercent(item.showAtMs, durationMs);
3110
+ const endPct = item.hideAtMs !== null ? msToPercent(item.hideAtMs, durationMs) : 100;
3111
+ const wPct = Math.max(endPct - startPct, .3);
3112
+ const isSelected = item.id === selectedItemId;
3113
+ const groupIndex = groups.findIndex((g) => g.id === item.groupId);
3114
+ const blockColor = groupIndex >= 0 ? groups[groupIndex].color ?? groupPalette[groupIndex % groupPalette.length] : item.color ?? defaultItemColor;
3115
+ return /* @__PURE__ */ jsx("div", {
3116
+ className: (0, import_classnames.default)("eui-mt-item-block", { "eui-mt-item-block--selected": isSelected }),
3117
+ style: {
3118
+ left: `${startPct}%`,
3119
+ width: `${wPct}%`,
3120
+ background: blockColor,
3121
+ opacity: isSelected ? 1 : .65
3122
+ },
3123
+ title: item.label ?? `${item.showAtMs}ms${item.hideAtMs !== null ? ` – ${item.hideAtMs}ms` : ""}`,
3124
+ role: "button",
3125
+ "aria-selected": isSelected,
3126
+ onClick: () => onSelectItem(isSelected ? null : item.id),
3127
+ onMouseDown: (e) => {
3128
+ onSelectItem(item.id);
3129
+ startDrag("item-move", item.id, e, item.showAtMs, item.hideAtMs);
3130
+ },
3131
+ children: /* @__PURE__ */ jsx("div", {
3132
+ className: "eui-mt-resize-handle eui-mt-resize-handle--end",
3133
+ onMouseDown: (e) => {
3134
+ e.stopPropagation();
3135
+ startDrag("item-resize-end", item.id, e, item.showAtMs, item.hideAtMs);
3136
+ },
3137
+ "aria-hidden": "true"
3138
+ })
3139
+ }, item.id);
3140
+ })
3141
+ })
3142
+ ]
3143
+ })]
3144
+ });
3145
+ }
3146
+ //#endregion
3147
+ export { CanvasDraw, CanvasDrawOverlay, CanvasDrawToolbar, MediaTimeline, autoFontColor, colorMap, contrastColor, defaultToolDefaults };