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