@shohojdhara/atomix 0.1.30 → 0.2.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 (469) hide show
  1. package/CHANGELOG.md +0 -0
  2. package/LICENSE +0 -0
  3. package/README.md +151 -39
  4. package/dist/atomix.css +13529 -0
  5. package/dist/atomix.min.css +15 -0
  6. package/dist/index.d.ts +6112 -1757
  7. package/dist/index.esm.js +16852 -8364
  8. package/dist/index.esm.js.map +1 -1
  9. package/dist/index.js +16892 -8369
  10. package/dist/index.js.map +1 -1
  11. package/dist/index.min.js +1 -1
  12. package/dist/index.min.js.map +1 -1
  13. package/dist/themes/boomdevs.css +13241 -0
  14. package/dist/themes/boomdevs.min.css +353 -0
  15. package/dist/themes/esrar.css +15374 -0
  16. package/dist/themes/esrar.min.css +189 -0
  17. package/dist/themes/mashroom.css +28079 -0
  18. package/dist/themes/mashroom.min.css +403 -0
  19. package/dist/themes/shaj-default.css +14203 -0
  20. package/dist/themes/shaj-default.min.css +500 -0
  21. package/dist/themes/yabai.css +13711 -0
  22. package/dist/themes/yabai.min.css +189 -0
  23. package/package.json +126 -99
  24. package/src/components/Accordion/Accordion.stories.tsx +271 -0
  25. package/src/components/Accordion/Accordion.tsx +131 -0
  26. package/src/components/Accordion/index.ts +3 -0
  27. package/src/components/AtomixLogo/AtomixLogo.tsx +36 -0
  28. package/src/components/AtomixLogo/index.ts +3 -0
  29. package/src/components/AtomixLogo.tsx +40 -0
  30. package/src/components/Avatar/Avatar.stories.tsx +257 -0
  31. package/src/components/Avatar/Avatar.tsx +68 -0
  32. package/src/components/Avatar/AvatarGroup.tsx +73 -0
  33. package/src/components/Avatar/index.ts +3 -0
  34. package/src/components/Badge/Badge.stories.tsx +371 -0
  35. package/src/components/Badge/Badge.tsx +39 -0
  36. package/src/components/Badge/index.ts +3 -0
  37. package/src/components/Block/Block.stories.tsx +408 -0
  38. package/src/components/Block/Block.tsx +137 -0
  39. package/src/components/Block/index.ts +1 -0
  40. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +106 -0
  41. package/src/components/Breadcrumb/Breadcrumb.tsx +112 -0
  42. package/src/components/Breadcrumb/index.ts +3 -0
  43. package/src/components/Button/Button.stories.tsx +312 -0
  44. package/src/components/Button/Button.tsx +69 -0
  45. package/src/components/Button/index.ts +3 -0
  46. package/src/components/Callout/Callout.stories.tsx +588 -0
  47. package/src/components/Callout/Callout.tsx +78 -0
  48. package/src/components/Callout/index.ts +1 -0
  49. package/src/components/Card/Card.stories.tsx +105 -0
  50. package/src/components/Card/Card.tsx +69 -0
  51. package/src/components/Card/ElevationCard.tsx +47 -0
  52. package/src/components/Card/index.ts +15 -0
  53. package/src/components/Chart/AdvancedChart.tsx +624 -0
  54. package/src/components/Chart/AnimatedChart.tsx +206 -0
  55. package/src/components/Chart/AreaChart.tsx +27 -0
  56. package/src/components/Chart/BarChart.tsx +148 -0
  57. package/src/components/Chart/BubbleChart.tsx +411 -0
  58. package/src/components/Chart/CandlestickChart.tsx +765 -0
  59. package/src/components/Chart/Chart.stories.tsx +527 -0
  60. package/src/components/Chart/Chart.tsx +218 -0
  61. package/src/components/Chart/ChartRenderer.tsx +322 -0
  62. package/src/components/Chart/ChartToolbar.tsx +436 -0
  63. package/src/components/Chart/ChartTooltip.tsx +101 -0
  64. package/src/components/Chart/DonutChart.tsx +370 -0
  65. package/src/components/Chart/FunnelChart.tsx +393 -0
  66. package/src/components/Chart/GaugeChart.tsx +550 -0
  67. package/src/components/Chart/HeatmapChart.tsx +614 -0
  68. package/src/components/Chart/LineChart.tsx +172 -0
  69. package/src/components/Chart/LineChartNew.tsx +167 -0
  70. package/src/components/Chart/MultiAxisChart.tsx +498 -0
  71. package/src/components/Chart/PieChart.tsx +103 -0
  72. package/src/components/Chart/RadarChart.tsx +332 -0
  73. package/src/components/Chart/RealTimeChart.tsx +436 -0
  74. package/src/components/Chart/ScatterChart.tsx +152 -0
  75. package/src/components/Chart/TreemapChart.tsx +574 -0
  76. package/src/components/Chart/WaterfallChart.tsx +450 -0
  77. package/src/components/Chart/index.ts +119 -0
  78. package/src/components/Chart/types.ts +338 -0
  79. package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +44 -0
  80. package/src/components/ColorModeToggle/ColorModeToggle.tsx +85 -0
  81. package/src/components/ColorModeToggle/index.ts +2 -0
  82. package/src/components/Countdown/Countdown.stories.tsx +46 -0
  83. package/src/components/Countdown/Countdown.tsx +90 -0
  84. package/src/components/Countdown/index.ts +2 -0
  85. package/src/components/DataTable/DataTable.stories.tsx +248 -0
  86. package/src/components/DataTable/DataTable.tsx +213 -0
  87. package/src/components/DataTable/index.ts +3 -0
  88. package/src/components/DatePicker/DatePicker.stories.tsx +364 -0
  89. package/src/components/DatePicker/DatePicker.tsx +504 -0
  90. package/src/components/DatePicker/index.ts +4 -0
  91. package/src/components/DatePicker/readme.md +106 -0
  92. package/src/components/DatePicker/types.ts +167 -0
  93. package/src/components/DatePicker/utils.ts +185 -0
  94. package/src/components/Dropdown/Dropdown.stories.tsx +358 -0
  95. package/src/components/Dropdown/Dropdown.tsx +352 -0
  96. package/src/components/Dropdown/index.ts +14 -0
  97. package/src/components/Dropdown/readme.md +151 -0
  98. package/src/components/EdgePanel/EdgePanel.stories.tsx +266 -0
  99. package/src/components/EdgePanel/EdgePanel.tsx +73 -0
  100. package/src/components/EdgePanel/index.ts +1 -0
  101. package/src/components/Form/Checkbox.stories.tsx +76 -0
  102. package/src/components/Form/Checkbox.tsx +69 -0
  103. package/src/components/Form/Form.stories.tsx +497 -0
  104. package/src/components/Form/Form.tsx +46 -0
  105. package/src/components/Form/FormGroup.stories.tsx +162 -0
  106. package/src/components/Form/FormGroup.tsx +53 -0
  107. package/src/components/Form/Input.stories.tsx +106 -0
  108. package/src/components/Form/Input.tsx +87 -0
  109. package/src/components/Form/Radio.stories.tsx +94 -0
  110. package/src/components/Form/Radio.tsx +65 -0
  111. package/src/components/Form/Select.stories.tsx +151 -0
  112. package/src/components/Form/Select.tsx +191 -0
  113. package/src/components/Form/Textarea.stories.tsx +123 -0
  114. package/src/components/Form/Textarea.tsx +78 -0
  115. package/src/components/Form/index.ts +7 -0
  116. package/src/components/Hero/Hero.stories.tsx +295 -0
  117. package/src/components/Hero/Hero.tsx +175 -0
  118. package/src/components/Hero/index.ts +6 -0
  119. package/src/components/Icon/Icon.tsx +87 -0
  120. package/src/components/Icon/index.ts +2 -0
  121. package/src/components/List/List.stories.tsx +122 -0
  122. package/src/components/List/List.tsx +35 -0
  123. package/src/components/List/ListGroup.tsx +35 -0
  124. package/src/components/List/index.ts +2 -0
  125. package/src/components/Messages/Messages.stories.tsx +160 -0
  126. package/src/components/Messages/Messages.tsx +172 -0
  127. package/src/components/Messages/index.ts +3 -0
  128. package/src/components/Modal/Modal.stories.tsx +284 -0
  129. package/src/components/Modal/Modal.tsx +198 -0
  130. package/src/components/Modal/README.md +169 -0
  131. package/src/components/Modal/index.ts +1 -0
  132. package/src/components/Navigation/Menu/MegaMenu.tsx +109 -0
  133. package/src/components/Navigation/Menu/Menu.stories.tsx +339 -0
  134. package/src/components/Navigation/Menu/Menu.tsx +111 -0
  135. package/src/components/Navigation/Nav/Nav.stories.tsx +456 -0
  136. package/src/components/Navigation/Nav/Nav.tsx +51 -0
  137. package/src/components/Navigation/Nav/NavDropdown.tsx +105 -0
  138. package/src/components/Navigation/Nav/NavItem.tsx +168 -0
  139. package/src/components/Navigation/Navbar/Navbar.stories.tsx +569 -0
  140. package/src/components/Navigation/Navbar/Navbar.tsx +150 -0
  141. package/src/components/Navigation/README.md +314 -0
  142. package/src/components/Navigation/SideMenu/SideMenu.README.md +494 -0
  143. package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +609 -0
  144. package/src/components/Navigation/SideMenu/SideMenu.tsx +101 -0
  145. package/src/components/Navigation/SideMenu/SideMenuItem.tsx +103 -0
  146. package/src/components/Navigation/SideMenu/SideMenuList.tsx +41 -0
  147. package/src/components/Navigation/index.ts +23 -0
  148. package/src/components/Pagination/Pagination.stories.tsx +188 -0
  149. package/src/components/Pagination/Pagination.tsx +162 -0
  150. package/src/components/Pagination/index.ts +1 -0
  151. package/src/components/PhotoViewer/PhotoViewer.stories.tsx +397 -0
  152. package/src/components/PhotoViewer/PhotoViewer.tsx +246 -0
  153. package/src/components/PhotoViewer/PhotoViewerHeader.tsx +184 -0
  154. package/src/components/PhotoViewer/PhotoViewerImage.tsx +173 -0
  155. package/src/components/PhotoViewer/PhotoViewerInfo.tsx +91 -0
  156. package/src/components/PhotoViewer/PhotoViewerNavigation.tsx +85 -0
  157. package/src/components/PhotoViewer/PhotoViewerThumbnails.tsx +63 -0
  158. package/src/components/PhotoViewer/README.md +358 -0
  159. package/src/components/PhotoViewer/examples/ImageGallery.tsx +187 -0
  160. package/src/components/PhotoViewer/examples/SimpleGallery.tsx +73 -0
  161. package/src/components/PhotoViewer/examples/index.ts +2 -0
  162. package/src/components/PhotoViewer/index.ts +14 -0
  163. package/src/components/Popover/Popover.stories.tsx +143 -0
  164. package/src/components/Popover/Popover.tsx +137 -0
  165. package/src/components/Popover/index.ts +5 -0
  166. package/src/components/Popover/readme.md +120 -0
  167. package/src/components/ProductReview/ProductReview.stories.tsx +88 -0
  168. package/src/components/ProductReview/ProductReview.tsx +169 -0
  169. package/src/components/ProductReview/index.ts +3 -0
  170. package/src/components/Progress/Progress.stories.tsx +75 -0
  171. package/src/components/Progress/Progress.tsx +45 -0
  172. package/src/components/Progress/index.ts +1 -0
  173. package/src/components/Rating/Rating.stories.tsx +109 -0
  174. package/src/components/Rating/Rating.tsx +286 -0
  175. package/src/components/Rating/index.ts +6 -0
  176. package/src/components/River/River.stories.tsx +230 -0
  177. package/src/components/River/River.tsx +134 -0
  178. package/src/components/River/index.ts +2 -0
  179. package/src/components/SectionIntro/SectionIntro.stories.tsx +143 -0
  180. package/src/components/SectionIntro/SectionIntro.tsx +184 -0
  181. package/src/components/SectionIntro/index.ts +3 -0
  182. package/src/components/Slider/Slider.stories.tsx +241 -0
  183. package/src/components/Slider/Slider.tsx +225 -0
  184. package/src/components/Slider/index.ts +24 -0
  185. package/src/components/Spinner/Spinner.stories.tsx +65 -0
  186. package/src/components/Spinner/Spinner.tsx +36 -0
  187. package/src/components/Spinner/index.ts +2 -0
  188. package/src/components/Steps/Steps.stories.tsx +158 -0
  189. package/src/components/Steps/Steps.tsx +115 -0
  190. package/src/components/Steps/index.ts +3 -0
  191. package/src/components/Tab/Tab.stories.tsx +129 -0
  192. package/src/components/Tab/Tab.tsx +111 -0
  193. package/src/components/Tab/index.ts +2 -0
  194. package/src/components/Testimonial/Testimonial.stories.tsx +180 -0
  195. package/src/components/Testimonial/Testimonial.tsx +138 -0
  196. package/src/components/Testimonial/index.ts +3 -0
  197. package/src/components/Todo/Todo.stories.tsx +103 -0
  198. package/src/components/Todo/Todo.tsx +158 -0
  199. package/src/components/Todo/index.ts +1 -0
  200. package/src/components/Toggle/Toggle.stories.tsx +49 -0
  201. package/src/components/Toggle/Toggle.tsx +84 -0
  202. package/src/components/Toggle/index.ts +2 -0
  203. package/src/components/Tooltip/Tooltip.stories.tsx +115 -0
  204. package/src/components/Tooltip/Tooltip.tsx +150 -0
  205. package/src/components/Tooltip/index.ts +3 -0
  206. package/src/components/Upload/Upload.stories.tsx +220 -0
  207. package/src/components/Upload/Upload.tsx +354 -0
  208. package/src/components/Upload/index.ts +3 -0
  209. package/src/components/VideoPlayer/VideoPlayer.stories.tsx +484 -0
  210. package/src/components/VideoPlayer/VideoPlayer.tsx +574 -0
  211. package/src/components/VideoPlayer/index.ts +7 -0
  212. package/src/components/index.ts +111 -0
  213. package/src/layouts/Grid/Container.tsx +58 -0
  214. package/src/layouts/Grid/Grid.stories.tsx +861 -0
  215. package/src/layouts/Grid/Grid.tsx +68 -0
  216. package/src/layouts/Grid/GridCol.tsx +161 -0
  217. package/src/layouts/Grid/README.md +108 -0
  218. package/src/layouts/Grid/Row.tsx +70 -0
  219. package/src/layouts/Grid/index.ts +8 -0
  220. package/src/layouts/MasonryGrid/MasonryGrid.stories.tsx +387 -0
  221. package/src/layouts/MasonryGrid/MasonryGrid.tsx +408 -0
  222. package/src/layouts/MasonryGrid/MasonryGridItem.tsx +44 -0
  223. package/src/layouts/MasonryGrid/README.md +117 -0
  224. package/src/layouts/MasonryGrid/index.ts +4 -0
  225. package/src/layouts/index.ts +7 -0
  226. package/src/lib/README.md +89 -0
  227. package/src/lib/composables/index.ts +63 -0
  228. package/src/lib/composables/useAccordion.ts +129 -0
  229. package/src/lib/composables/useAmbientMode.ts +90 -0
  230. package/src/lib/composables/useBadge.ts +42 -0
  231. package/src/lib/composables/useBarChart.ts +365 -0
  232. package/src/lib/composables/useBlock.ts +56 -0
  233. package/src/lib/composables/useBreadcrumb.ts +81 -0
  234. package/src/lib/composables/useButton.ts +59 -0
  235. package/src/lib/composables/useCallout.ts +55 -0
  236. package/src/lib/composables/useCard.ts +155 -0
  237. package/src/lib/composables/useChart.ts +1082 -0
  238. package/src/lib/composables/useChartAnalytics.ts +505 -0
  239. package/src/lib/composables/useChartData.ts +38 -0
  240. package/src/lib/composables/useChartExport.ts +392 -0
  241. package/src/lib/composables/useChartInteraction.ts +34 -0
  242. package/src/lib/composables/useChartInteractions.ts +123 -0
  243. package/src/lib/composables/useChartPerformance.ts +323 -0
  244. package/src/lib/composables/useChartScale.ts +48 -0
  245. package/src/lib/composables/useChartToolbar.ts +532 -0
  246. package/src/lib/composables/useCheckbox.ts +70 -0
  247. package/src/lib/composables/useDataTable.ts +208 -0
  248. package/src/lib/composables/useDatePicker.ts +564 -0
  249. package/src/lib/composables/useDropdown.ts +272 -0
  250. package/src/lib/composables/useEdgePanel.ts +261 -0
  251. package/src/lib/composables/useForm.ts +62 -0
  252. package/src/lib/composables/useFormGroup.ts +51 -0
  253. package/src/lib/composables/useHero.ts +250 -0
  254. package/src/lib/composables/useInput.ts +58 -0
  255. package/src/lib/composables/useLineChart.ts +319 -0
  256. package/src/lib/composables/useMessages.ts +77 -0
  257. package/src/lib/composables/useModal.ts +110 -0
  258. package/src/lib/composables/useNavbar.ts +288 -0
  259. package/src/lib/composables/usePagination.ts +101 -0
  260. package/src/lib/composables/usePhotoViewer.ts +937 -0
  261. package/src/lib/composables/usePieChart.ts +362 -0
  262. package/src/lib/composables/usePopover.ts +354 -0
  263. package/src/lib/composables/useProgress.ts +74 -0
  264. package/src/lib/composables/useRadio.ts +47 -0
  265. package/src/lib/composables/useRating.ts +174 -0
  266. package/src/lib/composables/useRiver.ts +205 -0
  267. package/src/lib/composables/useSelect.ts +52 -0
  268. package/src/lib/composables/useSideMenu.ts +197 -0
  269. package/src/lib/composables/useSlider.ts +339 -0
  270. package/src/lib/composables/useSpinner.ts +42 -0
  271. package/src/lib/composables/useTextarea.ts +55 -0
  272. package/src/lib/composables/useTodo.ts +141 -0
  273. package/src/lib/composables/useVideoPlayer.ts +398 -0
  274. package/src/lib/constants/components.ts +1433 -0
  275. package/src/lib/constants/index.ts +4 -0
  276. package/src/lib/index.ts +11 -0
  277. package/src/lib/types/components.ts +4750 -0
  278. package/src/lib/types/index.ts +2 -0
  279. package/src/lib/utils/dom.ts +41 -0
  280. package/src/lib/utils/icons.ts +74 -0
  281. package/src/lib/utils/index.ts +55 -0
  282. package/src/lib/utils/useForkRef.test.tsx +64 -0
  283. package/src/lib/utils/useForkRef.ts +36 -0
  284. package/src/lib/utils.test.ts +14 -0
  285. package/src/styles/01-settings/_index.scss +2 -0
  286. package/src/styles/01-settings/_settings.accordion.scss +7 -5
  287. package/src/styles/01-settings/_settings.animations.scss +0 -0
  288. package/src/styles/01-settings/_settings.avatar-group.scss +6 -3
  289. package/src/styles/01-settings/_settings.avatar.scss +2 -2
  290. package/src/styles/01-settings/_settings.badge.scss +15 -9
  291. package/src/styles/01-settings/_settings.block.scss +11 -0
  292. package/src/styles/01-settings/_settings.border-radius.scss +12 -9
  293. package/src/styles/01-settings/_settings.border.scss +4 -1
  294. package/src/styles/01-settings/_settings.box-shadow.scss +1 -1
  295. package/src/styles/01-settings/_settings.breadcrumb.scss +9 -8
  296. package/src/styles/01-settings/_settings.breakpoints.scss +0 -0
  297. package/src/styles/01-settings/_settings.btn-group.scss +4 -1
  298. package/src/styles/01-settings/_settings.button.scss +19 -21
  299. package/src/styles/01-settings/_settings.callout.scss +42 -24
  300. package/src/styles/01-settings/_settings.card.scss +12 -10
  301. package/src/styles/01-settings/_settings.chart.scss +199 -0
  302. package/src/styles/01-settings/_settings.checkbox-group.scss +0 -0
  303. package/src/styles/01-settings/_settings.checkbox.scss +0 -0
  304. package/src/styles/01-settings/_settings.color-mode.scss +0 -0
  305. package/src/styles/01-settings/_settings.colors.scss +20 -0
  306. package/src/styles/01-settings/_settings.config.scss +1 -1
  307. package/src/styles/01-settings/_settings.countdown.scss +0 -0
  308. package/src/styles/01-settings/_settings.data-table.scss +0 -0
  309. package/src/styles/01-settings/_settings.datepicker.scss +0 -0
  310. package/src/styles/01-settings/_settings.dropdown.scss +0 -0
  311. package/src/styles/01-settings/_settings.edge-panel.scss +0 -0
  312. package/src/styles/01-settings/_settings.fonts.scss +1 -1
  313. package/src/styles/01-settings/_settings.form-group.scss +0 -0
  314. package/src/styles/01-settings/_settings.form.scss +0 -0
  315. package/src/styles/01-settings/_settings.grid.scss +3 -3
  316. package/src/styles/01-settings/_settings.hero.scss +1 -1
  317. package/src/styles/01-settings/_settings.input.scss +1 -1
  318. package/src/styles/01-settings/_settings.link.scss +0 -0
  319. package/src/styles/01-settings/_settings.list-group.scss +0 -0
  320. package/src/styles/01-settings/_settings.list.scss +0 -0
  321. package/src/styles/01-settings/_settings.maps.scss +43 -8
  322. package/src/styles/01-settings/_settings.masonry-grid.scss +0 -0
  323. package/src/styles/01-settings/_settings.menu.scss +0 -0
  324. package/src/styles/01-settings/_settings.messages.scss +0 -0
  325. package/src/styles/01-settings/_settings.modal.scss +1 -1
  326. package/src/styles/01-settings/_settings.nav.scss +0 -0
  327. package/src/styles/01-settings/_settings.navbar.scss +0 -0
  328. package/src/styles/01-settings/_settings.pagination.scss +0 -0
  329. package/src/styles/01-settings/_settings.photoviewer.scss +89 -23
  330. package/src/styles/01-settings/_settings.popover.scss +0 -0
  331. package/src/styles/01-settings/_settings.position.scss +0 -0
  332. package/src/styles/01-settings/_settings.progress.scss +0 -0
  333. package/src/styles/01-settings/_settings.rating.scss +0 -0
  334. package/src/styles/01-settings/_settings.river.scss +0 -0
  335. package/src/styles/01-settings/_settings.sectionintro.scss +0 -0
  336. package/src/styles/01-settings/_settings.select.scss +0 -0
  337. package/src/styles/01-settings/_settings.side-menu.scss +0 -0
  338. package/src/styles/01-settings/_settings.skeleton.scss +0 -0
  339. package/src/styles/01-settings/_settings.slider.scss +59 -0
  340. package/src/styles/01-settings/_settings.spacing.scss +11 -3
  341. package/src/styles/01-settings/_settings.spinner.scss +0 -0
  342. package/src/styles/01-settings/_settings.steps.scss +1 -1
  343. package/src/styles/01-settings/_settings.tabs.scss +4 -4
  344. package/src/styles/01-settings/_settings.testimonials.scss +0 -0
  345. package/src/styles/01-settings/_settings.todo.scss +0 -0
  346. package/src/styles/01-settings/_settings.toggle.scss +1 -1
  347. package/src/styles/01-settings/_settings.tooltip.scss +0 -0
  348. package/src/styles/01-settings/_settings.typography.scss +2 -0
  349. package/src/styles/01-settings/_settings.upload.scss +0 -0
  350. package/src/styles/01-settings/_settings.video-player.scss +64 -0
  351. package/src/styles/01-settings/_settings.z-layers.scss +0 -0
  352. package/src/styles/02-tools/_index.scss +1 -0
  353. package/src/styles/02-tools/_tools.animations.scss +82 -0
  354. package/src/styles/02-tools/_tools.border-radius.scss +0 -0
  355. package/src/styles/02-tools/_tools.breakpoints.scss +0 -0
  356. package/src/styles/02-tools/_tools.button.scss +5 -0
  357. package/src/styles/02-tools/_tools.clearfix.scss +0 -0
  358. package/src/styles/02-tools/_tools.color-functions.scss +0 -0
  359. package/src/styles/02-tools/_tools.color-mode.scss +1 -1
  360. package/src/styles/02-tools/_tools.component.scss +479 -0
  361. package/src/styles/02-tools/_tools.event.scss +0 -0
  362. package/src/styles/02-tools/_tools.grid.scss +0 -0
  363. package/src/styles/02-tools/_tools.hidden-visually.scss +0 -0
  364. package/src/styles/02-tools/_tools.hidden.scss +0 -0
  365. package/src/styles/02-tools/_tools.map-loop.scss +0 -0
  366. package/src/styles/02-tools/_tools.media-queries.scss +0 -0
  367. package/src/styles/02-tools/_tools.object-fit.scss +0 -0
  368. package/src/styles/02-tools/_tools.placeholder.scss +0 -0
  369. package/src/styles/02-tools/_tools.rem.scss +5 -1
  370. package/src/styles/02-tools/_tools.size.scss +0 -0
  371. package/src/styles/02-tools/_tools.spacing.scss +0 -0
  372. package/src/styles/02-tools/_tools.to-rgb.scss +0 -0
  373. package/src/styles/02-tools/_tools.transition.scss +0 -0
  374. package/src/styles/02-tools/_tools.utilities.scss +0 -0
  375. package/src/styles/02-tools/_tools.utility-api.scss +23 -2
  376. package/src/styles/03-generic/_generic.fonts.scss +0 -0
  377. package/src/styles/03-generic/_generic.reset.scss +0 -0
  378. package/src/styles/03-generic/_generic.root.scss +5 -1
  379. package/src/styles/03-generic/_generic.selection.scss +0 -0
  380. package/src/styles/03-generic/_index.scss +0 -0
  381. package/src/styles/04-elements/_elements.all.scss +0 -0
  382. package/src/styles/04-elements/_elements.body.scss +0 -0
  383. package/src/styles/04-elements/_elements.heading.scss +0 -0
  384. package/src/styles/04-elements/_elements.html.scss +0 -0
  385. package/src/styles/04-elements/_elements.links.scss +0 -0
  386. package/src/styles/04-elements/_index.scss +0 -0
  387. package/src/styles/05-objects/_index.scss +1 -0
  388. package/src/styles/05-objects/_objects.block.scss +122 -0
  389. package/src/styles/05-objects/_objects.container.scss +14 -10
  390. package/src/styles/05-objects/_objects.grid.scss +0 -0
  391. package/src/styles/05-objects/_objects.masonry-grid.scss +0 -0
  392. package/src/styles/06-components/_components.accordion.scss +3 -1
  393. package/src/styles/06-components/_components.avatar-group.scss +0 -0
  394. package/src/styles/06-components/_components.avatar.scss +0 -0
  395. package/src/styles/06-components/_components.badge.scss +9 -9
  396. package/src/styles/06-components/_components.breadcrumb.scss +0 -0
  397. package/src/styles/06-components/_components.btn-group.scss +0 -0
  398. package/src/styles/06-components/_components.button.scss +0 -0
  399. package/src/styles/06-components/_components.callout.scss +2 -1
  400. package/src/styles/06-components/_components.card.scss +0 -1
  401. package/src/styles/06-components/_components.chart.scss +2102 -0
  402. package/src/styles/06-components/_components.checkbox-group.scss +0 -0
  403. package/src/styles/06-components/_components.checkbox.scss +0 -0
  404. package/src/styles/06-components/_components.color-mode-toggle.scss +0 -0
  405. package/src/styles/06-components/_components.countdown.scss +0 -0
  406. package/src/styles/06-components/_components.data-table.scss +0 -0
  407. package/src/styles/06-components/_components.datepicker.scss +0 -0
  408. package/src/styles/06-components/_components.dropdown.scss +0 -0
  409. package/src/styles/06-components/_components.edge-panel.scss +0 -0
  410. package/src/styles/06-components/_components.form-group.scss +0 -0
  411. package/src/styles/06-components/_components.form.scss +0 -0
  412. package/src/styles/06-components/_components.hero.scss +1 -0
  413. package/src/styles/06-components/_components.icon.scss +2 -2
  414. package/src/styles/06-components/_components.image-gallery.scss +0 -0
  415. package/src/styles/06-components/_components.input.scss +0 -0
  416. package/src/styles/06-components/_components.list-group.scss +0 -0
  417. package/src/styles/06-components/_components.list.scss +0 -0
  418. package/src/styles/06-components/_components.menu.scss +0 -0
  419. package/src/styles/06-components/_components.messages.scss +0 -0
  420. package/src/styles/06-components/_components.modal.scss +3 -0
  421. package/src/styles/06-components/_components.nav.scss +0 -0
  422. package/src/styles/06-components/_components.navbar.scss +0 -0
  423. package/src/styles/06-components/_components.pagination.scss +0 -0
  424. package/src/styles/06-components/_components.photoviewer.scss +603 -545
  425. package/src/styles/06-components/_components.popover.scss +0 -0
  426. package/src/styles/06-components/_components.product-review.scss +0 -0
  427. package/src/styles/06-components/_components.progress.scss +0 -0
  428. package/src/styles/06-components/_components.rating.scss +0 -0
  429. package/src/styles/06-components/_components.river.scss +0 -0
  430. package/src/styles/06-components/_components.sectionintro.scss +0 -0
  431. package/src/styles/06-components/_components.select.scss +0 -0
  432. package/src/styles/06-components/_components.side-menu.scss +0 -0
  433. package/src/styles/06-components/_components.skeleton.scss +0 -0
  434. package/src/styles/06-components/_components.slider.scss +273 -0
  435. package/src/styles/06-components/_components.spinner.scss +0 -0
  436. package/src/styles/06-components/_components.steps.scss +1 -0
  437. package/src/styles/06-components/_components.tabs.scss +0 -0
  438. package/src/styles/06-components/_components.testimonials.scss +0 -0
  439. package/src/styles/06-components/_components.todo.scss +0 -0
  440. package/src/styles/06-components/_components.toggle.scss +0 -0
  441. package/src/styles/06-components/_components.tooltip.scss +4 -9
  442. package/src/styles/06-components/_components.upload.scss +0 -0
  443. package/src/styles/06-components/_components.video-player.scss +623 -0
  444. package/src/styles/06-components/_index.scss +3 -0
  445. package/src/styles/06-components/old.chart.styles.scss +2819 -0
  446. package/src/styles/99-utilities/_index.scss +0 -0
  447. package/src/styles/99-utilities/_utilities.background.scss +0 -0
  448. package/src/styles/99-utilities/_utilities.border.scss +0 -0
  449. package/src/styles/99-utilities/_utilities.clearfix.scss +0 -0
  450. package/src/styles/99-utilities/_utilities.display.scss +0 -0
  451. package/src/styles/99-utilities/_utilities.flex.scss +0 -0
  452. package/src/styles/99-utilities/_utilities.link.scss +0 -0
  453. package/src/styles/99-utilities/_utilities.object-fit.scss +0 -0
  454. package/src/styles/99-utilities/_utilities.opacity.scss +0 -0
  455. package/src/styles/99-utilities/_utilities.overflow.scss +0 -0
  456. package/src/styles/99-utilities/_utilities.position.scss +0 -0
  457. package/src/styles/99-utilities/_utilities.scss +2 -1
  458. package/src/styles/99-utilities/_utilities.shadow.scss +0 -0
  459. package/src/styles/99-utilities/_utilities.sizes.scss +0 -0
  460. package/src/styles/99-utilities/_utilities.spacing.scss +0 -0
  461. package/src/styles/99-utilities/_utilities.text.scss +5 -0
  462. package/src/styles/99-utilities/_utilities.visibility.scss +0 -0
  463. package/src/styles/99-utilities/_utilities.visually-hidden.scss +0 -0
  464. package/src/styles/99-utilities/_utilities.z-index.scss +0 -0
  465. package/src/styles/css-modules.d.ts +0 -0
  466. package/src/styles/index.scss +0 -0
  467. package/dist/index.css +0 -15
  468. package/dist/index.esm.css +0 -15
  469. package/dist/index.min.css +0 -15
