@get-set/gs-sortable 0.0.35 → 0.0.37

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 (110) hide show
  1. package/README.md +99 -1
  2. package/actions/afterAllImagesLoad.ts +36 -0
  3. package/actions/calculate.ts +155 -0
  4. package/actions/calculateOnSort.ts +270 -0
  5. package/actions/checkItemInContainer.ts +22 -0
  6. package/actions/destroy.ts +30 -0
  7. package/actions/general.ts +72 -0
  8. package/actions/getCurrentParams.ts +32 -0
  9. package/actions/init.ts +31 -0
  10. package/actions/initDraggable.ts +85 -0
  11. package/actions/initMouseMove.ts +120 -0
  12. package/actions/initScroll.ts +21 -0
  13. package/actions/initSortEnd.ts +87 -0
  14. package/components/GSSortable.tsx +160 -0
  15. package/components/styles/GSSortable.css +39 -0
  16. package/components/styles/GSSortable.scss +38 -0
  17. package/components/styles/GSSortableCSS.ts +41 -0
  18. package/constants/constParams.ts +5 -0
  19. package/constants/defaultParams.ts +20 -0
  20. package/constants/types.ts +7 -0
  21. package/dist/GSSortable.d.ts +2 -0
  22. package/dist/actions/afterAllImagesLoad.d.ts +4 -0
  23. package/dist/actions/afterAllImagesLoad.d.ts.map +1 -0
  24. package/dist/actions/afterAllImagesLoad.js +35 -0
  25. package/dist/actions/afterAllImagesLoad.js.map +1 -0
  26. package/dist/actions/calculate.d.ts +3 -2
  27. package/dist/actions/calculate.d.ts.map +1 -0
  28. package/dist/actions/calculate.js +13 -18
  29. package/dist/actions/calculate.js.map +1 -1
  30. package/dist/actions/calculateOnSort.d.ts +3 -2
  31. package/dist/actions/calculateOnSort.d.ts.map +1 -0
  32. package/dist/actions/calculateOnSort.js +164 -58
  33. package/dist/actions/calculateOnSort.js.map +1 -1
  34. package/dist/actions/checkItemInContainer.d.ts +1 -0
  35. package/dist/actions/checkItemInContainer.d.ts.map +1 -0
  36. package/dist/actions/checkItemInContainer.js +8 -17
  37. package/dist/actions/checkItemInContainer.js.map +1 -1
  38. package/dist/actions/destroy.d.ts +3 -8
  39. package/dist/actions/destroy.d.ts.map +1 -0
  40. package/dist/actions/destroy.js +7 -9
  41. package/dist/actions/destroy.js.map +1 -1
  42. package/dist/actions/general.d.ts +1 -0
  43. package/dist/actions/general.d.ts.map +1 -0
  44. package/dist/actions/general.js +5 -12
  45. package/dist/actions/general.js.map +1 -1
  46. package/dist/actions/getCurrentParams.d.ts +4 -9
  47. package/dist/actions/getCurrentParams.d.ts.map +1 -0
  48. package/dist/actions/getCurrentParams.js +15 -18
  49. package/dist/actions/getCurrentParams.js.map +1 -1
  50. package/dist/actions/init.d.ts +3 -2
  51. package/dist/actions/init.d.ts.map +1 -0
  52. package/dist/actions/init.js +13 -16
  53. package/dist/actions/init.js.map +1 -1
  54. package/dist/actions/initDraggable.d.ts +3 -2
  55. package/dist/actions/initDraggable.d.ts.map +1 -0
  56. package/dist/actions/initDraggable.js +14 -22
  57. package/dist/actions/initDraggable.js.map +1 -1
  58. package/dist/actions/initMouseMove.d.ts +1 -0
  59. package/dist/actions/initMouseMove.d.ts.map +1 -0
  60. package/dist/actions/initMouseMove.js +40 -53
  61. package/dist/actions/initMouseMove.js.map +1 -1
  62. package/dist/actions/initScroll.d.ts +1 -0
  63. package/dist/actions/initScroll.d.ts.map +1 -0
  64. package/dist/actions/initScroll.js +7 -15
  65. package/dist/actions/initScroll.js.map +1 -1
  66. package/dist/actions/initSortEnd.d.ts +2 -1
  67. package/dist/actions/initSortEnd.d.ts.map +1 -0
  68. package/dist/actions/initSortEnd.js +62 -71
  69. package/dist/actions/initSortEnd.js.map +1 -1
  70. package/dist/components/GSSortable.d.ts +4 -19
  71. package/dist/components/GSSortable.d.ts.map +1 -0
  72. package/dist/components/GSSortable.js +72 -105
  73. package/dist/components/GSSortable.js.map +1 -1
  74. package/dist/components/styles/GSSortableCSS.d.ts +2 -1
  75. package/dist/components/styles/GSSortableCSS.d.ts.map +1 -0
  76. package/dist/components/styles/GSSortableCSS.js +3 -4
  77. package/dist/components/styles/GSSortableCSS.js.map +1 -1
  78. package/dist/constants/constParams.d.ts +4 -3
  79. package/dist/constants/constParams.d.ts.map +1 -0
  80. package/dist/constants/constParams.js +2 -4
  81. package/dist/constants/constParams.js.map +1 -1
  82. package/dist/constants/defaultParams.d.ts +3 -2
  83. package/dist/constants/defaultParams.d.ts.map +1 -0
  84. package/dist/constants/defaultParams.js +3 -8
  85. package/dist/constants/defaultParams.js.map +1 -1
  86. package/dist/constants/types.d.ts +1 -0
  87. package/dist/constants/types.d.ts.map +1 -0
  88. package/dist/constants/types.js +1 -3
  89. package/dist/constants/types.js.map +1 -1
  90. package/dist/helpers/uihelpers.d.ts +2 -1
  91. package/dist/helpers/uihelpers.d.ts.map +1 -0
  92. package/dist/helpers/uihelpers.js +9 -23
  93. package/dist/helpers/uihelpers.js.map +1 -1
  94. package/dist/types/params.d.ts +23 -0
  95. package/dist/types/params.d.ts.map +1 -0
  96. package/dist/types/params.js +2 -0
  97. package/dist/types/params.js.map +1 -0
  98. package/dist/types/ref.d.ts +41 -0
  99. package/dist/types/ref.d.ts.map +1 -0
  100. package/dist/types/ref.js +2 -0
  101. package/dist/types/ref.js.map +1 -0
  102. package/dist-js/bundle.js +1181 -0
  103. package/helpers/uihelpers.ts +44 -0
  104. package/package.json +71 -43
  105. package/styles/GSSortable.css +39 -0
  106. package/styles/GSSortable.scss +38 -0
  107. package/types/global.d.ts +19 -0
  108. package/types/params.ts +24 -0
  109. package/types/ref.ts +41 -0
  110. package/index.js +0 -3
