@websolutespa/bom-mixer-hooks 1.2.0 → 1.3.0
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.
- package/CHANGELOG.md +63 -49
- package/dist/index.d.ts +42 -23
- package/dist/index.js +177 -40
- package/dist/index.mjs +157 -26
- package/package.json +2 -2
- package/src/index.ts +1 -0
- package/src/useDateTimeFormat/useDateTimeFormat.test.tsx +2 -2
- package/src/useDateTimeFormat/useDateTimeFormat.ts +1 -1
- package/src/useElementSize/useElementSize.test.ts +5 -5
- package/src/useEventListener/useEventListener.test.ts +10 -10
- package/src/useFilters/useFilters.test.ts +1 -1
- package/src/useGeolocation/useGeolocation.test.ts +2 -2
- package/src/useInfiniteLoader/useInfiniteLoader.ts +1 -1
- package/src/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.ts +2 -1
- package/src/useKeyboard/useKeyboard.test.tsx +11 -11
- package/src/useKeyboard/useKeyboard.ts +2 -2
- package/src/useLabel/useLabel.tsx +30 -20
- package/src/useNumber/useNumber.test.tsx +1 -1
- package/src/useScrollTo/useScrollTo.ts +5 -4
- package/src/useSearchParams/useSearchParams.test.ts +1 -1
- package/src/useSearchParams/useSearchParams.ts +17 -15
- package/src/useSearchParamsEncoded/useSearchParamsEncoded.test.ts +1 -1
- package/src/useSearchParamsEncoded/useSearchParamsEncoded.ts +13 -13
- package/src/useSearchParamsQs/useSearchParamsQs.test.ts +80 -0
- package/src/useSearchParamsQs/useSearchParamsQs.ts +136 -0
package/dist/index.mjs
CHANGED
|
@@ -214,8 +214,9 @@ import { useState as useState3 } from "react";
|
|
|
214
214
|
import { useEffect as useEffect4, useRef as useRef2 } from "react";
|
|
215
215
|
|
|
216
216
|
// src/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.ts
|
|
217
|
+
import { isBrowser } from "@websolutespa/bom-core";
|
|
217
218
|
import { useEffect as useEffect3, useLayoutEffect } from "react";
|
|
218
|
-
var useIsomorphicLayoutEffect =
|
|
219
|
+
var useIsomorphicLayoutEffect = isBrowser ? useLayoutEffect : useEffect3;
|
|
219
220
|
|
|
220
221
|
// src/useEventListener/useEventListener.ts
|
|
221
222
|
function useEventListener_(eventName, handler, element, options) {
|
|
@@ -1228,16 +1229,28 @@ var useKeyboard = (handler, keyBindings, options = {}) => {
|
|
|
1228
1229
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1229
1230
|
var [useLabel, LabelContextProvider] = createGenericContext();
|
|
1230
1231
|
function LabelProvider({ children }) {
|
|
1231
|
-
const {
|
|
1232
|
-
const
|
|
1233
|
-
const
|
|
1234
|
-
|
|
1235
|
-
if (params) {
|
|
1236
|
-
return parseParams(label, params);
|
|
1237
|
-
}
|
|
1238
|
-
return label;
|
|
1232
|
+
const { labels } = useLayout();
|
|
1233
|
+
const labelService = new LabelService(labels);
|
|
1234
|
+
const getLabel = (key, params) => {
|
|
1235
|
+
return labelService.getLabel(key, params);
|
|
1239
1236
|
};
|
|
1240
|
-
return /* @__PURE__ */ jsx4(LabelContextProvider, { value:
|
|
1237
|
+
return /* @__PURE__ */ jsx4(LabelContextProvider, { value: getLabel, children });
|
|
1238
|
+
}
|
|
1239
|
+
var LabelService = class {
|
|
1240
|
+
constructor(labels) {
|
|
1241
|
+
this.labels = labels;
|
|
1242
|
+
this.dictionary = Object.fromEntries(labels.map((l) => [l.id, l.text]));
|
|
1243
|
+
}
|
|
1244
|
+
getLabel(key, params) {
|
|
1245
|
+
return parseLabel(this.dictionary, key, params);
|
|
1246
|
+
}
|
|
1247
|
+
};
|
|
1248
|
+
function parseLabel(dictionary, key, params) {
|
|
1249
|
+
const label = dictionary[key] != null ? dictionary[key] : key;
|
|
1250
|
+
if (params) {
|
|
1251
|
+
return parseParams(label, params);
|
|
1252
|
+
}
|
|
1253
|
+
return label;
|
|
1241
1254
|
}
|
|
1242
1255
|
function parseParams(label, params) {
|
|
1243
1256
|
const TEMPLATE_REGEXP = /@(\w+)/g;
|
|
@@ -1326,9 +1339,9 @@ function usePagination($items, $page = 1, $perPage = 15) {
|
|
|
1326
1339
|
import { useEffect as useEffect19, useState as useState14 } from "react";
|
|
1327
1340
|
var namespace = "theme";
|
|
1328
1341
|
function usePortal(name = getUID(), getContainer) {
|
|
1329
|
-
const { isBrowser:
|
|
1342
|
+
const { isBrowser: isBrowser6 } = useSSR();
|
|
1330
1343
|
const id = `${namespace}-${name}`;
|
|
1331
|
-
const [portal, setPortal] = useState14(
|
|
1344
|
+
const [portal, setPortal] = useState14(isBrowser6 ? createElementWithId(id) : null);
|
|
1332
1345
|
useEffect19(() => {
|
|
1333
1346
|
const container = typeof getContainer === "function" ? getContainer() : null;
|
|
1334
1347
|
const parentElement = container || document.body;
|
|
@@ -1420,19 +1433,20 @@ function useScroll() {
|
|
|
1420
1433
|
}
|
|
1421
1434
|
|
|
1422
1435
|
// src/useScrollTo/useScrollTo.ts
|
|
1436
|
+
import { isBrowser as isBrowser2 } from "@websolutespa/bom-core";
|
|
1423
1437
|
import { animate } from "framer-motion";
|
|
1424
|
-
function useScrollTo() {
|
|
1438
|
+
function useScrollTo(offset = 0) {
|
|
1425
1439
|
const scrollToHash = (event) => {
|
|
1426
1440
|
const href = event.currentTarget.getAttribute("href");
|
|
1427
1441
|
if (href && href.indexOf("#") !== -1) {
|
|
1428
1442
|
const hashId = `#${href.split("#")[1]}`;
|
|
1429
|
-
scrollToSelector(hashId);
|
|
1443
|
+
scrollToSelector(hashId, offset);
|
|
1430
1444
|
}
|
|
1431
1445
|
};
|
|
1432
1446
|
return scrollToHash;
|
|
1433
1447
|
}
|
|
1434
1448
|
function scrollToSelector(selector, offset = 0) {
|
|
1435
|
-
if (selector &&
|
|
1449
|
+
if (selector && isBrowser2) {
|
|
1436
1450
|
const element = document.querySelector(selector);
|
|
1437
1451
|
if (element) {
|
|
1438
1452
|
const rect = element.getBoundingClientRect();
|
|
@@ -1475,9 +1489,9 @@ function useScrolled(callback = DEFAULT_CALLBACK) {
|
|
|
1475
1489
|
}
|
|
1476
1490
|
|
|
1477
1491
|
// src/useSearchParams/useSearchParams.ts
|
|
1492
|
+
import { isBrowser as isBrowser3 } from "@websolutespa/bom-core";
|
|
1478
1493
|
import { useRouter } from "next/router";
|
|
1479
1494
|
import { useCallback as useCallback4, useMemo as useMemo5 } from "react";
|
|
1480
|
-
var isBrowser = typeof window !== "undefined";
|
|
1481
1495
|
function replace_(params) {
|
|
1482
1496
|
if (window.history) {
|
|
1483
1497
|
const title = document.title;
|
|
@@ -1528,7 +1542,7 @@ function pushSearchParams(router, params) {
|
|
|
1528
1542
|
router.push({ pathname, query });
|
|
1529
1543
|
}
|
|
1530
1544
|
function replaceSearchParamsSilently(params) {
|
|
1531
|
-
if (
|
|
1545
|
+
if (isBrowser3) {
|
|
1532
1546
|
const searchParams = serialize_(window.location.search, params);
|
|
1533
1547
|
replace_(searchParams);
|
|
1534
1548
|
}
|
|
@@ -1564,18 +1578,19 @@ function useSearchParamsValue(key) {
|
|
|
1564
1578
|
}
|
|
1565
1579
|
|
|
1566
1580
|
// src/useSearchParamsEncoded/useSearchParamsEncoded.ts
|
|
1581
|
+
import { isBrowser as isBrowser4 } from "@websolutespa/bom-core";
|
|
1567
1582
|
import { useRouter as useRouter2 } from "next/router";
|
|
1568
1583
|
import { useCallback as useCallback5, useMemo as useMemo6 } from "react";
|
|
1569
1584
|
var USE_ENCRYPTION = true;
|
|
1570
1585
|
function base64ToString(base64) {
|
|
1571
1586
|
if (!USE_ENCRYPTION)
|
|
1572
1587
|
return base64;
|
|
1573
|
-
return
|
|
1588
|
+
return isBrowser4 ? window.atob(base64) : Buffer.from(base64, "base64").toString();
|
|
1574
1589
|
}
|
|
1575
1590
|
function stringToBase64(text) {
|
|
1576
1591
|
if (!USE_ENCRYPTION)
|
|
1577
1592
|
return text;
|
|
1578
|
-
return
|
|
1593
|
+
return isBrowser4 ? window.btoa(text) : Buffer.from(text).toString("base64");
|
|
1579
1594
|
}
|
|
1580
1595
|
function stringToURLSearchParams(url) {
|
|
1581
1596
|
return new URLSearchParams(url);
|
|
@@ -1664,7 +1679,7 @@ function pushSearchParamsEncoded(router, value, key) {
|
|
|
1664
1679
|
router.push({ pathname, query });
|
|
1665
1680
|
}
|
|
1666
1681
|
function replaceSearchParamsEncodedSilently(value, key) {
|
|
1667
|
-
if (
|
|
1682
|
+
if (isBrowser4) {
|
|
1668
1683
|
const searchParams = serialize_2(window.location.search, value, key);
|
|
1669
1684
|
replace_2(searchParams);
|
|
1670
1685
|
}
|
|
@@ -1685,6 +1700,116 @@ function useSearchParamsEncoded(key) {
|
|
|
1685
1700
|
return { params, replaceParamsSilently, replaceParams };
|
|
1686
1701
|
}
|
|
1687
1702
|
|
|
1703
|
+
// src/useSearchParamsQs/useSearchParamsQs.ts
|
|
1704
|
+
import { isBrowser as isBrowser5, qsDeserializeRaw, qsSerializeRaw } from "@websolutespa/bom-core";
|
|
1705
|
+
import { useRouter as useRouter3 } from "next/router";
|
|
1706
|
+
import { useCallback as useCallback6, useMemo as useMemo7 } from "react";
|
|
1707
|
+
function decode2(encoded, key) {
|
|
1708
|
+
let decoded = null;
|
|
1709
|
+
if (encoded) {
|
|
1710
|
+
decoded = qsDeserializeRaw(encoded);
|
|
1711
|
+
}
|
|
1712
|
+
if (key && decoded) {
|
|
1713
|
+
decoded = decoded[key];
|
|
1714
|
+
}
|
|
1715
|
+
return decoded || null;
|
|
1716
|
+
}
|
|
1717
|
+
function encode2(params, value, key) {
|
|
1718
|
+
if (key) {
|
|
1719
|
+
params = __spreadProps(__spreadValues({}, params), { [key]: value });
|
|
1720
|
+
} else if (typeof value === "object") {
|
|
1721
|
+
params = __spreadValues(__spreadValues({}, params), value);
|
|
1722
|
+
} else {
|
|
1723
|
+
params = __spreadValues({}, params);
|
|
1724
|
+
}
|
|
1725
|
+
const encoded = qsSerializeRaw(params);
|
|
1726
|
+
return encoded;
|
|
1727
|
+
}
|
|
1728
|
+
function stringToURLSearchParams2(url) {
|
|
1729
|
+
return new URLSearchParams(url);
|
|
1730
|
+
}
|
|
1731
|
+
function getURLSearchParams2(url, key) {
|
|
1732
|
+
const params = stringToURLSearchParams2(url);
|
|
1733
|
+
return params.get(key);
|
|
1734
|
+
}
|
|
1735
|
+
function setURLSearchParams2(url, keyOrValue, value) {
|
|
1736
|
+
const params = stringToURLSearchParams2(url);
|
|
1737
|
+
if (value != null) {
|
|
1738
|
+
params.set(keyOrValue, value);
|
|
1739
|
+
} else {
|
|
1740
|
+
params.set(keyOrValue, "");
|
|
1741
|
+
}
|
|
1742
|
+
return params;
|
|
1743
|
+
}
|
|
1744
|
+
function replace_3(params) {
|
|
1745
|
+
if (window.history) {
|
|
1746
|
+
const title = document.title;
|
|
1747
|
+
const url = `${window.location.href.split("?")[0]}?${params.toString()}`;
|
|
1748
|
+
window.history.replaceState(params.toString(), title, url);
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
function deserialize_3(url, key) {
|
|
1752
|
+
const encoded = getURLSearchParams2(url, "params");
|
|
1753
|
+
return decode2(encoded, key);
|
|
1754
|
+
}
|
|
1755
|
+
function serialize_3(url, value, key) {
|
|
1756
|
+
const params = deserialize_3(url);
|
|
1757
|
+
const encoded = encode2(params, value, key);
|
|
1758
|
+
return setURLSearchParams2(url, "params", encoded);
|
|
1759
|
+
}
|
|
1760
|
+
function searchParamsToObject_3(params) {
|
|
1761
|
+
const entries = params.entries();
|
|
1762
|
+
const result = {};
|
|
1763
|
+
for (const [key, value] of entries) {
|
|
1764
|
+
result[key] = value;
|
|
1765
|
+
}
|
|
1766
|
+
return result;
|
|
1767
|
+
}
|
|
1768
|
+
function getSearchParamsQs(url, key) {
|
|
1769
|
+
const components = url.split("?");
|
|
1770
|
+
const search = components[1] || "";
|
|
1771
|
+
const searchParams = new URLSearchParams(search);
|
|
1772
|
+
const params = searchParams.get("params");
|
|
1773
|
+
const value = params ? decode2(params, key) : null;
|
|
1774
|
+
return value;
|
|
1775
|
+
}
|
|
1776
|
+
function updateSearchParamsQs(currentPath, value, key) {
|
|
1777
|
+
const components = currentPath.split("?");
|
|
1778
|
+
const searchParams = serialize_3(components[1] || "", value, key);
|
|
1779
|
+
const query = searchParamsToObject_3(searchParams);
|
|
1780
|
+
const pathname = components[0] || "";
|
|
1781
|
+
return { pathname, query };
|
|
1782
|
+
}
|
|
1783
|
+
function replaceSearchParamsQs(router, value, key) {
|
|
1784
|
+
const { pathname, query } = updateSearchParamsQs(router.asPath, value, key);
|
|
1785
|
+
router.replace({ pathname, query });
|
|
1786
|
+
}
|
|
1787
|
+
function pushSearchParamsQs(router, value, key) {
|
|
1788
|
+
const { pathname, query } = updateSearchParamsQs(router.asPath, value, key);
|
|
1789
|
+
router.push({ pathname, query });
|
|
1790
|
+
}
|
|
1791
|
+
function replaceSearchParamsQsSilently(value, key) {
|
|
1792
|
+
if (isBrowser5) {
|
|
1793
|
+
const searchParams = serialize_3(window.location.search, value, key);
|
|
1794
|
+
replace_3(searchParams);
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
function useSearchParamsQs(key) {
|
|
1798
|
+
const router = useRouter3();
|
|
1799
|
+
const initialValue = useMemo7(() => {
|
|
1800
|
+
const value = getSearchParamsQs(router.asPath, key);
|
|
1801
|
+
return value;
|
|
1802
|
+
}, [key, router.asPath]);
|
|
1803
|
+
const params = initialValue;
|
|
1804
|
+
const replaceParamsSilently = useCallback6((params2) => {
|
|
1805
|
+
replaceSearchParamsQsSilently(params2, key);
|
|
1806
|
+
}, [key]);
|
|
1807
|
+
const replaceParams = useCallback6((params2) => {
|
|
1808
|
+
replaceSearchParamsQs(router, params2, key);
|
|
1809
|
+
}, [key, router]);
|
|
1810
|
+
return { params, replaceParamsSilently, replaceParams };
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1688
1813
|
// src/useSorting/useSorting.ts
|
|
1689
1814
|
import { useEffect as useEffect22, useRef as useRef11, useState as useState18 } from "react";
|
|
1690
1815
|
function useSorting(items_, callback_, sort_) {
|
|
@@ -1707,12 +1832,12 @@ function useSorting(items_, callback_, sort_) {
|
|
|
1707
1832
|
}
|
|
1708
1833
|
|
|
1709
1834
|
// src/useSwiperIndex/useSwiperIndex.ts
|
|
1710
|
-
import { useCallback as
|
|
1835
|
+
import { useCallback as useCallback7, useEffect as useEffect23, useState as useState19 } from "react";
|
|
1711
1836
|
import { useSwiper } from "swiper/react";
|
|
1712
1837
|
function useSwiperIndex() {
|
|
1713
1838
|
const swiper = useSwiper();
|
|
1714
1839
|
const [index, setIndex] = useState19(swiper.realIndex);
|
|
1715
|
-
const slideTo =
|
|
1840
|
+
const slideTo = useCallback7((index2) => {
|
|
1716
1841
|
swiper.slideTo(index2);
|
|
1717
1842
|
}, [swiper]);
|
|
1718
1843
|
const onSlideChange = (swiper2) => {
|
|
@@ -1732,11 +1857,11 @@ function useSwiperIndex() {
|
|
|
1732
1857
|
}
|
|
1733
1858
|
|
|
1734
1859
|
// src/useSyncedRef/useSyncedRef.ts
|
|
1735
|
-
import { useMemo as
|
|
1860
|
+
import { useMemo as useMemo8, useRef as useRef12 } from "react";
|
|
1736
1861
|
function useSyncedRef(value) {
|
|
1737
1862
|
const ref = useRef12(value);
|
|
1738
1863
|
ref.current = value;
|
|
1739
|
-
return
|
|
1864
|
+
return useMemo8(() => Object.freeze({
|
|
1740
1865
|
get current() {
|
|
1741
1866
|
return ref.current;
|
|
1742
1867
|
}
|
|
@@ -1774,11 +1899,11 @@ export {
|
|
|
1774
1899
|
KeyCode,
|
|
1775
1900
|
KeyMod,
|
|
1776
1901
|
LabelProvider,
|
|
1902
|
+
LabelService,
|
|
1777
1903
|
LayoutProvider,
|
|
1778
1904
|
PageProvider,
|
|
1779
1905
|
createElementWithId,
|
|
1780
1906
|
createGenericContext,
|
|
1781
|
-
decode,
|
|
1782
1907
|
detectIsBrowser,
|
|
1783
1908
|
filtersToParams,
|
|
1784
1909
|
getCurrentPosition,
|
|
@@ -1790,15 +1915,19 @@ export {
|
|
|
1790
1915
|
getRealSize,
|
|
1791
1916
|
getSearchParams,
|
|
1792
1917
|
getSearchParamsEncoded,
|
|
1918
|
+
getSearchParamsQs,
|
|
1793
1919
|
getUID,
|
|
1794
1920
|
hasGeolocation,
|
|
1795
|
-
|
|
1921
|
+
parseLabel,
|
|
1796
1922
|
parseParams,
|
|
1797
1923
|
pushSearchParams,
|
|
1798
1924
|
pushSearchParamsEncoded,
|
|
1925
|
+
pushSearchParamsQs,
|
|
1799
1926
|
replaceSearchParams,
|
|
1800
1927
|
replaceSearchParamsEncoded,
|
|
1801
1928
|
replaceSearchParamsEncodedSilently,
|
|
1929
|
+
replaceSearchParamsQs,
|
|
1930
|
+
replaceSearchParamsQsSilently,
|
|
1802
1931
|
replaceSearchParamsSilently,
|
|
1803
1932
|
scrollToRelativeY,
|
|
1804
1933
|
scrollToSelector,
|
|
@@ -1806,6 +1935,7 @@ export {
|
|
|
1806
1935
|
setFilters,
|
|
1807
1936
|
updateSearchParams,
|
|
1808
1937
|
updateSearchParamsEncoded,
|
|
1938
|
+
updateSearchParamsQs,
|
|
1809
1939
|
useApi,
|
|
1810
1940
|
useApiDelete,
|
|
1811
1941
|
useApiFetch,
|
|
@@ -1852,6 +1982,7 @@ export {
|
|
|
1852
1982
|
useScrolled,
|
|
1853
1983
|
useSearchParams,
|
|
1854
1984
|
useSearchParamsEncoded,
|
|
1985
|
+
useSearchParamsQs,
|
|
1855
1986
|
useSearchParamsValue,
|
|
1856
1987
|
useSorting,
|
|
1857
1988
|
useSwiperIndex,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@websolutespa/bom-mixer-hooks",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Mixer Hooks module of the BOM Repository",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bom",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"next": ">= 13.4.19",
|
|
33
33
|
"react-dom": ">= 18.2.0",
|
|
34
34
|
"react": ">= 18.2.0",
|
|
35
|
-
"styled-components": ">= 5.3.11",
|
|
35
|
+
"styled-components": ">= 5.3.11 <6.x.x",
|
|
36
36
|
"swiper": ">= 8.3.2",
|
|
37
37
|
"zustand": ">= 4.4.0"
|
|
38
38
|
},
|
package/src/index.ts
CHANGED
|
@@ -43,6 +43,7 @@ export * from './useScrollTo/useScrollTo';
|
|
|
43
43
|
export * from './useScrolled/useScrolled';
|
|
44
44
|
export * from './useSearchParams/useSearchParams';
|
|
45
45
|
export * from './useSearchParamsEncoded/useSearchParamsEncoded';
|
|
46
|
+
export * from './useSearchParamsQs/useSearchParamsQs';
|
|
46
47
|
export * from './useSorting/useSorting';
|
|
47
48
|
export * from './useSwiperIndex/useSwiperIndex';
|
|
48
49
|
export * from './useSyncedRef/useSyncedRef';
|
|
@@ -29,7 +29,7 @@ describe('useDateTimeFormat', () => {
|
|
|
29
29
|
const { result } = renderHook(() => useDateTimeFormat({
|
|
30
30
|
year: 'numeric',
|
|
31
31
|
month: 'short',
|
|
32
|
-
day: 'numeric'
|
|
32
|
+
day: 'numeric',
|
|
33
33
|
}), { wrapper });
|
|
34
34
|
const formatted = result.current(new Date(2023, 0, 19));
|
|
35
35
|
expect(formatted).toEqual('Jan 19, 2023');
|
|
@@ -39,7 +39,7 @@ describe('useDateTimeFormat', () => {
|
|
|
39
39
|
const { result } = renderHook(() => useDateTimeFormat({
|
|
40
40
|
year: 'numeric',
|
|
41
41
|
month: 'short',
|
|
42
|
-
day: 'numeric'
|
|
42
|
+
day: 'numeric',
|
|
43
43
|
}), { wrapper });
|
|
44
44
|
const formatted = result.current('2023/1/19');
|
|
45
45
|
expect(formatted).toEqual('Jan 19, 2023');
|
|
@@ -5,16 +5,16 @@ import { useElementSize } from './useElementSize';
|
|
|
5
5
|
const setupHook = () => renderHook(() => useElementSize());
|
|
6
6
|
const originalOffsetHeight = Object.getOwnPropertyDescriptor(
|
|
7
7
|
HTMLElement.prototype,
|
|
8
|
-
'offsetHeight'
|
|
8
|
+
'offsetHeight'
|
|
9
9
|
) as PropertyDescriptor;
|
|
10
10
|
const originalOffsetWidth = Object.getOwnPropertyDescriptor(
|
|
11
11
|
HTMLElement.prototype,
|
|
12
|
-
'offsetWidth'
|
|
12
|
+
'offsetWidth'
|
|
13
13
|
) as PropertyDescriptor;
|
|
14
14
|
const resizeElement = (
|
|
15
15
|
node: HTMLElement,
|
|
16
16
|
dimension: 'width' | 'height',
|
|
17
|
-
value: number
|
|
17
|
+
value: number
|
|
18
18
|
): void => {
|
|
19
19
|
if (dimension === 'height') {
|
|
20
20
|
return void Object.defineProperty(node, 'offsetHeight', {
|
|
@@ -37,12 +37,12 @@ describe('useElementSize', () => {
|
|
|
37
37
|
Object.defineProperty(
|
|
38
38
|
HTMLElement.prototype,
|
|
39
39
|
'offsetHeight',
|
|
40
|
-
originalOffsetHeight
|
|
40
|
+
originalOffsetHeight
|
|
41
41
|
);
|
|
42
42
|
Object.defineProperty(
|
|
43
43
|
HTMLElement.prototype,
|
|
44
44
|
'offsetWidth',
|
|
45
|
-
originalOffsetWidth
|
|
45
|
+
originalOffsetWidth
|
|
46
46
|
);
|
|
47
47
|
});
|
|
48
48
|
|
|
@@ -26,7 +26,7 @@ const docRef = { current: window.document };
|
|
|
26
26
|
const docAddEventListenerSpy = jest.spyOn(docRef.current, 'addEventListener');
|
|
27
27
|
const docRemoveEventListenerSpy = jest.spyOn(
|
|
28
28
|
docRef.current,
|
|
29
|
-
'removeEventListener'
|
|
29
|
+
'removeEventListener'
|
|
30
30
|
);
|
|
31
31
|
|
|
32
32
|
describe('useEventListener', () => {
|
|
@@ -42,12 +42,12 @@ describe('useEventListener', () => {
|
|
|
42
42
|
expect(windowAddEventListenerSpy).toHaveBeenCalledWith(
|
|
43
43
|
eventName,
|
|
44
44
|
expect.any(Function),
|
|
45
|
-
options
|
|
45
|
+
options
|
|
46
46
|
);
|
|
47
47
|
unmount();
|
|
48
48
|
expect(windowRemoveEventListenerSpy).toHaveBeenCalledWith(
|
|
49
49
|
eventName,
|
|
50
|
-
expect.any(Function)
|
|
50
|
+
expect.any(Function)
|
|
51
51
|
);
|
|
52
52
|
});
|
|
53
53
|
|
|
@@ -56,18 +56,18 @@ describe('useEventListener', () => {
|
|
|
56
56
|
const handler = jest.fn();
|
|
57
57
|
const options = undefined;
|
|
58
58
|
const { unmount } = renderHook(() =>
|
|
59
|
-
useEventListener(eventName, handler, ref, options)
|
|
59
|
+
useEventListener(eventName, handler, ref, options)
|
|
60
60
|
);
|
|
61
61
|
expect(refAddEventListenerSpy).toHaveBeenCalledTimes(1);
|
|
62
62
|
expect(refAddEventListenerSpy).toHaveBeenCalledWith(
|
|
63
63
|
eventName,
|
|
64
64
|
expect.any(Function),
|
|
65
|
-
options
|
|
65
|
+
options
|
|
66
66
|
);
|
|
67
67
|
unmount();
|
|
68
68
|
expect(refRemoveEventListenerSpy).toHaveBeenCalledWith(
|
|
69
69
|
eventName,
|
|
70
|
-
expect.any(Function)
|
|
70
|
+
expect.any(Function)
|
|
71
71
|
);
|
|
72
72
|
});
|
|
73
73
|
|
|
@@ -76,18 +76,18 @@ describe('useEventListener', () => {
|
|
|
76
76
|
const handler = jest.fn();
|
|
77
77
|
const options = undefined;
|
|
78
78
|
const { unmount } = renderHook(() =>
|
|
79
|
-
useEventListener(eventName, handler, docRef, options)
|
|
79
|
+
useEventListener(eventName, handler, docRef, options)
|
|
80
80
|
);
|
|
81
81
|
expect(docAddEventListenerSpy).toHaveBeenCalledTimes(1);
|
|
82
82
|
expect(docAddEventListenerSpy).toHaveBeenCalledWith(
|
|
83
83
|
eventName,
|
|
84
84
|
expect.any(Function),
|
|
85
|
-
options
|
|
85
|
+
options
|
|
86
86
|
);
|
|
87
87
|
unmount();
|
|
88
88
|
expect(docRemoveEventListenerSpy).toHaveBeenCalledWith(
|
|
89
89
|
eventName,
|
|
90
|
-
expect.any(Function)
|
|
90
|
+
expect.any(Function)
|
|
91
91
|
);
|
|
92
92
|
});
|
|
93
93
|
|
|
@@ -103,7 +103,7 @@ describe('useEventListener', () => {
|
|
|
103
103
|
expect(windowAddEventListenerSpy).toHaveBeenCalledWith(
|
|
104
104
|
eventName,
|
|
105
105
|
expect.any(Function),
|
|
106
|
-
options
|
|
106
|
+
options
|
|
107
107
|
);
|
|
108
108
|
});
|
|
109
109
|
|
|
@@ -18,8 +18,8 @@ describe('useGeolocation', () => {
|
|
|
18
18
|
getCurrentPosition.mockImplementationOnce((success: (result: any) => Promise<any>) => Promise.resolve(success({
|
|
19
19
|
coords: {
|
|
20
20
|
latitude: 50.0,
|
|
21
|
-
longitude: 40.0
|
|
22
|
-
}
|
|
21
|
+
longitude: 40.0,
|
|
22
|
+
},
|
|
23
23
|
})));
|
|
24
24
|
const { result } = renderHook(() => useGeolocation());
|
|
25
25
|
expect(result.current.latitude).toBe(50.0);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useEffect, useMemo, useState } from 'react';
|
|
2
2
|
|
|
3
|
-
export function useInfiniteLoader(items:
|
|
3
|
+
export function useInfiniteLoader<T = any>(items: T[], perPage: number = 12, delayInMs = 100): [T[], () => void, boolean] {
|
|
4
4
|
|
|
5
5
|
const total = items.length;
|
|
6
6
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isBrowser } from '@websolutespa/bom-core';
|
|
1
2
|
import { useEffect, useLayoutEffect } from 'react';
|
|
2
3
|
|
|
3
|
-
export const useIsomorphicLayoutEffect =
|
|
4
|
+
export const useIsomorphicLayoutEffect = isBrowser ? useLayoutEffect : useEffect;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { fireEvent, render, renderHook, screen } from '@testing-library/react';
|
|
2
|
-
import {
|
|
2
|
+
import { KeyCode, KeyMod, KeyboardResult, useKeyboard } from './useKeyboard';
|
|
3
3
|
|
|
4
4
|
describe('useKeyboard', () => {
|
|
5
5
|
it('should work correctly', () => {
|
|
@@ -46,19 +46,19 @@ describe('useKeyboard', () => {
|
|
|
46
46
|
it('should work with each command', () => {
|
|
47
47
|
const handler = jest.fn().mockImplementation(() => { });
|
|
48
48
|
renderHook(() =>
|
|
49
|
-
useKeyboard(handler, [KeyCode.KEY_A, KeyMod.Alt, KeyMod.CtrlCmd, KeyMod.WinCtrl])
|
|
49
|
+
useKeyboard(handler, [KeyCode.KEY_A, KeyMod.Alt, KeyMod.CtrlCmd, KeyMod.WinCtrl])
|
|
50
50
|
);
|
|
51
51
|
document.dispatchEvent(
|
|
52
52
|
new KeyboardEvent('keydown', {
|
|
53
53
|
keyCode: KeyCode.KEY_A,
|
|
54
|
-
})
|
|
54
|
+
})
|
|
55
55
|
);
|
|
56
56
|
expect(handler).not.toBeCalled();
|
|
57
57
|
document.dispatchEvent(
|
|
58
58
|
new KeyboardEvent('keydown', {
|
|
59
59
|
keyCode: KeyCode.KEY_A,
|
|
60
60
|
altKey: true,
|
|
61
|
-
})
|
|
61
|
+
})
|
|
62
62
|
);
|
|
63
63
|
expect(handler).not.toBeCalled();
|
|
64
64
|
document.dispatchEvent(
|
|
@@ -66,7 +66,7 @@ describe('useKeyboard', () => {
|
|
|
66
66
|
keyCode: KeyCode.KEY_A,
|
|
67
67
|
altKey: true,
|
|
68
68
|
ctrlKey: true,
|
|
69
|
-
})
|
|
69
|
+
})
|
|
70
70
|
);
|
|
71
71
|
expect(handler).not.toBeCalled();
|
|
72
72
|
document.dispatchEvent(
|
|
@@ -75,7 +75,7 @@ describe('useKeyboard', () => {
|
|
|
75
75
|
altKey: true,
|
|
76
76
|
ctrlKey: true,
|
|
77
77
|
metaKey: true,
|
|
78
|
-
})
|
|
78
|
+
})
|
|
79
79
|
);
|
|
80
80
|
expect(handler).toBeCalledTimes(1);
|
|
81
81
|
});
|
|
@@ -103,12 +103,12 @@ describe('useKeyboard', () => {
|
|
|
103
103
|
const handler = jest.fn().mockImplementation(() => { });
|
|
104
104
|
const nativeHandler = jest.fn().mockImplementation(() => { });
|
|
105
105
|
const { result } = renderHook<KeyboardResult, {}>(() =>
|
|
106
|
-
useKeyboard(handler, KeyCode.Escape)
|
|
106
|
+
useKeyboard(handler, KeyCode.Escape)
|
|
107
107
|
);
|
|
108
108
|
const { container } = render(
|
|
109
109
|
<div onKeyDown={nativeHandler} >
|
|
110
110
|
<span data-testid="inner" {...result.current.bindings} />
|
|
111
|
-
</div
|
|
111
|
+
</div>
|
|
112
112
|
);
|
|
113
113
|
const inner = await screen.findByTestId('inner');
|
|
114
114
|
fireEvent.keyUp(inner, {
|
|
@@ -133,7 +133,7 @@ describe('useKeyboard', () => {
|
|
|
133
133
|
const { container } = render(
|
|
134
134
|
<div onKeyDown={nativeHandler} >
|
|
135
135
|
<span data-testid="inner" {...result.current.bindings} />
|
|
136
|
-
</div
|
|
136
|
+
</div>
|
|
137
137
|
);
|
|
138
138
|
const inner = await screen.findByTestId('inner');
|
|
139
139
|
expect(nativeHandler).not.toBeCalled();
|
|
@@ -147,12 +147,12 @@ describe('useKeyboard', () => {
|
|
|
147
147
|
it('should trigger capture event', async () => {
|
|
148
148
|
const handler = jest.fn().mockImplementation(() => { });
|
|
149
149
|
const { result } = renderHook<KeyboardResult, {}>(() =>
|
|
150
|
-
useKeyboard(handler, KeyCode.Escape, { capture: true, disableGlobalEvent: true })
|
|
150
|
+
useKeyboard(handler, KeyCode.Escape, { capture: true, disableGlobalEvent: true })
|
|
151
151
|
);
|
|
152
152
|
const { container } = render(
|
|
153
153
|
<div onKeyDownCapture={result.current.bindings.onKeyDownCapture} >
|
|
154
154
|
<span data-testid="inner" />
|
|
155
|
-
</div
|
|
155
|
+
</div>
|
|
156
156
|
);
|
|
157
157
|
const inner = await screen.findByTestId('inner');
|
|
158
158
|
fireEvent.keyDown(inner, {
|
|
@@ -43,7 +43,7 @@ export const useKeyboard: UseKeyboard = (handler, keyBindings, options = {}) =>
|
|
|
43
43
|
|
|
44
44
|
const elementBindingHandler = (
|
|
45
45
|
elementEventType: 'keydown' | 'keypress' | 'keyup',
|
|
46
|
-
isCapture: boolean = false
|
|
46
|
+
isCapture: boolean = false
|
|
47
47
|
) => {
|
|
48
48
|
if (elementEventType !== event) return () => { };
|
|
49
49
|
if (isCapture !== capture) return () => { };
|
|
@@ -61,7 +61,7 @@ export const useKeyboard: UseKeyboard = (handler, keyBindings, options = {}) =>
|
|
|
61
61
|
};
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
-
export {
|
|
64
|
+
export { KeyCode, KeyMod };
|
|
65
65
|
|
|
66
66
|
export type KeyboardOptions = {
|
|
67
67
|
disableGlobalEvent?: boolean
|