@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,397 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import React from 'react';
3
+ import { ImageType } from '../../lib/types/components';
4
+ import { Badge } from '../Badge/Badge';
5
+ import { Button } from '../Button/Button';
6
+ import { PhotoViewer } from './PhotoViewer';
7
+
8
+ const meta: Meta<typeof PhotoViewer> = {
9
+ title: 'Components/PhotoViewer',
10
+ component: PhotoViewer,
11
+ parameters: {
12
+ layout: 'fullscreen',
13
+ docs: {
14
+ description: {
15
+ component:
16
+ 'A modern, fully-featured photo viewer component with zoom, pan, navigation, and metadata display capabilities.',
17
+ },
18
+ },
19
+ },
20
+ argTypes: {
21
+ thumbnailPosition: {
22
+ control: 'select',
23
+ options: ['bottom', 'top', 'left', 'right', 'none'],
24
+ },
25
+ enableKeyboardNavigation: {
26
+ control: 'boolean',
27
+ },
28
+ enableGestures: {
29
+ control: 'boolean',
30
+ },
31
+ enableFullscreen: {
32
+ control: 'boolean',
33
+ },
34
+ },
35
+ };
36
+
37
+ export default meta;
38
+ type Story = StoryObj<typeof PhotoViewer>;
39
+
40
+ // Sample images with rich metadata
41
+ const sampleImages: ImageType[] = [
42
+ {
43
+ src: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200&h=800&fit=crop',
44
+ thumbnail: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=200&h=150&fit=crop',
45
+ alt: 'Mountain landscape at sunset',
46
+ title: 'Mountain Sunset',
47
+ description:
48
+ 'A breathtaking view of mountain peaks bathed in golden sunset light, showcasing the natural beauty of the wilderness.',
49
+ author: 'John Photographer',
50
+ date: '2024-01-15',
51
+ tags: ['landscape', 'mountains', 'sunset', 'nature'],
52
+ },
53
+ {
54
+ src: 'https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=1200&h=800&fit=crop',
55
+ thumbnail: 'https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=200&h=150&fit=crop',
56
+ alt: 'Forest path in autumn',
57
+ title: 'Autumn Forest Path',
58
+ description:
59
+ 'A winding forest path surrounded by vibrant autumn foliage, creating a peaceful and contemplative scene.',
60
+ author: 'Jane Nature',
61
+ date: '2024-01-10',
62
+ tags: ['forest', 'autumn', 'path', 'trees'],
63
+ },
64
+ {
65
+ src: 'https://images.unsplash.com/photo-1518837695005-2083093ee35b?w=1200&h=800&fit=crop',
66
+ thumbnail: 'https://images.unsplash.com/photo-1518837695005-2083093ee35b?w=200&h=150&fit=crop',
67
+ alt: 'Ocean waves on beach',
68
+ title: 'Ocean Waves',
69
+ description:
70
+ 'Powerful ocean waves crashing against the shore, demonstrating the raw energy and beauty of the sea.',
71
+ author: 'Mike Ocean',
72
+ date: '2024-01-05',
73
+ tags: ['ocean', 'waves', 'beach', 'water'],
74
+ },
75
+ {
76
+ src: 'https://images.unsplash.com/photo-1472214103451-9374bd1c798e?w=1200&h=800&fit=crop',
77
+ thumbnail: 'https://images.unsplash.com/photo-1472214103451-9374bd1c798e?w=200&h=150&fit=crop',
78
+ alt: 'City skyline at night',
79
+ title: 'City Lights',
80
+ description:
81
+ 'A stunning nighttime cityscape with illuminated skyscrapers reflecting in the water below.',
82
+ author: 'Sarah City',
83
+ date: '2024-01-01',
84
+ tags: ['city', 'night', 'lights', 'skyline'],
85
+ },
86
+ ];
87
+
88
+ // Interactive demo component
89
+ const PhotoViewerDemo: React.FC<{ images: ImageType[]; startIndex?: number }> = ({
90
+ images,
91
+ startIndex = 0,
92
+ }) => {
93
+ const [isOpen, setIsOpen] = React.useState(false);
94
+ const [currentIndex, setCurrentIndex] = React.useState(startIndex);
95
+
96
+ const openViewer = (index: number) => {
97
+ setCurrentIndex(index);
98
+ setIsOpen(true);
99
+ };
100
+
101
+ return (
102
+ <div className="u-p-6">
103
+ <div className="u-mb-6">
104
+ <h2 className="u-mb-4 u-text-primary">Photo Gallery</h2>
105
+ <p className="u-mb-4 u-text-secondary">
106
+ Click on any image to open the PhotoViewer with full functionality.
107
+ </p>
108
+ <div className="u-d-flex u-gap-4 u-mb-4">
109
+ <Badge variant="primary" label="Zoom & Pan" />
110
+ <Badge variant="secondary" label="Keyboard Navigation" />
111
+ <Badge variant="success" label="Touch Gestures" />
112
+ <Badge variant="info" label="Fullscreen Mode" />
113
+ </div>
114
+ </div>
115
+
116
+ <div
117
+ className="u-d-grid"
118
+ style={{ gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))', gap: '1rem' }}
119
+ >
120
+ {images.map((image, index) => (
121
+ <div key={index} className="u-position-relative u-overflow-hidden u-rounded u-shadow-sm">
122
+ <img
123
+ src={image.thumbnail || image.src}
124
+ alt={image.alt}
125
+ className="u-w-100 u-h-auto"
126
+ style={{ aspectRatio: '4/3', objectFit: 'cover', cursor: 'pointer' }}
127
+ onClick={() => openViewer(index)}
128
+ />
129
+ <div className="u-position-absolute u-bottom-0 u-start-0 u-end-0 u-bg-dark u-bg-opacity-75 u-p-3">
130
+ <h4 className="u-text-white u-fs-sm u-fw-medium u-mb-1">{image.title}</h4>
131
+ <p className="u-text-white u-fs-xs u-opacity-75 u-mb-0">{image.author}</p>
132
+ </div>
133
+ </div>
134
+ ))}
135
+ </div>
136
+
137
+ {isOpen && (
138
+ <PhotoViewer
139
+ images={images}
140
+ startIndex={currentIndex}
141
+ enableKeyboardNavigation={true}
142
+ enableGestures={true}
143
+ enableFullscreen={true}
144
+ thumbnailPosition="bottom"
145
+ onImageChange={setCurrentIndex}
146
+ onClose={() => setIsOpen(false)}
147
+ />
148
+ )}
149
+ </div>
150
+ );
151
+ };
152
+
153
+ /**
154
+ * ## Default PhotoViewer
155
+ *
156
+ * The PhotoViewer component with all features enabled, showcasing the modern design
157
+ * with proper Button, Badge, and Icon components from the Atomix design system.
158
+ */
159
+ export const Default: Story = {
160
+ render: () => <PhotoViewerDemo images={sampleImages} />,
161
+ };
162
+
163
+ /**
164
+ * ## Simple Images
165
+ *
166
+ * PhotoViewer with simple image URLs (no metadata).
167
+ */
168
+ export const SimpleImages: Story = {
169
+ render: () => {
170
+ const simpleImages = [
171
+ 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200&h=800&fit=crop',
172
+ 'https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=1200&h=800&fit=crop',
173
+ 'https://images.unsplash.com/photo-1518837695005-2083093ee35b?w=1200&h=800&fit=crop',
174
+ ];
175
+
176
+ return <PhotoViewerDemo images={simpleImages as unknown as ImageType[]} />;
177
+ },
178
+ };
179
+
180
+ /**
181
+ * ## Rich Metadata
182
+ *
183
+ * PhotoViewer showcasing rich image metadata including titles, descriptions,
184
+ * authors, dates, and tags.
185
+ */
186
+ export const RichMetadata: Story = {
187
+ render: () => {
188
+ const richImages: ImageType[] = [
189
+ {
190
+ src: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200&h=800&fit=crop',
191
+ thumbnail:
192
+ 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=200&h=150&fit=crop',
193
+ alt: 'Mountain landscape at sunset',
194
+ title: 'Majestic Mountain Sunset',
195
+ description:
196
+ 'This stunning photograph captures the serene beauty of mountain peaks bathed in the warm, golden light of a setting sun. The image showcases the dramatic contrast between the dark silhouettes of the mountains and the vibrant colors of the sky, creating a truly breathtaking scene that speaks to the power and majesty of nature.',
197
+ author: 'Alexandra Mountain',
198
+ date: '2024-01-15',
199
+ tags: [
200
+ 'landscape',
201
+ 'mountains',
202
+ 'sunset',
203
+ 'nature',
204
+ 'photography',
205
+ 'golden hour',
206
+ 'scenic',
207
+ ],
208
+ },
209
+ {
210
+ src: 'https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=1200&h=800&fit=crop',
211
+ thumbnail:
212
+ 'https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=200&h=150&fit=crop',
213
+ alt: 'Forest path in autumn',
214
+ title: 'Enchanted Forest Trail',
215
+ description:
216
+ 'A magical forest path winds through a canopy of autumn leaves, creating a tunnel of warm colors that seems to glow with inner light. This peaceful scene invites contemplation and represents the perfect harmony between human-made paths and natural beauty.',
217
+ author: 'Robert Forest',
218
+ date: '2024-01-10',
219
+ tags: ['forest', 'autumn', 'path', 'trees', 'nature', 'hiking', 'peaceful'],
220
+ },
221
+ ];
222
+
223
+ return <PhotoViewerDemo images={richImages} />;
224
+ },
225
+ };
226
+
227
+ /**
228
+ * ## Thumbnail Positions
229
+ *
230
+ * Demonstrates different thumbnail positioning options.
231
+ */
232
+ export const ThumbnailPositions: Story = {
233
+ render: () => {
234
+ const [position, setPosition] = React.useState<'bottom' | 'top' | 'left' | 'right' | 'none'>(
235
+ 'bottom'
236
+ );
237
+ const [isOpen, setIsOpen] = React.useState(false);
238
+
239
+ return (
240
+ <div className="u-p-6">
241
+ <div className="u-mb-6">
242
+ <h2 className="u-mb-4 u-text-primary">Thumbnail Positions</h2>
243
+ <p className="u-mb-4 u-text-secondary">
244
+ Choose a thumbnail position and click "Open Viewer" to see the layout.
245
+ </p>
246
+
247
+ <div className="u-d-flex u-gap-3 u-mb-4">
248
+ {(['bottom', 'top', 'left', 'right', 'none'] as const).map(pos => (
249
+ <Button
250
+ key={pos}
251
+ variant={position === pos ? 'primary' : 'secondary'}
252
+ size="sm"
253
+ onClick={() => setPosition(pos)}
254
+ >
255
+ {pos.charAt(0).toUpperCase() + pos.slice(1)}
256
+ </Button>
257
+ ))}
258
+ </div>
259
+
260
+ <Button onClick={() => setIsOpen(true)}>Open Viewer</Button>
261
+ </div>
262
+
263
+ {isOpen && (
264
+ <PhotoViewer
265
+ images={sampleImages}
266
+ thumbnailPosition={position}
267
+ enableKeyboardNavigation={true}
268
+ enableGestures={true}
269
+ enableFullscreen={true}
270
+ onClose={() => setIsOpen(false)}
271
+ />
272
+ )}
273
+ </div>
274
+ );
275
+ },
276
+ };
277
+
278
+ /**
279
+ * ## Feature Controls
280
+ *
281
+ * Interactive demo showing different feature combinations.
282
+ */
283
+ export const FeatureControls: Story = {
284
+ render: () => {
285
+ const [features, setFeatures] = React.useState({
286
+ keyboard: true,
287
+ gestures: true,
288
+ fullscreen: true,
289
+ });
290
+ const [isOpen, setIsOpen] = React.useState(false);
291
+
292
+ const toggleFeature = (feature: keyof typeof features) => {
293
+ setFeatures(prev => ({ ...prev, [feature]: !prev[feature] }));
294
+ };
295
+
296
+ return (
297
+ <div className="u-p-6">
298
+ <div className="u-mb-6">
299
+ <h2 className="u-mb-4 u-text-primary">Feature Controls</h2>
300
+ <p className="u-mb-4 u-text-secondary">
301
+ Toggle features on/off to see how they affect the PhotoViewer behavior.
302
+ </p>
303
+
304
+ <div className="u-d-flex u-gap-4 u-mb-4">
305
+ <label className="u-d-flex u-align-items-center u-gap-2">
306
+ <input
307
+ type="checkbox"
308
+ checked={features.keyboard}
309
+ onChange={() => toggleFeature('keyboard')}
310
+ />
311
+ <span>Keyboard Navigation</span>
312
+ </label>
313
+ <label className="u-d-flex u-align-items-center u-gap-2">
314
+ <input
315
+ type="checkbox"
316
+ checked={features.gestures}
317
+ onChange={() => toggleFeature('gestures')}
318
+ />
319
+ <span>Touch Gestures</span>
320
+ </label>
321
+ <label className="u-d-flex u-align-items-center u-gap-2">
322
+ <input
323
+ type="checkbox"
324
+ checked={features.fullscreen}
325
+ onChange={() => toggleFeature('fullscreen')}
326
+ />
327
+ <span>Fullscreen Mode</span>
328
+ </label>
329
+ </div>
330
+
331
+ <Button onClick={() => setIsOpen(true)}>Open Viewer</Button>
332
+ </div>
333
+
334
+ {isOpen && (
335
+ <PhotoViewer
336
+ images={sampleImages}
337
+ enableKeyboardNavigation={features.keyboard}
338
+ enableGestures={features.gestures}
339
+ enableFullscreen={features.fullscreen}
340
+ thumbnailPosition="bottom"
341
+ onClose={() => setIsOpen(false)}
342
+ />
343
+ )}
344
+ </div>
345
+ );
346
+ },
347
+ };
348
+
349
+ /**
350
+ * ## Single Image
351
+ *
352
+ * PhotoViewer with a single image (no thumbnails or navigation).
353
+ */
354
+ export const SingleImage: Story = {
355
+ render: () => {
356
+ const singleImage = [sampleImages[0]];
357
+ return (
358
+ <div className="u-w-50 u-h-50">
359
+ <PhotoViewerDemo images={singleImage} />
360
+ </div>
361
+ );
362
+ },
363
+ };
364
+
365
+ /**
366
+ * ## Mobile Optimized
367
+ *
368
+ * Shows how the PhotoViewer adapts to mobile screens with touch gestures.
369
+ */
370
+ export const MobileOptimized: Story = {
371
+ render: () => (
372
+ <div className="u-p-6">
373
+ <div className="u-mb-6">
374
+ <h2 className="u-mb-4 u-text-primary">Mobile Optimized</h2>
375
+ <p className="u-mb-4 u-text-secondary">
376
+ The PhotoViewer is fully responsive and optimized for mobile devices with:
377
+ </p>
378
+ <ul className="u-mb-4">
379
+ <li>Touch gestures for zoom and pan</li>
380
+ <li>Swipe navigation between images</li>
381
+ <li>Responsive controls and thumbnails</li>
382
+ <li>Full-screen info panel on mobile</li>
383
+ </ul>
384
+ <p className="u-text-tertiary u-fs-sm">
385
+ Try this on a mobile device or use browser dev tools to simulate mobile viewport.
386
+ </p>
387
+ </div>
388
+
389
+ <PhotoViewerDemo images={sampleImages} />
390
+ </div>
391
+ ),
392
+ parameters: {
393
+ viewport: {
394
+ defaultViewport: 'mobile1',
395
+ },
396
+ },
397
+ };
@@ -0,0 +1,246 @@
1
+ import React, { useMemo, useEffect } from 'react';
2
+ import { PhotoViewerProps, ImageType } from '../../lib/types/components';
3
+ import { usePhotoViewer } from '../../lib/composables/usePhotoViewer';
4
+ import { PhotoViewerHeader } from './PhotoViewerHeader';
5
+ import { PhotoViewerNavigation } from './PhotoViewerNavigation';
6
+ import { PhotoViewerImage } from './PhotoViewerImage';
7
+ import { PhotoViewerThumbnails } from './PhotoViewerThumbnails';
8
+ import { PhotoViewerInfo } from './PhotoViewerInfo';
9
+
10
+ /**
11
+ * PhotoViewer component - A comprehensive image viewer with zoom, pan, navigation, and metadata display
12
+ *
13
+ * Features:
14
+ * - Image navigation with keyboard support
15
+ * - Zoom and pan functionality
16
+ * - Touch gestures for mobile devices
17
+ * - Fullscreen mode
18
+ * - Image rotation
19
+ * - Download and share capabilities
20
+ * - Thumbnail navigation
21
+ * - Image metadata display
22
+ * - Responsive design
23
+ *
24
+ * @param props - PhotoViewerProps
25
+ * @returns JSX.Element
26
+ */
27
+ export const PhotoViewer: React.FC<PhotoViewerProps> = ({
28
+ images,
29
+ startIndex = 0,
30
+ className = '',
31
+ disabled = false,
32
+ enableKeyboardNavigation = true,
33
+ enableGestures = true,
34
+ enableFullscreen = true,
35
+ thumbnailPosition = 'bottom',
36
+ onImageChange,
37
+ onClose,
38
+ }) => {
39
+ // Use the external composable hook with enhanced features
40
+ const {
41
+ currentIndex,
42
+ zoomLevel,
43
+ imagePosition: dragPosition,
44
+ isDragging,
45
+ isFullscreen,
46
+ rotationAngle,
47
+ showInfo,
48
+ imageRef,
49
+ containerRef,
50
+ isTransitioning,
51
+ setZoomLevel,
52
+ setImagePosition: setDragPosition,
53
+ setIsDragging,
54
+ setIsFullscreen,
55
+ setRotationAngle,
56
+ setShowInfo,
57
+ closeModal,
58
+ goToPrevious,
59
+ goToNext,
60
+ setCurrentIndex: goToImage,
61
+ handleMouseDown,
62
+ handleMouseMove,
63
+ handleMouseUp,
64
+ handleWheel,
65
+ handleTouchStart,
66
+ handleTouchMove,
67
+ handleTouchEnd,
68
+ handleDoubleClick,
69
+ resetImageState,
70
+ } = usePhotoViewer({
71
+ images,
72
+ startIndex,
73
+ enableGestures,
74
+ onImageChange,
75
+ onClose: onClose || (() => {}),
76
+ });
77
+
78
+ // Process images to handle both string arrays and object arrays, ensuring ImageType structure
79
+ const processedImages: ImageType[] = useMemo(() => {
80
+ return images.map(img => (typeof img === 'string' ? { src: img } : img));
81
+ }, [images]);
82
+
83
+ // Current image object
84
+ const currentImage: ImageType | undefined = processedImages[currentIndex];
85
+
86
+ // Handle fullscreen toggle with bounds update
87
+ const handleToggleFullscreen = () => {
88
+ if (!enableFullscreen) return;
89
+
90
+ if (!isFullscreen) {
91
+ const element = document.documentElement;
92
+ if (element.requestFullscreen) {
93
+ element.requestFullscreen();
94
+ }
95
+ } else {
96
+ if (document.exitFullscreen) {
97
+ document.exitFullscreen();
98
+ }
99
+ }
100
+ setIsFullscreen(!isFullscreen);
101
+ };
102
+
103
+ // Handle image rotation with bounds update
104
+ const handleRotate = () => {
105
+ setRotationAngle((angle: number) => (angle + 90) % 360);
106
+ };
107
+
108
+ // Handle image download
109
+ const handleDownload = () => {
110
+ if (!currentImage?.src) return;
111
+
112
+ const link = document.createElement('a');
113
+ link.href = currentImage.src;
114
+ link.download = currentImage.title || `image-${currentIndex + 1}`;
115
+ document.body.appendChild(link);
116
+ link.click();
117
+ document.body.removeChild(link);
118
+ };
119
+
120
+ // Handle image sharing
121
+ const handleShare = async () => {
122
+ if (!navigator.share || !currentImage?.src) return;
123
+
124
+ try {
125
+ await navigator.share({
126
+ title: currentImage.title || 'Shared Image',
127
+ text: currentImage.description || 'Check out this image',
128
+ url: currentImage.src,
129
+ });
130
+ } catch (error) {
131
+ console.error('Error sharing:', error);
132
+ }
133
+ };
134
+
135
+ // Memoize class names
136
+ const photoViewerClasses = useMemo(
137
+ () =>
138
+ [
139
+ 'c-photo-viewer',
140
+ `c-photo-viewer--thumbnails-${thumbnailPosition}`,
141
+ isDragging ? 'c-photo-viewer--dragging' : '',
142
+ isFullscreen ? 'c-photo-viewer--fullscreen' : '',
143
+ showInfo ? 'c-photo-viewer--info-open' : '',
144
+ disabled ? 'is-disabled' : '',
145
+ className,
146
+ ]
147
+ .filter(Boolean)
148
+ .join(' '),
149
+ [isDragging, isFullscreen, showInfo, disabled, thumbnailPosition, className]
150
+ );
151
+
152
+ // Listen for fullscreen changes
153
+ useEffect(() => {
154
+ const handleFullscreenChange = () => {
155
+ setIsFullscreen(!!document.fullscreenElement);
156
+ };
157
+
158
+ document.addEventListener('fullscreenchange', handleFullscreenChange);
159
+ return () => document.removeEventListener('fullscreenchange', handleFullscreenChange);
160
+ }, [setIsFullscreen]);
161
+
162
+ // Add/remove is-open-photoviewer class on body
163
+ useEffect(() => {
164
+ document.body.classList.add('is-open-photoviewer');
165
+
166
+ return () => {
167
+ document.body.classList.remove('is-open-photoviewer');
168
+ };
169
+ }, []);
170
+
171
+ // Early return for empty images array
172
+ if (!images.length) return null;
173
+
174
+ return (
175
+ <div className={photoViewerClasses} role="dialog" aria-modal="true" aria-label="Photo viewer">
176
+ <div className="c-photo-viewer__backdrop" onClick={closeModal} />
177
+ <div className="c-photo-viewer__container">
178
+ <PhotoViewerHeader
179
+ currentIndex={currentIndex}
180
+ imagesLength={images.length}
181
+ onZoomOut={() => setZoomLevel((z: number) => Math.max(z - 0.25, 0.1))}
182
+ onResetZoom={() => {
183
+ resetImageState();
184
+ }}
185
+ onZoomIn={() => setZoomLevel((z: number) => Math.min(z + 0.25, 5))}
186
+ onToggleFullscreen={handleToggleFullscreen}
187
+ onClose={onClose || closeModal}
188
+ isFullscreen={isFullscreen}
189
+ zoomLevel={zoomLevel}
190
+ onRotate={handleRotate}
191
+ onDownload={handleDownload}
192
+ onShare={handleShare}
193
+ showInfo={showInfo}
194
+ onToggleInfo={() => setShowInfo(!showInfo)}
195
+ currentImage={currentImage}
196
+ />
197
+ <div className="c-photo-viewer__content">
198
+ <PhotoViewerNavigation
199
+ show={images.length > 1}
200
+ onPrev={goToPrevious}
201
+ onNext={goToNext}
202
+ currentIndex={currentIndex}
203
+ imagesLength={images.length}
204
+ enableKeyboardNav={enableKeyboardNavigation}
205
+ onClose={onClose || closeModal}
206
+ />
207
+ {currentImage?.src && (
208
+ <PhotoViewerImage
209
+ imageRef={imageRef}
210
+ containerRef={containerRef}
211
+ src={currentImage.src}
212
+ alt={currentImage?.alt || `Image ${currentIndex + 1}`}
213
+ zoomLevel={zoomLevel}
214
+ dragPosition={dragPosition}
215
+ isDragging={isDragging}
216
+ rotationAngle={rotationAngle}
217
+ isTransitioning={isTransitioning}
218
+ onMouseDown={handleMouseDown}
219
+ onMouseMove={handleMouseMove}
220
+ onMouseUp={handleMouseUp}
221
+ onWheel={handleWheel}
222
+ onTouchStart={handleTouchStart}
223
+ onTouchMove={handleTouchMove}
224
+ onTouchEnd={handleTouchEnd}
225
+ onDoubleClick={handleDoubleClick}
226
+ />
227
+ )}
228
+ </div>
229
+ {thumbnailPosition !== 'none' && (
230
+ <PhotoViewerThumbnails
231
+ images={processedImages}
232
+ currentIndex={currentIndex}
233
+ goToImage={goToImage}
234
+ />
235
+ )}
236
+ <PhotoViewerInfo show={showInfo} image={currentImage} onClose={() => setShowInfo(false)} />
237
+ </div>
238
+ </div>
239
+ );
240
+ };
241
+
242
+ export type { PhotoViewerProps };
243
+
244
+ PhotoViewer.displayName = 'PhotoViewer';
245
+
246
+ export default PhotoViewer;