piral-core 0.14.0-pre.3018 → 0.14.0-pre.3085

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 (300) hide show
  1. package/debug-pilet.d.ts +3 -0
  2. package/debug-pilet.js +12 -0
  3. package/debug-pilet.ts +11 -0
  4. package/debug-piral.d.ts +4 -0
  5. package/debug-piral.js +59 -0
  6. package/debug-piral.ts +74 -0
  7. package/esm/Piral.js +6 -8
  8. package/esm/Piral.js.map +1 -1
  9. package/esm/actions/app.js +9 -10
  10. package/esm/actions/app.js.map +1 -1
  11. package/esm/actions/components.js +4 -5
  12. package/esm/actions/components.js.map +1 -1
  13. package/esm/actions/data.js +16 -17
  14. package/esm/actions/data.js.map +1 -1
  15. package/esm/actions/define.js +2 -3
  16. package/esm/actions/define.js.map +1 -1
  17. package/esm/actions/portal.d.ts +2 -0
  18. package/esm/actions/portal.js +9 -4
  19. package/esm/actions/portal.js.map +1 -1
  20. package/esm/actions/state.js +1 -1
  21. package/esm/actions/state.js.map +1 -1
  22. package/esm/components/DefaultErrorInfo.js +1 -2
  23. package/esm/components/DefaultErrorInfo.js.map +1 -1
  24. package/esm/components/DefaultLayout.js +1 -4
  25. package/esm/components/DefaultLayout.js.map +1 -1
  26. package/esm/components/DefaultLoader.js +1 -1
  27. package/esm/components/DefaultLoader.js.map +1 -1
  28. package/esm/components/ErrorBoundary.js +13 -18
  29. package/esm/components/ErrorBoundary.js.map +1 -1
  30. package/esm/components/ExtensionSlot.js +5 -9
  31. package/esm/components/ExtensionSlot.js.map +1 -1
  32. package/esm/components/Mediator.js +8 -8
  33. package/esm/components/Mediator.js.map +1 -1
  34. package/esm/components/PiralRoutes.js +8 -8
  35. package/esm/components/PiralRoutes.js.map +1 -1
  36. package/esm/components/PiralView.js +11 -16
  37. package/esm/components/PiralView.js.map +1 -1
  38. package/esm/components/PortalRenderer.d.ts +5 -0
  39. package/esm/components/PortalRenderer.js +7 -0
  40. package/esm/components/PortalRenderer.js.map +1 -0
  41. package/esm/components/ResponsiveLayout.js +5 -6
  42. package/esm/components/ResponsiveLayout.js.map +1 -1
  43. package/esm/components/SetComponent.js +3 -4
  44. package/esm/components/SetComponent.js.map +1 -1
  45. package/esm/components/SetError.js +3 -4
  46. package/esm/components/SetError.js.map +1 -1
  47. package/esm/components/SetErrors.js +2 -3
  48. package/esm/components/SetErrors.js.map +1 -1
  49. package/esm/components/SetLayout.js +2 -3
  50. package/esm/components/SetLayout.js.map +1 -1
  51. package/esm/components/SetProvider.js +3 -4
  52. package/esm/components/SetProvider.js.map +1 -1
  53. package/esm/components/SetRedirect.js +3 -4
  54. package/esm/components/SetRedirect.js.map +1 -1
  55. package/esm/components/SetRoute.js +3 -4
  56. package/esm/components/SetRoute.js.map +1 -1
  57. package/esm/components/SwitchErrorInfo.js +12 -10
  58. package/esm/components/SwitchErrorInfo.js.map +1 -1
  59. package/esm/components/components.js +8 -9
  60. package/esm/components/components.js.map +1 -1
  61. package/esm/components/index.d.ts +1 -0
  62. package/esm/components/index.js +1 -0
  63. package/esm/components/index.js.map +1 -1
  64. package/esm/createInstance.js +24 -25
  65. package/esm/createInstance.js.map +1 -1
  66. package/esm/helpers.d.ts +11 -26
  67. package/esm/helpers.js +18 -56
  68. package/esm/helpers.js.map +1 -1
  69. package/esm/hooks/action.js +1 -1
  70. package/esm/hooks/action.js.map +1 -1
  71. package/esm/hooks/actions.js +1 -1
  72. package/esm/hooks/actions.js.map +1 -1
  73. package/esm/hooks/globalState.js +5 -5
  74. package/esm/hooks/globalState.js.map +1 -1
  75. package/esm/hooks/index.d.ts +0 -5
  76. package/esm/hooks/index.js +0 -5
  77. package/esm/hooks/index.js.map +1 -1
  78. package/esm/hooks/media.js +8 -7
  79. package/esm/hooks/media.js.map +1 -1
  80. package/esm/hooks/setter.js +3 -2
  81. package/esm/hooks/setter.js.map +1 -1
  82. package/esm/hooks/sharedData.js +2 -2
  83. package/esm/hooks/sharedData.js.map +1 -1
  84. package/esm/modules/api.js +79 -28
  85. package/esm/modules/api.js.map +1 -1
  86. package/esm/modules/dependencies.d.ts +3 -4
  87. package/esm/modules/dependencies.js +11 -14
  88. package/esm/modules/dependencies.js.map +1 -1
  89. package/esm/state/createActions.js +7 -12
  90. package/esm/state/createActions.js.map +1 -1
  91. package/esm/state/createGlobalState.js +6 -8
  92. package/esm/state/createGlobalState.js.map +1 -1
  93. package/esm/state/stateContext.js +1 -1
  94. package/esm/state/stateContext.js.map +1 -1
  95. package/esm/state/withApi.js +59 -62
  96. package/esm/state/withApi.js.map +1 -1
  97. package/esm/types/config.d.ts +23 -16
  98. package/esm/types/state.d.ts +13 -0
  99. package/esm/utils/compare.js +4 -4
  100. package/esm/utils/compare.js.map +1 -1
  101. package/esm/utils/data.js +6 -7
  102. package/esm/utils/data.js.map +1 -1
  103. package/esm/utils/foreign.d.ts +4 -2
  104. package/esm/utils/foreign.js +16 -8
  105. package/esm/utils/foreign.js.map +1 -1
  106. package/esm/utils/guid.js +3 -3
  107. package/esm/utils/guid.js.map +1 -1
  108. package/esm/utils/helpers.d.ts +11 -8
  109. package/esm/utils/helpers.js +28 -17
  110. package/esm/utils/helpers.js.map +1 -1
  111. package/esm/utils/media.js +8 -7
  112. package/esm/utils/media.js.map +1 -1
  113. package/esm/utils/storage.js +13 -14
  114. package/esm/utils/storage.js.map +1 -1
  115. package/lib/Piral.js +9 -11
  116. package/lib/Piral.js.map +1 -1
  117. package/lib/actions/app.js +11 -12
  118. package/lib/actions/app.js.map +1 -1
  119. package/lib/actions/components.js +5 -6
  120. package/lib/actions/components.js.map +1 -1
  121. package/lib/actions/data.js +17 -18
  122. package/lib/actions/data.js.map +1 -1
  123. package/lib/actions/define.js +2 -3
  124. package/lib/actions/define.js.map +1 -1
  125. package/lib/actions/index.js +7 -7
  126. package/lib/actions/index.js.map +1 -1
  127. package/lib/actions/portal.d.ts +2 -0
  128. package/lib/actions/portal.js +12 -5
  129. package/lib/actions/portal.js.map +1 -1
  130. package/lib/actions/state.js +3 -3
  131. package/lib/actions/state.js.map +1 -1
  132. package/lib/components/DefaultErrorInfo.js +4 -5
  133. package/lib/components/DefaultErrorInfo.js.map +1 -1
  134. package/lib/components/DefaultLayout.js +2 -5
  135. package/lib/components/DefaultLayout.js.map +1 -1
  136. package/lib/components/DefaultLoader.js +2 -2
  137. package/lib/components/DefaultLoader.js.map +1 -1
  138. package/lib/components/ErrorBoundary.js +18 -22
  139. package/lib/components/ErrorBoundary.js.map +1 -1
  140. package/lib/components/ExtensionSlot.js +10 -14
  141. package/lib/components/ExtensionSlot.js.map +1 -1
  142. package/lib/components/Mediator.js +11 -11
  143. package/lib/components/Mediator.js.map +1 -1
  144. package/lib/components/PiralRoutes.js +11 -11
  145. package/lib/components/PiralRoutes.js.map +1 -1
  146. package/lib/components/PiralView.js +16 -21
  147. package/lib/components/PiralView.js.map +1 -1
  148. package/lib/components/PortalRenderer.d.ts +5 -0
  149. package/lib/components/PortalRenderer.js +11 -0
  150. package/lib/components/PortalRenderer.js.map +1 -0
  151. package/lib/components/ResponsiveLayout.js +9 -10
  152. package/lib/components/ResponsiveLayout.js.map +1 -1
  153. package/lib/components/SetComponent.js +4 -5
  154. package/lib/components/SetComponent.js.map +1 -1
  155. package/lib/components/SetError.js +4 -5
  156. package/lib/components/SetError.js.map +1 -1
  157. package/lib/components/SetErrors.js +4 -5
  158. package/lib/components/SetErrors.js.map +1 -1
  159. package/lib/components/SetLayout.js +4 -5
  160. package/lib/components/SetLayout.js.map +1 -1
  161. package/lib/components/SetProvider.js +4 -5
  162. package/lib/components/SetProvider.js.map +1 -1
  163. package/lib/components/SetRedirect.js +6 -7
  164. package/lib/components/SetRedirect.js.map +1 -1
  165. package/lib/components/SetRoute.js +4 -5
  166. package/lib/components/SetRoute.js.map +1 -1
  167. package/lib/components/SwitchErrorInfo.js +14 -12
  168. package/lib/components/SwitchErrorInfo.js.map +1 -1
  169. package/lib/components/components.js +5 -6
  170. package/lib/components/components.js.map +1 -1
  171. package/lib/components/index.d.ts +1 -0
  172. package/lib/components/index.js +20 -19
  173. package/lib/components/index.js.map +1 -1
  174. package/lib/createInstance.js +31 -32
  175. package/lib/createInstance.js.map +1 -1
  176. package/lib/helpers.d.ts +11 -26
  177. package/lib/helpers.js +19 -59
  178. package/lib/helpers.js.map +1 -1
  179. package/lib/hooks/action.js +3 -3
  180. package/lib/hooks/action.js.map +1 -1
  181. package/lib/hooks/actions.js +4 -4
  182. package/lib/hooks/actions.js.map +1 -1
  183. package/lib/hooks/globalState.js +8 -8
  184. package/lib/hooks/globalState.js.map +1 -1
  185. package/lib/hooks/index.d.ts +0 -5
  186. package/lib/hooks/index.js +7 -12
  187. package/lib/hooks/index.js.map +1 -1
  188. package/lib/hooks/media.js +10 -9
  189. package/lib/hooks/media.js.map +1 -1
  190. package/lib/hooks/setter.js +4 -3
  191. package/lib/hooks/setter.js.map +1 -1
  192. package/lib/hooks/sharedData.js +3 -3
  193. package/lib/hooks/sharedData.js.map +1 -1
  194. package/lib/index.js +9 -9
  195. package/lib/index.js.map +1 -1
  196. package/lib/modules/api.js +86 -35
  197. package/lib/modules/api.js.map +1 -1
  198. package/lib/modules/dependencies.d.ts +3 -4
  199. package/lib/modules/dependencies.js +13 -16
  200. package/lib/modules/dependencies.js.map +1 -1
  201. package/lib/modules/index.js +3 -3
  202. package/lib/modules/index.js.map +1 -1
  203. package/lib/state/createActions.js +8 -13
  204. package/lib/state/createActions.js.map +1 -1
  205. package/lib/state/createGlobalState.js +9 -11
  206. package/lib/state/createGlobalState.js.map +1 -1
  207. package/lib/state/index.js +5 -5
  208. package/lib/state/index.js.map +1 -1
  209. package/lib/state/stateContext.js +1 -1
  210. package/lib/state/stateContext.js.map +1 -1
  211. package/lib/state/withApi.js +67 -70
  212. package/lib/state/withApi.js.map +1 -1
  213. package/lib/types/config.d.ts +23 -16
  214. package/lib/types/index.js +13 -13
  215. package/lib/types/index.js.map +1 -1
  216. package/lib/types/state.d.ts +13 -0
  217. package/lib/utils/compare.js +4 -4
  218. package/lib/utils/compare.js.map +1 -1
  219. package/lib/utils/data.js +6 -7
  220. package/lib/utils/data.js.map +1 -1
  221. package/lib/utils/foreign.d.ts +4 -2
  222. package/lib/utils/foreign.js +21 -11
  223. package/lib/utils/foreign.js.map +1 -1
  224. package/lib/utils/guid.js +3 -3
  225. package/lib/utils/guid.js.map +1 -1
  226. package/lib/utils/helpers.d.ts +11 -8
  227. package/lib/utils/helpers.js +30 -17
  228. package/lib/utils/helpers.js.map +1 -1
  229. package/lib/utils/index.js +9 -9
  230. package/lib/utils/index.js.map +1 -1
  231. package/lib/utils/media.js +7 -6
  232. package/lib/utils/media.js.map +1 -1
  233. package/lib/utils/react.js +1 -1
  234. package/lib/utils/react.js.map +1 -1
  235. package/lib/utils/storage.js +11 -12
  236. package/lib/utils/storage.js.map +1 -1
  237. package/package.json +12 -5
  238. package/src/Piral.tsx +2 -1
  239. package/src/actions/portal.ts +19 -1
  240. package/src/components/ExtensionSlot.tsx +2 -2
  241. package/src/components/Mediator.tsx +2 -1
  242. package/src/components/PortalRenderer.tsx +12 -0
  243. package/src/components/SwitchErrorInfo.tsx +5 -1
  244. package/src/components/index.ts +1 -0
  245. package/src/createInstance.tsx +6 -7
  246. package/src/helpers.test.tsx +7 -39
  247. package/src/helpers.tsx +32 -85
  248. package/src/hooks/index.ts +0 -5
  249. package/src/hooks/media.ts +2 -1
  250. package/src/hooks/setter.ts +2 -1
  251. package/src/modules/api.ts +72 -4
  252. package/src/modules/dependencies.test.ts +18 -5
  253. package/src/modules/dependencies.ts +12 -18
  254. package/src/state/withApi.tsx +12 -14
  255. package/src/types/config.ts +23 -17
  256. package/src/types/state.ts +13 -0
  257. package/src/utils/foreign.test.ts +4 -4
  258. package/src/utils/foreign.ts +28 -5
  259. package/src/utils/helpers.ts +21 -7
  260. package/src/utils/media.ts +2 -1
  261. package/esm/hooks/debounce.d.ts +0 -8
  262. package/esm/hooks/debounce.js +0 -18
  263. package/esm/hooks/debounce.js.map +0 -1
  264. package/esm/hooks/lockBodyScroll.d.ts +0 -6
  265. package/esm/hooks/lockBodyScroll.js +0 -15
  266. package/esm/hooks/lockBodyScroll.js.map +0 -1
  267. package/esm/hooks/onClickOutside.d.ts +0 -8
  268. package/esm/hooks/onClickOutside.js +0 -23
  269. package/esm/hooks/onClickOutside.js.map +0 -1
  270. package/esm/hooks/onScreenVisible.d.ts +0 -11
  271. package/esm/hooks/onScreenVisible.js +0 -28
  272. package/esm/hooks/onScreenVisible.js.map +0 -1
  273. package/esm/hooks/promise.d.ts +0 -13
  274. package/esm/hooks/promise.js +0 -21
  275. package/esm/hooks/promise.js.map +0 -1
  276. package/lib/hooks/debounce.d.ts +0 -8
  277. package/lib/hooks/debounce.js +0 -22
  278. package/lib/hooks/debounce.js.map +0 -1
  279. package/lib/hooks/lockBodyScroll.d.ts +0 -6
  280. package/lib/hooks/lockBodyScroll.js +0 -19
  281. package/lib/hooks/lockBodyScroll.js.map +0 -1
  282. package/lib/hooks/onClickOutside.d.ts +0 -8
  283. package/lib/hooks/onClickOutside.js +0 -27
  284. package/lib/hooks/onClickOutside.js.map +0 -1
  285. package/lib/hooks/onScreenVisible.d.ts +0 -11
  286. package/lib/hooks/onScreenVisible.js +0 -32
  287. package/lib/hooks/onScreenVisible.js.map +0 -1
  288. package/lib/hooks/promise.d.ts +0 -13
  289. package/lib/hooks/promise.js +0 -25
  290. package/lib/hooks/promise.js.map +0 -1
  291. package/src/hooks/debounce.test.ts +0 -67
  292. package/src/hooks/debounce.ts +0 -19
  293. package/src/hooks/lockBodyScroll.test.ts +0 -24
  294. package/src/hooks/lockBodyScroll.ts +0 -15
  295. package/src/hooks/onClickOutside.test.ts +0 -113
  296. package/src/hooks/onClickOutside.ts +0 -25
  297. package/src/hooks/onScreenVisible.test.ts +0 -68
  298. package/src/hooks/onScreenVisible.ts +0 -28
  299. package/src/hooks/promise.test.ts +0 -76
  300. package/src/hooks/promise.ts +0 -35
