@onepercentio/one-ui 0.28.8 → 0.28.9

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 (278) hide show
  1. package/package.json +4 -1
  2. package/src/assets/img/svg/checkbox.svg +3 -0
  3. package/src/assets/styles/index.scss +2 -0
  4. package/src/assets/styles/mixins.scss +12 -0
  5. package/src/assets/styles/variables.scss +49 -0
  6. package/src/components/AdaptiveButton/AdaptiveButton.module.scss +7 -0
  7. package/src/components/AdaptiveButton/AdaptiveButton.tsx +26 -0
  8. package/src/components/AdaptiveButton/index.tsx +1 -0
  9. package/src/components/AdaptiveContainer/AdaptiveContainer.module.scss +53 -0
  10. package/src/components/AdaptiveContainer/AdaptiveContainer.tsx +200 -0
  11. package/src/components/AdaptiveContainer/index.tsx +1 -0
  12. package/src/components/AdaptiveDialog/AdaptiveDialog.module.scss +147 -0
  13. package/src/components/AdaptiveDialog/AdaptiveDialog.tsx +97 -0
  14. package/src/components/AdaptiveDialog/index.tsx +1 -0
  15. package/src/components/AdaptiveSidebar/AdaptiveSidebar.module.scss +49 -0
  16. package/src/components/AdaptiveSidebar/AdaptiveSidebar.sample.tsx +10 -0
  17. package/src/components/AdaptiveSidebar/AdaptiveSidebar.tsx +123 -0
  18. package/src/components/AdaptiveSidebar/index.tsx +1 -0
  19. package/src/components/AnchoredTooltip/AnchoredTooltip.module.scss +64 -0
  20. package/src/components/AnchoredTooltip/AnchoredTooltip.tsx +250 -0
  21. package/src/components/AnchoredTooltip/index.tsx +1 -0
  22. package/src/components/AnimatedEntrance/AnimatedEntrance.module.scss +108 -0
  23. package/src/components/AnimatedEntrance/AnimatedEntrance.tsx +227 -0
  24. package/src/components/AnimatedEntrance/index.tsx +5 -0
  25. package/src/components/AsyncWrapper/AsyncWrapper.tsx +38 -0
  26. package/src/components/AsyncWrapper/index.tsx +1 -0
  27. package/src/components/Avatar/Avatar.module.scss +22 -0
  28. package/src/components/Avatar/Avatar.tsx +31 -0
  29. package/src/components/Avatar/index.tsx +1 -0
  30. package/src/components/BucketFill/BucketFill.module.scss +36 -0
  31. package/src/components/BucketFill/BucketFill.tsx +65 -0
  32. package/src/components/BucketFill/index.tsx +1 -0
  33. package/src/components/Button/Button.module.scss +45 -0
  34. package/src/components/Button/Button.tsx +40 -0
  35. package/src/components/Button/index.tsx +1 -0
  36. package/src/components/Card/Card.module.scss +12 -0
  37. package/src/components/Card/Card.tsx +9 -0
  38. package/src/components/Card/index.tsx +1 -0
  39. package/src/components/Chart/Chart.e2e.ts +4 -0
  40. package/src/components/Chart/Chart.logic.tsx +8 -0
  41. package/src/components/Chart/Chart.module.scss +58 -0
  42. package/src/components/Chart/Chart.types.ts +35 -0
  43. package/src/components/Chart/Chart.view.tsx +240 -0
  44. package/src/components/Chart/index.tsx +1 -0
  45. package/src/components/CheckBox/CheckBox.module.scss +36 -0
  46. package/src/components/CheckBox/CheckBox.tsx +63 -0
  47. package/src/components/CheckBox/index.tsx +1 -0
  48. package/src/components/CodeInput/CodeInput.module.scss +5 -0
  49. package/src/components/CodeInput/CodeInput.tsx +84 -0
  50. package/src/components/CodeInput/index.tsx +1 -0
  51. package/src/components/Collapsable/Collapsable.module.scss +42 -0
  52. package/src/components/Collapsable/Collapsable.tsx +253 -0
  53. package/src/components/Collapsable/index.tsx +1 -0
  54. package/src/components/Countdown/Countdown.tsx +130 -0
  55. package/src/components/Countdown/index.tsx +1 -0
  56. package/src/components/CurrencyInput/CurrencyInput.hook.ts +37 -0
  57. package/src/components/CurrencyInput/CurrencyInput.tsx +25 -0
  58. package/src/components/CurrencyInput/index.tsx +1 -0
  59. package/src/components/Divider/Divider.module.scss +7 -0
  60. package/src/components/Divider/Divider.tsx +13 -0
  61. package/src/components/Divider/index.tsx +1 -0
  62. package/src/components/EmailInput/EmailInput.module.scss +0 -0
  63. package/src/components/EmailInput/EmailInput.tsx +51 -0
  64. package/src/components/EmailInput/index.tsx +1 -0
  65. package/src/components/FadeIn/FadeIn.module.scss +9 -0
  66. package/src/components/FadeIn/FadeIn.tsx +77 -0
  67. package/src/components/FadeIn/index.tsx +1 -0
  68. package/src/components/FileInput/FileInput.module.scss +6 -0
  69. package/src/components/FileInput/FileInput.tsx +75 -0
  70. package/src/components/FileInput/View/BigFactory/BigFactory.module.scss +20 -0
  71. package/src/components/FileInput/View/BigFactory/BigFactory.tsx +48 -0
  72. package/src/components/FileInput/View/BigFactory/index.tsx +1 -0
  73. package/src/components/FileInput/View/Compact/Compact.module.scss +68 -0
  74. package/src/components/FileInput/View/Compact/Compact.tsx +151 -0
  75. package/src/components/FileInput/View/Compact/index.tsx +1 -0
  76. package/src/components/FileInput/View/View.types.ts +12 -0
  77. package/src/components/FileInput/index.tsx +1 -0
  78. package/src/components/FlowController/FlowController.module.scss +47 -0
  79. package/src/components/FlowController/FlowController.tsx +93 -0
  80. package/src/components/FlowController/index.tsx +1 -0
  81. package/src/components/Form/Form.tsx +243 -0
  82. package/src/components/Form/index.ts +1 -0
  83. package/src/components/Form/v2/Form.hook.ts +341 -0
  84. package/src/components/Form/v2/Form.module.scss +0 -0
  85. package/src/components/Form/v2/Form.tsx +78 -0
  86. package/src/components/Form/v2/Form.types.ts +118 -0
  87. package/src/components/Form/v2/FormField/Extensions/DateField/DateField.module.scss +0 -0
  88. package/src/components/Form/v2/FormField/Extensions/DateField/DateField.tsx +73 -0
  89. package/src/components/Form/v2/FormField/Extensions/DateField/index.tsx +1 -0
  90. package/src/components/Form/v2/FormField/Extensions/PhoneField/PhoneField.module.scss +0 -0
  91. package/src/components/Form/v2/FormField/Extensions/PhoneField/PhoneField.tsx +91 -0
  92. package/src/components/Form/v2/FormField/Extensions/PhoneField/index.tsx +1 -0
  93. package/src/components/Form/v2/FormField/FormField.module.scss +0 -0
  94. package/src/components/Form/v2/FormField/FormField.tsx +378 -0
  95. package/src/components/Form/v2/FormField/FormField.types.ts +129 -0
  96. package/src/components/Form/v2/FormField/index.tsx +1 -0
  97. package/src/components/Form/v2/index.tsx +1 -0
  98. package/src/components/Freeze/Freeze.tsx +9 -0
  99. package/src/components/Freeze/index.tsx +1 -0
  100. package/src/components/HSForms/HSForms.tsx +57 -0
  101. package/src/components/HSForms/index.tsx +1 -0
  102. package/src/components/Header/Header.module.scss +119 -0
  103. package/src/components/Header/Header.tsx +138 -0
  104. package/src/components/Header/index.tsx +1 -0
  105. package/src/components/HeaderCloseBtn/HeaderCloseBtn.module.scss +44 -0
  106. package/src/components/HeaderCloseBtn/HeaderCloseBtn.tsx +28 -0
  107. package/src/components/HeaderCloseBtn/index.tsx +1 -0
  108. package/src/components/InfinityScroll/InfinityScroll.module.scss +30 -0
  109. package/src/components/InfinityScroll/InfinityScroll.tsx +187 -0
  110. package/src/components/InfinityScroll/index.tsx +1 -0
  111. package/src/components/Input/Input.module.scss +71 -0
  112. package/src/components/Input/Input.tsx +134 -0
  113. package/src/components/Input/index.tsx +1 -0
  114. package/src/components/InstantCounter/InstantCounter.tsx +77 -0
  115. package/src/components/InstantCounter/index.tsx +1 -0
  116. package/src/components/LavaLamp/LavaLamp.data.tsx +114 -0
  117. package/src/components/LavaLamp/LavaLamp.module.scss +26 -0
  118. package/src/components/LavaLamp/LavaLamp.tsx +131 -0
  119. package/src/components/LavaLamp/index.tsx +1 -0
  120. package/src/components/LavaLamp/v2/LavaLamp.module.scss +23 -0
  121. package/src/components/LavaLamp/v2/LavaLamp.tsx +197 -0
  122. package/src/components/LinkToId/LinkToId.module.scss +4 -0
  123. package/src/components/LinkToId/LinkToId.tsx +51 -0
  124. package/src/components/LinkToId/index.tsx +1 -0
  125. package/src/components/Loader/Loader.module.scss +40 -0
  126. package/src/components/Loader/Loader.tsx +18 -0
  127. package/src/components/Loader/index.tsx +1 -0
  128. package/src/components/LoaderDotsIndicator/LoaderDotsIndicator.tsx +34 -0
  129. package/src/components/LoaderDotsIndicator/index.tsx +1 -0
  130. package/src/components/LoopableVideo/LoopableVideo.tsx +37 -0
  131. package/src/components/LoopableVideo/index.tsx +1 -0
  132. package/src/components/MainGrid/MainGrid.module.scss +28 -0
  133. package/src/components/MainGrid/MainGrid.tsx +68 -0
  134. package/src/components/MainGrid/index.tsx +1 -0
  135. package/src/components/MutableHamburgerButton/MutableHamburgerButton.module.scss +220 -0
  136. package/src/components/MutableHamburgerButton/MutableHamburgerButton.tsx +38 -0
  137. package/src/components/MutableHamburgerButton/index.tsx +1 -0
  138. package/src/components/Notification/Notification.module.scss +25 -0
  139. package/src/components/Notification/Notification.tsx +13 -0
  140. package/src/components/Notification/index.tsx +1 -0
  141. package/src/components/OrderableList/OrderableList.module.scss +98 -0
  142. package/src/components/OrderableList/OrderableList.tsx +564 -0
  143. package/src/components/OrderableList/index.tsx +1 -0
  144. package/src/components/PaginationIndicator/PaginationIndicator.tsx +365 -0
  145. package/src/components/PaginationIndicator/index.tsx +1 -0
  146. package/src/components/Parallax/Parallax.module.scss +28 -0
  147. package/src/components/Parallax/Parallax.tsx +248 -0
  148. package/src/components/Parallax/index.tsx +1 -0
  149. package/src/components/Parallax/math/helpers.ts +289 -0
  150. package/src/components/PasswordInput/PasswordInput.module.scss +17 -0
  151. package/src/components/PasswordInput/PasswordInput.tsx +154 -0
  152. package/src/components/PasswordInput/index.tsx +1 -0
  153. package/src/components/PingPongText/PingPongText.module.scss +4 -0
  154. package/src/components/PingPongText/PingPongText.tsx +83 -0
  155. package/src/components/PingPongText/index.tsx +1 -0
  156. package/src/components/PixelatedScan/PixelatedScan.module.scss +86 -0
  157. package/src/components/PixelatedScan/PixelatedScan.tsx +175 -0
  158. package/src/components/PixelatedScan/index.tsx +1 -0
  159. package/src/components/Portal/Portal.module.scss +3 -0
  160. package/src/components/Portal/Portal.tsx +68 -0
  161. package/src/components/Portal/index.tsx +1 -0
  162. package/src/components/ProgressBar/ProgressBar.module.scss +44 -0
  163. package/src/components/ProgressBar/ProgressBar.tsx +124 -0
  164. package/src/components/ProgressBar/index.tsx +1 -0
  165. package/src/components/ProgressTexts/ProgressTexts.module.scss +37 -0
  166. package/src/components/ProgressTexts/ProgressTexts.tsx +85 -0
  167. package/src/components/ProgressTexts/index.tsx +1 -0
  168. package/src/components/Radio/Radio.module.scss +36 -0
  169. package/src/components/Radio/Radio.tsx +53 -0
  170. package/src/components/Radio/index.tsx +1 -0
  171. package/src/components/SectionContainer/SectionContainer.module.scss +30 -0
  172. package/src/components/SectionContainer/SectionContainer.tsx +49 -0
  173. package/src/components/SectionContainer/index.tsx +1 -0
  174. package/src/components/Select/Select.module.scss +58 -0
  175. package/src/components/Select/Select.tsx +192 -0
  176. package/src/components/Select/index.tsx +1 -0
  177. package/src/components/Skeleton/Skeleton.module.scss +21 -0
  178. package/src/components/Skeleton/Skeleton.tsx +29 -0
  179. package/src/components/Skeleton/index.tsx +1 -0
  180. package/src/components/Spacing/Spacing.module.scss +13 -0
  181. package/src/components/Spacing/Spacing.tsx +24 -0
  182. package/src/components/Spacing/index.tsx +1 -0
  183. package/src/components/StaticScroller/StaticScroller.module.scss +14 -0
  184. package/src/components/StaticScroller/StaticScroller.tsx +83 -0
  185. package/src/components/StaticScroller/index.tsx +1 -0
  186. package/src/components/Switch/Switch.module.scss +43 -0
  187. package/src/components/Switch/Switch.tsx +41 -0
  188. package/src/components/Switch/index.tsx +1 -0
  189. package/src/components/Table/Table.module.scss +76 -0
  190. package/src/components/Table/Table.tsx +152 -0
  191. package/src/components/Table/index.tsx +1 -0
  192. package/src/components/Tabs/Tabs.module.scss +40 -0
  193. package/src/components/Tabs/Tabs.tsx +104 -0
  194. package/src/components/Tabs/index.tsx +1 -0
  195. package/src/components/Text/Text.module.scss +81 -0
  196. package/src/components/Text/Text.tsx +42 -0
  197. package/src/components/Text/index.tsx +1 -0
  198. package/src/components/Transition/MasksFactory/DiagonalReveal.tsx +47 -0
  199. package/src/components/Transition/MasksFactory/DiagonalSquareToBalls.tsx +78 -0
  200. package/src/components/Transition/MasksFactory/PhysicsSquares.tsx +106 -0
  201. package/src/components/Transition/MasksFactory/SquareToBalls.tsx +66 -0
  202. package/src/components/Transition/MasksFactory/utils.ts +35 -0
  203. package/src/components/Transition/Transition.module.scss +211 -0
  204. package/src/components/Transition/Transition.tsx +495 -0
  205. package/src/components/Transition/index.tsx +1 -0
  206. package/src/components/UncontrolledTransition/UncontrolledTransition.ai.md +9 -0
  207. package/src/components/UncontrolledTransition/UncontrolledTransition.sample.tsx +34 -0
  208. package/src/components/UncontrolledTransition/UncontrolledTransition.tsx +143 -0
  209. package/src/components/UncontrolledTransition/index.tsx +2 -0
  210. package/src/components/WalletConnectionWrapper/WalletConnectionWrapper.tsx +212 -0
  211. package/src/components/WalletConnectionWrapper/index.tsx +1 -0
  212. package/src/components/utilitary/ScrollAndFocusLock/ScrollAndFocusLock.module.scss +5 -0
  213. package/src/components/utilitary/ScrollAndFocusLock/ScrollAndFocusLock.tsx +52 -0
  214. package/src/components/utilitary/ScrollAndFocusLock/index.tsx +1 -0
  215. package/src/context/AsyncProcess.tsx +107 -0
  216. package/src/context/ContextAsyncControl.tsx +89 -0
  217. package/src/context/CustomBrowserRouter.tsx +55 -0
  218. package/src/context/OneUIProvider.tsx +308 -0
  219. package/src/hooks/logs/useDependencyChangeDetection.ts +25 -0
  220. package/src/hooks/logs/useIsMounting.ts +7 -0
  221. package/src/hooks/persistence/useLocalStorage.ts +45 -0
  222. package/src/hooks/shims/ObjectWatchShim.ts +56 -0
  223. package/src/hooks/ui/useAdaptiveImage.tsx +36 -0
  224. package/src/hooks/ui/useAlternating.tsx +22 -0
  225. package/src/hooks/ui/useBreakpoint.tsx +21 -0
  226. package/src/hooks/ui/useCustomScrollbar.module.scss +20 -0
  227. package/src/hooks/ui/useCustomScrollbar.tsx +22 -0
  228. package/src/hooks/ui/useEffectIf.ts +11 -0
  229. package/src/hooks/ui/useMouseHover.tsx +26 -0
  230. package/src/hooks/ui/usePaginationControls.module.scss +16 -0
  231. package/src/hooks/ui/usePaginationControls.tsx +176 -0
  232. package/src/hooks/ui/useSnapToViewport.module.scss +6 -0
  233. package/src/hooks/ui/useSnapToViewport.ts +28 -0
  234. package/src/hooks/ui/useTilt.tsx +219 -0
  235. package/src/hooks/ui/useZoomable.module.scss +34 -0
  236. package/src/hooks/ui/useZoomable.tsx +144 -0
  237. package/src/hooks/useAsyncControl.ai.md +25 -0
  238. package/src/hooks/useAsyncControl.ts +101 -0
  239. package/src/hooks/useContainedRepositioning.ts +110 -0
  240. package/src/hooks/useCustomHistory.ts +14 -0
  241. package/src/hooks/useElementFit.ts +82 -0
  242. package/src/hooks/useFirestoreWatch.ts +54 -0
  243. package/src/hooks/useForm.ts +49 -0
  244. package/src/hooks/useFreeze.ts +12 -0
  245. package/src/hooks/useHero.module.scss +41 -0
  246. package/src/hooks/useHero.ts +512 -0
  247. package/src/hooks/useIntersection.ts +32 -0
  248. package/src/hooks/useMergeRefs.ts +29 -0
  249. package/src/hooks/useObserve.ts +24 -0
  250. package/src/hooks/usePagination.ts +228 -0
  251. package/src/hooks/usePooledOperation.ts +54 -0
  252. package/src/hooks/usePooling.ts +46 -0
  253. package/src/hooks/useRebound.ts +23 -0
  254. package/src/hooks/useShortIntl.ai.md +5 -0
  255. package/src/hooks/useShortIntl.ts +97 -0
  256. package/src/hooks/utility/useAsyncMemo.ts +43 -0
  257. package/src/hooks/utility/useDepChange.ts +11 -0
  258. package/src/hooks/utility/useEvents.ts +33 -0
  259. package/src/hooks/utility/useImmediate.ts +8 -0
  260. package/src/hooks/utility/useManualInit.ts +24 -0
  261. package/src/hooks/utility/useModule.ts +15 -0
  262. package/src/hooks/utility/useQuery.ts +15 -0
  263. package/src/hooks/utility/useUniqueEffect.ts +22 -0
  264. package/src/index.ts +3 -0
  265. package/src/models/DebugLogger.ts +7 -0
  266. package/src/models/GenericContract.ts +169 -0
  267. package/src/models/Orbs.ts +97 -0
  268. package/src/reac-app-env.d.ts +6 -0
  269. package/src/storybook/assets/video/txt-reversed.mp4 +0 -0
  270. package/src/storybookUtils/index.tsx +53 -0
  271. package/src/type-utils.ts +49 -0
  272. package/src/utility.d.ts +70 -0
  273. package/src/utils/blockchain.ts +43 -0
  274. package/src/utils/flatten.ts +17 -0
  275. package/src/utils/formatters.ts +36 -0
  276. package/src/utils/html.utils.ts +3 -0
  277. package/src/utils/ownEvent.ts +8 -0
  278. package/src/utils/test.ts +19 -0