@@ -0,0 +1,765 @@
1
+ import { forwardRef, memo, useCallback, useMemo, useState } from 'react';
2
+ import { CHART } from '../../lib/constants/components';
3
+ import Chart from './Chart';
4
+ import ChartTooltip from './ChartTooltip';
5
+ import { ChartProps } from './types';
6
+
7
+ interface CandlestickDataPoint {
8
+ /**
9
+ * Date or timestamp
10
+ */
11
+ date: string | Date;
12
+
13
+ /**
14
+ * Opening price
15
+ */
16
+ open: number;
17
+
18
+ /**
19
+ * Highest price
20
+ */
21
+ high: number;
22
+
23
+ /**
24
+ * Lowest price
25
+ */
26
+ low: number;
27
+
28
+ /**
29
+ * Closing price
30
+ */
31
+ close: number;
32
+
33
+ /**
34
+ * Trading volume (optional)
35
+ */
36
+ volume?: number;
37
+
38
+ /**
39
+ * Additional metadata
40
+ */
41
+ metadata?: Record<string, any>;
42
+ }
43
+
44
+ interface CandlestickChartProps extends Omit<ChartProps, 'type' | 'datasets'> {
45
+ /**
46
+ * Candlestick chart data
47
+ */
48
+ candlestickData?: CandlestickDataPoint[];
49
+
50
+ /**
51
+ * Candlestick chart specific options
52
+ */
53
+ candlestickOptions?: {
54
+ /**
55
+ * Color for bullish (rising) candles
56
+ */
57
+ bullishColor?: string;
58
+
59
+ /**
60
+ * Color for bearish (falling) candles
61
+ */
62
+ bearishColor?: string;
63
+
64
+ /**
65
+ * Candle width as percentage of available space
66
+ */
67
+ candleWidth?: number;
68
+
69
+ /**
70
+ * Whether to show volume bars
71
+ */
72
+ showVolume?: boolean;
73
+
74
+ /**
75
+ * Volume bar height ratio
76
+ */
77
+ volumeHeightRatio?: number;
78
+
79
+ /**
80
+ * Whether to show moving averages
81
+ */
82
+ showMovingAverages?: boolean;
83
+
84
+ /**
85
+ * Moving average periods
86
+ */
87
+ movingAveragePeriods?: number[];
88
+
89
+ /**
90
+ * Moving average colors
91
+ */
92
+ movingAverageColors?: string[];
93
+
94
+ /**
95
+ * Whether to show trend lines
96
+ */
97
+ showTrendLines?: boolean;
98
+
99
+ /**
100
+ * Whether to enable crosshair
101
+ */
102
+ enableCrosshair?: boolean;
103
+
104
+ /**
105
+ * Whether to show OHLC tooltip
106
+ */
107
+ showOHLCTooltip?: boolean;
108
+
109
+ /**
110
+ * Date format for x-axis labels
111
+ */
112
+ dateFormat?: 'short' | 'medium' | 'long' | 'numeric';
113
+
114
+ /**
115
+ * Price precision (decimal places)
116
+ */
117
+ pricePrecision?: number;
118
+
119
+ /**
120
+ * Whether to enable zoom and pan
121
+ */
122
+ enableZoomPan?: boolean;
123
+ };
124
+ }
125
+
126
+ const CandlestickChart = memo(
127
+ forwardRef<HTMLDivElement, CandlestickChartProps>(
128
+ (
129
+ {
130
+ candlestickData = [],
131
+ config = {},
132
+ candlestickOptions = {
133
+ bullishColor: '#4DFF9F',
134
+ bearishColor: '#FF6B6B',
135
+ candleWidth: 0.8,
136
+ showVolume: false,
137
+ volumeHeightRatio: 0.3,
138
+ showMovingAverages: false,
139
+ movingAveragePeriods: [20, 50],
140
+ movingAverageColors: ['#FFD93D', '#6BCF7F'],
141
+ showTrendLines: false,
142
+ enableCrosshair: true,
143
+ showOHLCTooltip: true,
144
+ dateFormat: 'short',
145
+ pricePrecision: 2,
146
+ enableZoomPan: false,
147
+ },
148
+ onDataPointClick,
149
+ ...props
150
+ },
151
+ ref
152
+ ) => {
153
+ const [hoveredCandle, setHoveredCandle] = useState<{
154
+ index: number;
155
+ x: number;
156
+ y: number;
157
+ data: CandlestickDataPoint;
158
+ } | null>(null);
159
+
160
+ const [crosshair, setCrosshair] = useState<{ x: number; y: number } | null>(null);
161
+ const [zoom, setZoom] = useState({ scale: 1, translateX: 0, translateY: 0 });
162
+
163
+ // Calculate moving averages
164
+ const calculateMovingAverage = useCallback((data: CandlestickDataPoint[], period: number) => {
165
+ const result: number[] = [];
166
+
167
+ for (let i = 0; i < data.length; i++) {
168
+ if (i < period - 1) {
169
+ result.push(NaN);
170
+ } else {
171
+ const sum = data
172
+ .slice(i - period + 1, i + 1)
173
+ .reduce((acc, candle) => acc + candle.close, 0);
174
+ result.push(sum / period);
175
+ }
176
+ }
177
+
178
+ return result;
179
+ }, []);
180
+
181
+ // Format date for display
182
+ const formatDate = useCallback(
183
+ (date: string | Date) => {
184
+ const dateObj = typeof date === 'string' ? new Date(date) : date;
185
+
186
+ switch (candlestickOptions.dateFormat) {
187
+ case 'short':
188
+ return dateObj.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
189
+ case 'medium':
190
+ return dateObj.toLocaleDateString('en-US', {
191
+ month: 'short',
192
+ day: 'numeric',
193
+ year: '2-digit',
194
+ });
195
+ case 'long':
196
+ return dateObj.toLocaleDateString('en-US', {
197
+ month: 'long',
198
+ day: 'numeric',
199
+ year: 'numeric',
200
+ });
201
+ case 'numeric':
202
+ return dateObj.toLocaleDateString('en-US');
203
+ default:
204
+ return dateObj.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
205
+ }
206
+ },
207
+ [candlestickOptions.dateFormat]
208
+ );
209
+
210
+ // Chart content calculation
211
+ const chartContent = useMemo(() => {
212
+ if (!candlestickData.length) return null;
213
+
214
+ const width = 800;
215
+ const height = candlestickOptions.showVolume ? 500 : 400;
216
+ const padding = { top: 40, right: 70, bottom: 60, left: 70 };
217
+ const chartHeight = candlestickOptions.showVolume
218
+ ? height * (1 - candlestickOptions.volumeHeightRatio!)
219
+ : height - padding.top - padding.bottom;
220
+ const volumeHeight = candlestickOptions.showVolume
221
+ ? height * candlestickOptions.volumeHeightRatio!
222
+ : 0;
223
+ const innerWidth = width - padding.left - padding.right;
224
+
225
+ // Calculate price scales
226
+ const allPrices = candlestickData.flatMap(candle => [
227
+ candle.open,
228
+ candle.high,
229
+ candle.low,
230
+ candle.close,
231
+ ]);
232
+ const minPrice = config.yAxis?.min ?? Math.min(...allPrices);
233
+ const maxPrice = config.yAxis?.max ?? Math.max(...allPrices);
234
+
235
+ // Handle case where all prices are the same to avoid division by zero
236
+ const priceRange = maxPrice !== minPrice ? maxPrice - minPrice : 1;
237
+
238
+ // Calculate volume scale if needed
239
+ const candlesWithVolume = candlestickData.filter(d => d.volume);
240
+ const maxVolume =
241
+ candlestickOptions.showVolume && candlesWithVolume.length > 0
242
+ ? Math.max(...candlesWithVolume.map(d => d.volume!))
243
+ : 0;
244
+ // Ensure maxVolume is at least 1 to avoid division by zero
245
+ const safeMaxVolume = maxVolume > 0 ? maxVolume : 1;
246
+
247
+ const xScale = (i: number) => {
248
+ // Handle case where there's only one data point to avoid division by zero
249
+ const denominator = candlestickData.length > 1 ? candlestickData.length - 1 : 1;
250
+ const baseX = padding.left + (i / denominator) * innerWidth;
251
+ return baseX * zoom.scale + zoom.translateX;
252
+ };
253
+
254
+ const priceScale = (price: number) => {
255
+ const baseY = padding.top + chartHeight - ((price - minPrice) / priceRange) * chartHeight;
256
+ return baseY * zoom.scale + zoom.translateY;
257
+ };
258
+
259
+ const volumeScale = (volume: number) => {
260
+ // Use safeMaxVolume to avoid division by zero
261
+ return (
262
+ chartHeight +
263
+ padding.top +
264
+ 10 +
265
+ ((safeMaxVolume - volume) / safeMaxVolume) * (volumeHeight - 20)
266
+ );
267
+ };
268
+
269
+ // Ensure we have at least one data point to avoid division by zero
270
+ const safeDataLength = Math.max(candlestickData.length, 1);
271
+ const candleSpacing = innerWidth / safeDataLength;
272
+ const candleWidth = candleSpacing * (candlestickOptions.candleWidth || 0.8);
273
+
274
+ // Generate chart elements
275
+ const chartElements = [];
276
+
277
+ // Volume bars (if enabled)
278
+ if (candlestickOptions.showVolume && candlesWithVolume.length > 0) {
279
+ candlestickData.forEach((candle, i) => {
280
+ if (!candle.volume) return;
281
+
282
+ const x = xScale(i);
283
+ const isBullish = candle.close >= candle.open;
284
+ const volumeColor = isBullish
285
+ ? candlestickOptions.bullishColor
286
+ : candlestickOptions.bearishColor;
287
+
288
+ // Ensure all values are valid numbers before creating the rect element
289
+ const xPos = isNaN(x) ? 0 : x;
290
+ const candleWidthQuarter = isNaN(candleWidth / 4) ? 0 : candleWidth / 4;
291
+ const volScale = volumeScale(candle.volume);
292
+ const volHeight = chartHeight + padding.top + 10 + volumeHeight - 20 - volScale;
293
+
294
+ chartElements.push(
295
+ <rect
296
+ key={`volume-${i}`}
297
+ x={xPos - candleWidthQuarter}
298
+ y={isNaN(volScale) ? 0 : volScale}
299
+ width={isNaN(candleWidth / 2) ? 0 : candleWidth / 2}
300
+ height={isNaN(volHeight) ? 0 : volHeight}
301
+ fill={volumeColor}
302
+ opacity={0.3}
303
+ />
304
+ );
305
+ });
306
+
307
+ // Volume section separator
308
+ chartElements.push(
309
+ <line
310
+ key="volume-separator"
311
+ x1={padding.left}
312
+ y1={chartHeight + padding.top + 5}
313
+ x2={width - padding.right}
314
+ y2={chartHeight + padding.top + 5}
315
+ stroke="#e5e7eb"
316
+ strokeWidth={1}
317
+ />
318
+ );
319
+ }
320
+
321
+ // Candlesticks
322
+ candlestickData.forEach((candle, i) => {
323
+ const x = xScale(i);
324
+ const openY = priceScale(candle.open);
325
+ const highY = priceScale(candle.high);
326
+ const lowY = priceScale(candle.low);
327
+ const closeY = priceScale(candle.close);
328
+
329
+ const isBullish = candle.close >= candle.open;
330
+ const candleColor = isBullish
331
+ ? candlestickOptions.bullishColor
332
+ : candlestickOptions.bearishColor;
333
+
334
+ const bodyTop = Math.min(openY, closeY);
335
+ const bodyBottom = Math.max(openY, closeY);
336
+ const bodyHeight = Math.abs(closeY - openY);
337
+
338
+ const isHovered = hoveredCandle?.index === i;
339
+
340
+ // Ensure all values are valid numbers before creating elements
341
+ const xPos = isNaN(x) ? 0 : x;
342
+ const candleWidthHalf = isNaN(candleWidth / 2) ? 0 : candleWidth / 2;
343
+ const safeBodyTop = isNaN(bodyTop) ? 0 : bodyTop;
344
+ const safeBodyHeight = isNaN(bodyHeight) || bodyHeight === 0 ? 1 : Math.abs(bodyHeight);
345
+
346
+ chartElements.push(
347
+ <g key={`candle-${i}`}>
348
+ {/* High-Low line (wick) */}
349
+ <line
350
+ x1={isNaN(xPos) ? 0 : xPos}
351
+ y1={isNaN(highY) ? 0 : highY}
352
+ x2={isNaN(xPos) ? 0 : xPos}
353
+ y2={isNaN(lowY) ? 0 : lowY}
354
+ stroke={candleColor}
355
+ className={`c-chart__wick ${isHovered ? 'c-chart__wick--hovered' : ''}`}
356
+ />
357
+
358
+ {/* Candle body */}
359
+ <rect
360
+ x={xPos - candleWidthHalf}
361
+ y={safeBodyTop}
362
+ width={isNaN(candleWidth) ? 0 : candleWidth}
363
+ height={safeBodyHeight}
364
+ fill={isBullish ? candleColor : candleColor}
365
+ stroke={candleColor}
366
+ className={`c-chart__candlestick ${isBullish ? 'c-chart__candlestick--bullish' : 'c-chart__candlestick--bearish'}`}
367
+ onMouseEnter={e => {
368
+ const rect = e.currentTarget.ownerSVGElement?.getBoundingClientRect();
369
+ const clientX = rect ? rect.left + xPos : e.clientX;
370
+ const clientY = rect ? rect.top + safeBodyTop : e.clientY;
371
+ setHoveredCandle({ index: i, x: clientX, y: clientY, data: candle });
372
+ }}
373
+ onMouseLeave={() => setHoveredCandle(null)}
374
+ onClick={() => onDataPointClick?.(candle as any, 0, i)}
375
+ />
376
+
377
+ {/* Hover highlight */}
378
+ {isHovered && (
379
+ <rect
380
+ x={xPos - candleWidthHalf - 2}
381
+ y={safeBodyTop - 2}
382
+ width={isNaN(candleWidth + 4) ? 0 : candleWidth + 4}
383
+ height={isNaN(safeBodyHeight + 4) ? 5 : Math.max(safeBodyHeight + 4, 5)}
384
+ fill="none"
385
+ stroke={candleColor}
386
+ className="c-chart__candlestick-highlight"
387
+ />
388
+ )}
389
+ </g>
390
+ );
391
+ });
392
+
393
+ // Moving averages
394
+ if (candlestickOptions.showMovingAverages && candlestickOptions.movingAveragePeriods) {
395
+ candlestickOptions.movingAveragePeriods.forEach((period, periodIndex) => {
396
+ const movingAverage = calculateMovingAverage(candlestickData, period);
397
+ const color = candlestickOptions.movingAverageColors?.[periodIndex] || '#FFD93D';
398
+
399
+ const pathData = movingAverage
400
+ .map((value, i) => {
401
+ if (isNaN(value)) return '';
402
+ const x = xScale(i);
403
+ const y = priceScale(value);
404
+ if (i === 0) return `M ${isNaN(x) ? 0 : x},${isNaN(y) ? 0 : y}`;
405
+ const prevValue = movingAverage[i - 1];
406
+ return prevValue !== undefined && isNaN(prevValue)
407
+ ? `M ${isNaN(x) ? 0 : x},${isNaN(y) ? 0 : y}`
408
+ : `L ${isNaN(x) ? 0 : x},${isNaN(y) ? 0 : y}`;
409
+ })
410
+ .join(' ');
411
+
412
+ chartElements.push(
413
+ <path
414
+ key={`ma-${period}`}
415
+ d={pathData}
416
+ stroke={color}
417
+ fill="none"
418
+ className="c-chart__moving-average"
419
+ />
420
+ );
421
+ });
422
+ }
423
+
424
+ // Crosshair
425
+ if (crosshair && candlestickOptions.enableCrosshair) {
426
+ chartElements.push(
427
+ <g key="crosshair" className="c-chart__crosshair">
428
+ <line
429
+ x1={isNaN(crosshair.x) ? 0 : crosshair.x}
430
+ y1={padding.top}
431
+ x2={isNaN(crosshair.x) ? 0 : crosshair.x}
432
+ y2={chartHeight + padding.top}
433
+ className="c-chart__crosshair-line c-chart__crosshair-line--vertical"
434
+ />
435
+ <line
436
+ x1={padding.left}
437
+ y1={isNaN(crosshair.y) ? 0 : crosshair.y}
438
+ x2={width - padding.right}
439
+ y2={isNaN(crosshair.y) ? 0 : crosshair.y}
440
+ className="c-chart__crosshair-line c-chart__crosshair-line--horizontal"
441
+ />
442
+ </g>
443
+ );
444
+ }
445
+
446
+ // Grid
447
+ const grid = (
448
+ <g className={CHART.GRID_CLASS}>
449
+ {/* Horizontal price grid lines */}
450
+ {config.yAxis?.showGrid &&
451
+ Array.from({ length: 6 }).map((_, i) => {
452
+ const price = minPrice + (priceRange * i) / 5;
453
+ const yPos = priceScale(price);
454
+ return (
455
+ <line
456
+ key={`price-grid-${i}`}
457
+ x1={padding.left}
458
+ y1={isNaN(yPos) ? 0 : yPos}
459
+ x2={width - padding.right}
460
+ y2={isNaN(yPos) ? 0 : yPos}
461
+ stroke="#e5e7eb"
462
+ strokeWidth={1}
463
+ strokeDasharray="2,2"
464
+ opacity={0.2}
465
+ />
466
+ );
467
+ })}
468
+
469
+ {/* Vertical time grid lines */}
470
+ {config.xAxis?.showGrid &&
471
+ candlestickData.map((_, i) => {
472
+ if (i % Math.ceil(candlestickData.length / 10) !== 0) return null;
473
+ const xPos = xScale(i);
474
+ return (
475
+ <line
476
+ key={`time-grid-${i}`}
477
+ x1={isNaN(xPos) ? 0 : xPos}
478
+ y1={padding.top}
479
+ x2={isNaN(xPos) ? 0 : xPos}
480
+ y2={chartHeight + padding.top}
481
+ stroke="#e5e7eb"
482
+ strokeWidth={1}
483
+ strokeDasharray="2,2"
484
+ opacity={0.2}
485
+ />
486
+ );
487
+ })}
488
+ </g>
489
+ );
490
+
491
+ // Axes
492
+ const axes = (
493
+ <>
494
+ {/* Price axis (Y-axis) */}
495
+ <g className={`${CHART.AXIS_CLASS} ${CHART.AXIS_CLASS}--y`}>
496
+ <line
497
+ x1={padding.left}
498
+ y1={padding.top}
499
+ x2={padding.left}
500
+ y2={chartHeight + padding.top}
501
+ stroke="#e5e7eb"
502
+ strokeWidth={1}
503
+ />
504
+ {Array.from({ length: 6 }).map((_, i) => {
505
+ const price = minPrice + (priceRange * i) / 5;
506
+ const yPos = priceScale(price);
507
+ return (
508
+ <g key={`price-axis-${i}`}>
509
+ <line
510
+ x1={padding.left - 5}
511
+ y1={isNaN(yPos) ? 0 : yPos}
512
+ x2={padding.left}
513
+ y2={isNaN(yPos) ? 0 : yPos}
514
+ stroke="#e5e7eb"
515
+ strokeWidth={1}
516
+ />
517
+ <text
518
+ x={padding.left - 10}
519
+ y={isNaN(yPos) ? 0 : yPos}
520
+ textAnchor="end"
521
+ dominantBaseline="middle"
522
+ fontSize="12"
523
+ fill="#374151"
524
+ >
525
+ ${price.toFixed(candlestickOptions.pricePrecision)}
526
+ </text>
527
+ </g>
528
+ );
529
+ })}
530
+ </g>
531
+
532
+ {/* Time axis (X-axis) */}
533
+ <g className={`${CHART.AXIS_CLASS} ${CHART.AXIS_CLASS}--x`}>
534
+ <line
535
+ x1={padding.left}
536
+ y1={chartHeight + padding.top}
537
+ x2={width - padding.right}
538
+ y2={chartHeight + padding.top}
539
+ stroke="#e5e7eb"
540
+ strokeWidth={1}
541
+ />
542
+ {candlestickData.map((candle, i) => {
543
+ if (i % Math.ceil(candlestickData.length / 8) !== 0) return null;
544
+ const xPos = xScale(i);
545
+ return (
546
+ <g key={`time-axis-${i}`}>
547
+ <line
548
+ x1={isNaN(xPos) ? 0 : xPos}
549
+ y1={chartHeight + padding.top}
550
+ x2={isNaN(xPos) ? 0 : xPos}
551
+ y2={chartHeight + padding.top + 5}
552
+ stroke="#e5e7eb"
553
+ strokeWidth={1}
554
+ />
555
+ <text
556
+ x={isNaN(xPos) ? 0 : xPos}
557
+ y={chartHeight + padding.top + 20}
558
+ textAnchor="middle"
559
+ fontSize="12"
560
+ fill="#374151"
561
+ >
562
+ {formatDate(candle.date)}
563
+ </text>
564
+ </g>
565
+ );
566
+ })}
567
+ </g>
568
+
569
+ {/* Volume axis (if enabled) */}
570
+ {candlestickOptions.showVolume && candlesWithVolume.length > 0 && (
571
+ <g className={`${CHART.AXIS_CLASS} ${CHART.AXIS_CLASS}--volume`}>
572
+ <line
573
+ x1={width - padding.right}
574
+ y1={chartHeight + padding.top + 10}
575
+ x2={width - padding.right}
576
+ y2={height - padding.bottom}
577
+ stroke="#e5e7eb"
578
+ strokeWidth={1}
579
+ />
580
+ {Array.from({ length: 3 }).map((_, i) => {
581
+ const volume = (safeMaxVolume * (i + 1)) / 3;
582
+ const yPos = volumeScale(volume);
583
+ return (
584
+ <g key={`volume-axis-${i}`}>
585
+ <line
586
+ x1={width - padding.right}
587
+ y1={isNaN(yPos) ? 0 : yPos}
588
+ x2={width - padding.right + 5}
589
+ y2={isNaN(yPos) ? 0 : yPos}
590
+ stroke="#e5e7eb"
591
+ strokeWidth={1}
592
+ />
593
+ <text
594
+ x={width - padding.right + 10}
595
+ y={isNaN(yPos) ? 0 : yPos}
596
+ textAnchor="start"
597
+ dominantBaseline="middle"
598
+ fontSize="10"
599
+ fill="#374151"
600
+ >
601
+ {volume > 1000000
602
+ ? `${(volume / 1000000).toFixed(1)}M`
603
+ : volume > 1000
604
+ ? `${(volume / 1000).toFixed(0)}K`
605
+ : `${Math.round(volume)}`}
606
+ </text>
607
+ </g>
608
+ );
609
+ })}
610
+ </g>
611
+ )}
612
+ </>
613
+ );
614
+
615
+ return (
616
+ <svg
617
+ width="100%"
618
+ height="100%"
619
+ viewBox={`0 0 ${width} ${height}`}
620
+ preserveAspectRatio="xMidYMid meet"
621
+ onMouseMove={e => {
622
+ if (!candlestickOptions.enableCrosshair) return;
623
+ const rect = e.currentTarget.getBoundingClientRect();
624
+ const x = e.clientX - rect.left;
625
+ const y = e.clientY - rect.top;
626
+ setCrosshair({ x, y });
627
+ }}
628
+ onMouseLeave={() => setCrosshair(null)}
629
+ style={{ cursor: 'crosshair' }}
630
+ >
631
+ {grid}
632
+ {axes}
633
+ {chartElements}
634
+ </svg>
635
+ );
636
+ }, [
637
+ candlestickData,
638
+ config,
639
+ candlestickOptions,
640
+ hoveredCandle,
641
+ crosshair,
642
+ zoom,
643
+ calculateMovingAverage,
644
+ formatDate,
645
+ onDataPointClick,
646
+ ]);
647
+
648
+ // OHLC Tooltip custom renderer
649
+ const renderOHLCTooltip = useCallback(
650
+ (dataPoint: any) => {
651
+ if (!hoveredCandle) return null;
652
+
653
+ const { data } = hoveredCandle;
654
+ const isBullish = data.close >= data.open;
655
+ const change = data.close - data.open;
656
+ const changePercent = (change / data.open) * 100;
657
+
658
+ return (
659
+ <div>
660
+ <div style={{ fontWeight: 'bold', marginBottom: '0.5rem' }}>
661
+ {formatDate(data.date)}
662
+ </div>
663
+ <div
664
+ style={{
665
+ display: 'grid',
666
+ gridTemplateColumns: '1fr 1fr',
667
+ gap: '0.25rem',
668
+ fontSize: '0.75rem',
669
+ }}
670
+ >
671
+ <div>
672
+ Open: <strong>${data.open.toFixed(candlestickOptions.pricePrecision)}</strong>
673
+ </div>
674
+ <div>
675
+ High: <strong>${data.high.toFixed(candlestickOptions.pricePrecision)}</strong>
676
+ </div>
677
+ <div>
678
+ Low: <strong>${data.low.toFixed(candlestickOptions.pricePrecision)}</strong>
679
+ </div>
680
+ <div>
681
+ Close: <strong>${data.close.toFixed(candlestickOptions.pricePrecision)}</strong>
682
+ </div>
683
+ </div>
684
+ <div
685
+ style={{
686
+ marginTop: '0.5rem',
687
+ paddingTop: '0.5rem',
688
+ borderTop: '1px solid var(--atomix-gray-3)',
689
+ color: isBullish
690
+ ? candlestickOptions.bullishColor
691
+ : candlestickOptions.bearishColor,
692
+ fontWeight: 'bold',
693
+ }}
694
+ >
695
+ {isBullish ? '+' : ''}
696
+ {change.toFixed(candlestickOptions.pricePrecision)} ({changePercent.toFixed(2)}%)
697
+ </div>
698
+ {data.volume && (
699
+ <div style={{ marginTop: '0.25rem', fontSize: '0.75rem' }}>
700
+ Volume: {data.volume.toLocaleString()}
701
+ </div>
702
+ )}
703
+ </div>
704
+ );
705
+ },
706
+ [candlestickOptions, hoveredCandle, formatDate]
707
+ );
708
+
709
+ return (
710
+ <Chart ref={ref} type="candlestick" datasets={[]} config={config} {...props}>
711
+ {chartContent}
712
+ {candlestickOptions.showOHLCTooltip && hoveredCandle && (
713
+ <ChartTooltip
714
+ dataPoint={{
715
+ label: formatDate(hoveredCandle.data.date),
716
+ value: hoveredCandle.data.close,
717
+ metadata: {
718
+ open: hoveredCandle.data.open,
719
+ high: hoveredCandle.data.high,
720
+ low: hoveredCandle.data.low,
721
+ close: hoveredCandle.data.close,
722
+ volume: hoveredCandle.data.volume,
723
+ },
724
+ }}
725
+ datasetLabel="OHLC"
726
+ position={{ x: hoveredCandle.x, y: hoveredCandle.y }}
727
+ visible={true}
728
+ customRenderer={renderOHLCTooltip}
729
+ />
730
+ )}
731
+ {candlestickOptions.showMovingAverages && candlestickOptions.movingAveragePeriods && (
732
+ <div
733
+ className={CHART.LEGEND_CLASS}
734
+ style={{
735
+ display: 'flex',
736
+ gap: '0.75rem',
737
+ marginTop: '0.5rem',
738
+ fontSize: '0.875rem',
739
+ }}
740
+ >
741
+ {candlestickOptions.movingAveragePeriods.map((period, i) => (
742
+ <div key={period} style={{ display: 'flex', alignItems: 'center' }}>
743
+ <div
744
+ className={CHART.LEGEND_COLOR_CLASS}
745
+ style={{
746
+ width: '12px',
747
+ height: '2px',
748
+ backgroundColor: candlestickOptions.movingAverageColors?.[i] || '#FFD93D',
749
+ marginRight: '0.25rem',
750
+ }}
751
+ />
752
+ <span className={CHART.LEGEND_LABEL_CLASS}>MA{period}</span>
753
+ </div>
754
+ ))}
755
+ </div>
756
+ )}
757
+ </Chart>
758
+ );
759
+ }
760
+ )
761
+ );
762
+
763
+ CandlestickChart.displayName = 'CandlestickChart';
764
+ export default CandlestickChart;
765
+ export type { CandlestickChartProps, CandlestickDataPoint };