@@ -1,32 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useOnScreenVisible = void 0;
4
- var react_1 = require("react");
5
- /**
6
- * Hook that detects if a reference element within the main document is
7
- * visible.
8
- * Useful for performing some animation or triggering certain actions (e.g.,
9
- * loading data for infinity scrolling) when an element appears or is close
10
- * to appear on screen.
11
- * @param ref The reference element to be visible.
12
- * @param rootMargin The tolerance level to the reference element.
13
- */
14
- function useOnScreenVisible(ref, rootMargin) {
15
- if (rootMargin === void 0) { rootMargin = '0px'; }
16
- var _a = react_1.useState(false), isIntersecting = _a[0], setIntersecting = _a[1];
17
- react_1.useEffect(function () {
18
- var observer = new IntersectionObserver(function (_a) {
19
- var entry = _a[0];
20
- return setIntersecting(entry.isIntersecting);
21
- }, {
22
- rootMargin: rootMargin,
23
- });
24
- if (ref.current) {
25
- observer.observe(ref.current);
26
- }
27
- return function () { return observer.unobserve(ref.current); };
28
- }, []);
29
- return isIntersecting;
30
- }
31
- exports.useOnScreenVisible = useOnScreenVisible;
32
- //# sourceMappingURL=onScreenVisible.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"onScreenVisible.js","sourceRoot":"","sources":["../../src/hooks/onScreenVisible.ts"],"names":[],"mappings":";;;AAAA,+BAAuD;AAEvD;;;;;;;;GAQG;AACH,SAAgB,kBAAkB,CAAwB,GAAiB,EAAE,UAAkB;IAAlB,2BAAA,EAAA,kBAAkB;IACvF,IAAA,KAAoC,gBAAQ,CAAC,KAAK,CAAC,EAAlD,cAAc,QAAA,EAAE,eAAe,QAAmB,CAAC;IAE1D,iBAAS,CAAC;QACR,IAAM,QAAQ,GAAG,IAAI,oBAAoB,CAAC,UAAC,EAAO;gBAAN,KAAK,QAAA;YAAM,OAAA,eAAe,CAAC,KAAK,CAAC,cAAc,CAAC;QAArC,CAAqC,EAAE;YAC5F,UAAU,YAAA;SACX,CAAC,CAAC;QAEH,IAAI,GAAG,CAAC,OAAO,EAAE;YACf,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;SAC/B;QAED,OAAO,cAAM,OAAA,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAA/B,CAA+B,CAAC;IAC/C,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,cAAc,CAAC;AACxB,CAAC;AAhBD,gDAgBC"}
@@ -1,13 +0,0 @@
1
- /**
2
- * The currently captured Promise state.
3
- */
4
- export interface UsePromiseResult<T> {
5
- loading: boolean;
6
- data: T;
7
- error: any;
8
- }
9
- /**
10
- * Hook for introducing a complete local loading state for a promise.
11
- * @param promise The callback for the promise to wait for.
12
- */
13
- export declare function usePromise<T>(promise: () => Promise<T>): UsePromiseResult<T>;
@@ -1,25 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.usePromise = void 0;
4
- var react_1 = require("react");
5
- /**
6
- * Hook for introducing a complete local loading state for a promise.
7
- * @param promise The callback for the promise to wait for.
8
- */
9
- function usePromise(promise) {
10
- var _a = react_1.useState({
11
- loading: true,
12
- data: undefined,
13
- error: undefined,
14
- }), result = _a[0], setResult = _a[1];
15
- react_1.useEffect(function () {
16
- var cancelled = false;
17
- promise().then(function (data) { return !cancelled && setResult({ data: data, error: undefined, loading: false }); }, function (error) { return !cancelled && setResult({ data: undefined, error: error, loading: false }); });
18
- return function () {
19
- cancelled = true;
20
- };
21
- }, []);
22
- return result;
23
- }
24
- exports.usePromise = usePromise;
25
- //# sourceMappingURL=promise.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"promise.js","sourceRoot":"","sources":["../../src/hooks/promise.ts"],"names":[],"mappings":";;;AAAA,+BAA4C;AAW5C;;;GAGG;AACH,SAAgB,UAAU,CAAI,OAAyB;IAC/C,IAAA,KAAsB,gBAAQ,CAAsB;QACxD,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;KACjB,CAAC,EAJK,MAAM,QAAA,EAAE,SAAS,QAItB,CAAC;IACH,iBAAS,CAAC;QACR,IAAI,SAAS,GAAG,KAAK,CAAC;QAEtB,OAAO,EAAE,CAAC,IAAI,CACZ,UAAC,IAAI,IAAK,OAAA,CAAC,SAAS,IAAI,SAAS,CAAC,EAAE,IAAI,MAAA,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAnE,CAAmE,EAC7E,UAAC,KAAK,IAAK,OAAA,CAAC,SAAS,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,OAAA,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAnE,CAAmE,CAC/E,CAAC;QAEF,OAAO;YACL,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,OAAO,MAAM,CAAC;AAChB,CAAC;AAnBD,gCAmBC"}
@@ -1,67 +0,0 @@
1
- import * as React from 'react';
2
- import { useDebounce } from './debounce';
3
-
4
- jest.mock('react');
5
-
6
- describe('Debounce Hook Module', () => {
7
- it('just returns initial value if nothing has been changed', () => {
8
- const usedEffect = jest.fn();
9
- const usedState = jest.fn((value) => [value]);
10
- (React as any).useState = usedState;
11
- (React as any).useEffect = usedEffect;
12
- const result = useDebounce('foo');
13
- expect(usedEffect).toHaveBeenCalled();
14
- expect(usedState).toHaveBeenCalled();
15
- expect(result).toBe('foo');
16
- });
17
-
18
- it('invokes useEffect immediately, but does not set value immediately', () => {
19
- const usedEffect = jest.fn((fn) => fn());
20
- const setValue = jest.fn();
21
- const usedState = jest.fn((value) => [value, setValue]);
22
- (React as any).useState = usedState;
23
- (React as any).useEffect = usedEffect;
24
- useDebounce('foo');
25
- expect(setValue).not.toHaveBeenCalled();
26
- });
27
-
28
- it('invokes useEffect immediately, but sets value immediately if 0', () => {
29
- jest.useFakeTimers();
30
- const usedEffect = jest.fn((fn) => fn());
31
- const setValue = jest.fn();
32
- const usedState = jest.fn((value) => [value, setValue]);
33
- (React as any).useState = usedState;
34
- (React as any).useEffect = usedEffect;
35
- useDebounce('foo', 0);
36
- jest.advanceTimersByTime(0);
37
- expect(setValue).toHaveBeenCalled();
38
- });
39
-
40
- it('invokes useEffect immediately, but sets value after wait time', () => {
41
- jest.useFakeTimers();
42
- const usedEffect = jest.fn((fn) => fn());
43
- const setValue = jest.fn();
44
- const usedState = jest.fn((value) => [value, setValue]);
45
- (React as any).useState = usedState;
46
- (React as any).useEffect = usedEffect;
47
- expect(setValue).not.toHaveBeenCalled();
48
- useDebounce('foo', 300);
49
- jest.advanceTimersByTime(300);
50
- expect(setValue).toHaveBeenCalled();
51
- });
52
-
53
- it('invokes useEffect immediately and resets timer if needed', () => {
54
- jest.useFakeTimers();
55
- const usedEffect = jest.fn((fn) => fn());
56
- const setValue = jest.fn();
57
- const usedState = jest.fn((value) => [value, setValue]);
58
- (React as any).useState = usedState;
59
- (React as any).useEffect = usedEffect;
60
- expect(setValue).not.toHaveBeenCalled();
61
- useDebounce('foo', 300);
62
- jest.advanceTimersByTime(250);
63
- usedEffect.mock.results[0].value();
64
- jest.advanceTimersByTime(50);
65
- expect(setValue).not.toHaveBeenCalled();
66
- });
67
- });
@@ -1,19 +0,0 @@
1
- import { useState, useEffect } from 'react';
2
-
3
- /**
4
- * Hook that returns the debounced (i.e., delayed) value.
5
- * Useful when user input should not fire immediately, but rather
6
- * only after a certain timespan without any changes passed.
7
- * @param value The value to consider.
8
- * @param delay The timespan to pass before applying the value.
9
- */
10
- export function useDebounce<T>(value: T, delay = 300) {
11
- const [debouncedValue, setDebouncedValue] = useState(value);
12
-
13
- useEffect(() => {
14
- const handler = setTimeout(() => setDebouncedValue(value), delay);
15
- return () => clearTimeout(handler);
16
- }, [value, delay]);
17
-
18
- return debouncedValue;
19
- }
@@ -1,24 +0,0 @@
1
- import * as React from 'react';
2
- import { useLockBodyScroll } from './lockBodyScroll';
3
-
4
- jest.mock('react');
5
-
6
- describe('LockBodyScroll Hook Module', () => {
7
- it('sets the body overflow to hidden on being initiated', () => {
8
- const usedEffect = jest.fn();
9
- (React as any).useLayoutEffect = usedEffect;
10
- useLockBodyScroll();
11
- expect(usedEffect).toHaveBeenCalled();
12
- usedEffect.mock.calls[0][0]();
13
- expect(document.body.style.overflow).toBe('hidden');
14
- });
15
-
16
- it('sets the body overflow to visible on cleanup', () => {
17
- const usedEffect = jest.fn();
18
- (React as any).useLayoutEffect = usedEffect;
19
- useLockBodyScroll();
20
- const cleanup = usedEffect.mock.calls[0][0]();
21
- cleanup();
22
- expect(document.body.style.overflow).toBe('visible');
23
- });
24
- });
@@ -1,15 +0,0 @@
1
- import { useLayoutEffect } from 'react';
2
-
3
- /**
4
- * Hook that locks scrolling on the main document.
5
- * Useful for preventing the standard scrolling in context of
6
- * a modal dialog.
7
- */
8
- export function useLockBodyScroll() {
9
- useLayoutEffect(() => {
10
- document.body.style.overflow = 'hidden';
11
- return () => {
12
- document.body.style.overflow = 'visible';
13
- };
14
- }, []);
15
- }
@@ -1,113 +0,0 @@
1
- import * as React from 'react';
2
- import { useOnClickOutside } from './onClickOutside';
3
-
4
- jest.mock('react');
5
-
6
- describe('OnClickOutside Module', () => {
7
- it('is properly hooked on when initiating the effect', () => {
8
- const usedEffect = jest.fn();
9
- const originalAdd = document.addEventListener;
10
- const originalRemove = document.addEventListener;
11
- document.addEventListener = jest.fn();
12
- document.removeEventListener = jest.fn();
13
- (React as any).useEffect = usedEffect;
14
- useOnClickOutside({ current: {} as any }, jest.fn());
15
- expect(usedEffect).toHaveBeenCalled();
16
- const cleanup = usedEffect.mock.calls[0][0]();
17
- cleanup();
18
- expect(document.addEventListener).toHaveBeenCalledTimes(2);
19
- document.addEventListener = originalAdd;
20
- document.removeEventListener = originalRemove;
21
- });
22
-
23
- it('is properly cleaned up when leaving the effect', () => {
24
- const usedEffect = jest.fn();
25
- const originalAdd = document.addEventListener;
26
- const originalRemove = document.addEventListener;
27
- document.addEventListener = jest.fn();
28
- document.removeEventListener = jest.fn();
29
- (React as any).useEffect = usedEffect;
30
- useOnClickOutside({ current: {} as any }, jest.fn());
31
- expect(usedEffect).toHaveBeenCalled();
32
- const cleanup = usedEffect.mock.calls[0][0]();
33
- cleanup();
34
- expect(document.removeEventListener).toHaveBeenCalledTimes(2);
35
- document.addEventListener = originalAdd;
36
- document.removeEventListener = originalRemove;
37
- });
38
-
39
- it('not calling the handler on mousedown if no ref is available', () => {
40
- const usedEffect = jest.fn();
41
- const handler = jest.fn();
42
- (React as any).useEffect = usedEffect;
43
- useOnClickOutside({ current: undefined }, handler);
44
- const cleanup = usedEffect.mock.calls[0][0]();
45
- const event = new Event('mousedown', { bubbles: true });
46
- document.body.dispatchEvent(event);
47
- cleanup();
48
- expect(handler).not.toHaveBeenCalled();
49
- });
50
-
51
- it('not calling the handler on mousedown if ref is available, but contains the node', () => {
52
- const usedEffect = jest.fn();
53
- const handler = jest.fn();
54
- (React as any).useEffect = usedEffect;
55
- useOnClickOutside(
56
- {
57
- current: {
58
- contains() {
59
- return true;
60
- },
61
- } as any,
62
- },
63
- handler,
64
- );
65
- const cleanup = usedEffect.mock.calls[0][0]();
66
- const event = new Event('mousedown', { bubbles: true });
67
- document.body.dispatchEvent(event);
68
- cleanup();
69
- expect(handler).not.toHaveBeenCalled();
70
- });
71
-
72
- it('called the handler on mousedown if ref is available and does not contain node', () => {
73
- const usedEffect = jest.fn();
74
- const handler = jest.fn();
75
- (React as any).useEffect = usedEffect;
76
- useOnClickOutside(
77
- {
78
- current: {
79
- contains() {
80
- return false;
81
- },
82
- } as any,
83
- },
84
- handler,
85
- );
86
- const cleanup = usedEffect.mock.calls[0][0]();
87
- const event = new Event('mousedown', { bubbles: true });
88
- document.body.dispatchEvent(event);
89
- cleanup();
90
- expect(handler).toHaveBeenCalledWith(event);
91
- });
92
-
93
- it('called the handler on touchstart if ref is available and does not contain node', () => {
94
- const usedEffect = jest.fn();
95
- const handler = jest.fn();
96
- (React as any).useEffect = usedEffect;
97
- useOnClickOutside(
98
- {
99
- current: {
100
- contains() {
101
- return false;
102
- },
103
- } as any,
104
- },
105
- handler,
106
- );
107
- const cleanup = usedEffect.mock.calls[0][0]();
108
- const event = new Event('touchstart', { bubbles: true });
109
- document.body.dispatchEvent(event);
110
- cleanup();
111
- expect(handler).toHaveBeenCalledWith(event);
112
- });
113
- });
@@ -1,25 +0,0 @@
1
- import { useEffect, RefObject } from 'react';
2
-
3
- /**
4
- * Hook that detects if a click outside the given reference
5
- * has been performed.
6
- * @param ref The reference to the element.
7
- * @param handler The callback to invoke when an outside click happened.
8
- */
9
- export function useOnClickOutside<T extends HTMLElement>(ref: RefObject<T>, handler: (event: MouseEvent) => void) {
10
- useEffect(() => {
11
- const listener = (event: MouseEvent) => {
12
- if (ref.current && !ref.current.contains(event.target as Node)) {
13
- handler(event);
14
- }
15
- };
16
-
17
- document.addEventListener('mousedown', listener);
18
- document.addEventListener('touchstart', listener);
19
-
20
- return () => {
21
- document.removeEventListener('mousedown', listener);
22
- document.removeEventListener('touchstart', listener);
23
- };
24
- }, [handler]);
25
- }
@@ -1,68 +0,0 @@
1
- import * as React from 'react';
2
- import { useOnScreenVisible } from './onScreenVisible';
3
-
4
- jest.mock('react');
5
-
6
- (React as any).useState = (result) => [result, jest.fn()];
7
-
8
- function mockIntersectionObserver() {
9
- const instances = [];
10
- (window as any).IntersectionObserver = class {
11
- constructor(cb, margin) {
12
- instances.push(this);
13
- this.init(cb, margin);
14
- }
15
- init = jest.fn();
16
- observe = jest.fn();
17
- unobserve = jest.fn();
18
- };
19
- return instances;
20
- }
21
-
22
- describe('OnScreenVisible Module', () => {
23
- it('is not intersecting by default', () => {
24
- const result = useOnScreenVisible({ current: undefined });
25
- expect(result).toBeFalsy();
26
- });
27
-
28
- it('creates one intersection observer with effect', () => {
29
- const usedEffect = jest.fn();
30
- (React as any).useEffect = usedEffect;
31
- const instances = mockIntersectionObserver();
32
- useOnScreenVisible({ current: undefined });
33
- const cleanup = usedEffect.mock.calls[0][0]();
34
- expect(instances.length).toBe(1);
35
- cleanup();
36
- });
37
-
38
- it('does not observe if no ref given', () => {
39
- const usedEffect = jest.fn();
40
- (React as any).useEffect = usedEffect;
41
- const instances = mockIntersectionObserver();
42
- useOnScreenVisible({ current: undefined });
43
- const cleanup = usedEffect.mock.calls[0][0]();
44
- expect(instances[0].observe).toHaveBeenCalledTimes(0);
45
- cleanup();
46
- });
47
-
48
- it('does observe if valid ref given', () => {
49
- const usedEffect = jest.fn();
50
- (React as any).useEffect = usedEffect;
51
- const instances = mockIntersectionObserver();
52
- useOnScreenVisible({ current: {} as any });
53
- const cleanup = usedEffect.mock.calls[0][0]();
54
- expect(instances[0].observe).toHaveBeenCalledTimes(1);
55
- cleanup();
56
- });
57
-
58
- it('calls setIntersecting if something changes', () => {
59
- const usedEffect = jest.fn();
60
- (React as any).useEffect = usedEffect;
61
- const instances = mockIntersectionObserver();
62
- useOnScreenVisible({ current: {} as any });
63
- const cleanup = usedEffect.mock.calls[0][0]();
64
- instances[0].init.mock.calls[0][0]([{ isIntersecting: true }]);
65
- cleanup();
66
- expect(instances[0].unobserve).toHaveBeenCalledTimes(1);
67
- });
68
- });
@@ -1,28 +0,0 @@
1
- import { useState, useEffect, RefObject } from 'react';
2
-
3
- /**
4
- * Hook that detects if a reference element within the main document is
5
- * visible.
6
- * Useful for performing some animation or triggering certain actions (e.g.,
7
- * loading data for infinity scrolling) when an element appears or is close
8
- * to appear on screen.
9
- * @param ref The reference element to be visible.
10
- * @param rootMargin The tolerance level to the reference element.
11
- */
12
- export function useOnScreenVisible<T extends HTMLElement>(ref: RefObject<T>, rootMargin = '0px') {
13
- const [isIntersecting, setIntersecting] = useState(false);
14
-
15
- useEffect(() => {
16
- const observer = new IntersectionObserver(([entry]) => setIntersecting(entry.isIntersecting), {
17
- rootMargin,
18
- });
19
-
20
- if (ref.current) {
21
- observer.observe(ref.current);
22
- }
23
-
24
- return () => observer.unobserve(ref.current);
25
- }, []);
26
-
27
- return isIntersecting;
28
- }
@@ -1,76 +0,0 @@
1
- import * as React from 'react';
2
- import { usePromise } from './promise';
3
-
4
- jest.mock('react');
5
-
6
- describe('Promise Module', () => {
7
- it('directly reports loading', () => {
8
- const usedEffect = jest.fn();
9
- const setState = jest.fn();
10
- (React as any).useEffect = usedEffect;
11
- (React as any).useState = (current) => [current, setState];
12
- const result = usePromise(() => Promise.resolve());
13
- expect(result).toEqual({
14
- loading: true,
15
- data: undefined,
16
- error: undefined,
17
- });
18
- });
19
-
20
- it('reports loading after the effect is done', () => {
21
- const usedEffect = jest.fn((fn) => fn());
22
- const setState = jest.fn();
23
- (React as any).useEffect = usedEffect;
24
- (React as any).useState = (current) => [current, setState];
25
- const result = usePromise(() => Promise.resolve());
26
- expect(result).toEqual({
27
- loading: true,
28
- data: undefined,
29
- error: undefined,
30
- });
31
- });
32
-
33
- it('reports done when the loading finished', async () => {
34
- const usedEffect = jest.fn((fn) => fn());
35
- const setState = jest.fn();
36
- (React as any).useEffect = usedEffect;
37
- (React as any).useState = (current) => [current, setState];
38
- usePromise(() => Promise.resolve('123'));
39
- await Promise.resolve();
40
- expect(setState.mock.calls.length).toBe(1);
41
- expect(setState.mock.calls[0]).toEqual([
42
- {
43
- loading: false,
44
- data: '123',
45
- error: undefined,
46
- },
47
- ]);
48
- });
49
-
50
- it('reports error when the loading finished', async () => {
51
- const usedEffect = jest.fn((fn) => fn());
52
- const setState = jest.fn();
53
- (React as any).useEffect = usedEffect;
54
- (React as any).useState = (current) => [current, setState];
55
- usePromise(() => Promise.reject('123'));
56
- await Promise.resolve();
57
- expect(setState.mock.calls.length).toBe(1);
58
- expect(setState.mock.calls[0]).toEqual([
59
- {
60
- loading: false,
61
- data: undefined,
62
- error: '123',
63
- },
64
- ]);
65
- });
66
-
67
- it('does not set the state on cancel', async () => {
68
- const usedEffect = jest.fn((fn) => fn()());
69
- const setState = jest.fn();
70
- (React as any).useEffect = usedEffect;
71
- (React as any).useState = (current) => [current, setState];
72
- usePromise(() => Promise.reject('123'));
73
- await Promise.resolve();
74
- expect(setState.mock.calls.length).toBe(0);
75
- });
76
- });
@@ -1,35 +0,0 @@
1
- import { useState, useEffect } from 'react';
2
-
3
- /**
4
- * The currently captured Promise state.
5
- */
6
- export interface UsePromiseResult<T> {
7
- loading: boolean;
8
- data: T;
9
- error: any;
10
- }
11
-
12
- /**
13
- * Hook for introducing a complete local loading state for a promise.
14
- * @param promise The callback for the promise to wait for.
15
- */
16
- export function usePromise<T>(promise: () => Promise<T>) {
17
- const [result, setResult] = useState<UsePromiseResult<T>>({
18
- loading: true,
19
- data: undefined,
20
- error: undefined,
21
- });
22
- useEffect(() => {
23
- let cancelled = false;
24
-
25
- promise().then(
26
- (data) => !cancelled && setResult({ data, error: undefined, loading: false }),
27
- (error) => !cancelled && setResult({ data: undefined, error, loading: false }),
28
- );
29
-
30
- return () => {
31
- cancelled = true;
32
- };
33
- }, []);
34
- return result;
35
- }