@get-set/gs-zoom 0.0.4 → 0.0.6

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 (171) hide show
  1. package/README.md +129 -1
  2. package/actions/general.ts +29 -0
  3. package/actions/getAdjustTransform.ts +46 -0
  4. package/actions/getCurrentParams.ts +42 -0
  5. package/actions/getTranslateCoordToPoint.ts +37 -0
  6. package/actions/init.ts +25 -0
  7. package/actions/initActionEvents.ts +102 -0
  8. package/actions/initAdditionals.ts +91 -0
  9. package/actions/initAdjust.ts +120 -0
  10. package/actions/initAdjustAdditionalActive.ts +31 -0
  11. package/actions/initArrows.ts +36 -0
  12. package/actions/initAutoplay.ts +91 -0
  13. package/actions/initChange.ts +139 -0
  14. package/actions/initClose.ts +29 -0
  15. package/actions/initDraggle.ts +258 -0
  16. package/actions/initDraw.ts +83 -0
  17. package/actions/initDrawItem.ts +77 -0
  18. package/actions/initFullScreen.ts +30 -0
  19. package/actions/initLightBox.ts +13 -0
  20. package/actions/initMagnifier.ts +53 -0
  21. package/actions/initNavigateWithKeys.ts +22 -0
  22. package/actions/initOpen.ts +29 -0
  23. package/actions/initWheel.ts +44 -0
  24. package/actions/setStyles.ts +28 -0
  25. package/components/GSZoom.tsx +178 -0
  26. package/{dist/components → components}/styles/GSZoom.scss +252 -254
  27. package/components/styles/GSZoomCSS.ts +237 -0
  28. package/constants/defaultParams.ts +20 -0
  29. package/constants/icons.ts +25 -0
  30. package/constants/magnifierDefaultProps.ts +9 -0
  31. package/constants/types.ts +6 -0
  32. package/dist/GSZoom.d.ts +2 -0
  33. package/dist/actions/general.d.ts +7 -0
  34. package/dist/actions/general.d.ts.map +1 -0
  35. package/dist/actions/general.js +26 -30
  36. package/dist/actions/general.js.map +1 -0
  37. package/dist/actions/getAdjustTransform.d.ts +3 -0
  38. package/dist/actions/getAdjustTransform.d.ts.map +1 -0
  39. package/dist/actions/getAdjustTransform.js +41 -43
  40. package/dist/actions/getAdjustTransform.js.map +1 -0
  41. package/dist/actions/getCurrentParams.d.ts +4 -0
  42. package/dist/actions/getCurrentParams.d.ts.map +1 -0
  43. package/dist/actions/getCurrentParams.js +35 -42
  44. package/dist/actions/getCurrentParams.js.map +1 -0
  45. package/dist/actions/getTranslateCoordToPoint.d.ts +3 -0
  46. package/dist/actions/getTranslateCoordToPoint.d.ts.map +1 -0
  47. package/dist/actions/getTranslateCoordToPoint.js +21 -41
  48. package/dist/actions/getTranslateCoordToPoint.js.map +1 -0
  49. package/dist/actions/init.d.ts +4 -0
  50. package/dist/actions/init.d.ts.map +1 -0
  51. package/dist/actions/init.js +21 -21
  52. package/dist/actions/init.js.map +1 -0
  53. package/dist/actions/initActionEvents.d.ts +4 -0
  54. package/dist/actions/initActionEvents.d.ts.map +1 -0
  55. package/dist/actions/initActionEvents.js +80 -127
  56. package/dist/actions/initActionEvents.js.map +1 -0
  57. package/dist/actions/initAdditionals.d.ts +4 -0
  58. package/dist/actions/initAdditionals.d.ts.map +1 -0
  59. package/dist/actions/initAdditionals.js +78 -117
  60. package/dist/actions/initAdditionals.js.map +1 -0
  61. package/dist/actions/initAdjust.d.ts +4 -0
  62. package/dist/actions/initAdjust.d.ts.map +1 -0
  63. package/dist/actions/initAdjust.js +96 -107
  64. package/dist/actions/initAdjust.js.map +1 -0
  65. package/dist/actions/initAdjustAdditionalActive.d.ts +4 -0
  66. package/dist/actions/initAdjustAdditionalActive.d.ts.map +1 -0
  67. package/dist/actions/initAdjustAdditionalActive.js +25 -33
  68. package/dist/actions/initAdjustAdditionalActive.js.map +1 -0
  69. package/dist/actions/initArrows.d.ts +4 -0
  70. package/dist/actions/initArrows.d.ts.map +1 -0
  71. package/dist/actions/initArrows.js +28 -44
  72. package/dist/actions/initArrows.js.map +1 -0
  73. package/dist/actions/initAutoplay.d.ts +6 -0
  74. package/dist/actions/initAutoplay.d.ts.map +1 -0
  75. package/dist/actions/initAutoplay.js +85 -81
  76. package/dist/actions/initAutoplay.js.map +1 -0
  77. package/dist/actions/initChange.d.ts +4 -0
  78. package/dist/actions/initChange.d.ts.map +1 -0
  79. package/dist/actions/initChange.js +116 -137
  80. package/dist/actions/initChange.js.map +1 -0
  81. package/dist/actions/initClose.d.ts +3 -0
  82. package/dist/actions/initClose.d.ts.map +1 -0
  83. package/dist/actions/initClose.js +24 -28
  84. package/dist/actions/initClose.js.map +1 -0
  85. package/dist/actions/initDraggle.d.ts +4 -0
  86. package/dist/actions/initDraggle.d.ts.map +1 -0
  87. package/dist/actions/initDraggle.js +227 -303
  88. package/dist/actions/initDraggle.js.map +1 -0
  89. package/dist/actions/initDraw.d.ts +4 -0
  90. package/dist/actions/initDraw.d.ts.map +1 -0
  91. package/dist/actions/initDraw.js +74 -90
  92. package/dist/actions/initDraw.js.map +1 -0
  93. package/dist/actions/initDrawItem.d.ts +4 -0
  94. package/dist/actions/initDrawItem.d.ts.map +1 -0
  95. package/dist/actions/initDrawItem.js +63 -79
  96. package/dist/actions/initDrawItem.js.map +1 -0
  97. package/dist/actions/initFullScreen.d.ts +4 -0
  98. package/dist/actions/initFullScreen.d.ts.map +1 -0
  99. package/dist/actions/initFullScreen.js +32 -32
  100. package/dist/actions/initFullScreen.js.map +1 -0
  101. package/dist/actions/initLightBox.d.ts +4 -0
  102. package/dist/actions/initLightBox.d.ts.map +1 -0
  103. package/dist/actions/initLightBox.js +11 -12
  104. package/dist/actions/initLightBox.js.map +1 -0
  105. package/dist/actions/initMagnifier.d.ts +4 -0
  106. package/dist/actions/initMagnifier.d.ts.map +1 -0
  107. package/dist/actions/initMagnifier.js +42 -54
  108. package/dist/actions/initMagnifier.js.map +1 -0
  109. package/dist/actions/initNavigateWithKeys.d.ts +4 -0
  110. package/dist/actions/initNavigateWithKeys.d.ts.map +1 -0
  111. package/dist/actions/initNavigateWithKeys.js +18 -27
  112. package/dist/actions/initNavigateWithKeys.js.map +1 -0
  113. package/dist/actions/initOpen.d.ts +4 -0
  114. package/dist/actions/initOpen.d.ts.map +1 -0
  115. package/dist/actions/initOpen.js +27 -28
  116. package/dist/actions/initOpen.js.map +1 -0
  117. package/dist/actions/initWheel.d.ts +4 -0
  118. package/dist/actions/initWheel.d.ts.map +1 -0
  119. package/dist/actions/initWheel.js +27 -49
  120. package/dist/actions/initWheel.js.map +1 -0
  121. package/dist/actions/setStyles.d.ts +4 -0
  122. package/dist/actions/setStyles.d.ts.map +1 -0
  123. package/dist/actions/setStyles.js +23 -24
  124. package/dist/actions/setStyles.js.map +1 -0
  125. package/dist/components/GSZoom.d.ts +23 -0
  126. package/dist/components/GSZoom.d.ts.map +1 -0
  127. package/dist/components/GSZoom.js +122 -177
  128. package/dist/components/GSZoom.js.map +1 -0
  129. package/dist/components/styles/GSZoomCSS.d.ts +3 -0
  130. package/dist/components/styles/GSZoomCSS.d.ts.map +1 -0
  131. package/dist/components/styles/GSZoomCSS.js +238 -0
  132. package/dist/components/styles/GSZoomCSS.js.map +1 -0
  133. package/dist/constants/defaultParams.d.ts +4 -0
  134. package/dist/constants/defaultParams.d.ts.map +1 -0
  135. package/dist/constants/defaultParams.js +18 -19
  136. package/dist/constants/defaultParams.js.map +1 -0
  137. package/dist/constants/icons.d.ts +13 -0
  138. package/dist/constants/icons.d.ts.map +1 -0
  139. package/dist/constants/icons.js +16 -25
  140. package/dist/constants/icons.js.map +1 -0
  141. package/dist/constants/magnifierDefaultProps.d.ts +4 -0
  142. package/dist/constants/magnifierDefaultProps.d.ts.map +1 -0
  143. package/dist/constants/magnifierDefaultProps.js +7 -7
  144. package/dist/constants/magnifierDefaultProps.js.map +1 -0
  145. package/dist/constants/types.d.ts +6 -0
  146. package/dist/constants/types.d.ts.map +1 -0
  147. package/dist/constants/types.js +6 -6
  148. package/dist/constants/types.js.map +1 -0
  149. package/dist/helpers/uihelpers.d.ts +2 -0
  150. package/dist/helpers/uihelpers.d.ts.map +1 -0
  151. package/dist/helpers/uihelpers.js +8 -9
  152. package/dist/helpers/uihelpers.js.map +1 -0
  153. package/dist/types/params.d.ts +35 -0
  154. package/dist/types/params.d.ts.map +1 -0
  155. package/dist/types/params.js +2 -0
  156. package/dist/types/params.js.map +1 -0
  157. package/dist/types/ref.d.ts +23 -0
  158. package/dist/types/ref.d.ts.map +1 -0
  159. package/dist/types/ref.js +2 -0
  160. package/dist/types/ref.js.map +1 -0
  161. package/dist-js/bundle.js +1689 -0
  162. package/helpers/uihelpers.ts +7 -0
  163. package/package.json +74 -43
  164. package/styles/GSZoom.scss +252 -0
  165. package/types/global.d.ts +33 -0
  166. package/types/params.ts +36 -0
  167. package/types/ref.ts +23 -0
  168. package/dist/components/styles/GSZoom.css.map +0 -1
  169. package/index.js +0 -3
  170. /package/{dist → components/styles}/GSZoom.css +0 -0
  171. /package/{dist/components/styles → styles}/GSZoom.css +0 -0
