@gabvdl/ui 0.0.14

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 (330) hide show
  1. package/README.md +95 -0
  2. package/dist/components/button/button.d.ts +39 -0
  3. package/dist/components/button/button.d.ts.map +1 -0
  4. package/dist/components/button/button.js +72 -0
  5. package/dist/components/button/button.js.map +1 -0
  6. package/dist/components/button/index.d.ts +5 -0
  7. package/dist/components/button/index.d.ts.map +1 -0
  8. package/dist/components/button/tooltip.d.ts +31 -0
  9. package/dist/components/button/tooltip.d.ts.map +1 -0
  10. package/dist/components/button/tooltip.js +83 -0
  11. package/dist/components/button/tooltip.js.map +1 -0
  12. package/dist/components/changelog/changelog.d.ts +52 -0
  13. package/dist/components/changelog/changelog.d.ts.map +1 -0
  14. package/dist/components/changelog/changelog.js +164 -0
  15. package/dist/components/changelog/changelog.js.map +1 -0
  16. package/dist/components/changelog/index.d.ts +3 -0
  17. package/dist/components/changelog/index.d.ts.map +1 -0
  18. package/dist/components/copy-button/copy-button.d.ts +16 -0
  19. package/dist/components/copy-button/copy-button.d.ts.map +1 -0
  20. package/dist/components/copy-button/copy-button.js +40 -0
  21. package/dist/components/copy-button/copy-button.js.map +1 -0
  22. package/dist/components/copy-button/index.d.ts +3 -0
  23. package/dist/components/copy-button/index.d.ts.map +1 -0
  24. package/dist/components/drop-zone/drop-zone.d.ts +20 -0
  25. package/dist/components/drop-zone/drop-zone.d.ts.map +1 -0
  26. package/dist/components/drop-zone/drop-zone.js +54 -0
  27. package/dist/components/drop-zone/drop-zone.js.map +1 -0
  28. package/dist/components/drop-zone/index.d.ts +5 -0
  29. package/dist/components/drop-zone/index.d.ts.map +1 -0
  30. package/dist/components/drop-zone/use-file-drop.d.ts +45 -0
  31. package/dist/components/drop-zone/use-file-drop.d.ts.map +1 -0
  32. package/dist/components/drop-zone/use-file-drop.js +97 -0
  33. package/dist/components/drop-zone/use-file-drop.js.map +1 -0
  34. package/dist/components/element-picker/element-picker-field.d.ts +30 -0
  35. package/dist/components/element-picker/element-picker-field.d.ts.map +1 -0
  36. package/dist/components/element-picker/element-picker-field.js +273 -0
  37. package/dist/components/element-picker/element-picker-field.js.map +1 -0
  38. package/dist/components/element-picker/element-picker.d.ts +45 -0
  39. package/dist/components/element-picker/element-picker.d.ts.map +1 -0
  40. package/dist/components/element-picker/element-picker.js +179 -0
  41. package/dist/components/element-picker/element-picker.js.map +1 -0
  42. package/dist/components/element-picker/element-preview.d.ts +23 -0
  43. package/dist/components/element-picker/element-preview.d.ts.map +1 -0
  44. package/dist/components/element-picker/element-preview.js +72 -0
  45. package/dist/components/element-picker/element-preview.js.map +1 -0
  46. package/dist/components/element-picker/index.d.ts +12 -0
  47. package/dist/components/element-picker/index.d.ts.map +1 -0
  48. package/dist/components/element-picker/parse.d.ts +32 -0
  49. package/dist/components/element-picker/parse.d.ts.map +1 -0
  50. package/dist/components/element-picker/parse.js +230 -0
  51. package/dist/components/element-picker/parse.js.map +1 -0
  52. package/dist/components/element-picker/types.d.ts +72 -0
  53. package/dist/components/element-picker/types.d.ts.map +1 -0
  54. package/dist/components/element-picker/use-element-picker.d.ts +56 -0
  55. package/dist/components/element-picker/use-element-picker.d.ts.map +1 -0
  56. package/dist/components/element-picker/use-element-picker.js +201 -0
  57. package/dist/components/element-picker/use-element-picker.js.map +1 -0
  58. package/dist/components/empty-state/empty-state.d.ts +16 -0
  59. package/dist/components/empty-state/empty-state.d.ts.map +1 -0
  60. package/dist/components/empty-state/empty-state.js +41 -0
  61. package/dist/components/empty-state/empty-state.js.map +1 -0
  62. package/dist/components/empty-state/index.d.ts +3 -0
  63. package/dist/components/empty-state/index.d.ts.map +1 -0
  64. package/dist/components/floating-panel/dock-context.d.ts +66 -0
  65. package/dist/components/floating-panel/dock-context.d.ts.map +1 -0
  66. package/dist/components/floating-panel/dock-context.js +96 -0
  67. package/dist/components/floating-panel/dock-context.js.map +1 -0
  68. package/dist/components/floating-panel/dock.d.ts +26 -0
  69. package/dist/components/floating-panel/dock.d.ts.map +1 -0
  70. package/dist/components/floating-panel/dock.js +46 -0
  71. package/dist/components/floating-panel/dock.js.map +1 -0
  72. package/dist/components/floating-panel/floating-panel.d.ts +69 -0
  73. package/dist/components/floating-panel/floating-panel.d.ts.map +1 -0
  74. package/dist/components/floating-panel/floating-panel.js +285 -0
  75. package/dist/components/floating-panel/floating-panel.js.map +1 -0
  76. package/dist/components/floating-panel/index.d.ts +7 -0
  77. package/dist/components/floating-panel/index.d.ts.map +1 -0
  78. package/dist/components/fuzzy-list/fuzzy-list.d.ts +96 -0
  79. package/dist/components/fuzzy-list/fuzzy-list.d.ts.map +1 -0
  80. package/dist/components/fuzzy-list/fuzzy-list.js +127 -0
  81. package/dist/components/fuzzy-list/fuzzy-list.js.map +1 -0
  82. package/dist/components/fuzzy-list/index.d.ts +4 -0
  83. package/dist/components/fuzzy-list/index.d.ts.map +1 -0
  84. package/dist/components/global-search/global-search.d.ts +78 -0
  85. package/dist/components/global-search/global-search.d.ts.map +1 -0
  86. package/dist/components/global-search/global-search.js +181 -0
  87. package/dist/components/global-search/global-search.js.map +1 -0
  88. package/dist/components/global-search/hotkey.d.ts +23 -0
  89. package/dist/components/global-search/hotkey.d.ts.map +1 -0
  90. package/dist/components/global-search/hotkey.js +41 -0
  91. package/dist/components/global-search/hotkey.js.map +1 -0
  92. package/dist/components/global-search/index.d.ts +5 -0
  93. package/dist/components/global-search/index.d.ts.map +1 -0
  94. package/dist/components/iframe-preview/iframe-preview.d.ts +64 -0
  95. package/dist/components/iframe-preview/iframe-preview.d.ts.map +1 -0
  96. package/dist/components/iframe-preview/iframe-preview.js +257 -0
  97. package/dist/components/iframe-preview/iframe-preview.js.map +1 -0
  98. package/dist/components/iframe-preview/index.d.ts +3 -0
  99. package/dist/components/iframe-preview/index.d.ts.map +1 -0
  100. package/dist/components/image-viewer/image-viewer.d.ts +30 -0
  101. package/dist/components/image-viewer/image-viewer.d.ts.map +1 -0
  102. package/dist/components/image-viewer/image-viewer.js +226 -0
  103. package/dist/components/image-viewer/image-viewer.js.map +1 -0
  104. package/dist/components/image-viewer/index.d.ts +4 -0
  105. package/dist/components/image-viewer/index.d.ts.map +1 -0
  106. package/dist/components/image-viewer/progressive-image.d.ts +20 -0
  107. package/dist/components/image-viewer/progressive-image.d.ts.map +1 -0
  108. package/dist/components/image-viewer/progressive-image.js +62 -0
  109. package/dist/components/image-viewer/progressive-image.js.map +1 -0
  110. package/dist/components/image-viewer/viewable-image.d.ts +17 -0
  111. package/dist/components/image-viewer/viewable-image.d.ts.map +1 -0
  112. package/dist/components/image-viewer/viewable-image.js +38 -0
  113. package/dist/components/image-viewer/viewable-image.js.map +1 -0
  114. package/dist/components/input/index.d.ts +3 -0
  115. package/dist/components/input/index.d.ts.map +1 -0
  116. package/dist/components/input/input.d.ts +15 -0
  117. package/dist/components/input/input.d.ts.map +1 -0
  118. package/dist/components/input/input.js +56 -0
  119. package/dist/components/input/input.js.map +1 -0
  120. package/dist/components/modal/index.d.ts +5 -0
  121. package/dist/components/modal/index.d.ts.map +1 -0
  122. package/dist/components/modal/modal-context.d.ts +37 -0
  123. package/dist/components/modal/modal-context.d.ts.map +1 -0
  124. package/dist/components/modal/modal-context.js +81 -0
  125. package/dist/components/modal/modal-context.js.map +1 -0
  126. package/dist/components/modal/modal.d.ts +28 -0
  127. package/dist/components/modal/modal.d.ts.map +1 -0
  128. package/dist/components/modal/modal.js +94 -0
  129. package/dist/components/modal/modal.js.map +1 -0
  130. package/dist/components/nav-2d/index.d.ts +3 -0
  131. package/dist/components/nav-2d/index.d.ts.map +1 -0
  132. package/dist/components/nav-2d/nav-2d.d.ts +59 -0
  133. package/dist/components/nav-2d/nav-2d.d.ts.map +1 -0
  134. package/dist/components/nav-2d/nav-2d.js +290 -0
  135. package/dist/components/nav-2d/nav-2d.js.map +1 -0
  136. package/dist/components/phone-preview/index.d.ts +3 -0
  137. package/dist/components/phone-preview/index.d.ts.map +1 -0
  138. package/dist/components/phone-preview/phone-preview.d.ts +45 -0
  139. package/dist/components/phone-preview/phone-preview.d.ts.map +1 -0
  140. package/dist/components/phone-preview/phone-preview.js +117 -0
  141. package/dist/components/phone-preview/phone-preview.js.map +1 -0
  142. package/dist/components/progressive-bash/index.d.ts +7 -0
  143. package/dist/components/progressive-bash/index.d.ts.map +1 -0
  144. package/dist/components/progressive-bash/parse.d.ts +88 -0
  145. package/dist/components/progressive-bash/parse.d.ts.map +1 -0
  146. package/dist/components/progressive-bash/parse.js +120 -0
  147. package/dist/components/progressive-bash/parse.js.map +1 -0
  148. package/dist/components/progressive-bash/playback.d.ts +50 -0
  149. package/dist/components/progressive-bash/playback.d.ts.map +1 -0
  150. package/dist/components/progressive-bash/playback.js +19 -0
  151. package/dist/components/progressive-bash/playback.js.map +1 -0
  152. package/dist/components/progressive-bash/progressive-bash.d.ts +97 -0
  153. package/dist/components/progressive-bash/progressive-bash.d.ts.map +1 -0
  154. package/dist/components/progressive-bash/progressive-bash.js +377 -0
  155. package/dist/components/progressive-bash/progressive-bash.js.map +1 -0
  156. package/dist/components/progressive-list/index.d.ts +3 -0
  157. package/dist/components/progressive-list/index.d.ts.map +1 -0
  158. package/dist/components/progressive-list/progressive-list.d.ts +55 -0
  159. package/dist/components/progressive-list/progressive-list.d.ts.map +1 -0
  160. package/dist/components/progressive-list/progressive-list.js +83 -0
  161. package/dist/components/progressive-list/progressive-list.js.map +1 -0
  162. package/dist/components/progressive-table/index.d.ts +3 -0
  163. package/dist/components/progressive-table/index.d.ts.map +1 -0
  164. package/dist/components/progressive-table/progressive-table.d.ts +58 -0
  165. package/dist/components/progressive-table/progressive-table.d.ts.map +1 -0
  166. package/dist/components/progressive-table/progressive-table.js +86 -0
  167. package/dist/components/progressive-table/progressive-table.js.map +1 -0
  168. package/dist/components/progressive-text/index.d.ts +3 -0
  169. package/dist/components/progressive-text/index.d.ts.map +1 -0
  170. package/dist/components/progressive-text/progressive-text.d.ts +54 -0
  171. package/dist/components/progressive-text/progressive-text.d.ts.map +1 -0
  172. package/dist/components/progressive-text/progressive-text.js +97 -0
  173. package/dist/components/progressive-text/progressive-text.js.map +1 -0
  174. package/dist/components/progressive-timeline/index.d.ts +3 -0
  175. package/dist/components/progressive-timeline/index.d.ts.map +1 -0
  176. package/dist/components/progressive-timeline/progressive-timeline.d.ts +46 -0
  177. package/dist/components/progressive-timeline/progressive-timeline.d.ts.map +1 -0
  178. package/dist/components/progressive-timeline/progressive-timeline.js +62 -0
  179. package/dist/components/progressive-timeline/progressive-timeline.js.map +1 -0
  180. package/dist/components/relative-time/index.d.ts +3 -0
  181. package/dist/components/relative-time/index.d.ts.map +1 -0
  182. package/dist/components/relative-time/relative-time.d.ts +14 -0
  183. package/dist/components/relative-time/relative-time.d.ts.map +1 -0
  184. package/dist/components/relative-time/relative-time.js +15 -0
  185. package/dist/components/relative-time/relative-time.js.map +1 -0
  186. package/dist/components/resizable-layout/index.d.ts +3 -0
  187. package/dist/components/resizable-layout/index.d.ts.map +1 -0
  188. package/dist/components/resizable-layout/resizable-layout.d.ts +113 -0
  189. package/dist/components/resizable-layout/resizable-layout.d.ts.map +1 -0
  190. package/dist/components/resizable-layout/resizable-layout.js +398 -0
  191. package/dist/components/resizable-layout/resizable-layout.js.map +1 -0
  192. package/dist/components/rich-input/compose.d.ts +13 -0
  193. package/dist/components/rich-input/compose.d.ts.map +1 -0
  194. package/dist/components/rich-input/compose.js +28 -0
  195. package/dist/components/rich-input/compose.js.map +1 -0
  196. package/dist/components/rich-input/index.d.ts +5 -0
  197. package/dist/components/rich-input/index.d.ts.map +1 -0
  198. package/dist/components/rich-input/parts.d.ts +53 -0
  199. package/dist/components/rich-input/parts.d.ts.map +1 -0
  200. package/dist/components/rich-input/parts.js +285 -0
  201. package/dist/components/rich-input/parts.js.map +1 -0
  202. package/dist/components/rich-input/rich-input.d.ts +64 -0
  203. package/dist/components/rich-input/rich-input.d.ts.map +1 -0
  204. package/dist/components/rich-input/rich-input.js +351 -0
  205. package/dist/components/rich-input/rich-input.js.map +1 -0
  206. package/dist/components/rich-input/types.d.ts +92 -0
  207. package/dist/components/rich-input/types.d.ts.map +1 -0
  208. package/dist/components/rich-input/use-draft.d.ts +9 -0
  209. package/dist/components/rich-input/use-draft.d.ts.map +1 -0
  210. package/dist/components/rich-input/use-draft.js +47 -0
  211. package/dist/components/rich-input/use-draft.js.map +1 -0
  212. package/dist/components/rich-input/use-file-upload.d.ts +18 -0
  213. package/dist/components/rich-input/use-file-upload.d.ts.map +1 -0
  214. package/dist/components/rich-input/use-file-upload.js +88 -0
  215. package/dist/components/rich-input/use-file-upload.js.map +1 -0
  216. package/dist/components/rich-input/use-guidelines.d.ts +16 -0
  217. package/dist/components/rich-input/use-guidelines.d.ts.map +1 -0
  218. package/dist/components/rich-input/use-guidelines.js +85 -0
  219. package/dist/components/rich-input/use-guidelines.js.map +1 -0
  220. package/dist/components/rich-input/use-input-history.d.ts +22 -0
  221. package/dist/components/rich-input/use-input-history.d.ts.map +1 -0
  222. package/dist/components/rich-input/use-input-history.js +61 -0
  223. package/dist/components/rich-input/use-input-history.js.map +1 -0
  224. package/dist/components/rich-input/use-mention.d.ts +24 -0
  225. package/dist/components/rich-input/use-mention.d.ts.map +1 -0
  226. package/dist/components/rich-input/use-mention.js +54 -0
  227. package/dist/components/rich-input/use-mention.js.map +1 -0
  228. package/dist/components/search-input/index.d.ts +3 -0
  229. package/dist/components/search-input/index.d.ts.map +1 -0
  230. package/dist/components/search-input/search-input.d.ts +14 -0
  231. package/dist/components/search-input/search-input.d.ts.map +1 -0
  232. package/dist/components/search-input/search-input.js +63 -0
  233. package/dist/components/search-input/search-input.js.map +1 -0
  234. package/dist/components/skeleton/index.d.ts +3 -0
  235. package/dist/components/skeleton/index.d.ts.map +1 -0
  236. package/dist/components/skeleton/skeleton.d.ts +19 -0
  237. package/dist/components/skeleton/skeleton.d.ts.map +1 -0
  238. package/dist/components/skeleton/skeleton.js +29 -0
  239. package/dist/components/skeleton/skeleton.js.map +1 -0
  240. package/dist/components/spinner/index.d.ts +3 -0
  241. package/dist/components/spinner/index.d.ts.map +1 -0
  242. package/dist/components/spinner/spinner.d.ts +11 -0
  243. package/dist/components/spinner/spinner.d.ts.map +1 -0
  244. package/dist/components/spinner/spinner.js +32 -0
  245. package/dist/components/spinner/spinner.js.map +1 -0
  246. package/dist/components/status-badge/index.d.ts +3 -0
  247. package/dist/components/status-badge/index.d.ts.map +1 -0
  248. package/dist/components/status-badge/status-badge.d.ts +31 -0
  249. package/dist/components/status-badge/status-badge.d.ts.map +1 -0
  250. package/dist/components/status-badge/status-badge.js +53 -0
  251. package/dist/components/status-badge/status-badge.js.map +1 -0
  252. package/dist/components/theme/index.d.ts +5 -0
  253. package/dist/components/theme/index.d.ts.map +1 -0
  254. package/dist/components/theme/theme-toggle.d.ts +11 -0
  255. package/dist/components/theme/theme-toggle.d.ts.map +1 -0
  256. package/dist/components/theme/theme-toggle.js +57 -0
  257. package/dist/components/theme/theme-toggle.js.map +1 -0
  258. package/dist/components/theme/theme.d.ts +29 -0
  259. package/dist/components/theme/theme.d.ts.map +1 -0
  260. package/dist/components/theme/theme.js +70 -0
  261. package/dist/components/theme/theme.js.map +1 -0
  262. package/dist/components/toast/index.d.ts +3 -0
  263. package/dist/components/toast/index.d.ts.map +1 -0
  264. package/dist/components/toast/toast.d.ts +64 -0
  265. package/dist/components/toast/toast.d.ts.map +1 -0
  266. package/dist/components/toast/toast.js +155 -0
  267. package/dist/components/toast/toast.js.map +1 -0
  268. package/dist/components/virtual-list/index.d.ts +3 -0
  269. package/dist/components/virtual-list/index.d.ts.map +1 -0
  270. package/dist/components/virtual-list/virtual-list.d.ts +71 -0
  271. package/dist/components/virtual-list/virtual-list.d.ts.map +1 -0
  272. package/dist/components/virtual-list/virtual-list.js +65 -0
  273. package/dist/components/virtual-list/virtual-list.js.map +1 -0
  274. package/dist/hooks/index.d.ts +12 -0
  275. package/dist/hooks/index.d.ts.map +1 -0
  276. package/dist/hooks/use-copy-to-clipboard.d.ts +26 -0
  277. package/dist/hooks/use-copy-to-clipboard.d.ts.map +1 -0
  278. package/dist/hooks/use-copy-to-clipboard.js +36 -0
  279. package/dist/hooks/use-copy-to-clipboard.js.map +1 -0
  280. package/dist/hooks/use-debounced-value.d.ts +23 -0
  281. package/dist/hooks/use-debounced-value.d.ts.map +1 -0
  282. package/dist/hooks/use-debounced-value.js +19 -0
  283. package/dist/hooks/use-debounced-value.js.map +1 -0
  284. package/dist/hooks/use-intersection.d.ts +25 -0
  285. package/dist/hooks/use-intersection.d.ts.map +1 -0
  286. package/dist/hooks/use-intersection.js +38 -0
  287. package/dist/hooks/use-intersection.js.map +1 -0
  288. package/dist/hooks/use-local-storage.d.ts +12 -0
  289. package/dist/hooks/use-local-storage.d.ts.map +1 -0
  290. package/dist/hooks/use-local-storage.js +43 -0
  291. package/dist/hooks/use-local-storage.js.map +1 -0
  292. package/dist/hooks/use-long-press.d.ts +37 -0
  293. package/dist/hooks/use-long-press.d.ts.map +1 -0
  294. package/dist/hooks/use-long-press.js +39 -0
  295. package/dist/hooks/use-long-press.js.map +1 -0
  296. package/dist/hooks/use-media-query.d.ts +17 -0
  297. package/dist/hooks/use-media-query.d.ts.map +1 -0
  298. package/dist/hooks/use-media-query.js +37 -0
  299. package/dist/hooks/use-media-query.js.map +1 -0
  300. package/dist/hooks/use-overlay.d.ts +20 -0
  301. package/dist/hooks/use-overlay.d.ts.map +1 -0
  302. package/dist/hooks/use-overlay.js +42 -0
  303. package/dist/hooks/use-overlay.js.map +1 -0
  304. package/dist/image-viewer.css +152 -0
  305. package/dist/index.d.ts +67 -0
  306. package/dist/index.d.ts.map +1 -0
  307. package/dist/index.js +161 -0
  308. package/dist/index.js.map +1 -0
  309. package/dist/lib/format.d.ts +19 -0
  310. package/dist/lib/format.d.ts.map +1 -0
  311. package/dist/lib/format.js +62 -0
  312. package/dist/lib/format.js.map +1 -0
  313. package/dist/lib/highlight.d.ts +15 -0
  314. package/dist/lib/highlight.d.ts.map +1 -0
  315. package/dist/lib/highlight.js +39 -0
  316. package/dist/lib/highlight.js.map +1 -0
  317. package/dist/lib/search.d.ts +40 -0
  318. package/dist/lib/search.d.ts.map +1 -0
  319. package/dist/lib/search.js +91 -0
  320. package/dist/lib/search.js.map +1 -0
  321. package/dist/lib/utils.d.ts +4 -0
  322. package/dist/lib/utils.d.ts.map +1 -0
  323. package/dist/lib/utils.js +9 -0
  324. package/dist/lib/utils.js.map +1 -0
  325. package/dist/overlay.css +78 -0
  326. package/dist/styles.css +6 -0
  327. package/dist/theme.css +81 -0
  328. package/dist/tooltip.css +53 -0
  329. package/dist/virtual-list.css +29 -0
  330. package/package.json +77 -0