@@ -0,0 +1,564 @@
1
+ import throttle from "lodash/throttle";
2
+ import React, {
3
+ createContext,
4
+ DetailedHTMLProps,
5
+ Fragment,
6
+ HTMLAttributes,
7
+ PropsWithChildren,
8
+ ReactElement,
9
+ useCallback,
10
+ useContext,
11
+ useEffect,
12
+ useLayoutEffect,
13
+ useMemo,
14
+ useRef,
15
+ useState,
16
+ } from "react";
17
+ import UncontrolledTransition from "../UncontrolledTransition";
18
+ import TransitionStyles from "../Transition/Transition.module.scss";
19
+ import useHero from "../../hooks/useHero";
20
+ import AnimatedEntrance from "../AnimatedEntrance";
21
+ import { TransitionAnimationTypes } from "../Transition";
22
+ import Styles from "./OrderableList.module.scss";
23
+ import useEvents from "../../hooks/utility/useEvents";
24
+ import ownEvent from "../../utils/ownEvent";
25
+
26
+ type Events = "order-stop" | "order-start";
27
+
28
+ const OrderableListContext = createContext<{
29
+ bindAnchor: (bindElement: HTMLDivElement) => void;
30
+ unbindAnchor: (bindElement: HTMLDivElement) => void;
31
+ on: (eventName: Events, cb: () => void) => () => void;
32
+ }>(null as any);
33
+
34
+ export enum OrderableListReorderMode {
35
+ VERTICAL = "v",
36
+ TWO_DIMENSIONS = "hv",
37
+ }
38
+
39
+ function cleanKeys(keys: string[]) {
40
+ return keys.map((a) => a.split(";")[0]);
41
+ }
42
+
43
+ /**
44
+ * This component receives a list of keyed elements and orders it based of the order provided via the prop "keyOrder"
45
+ **/
46
+ export default function OrderableList({
47
+ children,
48
+ className = "",
49
+ mode = OrderableListReorderMode.VERTICAL,
50
+ shrinkToOnOrder,
51
+ reorderingClassName,
52
+ cloneClassName,
53
+ ...props
54
+ }: {
55
+ children: ReactElement[];
56
+ className?: string;
57
+ mode?: OrderableListReorderMode;
58
+ /**
59
+ * If provided, makes the elements shrink to this value in px when ordering elements
60
+ */
61
+ shrinkToOnOrder?: number;
62
+
63
+ /**
64
+ * A class to apply when reordering
65
+ */
66
+ reorderingClassName?: string;
67
+
68
+ /**
69
+ * A class to apply to the clone el
70
+ */
71
+ cloneClassName?: string;
72
+ } & (
73
+ | {
74
+ keyOrder?: string[];
75
+ onChangeKeyOrder: (newOrder: string[]) => void;
76
+ }
77
+ | {
78
+ currentOrder?: string[];
79
+ }
80
+ ) &
81
+ DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>) {
82
+ const availableKeys = children.map((a) => a.key as string);
83
+ const availableKeysDep = availableKeys.join(",");
84
+ const initializeOrder = useCallback(() => {
85
+ const missingOrderKeys =
86
+ "keyOrder" in props && props.keyOrder
87
+ ? availableKeys.filter((a) => !props.keyOrder!.includes(a))
88
+ : [];
89
+
90
+ return (
91
+ ("keyOrder" in props && props.keyOrder
92
+ ? [...props.keyOrder, ...missingOrderKeys]
93
+ : undefined) || availableKeys
94
+ );
95
+ }, [availableKeysDep, (props as any).keyOrder]);
96
+ const { current: anchorsList } = useRef<HTMLDivElement[]>([]);
97
+ const eventEmitter = useEvents<Events, { [k in Events]: [] }>();
98
+ const currentClone = useRef<HTMLDivElement | null>(null);
99
+ const currentWorkingKey = useRef<string>(undefined);
100
+ const rootRef = useRef<HTMLDivElement>(null as any);
101
+ const [_order, setOrder] = useState(initializeOrder);
102
+ useEffect(() => setOrder(initializeOrder()), [initializeOrder]);
103
+
104
+ const order = useMemo(() => {
105
+ return (
106
+ "currentOrder" in props ? props.currentOrder || _order : _order
107
+ ).filter((o) => o.includes(";") || availableKeys.includes(o));
108
+ }, [(props as any).currentOrder, _order, availableKeysDep]);
109
+ const cleanOrder = useMemo(() => order.map((a) => a.split(";")[0]), [order]);
110
+ const orderId = useMemo(() => "key-" + cleanOrder.join(""), [cleanOrder]);
111
+ function rootEl() {
112
+ if (mode === OrderableListReorderMode.TWO_DIMENSIONS)
113
+ return rootRef.current!.lastElementChild!
114
+ .lastElementChild! as HTMLDivElement;
115
+ return rootRef.current! as HTMLDivElement;
116
+ }
117
+
118
+ const findParentElement = (target: HTMLDivElement) => {
119
+ let parent: HTMLDivElement = target as HTMLDivElement;
120
+ while (parent.parentElement !== rootEl()) {
121
+ if (parent.parentElement === null) break;
122
+ parent = parent.parentElement as any;
123
+ }
124
+ if (process.env.NODE_ENV === "development" && parent === null)
125
+ throw new Error(
126
+ "It seems like we could not find a relation between this element and the root list. Are you using portals maybe?"
127
+ );
128
+ return parent;
129
+ };
130
+
131
+ useLayoutEffect(() => {
132
+ if (shrinkToOnOrder)
133
+ rootEl().style.setProperty("--shrink-to", `${shrinkToOnOrder}px`);
134
+ }, [shrinkToOnOrder]);
135
+
136
+ const calculateReordering = useMemo(() => {
137
+ return throttle((e: any, els: HTMLDivElement[], currentOrder: string[]) => {
138
+ if (els.length > currentOrder.length || !currentWorkingKey.current)
139
+ return;
140
+ const parent = findParentElement(e.target);
141
+ const indexOfKeyInCleanOrder = els.indexOf(parent);
142
+ const keyOfTheOverElement = currentOrder[indexOfKeyInCleanOrder];
143
+ const isDraggingOwnElement =
144
+ currentWorkingKey.current === keyOfTheOverElement;
145
+ if (indexOfKeyInCleanOrder === -1 || keyOfTheOverElement === undefined)
146
+ return;
147
+ if (!isDraggingOwnElement) {
148
+ const { isAfter, isBefore } = (() => {
149
+ if (mode === OrderableListReorderMode.TWO_DIMENSIONS) {
150
+ const distanceFromLeft = e.offsetX;
151
+ const widthOfEl = parent.clientWidth;
152
+ const offset = widthOfEl * 0.25;
153
+ const isAfter = distanceFromLeft > widthOfEl - offset;
154
+ const isBefore = distanceFromLeft < offset;
155
+ return { isAfter, isBefore };
156
+ } else {
157
+ const distanceFromTop = e.offsetY;
158
+ const heightOfEl = parent.clientHeight;
159
+ const offset = heightOfEl * 0.25;
160
+ const isAfter = distanceFromTop > heightOfEl - offset;
161
+ const isBefore = distanceFromTop < offset;
162
+ return { isAfter, isBefore };
163
+ }
164
+ })();
165
+
166
+ const checkIfCanMove = (keyOfOverElement?: string) => {
167
+ return (
168
+ keyOfOverElement === undefined ||
169
+ keyOfOverElement !== currentWorkingKey.current
170
+ );
171
+ };
172
+ const indexOfTheNewElement =
173
+ indexOfKeyInCleanOrder + (isAfter ? 1 : -1);
174
+ const shouldTriggerReordering =
175
+ (isAfter || isBefore) &&
176
+ checkIfCanMove(currentOrder[indexOfTheNewElement]);
177
+ if (shouldTriggerReordering) {
178
+ setOrder((p) => {
179
+ const previousIndex = currentOrder.indexOf(
180
+ currentWorkingKey.current!
181
+ );
182
+ const indexOfKeyInProvidedOrder =
183
+ cleanKeys(p).indexOf(keyOfTheOverElement);
184
+ let indexOfTheNewElement =
185
+ indexOfKeyInProvidedOrder + (isBefore ? -1 : 0);
186
+ if (previousIndex > indexOfTheNewElement) indexOfTheNewElement++;
187
+ const orderWithoutCurrent = p.filter((a) => {
188
+ if (a.startsWith(`${currentWorkingKey.current};`)) return false;
189
+ return a !== currentWorkingKey.current;
190
+ });
191
+ orderWithoutCurrent.splice(
192
+ indexOfTheNewElement,
193
+ 0,
194
+ `${currentWorkingKey.current};${Date.now()}`
195
+ );
196
+ return orderWithoutCurrent;
197
+ });
198
+ }
199
+ }
200
+ }, 1000 / 60);
201
+ }, []);
202
+
203
+ useEffect(() => {
204
+ function registerListeners() {
205
+ const els = Array.from(rootEl()!.children) as HTMLDivElement[];
206
+ const calculateReorderingCall = (e: any) => {
207
+ const els = Array.from(rootEl()!.children) as HTMLDivElement[];
208
+ calculateReordering(e, els, cleanOrder);
209
+ };
210
+ for (let el of els)
211
+ el.addEventListener("mousemove", calculateReorderingCall);
212
+
213
+ return () => {
214
+ for (let el of els)
215
+ el.removeEventListener("mousemove", calculateReorderingCall);
216
+ };
217
+ }
218
+
219
+ if (mode === OrderableListReorderMode.VERTICAL) {
220
+ return registerListeners();
221
+ } else {
222
+ let unsubscribe: () => void;
223
+ let timeout = setTimeout(() => {
224
+ unsubscribe = registerListeners();
225
+ }, 250);
226
+ return () => {
227
+ clearTimeout(timeout);
228
+ if (unsubscribe) unsubscribe();
229
+ };
230
+ }
231
+ }, [cleanOrder]);
232
+
233
+ useEffect(() => {
234
+ if ("onChangeKeyOrder" in props) props.onChangeKeyOrder(cleanKeys(_order));
235
+ }, [_order]);
236
+
237
+ const cleanOrderRef = useRef(cleanOrder);
238
+ useEffect(() => {
239
+ cleanOrderRef.current = cleanOrder;
240
+ }, [cleanOrder]);
241
+ const onAnchorClick = useCallback(
242
+ ({ target: anchor }: Pick<MouseEvent, "target">) => {
243
+ let offset: [x: number, y: number];
244
+ const orderableListItemForAnchor = findParentElement(
245
+ anchor as HTMLDivElement
246
+ );
247
+ const box = orderableListItemForAnchor.getBoundingClientRect();
248
+ const els = Array.from(rootEl()!.children) as HTMLDivElement[];
249
+ const elIndex = els.indexOf(orderableListItemForAnchor);
250
+
251
+ const clone = orderableListItemForAnchor.cloneNode(
252
+ true
253
+ ) as HTMLDivElement;
254
+ currentClone.current = clone;
255
+ if (process.env.NODE_ENV === "development")
256
+ clone.setAttribute("data-testid", "orderable-list-clone");
257
+ clone.setAttribute("data-orderableid", "orderable-list-clone");
258
+ clone.style.width = `${box.width}px`;
259
+ clone.style.height = `${box.height}px`;
260
+ clone.style.top = `${box.top}px`;
261
+ clone.style.left = `${box.left}px`;
262
+ clone.classList.add(Styles.clone);
263
+ if (shrinkToOnOrder) clone.style.maxHeight = `${box.height}px`;
264
+ setTimeout(() => {
265
+ if (cloneClassName) clone.classList.add(cloneClassName);
266
+ if (shrinkToOnOrder) clone.style.maxHeight = `${shrinkToOnOrder}px`;
267
+ }, 0);
268
+
269
+ orderableListItemForAnchor.classList.add(Styles.currentOrdering);
270
+ orderableListItemForAnchor.classList.remove(Styles.visible);
271
+
272
+ const movementControl = (e: MouseEvent | TouchEvent) => {
273
+ const { x: x1, y: y1 } =
274
+ "touches" in e ? { x: e.touches[0].pageX, y: e.touches[0].pageY } : e;
275
+ if (!offset) offset = [x1 - box.left, y1 - box.top];
276
+
277
+ const [offsetX, offsetY] = offset;
278
+ clone.style.top = `${y1 - offsetY}px`;
279
+ clone.style.left = `${x1 - offsetX}px`;
280
+ };
281
+
282
+ document.body.appendChild(clone);
283
+ const deleteClone = () => {
284
+ window.removeEventListener("mousemove", movementControl);
285
+ window.removeEventListener("touchmove", movementControl);
286
+ window.removeEventListener("touchend", deleteClone);
287
+ window.removeEventListener("mouseup", deleteClone);
288
+ orderableListItemForAnchor.style.visibility = "initial";
289
+ currentWorkingKey.current = undefined;
290
+ window.document.body.classList.remove(Styles.unselectable);
291
+ {
292
+ const els = Array.from(rootEl()!.children) as HTMLDivElement[];
293
+ const elInvisible = els.find(
294
+ (a) =>
295
+ !a.classList.contains(Styles.visible) &&
296
+ a.style.maxHeight !== "0px"
297
+ )!;
298
+ if (shrinkToOnOrder) {
299
+ const child = elInvisible.lastElementChild as HTMLDivElement;
300
+ child.style.maxHeight = `${child.scrollHeight}px`;
301
+ child.classList.add(Styles.transitionHeight);
302
+ const onEnd = ownEvent(() => {
303
+ child.removeEventListener("transitionend", onEnd);
304
+ child.style.maxHeight = `initial`;
305
+ child.classList.remove(Styles.transitionHeight);
306
+ });
307
+ child.addEventListener("transitionend", onEnd);
308
+ }
309
+ const box = elInvisible.getBoundingClientRect();
310
+ function cleanUp() {
311
+ if (shrinkToOnOrder) {
312
+ rootEl().style.removeProperty("padding-top");
313
+ rootEl().style.removeProperty("min-height");
314
+ }
315
+
316
+ eventEmitter.dispatcher("order-stop");
317
+ rootEl().classList.remove(Styles.ordering);
318
+ if (reorderingClassName)
319
+ rootEl().classList.remove(reorderingClassName);
320
+ for (let el of els) el.classList.remove(Styles.visible);
321
+ clone.remove();
322
+ currentClone.current = null;
323
+ for (let el of Array.from(elInvisible.children) as HTMLDivElement[])
324
+ el.style.height = "";
325
+ }
326
+ if (
327
+ clone.style.top.startsWith(Math.floor(box.top).toString()) &&
328
+ clone.style.left.startsWith(Math.floor(box.left).toString())
329
+ ) {
330
+ cleanUp();
331
+ } else {
332
+ clone.style.top = `${box.top}px`;
333
+ clone.style.left = `${box.left}px`;
334
+ clone.style.transition = `top 500ms linear, left 500ms linear`;
335
+ clone.addEventListener("transitionend", () => {
336
+ cleanUp();
337
+ });
338
+ }
339
+ }
340
+ };
341
+ for (let el of els) {
342
+ el.classList.add(Styles.visible);
343
+ }
344
+ if (shrinkToOnOrder) {
345
+ for (let el of els) el.style.maxHeight = `${el.scrollHeight}px`;
346
+ const targetHeight = elIndex * shrinkToOnOrder;
347
+ const currentHeight =
348
+ orderableListItemForAnchor.offsetTop - els[0].offsetTop;
349
+ const paddingTop = currentHeight - targetHeight;
350
+ rootEl().style.paddingTop = `${paddingTop}px`;
351
+ rootEl().style.minHeight = `${rootEl().clientHeight}px`;
352
+ }
353
+ orderableListItemForAnchor.style.visibility = "hidden";
354
+ orderableListItemForAnchor.classList.remove(Styles.visible);
355
+ rootEl().classList.add(Styles.ordering);
356
+ if (reorderingClassName) rootEl().classList.add(reorderingClassName);
357
+ currentWorkingKey.current = cleanOrderRef.current[elIndex];
358
+ eventEmitter.dispatcher("order-start");
359
+ window.document.body.classList.add(Styles.unselectable);
360
+ window.addEventListener("mouseup", deleteClone);
361
+ window.addEventListener("mousemove", movementControl);
362
+ window.addEventListener("touchend", deleteClone);
363
+ window.addEventListener("touchmove", movementControl);
364
+ },
365
+ []
366
+ );
367
+
368
+ useLayoutEffect(() => {
369
+ if (currentClone.current) {
370
+ const els = Array.from(rootEl()!.children) as HTMLDivElement[];
371
+ const elInvisible = els.find(
372
+ (a) =>
373
+ !a.classList.contains(Styles.visible) && a.style.maxHeight !== "0px"
374
+ )!;
375
+ (elInvisible.children[0] as HTMLDivElement).style.height = `${
376
+ currentClone.current!.clientHeight
377
+ }px`;
378
+ setTimeout(() => {
379
+ (elInvisible.children[1] as HTMLDivElement).style.height = `${
380
+ currentClone.current!.clientHeight
381
+ }px`;
382
+ }, 150);
383
+ }
384
+ }, [cleanOrder]);
385
+
386
+ const toSpread = { ...props } as any;
387
+ delete toSpread.keyOrder;
388
+ delete toSpread.onChangeKeyOrder;
389
+
390
+ const childrenToRender = [...children]
391
+ .filter((a) => cleanOrder.includes(a.key as string))
392
+ .sort(
393
+ (a, b) =>
394
+ cleanOrder.indexOf(a.key as string) -
395
+ cleanOrder.indexOf(b.key as string)
396
+ )
397
+ .map((a: ReactElement, i) => ({
398
+ ...a,
399
+ key: order[i],
400
+ }));
401
+
402
+ useLayoutEffect(() => {
403
+ rootEl()!.addEventListener("touchstart", (e) => {
404
+ const relatedAnchor = anchorsList.find((anchor) =>
405
+ anchor.contains(e.target as any)
406
+ );
407
+ if (relatedAnchor) {
408
+ e.preventDefault();
409
+ onAnchorClick({
410
+ target: relatedAnchor,
411
+ });
412
+
413
+ const moveCb = throttle((e: TouchEvent) => {
414
+ const touch = e.touches[0];
415
+ const [x, y] = [touch.clientX, touch.clientY];
416
+ const els = Array.from(rootEl().children) as HTMLDivElement[];
417
+ const currentElementIdx = els.findIndex((c, i) => {
418
+ const rect = c?.getBoundingClientRect();
419
+ if (!rect) return false;
420
+ return rect.top < y && rect.top + rect.height > y;
421
+ });
422
+ if (currentElementIdx !== -1) {
423
+ const el = els[currentElementIdx];
424
+ const rect = el.getBoundingClientRect();
425
+ calculateReordering(
426
+ {
427
+ target: el,
428
+ offsetY: y - rect.top,
429
+ },
430
+ els,
431
+ cleanOrderRef.current
432
+ );
433
+ }
434
+ }, 500);
435
+ const t = e.target as HTMLDivElement;
436
+ const touchMoveCb = (e: TouchEvent) => {
437
+ e.stopPropagation();
438
+ window.dispatchEvent(new TouchEvent(e.type, e as any));
439
+ moveCb(e);
440
+ };
441
+ const removeCb = (e: TouchEvent) => {
442
+ t.removeEventListener("touchmove", touchMoveCb);
443
+ t.removeEventListener("touchend", removeCb);
444
+ window.dispatchEvent(new TouchEvent(e.type, e as any));
445
+ };
446
+ t.addEventListener("touchmove", touchMoveCb);
447
+ t.addEventListener("touchend", removeCb);
448
+ }
449
+ });
450
+ }, []);
451
+
452
+ const e = useMemo(
453
+ () => ({
454
+ bindAnchor: (el: HTMLDivElement) => {
455
+ el.addEventListener("mousedown", onAnchorClick);
456
+ anchorsList.push(el);
457
+ },
458
+ unbindAnchor: (el: HTMLDivElement) => {
459
+ el.removeEventListener("mousedown", onAnchorClick);
460
+ anchorsList.splice(anchorsList.indexOf(el), 1);
461
+ },
462
+ on: eventEmitter.subscriber,
463
+ }),
464
+ []
465
+ );
466
+
467
+ return (
468
+ <OrderableListContext.Provider value={e}>
469
+ <div
470
+ ref={rootRef}
471
+ className={`${Styles.root} ${className} ${
472
+ shrinkToOnOrder ? Styles.shrinkable : ""
473
+ }`}
474
+ {...toSpread}
475
+ >
476
+ {mode === OrderableListReorderMode.VERTICAL ? (
477
+ <AnimatedEntrance>{childrenToRender}</AnimatedEntrance>
478
+ ) : (
479
+ <UncontrolledTransition
480
+ className={Styles.transition}
481
+ transitionType={TransitionAnimationTypes.CUSTOM}
482
+ config={{
483
+ backward: {
484
+ elementEntering: "",
485
+ elementExiting: "",
486
+ },
487
+ forward: {
488
+ elementEntering: Styles.stubEntering,
489
+ elementExiting: TransitionStyles.fadeOut,
490
+ },
491
+ }}
492
+ contentClassName={`${className}`}
493
+ >
494
+ <Fragment key={orderId}>
495
+ {[...children]
496
+ .filter((a) => cleanOrder.includes(a.key as string))
497
+ .sort(
498
+ (a, b) =>
499
+ cleanOrder.indexOf(a.key as string) -
500
+ cleanOrder.indexOf(b.key as string)
501
+ )
502
+ .map((a, i) => (
503
+ <HeroWrapper key={i} id={a.key as string}>
504
+ {a}
505
+ </HeroWrapper>
506
+ ))}
507
+ </Fragment>
508
+ </UncontrolledTransition>
509
+ )}
510
+ </div>
511
+ </OrderableListContext.Provider>
512
+ );
513
+ }
514
+
515
+ function HeroWrapper({ children, id }: PropsWithChildren<{ id: string }>) {
516
+ const { heroRef } = useHero(id, undefined, {
517
+ onHeroStart: (_c, _o, t) => {
518
+ t.querySelectorAll("img").forEach(
519
+ (img) => (img.style.visibility = "hidden")
520
+ );
521
+ },
522
+ onHeroCloned(clone) {
523
+ // if (!clone.classList.contains(Styles.visible)) clone.style.opacity = "0";
524
+ },
525
+ onHeroEnd: () => {
526
+ if (heroRef.current)
527
+ heroRef.current
528
+ .querySelectorAll("img")
529
+ .forEach((img) => (img.style.visibility = ""));
530
+ },
531
+ });
532
+ return <div ref={heroRef}>{children}</div>;
533
+ }
534
+
535
+ export function useOrderableListAnchor() {
536
+ const anchorRef = useRef<HTMLDivElement>(null as any);
537
+ const ctx = useContext(OrderableListContext);
538
+ useLayoutEffect(() => {
539
+ if (!ctx) return;
540
+ const { bindAnchor, unbindAnchor } = ctx;
541
+ bindAnchor(anchorRef.current!);
542
+ return () => unbindAnchor(anchorRef.current!);
543
+ }, []);
544
+ return {
545
+ anchorRef: ctx ? anchorRef : undefined,
546
+ };
547
+ }
548
+
549
+ export function useOrderableEvents(
550
+ events: {
551
+ [k in Events]: () => void;
552
+ }
553
+ ) {
554
+ const { on } = useContext(OrderableListContext);
555
+ useEffect(() => {
556
+ const unsubscribers: any[] = [];
557
+ for (let eventName in events) {
558
+ unsubscribers.push(on(eventName as Events, events[eventName as Events]));
559
+ }
560
+ return () => {
561
+ unsubscribers.forEach((u) => u());
562
+ };
563
+ }, [events]);
564
+ }
@@ -0,0 +1 @@
1
+ export { default } from './OrderableList';