@@ -0,0 +1,77 @@
1
+ import initDraggle from './initDraggle';
2
+ import initWheel from './initWheel';
3
+ import { Ref } from '../types/ref';
4
+
5
+ const initDrawItem = (ref: Ref, index: number): void => {
6
+ const params = ref.currentParams;
7
+ const $imgList = ref.$imgList!;
8
+ const $mainImg = $imgList.querySelector(
9
+ `.gs-zoom-main-img[data-index='${index}']`,
10
+ ) as HTMLElement;
11
+
12
+ $mainImg.innerHTML = '';
13
+
14
+ const $imgTouch = document.createElement('div');
15
+ const $imgloading = document.createElement('div');
16
+ const $img = document.createElement('img');
17
+ const item = ref.list[index];
18
+
19
+ $imgloading.classList.add('gz-zoom-loading-container');
20
+ $img.src = item.src.split('?')[0] + params.mainImageQueryParameters;
21
+ $img.classList.add('gs-zoom-img');
22
+ $img.dataset.scale = '1';
23
+ $img.dataset.translatex = '0';
24
+ $img.dataset.translatey = '0';
25
+ $imgTouch.classList.add('gs-zoom-img-touch');
26
+
27
+ $img.onload = () => {
28
+ $mainImg.classList.remove('gz-zoom-is-loading');
29
+ };
30
+ $mainImg.classList.add('gz-zoom-is-loading');
31
+ $mainImg.append($img);
32
+ $imgloading.innerHTML = params.imgLoading!;
33
+ $mainImg.append($imgloading);
34
+ $mainImg.append($imgTouch);
35
+
36
+ // Title / subtitle / description — sourced from data attributes on the original img element
37
+ if (
38
+ (item.dataset.gstitle?.trim().length ?? 0) > 0 ||
39
+ (item.dataset.gssubtitle?.trim().length ?? 0) > 0 ||
40
+ (item.dataset.gsdescription?.trim().length ?? 0) > 0
41
+ ) {
42
+ const $txtarea = document.createElement('div');
43
+ $txtarea.classList.add('gs-zoom-hide-inzoomed');
44
+ $txtarea.classList.add('gs-zoom-info-data');
45
+
46
+ if ((item.dataset.gstitle?.trim().length ?? 0) > 0) {
47
+ const $title = document.createElement('div');
48
+ $title.classList.add('gs-zoom-info-title');
49
+ $title.innerHTML = item.dataset.gstitle!;
50
+ $txtarea.append($title);
51
+ }
52
+ if ((item.dataset.gssubtitle?.trim().length ?? 0) > 0) {
53
+ const $subtitle = document.createElement('div');
54
+ $subtitle.classList.add('gs-zoom-info-subtitle');
55
+ $subtitle.innerHTML = item.dataset.gssubtitle!;
56
+ $txtarea.append($subtitle);
57
+ }
58
+ if ((item.dataset.gsdescription?.trim().length ?? 0) > 0) {
59
+ const $description = document.createElement('div');
60
+ $description.classList.add('gs-zoom-info-description');
61
+ $description.innerHTML = item.dataset.gsdescription!;
62
+ $txtarea.append($description);
63
+ }
64
+ $mainImg.append($txtarea);
65
+ }
66
+
67
+ if (index === ref.currentIndex) {
68
+ ref.$mainImg = $mainImg;
69
+ ref.$imgTouch = $imgTouch;
70
+ ref.$img = $img;
71
+ }
72
+
73
+ initWheel(ref, index);
74
+ initDraggle(ref, index);
75
+ };
76
+
77
+ export default initDrawItem;
@@ -0,0 +1,30 @@
1
+ import { fullscreenchange } from './general';
2
+ import initClose from './initClose';
3
+ import { Ref } from '../types/ref';
4
+
5
+ export const initFullScreen = (ref: Ref): void => {
6
+ const $html = document.querySelector('html') as any;
7
+ if (!ref.currentParams.disableFullScreen) {
8
+ if ($html.requestFullscreen) {
9
+ $html.requestFullscreen();
10
+ } else if ($html.webkitRequestFullscreen) {
11
+ $html.webkitRequestFullscreen();
12
+ } else if ($html.msRequestFullscreen) {
13
+ $html.msRequestFullscreen();
14
+ }
15
+ }
16
+ document.removeEventListener('fullscreenchange', fullscreenchange);
17
+ document.addEventListener('fullscreenchange', fullscreenchange);
18
+ };
19
+
20
+ export const exitFullScreen = (): void => {
21
+ const doc = document as any;
22
+ if (doc.exitFullscreen) {
23
+ doc.exitFullscreen();
24
+ } else if (doc.webkitExitFullscreen) {
25
+ doc.webkitExitFullscreen();
26
+ } else if (doc.msExitFullscreen) {
27
+ doc.msExitFullscreen();
28
+ }
29
+ initClose();
30
+ };
@@ -0,0 +1,13 @@
1
+ import initOpen from './initOpen';
2
+ import { Ref } from '../types/ref';
3
+
4
+ const initLightBox = (ref: Ref): void => {
5
+ ref.list.forEach((item, index) => {
6
+ item.dataset.index = String(index);
7
+ item.addEventListener('click', () => {
8
+ initOpen(ref, index);
9
+ });
10
+ });
11
+ };
12
+
13
+ export default initLightBox;
@@ -0,0 +1,53 @@
1
+ import { Ref } from '../types/ref';
2
+
3
+ const initMagnifier = (ref: Ref, images?: HTMLImageElement[]): void => {
4
+ const params = ref.currentParams.magnifier!;
5
+ const targets = images ?? ref.list;
6
+
7
+ targets.forEach((item) => {
8
+ item.classList.add('gs-zoom-magnifier-instance');
9
+
10
+ item.onmouseenter = (e: MouseEvent) => {
11
+ const $magnifier = document.createElement('div');
12
+ $magnifier.dataset.type = params.form;
13
+
14
+ const $img = document.createElement('img');
15
+ $img.src = item.dataset.gszoomsrc ?? item.src;
16
+ $img.width = item.clientWidth;
17
+ $img.height = item.clientHeight;
18
+ $img.style.objectFit = window.getComputedStyle(item).getPropertyValue('object-fit');
19
+ $img.style.transform = `scale(${params.zoom})`;
20
+
21
+ $magnifier.classList.add('gs-zoom-magnifier');
22
+ $magnifier.append($img);
23
+
24
+ $magnifier.style.width = `${params.size}px`;
25
+ $magnifier.style.top = `${e.clientY - params.size / 2}px`;
26
+ $magnifier.style.left = `${e.clientX - params.size / 2}px`;
27
+
28
+ ref.$magnifier = $magnifier;
29
+ ref.$img = $img;
30
+ document.querySelector('body')!.append($magnifier);
31
+ };
32
+
33
+ item.onmousemove = (e: MouseEvent) => {
34
+ const $img = ref.$img!;
35
+ const imgRect = item.getBoundingClientRect();
36
+ const distanceFromTop = e.clientY - imgRect.top;
37
+ const distanceFromLeft = e.clientX - imgRect.left;
38
+ const $magnifier = ref.$magnifier!;
39
+
40
+ $magnifier.style.top = `${e.clientY - params.size / 2}px`;
41
+ $magnifier.style.left = `${e.clientX - params.size / 2}px`;
42
+ $img.style.top = `${params.size / 2 - distanceFromTop * params.zoom}px`;
43
+ $img.style.left = `${params.size / 2 - distanceFromLeft * params.zoom}px`;
44
+ $img.style.transform = `scale(${params.zoom})`;
45
+ };
46
+
47
+ item.onmouseleave = () => {
48
+ ref.$magnifier?.remove();
49
+ };
50
+ });
51
+ };
52
+
53
+ export default initMagnifier;
@@ -0,0 +1,22 @@
1
+ import initChange from './initChange';
2
+ import { Ref } from '../types/ref';
3
+
4
+ const initNavigateWithKeys = (ref: Ref): void => {
5
+ const params = ref.currentParams;
6
+
7
+ if (params.navigateWithKeys && ref.list.length > 1) {
8
+ document.onkeyup = (e: KeyboardEvent) => {
9
+ if (e.key === 'ArrowRight') {
10
+ const newIndex =
11
+ ref.currentIndex < ref.list.length - 1 ? ref.currentIndex + 1 : 0;
12
+ initChange(ref, newIndex);
13
+ } else if (e.key === 'ArrowLeft') {
14
+ const newIndex =
15
+ ref.currentIndex === 0 ? ref.list.length - 1 : ref.currentIndex - 1;
16
+ initChange(ref, newIndex);
17
+ }
18
+ };
19
+ }
20
+ };
21
+
22
+ export default initNavigateWithKeys;
@@ -0,0 +1,29 @@
1
+ import initActionEvents from './initActionEvents';
2
+ import initAdditionals from './initAdditionals';
3
+ import initArrows from './initArrows';
4
+ import initDraggle from './initDraggle';
5
+ import initDraw from './initDraw';
6
+ import { initFullScreen } from './initFullScreen';
7
+ import initNavigateWithKeys from './initNavigateWithKeys';
8
+ import { Ref } from '../types/ref';
9
+
10
+ const initOpen = (ref: Ref, index: number): void => {
11
+ window.GSZoomConfigue!.openedZoom = ref.currentParams.reference;
12
+ if (typeof ref.currentParams.beforeLightBoxOpen === 'function') {
13
+ ref.currentParams.beforeLightBoxOpen();
14
+ }
15
+ ref.currentIndex = index;
16
+ document.querySelector('html')!.classList.add('gs-zoom-opened');
17
+ initDraw(ref);
18
+ initAdditionals(ref);
19
+ initFullScreen(ref);
20
+ initNavigateWithKeys(ref);
21
+ initArrows(ref);
22
+ initActionEvents(ref);
23
+ if (typeof ref.currentParams.afterLightBoxOpen === 'function') {
24
+ ref.currentParams.afterLightBoxOpen();
25
+ }
26
+ initDraggle(ref, index);
27
+ };
28
+
29
+ export default initOpen;
@@ -0,0 +1,44 @@
1
+ import getTranslateCoordToPoint from './getTranslateCoordToPoint';
2
+ import initAdjust from './initAdjust';
3
+ import setStyles from './setStyles';
4
+ import { Ref } from '../types/ref';
5
+
6
+ const initWheel = (ref: Ref, index: number): void => {
7
+ const params = ref.currentParams;
8
+ const $container = ref.$container!;
9
+ const item = ref.$imgList!.querySelector(
10
+ `.gs-zoom-main-img[data-index='${index}']`,
11
+ ) as HTMLElement;
12
+
13
+ if (item != null && params.zoomOnWheel) {
14
+ item.addEventListener('wheel', function (e: WheelEvent) {
15
+ const $img = this.querySelector('.gs-zoom-img') as HTMLElement;
16
+ const scale =
17
+ $img.dataset.scale !== undefined ? parseFloat($img.dataset.scale) : 1;
18
+
19
+ const newScale =
20
+ e.deltaY < 0 && scale < params.maxZoom!
21
+ ? Math.min(scale + 0.1, params.maxZoom!)
22
+ : e.deltaY > 0 && scale > 1
23
+ ? Math.max(1, scale - 0.1)
24
+ : scale;
25
+
26
+ const [newTranslatex, newTranslatey] = getTranslateCoordToPoint(
27
+ $img,
28
+ $container,
29
+ scale,
30
+ newScale,
31
+ e.clientX,
32
+ e.clientY,
33
+ );
34
+
35
+ $img.dataset.scale = String(newScale);
36
+ setStyles(ref, $img, {
37
+ transform: `scale(${newScale}) translate(${newTranslatex / newScale}px, ${newTranslatey / newScale}px)`,
38
+ });
39
+ initAdjust(ref, $container, $img, false);
40
+ });
41
+ }
42
+ };
43
+
44
+ export default initWheel;
@@ -0,0 +1,28 @@
1
+ import { stopAutoplay } from './initAutoplay';
2
+ import { Ref } from '../types/ref';
3
+
4
+ const setStyles = (ref: Ref, $img: HTMLElement, styles: Record<string, string>): void => {
5
+ const $container = ref.$container!;
6
+
7
+ for (const style in styles) {
8
+ ($img.style as any)[style] = styles[style];
9
+ }
10
+
11
+ const scale =
12
+ $img.dataset.tempscale !== undefined
13
+ ? $img.dataset.tempscale
14
+ : $img.dataset.scale;
15
+
16
+ if (scale === undefined || parseFloat(scale) === 1) {
17
+ $container.classList.remove('gs-zoom-is-zoomed');
18
+ ref.isZoomed = false;
19
+ } else {
20
+ $container.classList.add('gs-zoom-is-zoomed');
21
+ ref.isZoomed = true;
22
+ if (ref.autoplay !== undefined) {
23
+ stopAutoplay(ref);
24
+ }
25
+ }
26
+ };
27
+
28
+ export default setStyles;
@@ -0,0 +1,178 @@
1
+ import React, { useEffect, useRef, useState } from 'react';
2
+ import { NewGuid } from '../helpers/uihelpers';
3
+ import cssContent from './styles/GSZoomCSS';
4
+ import getCurrentParams from '../actions/getCurrentParams';
5
+ import initOpen from '../actions/initOpen';
6
+ import initMagnifier from '../actions/initMagnifier';
7
+ import types from '../constants/types';
8
+ import { Params } from '../types/params';
9
+ import { Ref } from '../types/ref';
10
+
11
+ declare global {
12
+ interface Window {
13
+ GSZoom: any;
14
+ GSZoomConfigue?: {
15
+ references: Array<{ key: string; ref: Ref }>;
16
+ openedZoom: string | undefined;
17
+ instance: (ref: string) => Ref | undefined;
18
+ };
19
+ }
20
+ }
21
+
22
+ export interface GSZoomProps extends Params {
23
+ src?: string;
24
+ children?: React.ReactNode;
25
+ }
26
+
27
+ const GSZoom: React.FC<GSZoomProps> = ({ children, ...rest }) => {
28
+ const params: GSZoomProps = { ...rest };
29
+ const [componentKey, setComponentKey] = useState<string | null>(null);
30
+ const [indexes, setIndexes] = useState<number[]>([]);
31
+ const zoomRef = useRef<HTMLDivElement | null>(null);
32
+ const singleImageRef = useRef<HTMLImageElement | null>(null);
33
+
34
+ useEffect(() => {
35
+ if (componentKey != null) {
36
+ // Initialise the global registry once
37
+ if (typeof window.GSZoomConfigue === 'undefined') {
38
+ window.GSZoomConfigue = {
39
+ references: [],
40
+ openedZoom: undefined,
41
+ instance: (ref: string) => {
42
+ if (ref != undefined && ref !== '') {
43
+ const instance = window.GSZoomConfigue!.references.find(
44
+ (x) => x.key === ref,
45
+ );
46
+ if (instance != undefined) {
47
+ return instance.ref;
48
+ }
49
+ }
50
+ },
51
+ };
52
+ }
53
+
54
+ // Register this instance if it doesn't exist yet
55
+ if (window.GSZoomConfigue.instance(componentKey) === undefined) {
56
+ const currentParams = getCurrentParams(params as Params);
57
+ window.GSZoomConfigue.references.push({
58
+ key: componentKey,
59
+ ref: {
60
+ list: [],
61
+ currentParams,
62
+ currentIndex: 0,
63
+ },
64
+ });
65
+ }
66
+
67
+ const instance = window.GSZoomConfigue.instance(componentKey)!;
68
+
69
+ // Inject styles once — no external CSS import needed by the consumer
70
+ const styleId = 'gs-zoom-styles';
71
+ if (!document.getElementById(styleId)) {
72
+ const style = document.createElement('style');
73
+ style.id = styleId;
74
+ style.textContent = cssContent;
75
+ document.head.appendChild(style);
76
+ }
77
+
78
+ if (params.src != undefined && params.src !== '') {
79
+ // Single-image mode: render an <img> and register it
80
+ const idx = instance.list.length;
81
+ setIndexes([idx]);
82
+
83
+ // We push a placeholder first; once the ref is available (next effect tick)
84
+ // the actual element is in singleImageRef.current
85
+ if (singleImageRef.current != null) {
86
+ instance.list.push(singleImageRef.current);
87
+
88
+ if (instance.currentParams.type === types.lightbox) {
89
+ singleImageRef.current.addEventListener('click', () => {
90
+ initOpen(instance, +singleImageRef.current!.dataset.index!);
91
+ });
92
+ } else if (instance.currentParams.type === types.magnifier) {
93
+ initMagnifier(instance, [singleImageRef.current]);
94
+ }
95
+ }
96
+ } else {
97
+ // Collection mode: grab all <img> elements inside the wrapper
98
+ const images = [...zoomRef.current!.querySelectorAll<HTMLImageElement>('img')];
99
+ const newIndexes: number[] = [];
100
+
101
+ images.forEach((img) => {
102
+ const idx = instance.list.length;
103
+ instance.list.push(img);
104
+ newIndexes.push(idx);
105
+ img.dataset.index = String(idx);
106
+
107
+ if (instance.currentParams.type === types.lightbox) {
108
+ img.addEventListener('click', () => {
109
+ initOpen(instance, idx);
110
+ });
111
+ }
112
+ });
113
+
114
+ if (instance.currentParams.type === types.magnifier) {
115
+ initMagnifier(instance, images);
116
+ }
117
+
118
+ setIndexes(newIndexes);
119
+ }
120
+ }
121
+ }, [componentKey]);
122
+
123
+ useEffect(() => {
124
+ setComponentKey(params.reference ?? NewGuid());
125
+ }, []);
126
+
127
+ // Cleanup: remove this component's images from the shared list on unmount
128
+ useEffect(() => {
129
+ if (indexes.length > 0) {
130
+ return () => {
131
+ if (window.GSZoomConfigue != undefined) {
132
+ const instance = window.GSZoomConfigue.instance(componentKey!);
133
+ if (instance != undefined) {
134
+ instance.list = instance.list.filter(
135
+ (_, i) => !indexes.includes(i),
136
+ );
137
+ }
138
+ }
139
+ };
140
+ }
141
+ }, [indexes]);
142
+
143
+ // Strip GSZoom-specific props so they don't land on the DOM element
144
+ const domProps = Object.fromEntries(
145
+ Object.entries(rest).filter(
146
+ ([key]) =>
147
+ ![
148
+ 'reference', 'arrows', 'navigateWithKeys', 'showAdditionals',
149
+ 'zoomOnWheel', 'maxZoom', 'type', 'mainImageQueryParameters',
150
+ 'additionalImageQueryParameters', 'disableFullScreen', 'imgLoading',
151
+ 'autoplaySpeed', 'magnifier', 'responsive', 'beforeInit', 'afterInit',
152
+ 'beforeLightBoxOpen', 'afterLightBoxOpen', 'beforeLightBoxClose',
153
+ 'afterLightBoxClose', 'afterChange',
154
+ ].includes(key),
155
+ ),
156
+ );
157
+
158
+ return (
159
+ <>
160
+ {params.src != undefined && params.src !== '' ? (
161
+ <img
162
+ ref={singleImageRef}
163
+ {...(indexes[0] !== undefined ? { 'data-index': indexes[0] } : {})}
164
+ {...domProps}
165
+ src={params.src}
166
+ />
167
+ ) : (
168
+ <div className="gs-zoom-collection" ref={zoomRef}>
169
+ {children}
170
+ </div>
171
+ )}
172
+ </>
173
+ );
174
+ };
175
+
176
+ GSZoom.displayName = 'GSZoom';
177
+
178
+ export default GSZoom;