@@ -0,0 +1,32 @@
1
+ import _defaultParams from '../constants/defaultParams';
2
+ import { Params } from '../types/params';
3
+
4
+ const getCurrentParams = (params: Params): Params => {
5
+ const defaultParams: Params = { ..._defaultParams };
6
+ let finalParams: Params = {
7
+ ...defaultParams,
8
+ ...params,
9
+ };
10
+
11
+ if (finalParams.responsive && finalParams.responsive.length > 0) {
12
+ finalParams.responsive.sort((a, b) => b.windowSize - a.windowSize);
13
+ }
14
+
15
+ if (finalParams.responsive && finalParams.responsive.length > 0) {
16
+ const windowSize = window.innerWidth;
17
+ const availableResponsives = finalParams.responsive.filter(
18
+ (resp) => resp.windowSize >= windowSize,
19
+ );
20
+
21
+ availableResponsives.forEach((resp) => {
22
+ finalParams = {
23
+ ...finalParams,
24
+ ...resp.params,
25
+ };
26
+ });
27
+ }
28
+
29
+ return finalParams;
30
+ };
31
+
32
+ export default getCurrentParams;
@@ -0,0 +1,31 @@
1
+ import constParams from '../constants/constParams';
2
+ import calculate from './calculate';
3
+ import initDraggable from './initDraggable';
4
+ import { Ref } from '../types/ref';
5
+
6
+ const init = (ref: Ref): void => {
7
+ const transition = `left ${constParams.animationSpeed}ms, top ${constParams.animationSpeed}ms, transform ${constParams.animationSpeed}ms`;
8
+
9
+ ref.grid.classList.add('gs-sortable-instance');
10
+ ref.grid.classList.add(`gs-sortable-${ref.currentParams.type}`);
11
+
12
+ // Disconnect any observers from a previous init/refresh cycle
13
+ ref.itemResizeObservers?.forEach((obs) => obs.disconnect());
14
+ ref.itemResizeObservers = [];
15
+
16
+ Array.from(ref.grid.children).forEach((el) => {
17
+ const element = el as HTMLElement;
18
+ element.classList.add('gs-sortable-item');
19
+ element.style.transition = transition;
20
+ element.style.position = 'absolute';
21
+
22
+ const obs = new ResizeObserver(() => calculate(ref));
23
+ obs.observe(element);
24
+ ref.itemResizeObservers!.push(obs);
25
+ });
26
+
27
+ ref.count = ref.grid.children.length;
28
+ initDraggable(ref);
29
+ };
30
+
31
+ export default init;
@@ -0,0 +1,85 @@
1
+ import constParams from '../constants/constParams';
2
+ import { getOffsetFromWindow } from './general';
3
+ import { Ref } from '../types/ref';
4
+
5
+ const initDraggable = (ref: Ref): void => {
6
+ const params = ref.currentParams;
7
+ const $items = Array.from(ref.grid.children) as HTMLElement[];
8
+
9
+ $items.forEach(($el, index) => {
10
+ $el.onmousedown = null;
11
+ const handler = params.handler
12
+ ? $el.querySelector<HTMLElement>(params.handler)
13
+ : $el;
14
+
15
+ if (handler instanceof HTMLElement) {
16
+ handler.style.cursor = 'move';
17
+ handler.onmousedown = (e: MouseEvent) => {
18
+ if (!ref.isAdjusting) {
19
+ window.GSSortableConfigue!.overInItemRef = ref;
20
+ window.GSSortableConfigue!.takeFrom = ref;
21
+
22
+ const container = ref.grid;
23
+ const elStyles = getComputedStyle($el);
24
+ const containerStyles = getComputedStyle(container);
25
+ const paddingTop = parseFloat(containerStyles.paddingTop);
26
+ const paddingLeft = parseFloat(containerStyles.paddingLeft);
27
+ const top = parseFloat(elStyles.top);
28
+ const left = parseFloat(elStyles.left);
29
+ let $draggableEl = $el;
30
+ let placeholder: HTMLElement | undefined;
31
+
32
+ if (!params.takeClone) {
33
+ placeholder = document.createElement('div');
34
+ placeholder.classList.add('gs-sortable-placeholder');
35
+ placeholder.style.position = elStyles.position;
36
+ placeholder.style.transition = `left ${constParams.animationSpeed}ms, top ${constParams.animationSpeed}ms, transform ${constParams.animationSpeed}ms, opacity ${constParams.animationSpeed}ms`;
37
+ placeholder.style.width = `${$el.offsetWidth}px`;
38
+ placeholder.style.height = `${$el.offsetHeight}px`;
39
+ placeholder.style.top = `${top}px`;
40
+ placeholder.style.left = `${left}px`;
41
+ placeholder.style.border = elStyles.border;
42
+ placeholder.style.borderRadius = elStyles.borderRadius;
43
+ ref.grid.append(placeholder);
44
+ } else {
45
+ const $cloneEl = $el.cloneNode(true) as HTMLElement;
46
+ ref.grid.append($cloneEl);
47
+ $draggableEl = $cloneEl;
48
+ }
49
+
50
+ const elOffsetWindow = getOffsetFromWindow($el);
51
+ let translateX = !isNaN(left) ? left : 0;
52
+ let translateY = !isNaN(top) ? top : 0;
53
+
54
+ $draggableEl.style.transform = `translate(${translateX - paddingLeft}px, ${translateY - paddingTop}px)`;
55
+ $draggableEl.style.top = `${paddingTop}px`;
56
+ $draggableEl.style.left = `${paddingLeft}px`;
57
+
58
+ window.GSSortableConfigue!.draggableInfo = {
59
+ moved: false,
60
+ ref,
61
+ index,
62
+ $el: $draggableEl,
63
+ clientX: e.clientX,
64
+ clientY: e.clientY,
65
+ placeholder,
66
+ newLeft: left,
67
+ newTop: top,
68
+ fromLeft: (e.clientX - elOffsetWindow.left) / $el.offsetWidth,
69
+ fromTop: (e.clientY - elOffsetWindow.top) / $el.offsetHeight,
70
+ };
71
+
72
+ $draggableEl.classList.add('gs-sortable-item-inmove');
73
+ ref.grid.classList.add('gs-sortable-active');
74
+
75
+ const closestItem = ref.grid.closest('.gs-sortable-item');
76
+ if (closestItem) {
77
+ closestItem.classList.add('gs-sortable-item-active-parent');
78
+ }
79
+ }
80
+ };
81
+ }
82
+ });
83
+ };
84
+
85
+ export default initDraggable;
@@ -0,0 +1,120 @@
1
+ import { getOffsetFromWindow, getTranslateCoord } from './general';
2
+ import checkItemInContainer from './checkItemInContainer';
3
+ import calculate from './calculate';
4
+ import constParams from '../constants/constParams';
5
+ import calculateOnSort from './calculateOnSort';
6
+ import { Ref, DraggableInfo } from '../types/ref';
7
+
8
+ const initMouseMove = (event: MouseEvent): void => {
9
+ const info = window.GSSortableConfigue?.draggableInfo as DraggableInfo | undefined;
10
+
11
+ if (info !== undefined) {
12
+ info.moved = true;
13
+
14
+ const allRefs: Ref[] = [];
15
+ if (window.GSSortableConfigue!.takeFrom !== undefined) {
16
+ allRefs.push(window.GSSortableConfigue!.takeFrom);
17
+ }
18
+ window.GSSortableConfigue!.references.forEach((item) => {
19
+ if (
20
+ item.ref.currentParams.acceptFrom!.includes(
21
+ window.GSSortableConfigue!.takeFrom!.currentParams.reference,
22
+ )
23
+ ) {
24
+ allRefs.push(item.ref);
25
+ }
26
+ });
27
+
28
+ let findedRef = '';
29
+ allRefs.forEach((item) => {
30
+ if (checkItemInContainer(item.grid as HTMLElement, info.$el)) {
31
+ findedRef = item.currentParams.reference;
32
+ }
33
+ });
34
+
35
+ if (findedRef !== '') {
36
+ const newRef = window.GSSortableConfigue!.instance(findedRef);
37
+ if (
38
+ newRef !== undefined &&
39
+ info.ref.currentParams.reference !== newRef.currentParams.reference
40
+ ) {
41
+ const placeholder = document.querySelector('.gs-sortable-placeholder');
42
+ if (placeholder != null) {
43
+ placeholder.remove();
44
+ calculate(window.GSSortableConfigue!.overInItemRef as Ref);
45
+ }
46
+ window.GSSortableConfigue!.overInItemRef = newRef;
47
+ info.$el.style.width = window.GSSortableConfigue!.overInItemRef.itemWidth!;
48
+
49
+ const newWidth = info.$el.clientWidth;
50
+ const newHeight = info.$el.clientHeight;
51
+ const newContainerOffset = getOffsetFromWindow(
52
+ window.GSSortableConfigue!.takeFrom!.grid as HTMLElement,
53
+ );
54
+
55
+ const translateY = event.clientY - newContainerOffset.top - newHeight * info.fromTop;
56
+ const translateX = event.clientX - newContainerOffset.left - newWidth * info.fromLeft;
57
+
58
+ const elStyles = getComputedStyle(info.$el);
59
+ const top = parseFloat(elStyles.top);
60
+ const left = parseFloat(elStyles.left);
61
+
62
+ if (!window.GSSortableConfigue!.overInItemRef.currentParams.takeClone) {
63
+ const newPlaceholder = document.createElement('div');
64
+ newPlaceholder.classList.add('gs-sortable-placeholder');
65
+ newPlaceholder.style.position = elStyles.position;
66
+ info.$el.style.transform = `translate(${translateX}px, ${translateY}px)`;
67
+ newPlaceholder.style.transition = `left ${constParams.animationSpeed}ms, top ${constParams.animationSpeed}ms, transform ${constParams.animationSpeed}ms, opacity ${constParams.animationSpeed}ms`;
68
+ newPlaceholder.style.top = `${top}px`;
69
+ newPlaceholder.style.left = `${left}px`;
70
+ newPlaceholder.style.border = elStyles.border;
71
+ newPlaceholder.style.borderRadius = elStyles.borderRadius;
72
+ info.placeholder = newPlaceholder;
73
+ info.ref = newRef;
74
+ newPlaceholder.style.width = `${info.$el.offsetWidth}px`;
75
+ newPlaceholder.style.height = `${info.$el.offsetHeight}px`;
76
+ newRef.grid.append(newPlaceholder);
77
+ calculate(newRef);
78
+ return;
79
+ } else {
80
+ info.ref = newRef;
81
+ }
82
+ }
83
+ }
84
+
85
+ const params = info.ref.currentParams;
86
+ const $el = info.$el;
87
+ const containerStyles = getComputedStyle(info.ref.grid);
88
+ const paddingLeft = parseFloat(containerStyles.paddingLeft);
89
+ const paddingTop = parseFloat(containerStyles.paddingTop);
90
+ const paddingRight = parseFloat(containerStyles.paddingRight);
91
+ const paddingBottom = parseFloat(containerStyles.paddingBottom);
92
+ const containerInnerHeight = info.ref.grid.clientHeight - paddingTop - paddingBottom;
93
+ const containerInnerWidth = info.ref.grid.clientWidth - paddingLeft - paddingRight;
94
+
95
+ const moveX = event.clientX - info.clientX;
96
+ const moveY = event.clientY - info.clientY;
97
+ const coord = getTranslateCoord($el);
98
+ info.clientX = event.clientX;
99
+ info.clientY = event.clientY;
100
+
101
+ let translateX = moveX + coord.x;
102
+ let translateY = moveY + coord.y;
103
+
104
+ if (!params.allowOutOfBox) {
105
+ translateX = Math.min(Math.max(translateX, 0), containerInnerWidth - $el.offsetWidth);
106
+ translateY = Math.min(Math.max(translateY, 0), containerInnerHeight - $el.offsetHeight);
107
+ }
108
+
109
+ $el.style.transform = `translate(${translateX}px, ${translateY}px)`;
110
+
111
+ if (findedRef !== '') {
112
+ calculateOnSort(window.GSSortableConfigue!.overInItemRef as Ref);
113
+ }
114
+ }
115
+
116
+ window.scrollY = document.documentElement.scrollTop;
117
+ window.scrollX = document.documentElement.scrollLeft;
118
+ };
119
+
120
+ export default initMouseMove;
@@ -0,0 +1,21 @@
1
+ import { getTranslateCoord } from './general';
2
+
3
+ const initScroll = (): void => {
4
+ const info = window.GSSortableConfigue?.draggableInfo;
5
+
6
+ if (info !== undefined) {
7
+ const coord = getTranslateCoord(info.$el);
8
+ const scrollY = document.documentElement.scrollTop;
9
+ const scrollX = document.documentElement.scrollLeft;
10
+
11
+ const translateX = coord.x + (scrollX - (window.scrollX || 0));
12
+ const translateY = coord.y + (scrollY - (window.scrollY || 0));
13
+
14
+ window.scrollY = scrollY;
15
+ window.scrollX = scrollX;
16
+
17
+ info.$el.style.transform = `translate(${translateX}px, ${translateY}px)`;
18
+ }
19
+ };
20
+
21
+ export default initScroll;
@@ -0,0 +1,87 @@
1
+ import constParams from '../constants/constParams';
2
+ import calculate from './calculate';
3
+ import { getOffsetFromBody, moveChildToIndex } from './general';
4
+ import { Ref } from '../types/ref';
5
+
6
+ const initSortEnd = (_event: MouseEvent): void => {
7
+ if (window.GSSortableConfigue?.draggableInfo === undefined) return;
8
+
9
+ // Capture all needed values before clearing the global — prevents a second
10
+ // mousedown during the animation from reading stale isAdjusting state.
11
+ const draggableInfo = window.GSSortableConfigue.draggableInfo;
12
+ const { $el, ref, placeholder, moved, newTop, newLeft, index } = draggableInfo;
13
+ const takeFrom = window.GSSortableConfigue.takeFrom!;
14
+
15
+ // Clear global immediately so new drags are not blocked
16
+ window.GSSortableConfigue.draggableInfo = undefined;
17
+
18
+ if (moved) {
19
+ let containerDifX = 0;
20
+ let containerDifY = 0;
21
+
22
+ if (ref.currentParams.reference !== takeFrom.currentParams.reference) {
23
+ const fromCoord = getOffsetFromBody(takeFrom.grid as HTMLElement);
24
+ const toCoord = getOffsetFromBody(ref.grid as HTMLElement);
25
+ containerDifY = toCoord.top - fromCoord.top;
26
+ containerDifX = toCoord.left - fromCoord.left;
27
+ }
28
+
29
+ ref.isAdjusting = true;
30
+
31
+ $el.classList.remove('gs-sortable-item-inmove');
32
+ ref.grid.classList.remove('gs-sortable-active');
33
+
34
+ const activeParent = ref.grid.closest('.gs-sortable-item-active-parent');
35
+ if (activeParent) {
36
+ activeParent.classList.remove('gs-sortable-item-active-parent');
37
+ }
38
+
39
+ $el.classList.add('gs-sortable-item-adjusting');
40
+
41
+ $el.style.top = `${newTop + containerDifY}px`;
42
+ $el.style.left = `${newLeft + containerDifX}px`;
43
+ $el.style.removeProperty('transform');
44
+
45
+ setTimeout(() => {
46
+ $el.classList.remove('gs-sortable-item-adjusting');
47
+
48
+ if (
49
+ ref.currentParams.reference === takeFrom.currentParams.reference &&
50
+ takeFrom.currentParams.takeClone
51
+ ) {
52
+ $el.remove();
53
+ } else {
54
+ if (index !== undefined) {
55
+ moveChildToIndex(ref.grid as HTMLElement, $el, index);
56
+ }
57
+ }
58
+
59
+ placeholder?.remove();
60
+
61
+ if (ref.currentParams.reference !== takeFrom.currentParams.reference) {
62
+ takeFrom.currentParams.afterSort?.(
63
+ takeFrom.grid.querySelectorAll('.gs-sortable-item'),
64
+ );
65
+ ref.currentParams.afterSort?.(
66
+ ref.grid.querySelectorAll('.gs-sortable-item'),
67
+ );
68
+ takeFrom.refresh();
69
+ ref.refresh();
70
+ } else {
71
+ calculate(ref);
72
+ ref.currentParams.afterSort?.(
73
+ ref.grid.querySelectorAll('.gs-sortable-item'),
74
+ );
75
+ }
76
+
77
+ ref.isAdjusting = false;
78
+ }, constParams.animationSpeed);
79
+ } else {
80
+ $el.style.top = `${newTop}px`;
81
+ $el.style.left = `${newLeft}px`;
82
+ $el.style.removeProperty('transform');
83
+ placeholder?.remove();
84
+ }
85
+ };
86
+
87
+ export default initSortEnd;
@@ -0,0 +1,160 @@
1
+ import React, { useEffect, useRef, useState, ReactNode, CSSProperties } from 'react';
2
+ import getCurrentParams from '../actions/getCurrentParams';
3
+ import init from '../actions/init';
4
+ import destroy from '../actions/destroy';
5
+ import afterAllImagesLoad from '../actions/afterAllImagesLoad';
6
+ import defaultParams from '../constants/defaultParams';
7
+ import initMouseMove from '../actions/initMouseMove';
8
+ import initSortEnd from '../actions/initSortEnd';
9
+ import initScroll from '../actions/initScroll';
10
+ import {
11
+ NewGuid,
12
+ convertScssToCss,
13
+ injectCssToHead,
14
+ removeCssFromHead,
15
+ } from '../helpers/uihelpers';
16
+ import cssContent from './styles/GSSortableCSS';
17
+ import { Params } from '../types/params';
18
+ import { Ref } from '../types/ref';
19
+
20
+ export interface GSSortableProps extends Params {
21
+ children?: ReactNode;
22
+ }
23
+
24
+ const GSSortable: React.FC<GSSortableProps> = ({ children, ...rest }) => {
25
+ const params: Partial<Params> = { ...rest };
26
+ const [componentKey, setComponentKey] = useState<string | null>(null);
27
+ const gridRef = useRef<HTMLDivElement | null>(null);
28
+ const initializedRef = useRef(false);
29
+
30
+ useEffect(() => {
31
+ if (componentKey != null) {
32
+ // Inject CSS once — no external import needed by the consumer
33
+ const styleId = 'gs-sortable-styles';
34
+ if (!document.getElementById(styleId)) {
35
+ const style = document.createElement('style');
36
+ style.id = styleId;
37
+ style.textContent = cssContent;
38
+ document.head.appendChild(style);
39
+ }
40
+
41
+ // Initialise global registry and window event listeners once
42
+ if (typeof window.GSSortableConfigue === 'undefined') {
43
+ window.GSSortableConfigue = {
44
+ references: [],
45
+ instance: (ref: string) => {
46
+ if (ref) {
47
+ const instance = window.GSSortableConfigue?.references.find(
48
+ (x) => x.key === ref,
49
+ );
50
+ if (instance) return instance.ref;
51
+ }
52
+ },
53
+ };
54
+ window.addEventListener('mousemove', (e) => initMouseMove(e));
55
+ window.addEventListener('mouseup', (e) => initSortEnd(e));
56
+ window.addEventListener('scroll', () => initScroll());
57
+ }
58
+
59
+ if (
60
+ window.GSSortableConfigue.references.find(
61
+ (x) => x.key === componentKey,
62
+ ) === undefined
63
+ ) {
64
+ const currentParams = getCurrentParams({
65
+ ...params,
66
+ reference: componentKey,
67
+ } as Params);
68
+
69
+ window.GSSortableConfigue.references.push({
70
+ key: componentKey,
71
+ ref: {
72
+ isAdjusting: false,
73
+ grid: gridRef.current!,
74
+ currentParams: { ...currentParams, reference: componentKey },
75
+ itemResizeObservers: [],
76
+ destroy: () => {
77
+ destroy(window.GSSortableConfigue?.instance(componentKey)!);
78
+ },
79
+ refresh: () => {
80
+ const ref = window.GSSortableConfigue?.instance(componentKey)!;
81
+ destroy(ref);
82
+ init(ref);
83
+ },
84
+ },
85
+ });
86
+
87
+ const currentRef = window.GSSortableConfigue.references.find(
88
+ (x) => x.key === componentKey,
89
+ )?.ref;
90
+
91
+ if (params.gsx && currentRef) {
92
+ const scss: Record<string, CSSProperties> = {};
93
+ scss[`[data-key='${componentKey}']`] = { ...params.gsx };
94
+ const style = convertScssToCss(scss);
95
+ injectCssToHead(style, componentKey);
96
+ }
97
+
98
+ if (currentRef) {
99
+ init(currentRef);
100
+ afterAllImagesLoad(currentRef);
101
+ initializedRef.current = true;
102
+ }
103
+ }
104
+
105
+ return () => {
106
+ const ref = window.GSSortableConfigue?.instance(componentKey);
107
+ if (ref) {
108
+ ref.itemResizeObservers?.forEach((obs) => obs.disconnect());
109
+ ref.itemResizeObservers = [];
110
+ }
111
+ if (window.GSSortableConfigue) {
112
+ window.GSSortableConfigue.references =
113
+ window.GSSortableConfigue.references.filter(
114
+ (x) => x.key !== componentKey,
115
+ );
116
+ }
117
+ removeCssFromHead(componentKey);
118
+ };
119
+ }
120
+ }, [componentKey]);
121
+
122
+ // Re-init when children change (items added/removed) — but only after first init
123
+ useEffect(() => {
124
+ if (componentKey != null && initializedRef.current) {
125
+ const ref = window.GSSortableConfigue?.instance(componentKey);
126
+ if (ref) {
127
+ destroy(ref);
128
+ init(ref);
129
+ afterAllImagesLoad(ref);
130
+ }
131
+ }
132
+ }, [children]);
133
+
134
+ useEffect(() => {
135
+ setComponentKey(params.reference || NewGuid());
136
+ }, []);
137
+
138
+ return (
139
+ <>
140
+ {componentKey != null ? (
141
+ <div
142
+ className={`gs-sortable-instance gs-sortable-${params.type ?? 'column'} ${
143
+ rest.className || ''
144
+ }`}
145
+ ref={gridRef}
146
+ data-key={componentKey}
147
+ {...Object.fromEntries(
148
+ Object.entries(rest).filter(([key]) => !(key in defaultParams)),
149
+ )}
150
+ >
151
+ {children}
152
+ </div>
153
+ ) : null}
154
+ </>
155
+ );
156
+ };
157
+
158
+ GSSortable.displayName = 'GSSortable';
159
+
160
+ export default GSSortable;
@@ -0,0 +1,39 @@
1
+ .gs-sortable-instance {
2
+ box-sizing: border-box;
3
+ -webkit-user-select: none !important;
4
+ -moz-user-select: none !important;
5
+ user-select: none !important;
6
+ transition: 0.4s;
7
+ z-index: 1;
8
+ }
9
+ .gs-sortable-instance.gs-sortable-active {
10
+ z-index: 2;
11
+ }
12
+ .gs-sortable-instance * {
13
+ -webkit-user-select: none !important;
14
+ -moz-user-select: none !important;
15
+ user-select: none !important;
16
+ }
17
+ .gs-sortable-instance .gs-sortable-placeholder {
18
+ position: absolute;
19
+ background-color: #f1f1f1;
20
+ border: 1px solid;
21
+ z-index: 1;
22
+ }
23
+ .gs-sortable-instance .gs-sortable-item {
24
+ z-index: 2;
25
+ }
26
+ .gs-sortable-instance .gs-sortable-item.gs-sortable-item-active-parent {
27
+ z-index: 3;
28
+ }
29
+ .gs-sortable-instance .gs-sortable-item-inmove {
30
+ transition: none !important;
31
+ z-index: 99999;
32
+ }
33
+ .gs-sortable-instance .gs-sortable-item-addjusting {
34
+ z-index: 99999;
35
+ }
36
+ .gs-sortable-instance.gs-sortable-row .gs-sortable-item {
37
+ width: -moz-max-content;
38
+ width: max-content;
39
+ }/*# sourceMappingURL=GSSortable.css.map */
@@ -0,0 +1,38 @@
1
+ .gs-sortable-instance {
2
+ box-sizing: border-box;
3
+ user-select: none !important;
4
+ transition: 0.4s;
5
+ z-index: 1;
6
+ &.gs-sortable-active {
7
+ z-index: 2;
8
+ }
9
+
10
+ * {
11
+ user-select: none !important;
12
+ }
13
+ .gs-sortable-placeholder {
14
+ position: absolute;
15
+ background-color: #f1f1f1;
16
+ border: 1px solid;
17
+ z-index: 1;
18
+ }
19
+ .gs-sortable-item {
20
+ z-index: 2;
21
+ &.gs-sortable-item-active-parent {
22
+ z-index: 3;
23
+ }
24
+ }
25
+ .gs-sortable-item-inmove {
26
+ //transition: width 0.2s, height 0.2s !important;
27
+ transition: none !important;
28
+ z-index: 99999;
29
+ }
30
+ .gs-sortable-item-addjusting {
31
+ z-index: 99999;
32
+ }
33
+ &.gs-sortable-row {
34
+ .gs-sortable-item {
35
+ width: max-content;
36
+ }
37
+ }
38
+ }
@@ -0,0 +1,41 @@
1
+ export default `
2
+ .gs-sortable-instance {
3
+ box-sizing: border-box;
4
+ -webkit-user-select: none !important;
5
+ -moz-user-select: none !important;
6
+ user-select: none !important;
7
+ transition: 0.4s;
8
+ z-index: 1;
9
+ }
10
+ .gs-sortable-instance.gs-sortable-active {
11
+ z-index: 2;
12
+ }
13
+ .gs-sortable-instance * {
14
+ -webkit-user-select: none !important;
15
+ -moz-user-select: none !important;
16
+ user-select: none !important;
17
+ }
18
+ .gs-sortable-instance .gs-sortable-placeholder {
19
+ position: absolute;
20
+ background-color: #f1f1f1;
21
+ border: 1px solid;
22
+ z-index: 1;
23
+ }
24
+ .gs-sortable-instance .gs-sortable-item {
25
+ z-index: 2;
26
+ }
27
+ .gs-sortable-instance .gs-sortable-item.gs-sortable-item-active-parent {
28
+ z-index: 3;
29
+ }
30
+ .gs-sortable-instance .gs-sortable-item-inmove {
31
+ transition: none !important;
32
+ z-index: 99999;
33
+ }
34
+ .gs-sortable-instance .gs-sortable-item-addjusting {
35
+ z-index: 99999;
36
+ }
37
+ .gs-sortable-instance.gs-sortable-row .gs-sortable-item {
38
+ width: -moz-max-content;
39
+ width: max-content;
40
+ }/*# sourceMappingURL=GSSortable.css.map */
41
+ `;
@@ -0,0 +1,5 @@
1
+ const constParams = {
2
+ animationSpeed: 400,
3
+ } as const;
4
+
5
+ export default Object.freeze(constParams);
@@ -0,0 +1,20 @@
1
+ import types from './types';
2
+ import { Params } from '../types/params';
3
+
4
+ const defaultParams: Params = {
5
+ acceptFrom: [],
6
+ className: '',
7
+ takeClone: false,
8
+ reference: '',
9
+ count: 3,
10
+ gap: '',
11
+ gsx: undefined,
12
+ handler: '',
13
+ width: 'auto',
14
+ type: types.column,
15
+ allowOutOfBox: true,
16
+ responsive: [],
17
+ afterSort: () => {},
18
+ };
19
+
20
+ export default Object.freeze(defaultParams);