@websolutespa/bom-mixer-hooks 1.7.0 → 1.7.2

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 CHANGED
@@ -1,99 +1,115 @@
1
- # @websolutespa/bom-mixer-hooks
2
-
3
- ## 1.7.0
4
-
5
- ### Minor Changes
6
-
7
- - 28e86bd: Modified: IPage, Store services & decorators
8
- - Updated dependencies [28e86bd]
9
- - @websolutespa/bom-mixer-models@1.7.0
10
- - @websolutespa/bom-mixer-store@1.7.0
11
- - @websolutespa/bom-core@1.7.0
12
-
13
- ## 1.4.2
14
-
15
- ### Patch Changes
16
-
17
- - Modified: IFeatureType
18
- - Updated dependencies
19
- - @websolutespa/bom-mixer-models@1.5.4
20
- - @websolutespa/bom-mixer-store@1.4.3
21
- - @websolutespa/bom-core@0.6.5
22
-
23
- ## 1.4.1
24
-
25
- ### Patch Changes
26
-
27
- - Added: useCollectionApi, useExtra
28
- - Modified: usePagination, useSearchParamsQs
29
- - Updated dependencies
30
- - @websolutespa/bom-mixer-models@1.5.2
31
- - @websolutespa/bom-core@0.6.2
32
-
33
- ## 1.4.0
34
-
35
- ### Minor Changes
36
-
37
- - Added useLazyModules
38
-
39
- ## 1.3.0
40
-
41
- ### Minor Changes
42
-
43
- - Added: useSearchParamsQs
44
- - Modified: useSearchParamsEncoded, useSearchParams, useScrollTo
45
-
46
- ## 1.2.1
47
-
48
- ### Patch Changes
49
-
50
- - Added: LabelService
51
- - Modified: useLabels, useScrollTo
52
-
53
- ## 1.2.0
54
-
55
- ### Minor Changes
56
-
57
- - Updating: next 13
58
-
59
- ## 1.1.0
60
-
61
- ### Minor Changes
62
-
63
- - Modified: useHttp, useApi
64
-
65
- ## 1.0.0
66
-
67
- ### Minor Changes
68
-
69
- - Added: useScrolled
70
-
71
- ## 0.2.2
72
-
73
- ### Patch Changes
74
-
75
- - Modified: useBreakpoint theme mediaQuery
76
-
77
- ## 0.2.1
78
-
79
- ### Patch Changes
80
-
81
- - Added: source files
82
-
83
- ## 0.2.0
84
-
85
- ### Minor Changes
86
-
87
- - Added: splat routes
88
-
89
- ## 0.1.0
90
-
91
- ### Minor Changes
92
-
93
- - Added: @websolutespa/bom-core
94
-
95
- ## 0.0.2
96
-
97
- ### Patch Changes
98
-
99
- - Added: first release
1
+ # @websolutespa/bom-mixer-hooks
2
+
3
+ ## 1.7.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Updating: dependencies
8
+ - Updated dependencies
9
+ - @websolutespa/bom-mixer-models@1.7.2
10
+ - @websolutespa/bom-mixer-store@1.7.3
11
+ - @websolutespa/bom-core@1.7.3
12
+
13
+ ## 1.7.1
14
+
15
+ ### Patch Changes
16
+
17
+ - aa41666: Added: useIntersectionObserver
18
+
19
+ ## 1.7.0
20
+
21
+ ### Minor Changes
22
+
23
+ - 28e86bd: Modified: IPage, Store services & decorators
24
+ - Updated dependencies [28e86bd]
25
+ - @websolutespa/bom-mixer-models@1.7.0
26
+ - @websolutespa/bom-mixer-store@1.7.0
27
+ - @websolutespa/bom-core@1.7.0
28
+
29
+ ## 1.4.2
30
+
31
+ ### Patch Changes
32
+
33
+ - Modified: IFeatureType
34
+ - Updated dependencies
35
+ - @websolutespa/bom-mixer-models@1.5.4
36
+ - @websolutespa/bom-mixer-store@1.4.3
37
+ - @websolutespa/bom-core@0.6.5
38
+
39
+ ## 1.4.1
40
+
41
+ ### Patch Changes
42
+
43
+ - Added: useCollectionApi, useExtra
44
+ - Modified: usePagination, useSearchParamsQs
45
+ - Updated dependencies
46
+ - @websolutespa/bom-mixer-models@1.5.2
47
+ - @websolutespa/bom-core@0.6.2
48
+
49
+ ## 1.4.0
50
+
51
+ ### Minor Changes
52
+
53
+ - Added useLazyModules
54
+
55
+ ## 1.3.0
56
+
57
+ ### Minor Changes
58
+
59
+ - Added: useSearchParamsQs
60
+ - Modified: useSearchParamsEncoded, useSearchParams, useScrollTo
61
+
62
+ ## 1.2.1
63
+
64
+ ### Patch Changes
65
+
66
+ - Added: LabelService
67
+ - Modified: useLabels, useScrollTo
68
+
69
+ ## 1.2.0
70
+
71
+ ### Minor Changes
72
+
73
+ - Updating: next 13
74
+
75
+ ## 1.1.0
76
+
77
+ ### Minor Changes
78
+
79
+ - Modified: useHttp, useApi
80
+
81
+ ## 1.0.0
82
+
83
+ ### Minor Changes
84
+
85
+ - Added: useScrolled
86
+
87
+ ## 0.2.2
88
+
89
+ ### Patch Changes
90
+
91
+ - Modified: useBreakpoint theme mediaQuery
92
+
93
+ ## 0.2.1
94
+
95
+ ### Patch Changes
96
+
97
+ - Added: source files
98
+
99
+ ## 0.2.0
100
+
101
+ ### Minor Changes
102
+
103
+ - Added: splat routes
104
+
105
+ ## 0.1.0
106
+
107
+ ### Minor Changes
108
+
109
+ - Added: @websolutespa/bom-core
110
+
111
+ ## 0.0.2
112
+
113
+ ### Patch Changes
114
+
115
+ - Added: first release
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import react__default, { RefObject, Dispatch, SetStateAction, MutableRefObject, ComponentProps, useEffect } from 'react';
2
+ import react__default, { RefObject, Dispatch, SetStateAction, CSSProperties, MutableRefObject, ComponentProps, useEffect } from 'react';
3
3
  import { ApiRequestOptions } from '@websolutespa/bom-mixer-store';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  import * as zustand_middleware from 'zustand/middleware';
@@ -42,7 +42,8 @@ type Breakpoint = {
42
42
  min: number;
43
43
  max: number;
44
44
  };
45
- declare function useBreakpoint(): Breakpoint;
45
+ type MediaQuery = Record<BreakpointType, CSSProperties['width']>;
46
+ declare function useBreakpoint(mediaQuery?: MediaQuery): Breakpoint;
46
47
 