@@ -0,0 +1,257 @@
1
+ import { jsx as e, jsxs as s, Fragment as X } from "react/jsx-runtime";
2
+ import * as n from "react";
3
+ import { createPortal as q } from "react-dom";
4
+ import { ExternalLink as D, RotateCw as A, Monitor as G, Smartphone as J, X as Q } from "lucide-react";
5
+ import { cn as E } from "../../lib/utils.js";
6
+ import { useScrollLock as V, useEscape as Y } from "../../hooks/use-overlay.js";
7
+ import { Button as m } from "../button/button.js";
8
+ import { Input as Z } from "../input/input.js";
9
+ import { Spinner as U } from "../spinner/spinner.js";
10
+ const ee = 414, te = 6e3;
11
+ function re(t) {
12
+ const o = t.trim();
13
+ return o && (/^[a-z][a-z0-9+.-]*:/i.test(o) ? o : `https://${o}`);
14
+ }
15
+ function oe(t, o) {
16
+ try {
17
+ const a = new URL(t, typeof window > "u" ? void 0 : window.location.href);
18
+ return a.searchParams.set("_ts", String(o)), a.toString();
19
+ } catch {
20
+ return t;
21
+ }
22
+ }
23
+ function ae({
24
+ open: t,
25
+ onClose: o,
26
+ url: a,
27
+ onUrlChange: l,
28
+ title: i,
29
+ editableUrl: w = !0,
30
+ actions: u,
31
+ devices: g = !0,
32
+ device: k,
33
+ onDeviceChange: f,
34
+ cacheBust: p = !1,
35
+ sandbox: N,
36
+ allow: c = "clipboard-write; fullscreen; geolocation",
37
+ className: S,
38
+ children: b
39
+ }) {
40
+ const [d, R] = n.useState(a), [T, y] = n.useState(a), [z, P] = n.useState(0), [H, _] = n.useState(!0), [O, L] = n.useState(!1), [$, F] = n.useState("desktop"), x = k ?? $;
41
+ V(t), Y(o, t), n.useEffect(() => {
42
+ t && (R(a), y(a), P((r) => r + 1));
43
+ }, [t, a]);
44
+ const I = n.useMemo(
45
+ () => p ? oe(d, z) : d,
46
+ [p, d, z]
47
+ ), j = `${I}#${z}`;
48
+ n.useEffect(() => {
49
+ if (!t) return;
50
+ _(!0), L(!1);
51
+ const r = window.setTimeout(() => L(!0), te);
52
+ return () => window.clearTimeout(r);
53
+ }, [t, j]);
54
+ const K = () => P((r) => r + 1), C = (r) => {
55
+ var v, B;
56
+ r.preventDefault();
57
+ const h = re(T);
58
+ h && (y(h), R(h), P((W) => W + 1), l == null || l(h), (B = (v = document.activeElement) == null ? void 0 : v.blur) == null || B.call(v));
59
+ }, M = (r) => {
60
+ F(r), f == null || f(r);
61
+ };
62
+ return !t || typeof document > "u" ? null : q(
63
+ /* @__PURE__ */ s(
64
+ "div",
65
+ {
66
+ className: E(
67
+ "ds-iframe-preview fixed inset-0 z-[95] flex h-[100dvh] w-screen flex-col bg-background text-foreground",
68
+ S
69
+ ),
70
+ role: "dialog",
71
+ "aria-modal": "true",
72
+ "aria-label": i ?? "Preview",
73
+ children: [
74
+ /* @__PURE__ */ s(
75
+ "header",
76
+ {
77
+ className: "flex shrink-0 flex-col gap-1.5 border-b border-border bg-card/80 px-2 py-2 backdrop-blur",
78
+ style: { paddingTop: "max(0.5rem, env(safe-area-inset-top))" },
79
+ children: [
80
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-1", children: [
81
+ /* @__PURE__ */ e(
82
+ m,
83
+ {
84
+ variant: "ghost",
85
+ size: "icon-sm",
86
+ icon: /* @__PURE__ */ e(A, {}),
87
+ "aria-label": "Reload",
88
+ tooltip: "Reload",
89
+ onClick: K
90
+ }
91
+ ),
92
+ w ? /* @__PURE__ */ e("form", { onSubmit: C, className: "min-w-0 flex-1", children: /* @__PURE__ */ e(
93
+ Z,
94
+ {
95
+ value: T,
96
+ onChange: (r) => y(r.target.value),
97
+ onFocus: (r) => r.currentTarget.select(),
98
+ spellCheck: !1,
99
+ autoCapitalize: "off",
100
+ autoCorrect: "off",
101
+ inputMode: "url",
102
+ type: "text",
103
+ "aria-label": "Preview URL",
104
+ className: "h-8 w-full truncate rounded-full px-3 text-xs sm:text-sm"
105
+ }
106
+ ) }) : /* @__PURE__ */ e("span", { className: "min-w-0 flex-1 truncate px-2 text-xs text-muted-foreground sm:text-sm", children: i ?? d }),
107
+ g && /* @__PURE__ */ s("div", { className: "hidden items-center gap-0.5 rounded-full border border-border p-0.5 sm:flex", children: [
108
+ /* @__PURE__ */ e(
109
+ m,
110
+ {
111
+ variant: x === "desktop" ? "default" : "ghost",
112
+ size: "icon-sm",
113
+ icon: /* @__PURE__ */ e(G, {}),
114
+ "aria-label": "Desktop width",
115
+ tooltip: "Desktop",
116
+ className: "rounded-full",
117
+ onClick: () => M("desktop")
118
+ }
119
+ ),
120
+ /* @__PURE__ */ e(
121
+ m,
122
+ {
123
+ variant: x === "phone" ? "default" : "ghost",
124
+ size: "icon-sm",
125
+ icon: /* @__PURE__ */ e(J, {}),
126
+ "aria-label": "Phone width",
127
+ tooltip: "Phone",
128
+ className: "rounded-full",
129
+ onClick: () => M("phone")
130
+ }
131
+ )
132
+ ] }),
133
+ /* @__PURE__ */ e(
134
+ "a",
135
+ {
136
+ href: d,
137
+ target: "_blank",
138
+ rel: "noreferrer noopener",
139
+ "aria-label": "Open in a new tab",
140
+ className: "inline-flex size-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
141
+ children: /* @__PURE__ */ e(D, { className: "size-3.5" })
142
+ }
143
+ ),
144
+ /* @__PURE__ */ e(
145
+ m,
146
+ {
147
+ variant: "ghost",
148
+ size: "icon-sm",
149
+ icon: /* @__PURE__ */ e(Q, {}),
150
+ "aria-label": "Close preview",
151
+ tooltip: "Close",
152
+ onClick: o
153
+ }
154
+ )
155
+ ] }),
156
+ u && /* @__PURE__ */ e("div", { className: "-mx-1 flex items-center gap-1 overflow-x-auto px-1 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden", children: u })
157
+ ]
158
+ }
159
+ ),
160
+ b,
161
+ /* @__PURE__ */ s("div", { className: "relative min-h-0 flex-1 bg-muted/30", children: [
162
+ /* @__PURE__ */ e(
163
+ "div",
164
+ {
165
+ className: E(
166
+ "mx-auto h-full transition-[width] duration-200",
167
+ x === "phone" ? "w-full max-w-[414px] border-x border-border bg-background shadow-xl" : "w-full"
168
+ ),
169
+ style: x === "phone" ? { width: ee } : void 0,
170
+ children: /* @__PURE__ */ e(
171
+ "iframe",
172
+ {
173
+ src: I,
174
+ title: i ?? "Preview",
175
+ sandbox: N,
176
+ allow: c,
177
+ referrerPolicy: "no-referrer-when-downgrade",
178
+ onLoad: () => {
179
+ _(!1), L(!1);
180
+ },
181
+ className: "size-full border-0 bg-white"
182
+ },
183
+ j
184
+ )
185
+ }
186
+ ),
187
+ H && /* @__PURE__ */ s("div", { className: "pointer-events-none absolute inset-0 flex flex-col items-center justify-center gap-3 bg-background/70", children: [
188
+ /* @__PURE__ */ e(U, { size: "lg" }),
189
+ O && /* @__PURE__ */ s("p", { className: "pointer-events-auto max-w-xs px-6 text-center text-xs text-muted-foreground", children: [
190
+ "Still blank — the site may refuse to be framed.",
191
+ " ",
192
+ /* @__PURE__ */ e("a", { href: d, target: "_blank", rel: "noreferrer noopener", className: "underline", children: "Open it in a new tab" }),
193
+ "."
194
+ ] })
195
+ ] })
196
+ ] })
197
+ ]
198
+ }
199
+ ),
200
+ document.body
201
+ );
202
+ }
203
+ function me({
204
+ url: t,
205
+ open: o,
206
+ defaultOpen: a = !1,
207
+ onOpenChange: l,
208
+ children: i,
209
+ label: w,
210
+ triggerClassName: u,
211
+ className: g,
212
+ ...k
213
+ }) {
214
+ const [f, p] = n.useState(a), N = o ?? f, c = (b) => {
215
+ p(b), l == null || l(b);
216
+ }, S = typeof i == "function" ? i({ open: () => c(!0) }) : i ? /* @__PURE__ */ e(
217
+ "button",
218
+ {
219
+ type: "button",
220
+ onClick: () => c(!0),
221
+ "aria-haspopup": "dialog",
222
+ className: E(
223
+ "cursor-pointer rounded-md text-left outline-none focus-visible:ring-2 focus-visible:ring-ring",
224
+ u
225
+ ),
226
+ children: i
227
+ }
228
+ ) : /* @__PURE__ */ e(
229
+ m,
230
+ {
231
+ variant: "outline",
232
+ icon: /* @__PURE__ */ e(D, {}),
233
+ "aria-haspopup": "dialog",
234
+ className: u,
235
+ onClick: () => c(!0),
236
+ children: w ?? "Preview"
237
+ }
238
+ );
239
+ return /* @__PURE__ */ s(X, { children: [
240
+ S,
241
+ /* @__PURE__ */ e(
242
+ ae,
243
+ {
244
+ ...k,
245
+ className: g,
246
+ url: t,
247
+ open: N,
248
+ onClose: () => c(!1)
249
+ }
250
+ )
251
+ ] });
252
+ }
253
+ export {
254
+ me as IframePreview,
255
+ ae as IframePreviewOverlay
256
+ };
257
+ //# sourceMappingURL=iframe-preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iframe-preview.js","sources":["../../../src/components/iframe-preview/iframe-preview.tsx"],"sourcesContent":["import * as React from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n ExternalLink,\n Monitor,\n RotateCw,\n Smartphone,\n X,\n} from 'lucide-react';\n\nimport { cn } from '../../lib/utils';\nimport { useEscape, useScrollLock } from '../../hooks/use-overlay';\nimport { Button } from '../button';\nimport { Input } from '../input';\nimport { Spinner } from '../spinner';\n\nexport type IframePreviewDevice = 'desktop' | 'phone';\n\n/** Logical width the phone tier lays the embedded page out at. */\nconst PHONE_WIDTH = 414;\n\n/** How long a blank iframe may hang before we suggest the site refuses framing. */\nconst BLOCK_HINT_MS = 6000;\n\nexport interface IframePreviewOverlayProps {\n open: boolean;\n onClose: () => void;\n /** The page to frame. Changing it (while open) navigates the iframe. */\n url: string;\n /** Called whenever the user commits a new URL in the address field. */\n onUrlChange?: (url: string) => void;\n title?: string;\n /** Show the editable address field. Default `true`. */\n editableUrl?: boolean;\n /** Extra controls, rendered in the toolbar next to the built-in ones. */\n actions?: React.ReactNode;\n /** Phone/desktop tier toggle (desktop viewports only). Default `true`. */\n devices?: boolean;\n device?: IframePreviewDevice;\n onDeviceChange?: (device: IframePreviewDevice) => void;\n /**\n * Append a cache-busting query param on every (re)load, so a just-deployed\n * page can't be served from the browser cache. Default `false`.\n */\n cacheBust?: boolean;\n sandbox?: string;\n allow?: string;\n className?: string;\n /** Rendered under the toolbar, above the frame — a banner, a tab bar… */\n children?: React.ReactNode;\n}\n\n/** `https://x` for a bare `x`, so typing `foo.dev` in the field just works. */\nfunction normalizeUrl(raw: string): string {\n const value = raw.trim();\n if (!value) return value;\n return /^[a-z][a-z0-9+.-]*:/i.test(value) ? value : `https://${value}`;\n}\n\nfunction withBust(url: string, nonce: number): string {\n try {\n const u = new URL(url, typeof window === 'undefined' ? undefined : window.location.href);\n u.searchParams.set('_ts', String(nonce));\n return u.toString();\n } catch {\n return url;\n }\n}\n\n/**\n * The full-screen half of {@link IframePreview}, driven entirely from props —\n * use it directly when the trigger lives somewhere else (a menu item, a\n * floating gizmo) or when the URL is owned by the app.\n *\n * The iframe is keyed on the resolved source, so every open — and every hit of\n * the reload button — remounts it and re-fetches the page rather than showing a\n * stale render.\n */\nexport function IframePreviewOverlay({\n open,\n onClose,\n url,\n onUrlChange,\n title,\n editableUrl = true,\n actions,\n devices = true,\n device: deviceProp,\n onDeviceChange,\n cacheBust = false,\n sandbox,\n allow = 'clipboard-write; fullscreen; geolocation',\n className,\n children,\n}: IframePreviewOverlayProps) {\n const [src, setSrc] = React.useState(url);\n const [draft, setDraft] = React.useState(url);\n const [nonce, setNonce] = React.useState(0);\n const [loading, setLoading] = React.useState(true);\n const [blocked, setBlocked] = React.useState(false);\n const [deviceState, setDeviceState] = React.useState<IframePreviewDevice>('desktop');\n const device = deviceProp ?? deviceState;\n\n useScrollLock(open);\n useEscape(onClose, open);\n\n // Every open (and every external url change) starts from a fresh fetch.\n React.useEffect(() => {\n if (!open) return;\n setSrc(url);\n setDraft(url);\n setNonce((n) => n + 1);\n }, [open, url]);\n\n const resolved = React.useMemo(\n () => (cacheBust ? withBust(src, nonce) : src),\n [cacheBust, src, nonce],\n );\n const frameKey = `${resolved}#${nonce}`;\n\n React.useEffect(() => {\n if (!open) return;\n setLoading(true);\n setBlocked(false);\n const t = window.setTimeout(() => setBlocked(true), BLOCK_HINT_MS);\n return () => window.clearTimeout(t);\n }, [open, frameKey]);\n\n const reload = () => setNonce((n) => n + 1);\n\n const navigate = (e: React.FormEvent) => {\n e.preventDefault();\n const next = normalizeUrl(draft);\n if (!next) return;\n setDraft(next);\n setSrc(next);\n setNonce((n) => n + 1);\n onUrlChange?.(next);\n (document.activeElement as HTMLElement | null)?.blur?.();\n };\n\n const setDevice = (next: IframePreviewDevice) => {\n setDeviceState(next);\n onDeviceChange?.(next);\n };\n\n if (!open || typeof document === 'undefined') return null;\n\n return createPortal(\n <div\n className={cn(\n 'ds-iframe-preview fixed inset-0 z-[95] flex h-[100dvh] w-screen flex-col bg-background text-foreground',\n className,\n )}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title ?? 'Preview'}\n >\n <header\n className=\"flex shrink-0 flex-col gap-1.5 border-b border-border bg-card/80 px-2 py-2 backdrop-blur\"\n style={{ paddingTop: 'max(0.5rem, env(safe-area-inset-top))' }}\n >\n <div className=\"flex items-center gap-1\">\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n icon={<RotateCw />}\n aria-label=\"Reload\"\n tooltip=\"Reload\"\n onClick={reload}\n />\n\n {editableUrl ? (\n <form onSubmit={navigate} className=\"min-w-0 flex-1\">\n <Input\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onFocus={(e) => e.currentTarget.select()}\n spellCheck={false}\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n inputMode=\"url\"\n type=\"text\"\n aria-label=\"Preview URL\"\n className=\"h-8 w-full truncate rounded-full px-3 text-xs sm:text-sm\"\n />\n </form>\n ) : (\n <span className=\"min-w-0 flex-1 truncate px-2 text-xs text-muted-foreground sm:text-sm\">\n {title ?? src}\n </span>\n )}\n\n {devices && (\n <div className=\"hidden items-center gap-0.5 rounded-full border border-border p-0.5 sm:flex\">\n <Button\n variant={device === 'desktop' ? 'default' : 'ghost'}\n size=\"icon-sm\"\n icon={<Monitor />}\n aria-label=\"Desktop width\"\n tooltip=\"Desktop\"\n className=\"rounded-full\"\n onClick={() => setDevice('desktop')}\n />\n <Button\n variant={device === 'phone' ? 'default' : 'ghost'}\n size=\"icon-sm\"\n icon={<Smartphone />}\n aria-label=\"Phone width\"\n tooltip=\"Phone\"\n className=\"rounded-full\"\n onClick={() => setDevice('phone')}\n />\n </div>\n )}\n\n <a\n href={src}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n aria-label=\"Open in a new tab\"\n className=\"inline-flex size-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n <ExternalLink className=\"size-3.5\" />\n </a>\n\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n icon={<X />}\n aria-label=\"Close preview\"\n tooltip=\"Close\"\n onClick={onClose}\n />\n </div>\n\n {actions && (\n <div className=\"-mx-1 flex items-center gap-1 overflow-x-auto px-1 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\">\n {actions}\n </div>\n )}\n </header>\n\n {children}\n\n <div className=\"relative min-h-0 flex-1 bg-muted/30\">\n <div\n className={cn(\n 'mx-auto h-full transition-[width] duration-200',\n device === 'phone'\n ? 'w-full max-w-[414px] border-x border-border bg-background shadow-xl'\n : 'w-full',\n )}\n style={device === 'phone' ? { width: PHONE_WIDTH } : undefined}\n >\n <iframe\n key={frameKey}\n src={resolved}\n title={title ?? 'Preview'}\n sandbox={sandbox}\n allow={allow}\n referrerPolicy=\"no-referrer-when-downgrade\"\n onLoad={() => {\n setLoading(false);\n setBlocked(false);\n }}\n className=\"size-full border-0 bg-white\"\n />\n </div>\n\n {loading && (\n <div className=\"pointer-events-none absolute inset-0 flex flex-col items-center justify-center gap-3 bg-background/70\">\n <Spinner size=\"lg\" />\n {blocked && (\n <p className=\"pointer-events-auto max-w-xs px-6 text-center text-xs text-muted-foreground\">\n Still blank — the site may refuse to be framed.{' '}\n <a href={src} target=\"_blank\" rel=\"noreferrer noopener\" className=\"underline\">\n Open it in a new tab\n </a>\n .\n </p>\n )}\n </div>\n )}\n </div>\n </div>,\n document.body,\n );\n}\n\nexport interface IframePreviewProps\n extends Omit<IframePreviewOverlayProps, 'open' | 'onClose' | 'url' | 'children'> {\n /** Initial URL. The field can navigate away from it; reopening resets to it. */\n url: string;\n /** Controlled open state. Omit to let the component own it. */\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Custom trigger. A render prop gets `open()`; a node is wrapped in a button. */\n children?: React.ReactNode | ((api: { open: () => void }) => React.ReactNode);\n /** Label of the default button trigger. */\n label?: string;\n /** Class for the default trigger. */\n triggerClassName?: string;\n}\n\n/**\n * A trigger — a button by default, any element you like — that opens the page\n * at `url` full-screen in an iframe, with an editable address field, a reload\n * that really re-fetches, a phone/desktop tier and a slot for your own\n * controls. Built for phones: `100dvh`, safe-area padding, tap-sized buttons\n * and a toolbar that stays one row wide.\n */\nexport function IframePreview({\n url,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n children,\n label,\n triggerClassName,\n className,\n ...overlay\n}: IframePreviewProps) {\n const [openState, setOpenState] = React.useState(defaultOpen);\n const open = openProp ?? openState;\n\n const setOpen = (next: boolean) => {\n setOpenState(next);\n onOpenChange?.(next);\n };\n\n const trigger =\n typeof children === 'function' ? (\n children({ open: () => setOpen(true) })\n ) : children ? (\n <button\n type=\"button\"\n onClick={() => setOpen(true)}\n aria-haspopup=\"dialog\"\n className={cn(\n 'cursor-pointer rounded-md text-left outline-none focus-visible:ring-2 focus-visible:ring-ring',\n triggerClassName,\n )}\n >\n {children}\n </button>\n ) : (\n <Button\n variant=\"outline\"\n icon={<ExternalLink />}\n aria-haspopup=\"dialog\"\n className={triggerClassName}\n onClick={() => setOpen(true)}\n >\n {label ?? 'Preview'}\n </Button>\n );\n\n return (\n <>\n {trigger}\n <IframePreviewOverlay\n {...overlay}\n className={className}\n url={url}\n open={open}\n onClose={() => setOpen(false)}\n />\n </>\n );\n}\n"],"names":["PHONE_WIDTH","BLOCK_HINT_MS","normalizeUrl","raw","value","withBust","url","nonce","u","IframePreviewOverlay","open","onClose","onUrlChange","title","editableUrl","actions","devices","deviceProp","onDeviceChange","cacheBust","sandbox","allow","className","children","src","setSrc","React","draft","setDraft","setNonce","loading","setLoading","blocked","setBlocked","deviceState","setDeviceState","device","useScrollLock","useEscape","n","resolved","frameKey","t","reload","navigate","e","next","_b","_a","setDevice","createPortal","jsxs","cn","jsx","Button","RotateCw","Input","Monitor","Smartphone","ExternalLink","X","Spinner","IframePreview","openProp","defaultOpen","onOpenChange","label","triggerClassName","overlay","openState","setOpenState","setOpen","trigger","Fragment"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { IframePreview, IframePreviewOverlay } from './iframe-preview';
2
+ export type { IframePreviewProps, IframePreviewOverlayProps, IframePreviewDevice, } from './iframe-preview';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/iframe-preview/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACvE,YAAY,EACV,kBAAkB,EAClB,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { ReactNode } from 'react';
2
+ /**
3
+ * A reusable full-screen image viewer with zoom/pan + a swipe/arrow carousel.
4
+ *
5
+ * Wrap the app in {@link ImageViewerProvider}; anywhere inside, call
6
+ * `useImageViewer().open(images, index)` to launch the overlay over a group of
7
+ * image URLs. The {@link ViewableImage} wrapper does this on click. The overlay
8
+ * is portalled to `<body>`, locks page scroll, and supports:
9
+ * • wheel / pinch / double-tap / +− keys to zoom (about the cursor/midpoint)
10
+ * • drag to pan when zoomed
11
+ * • horizontal swipe (touch) or ←/→ arrows + on-screen chevrons to browse
12
+ * • Escape or a tap on the backdrop to close
13
+ * • a vertical swipe to dismiss (with a live backdrop fade)
14
+ *
15
+ * Styling lives in `@gabvdl/ui/image-viewer.css` (all `.viewer-*` classes),
16
+ * themeable through the `--ds-viewer-*` custom properties.
17
+ */
18
+ interface ImageViewerContextValue {
19
+ /** Open the overlay over `images`, starting at `index` (default 0). */
20
+ open: (images: string[], index?: number) => void;
21
+ /** Close the overlay. */
22
+ close: () => void;
23
+ }
24
+ /** Access the ambient {@link ImageViewerProvider}. Throws if used outside one. */
25
+ export declare function useImageViewer(): ImageViewerContextValue;
26
+ export declare function ImageViewerProvider({ children }: {
27
+ children: ReactNode;
28
+ }): import("react").JSX.Element;
29
+ export {};
30
+ //# sourceMappingURL=image-viewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-viewer.d.ts","sourceRoot":"","sources":["../../../src/components/image-viewer/image-viewer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf;;;;;;;;;;;;;;;GAeG;AACH,UAAU,uBAAuB;IAC/B,uEAAuE;IACvE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,yBAAyB;IACzB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAID,kFAAkF;AAClF,wBAAgB,cAAc,IAAI,uBAAuB,CAIxD;AAQD,wBAAgB,mBAAmB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAqBxE"}
@@ -0,0 +1,226 @@
1
+ import { jsxs as P, jsx as i, Fragment as T } from "react/jsx-runtime";
2
+ import { useState as $, useCallback as X, useContext as F, createContext as K, useRef as x, useEffect as k } from "react";
3
+ import { createPortal as U } from "react-dom";
4
+ import { X as q, ZoomOut as G, ZoomIn as J, ChevronLeft as Q, ChevronRight as ee } from "lucide-react";
5
+ const _ = K(null);
6
+ function le() {
7
+ const l = F(_);
8
+ if (!l) throw new Error("useImageViewer must be used within <ImageViewerProvider>");
9
+ return l;
10
+ }
11
+ const V = 1, W = 5, te = 60, re = 90, C = (l, a, v) => Math.min(v, Math.max(a, l));
12
+ function ue({ children: l }) {
13
+ const [a, v] = $(null), [h, c] = $(0), y = X((p, r = 0) => {
14
+ p.length && (v(p), c(C(r, 0, p.length - 1)));
15
+ }, []), u = X(() => v(null), []);
16
+ return /* @__PURE__ */ P(_.Provider, { value: { open: y, close: u }, children: [
17
+ l,
18
+ a && U(
19
+ /* @__PURE__ */ i(ne, { images: a, index: h, setIndex: c, close: u }),
20
+ document.body
21
+ )
22
+ ] });
23
+ }
24
+ function ne({
25
+ images: l,
26
+ index: a,
27
+ setIndex: v,
28
+ close: h
29
+ }) {
30
+ const c = l.length, y = x(null), u = x(null), p = x(null), r = x({ scale: 1, x: 0, y: 0 }), d = x(/* @__PURE__ */ new Map()), w = x(null), R = x(0), [j, A] = $(!1), I = X(() => v((e) => (e + 1) % c), [c, v]), S = X(() => v((e) => (e - 1 + c) % c), [c, v]), f = X(() => {
31
+ const e = p.current;
32
+ e && (e.style.transform = `translate3d(${r.current.x}px, ${r.current.y}px, 0) scale(${r.current.scale})`);
33
+ }, []), g = (e) => {
34
+ const t = p.current;
35
+ t && (t.style.transition = e ? "transform 0.22s ease" : "none");
36
+ }, E = X(() => {
37
+ r.current = { scale: 1, x: 0, y: 0 }, A(!1), g(!0), f(), y.current && (y.current.style.opacity = "");
38
+ }, [f]);
39
+ k(() => {
40
+ E();
41
+ }, [a, E]), k(() => {
42
+ const e = document.body.style.overflow;
43
+ return document.body.style.overflow = "hidden", () => {
44
+ document.body.style.overflow = e;
45
+ };
46
+ }, []), k(() => {
47
+ c < 2 || [l[(a + 1) % c], l[(a - 1 + c) % c]].forEach((e) => {
48
+ const t = new Image();
49
+ t.src = e;
50
+ });
51
+ }, [l, a, c]);
52
+ const Y = () => {
53
+ const e = p.current, t = u.current;
54
+ if (!e || !t) return;
55
+ const n = r.current.scale, s = Math.max(0, (e.clientWidth * n - t.clientWidth) / 2), o = Math.max(0, (e.clientHeight * n - t.clientHeight) / 2);
56
+ r.current.x = C(r.current.x, -s, s), r.current.y = C(r.current.y, -o, o);
57
+ }, N = X(
58
+ (e, t, n) => {
59
+ const s = u.current;
60
+ if (!s) return;
61
+ const o = s.getBoundingClientRect(), m = t - o.left - o.width / 2, z = n - o.top - o.height / 2, M = r.current.scale, b = C(M * e, V, W), O = b / M;
62
+ r.current.x = m - (m - r.current.x) * O, r.current.y = z - (z - r.current.y) * O, r.current.scale = b, b <= 1.001 && (r.current.x = 0, r.current.y = 0), Y(), A(b > 1.01), f();
63
+ },
64
+ [f]
65
+ ), L = (e) => {
66
+ const t = u.current;
67
+ if (!t) return;
68
+ const n = t.getBoundingClientRect();
69
+ g(!0), N(e, n.left + n.width / 2, n.top + n.height / 2);
70
+ };
71
+ k(() => {
72
+ const e = u.current;
73
+ if (!e) return;
74
+ const t = (n) => {
75
+ n.preventDefault(), g(!1), N(n.deltaY < 0 ? 1.16 : 1 / 1.16, n.clientX, n.clientY);
76
+ };
77
+ return e.addEventListener("wheel", t, { passive: !1 }), () => e.removeEventListener("wheel", t);
78
+ }, [N]), k(() => {
79
+ const e = (t) => {
80
+ t.key === "Escape" ? h() : t.key === "ArrowRight" ? I() : t.key === "ArrowLeft" ? S() : t.key === "+" || t.key === "=" ? L(1.25) : t.key === "-" && L(0.8);
81
+ };
82
+ return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
83
+ }, [h, I, S]);
84
+ const Z = (e, t) => Math.hypot(e.x - t.x, e.y - t.y), B = (e) => {
85
+ var n, s;
86
+ if ((s = (n = e.target).setPointerCapture) == null || s.call(n, e.pointerId), d.current.set(e.pointerId, { x: e.clientX, y: e.clientY }), g(!1), d.current.size === 2) {
87
+ const [o, m] = [...d.current.values()];
88
+ w.current = {
89
+ mode: "pinch",
90
+ startX: e.clientX,
91
+ startY: e.clientY,
92
+ baseX: r.current.x,
93
+ baseY: r.current.y,
94
+ startDist: Z(o, m),
95
+ baseScale: r.current.scale,
96
+ startMidX: (o.x + m.x) / 2,
97
+ startMidY: (o.y + m.y) / 2,
98
+ moved: !1
99
+ };
100
+ return;
101
+ }
102
+ const t = e.timeStamp;
103
+ if (t - R.current < 300) {
104
+ g(!0), r.current.scale > 1.01 ? E() : N(2.4, e.clientX, e.clientY), R.current = 0, w.current = null;
105
+ return;
106
+ }
107
+ R.current = t, w.current = {
108
+ mode: r.current.scale > 1.01 ? "pan" : "swipe",
109
+ startX: e.clientX,
110
+ startY: e.clientY,
111
+ baseX: r.current.x,
112
+ baseY: r.current.y,
113
+ moved: !1
114
+ };
115
+ }, H = (e) => {
116
+ if (!d.current.has(e.pointerId)) return;
117
+ d.current.set(e.pointerId, { x: e.clientX, y: e.clientY });
118
+ const t = w.current;
119
+ if (!t) return;
120
+ if (t.mode === "pinch" && d.current.size >= 2) {
121
+ const [o, m] = [...d.current.values()], z = Z(o, m) / (t.startDist || 1);
122
+ r.current.scale = C((t.baseScale || 1) * z, V, W);
123
+ const M = (o.x + m.x) / 2, b = (o.y + m.y) / 2;
124
+ r.current.x = t.baseX + (M - (t.startMidX || M)), r.current.y = t.baseY + (b - (t.startMidY || b)), Y(), A(r.current.scale > 1.01), f(), t.moved = !0;
125
+ return;
126
+ }
127
+ const n = e.clientX - t.startX, s = e.clientY - t.startY;
128
+ if ((Math.abs(n) > 6 || Math.abs(s) > 6) && (t.moved = !0), t.mode === "pan")
129
+ r.current.x = t.baseX + n, r.current.y = t.baseY + s, Y(), f();
130
+ else if (t.mode === "swipe") {
131
+ const o = Math.abs(s) > Math.abs(n);
132
+ r.current.x = c > 1 ? n : n * 0.25, r.current.y = s, f(), y.current && (y.current.style.opacity = o ? String(C(1 - Math.abs(s) / 500, 0.35, 1)) : "1");
133
+ }
134
+ }, D = (e) => {
135
+ d.current.delete(e.pointerId);
136
+ const t = w.current;
137
+ if (t) {
138
+ if (t.mode === "pinch") {
139
+ if (d.current.size === 1) {
140
+ const [n] = [...d.current.values()];
141
+ w.current = {
142
+ mode: r.current.scale > 1.01 ? "pan" : "swipe",
143
+ startX: n.x,
144
+ startY: n.y,
145
+ baseX: r.current.x,
146
+ baseY: r.current.y,
147
+ moved: !1
148
+ };
149
+ } else
150
+ r.current.scale <= 1.01 ? E() : (g(!0), Y(), f(), w.current = null);
151
+ return;
152
+ }
153
+ if (t.mode === "swipe") {
154
+ const n = e.clientX - t.startX, s = e.clientY - t.startY;
155
+ if (Math.abs(s) > Math.abs(n) && Math.abs(s) > re) {
156
+ h();
157
+ return;
158
+ }
159
+ c > 1 && Math.abs(n) > te ? n < 0 ? I() : S() : (g(!0), r.current.x = 0, r.current.y = 0, f(), y.current && (y.current.style.opacity = ""), !t.moved && e.target === u.current && h());
160
+ } else t.mode === "pan" && (g(!0), Y(), f());
161
+ w.current = null;
162
+ }
163
+ };
164
+ return /* @__PURE__ */ P("div", { className: "viewer-overlay", ref: y, role: "dialog", "aria-modal": "true", children: [
165
+ /* @__PURE__ */ i(
166
+ "div",
167
+ {
168
+ ref: u,
169
+ className: `viewer-stage${j ? " is-zoomed" : ""}`,
170
+ onPointerDown: B,
171
+ onPointerMove: H,
172
+ onPointerUp: D,
173
+ onPointerCancel: D,
174
+ onClick: (e) => {
175
+ e.target === u.current && h();
176
+ },
177
+ children: /* @__PURE__ */ i(
178
+ "img",
179
+ {
180
+ ref: p,
181
+ src: l[a],
182
+ alt: `Image ${a + 1} of ${c}`,
183
+ className: "viewer-img",
184
+ draggable: !1
185
+ },
186
+ a
187
+ )
188
+ }
189
+ ),
190
+ /* @__PURE__ */ i("button", { className: "viewer-ctl viewer-close", onClick: h, "aria-label": "Close", children: /* @__PURE__ */ i(q, {}) }),
191
+ /* @__PURE__ */ P("div", { className: "viewer-zoom", children: [
192
+ /* @__PURE__ */ i("button", { className: "viewer-ctl", onClick: () => L(1 / 1.25), "aria-label": "Zoom out", children: /* @__PURE__ */ i(G, {}) }),
193
+ /* @__PURE__ */ i("button", { className: "viewer-ctl", onClick: () => L(1.25), "aria-label": "Zoom in", children: /* @__PURE__ */ i(J, {}) })
194
+ ] }),
195
+ c > 1 && /* @__PURE__ */ P(T, { children: [
196
+ /* @__PURE__ */ i(
197
+ "button",
198
+ {
199
+ className: "viewer-ctl viewer-nav viewer-nav--prev",
200
+ onClick: S,
201
+ "aria-label": "Previous image",
202
+ children: /* @__PURE__ */ i(Q, {})
203
+ }
204
+ ),
205
+ /* @__PURE__ */ i(
206
+ "button",
207
+ {
208
+ className: "viewer-ctl viewer-nav viewer-nav--next",
209
+ onClick: I,
210
+ "aria-label": "Next image",
211
+ children: /* @__PURE__ */ i(ee, {})
212
+ }
213
+ ),
214
+ /* @__PURE__ */ P("div", { className: "viewer-counter", children: [
215
+ a + 1,
216
+ " / ",
217
+ c
218
+ ] })
219
+ ] })
220
+ ] });
221
+ }
222
+ export {
223
+ ue as ImageViewerProvider,
224
+ le as useImageViewer
225
+ };
226
+ //# sourceMappingURL=image-viewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-viewer.js","sources":["../../../src/components/image-viewer/image-viewer.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { ChevronLeft, ChevronRight, X, ZoomIn, ZoomOut } from 'lucide-react';\n\n/**\n * A reusable full-screen image viewer with zoom/pan + a swipe/arrow carousel.\n *\n * Wrap the app in {@link ImageViewerProvider}; anywhere inside, call\n * `useImageViewer().open(images, index)` to launch the overlay over a group of\n * image URLs. The {@link ViewableImage} wrapper does this on click. The overlay\n * is portalled to `<body>`, locks page scroll, and supports:\n * • wheel / pinch / double-tap / +− keys to zoom (about the cursor/midpoint)\n * • drag to pan when zoomed\n * • horizontal swipe (touch) or ←/→ arrows + on-screen chevrons to browse\n * • Escape or a tap on the backdrop to close\n * • a vertical swipe to dismiss (with a live backdrop fade)\n *\n * Styling lives in `@gabvdl/ui/image-viewer.css` (all `.viewer-*` classes),\n * themeable through the `--ds-viewer-*` custom properties.\n */\ninterface ImageViewerContextValue {\n /** Open the overlay over `images`, starting at `index` (default 0). */\n open: (images: string[], index?: number) => void;\n /** Close the overlay. */\n close: () => void;\n}\n\nconst Ctx = createContext<ImageViewerContextValue | null>(null);\n\n/** Access the ambient {@link ImageViewerProvider}. Throws if used outside one. */\nexport function useImageViewer(): ImageViewerContextValue {\n const v = useContext(Ctx);\n if (!v) throw new Error('useImageViewer must be used within <ImageViewerProvider>');\n return v;\n}\n\nconst MIN_SCALE = 1;\nconst MAX_SCALE = 5;\nconst SWIPE_PX = 60;\nconst CLOSE_PX = 90;\nconst clamp = (v: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, v));\n\nexport function ImageViewerProvider({ children }: { children: ReactNode }) {\n const [images, setImages] = useState<string[] | null>(null);\n const [index, setIndex] = useState(0);\n\n const open = useCallback((imgs: string[], i = 0) => {\n if (!imgs.length) return;\n setImages(imgs);\n setIndex(clamp(i, 0, imgs.length - 1));\n }, []);\n const close = useCallback(() => setImages(null), []);\n\n return (\n <Ctx.Provider value={{ open, close }}>\n {children}\n {images &&\n createPortal(\n <Overlay images={images} index={index} setIndex={setIndex} close={close} />,\n document.body,\n )}\n </Ctx.Provider>\n );\n}\n\ninterface Gesture {\n mode: 'pan' | 'swipe' | 'pinch';\n startX: number;\n startY: number;\n baseX: number;\n baseY: number;\n startDist?: number;\n baseScale?: number;\n startMidX?: number;\n startMidY?: number;\n moved: boolean;\n}\n\nfunction Overlay({\n images,\n index,\n setIndex,\n close,\n}: {\n images: string[];\n index: number;\n setIndex: (updater: (i: number) => number) => void;\n close: () => void;\n}) {\n const count = images.length;\n const overlayRef = useRef<HTMLDivElement>(null);\n const stageRef = useRef<HTMLDivElement>(null);\n const imgRef = useRef<HTMLImageElement>(null);\n const t = useRef({ scale: 1, x: 0, y: 0 });\n const pointers = useRef<Map<number, { x: number; y: number }>>(new Map());\n const gesture = useRef<Gesture | null>(null);\n const lastTap = useRef(0);\n const [zoomed, setZoomed] = useState(false);\n\n const next = useCallback(() => setIndex((i) => (i + 1) % count), [count, setIndex]);\n const prev = useCallback(() => setIndex((i) => (i - 1 + count) % count), [count, setIndex]);\n\n const apply = useCallback(() => {\n const el = imgRef.current;\n if (el)\n el.style.transform = `translate3d(${t.current.x}px, ${t.current.y}px, 0) scale(${t.current.scale})`;\n }, []);\n\n const setTransition = (on: boolean) => {\n const el = imgRef.current;\n if (el) el.style.transition = on ? 'transform 0.22s ease' : 'none';\n };\n\n const reset = useCallback(() => {\n t.current = { scale: 1, x: 0, y: 0 };\n setZoomed(false);\n setTransition(true);\n apply();\n if (overlayRef.current) overlayRef.current.style.opacity = '';\n }, [apply]);\n\n // Reset zoom/pan whenever the shown image changes.\n useEffect(() => {\n reset();\n }, [index, reset]);\n\n // Lock page scroll while the viewer is open + preload the neighbours.\n useEffect(() => {\n const prevOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n return () => {\n document.body.style.overflow = prevOverflow;\n };\n }, []);\n useEffect(() => {\n if (count < 2) return;\n [images[(index + 1) % count], images[(index - 1 + count) % count]].forEach((src) => {\n const img = new Image();\n img.src = src;\n });\n }, [images, index, count]);\n\n const clampPan = () => {\n const el = imgRef.current;\n const stage = stageRef.current;\n if (!el || !stage) return;\n const sc = t.current.scale;\n const maxX = Math.max(0, (el.clientWidth * sc - stage.clientWidth) / 2);\n const maxY = Math.max(0, (el.clientHeight * sc - stage.clientHeight) / 2);\n t.current.x = clamp(t.current.x, -maxX, maxX);\n t.current.y = clamp(t.current.y, -maxY, maxY);\n };\n\n // Zoom by `factor` while keeping the point (cx,cy) — in client coords — fixed.\n const zoomAt = useCallback(\n (factor: number, cx: number, cy: number) => {\n const stage = stageRef.current;\n if (!stage) return;\n const rect = stage.getBoundingClientRect();\n const ox = cx - rect.left - rect.width / 2;\n const oy = cy - rect.top - rect.height / 2;\n const prevScale = t.current.scale;\n const nextScale = clamp(prevScale * factor, MIN_SCALE, MAX_SCALE);\n const ratio = nextScale / prevScale;\n t.current.x = ox - (ox - t.current.x) * ratio;\n t.current.y = oy - (oy - t.current.y) * ratio;\n t.current.scale = nextScale;\n if (nextScale <= 1.001) {\n t.current.x = 0;\n t.current.y = 0;\n }\n clampPan();\n setZoomed(nextScale > 1.01);\n apply();\n },\n [apply],\n );\n\n const zoomCenter = (factor: number) => {\n const stage = stageRef.current;\n if (!stage) return;\n const r = stage.getBoundingClientRect();\n setTransition(true);\n zoomAt(factor, r.left + r.width / 2, r.top + r.height / 2);\n };\n\n // Non-passive wheel listener so we can preventDefault the page zoom/scroll.\n useEffect(() => {\n const stage = stageRef.current;\n if (!stage) return;\n const onWheel = (e: WheelEvent) => {\n e.preventDefault();\n setTransition(false);\n zoomAt(e.deltaY < 0 ? 1.16 : 1 / 1.16, e.clientX, e.clientY);\n };\n stage.addEventListener('wheel', onWheel, { passive: false });\n return () => stage.removeEventListener('wheel', onWheel);\n }, [zoomAt]);\n\n // Keyboard: arrows browse, +/- zoom, Escape closes.\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') close();\n else if (e.key === 'ArrowRight') next();\n else if (e.key === 'ArrowLeft') prev();\n else if (e.key === '+' || e.key === '=') zoomCenter(1.25);\n else if (e.key === '-') zoomCenter(0.8);\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [close, next, prev]);\n\n const dist = (a: { x: number; y: number }, b: { x: number; y: number }) =>\n Math.hypot(a.x - b.x, a.y - b.y);\n\n const onPointerDown = (e: React.PointerEvent) => {\n (e.target as Element).setPointerCapture?.(e.pointerId);\n pointers.current.set(e.pointerId, { x: e.clientX, y: e.clientY });\n setTransition(false);\n\n if (pointers.current.size === 2) {\n const [a, b] = [...pointers.current.values()];\n gesture.current = {\n mode: 'pinch',\n startX: e.clientX,\n startY: e.clientY,\n baseX: t.current.x,\n baseY: t.current.y,\n startDist: dist(a, b),\n baseScale: t.current.scale,\n startMidX: (a.x + b.x) / 2,\n startMidY: (a.y + b.y) / 2,\n moved: false,\n };\n return;\n }\n\n // Double-tap / double-click toggles zoom.\n const now = e.timeStamp;\n if (now - lastTap.current < 300) {\n setTransition(true);\n if (t.current.scale > 1.01) reset();\n else zoomAt(2.4, e.clientX, e.clientY);\n lastTap.current = 0;\n gesture.current = null;\n return;\n }\n lastTap.current = now;\n\n gesture.current = {\n mode: t.current.scale > 1.01 ? 'pan' : 'swipe',\n startX: e.clientX,\n startY: e.clientY,\n baseX: t.current.x,\n baseY: t.current.y,\n moved: false,\n };\n };\n\n const onPointerMove = (e: React.PointerEvent) => {\n if (!pointers.current.has(e.pointerId)) return;\n pointers.current.set(e.pointerId, { x: e.clientX, y: e.clientY });\n const g = gesture.current;\n if (!g) return;\n\n if (g.mode === 'pinch' && pointers.current.size >= 2) {\n const [a, b] = [...pointers.current.values()];\n const ratio = dist(a, b) / (g.startDist || 1);\n t.current.scale = clamp((g.baseScale || 1) * ratio, MIN_SCALE, MAX_SCALE);\n const midX = (a.x + b.x) / 2;\n const midY = (a.y + b.y) / 2;\n t.current.x = g.baseX + (midX - (g.startMidX || midX));\n t.current.y = g.baseY + (midY - (g.startMidY || midY));\n clampPan();\n setZoomed(t.current.scale > 1.01);\n apply();\n g.moved = true;\n return;\n }\n\n const dx = e.clientX - g.startX;\n const dy = e.clientY - g.startY;\n if (Math.abs(dx) > 6 || Math.abs(dy) > 6) g.moved = true;\n\n if (g.mode === 'pan') {\n t.current.x = g.baseX + dx;\n t.current.y = g.baseY + dy;\n clampPan();\n apply();\n } else if (g.mode === 'swipe') {\n // Horizontal → carousel feedback; vertical → drag-to-dismiss feedback.\n const vertical = Math.abs(dy) > Math.abs(dx);\n t.current.x = count > 1 ? dx : dx * 0.25;\n t.current.y = dy;\n apply();\n if (overlayRef.current)\n overlayRef.current.style.opacity = vertical\n ? String(clamp(1 - Math.abs(dy) / 500, 0.35, 1))\n : '1';\n }\n };\n\n const endPointer = (e: React.PointerEvent) => {\n pointers.current.delete(e.pointerId);\n const g = gesture.current;\n if (!g) return;\n\n if (g.mode === 'pinch') {\n // Lifting one finger: continue panning with the remaining one, or settle.\n if (pointers.current.size === 1) {\n const [p] = [...pointers.current.values()];\n gesture.current = {\n mode: t.current.scale > 1.01 ? 'pan' : 'swipe',\n startX: p.x,\n startY: p.y,\n baseX: t.current.x,\n baseY: t.current.y,\n moved: false,\n };\n } else {\n if (t.current.scale <= 1.01) reset();\n else {\n setTransition(true);\n clampPan();\n apply();\n gesture.current = null;\n }\n }\n return;\n }\n\n if (g.mode === 'swipe') {\n const dx = e.clientX - g.startX;\n const dy = e.clientY - g.startY;\n // A vertical swipe (up or down) past the threshold dismisses the viewer.\n if (Math.abs(dy) > Math.abs(dx) && Math.abs(dy) > CLOSE_PX) {\n close();\n return;\n }\n if (count > 1 && Math.abs(dx) > SWIPE_PX) {\n if (dx < 0) next();\n else prev();\n } else {\n setTransition(true);\n t.current.x = 0;\n t.current.y = 0;\n apply();\n if (overlayRef.current) overlayRef.current.style.opacity = '';\n // A stationary tap on the empty backdrop (not the image) closes.\n if (!g.moved && e.target === stageRef.current) close();\n }\n } else if (g.mode === 'pan') {\n setTransition(true);\n clampPan();\n apply();\n }\n gesture.current = null;\n };\n\n // Tapping the empty backdrop (not the image) closes.\n const onStageClick = (e: React.MouseEvent) => {\n if (e.target === stageRef.current) close();\n };\n\n return (\n <div className=\"viewer-overlay\" ref={overlayRef} role=\"dialog\" aria-modal=\"true\">\n <div\n ref={stageRef}\n className={`viewer-stage${zoomed ? ' is-zoomed' : ''}`}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endPointer}\n onPointerCancel={endPointer}\n onClick={onStageClick}\n >\n <img\n ref={imgRef}\n key={index}\n src={images[index]}\n alt={`Image ${index + 1} of ${count}`}\n className=\"viewer-img\"\n draggable={false}\n />\n </div>\n\n <button className=\"viewer-ctl viewer-close\" onClick={close} aria-label=\"Close\">\n <X />\n </button>\n\n <div className=\"viewer-zoom\">\n <button className=\"viewer-ctl\" onClick={() => zoomCenter(1 / 1.25)} aria-label=\"Zoom out\">\n <ZoomOut />\n </button>\n <button className=\"viewer-ctl\" onClick={() => zoomCenter(1.25)} aria-label=\"Zoom in\">\n <ZoomIn />\n </button>\n </div>\n\n {count > 1 && (\n <>\n <button\n className=\"viewer-ctl viewer-nav viewer-nav--prev\"\n onClick={prev}\n aria-label=\"Previous image\"\n >\n <ChevronLeft />\n </button>\n <button\n className=\"viewer-ctl viewer-nav viewer-nav--next\"\n onClick={next}\n aria-label=\"Next image\"\n >\n <ChevronRight />\n </button>\n <div className=\"viewer-counter\">\n {index + 1} / {count}\n </div>\n </>\n )}\n </div>\n );\n}\n"],"names":["Ctx","createContext","useImageViewer","v","useContext","MIN_SCALE","MAX_SCALE","SWIPE_PX","CLOSE_PX","clamp","lo","hi","ImageViewerProvider","children","images","setImages","useState","index","setIndex","open","useCallback","imgs","i","close","jsxs","createPortal","jsx","Overlay","count","overlayRef","useRef","stageRef","imgRef","t","pointers","gesture","lastTap","zoomed","setZoomed","next","prev","apply","el","setTransition","on","reset","useEffect","prevOverflow","src","img","clampPan","stage","sc","maxX","maxY","zoomAt","factor","cx","cy","rect","ox","oy","prevScale","nextScale","ratio","zoomCenter","r","onWheel","e","onKey","dist","a","b","onPointerDown","_b","_a","now","onPointerMove","g","midX","midY","dx","dy","vertical","endPointer","p","X","ZoomOut","ZoomIn","Fragment","ChevronLeft","ChevronRight"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { ImageViewerProvider, useImageViewer } from './image-viewer';
2
+ export { ViewableImage } from './viewable-image';
3
+ export { ProgressiveImage } from './progressive-image';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/image-viewer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}