47
48
  type CartProps = {
48
49
  hydrated: boolean;
@@ -300,6 +301,9 @@ declare function useIdle(delay?: number, immediate?: boolean): boolean;
300
301
 
301
302
  declare function useInfiniteLoader<T = any>(items: T[], perPage?: number, delayInMs?: number): [T[], () => void, boolean];
302
303
 
304
+ declare function useIntersectionObserver(ref: MutableRefObject<Node | undefined>, options?: IntersectionObserverInit): boolean;
305
+ declare function isElement(node?: Node): node is Element;
306
+
303
307
  declare const useIsomorphicLayoutEffect: typeof useEffect;
304
308
 
305
309
  /**
@@ -624,4 +628,4 @@ type WindowSize = {
624
628
  };
625
629
  declare function useWindowSize(): WindowSize;
626
630
 
627
- export { BodyScrollOptions, CartContext, CartProvider, CheckoutContext, CheckoutProvider, ClickOutGetContainer, CurrentStateType, ElementStackItem, ExtraProvider, Filter, FilterMode, FilterParams, FilterValues, GeoLocationSensorState, IExtra, IFilter, IFilterOption, IGeolocationPositionError, ILabelContext, ILayoutContext, ILazyModulesContext, IPageContext, IPaginationInfo, IParams, IParamsEncoded, IParamsQs, IUseSearchParamsEncodedResult, IUseSearchParamsQsResult, IUseSearchParamsResult, IUseSearchParamsValueResult, KeyCode, KeyMod, KeyboardOptions, KeyboardResult, LabelProvider, LabelService, LayoutProvider, LazyModulesProvider, PageProvider, SSRState, SizeResult, SizeType, Sorting, UIReducer, UIValue, UseFiltersResultType, UseKeyboard, UseKeyboardHandler, createElementWithId, createGenericContext, detectIsBrowser, filtersToParams, getCurrentPosition, getFilteredItems, getFilters, getOwnerPaddingRight, getOwnerScrollbarWidth, getPagedItems, getPaginationInfo, getRealSize, getSearchParams, getSearchParamsEncoded, getSearchParamsQs, getUID, hasGeolocation, isPaginationInfo, localCollectionDelete, localCollectionFetch, localCollectionGet, localCollectionPatch, localCollectionPost, localCollectionPut, parseLabel, parseParams, pushSearchParams, pushSearchParamsEncoded, pushSearchParamsQs, replaceSearchParams, replaceSearchParamsEncoded, replaceSearchParamsEncodedSilently, replaceSearchParamsQs, replaceSearchParamsQsSilently, replaceSearchParamsSilently, scrollToRelativeY, scrollToSelector, scrollToY, setFilters, updateSearchParams, updateSearchParamsEncoded, updateSearchParamsQs, useApi, useApiDelete, useApiFetch, useApiGet, useApiPatch, useApiPost, useApiPut, useBodyScroll, useBreakpoint, useCart, useCheckout, useClickAnyWhere, useClickOut, useCollectionApi, useCollectionApiDelete, useCollectionApiGet, useCollectionApiPatch, useCollectionApiPost, useCollectionApiPut, useCurrency, useCurrentState, useDateTimeFormat, useDebounce, useDebounceCallback, useDebugChangedProps, useDomObserver, useDrawer, useElementSize, useEventListener, useExtra, useFilters, useGeolocation, useIdle, useInfiniteLoader, useIsomorphicLayoutEffect, useKeyboard, useLabel, useLayout, useLazyModules, useModal, useMounted, useNumber, usePage, usePagination, usePortal, usePrevious, useRealSize, useResize, useSSR, useScroll, useScrollTo, useScrolled, useSearchParams, useSearchParamsEncoded, useSearchParamsQs, useSearchParamsValue, useSorting, useSwiperIndex, useSyncedRef, useUI, useUnit, useUnmountEffect, useUser, useWindowSize };
631
+ export { BodyScrollOptions, CartContext, CartProvider, CheckoutContext, CheckoutProvider, ClickOutGetContainer, CurrentStateType, ElementStackItem, ExtraProvider, Filter, FilterMode, FilterParams, FilterValues, GeoLocationSensorState, IExtra, IFilter, IFilterOption, IGeolocationPositionError, ILabelContext, ILayoutContext, ILazyModulesContext, IPageContext, IPaginationInfo, IParams, IParamsEncoded, IParamsQs, IUseSearchParamsEncodedResult, IUseSearchParamsQsResult, IUseSearchParamsResult, IUseSearchParamsValueResult, KeyCode, KeyMod, KeyboardOptions, KeyboardResult, LabelProvider, LabelService, LayoutProvider, LazyModulesProvider, PageProvider, SSRState, SizeResult, SizeType, Sorting, UIReducer, UIValue, UseFiltersResultType, UseKeyboard, UseKeyboardHandler, createElementWithId, createGenericContext, detectIsBrowser, filtersToParams, getCurrentPosition, getFilteredItems, getFilters, getOwnerPaddingRight, getOwnerScrollbarWidth, getPagedItems, getPaginationInfo, getRealSize, getSearchParams, getSearchParamsEncoded, getSearchParamsQs, getUID, hasGeolocation, isElement, isPaginationInfo, localCollectionDelete, localCollectionFetch, localCollectionGet, localCollectionPatch, localCollectionPost, localCollectionPut, parseLabel, parseParams, pushSearchParams, pushSearchParamsEncoded, pushSearchParamsQs, replaceSearchParams, replaceSearchParamsEncoded, replaceSearchParamsEncodedSilently, replaceSearchParamsQs, replaceSearchParamsQsSilently, replaceSearchParamsSilently, scrollToRelativeY, scrollToSelector, scrollToY, setFilters, updateSearchParams, updateSearchParamsEncoded, updateSearchParamsQs, useApi, useApiDelete, useApiFetch, useApiGet, useApiPatch, useApiPost, useApiPut, useBodyScroll, useBreakpoint, useCart, useCheckout, useClickAnyWhere, useClickOut, useCollectionApi, useCollectionApiDelete, useCollectionApiGet, useCollectionApiPatch, useCollectionApiPost, useCollectionApiPut, useCurrency, useCurrentState, useDateTimeFormat, useDebounce, useDebounceCallback, useDebugChangedProps, useDomObserver, useDrawer, useElementSize, useEventListener, useExtra, useFilters, useGeolocation, useIdle, useInfiniteLoader, useIntersectionObserver, useIsomorphicLayoutEffect, useKeyboard, useLabel, useLayout, useLazyModules, useModal, useMounted, useNumber, usePage, usePagination, usePortal, usePrevious, useRealSize, useResize, useSSR, useScroll, useScrollTo, useScrolled, useSearchParams, useSearchParamsEncoded, useSearchParamsQs, useSearchParamsValue, useSorting, useSwiperIndex, useSyncedRef, useUI, useUnit, useUnmountEffect, useUser, useWindowSize };
package/dist/index.js CHANGED
@@ -100,6 +100,7 @@ __export(src_exports, {
100
100
  getSearchParamsQs: () => getSearchParamsQs,
101
101
  getUID: () => getUID,
102
102
  hasGeolocation: () => hasGeolocation,
103
+ isElement: () => isElement,
103
104
  isPaginationInfo: () => isPaginationInfo,
104
105
  localCollectionDelete: () => localCollectionDelete,
105
106
  localCollectionFetch: () => localCollectionFetch,
@@ -159,6 +160,7 @@ __export(src_exports, {
159
160
  useGeolocation: () => useGeolocation,
160
161
  useIdle: () => useIdle,
161
162
  useInfiniteLoader: () => useInfiniteLoader,
163
+ useIntersectionObserver: () => useIntersectionObserver,
162
164
  useIsomorphicLayoutEffect: () => useIsomorphicLayoutEffect,
163
165
  useKeyboard: () => useKeyboard,
164
166
  useLabel: () => useLabel,
@@ -399,14 +401,15 @@ function useWindowSize() {
399
401
  }
400
402
 
401
403
  // src/useBreakpoint/useBreakpoint.ts
402
- function useBreakpoint() {
404
+ function useBreakpoint(mediaQuery) {
403
405
  const windowSize = useWindowSize();
404
406
  const theme = (0, import_react7.useContext)(import_styled_components.ThemeContext);
405
- if (!theme) {
407
+ if (!theme && !mediaQuery) {
406
408
  throw new Error("useBreakpoint must be used within ThemeProvider");
407
409
  }
408
- const breakpoints = Object.keys(theme.mediaQuery);
409
- const values = Object.values(theme.mediaQuery).map((x) => parseInt(String(x)));
410
+ const queries = mediaQuery || theme.mediaQuery;
411
+ const breakpoints = Object.keys(queries);
412
+ const values = Object.values(queries).map((x) => parseInt(String(x)));
410
413
  const breakpoint = (0, import_react7.useMemo)(() => {
411
414
  const breakpoint2 = values.reduce((p, c, i) => {
412
415
  if (c < windowSize.width) {
@@ -1258,8 +1261,43 @@ function useInfiniteLoader(items, perPage = 12, delayInMs = 100) {
1258
1261
  return [visibleItems, loadMore, hasMore];
1259
1262
  }
1260
1263
 
1264
+ // src/useIntersectionObserver/useIntersectionObserver.ts
1265
+ var import_react23 = require("react");
1266
+ function useIntersectionObserver(ref, options = {}) {
1267
+ const {
1268
+ threshold = 1,
1269
+ root = null,
1270
+ rootMargin = "0px"
1271
+ } = options;
1272
+ const [entry, setEntry] = (0, import_react23.useState)();
1273
+ const previousObserver = (0, import_react23.useRef)();
1274
+ const init = (0, import_react23.useCallback)((node) => {
1275
+ if (previousObserver.current) {
1276
+ previousObserver.current.disconnect();
1277
+ previousObserver.current = void 0;
1278
+ }
1279
+ if (isElement(node)) {
1280
+ const observer = new IntersectionObserver(([entry2]) => {
1281
+ setEntry(entry2);
1282
+ }, { threshold, root, rootMargin });
1283
+ observer.observe(node);
1284
+ previousObserver.current = observer;
1285
+ }
1286
+ }, [threshold, root, rootMargin]);
1287
+ (0, import_react23.useEffect)(() => {
1288
+ if (ref.current) {
1289
+ init(ref.current);
1290
+ }
1291
+ }, [init, ref]);
1292
+ const isIntersecting = entry ? entry.isIntersecting : false;
1293
+ return isIntersecting;
1294
+ }
1295
+ function isElement(node) {
1296
+ return (node == null ? void 0 : node.nodeType) === Node.ELEMENT_NODE;
1297
+ }
1298
+
1261
1299
  // src/useKeyboard/useKeyboard.ts
1262
- var import_react24 = require("react");
1300
+ var import_react25 = require("react");
1263
1301
 
1264
1302
  // src/useKeyboard/codes.ts
1265
1303
  var KeyCode = /* @__PURE__ */ ((KeyCode2) => {
@@ -1350,15 +1388,15 @@ var KeyMod = /* @__PURE__ */ ((KeyMod2) => {
1350
1388
  })(KeyMod || {});
1351
1389
 
1352
1390
  // src/useSSR/useSSR.ts
1353
- var import_react23 = require("react");
1391
+ var import_react24 = require("react");
1354
1392
  var detectIsBrowser = () => {
1355
1393
  return Boolean(
1356
1394
  typeof window !== "undefined" && window.document && window.document.createElement
1357
1395
  );
1358
1396
  };
1359
1397
  function useSSR() {
1360
- const [browser, setBrowser] = (0, import_react23.useState)(false);
1361
- (0, import_react23.useEffect)(() => {
1398
+ const [browser, setBrowser] = (0, import_react24.useState)(false);
1399
+ (0, import_react24.useEffect)(() => {
1362
1400
  setBrowser(detectIsBrowser());
1363
1401
  }, []);
1364
1402
  return {
@@ -1428,7 +1466,7 @@ var useKeyboard = (handler, keyBindings, options = {}) => {
1428
1466
  }
1429
1467
  handler && handler(event2);
1430
1468
  };
1431
- (0, import_react24.useEffect)(() => {
1469
+ (0, import_react25.useEffect)(() => {
1432
1470
  if (!disableGlobalEvent) {
1433
1471
  document.addEventListener(event, eventHandler);
1434
1472
  }
@@ -1516,10 +1554,10 @@ function useModal() {
1516
1554
  }
1517
1555
 
1518
1556
  // src/useMounted/useMounted.ts
1519
- var import_react25 = require("react");
1557
+ var import_react26 = require("react");
1520
1558
  function useMounted() {
1521
- const [mounted, setMounted] = (0, import_react25.useState)(false);
1522
- (0, import_react25.useEffect)(() => {
1559
+ const [mounted, setMounted] = (0, import_react26.useState)(false);
1560
+ (0, import_react26.useEffect)(() => {
1523
1561
  setMounted(true);
1524
1562
  }, []);
1525
1563
  return mounted;
@@ -1550,14 +1588,14 @@ function getPaginationInfo(items, page = 1, perPage = 15) {
1550
1588
  }
1551
1589
 
1552
1590
  // src/usePagination/usePagination.ts
1553
- var import_react26 = require("react");
1591
+ var import_react27 = require("react");
1554
1592
  function usePagination($items, $page = 1, $perPage = 15) {
1555
1593
  const total = $items.length;
1556
- const [page, setPage] = (0, import_react26.useState)($page);
1557
- const [perPage, setPerPage_] = (0, import_react26.useState)($perPage);
1558
- const [items, setItems] = (0, import_react26.useState)(getPagedItems($items, $page, $perPage));
1594
+ const [page, setPage] = (0, import_react27.useState)($page);
1595
+ const [perPage, setPerPage_] = (0, import_react27.useState)($perPage);
1596
+ const [items, setItems] = (0, import_react27.useState)(getPagedItems($items, $page, $perPage));
1559
1597
  const pages = Math.ceil(total / perPage);
1560
- (0, import_react26.useEffect)(() => {
1598
+ (0, import_react27.useEffect)(() => {
1561
1599
  setItems(getPagedItems($items, page, perPage));
1562
1600
  }, [$items]);
1563
1601
  function goToPage(page2) {
@@ -1585,13 +1623,13 @@ function usePagination($items, $page = 1, $perPage = 15) {
1585
1623
  }
1586
1624
 
1587
1625
  // src/usePortal/usePortal.ts
1588
- var import_react27 = require("react");
1626
+ var import_react28 = require("react");
1589
1627
  var namespace = "theme";
1590
1628
  function usePortal(name = getUID(), getContainer) {
1591
1629
  const { isBrowser: isBrowser6 } = useSSR();
1592
1630
  const id = `${namespace}-${name}`;
1593
- const [portal, setPortal] = (0, import_react27.useState)(isBrowser6 ? createElementWithId(id) : null);
1594
- (0, import_react27.useEffect)(() => {
1631
+ const [portal, setPortal] = (0, import_react28.useState)(isBrowser6 ? createElementWithId(id) : null);
1632
+ (0, import_react28.useEffect)(() => {
1595
1633
  const container = typeof getContainer === "function" ? getContainer() : null;
1596
1634
  const parentElement = container || document.body;
1597
1635
  const element = parentElement.querySelector(`#${id}`) || createElementWithId(id);
@@ -1612,24 +1650,24 @@ function getUID() {
1612
1650
  }
1613
1651
 
1614
1652
  // src/usePrevious/usePrevious.ts
1615
- var import_react28 = require("react");
1653
+ var import_react29 = require("react");
1616
1654
  function usePrevious(state) {
1617
- const ref = (0, import_react28.useRef)(null);
1618
- (0, import_react28.useEffect)(() => {
1655
+ const ref = (0, import_react29.useRef)(null);
1656
+ (0, import_react29.useEffect)(() => {
1619
1657
  ref.current = state;
1620
1658
  });
1621
1659
  return ref.current;
1622
1660
  }
1623
1661
 
1624
1662
  // src/useRealSize/useRealSize.ts
1625
- var import_react29 = require("react");
1663
+ var import_react30 = require("react");
1626
1664
  function useRealSize(ref) {
1627
- const [state, setState] = (0, import_react29.useState)({ width: 0, height: 0 });
1665
+ const [state, setState] = (0, import_react30.useState)({ width: 0, height: 0 });
1628
1666
  const update = () => {
1629
1667
  const { width, height } = getRealSize(ref.current);
1630
1668
  setState({ width, height });
1631
1669
  };
1632
- (0, import_react29.useEffect)(() => update(), [ref.current]);
1670
+ (0, import_react30.useEffect)(() => update(), [ref.current]);
1633
1671
  return [state, update];
1634
1672
  }
1635
1673
  function getRealSize(element) {
@@ -1664,9 +1702,9 @@ function useResize(callback, immediate = true) {
1664
1702
  }
1665
1703
 
1666
1704
  // src/useScroll/useScroll.ts
1667
- var import_react30 = require("react");
1705
+ var import_react31 = require("react");
1668
1706
  function useScroll() {
1669
- const [scroll, setScroll] = (0, import_react30.useState)({ left: 0, top: 0 });
1707
+ const [scroll, setScroll] = (0, import_react31.useState)({ left: 0, top: 0 });
1670
1708
  const onScroll = () => {
1671
1709
  const left = window.scrollX;
1672
1710
  const top = window.scrollY;
@@ -1718,12 +1756,12 @@ function scrollToY(y = 0) {
1718
1756
  }
1719
1757
 
1720
1758
  // src/useScrolled/useScrolled.ts
1721
- var import_react31 = require("react");
1759
+ var import_react32 = require("react");
1722
1760
  var DEFAULT_CALLBACK = (top, left) => {
1723
1761
  return top > 0;
1724
1762
  };
1725
1763
  function useScrolled(callback = DEFAULT_CALLBACK) {
1726
- const [scrolled, setScrolled] = (0, import_react31.useState)(false);
1764
+ const [scrolled, setScrolled] = (0, import_react32.useState)(false);
1727
1765
  const onScrolled = () => {
1728
1766
  const scrolled_ = callback(window.scrollY, window.scrollX);
1729
1767
  if (scrolled !== scrolled_) {
@@ -1740,7 +1778,7 @@ function useScrolled(callback = DEFAULT_CALLBACK) {
1740
1778
  // src/useSearchParams/useSearchParams.ts
1741
1779
  var import_bom_core7 = require("@websolutespa/bom-core");
1742
1780
  var import_router = require("next/router");
1743
- var import_react32 = require("react");
1781
+ var import_react33 = require("react");
1744
1782
  function replace_(params) {
1745
1783
  if (window.history) {
1746
1784
  const title = document.title;
@@ -1798,29 +1836,29 @@ function replaceSearchParamsSilently(params) {
1798
1836
  }
1799
1837
  function useSearchParams() {
1800
1838
  const router = (0, import_router.useRouter)();
1801
- const initialValue = (0, import_react32.useMemo)(() => {
1839
+ const initialValue = (0, import_react33.useMemo)(() => {
1802
1840
  const params2 = deserialize_(router.asPath);
1803
1841
  const value = Object.fromEntries(params2);
1804
1842
  return value;
1805
1843
  }, [router.asPath]);
1806
1844
  const params = initialValue;
1807
- const replaceParamsSilently = (0, import_react32.useCallback)((params2) => {
1845
+ const replaceParamsSilently = (0, import_react33.useCallback)((params2) => {
1808
1846
  replaceSearchParamsSilently(params2);
1809
1847
  }, []);
1810
- const replaceParams = (0, import_react32.useCallback)((params2) => {
1848
+ const replaceParams = (0, import_react33.useCallback)((params2) => {
1811
1849
  replaceSearchParams(router, params2);
1812
1850
  }, [router]);
1813
1851
  return { params, replaceParamsSilently, replaceParams };
1814
1852
  }
1815
1853
  function useSearchParamsValue(key) {
1816
1854
  const router = (0, import_router.useRouter)();
1817
- const initialValue = (0, import_react32.useMemo)(() => {
1855
+ const initialValue = (0, import_react33.useMemo)(() => {
1818
1856
  const params2 = deserialize_(router.asPath);
1819
1857
  const value = params2.get(key);
1820
1858
  return value;
1821
1859
  }, [key, router.asPath]);
1822
1860
  const params = initialValue;
1823
- const replaceParamsSilently = (0, import_react32.useCallback)((params2) => {
1861
+ const replaceParamsSilently = (0, import_react33.useCallback)((params2) => {
1824
1862
  replaceSearchParamsSilently(params2);
1825
1863
  }, []);
1826
1864
  return { params, replaceParamsSilently };
@@ -1829,7 +1867,7 @@ function useSearchParamsValue(key) {
1829
1867
  // src/useSearchParamsEncoded/useSearchParamsEncoded.ts
1830
1868
  var import_bom_core8 = require("@websolutespa/bom-core");
1831
1869
  var import_router2 = require("next/router");
1832
- var import_react33 = require("react");
1870
+ var import_react34 = require("react");
1833
1871
  var USE_ENCRYPTION = true;
1834
1872
  function base64ToString(base64) {
1835
1873
  if (!USE_ENCRYPTION)
@@ -1935,15 +1973,15 @@ function replaceSearchParamsEncodedSilently(value, key) {
1935
1973
  }
1936
1974
  function useSearchParamsEncoded(key) {
1937
1975
  const router = (0, import_router2.useRouter)();
1938
- const initialValue = (0, import_react33.useMemo)(() => {
1976
+ const initialValue = (0, import_react34.useMemo)(() => {
1939
1977
  const value = getSearchParamsEncoded(router.asPath, key);
1940
1978
  return value;
1941
1979
  }, [key, router.asPath]);
1942
1980
  const params = initialValue;
1943
- const replaceParamsSilently = (0, import_react33.useCallback)((params2) => {
1981
+ const replaceParamsSilently = (0, import_react34.useCallback)((params2) => {
1944
1982
  replaceSearchParamsEncodedSilently(params2, key);
1945
1983
  }, [key]);
1946
- const replaceParams = (0, import_react33.useCallback)((params2) => {
1984
+ const replaceParams = (0, import_react34.useCallback)((params2) => {
1947
1985
  replaceSearchParamsEncoded(router, params2, key);
1948
1986
  }, [key, router]);
1949
1987
  return { params, replaceParamsSilently, replaceParams };
@@ -1952,7 +1990,7 @@ function useSearchParamsEncoded(key) {
1952
1990
  // src/useSearchParamsQs/useSearchParamsQs.ts
1953
1991
  var import_bom_core9 = require("@websolutespa/bom-core");
1954
1992
  var import_router3 = require("next/router");
1955
- var import_react34 = require("react");
1993
+ var import_react35 = require("react");
1956
1994
  function replace(search) {
1957
1995
  if (window.history) {
1958
1996
  const title = document.title;
@@ -2018,27 +2056,27 @@ function replaceSearchParamsQsSilently(value, key) {
2018
2056
  }
2019
2057
  function useSearchParamsQs(key) {
2020
2058
  const router = (0, import_router3.useRouter)();
2021
- const initialValue = (0, import_react34.useMemo)(() => {
2059
+ const initialValue = (0, import_react35.useMemo)(() => {
2022
2060
  const value = getSearchParamsQs(router.asPath, key);
2023
2061
  return value;
2024
2062
  }, [key, router.asPath]);
2025
2063
  const params = initialValue;
2026
- const replaceParamsSilently = (0, import_react34.useCallback)((params2) => {
2064
+ const replaceParamsSilently = (0, import_react35.useCallback)((params2) => {
2027
2065
  replaceSearchParamsQsSilently(params2, key);
2028
2066
  }, [key]);
2029
- const replaceParams = (0, import_react34.useCallback)((params2) => {
2067
+ const replaceParams = (0, import_react35.useCallback)((params2) => {
2030
2068
  replaceSearchParamsQs(router, params2, key);
2031
2069
  }, [key, router]);
2032
2070
  return { params, replaceParamsSilently, replaceParams };
2033
2071
  }
2034
2072
 
2035
2073
  // src/useSorting/useSorting.ts
2036
- var import_react35 = require("react");
2074
+ var import_react36 = require("react");
2037
2075
  function useSorting(items_, callback_, sort_) {
2038
- const [sort, setSort] = (0, import_react35.useState)(sort_);
2039
- const [items, setItems] = (0, import_react35.useState)(callback_(items_.slice(), sort));
2040
- const isInitialMount = (0, import_react35.useRef)(true);
2041
- (0, import_react35.useEffect)(() => {
2076
+ const [sort, setSort] = (0, import_react36.useState)(sort_);
2077
+ const [items, setItems] = (0, import_react36.useState)(callback_(items_.slice(), sort));
2078
+ const isInitialMount = (0, import_react36.useRef)(true);
2079
+ (0, import_react36.useEffect)(() => {
2042
2080
  if (isInitialMount.current) {
2043
2081
  isInitialMount.current = false;
2044
2082
  } else {
@@ -2054,18 +2092,18 @@ function useSorting(items_, callback_, sort_) {
2054
2092
  }
2055
2093
 
2056
2094
  // src/useSwiperIndex/useSwiperIndex.ts
2057
- var import_react36 = require("react");
2058
- var import_react37 = require("swiper/react");
2095
+ var import_react37 = require("react");
2096
+ var import_react38 = require("swiper/react");
2059
2097
  function useSwiperIndex() {
2060
- const swiper = (0, import_react37.useSwiper)();
2061
- const [index, setIndex] = (0, import_react36.useState)(swiper.realIndex);
2062
- const slideTo = (0, import_react36.useCallback)((index2) => {
2098
+ const swiper = (0, import_react38.useSwiper)();
2099
+ const [index, setIndex] = (0, import_react37.useState)(swiper.realIndex);
2100
+ const slideTo = (0, import_react37.useCallback)((index2) => {
2063
2101
  swiper.slideTo(index2);
2064
2102
  }, [swiper]);
2065
2103
  const onSlideChange = (swiper2) => {
2066
2104
  setIndex(swiper2.realIndex);
2067
2105
  };
2068
- (0, import_react36.useEffect)(() => {
2106
+ (0, import_react37.useEffect)(() => {
2069
2107
  if (swiper) {
2070
2108
  swiper.on("slideChange", onSlideChange);
2071
2109
  }
@@ -2079,11 +2117,11 @@ function useSwiperIndex() {
2079
2117
  }
2080
2118
 
2081
2119
  // src/useSyncedRef/useSyncedRef.ts
2082
- var import_react38 = require("react");
2120
+ var import_react39 = require("react");
2083
2121
  function useSyncedRef(value) {
2084
- const ref = (0, import_react38.useRef)(value);
2122
+ const ref = (0, import_react39.useRef)(value);
2085
2123
  ref.current = value;
2086
- return (0, import_react38.useMemo)(() => Object.freeze({
2124
+ return (0, import_react39.useMemo)(() => Object.freeze({
2087
2125
  get current() {
2088
2126
  return ref.current;
2089
2127
  }
@@ -2096,10 +2134,10 @@ function useUnit(unit = "kilometer", locale) {
2096
2134
  }
2097
2135
 
2098
2136
  // src/useUnmountEffect/useUnmountEffect.ts
2099
- var import_react39 = require("react");
2137
+ var import_react40 = require("react");
2100
2138
  function useUnmountEffect(effect) {
2101
2139
  const effectRef = useSyncedRef(effect);
2102
- (0, import_react39.useEffect)(() => () => {
2140
+ (0, import_react40.useEffect)(() => () => {
2103
2141
  effectRef.current();
2104
2142
  }, []);
2105
2143
  }
@@ -2144,6 +2182,7 @@ var useUser = (0, import_zustand4.create)((set) => ({
2144
2182
  getSearchParamsQs,
2145
2183
  getUID,
2146
2184
  hasGeolocation,
2185
+ isElement,
2147
2186
  isPaginationInfo,
2148
2187
  localCollectionDelete,
2149
2188
  localCollectionFetch,
@@ -2203,6 +2242,7 @@ var useUser = (0, import_zustand4.create)((set) => ({
2203
2242
  useGeolocation,
2204
2243
  useIdle,
2205
2244
  useInfiniteLoader,
2245
+ useIntersectionObserver,
2206
2246
  useIsomorphicLayoutEffect,
2207
2247
  useKeyboard,
2208
2248
  useLabel,
package/dist/index.mjs CHANGED
@@ -257,14 +257,15 @@ function useWindowSize() {
257
257
  }
258
258
 
259
259
  // src/useBreakpoint/useBreakpoint.ts
260
- function useBreakpoint() {
260
+ function useBreakpoint(mediaQuery) {
261
261
  const windowSize = useWindowSize();
262
262
  const theme = useContext2(ThemeContext);
263
- if (!theme) {
263
+ if (!theme && !mediaQuery) {
264
264
  throw new Error("useBreakpoint must be used within ThemeProvider");
265
265
  }
266
- const breakpoints = Object.keys(theme.mediaQuery);
267
- const values = Object.values(theme.mediaQuery).map((x) => parseInt(String(x)));
266
+ const queries = mediaQuery || theme.mediaQuery;
267
+ const breakpoints = Object.keys(queries);
268
+ const values = Object.values(queries).map((x) => parseInt(String(x)));
268
269
  const breakpoint = useMemo(() => {
269
270
  const breakpoint2 = values.reduce((p, c, i) => {
270
271
  if (c < windowSize.width) {
@@ -1116,8 +1117,43 @@ function useInfiniteLoader(items, perPage = 12, delayInMs = 100) {
1116
1117
  return [visibleItems, loadMore, hasMore];
1117
1118
  }
1118
1119
 
1120
+ // src/useIntersectionObserver/useIntersectionObserver.ts
1121
+ import { useCallback as useCallback4, useEffect as useEffect15, useRef as useRef10, useState as useState11 } from "react";
1122
+ function useIntersectionObserver(ref, options = {}) {
1123
+ const {
1124
+ threshold = 1,
1125
+ root = null,
1126
+ rootMargin = "0px"
1127
+ } = options;
1128
+ const [entry, setEntry] = useState11();
1129
+ const previousObserver = useRef10();
1130
+ const init = useCallback4((node) => {
1131
+ if (previousObserver.current) {
1132
+ previousObserver.current.disconnect();
1133
+ previousObserver.current = void 0;
1134
+ }
1135
+ if (isElement(node)) {
1136
+ const observer = new IntersectionObserver(([entry2]) => {
1137
+ setEntry(entry2);
1138
+ }, { threshold, root, rootMargin });
1139
+ observer.observe(node);
1140
+ previousObserver.current = observer;
1141
+ }
1142
+ }, [threshold, root, rootMargin]);
1143
+ useEffect15(() => {
1144
+ if (ref.current) {
1145
+ init(ref.current);
1146
+ }
1147
+ }, [init, ref]);
1148
+ const isIntersecting = entry ? entry.isIntersecting : false;
1149
+ return isIntersecting;
1150
+ }
1151
+ function isElement(node) {
1152
+ return (node == null ? void 0 : node.nodeType) === Node.ELEMENT_NODE;
1153
+ }
1154
+
1119
1155
  // src/useKeyboard/useKeyboard.ts
1120
- import { useEffect as useEffect16 } from "react";
1156
+ import { useEffect as useEffect17 } from "react";
1121
1157
 
1122
1158
  // src/useKeyboard/codes.ts
1123
1159
  var KeyCode = /* @__PURE__ */ ((KeyCode2) => {
@@ -1208,15 +1244,15 @@ var KeyMod = /* @__PURE__ */ ((KeyMod2) => {
1208
1244
  })(KeyMod || {});
1209
1245
 
1210
1246
  // src/useSSR/useSSR.ts
1211
- import { useEffect as useEffect15, useState as useState11 } from "react";
1247
+ import { useEffect as useEffect16, useState as useState12 } from "react";
1212
1248
  var detectIsBrowser = () => {
1213
1249
  return Boolean(
1214
1250
  typeof window !== "undefined" && window.document && window.document.createElement
1215
1251
  );
1216
1252
  };
1217
1253
  function useSSR() {
1218
- const [browser, setBrowser] = useState11(false);
1219
- useEffect15(() => {
1254
+ const [browser, setBrowser] = useState12(false);
1255
+ useEffect16(() => {
1220
1256
  setBrowser(detectIsBrowser());
1221
1257
  }, []);
1222
1258
  return {
@@ -1286,7 +1322,7 @@ var useKeyboard = (handler, keyBindings, options = {}) => {
1286
1322
  }
1287
1323
  handler && handler(event2);
1288
1324
  };
1289
- useEffect16(() => {
1325
+ useEffect17(() => {
1290
1326
  if (!disableGlobalEvent) {
1291
1327
  document.addEventListener(event, eventHandler);
1292
1328
  }
@@ -1374,10 +1410,10 @@ function useModal() {
1374
1410
  }
1375
1411
 
1376
1412
  // src/useMounted/useMounted.ts
1377
- import { useEffect as useEffect17, useState as useState12 } from "react";
1413
+ import { useEffect as useEffect18, useState as useState13 } from "react";
1378
1414
  function useMounted() {
1379
- const [mounted, setMounted] = useState12(false);
1380
- useEffect17(() => {
1415
+ const [mounted, setMounted] = useState13(false);
1416
+ useEffect18(() => {
1381
1417
  setMounted(true);
1382
1418
  }, []);
1383
1419
  return mounted;
@@ -1408,14 +1444,14 @@ function getPaginationInfo(items, page = 1, perPage = 15) {
1408
1444
  }
1409
1445
 
1410
1446
  // src/usePagination/usePagination.ts
1411
- import { useEffect as useEffect18, useState as useState13 } from "react";
1447
+ import { useEffect as useEffect19, useState as useState14 } from "react";
1412
1448
  function usePagination($items, $page = 1, $perPage = 15) {
1413
1449
  const total = $items.length;
1414
- const [page, setPage] = useState13($page);
1415
- const [perPage, setPerPage_] = useState13($perPage);
1416
- const [items, setItems] = useState13(getPagedItems($items, $page, $perPage));
1450
+ const [page, setPage] = useState14($page);
1451
+ const [perPage, setPerPage_] = useState14($perPage);
1452
+ const [items, setItems] = useState14(getPagedItems($items, $page, $perPage));
1417
1453
  const pages = Math.ceil(total / perPage);
1418
- useEffect18(() => {
1454
+ useEffect19(() => {
1419
1455
  setItems(getPagedItems($items, page, perPage));
1420
1456
  }, [$items]);
1421
1457
  function goToPage(page2) {
@@ -1443,13 +1479,13 @@ function usePagination($items, $page = 1, $perPage = 15) {
1443
1479
  }
1444
1480
 
1445
1481
  // src/usePortal/usePortal.ts
1446
- import { useEffect as useEffect19, useState as useState14 } from "react";
1482
+ import { useEffect as useEffect20, useState as useState15 } from "react";
1447
1483
  var namespace = "theme";
1448
1484
  function usePortal(name = getUID(), getContainer) {
1449
1485
  const { isBrowser: isBrowser6 } = useSSR();
1450
1486
  const id = `${namespace}-${name}`;
1451
- const [portal, setPortal] = useState14(isBrowser6 ? createElementWithId(id) : null);
1452
- useEffect19(() => {
1487
+ const [portal, setPortal] = useState15(isBrowser6 ? createElementWithId(id) : null);
1488
+ useEffect20(() => {
1453
1489
  const container = typeof getContainer === "function" ? getContainer() : null;
1454
1490
  const parentElement = container || document.body;
1455
1491
  const element = parentElement.querySelector(`#${id}`) || createElementWithId(id);
@@ -1470,24 +1506,24 @@ function getUID() {
1470
1506
  }
1471
1507
 
1472
1508
  // src/usePrevious/usePrevious.ts
1473
- import { useEffect as useEffect20, useRef as useRef10 } from "react";
1509
+ import { useEffect as useEffect21, useRef as useRef11 } from "react";
1474
1510
  function usePrevious(state) {
1475
- const ref = useRef10(null);
1476
- useEffect20(() => {
1511
+ const ref = useRef11(null);
1512
+ useEffect21(() => {
1477
1513
  ref.current = state;
1478
1514
  });
1479
1515
  return ref.current;
1480
1516
  }
1481
1517
 
1482
1518
  // src/useRealSize/useRealSize.ts
1483
- import { useEffect as useEffect21, useState as useState15 } from "react";
1519
+ import { useEffect as useEffect22, useState as useState16 } from "react";
1484
1520
  function useRealSize(ref) {
1485
- const [state, setState] = useState15({ width: 0, height: 0 });
1521
+ const [state, setState] = useState16({ width: 0, height: 0 });
1486
1522
  const update = () => {
1487
1523
  const { width, height } = getRealSize(ref.current);
1488
1524
  setState({ width, height });
1489
1525
  };
1490
- useEffect21(() => update(), [ref.current]);
1526
+ useEffect22(() => update(), [ref.current]);
1491
1527
  return [state, update];
1492
1528
  }
1493
1529
  function getRealSize(element) {
@@ -1522,9 +1558,9 @@ function useResize(callback, immediate = true) {
1522
1558
  }
1523
1559
 
1524
1560
  // src/useScroll/useScroll.ts
1525
- import { useState as useState16 } from "react";
1561
+ import { useState as useState17 } from "react";
1526
1562
  function useScroll() {
1527
- const [scroll, setScroll] = useState16({ left: 0, top: 0 });
1563
+ const [scroll, setScroll] = useState17({ left: 0, top: 0 });
1528
1564
  const onScroll = () => {
1529
1565
  const left = window.scrollX;
1530
1566
  const top = window.scrollY;
@@ -1576,12 +1612,12 @@ function scrollToY(y = 0) {
1576
1612
  }
1577
1613
 
1578
1614
  // src/useScrolled/useScrolled.ts
1579
- import { useState as useState17 } from "react";
1615
+ import { useState as useState18 } from "react";
1580
1616
  var DEFAULT_CALLBACK = (top, left) => {
1581
1617
  return top > 0;
1582
1618
  };
1583
1619
  function useScrolled(callback = DEFAULT_CALLBACK) {
1584
- const [scrolled, setScrolled] = useState17(false);
1620
+ const [scrolled, setScrolled] = useState18(false);
1585
1621
  const onScrolled = () => {
1586
1622
  const scrolled_ = callback(window.scrollY, window.scrollX);
1587
1623
  if (scrolled !== scrolled_) {
@@ -1598,7 +1634,7 @@ function useScrolled(callback = DEFAULT_CALLBACK) {
1598
1634
  // src/useSearchParams/useSearchParams.ts
1599
1635
  import { isBrowser as isBrowser3 } from "@websolutespa/bom-core";
1600
1636
  import { useRouter } from "next/router";
1601
- import { useCallback as useCallback4, useMemo as useMemo5 } from "react";
1637
+ import { useCallback as useCallback5, useMemo as useMemo5 } from "react";
1602
1638
  function replace_(params) {
1603
1639
  if (window.history) {
1604
1640
  const title = document.title;
@@ -1662,10 +1698,10 @@ function useSearchParams() {
1662
1698
  return value;
1663
1699
  }, [router.asPath]);
1664
1700
  const params = initialValue;
1665
- const replaceParamsSilently = useCallback4((params2) => {
1701
+ const replaceParamsSilently = useCallback5((params2) => {
1666
1702
  replaceSearchParamsSilently(params2);
1667
1703
  }, []);
1668
- const replaceParams = useCallback4((params2) => {
1704
+ const replaceParams = useCallback5((params2) => {
1669
1705
  replaceSearchParams(router, params2);
1670
1706
  }, [router]);
1671
1707
  return { params, replaceParamsSilently, replaceParams };
@@ -1678,7 +1714,7 @@ function useSearchParamsValue(key) {
1678
1714
  return value;
1679
1715
  }, [key, router.asPath]);
1680
1716
  const params = initialValue;
1681
- const replaceParamsSilently = useCallback4((params2) => {
1717
+ const replaceParamsSilently = useCallback5((params2) => {
1682
1718
  replaceSearchParamsSilently(params2);
1683
1719
  }, []);
1684
1720
  return { params, replaceParamsSilently };
@@ -1687,7 +1723,7 @@ function useSearchParamsValue(key) {
1687
1723
  // src/useSearchParamsEncoded/useSearchParamsEncoded.ts
1688
1724
  import { isBrowser as isBrowser4 } from "@websolutespa/bom-core";
1689
1725
  import { useRouter as useRouter2 } from "next/router";
1690
- import { useCallback as useCallback5, useMemo as useMemo6 } from "react";
1726
+ import { useCallback as useCallback6, useMemo as useMemo6 } from "react";
1691
1727
  var USE_ENCRYPTION = true;
1692
1728
  function base64ToString(base64) {
1693
1729
  if (!USE_ENCRYPTION)
@@ -1798,10 +1834,10 @@ function useSearchParamsEncoded(key) {
1798
1834
  return value;
1799
1835
  }, [key, router.asPath]);
1800
1836
  const params = initialValue;
1801
- const replaceParamsSilently = useCallback5((params2) => {
1837
+ const replaceParamsSilently = useCallback6((params2) => {
1802
1838
  replaceSearchParamsEncodedSilently(params2, key);
1803
1839
  }, [key]);
1804
- const replaceParams = useCallback5((params2) => {
1840
+ const replaceParams = useCallback6((params2) => {
1805
1841
  replaceSearchParamsEncoded(router, params2, key);
1806
1842
  }, [key, router]);
1807
1843
  return { params, replaceParamsSilently, replaceParams };
@@ -1810,7 +1846,7 @@ function useSearchParamsEncoded(key) {
1810
1846
  // src/useSearchParamsQs/useSearchParamsQs.ts
1811
1847
  import { isBrowser as isBrowser5, qsDeserializeRaw, qsSerializeRaw } from "@websolutespa/bom-core";
1812
1848
  import { useRouter as useRouter3 } from "next/router";
1813
- import { useCallback as useCallback6, useMemo as useMemo7 } from "react";
1849
+ import { useCallback as useCallback7, useMemo as useMemo7 } from "react";
1814
1850
  function replace(search) {
1815
1851
  if (window.history) {
1816
1852
  const title = document.title;
@@ -1881,22 +1917,22 @@ function useSearchParamsQs(key) {
1881
1917
  return value;
1882
1918
  }, [key, router.asPath]);
1883
1919
  const params = initialValue;
1884
- const replaceParamsSilently = useCallback6((params2) => {
1920
+ const replaceParamsSilently = useCallback7((params2) => {
1885
1921
  replaceSearchParamsQsSilently(params2, key);
1886
1922
  }, [key]);
1887
- const replaceParams = useCallback6((params2) => {
1923
+ const replaceParams = useCallback7((params2) => {
1888
1924
  replaceSearchParamsQs(router, params2, key);
1889
1925
  }, [key, router]);
1890
1926
  return { params, replaceParamsSilently, replaceParams };
1891
1927
  }
1892
1928
 
1893
1929
  // src/useSorting/useSorting.ts
1894
- import { useEffect as useEffect22, useRef as useRef11, useState as useState18 } from "react";
1930
+ import { useEffect as useEffect23, useRef as useRef12, useState as useState19 } from "react";
1895
1931
  function useSorting(items_, callback_, sort_) {
1896
- const [sort, setSort] = useState18(sort_);
1897
- const [items, setItems] = useState18(callback_(items_.slice(), sort));
1898
- const isInitialMount = useRef11(true);
1899
- useEffect22(() => {
1932
+ const [sort, setSort] = useState19(sort_);
1933
+ const [items, setItems] = useState19(callback_(items_.slice(), sort));
1934
+ const isInitialMount = useRef12(true);
1935
+ useEffect23(() => {
1900
1936
  if (isInitialMount.current) {
1901
1937
  isInitialMount.current = false;
1902
1938
  } else {
@@ -1912,18 +1948,18 @@ function useSorting(items_, callback_, sort_) {
1912
1948
  }
1913
1949
 
1914
1950
  // src/useSwiperIndex/useSwiperIndex.ts
1915
- import { useCallback as useCallback7, useEffect as useEffect23, useState as useState19 } from "react";
1951
+ import { useCallback as useCallback8, useEffect as useEffect24, useState as useState20 } from "react";
1916
1952
  import { useSwiper } from "swiper/react";
1917
1953
  function useSwiperIndex() {
1918
1954
  const swiper = useSwiper();
1919
- const [index, setIndex] = useState19(swiper.realIndex);
1920
- const slideTo = useCallback7((index2) => {
1955
+ const [index, setIndex] = useState20(swiper.realIndex);
1956
+ const slideTo = useCallback8((index2) => {
1921
1957
  swiper.slideTo(index2);
1922
1958
  }, [swiper]);
1923
1959
  const onSlideChange = (swiper2) => {
1924
1960
  setIndex(swiper2.realIndex);
1925
1961
  };
1926
- useEffect23(() => {
1962
+ useEffect24(() => {
1927
1963
  if (swiper) {
1928
1964
  swiper.on("slideChange", onSlideChange);
1929
1965
  }
@@ -1937,9 +1973,9 @@ function useSwiperIndex() {
1937
1973
  }
1938
1974
 
1939
1975
  // src/useSyncedRef/useSyncedRef.ts
1940
- import { useMemo as useMemo8, useRef as useRef12 } from "react";
1976
+ import { useMemo as useMemo8, useRef as useRef13 } from "react";
1941
1977
  function useSyncedRef(value) {
1942
- const ref = useRef12(value);
1978
+ const ref = useRef13(value);
1943
1979
  ref.current = value;
1944
1980
  return useMemo8(() => Object.freeze({
1945
1981
  get current() {
@@ -1954,10 +1990,10 @@ function useUnit(unit = "kilometer", locale) {
1954
1990
  }
1955
1991
 
1956
1992
  // src/useUnmountEffect/useUnmountEffect.ts
1957
- import { useEffect as useEffect24 } from "react";
1993
+ import { useEffect as useEffect25 } from "react";
1958
1994
  function useUnmountEffect(effect) {
1959
1995
  const effectRef = useSyncedRef(effect);
1960
- useEffect24(() => () => {
1996
+ useEffect25(() => () => {
1961
1997
  effectRef.current();
1962
1998
  }, []);
1963
1999
  }
@@ -2001,6 +2037,7 @@ export {
2001
2037
  getSearchParamsQs,
2002
2038
  getUID,
2003
2039
  hasGeolocation,
2040
+ isElement,
2004
2041
  isPaginationInfo,
2005
2042
  localCollectionDelete,
2006
2043
  localCollectionFetch,
@@ -2060,6 +2097,7 @@ export {
2060
2097
  useGeolocation,
2061
2098
  useIdle,
2062
2099
  useInfiniteLoader,
2100
+ useIntersectionObserver,
2063
2101
  useIsomorphicLayoutEffect,
2064
2102
  useKeyboard,
2065
2103
  useLabel,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@websolutespa/bom-mixer-hooks",
3
- "version": "1.7.0",
3
+ "version": "1.7.2",
4
4
  "description": "Mixer Hooks module of the BOM Repository",
5
5
  "keywords": [
6
6
  "bom",
@@ -29,7 +29,7 @@
29
29
  "@websolutespa/bom-mixer-store": "*",
30
30
  "framer-motion": ">= 7.2.1",
31
31
  "iron-session": ">= 6.2.1",
32
- "next": ">= 13.4.19",
32
+ "next": ">= 14.1.4",
33
33
  "react-dom": ">= 18.2.0",
34
34
  "react": ">= 18.2.0",
35
35
  "styled-components": ">= 5.3.11 <6.x.x",
@@ -37,21 +37,21 @@
37
37
  "zustand": ">= 4.4.0"
38
38
  },
39
39
  "devDependencies": {
40
- "@types/react": "^18.2.18",
41
- "@types/react-dom": "^18.2.7",
40
+ "@types/react": "^18.2.75",
41
+ "@types/react-dom": "^18.2.24",
42
42
  "@types/styled-components": "^5.1.26",
43
43
  "@websolutespa/bom-cli": "*",
44
44
  "@websolutespa/test": "*",
45
45
  "@websolutespa/tsconfig": "*",
46
- "eslint": "^8.46.0",
46
+ "eslint": "^9.0.0",
47
47
  "eslint-config-websolute": "*",
48
48
  "npm-run-all": "^4.1.5",
49
49
  "raw-loader": "^4.0.2",
50
50
  "react": "^18.2.0",
51
51
  "styled-components": "^5.3.11",
52
- "ts-node": "^10.9.1",
52
+ "ts-node": "^10.9.2",
53
53
  "tsup": "^6.7.0",
54
- "typescript": "^5.1.6"
54
+ "typescript": "^5.4.5"
55
55
  },
56
56
  "publishConfig": {
57
57
  "access": "public"
package/src/index.ts CHANGED
@@ -26,6 +26,7 @@ export * from './useGeolocation/geolocation.service';
26
26
  export * from './useGeolocation/useGeolocation';
27
27
  export * from './useIdle/useIdle';
28
28
  export * from './useInfiniteLoader/useInfiniteLoader';
29
+ export * from './useIntersectionObserver/useIntersectionObserver';
29
30
  export * from './useIsomorphicLayoutEffect/useIsomorphicLayoutEffect';
30
31
  export * from './useKeyboard/useKeyboard';
31
32
  export * from './useLabel/useLabel';
@@ -1,4 +1,4 @@
1
- import { useContext, useMemo } from 'react';
1
+ import { CSSProperties, useContext, useMemo } from 'react';
2
2
  import { ThemeContext } from 'styled-components';
3
3
  import { useWindowSize } from '../useWindowSize/useWindowSize';
4
4
 
@@ -10,19 +10,21 @@ type Breakpoint = {
10
10
  max: number;
11
11
  };
12
12
 
13
- export function useBreakpoint(): Breakpoint {
14
- // todo
15
- const windowSize = useWindowSize();
13
+ type MediaQuery = Record<BreakpointType, CSSProperties['width']>;
16
14
 
17
- // const [breakpoint, setBreakpoint] = useState<Breakpoint>({ key: 'xs', min: 0, max: 0 });
15
+ export function useBreakpoint(mediaQuery?: MediaQuery): Breakpoint {
16
+ const windowSize = useWindowSize();
18
17
 
19
18
  const theme = useContext(ThemeContext);
20
- if (!theme) {
19
+
20
+ if (!theme && !mediaQuery) {
21
21
  throw new Error('useBreakpoint must be used within ThemeProvider');
22
22
  }
23
23
 
24
- const breakpoints: BreakpointType[] = Object.keys(theme.mediaQuery) as BreakpointType[];
25
- const values: number[] = Object.values(theme.mediaQuery).map(x => parseInt(String(x)));
24
+ const queries: MediaQuery = mediaQuery || theme.mediaQuery;
25
+
26
+ const breakpoints: BreakpointType[] = Object.keys(queries) as BreakpointType[];
27
+ const values: number[] = Object.values(queries).map(x => parseInt(String(x)));
26
28
 
27
29
  const breakpoint = useMemo(() => {
28
30
  const breakpoint = values.reduce((p, c, i) => {
@@ -1,6 +1,7 @@
1
1
  import { QueryParams, qsSerialize } from '@websolutespa/bom-core';
2
- import { useApiFetch, useLayout } from '@websolutespa/bom-mixer-hooks';
3
2
  import { ApiRequestOptions } from '@websolutespa/bom-mixer-store';
3
+ import { useApiFetch } from '../useApi/useApi';
4
+ import { useLayout } from '../useLayout/useLayout';
4
5
  import { localCollectionDelete, localCollectionGet, localCollectionPatch, localCollectionPost, localCollectionPut } from './local.collection';
5
6
 
6
7
  type CollectionApi = {
@@ -0,0 +1,38 @@
1
+ import { MutableRefObject, useCallback, useEffect, useRef, useState } from 'react';
2
+
3
+ export function useIntersectionObserver(
4
+ ref: MutableRefObject<Node | undefined>,
5
+ options: IntersectionObserverInit = {}): boolean {
6
+ const {
7
+ threshold = 1,
8
+ root = null,
9
+ rootMargin = '0px',
10
+ } = options;
11
+ const [entry, setEntry] = useState<IntersectionObserverEntry>();
12
+ const previousObserver = useRef<IntersectionObserver>();
13
+ const init = useCallback((node?: Node) => {
14
+ if (previousObserver.current) {
15
+ previousObserver.current.disconnect();
16
+ previousObserver.current = undefined;
17
+ }
18
+ if (isElement(node)) {
19
+ const observer = new IntersectionObserver(([entry]) => {
20
+ setEntry(entry);
21
+ }, { threshold, root, rootMargin });
22
+ observer.observe(node);
23
+ previousObserver.current = observer;
24
+ }
25
+ }, [threshold, root, rootMargin]);
26
+ useEffect(() => {
27
+ if (ref.current) {
28
+ init(ref.current);
29
+ }
30
+ }, [init, ref]);
31
+ // console.log(entry);
32
+ const isIntersecting = entry ? entry.isIntersecting : false;
33
+ return isIntersecting;
34
+ }
35
+
36
+ export function isElement(node?: Node): node is Element {
37
+ return node?.nodeType === Node.ELEMENT_NODE;
38
+ }
@@ -1,6 +1,6 @@
1
- import { createGenericContext } from '@websolutespa/bom-mixer-hooks';
2
1
  import { ILazyModules } from '@websolutespa/bom-mixer-models';
3
2
  import React from 'react';
3
+ import { createGenericContext } from '../useGenericContext/useGenericContext';
4
4
 
5
5
  export type ILazyModulesContext = ILazyModules;
6
6