@elliemae/ds-mobile 3.4.0-rc.2 → 3.4.0-rc.3

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.
@@ -37,11 +37,15 @@ const useMakeMutable = (referenceVar) => {
37
37
  }, [referenceVar]);
38
38
  return mutable;
39
39
  };
40
- function useIntersectionObserver(elementRef, { threshold = 0, root = null, rootMargin = "0%", freezeOnceVisible = false }) {
40
+ function useIntersectionObserver(elementRef, { threshold = 0, root = null, rootMargin = "0%", freezeOnceVisible = false }, onIntersectionCb = (entry) => {
41
+ }) {
42
+ const mutableIntersectionCb = useMakeMutable(onIntersectionCb);
41
43
  const [entry, setEntry] = (0, import_react.useState)();
42
44
  const frozen = entry?.isIntersecting && freezeOnceVisible;
43
45
  const updateEntry = ([newEntry]) => {
44
46
  setEntry(newEntry);
47
+ if (newEntry.isIntersecting)
48
+ mutableIntersectionCb.current(newEntry);
45
49
  };
46
50
  (0, import_react.useEffect)(() => {
47
51
  const node = elementRef?.current;
@@ -59,18 +63,18 @@ function useIntersectionObserver(elementRef, { threshold = 0, root = null, rootM
59
63
  const InfiniteLoader = ({ isFetching, fetchData, children, height, hasMoreItems = true }) => {
60
64
  const [viewportHeight, setViewportHeight] = (0, import_react.useState)(height);
61
65
  const baselineRef = (0, import_react.useRef)(null);
62
- const entry = useIntersectionObserver(baselineRef, {
66
+ const mutableIsFetching = useMakeMutable(isFetching);
67
+ const mutableFetchData = useMakeMutable(fetchData);
68
+ const onIntersectionCb = import_react.default.useCallback(() => {
69
+ if (hasMoreItems && !mutableIsFetching.current) {
70
+ mutableFetchData.current();
71
+ }
72
+ }, [hasMoreItems, mutableFetchData, mutableIsFetching]);
73
+ useIntersectionObserver(baselineRef, {
63
74
  root: null,
64
75
  rootMargin: "0px",
65
76
  threshold: 0.1
66
- });
67
- const isIntersecting = !!entry?.isIntersecting;
68
- const mutableIsFetching = useMakeMutable(isFetching);
69
- (0, import_react.useEffect)(() => {
70
- if (hasMoreItems && isIntersecting && !mutableIsFetching.current) {
71
- fetchData();
72
- }
73
- }, [fetchData, isIntersecting, hasMoreItems, mutableIsFetching]);
77
+ }, onIntersectionCb);
74
78
  const handleResize = (0, import_react.useCallback)(() => {
75
79
  setViewportHeight(window.innerHeight);
76
80
  }, []);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/InfiniteLoader/Infiniteloader.tsx", "../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["import React, { useEffect, useRef, useCallback, useState, type RefObject, type WeakValidationMap } from 'react';\nimport { PropTypes, describe } from '@elliemae/ds-utilities';\nimport { Grid } from '@elliemae/ds-grid';\nimport { Loader } from './Loader';\n\ninterface Props {\n isFetching: boolean;\n hasMoreItems?: boolean;\n fetchData: () => void;\n children: React.ReactNode;\n height?: number | string;\n}\ntype UseMakeMutable<T = unknown> = (referenceVar: T) => React.MutableRefObject<T>;\nconst useMakeMutable: UseMakeMutable = (referenceVar) => {\n const mutable = useRef(referenceVar);\n useEffect(() => {\n mutable.current = referenceVar;\n }, [referenceVar]);\n return mutable;\n};\n\ninterface Args extends IntersectionObserverInit {\n freezeOnceVisible?: boolean;\n}\n\nfunction useIntersectionObserver(\n elementRef: RefObject<Element>,\n { threshold = 0, root = null, rootMargin = '0%', freezeOnceVisible = false }: Args,\n): IntersectionObserverEntry | undefined {\n const [entry, setEntry] = useState<IntersectionObserverEntry>();\n\n const frozen = entry?.isIntersecting && freezeOnceVisible;\n\n const updateEntry = ([newEntry]: IntersectionObserverEntry[]): void => {\n setEntry(newEntry);\n };\n\n useEffect(() => {\n const node = elementRef?.current; // DOM Ref\n const hasIOSupport = !!window.IntersectionObserver;\n\n if (!hasIOSupport || frozen || !node) return () => {};\n\n const observerParams = { threshold, root, rootMargin };\n const observer = new IntersectionObserver(updateEntry, observerParams);\n\n observer.observe(node);\n\n return () => observer.disconnect();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [elementRef, JSON.stringify(threshold), root, rootMargin, frozen]);\n\n return entry;\n}\n\nconst InfiniteLoader = ({ isFetching, fetchData, children, height, hasMoreItems = true }: Props) => {\n const [viewportHeight, setViewportHeight] = useState<number | undefined | string>(height);\n\n const baselineRef = useRef<HTMLDivElement | null>(null);\n const entry = useIntersectionObserver(baselineRef, {\n root: null,\n rootMargin: '0px',\n threshold: 0.1,\n });\n const isIntersecting = !!entry?.isIntersecting;\n const mutableIsFetching = useMakeMutable(isFetching);\n\n useEffect(() => {\n if (hasMoreItems && isIntersecting && !mutableIsFetching.current) {\n fetchData();\n }\n // we only want to redefine the callback when \"fetchData\" changes\n // we don't need to redefine if isFetching changes, so we use \"mutableIsFetching\"\n }, [fetchData, isIntersecting, hasMoreItems, mutableIsFetching]);\n\n const handleResize = useCallback(() => {\n setViewportHeight(window.innerHeight);\n }, []);\n\n useEffect(() => {\n if (!height) {\n window.addEventListener('resize', handleResize);\n handleResize();\n }\n return () => {\n if (!height) window.removeEventListener('resize', handleResize);\n };\n }, [handleResize, height]);\n\n return (\n <Grid style={{ position: 'relative', overflow: 'hidden', height: viewportHeight }}>\n <Grid style={{ overflow: isFetching ? 'hidden' : 'auto', height: viewportHeight }}>\n {children}\n <div ref={baselineRef} style={{ height: 1 }} />\n </Grid>\n <Loader isOpen={isFetching} />\n </Grid>\n );\n};\n\nconst listProps = {\n isFetching: PropTypes.bool.description('toggle loading state'),\n hasMoreItems: PropTypes.bool\n .description('wheter or not you have more items that need to be loaded')\n .defaultValue(true),\n fetchData: PropTypes.func.description('callback to fetch new items'),\n children: PropTypes.element.description('row items for infinite loader'),\n height: PropTypes.number.description('infinite loader list height'),\n} as WeakValidationMap<unknown>;\n\nconst InfiniteLoaderWithSchema = describe(InfiniteLoader);\nInfiniteLoaderWithSchema.propTypes = listProps;\nexport { InfiniteLoader, InfiniteLoaderWithSchema };\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAwG;AACxG,0BAAoC;AACpC,qBAAqB;AACrB,oBAAuB;AAUvB,MAAM,iBAAiC,CAAC,iBAAiB;AACvD,QAAM,UAAU,yBAAO,YAAY;AACnC,8BAAU,MAAM;AACd,YAAQ,UAAU;AAAA,EACpB,GAAG,CAAC,YAAY,CAAC;AACjB,SAAO;AACT;AAMA,iCACE,YACA,EAAE,YAAY,GAAG,OAAO,MAAM,aAAa,MAAM,oBAAoB,SAC9B;AACvC,QAAM,CAAC,OAAO,YAAY,2BAAoC;AAE9D,QAAM,SAAS,OAAO,kBAAkB;AAExC,QAAM,cAAc,CAAC,CAAC,cAAiD;AACrE,aAAS,QAAQ;AAAA,EACnB;AAEA,8BAAU,MAAM;AACd,UAAM,OAAO,YAAY;AACzB,UAAM,eAAe,CAAC,CAAC,OAAO;AAE9B,QAAI,CAAC,gBAAgB,UAAU,CAAC;AAAM,aAAO,MAAM;AAAA,MAAC;AAEpD,UAAM,iBAAiB,EAAE,WAAW,MAAM,WAAW;AACrD,UAAM,WAAW,IAAI,qBAAqB,aAAa,cAAc;AAErE,aAAS,QAAQ,IAAI;AAErB,WAAO,MAAM,SAAS,WAAW;AAAA,EAEnC,GAAG,CAAC,YAAY,KAAK,UAAU,SAAS,GAAG,MAAM,YAAY,MAAM,CAAC;AAEpE,SAAO;AACT;AAEA,MAAM,iBAAiB,CAAC,EAAE,YAAY,WAAW,UAAU,QAAQ,eAAe,WAAkB;AAClG,QAAM,CAAC,gBAAgB,qBAAqB,2BAAsC,MAAM;AAExF,QAAM,cAAc,yBAA8B,IAAI;AACtD,QAAM,QAAQ,wBAAwB,aAAa;AAAA,IACjD,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,EACb,CAAC;AACD,QAAM,iBAAiB,CAAC,CAAC,OAAO;AAChC,QAAM,oBAAoB,eAAe,UAAU;AAEnD,8BAAU,MAAM;AACd,QAAI,gBAAgB,kBAAkB,CAAC,kBAAkB,SAAS;AAChE,gBAAU;AAAA,IACZ;AAAA,EAGF,GAAG,CAAC,WAAW,gBAAgB,cAAc,iBAAiB,CAAC;AAE/D,QAAM,eAAe,8BAAY,MAAM;AACrC,sBAAkB,OAAO,WAAW;AAAA,EACtC,GAAG,CAAC,CAAC;AAEL,8BAAU,MAAM;AACd,QAAI,CAAC,QAAQ;AACX,aAAO,iBAAiB,UAAU,YAAY;AAC9C,mBAAa;AAAA,IACf;AACA,WAAO,MAAM;AACX,UAAI,CAAC;AAAQ,eAAO,oBAAoB,UAAU,YAAY;AAAA,IAChE;AAAA,EACF,GAAG,CAAC,cAAc,MAAM,CAAC;AAEzB,SACE,mDAAC;AAAA,IAAK,OAAO,EAAE,UAAU,YAAY,UAAU,UAAU,QAAQ,eAAe;AAAA,KAC9E,mDAAC;AAAA,IAAK,OAAO,EAAE,UAAU,aAAa,WAAW,QAAQ,QAAQ,eAAe;AAAA,KAC7E,UACD,mDAAC;AAAA,IAAI,KAAK;AAAA,IAAa,OAAO,EAAE,QAAQ,EAAE;AAAA,GAAG,CAC/C,GACA,mDAAC;AAAA,IAAO,QAAQ;AAAA,GAAY,CAC9B;AAEJ;AAEA,MAAM,YAAY;AAAA,EAChB,YAAY,8BAAU,KAAK,YAAY,sBAAsB;AAAA,EAC7D,cAAc,8BAAU,KACrB,YAAY,0DAA0D,EACtE,aAAa,IAAI;AAAA,EACpB,WAAW,8BAAU,KAAK,YAAY,6BAA6B;AAAA,EACnE,UAAU,8BAAU,QAAQ,YAAY,+BAA+B;AAAA,EACvE,QAAQ,8BAAU,OAAO,YAAY,6BAA6B;AACpE;AAEA,MAAM,2BAA2B,kCAAS,cAAc;AACxD,yBAAyB,YAAY;",
4
+ "sourcesContent": ["import React, { useEffect, useRef, useCallback, useState, type RefObject, type WeakValidationMap } from 'react';\nimport { PropTypes, describe } from '@elliemae/ds-utilities';\nimport { Grid } from '@elliemae/ds-grid';\nimport { Loader } from './Loader';\n\ninterface Props {\n isFetching: boolean;\n hasMoreItems?: boolean;\n fetchData: () => void;\n children: React.ReactNode;\n height?: number | string;\n}\n\nconst useMakeMutable = <T,>(referenceVar: T): React.MutableRefObject<T> => {\n const mutable = useRef(referenceVar);\n useEffect(() => {\n mutable.current = referenceVar;\n }, [referenceVar]);\n return mutable;\n};\n\ninterface Args extends IntersectionObserverInit {\n freezeOnceVisible?: boolean;\n}\n\nfunction useIntersectionObserver(\n elementRef: RefObject<Element>,\n { threshold = 0, root = null, rootMargin = '0%', freezeOnceVisible = false }: Args,\n // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars\n onIntersectionCb = (entry: IntersectionObserverEntry): void => {},\n): IntersectionObserverEntry | undefined {\n const mutableIntersectionCb = useMakeMutable(onIntersectionCb);\n const [entry, setEntry] = useState<IntersectionObserverEntry>();\n\n const frozen = entry?.isIntersecting && freezeOnceVisible;\n\n const updateEntry = ([newEntry]: IntersectionObserverEntry[]): void => {\n setEntry(newEntry);\n if (newEntry.isIntersecting) mutableIntersectionCb.current(newEntry);\n };\n\n useEffect(() => {\n const node = elementRef?.current; // DOM Ref\n const hasIOSupport = !!window.IntersectionObserver;\n\n if (!hasIOSupport || frozen || !node) return () => {};\n\n const observerParams = { threshold, root, rootMargin };\n const observer = new IntersectionObserver(updateEntry, observerParams);\n\n observer.observe(node);\n\n return () => observer.disconnect();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [elementRef, JSON.stringify(threshold), root, rootMargin, frozen]);\n\n return entry;\n}\n\nconst InfiniteLoader = ({ isFetching, fetchData, children, height, hasMoreItems = true }: Props) => {\n const [viewportHeight, setViewportHeight] = useState<number | undefined | string>(height);\n\n const baselineRef = useRef<HTMLDivElement | null>(null);\n const mutableIsFetching = useMakeMutable(isFetching);\n const mutableFetchData = useMakeMutable(fetchData);\n const onIntersectionCb = React.useCallback(() => {\n if (hasMoreItems && !mutableIsFetching.current) {\n mutableFetchData.current();\n }\n }, [hasMoreItems, mutableFetchData, mutableIsFetching]);\n useIntersectionObserver(\n baselineRef,\n {\n root: null,\n rootMargin: '0px',\n threshold: 0.1,\n },\n onIntersectionCb,\n );\n\n const handleResize = useCallback(() => {\n setViewportHeight(window.innerHeight);\n }, []);\n\n useEffect(() => {\n if (!height) {\n window.addEventListener('resize', handleResize);\n handleResize();\n }\n return () => {\n if (!height) window.removeEventListener('resize', handleResize);\n };\n }, [handleResize, height]);\n\n return (\n <Grid style={{ position: 'relative', overflow: 'hidden', height: viewportHeight }}>\n <Grid style={{ overflow: isFetching ? 'hidden' : 'auto', height: viewportHeight }}>\n {children}\n <div ref={baselineRef} style={{ height: 1 }} />\n </Grid>\n <Loader isOpen={isFetching} />\n </Grid>\n );\n};\n\nconst listProps = {\n isFetching: PropTypes.bool.description('toggle loading state'),\n hasMoreItems: PropTypes.bool\n .description('wheter or not you have more items that need to be loaded')\n .defaultValue(true),\n fetchData: PropTypes.func.description('callback to fetch new items'),\n children: PropTypes.element.description('row items for infinite loader'),\n height: PropTypes.number.description('infinite loader list height'),\n} as WeakValidationMap<unknown>;\n\nconst InfiniteLoaderWithSchema = describe(InfiniteLoader);\nInfiniteLoaderWithSchema.propTypes = listProps;\nexport { InfiniteLoader, InfiniteLoaderWithSchema };\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -10,11 +10,15 @@ const useMakeMutable = (referenceVar) => {
10
10
  }, [referenceVar]);
11
11
  return mutable;
12
12
  };
13
- function useIntersectionObserver(elementRef, { threshold = 0, root = null, rootMargin = "0%", freezeOnceVisible = false }) {
13
+ function useIntersectionObserver(elementRef, { threshold = 0, root = null, rootMargin = "0%", freezeOnceVisible = false }, onIntersectionCb = (entry) => {
14
+ }) {
15
+ const mutableIntersectionCb = useMakeMutable(onIntersectionCb);
14
16
  const [entry, setEntry] = useState();
15
17
  const frozen = entry?.isIntersecting && freezeOnceVisible;
16
18
  const updateEntry = ([newEntry]) => {
17
19
  setEntry(newEntry);
20
+ if (newEntry.isIntersecting)
21
+ mutableIntersectionCb.current(newEntry);
18
22
  };
19
23
  useEffect(() => {
20
24
  const node = elementRef?.current;
@@ -32,18 +36,18 @@ function useIntersectionObserver(elementRef, { threshold = 0, root = null, rootM
32
36
  const InfiniteLoader = ({ isFetching, fetchData, children, height, hasMoreItems = true }) => {
33
37
  const [viewportHeight, setViewportHeight] = useState(height);
34
38
  const baselineRef = useRef(null);
35
- const entry = useIntersectionObserver(baselineRef, {
39
+ const mutableIsFetching = useMakeMutable(isFetching);
40
+ const mutableFetchData = useMakeMutable(fetchData);
41
+ const onIntersectionCb = React2.useCallback(() => {
42
+ if (hasMoreItems && !mutableIsFetching.current) {
43
+ mutableFetchData.current();
44
+ }
45
+ }, [hasMoreItems, mutableFetchData, mutableIsFetching]);
46
+ useIntersectionObserver(baselineRef, {
36
47
  root: null,
37
48
  rootMargin: "0px",
38
49
  threshold: 0.1
39
- });
40
- const isIntersecting = !!entry?.isIntersecting;
41
- const mutableIsFetching = useMakeMutable(isFetching);
42
- useEffect(() => {
43
- if (hasMoreItems && isIntersecting && !mutableIsFetching.current) {
44
- fetchData();
45
- }
46
- }, [fetchData, isIntersecting, hasMoreItems, mutableIsFetching]);
50
+ }, onIntersectionCb);
47
51
  const handleResize = useCallback(() => {
48
52
  setViewportHeight(window.innerHeight);
49
53
  }, []);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../../src/InfiniteLoader/Infiniteloader.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React, { useEffect, useRef, useCallback, useState, type RefObject, type WeakValidationMap } from 'react';\nimport { PropTypes, describe } from '@elliemae/ds-utilities';\nimport { Grid } from '@elliemae/ds-grid';\nimport { Loader } from './Loader';\n\ninterface Props {\n isFetching: boolean;\n hasMoreItems?: boolean;\n fetchData: () => void;\n children: React.ReactNode;\n height?: number | string;\n}\ntype UseMakeMutable<T = unknown> = (referenceVar: T) => React.MutableRefObject<T>;\nconst useMakeMutable: UseMakeMutable = (referenceVar) => {\n const mutable = useRef(referenceVar);\n useEffect(() => {\n mutable.current = referenceVar;\n }, [referenceVar]);\n return mutable;\n};\n\ninterface Args extends IntersectionObserverInit {\n freezeOnceVisible?: boolean;\n}\n\nfunction useIntersectionObserver(\n elementRef: RefObject<Element>,\n { threshold = 0, root = null, rootMargin = '0%', freezeOnceVisible = false }: Args,\n): IntersectionObserverEntry | undefined {\n const [entry, setEntry] = useState<IntersectionObserverEntry>();\n\n const frozen = entry?.isIntersecting && freezeOnceVisible;\n\n const updateEntry = ([newEntry]: IntersectionObserverEntry[]): void => {\n setEntry(newEntry);\n };\n\n useEffect(() => {\n const node = elementRef?.current; // DOM Ref\n const hasIOSupport = !!window.IntersectionObserver;\n\n if (!hasIOSupport || frozen || !node) return () => {};\n\n const observerParams = { threshold, root, rootMargin };\n const observer = new IntersectionObserver(updateEntry, observerParams);\n\n observer.observe(node);\n\n return () => observer.disconnect();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [elementRef, JSON.stringify(threshold), root, rootMargin, frozen]);\n\n return entry;\n}\n\nconst InfiniteLoader = ({ isFetching, fetchData, children, height, hasMoreItems = true }: Props) => {\n const [viewportHeight, setViewportHeight] = useState<number | undefined | string>(height);\n\n const baselineRef = useRef<HTMLDivElement | null>(null);\n const entry = useIntersectionObserver(baselineRef, {\n root: null,\n rootMargin: '0px',\n threshold: 0.1,\n });\n const isIntersecting = !!entry?.isIntersecting;\n const mutableIsFetching = useMakeMutable(isFetching);\n\n useEffect(() => {\n if (hasMoreItems && isIntersecting && !mutableIsFetching.current) {\n fetchData();\n }\n // we only want to redefine the callback when \"fetchData\" changes\n // we don't need to redefine if isFetching changes, so we use \"mutableIsFetching\"\n }, [fetchData, isIntersecting, hasMoreItems, mutableIsFetching]);\n\n const handleResize = useCallback(() => {\n setViewportHeight(window.innerHeight);\n }, []);\n\n useEffect(() => {\n if (!height) {\n window.addEventListener('resize', handleResize);\n handleResize();\n }\n return () => {\n if (!height) window.removeEventListener('resize', handleResize);\n };\n }, [handleResize, height]);\n\n return (\n <Grid style={{ position: 'relative', overflow: 'hidden', height: viewportHeight }}>\n <Grid style={{ overflow: isFetching ? 'hidden' : 'auto', height: viewportHeight }}>\n {children}\n <div ref={baselineRef} style={{ height: 1 }} />\n </Grid>\n <Loader isOpen={isFetching} />\n </Grid>\n );\n};\n\nconst listProps = {\n isFetching: PropTypes.bool.description('toggle loading state'),\n hasMoreItems: PropTypes.bool\n .description('wheter or not you have more items that need to be loaded')\n .defaultValue(true),\n fetchData: PropTypes.func.description('callback to fetch new items'),\n children: PropTypes.element.description('row items for infinite loader'),\n height: PropTypes.number.description('infinite loader list height'),\n} as WeakValidationMap<unknown>;\n\nconst InfiniteLoaderWithSchema = describe(InfiniteLoader);\nInfiniteLoaderWithSchema.propTypes = listProps;\nexport { InfiniteLoader, InfiniteLoaderWithSchema };\n"],
5
- "mappings": "AAAA;ACAA;AACA;AACA;AACA;AAUA,MAAM,iBAAiC,CAAC,iBAAiB;AACvD,QAAM,UAAU,OAAO,YAAY;AACnC,YAAU,MAAM;AACd,YAAQ,UAAU;AAAA,EACpB,GAAG,CAAC,YAAY,CAAC;AACjB,SAAO;AACT;AAMA,iCACE,YACA,EAAE,YAAY,GAAG,OAAO,MAAM,aAAa,MAAM,oBAAoB,SAC9B;AACvC,QAAM,CAAC,OAAO,YAAY,SAAoC;AAE9D,QAAM,SAAS,OAAO,kBAAkB;AAExC,QAAM,cAAc,CAAC,CAAC,cAAiD;AACrE,aAAS,QAAQ;AAAA,EACnB;AAEA,YAAU,MAAM;AACd,UAAM,OAAO,YAAY;AACzB,UAAM,eAAe,CAAC,CAAC,OAAO;AAE9B,QAAI,CAAC,gBAAgB,UAAU,CAAC;AAAM,aAAO,MAAM;AAAA,MAAC;AAEpD,UAAM,iBAAiB,EAAE,WAAW,MAAM,WAAW;AACrD,UAAM,WAAW,IAAI,qBAAqB,aAAa,cAAc;AAErE,aAAS,QAAQ,IAAI;AAErB,WAAO,MAAM,SAAS,WAAW;AAAA,EAEnC,GAAG,CAAC,YAAY,KAAK,UAAU,SAAS,GAAG,MAAM,YAAY,MAAM,CAAC;AAEpE,SAAO;AACT;AAEA,MAAM,iBAAiB,CAAC,EAAE,YAAY,WAAW,UAAU,QAAQ,eAAe,WAAkB;AAClG,QAAM,CAAC,gBAAgB,qBAAqB,SAAsC,MAAM;AAExF,QAAM,cAAc,OAA8B,IAAI;AACtD,QAAM,QAAQ,wBAAwB,aAAa;AAAA,IACjD,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,EACb,CAAC;AACD,QAAM,iBAAiB,CAAC,CAAC,OAAO;AAChC,QAAM,oBAAoB,eAAe,UAAU;AAEnD,YAAU,MAAM;AACd,QAAI,gBAAgB,kBAAkB,CAAC,kBAAkB,SAAS;AAChE,gBAAU;AAAA,IACZ;AAAA,EAGF,GAAG,CAAC,WAAW,gBAAgB,cAAc,iBAAiB,CAAC;AAE/D,QAAM,eAAe,YAAY,MAAM;AACrC,sBAAkB,OAAO,WAAW;AAAA,EACtC,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,QAAI,CAAC,QAAQ;AACX,aAAO,iBAAiB,UAAU,YAAY;AAC9C,mBAAa;AAAA,IACf;AACA,WAAO,MAAM;AACX,UAAI,CAAC;AAAQ,eAAO,oBAAoB,UAAU,YAAY;AAAA,IAChE;AAAA,EACF,GAAG,CAAC,cAAc,MAAM,CAAC;AAEzB,SACE,qCAAC;AAAA,IAAK,OAAO,EAAE,UAAU,YAAY,UAAU,UAAU,QAAQ,eAAe;AAAA,KAC9E,qCAAC;AAAA,IAAK,OAAO,EAAE,UAAU,aAAa,WAAW,QAAQ,QAAQ,eAAe;AAAA,KAC7E,UACD,qCAAC;AAAA,IAAI,KAAK;AAAA,IAAa,OAAO,EAAE,QAAQ,EAAE;AAAA,GAAG,CAC/C,GACA,qCAAC;AAAA,IAAO,QAAQ;AAAA,GAAY,CAC9B;AAEJ;AAEA,MAAM,YAAY;AAAA,EAChB,YAAY,UAAU,KAAK,YAAY,sBAAsB;AAAA,EAC7D,cAAc,UAAU,KACrB,YAAY,0DAA0D,EACtE,aAAa,IAAI;AAAA,EACpB,WAAW,UAAU,KAAK,YAAY,6BAA6B;AAAA,EACnE,UAAU,UAAU,QAAQ,YAAY,+BAA+B;AAAA,EACvE,QAAQ,UAAU,OAAO,YAAY,6BAA6B;AACpE;AAEA,MAAM,2BAA2B,SAAS,cAAc;AACxD,yBAAyB,YAAY;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React, { useEffect, useRef, useCallback, useState, type RefObject, type WeakValidationMap } from 'react';\nimport { PropTypes, describe } from '@elliemae/ds-utilities';\nimport { Grid } from '@elliemae/ds-grid';\nimport { Loader } from './Loader';\n\ninterface Props {\n isFetching: boolean;\n hasMoreItems?: boolean;\n fetchData: () => void;\n children: React.ReactNode;\n height?: number | string;\n}\n\nconst useMakeMutable = <T,>(referenceVar: T): React.MutableRefObject<T> => {\n const mutable = useRef(referenceVar);\n useEffect(() => {\n mutable.current = referenceVar;\n }, [referenceVar]);\n return mutable;\n};\n\ninterface Args extends IntersectionObserverInit {\n freezeOnceVisible?: boolean;\n}\n\nfunction useIntersectionObserver(\n elementRef: RefObject<Element>,\n { threshold = 0, root = null, rootMargin = '0%', freezeOnceVisible = false }: Args,\n // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars\n onIntersectionCb = (entry: IntersectionObserverEntry): void => {},\n): IntersectionObserverEntry | undefined {\n const mutableIntersectionCb = useMakeMutable(onIntersectionCb);\n const [entry, setEntry] = useState<IntersectionObserverEntry>();\n\n const frozen = entry?.isIntersecting && freezeOnceVisible;\n\n const updateEntry = ([newEntry]: IntersectionObserverEntry[]): void => {\n setEntry(newEntry);\n if (newEntry.isIntersecting) mutableIntersectionCb.current(newEntry);\n };\n\n useEffect(() => {\n const node = elementRef?.current; // DOM Ref\n const hasIOSupport = !!window.IntersectionObserver;\n\n if (!hasIOSupport || frozen || !node) return () => {};\n\n const observerParams = { threshold, root, rootMargin };\n const observer = new IntersectionObserver(updateEntry, observerParams);\n\n observer.observe(node);\n\n return () => observer.disconnect();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [elementRef, JSON.stringify(threshold), root, rootMargin, frozen]);\n\n return entry;\n}\n\nconst InfiniteLoader = ({ isFetching, fetchData, children, height, hasMoreItems = true }: Props) => {\n const [viewportHeight, setViewportHeight] = useState<number | undefined | string>(height);\n\n const baselineRef = useRef<HTMLDivElement | null>(null);\n const mutableIsFetching = useMakeMutable(isFetching);\n const mutableFetchData = useMakeMutable(fetchData);\n const onIntersectionCb = React.useCallback(() => {\n if (hasMoreItems && !mutableIsFetching.current) {\n mutableFetchData.current();\n }\n }, [hasMoreItems, mutableFetchData, mutableIsFetching]);\n useIntersectionObserver(\n baselineRef,\n {\n root: null,\n rootMargin: '0px',\n threshold: 0.1,\n },\n onIntersectionCb,\n );\n\n const handleResize = useCallback(() => {\n setViewportHeight(window.innerHeight);\n }, []);\n\n useEffect(() => {\n if (!height) {\n window.addEventListener('resize', handleResize);\n handleResize();\n }\n return () => {\n if (!height) window.removeEventListener('resize', handleResize);\n };\n }, [handleResize, height]);\n\n return (\n <Grid style={{ position: 'relative', overflow: 'hidden', height: viewportHeight }}>\n <Grid style={{ overflow: isFetching ? 'hidden' : 'auto', height: viewportHeight }}>\n {children}\n <div ref={baselineRef} style={{ height: 1 }} />\n </Grid>\n <Loader isOpen={isFetching} />\n </Grid>\n );\n};\n\nconst listProps = {\n isFetching: PropTypes.bool.description('toggle loading state'),\n hasMoreItems: PropTypes.bool\n .description('wheter or not you have more items that need to be loaded')\n .defaultValue(true),\n fetchData: PropTypes.func.description('callback to fetch new items'),\n children: PropTypes.element.description('row items for infinite loader'),\n height: PropTypes.number.description('infinite loader list height'),\n} as WeakValidationMap<unknown>;\n\nconst InfiniteLoaderWithSchema = describe(InfiniteLoader);\nInfiniteLoaderWithSchema.propTypes = listProps;\nexport { InfiniteLoader, InfiniteLoaderWithSchema };\n"],
5
+ "mappings": "AAAA;ACAA;AACA;AACA;AACA;AAUA,MAAM,iBAAiB,CAAK,iBAA+C;AACzE,QAAM,UAAU,OAAO,YAAY;AACnC,YAAU,MAAM;AACd,YAAQ,UAAU;AAAA,EACpB,GAAG,CAAC,YAAY,CAAC;AACjB,SAAO;AACT;AAMA,iCACE,YACA,EAAE,YAAY,GAAG,OAAO,MAAM,aAAa,MAAM,oBAAoB,SAErE,mBAAmB,CAAC,UAA2C;AAAC,GACzB;AACvC,QAAM,wBAAwB,eAAe,gBAAgB;AAC7D,QAAM,CAAC,OAAO,YAAY,SAAoC;AAE9D,QAAM,SAAS,OAAO,kBAAkB;AAExC,QAAM,cAAc,CAAC,CAAC,cAAiD;AACrE,aAAS,QAAQ;AACjB,QAAI,SAAS;AAAgB,4BAAsB,QAAQ,QAAQ;AAAA,EACrE;AAEA,YAAU,MAAM;AACd,UAAM,OAAO,YAAY;AACzB,UAAM,eAAe,CAAC,CAAC,OAAO;AAE9B,QAAI,CAAC,gBAAgB,UAAU,CAAC;AAAM,aAAO,MAAM;AAAA,MAAC;AAEpD,UAAM,iBAAiB,EAAE,WAAW,MAAM,WAAW;AACrD,UAAM,WAAW,IAAI,qBAAqB,aAAa,cAAc;AAErE,aAAS,QAAQ,IAAI;AAErB,WAAO,MAAM,SAAS,WAAW;AAAA,EAEnC,GAAG,CAAC,YAAY,KAAK,UAAU,SAAS,GAAG,MAAM,YAAY,MAAM,CAAC;AAEpE,SAAO;AACT;AAEA,MAAM,iBAAiB,CAAC,EAAE,YAAY,WAAW,UAAU,QAAQ,eAAe,WAAkB;AAClG,QAAM,CAAC,gBAAgB,qBAAqB,SAAsC,MAAM;AAExF,QAAM,cAAc,OAA8B,IAAI;AACtD,QAAM,oBAAoB,eAAe,UAAU;AACnD,QAAM,mBAAmB,eAAe,SAAS;AACjD,QAAM,mBAAmB,OAAM,YAAY,MAAM;AAC/C,QAAI,gBAAgB,CAAC,kBAAkB,SAAS;AAC9C,uBAAiB,QAAQ;AAAA,IAC3B;AAAA,EACF,GAAG,CAAC,cAAc,kBAAkB,iBAAiB,CAAC;AACtD,0BACE,aACA;AAAA,IACE,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,EACb,GACA,gBACF;AAEA,QAAM,eAAe,YAAY,MAAM;AACrC,sBAAkB,OAAO,WAAW;AAAA,EACtC,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,QAAI,CAAC,QAAQ;AACX,aAAO,iBAAiB,UAAU,YAAY;AAC9C,mBAAa;AAAA,IACf;AACA,WAAO,MAAM;AACX,UAAI,CAAC;AAAQ,eAAO,oBAAoB,UAAU,YAAY;AAAA,IAChE;AAAA,EACF,GAAG,CAAC,cAAc,MAAM,CAAC;AAEzB,SACE,qCAAC;AAAA,IAAK,OAAO,EAAE,UAAU,YAAY,UAAU,UAAU,QAAQ,eAAe;AAAA,KAC9E,qCAAC;AAAA,IAAK,OAAO,EAAE,UAAU,aAAa,WAAW,QAAQ,QAAQ,eAAe;AAAA,KAC7E,UACD,qCAAC;AAAA,IAAI,KAAK;AAAA,IAAa,OAAO,EAAE,QAAQ,EAAE;AAAA,GAAG,CAC/C,GACA,qCAAC;AAAA,IAAO,QAAQ;AAAA,GAAY,CAC9B;AAEJ;AAEA,MAAM,YAAY;AAAA,EAChB,YAAY,UAAU,KAAK,YAAY,sBAAsB;AAAA,EAC7D,cAAc,UAAU,KACrB,YAAY,0DAA0D,EACtE,aAAa,IAAI;AAAA,EACpB,WAAW,UAAU,KAAK,YAAY,6BAA6B;AAAA,EACnE,UAAU,UAAU,QAAQ,YAAY,+BAA+B;AAAA,EACvE,QAAQ,UAAU,OAAO,YAAY,6BAA6B;AACpE;AAEA,MAAM,2BAA2B,SAAS,cAAc;AACxD,yBAAyB,YAAY;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/ds-mobile",
3
- "version": "3.4.0-rc.2",
3
+ "version": "3.4.0-rc.3",
4
4
  "license": "MIT",
5
5
  "description": "ICE MT - Dimsum - System",
6
6
  "files": [
@@ -435,21 +435,21 @@
435
435
  "typeSafety": false
436
436
  },
437
437
  "dependencies": {
438
- "@elliemae/ds-accordion": "3.4.0-rc.2",
439
- "@elliemae/ds-backdrop": "3.4.0-rc.2",
440
- "@elliemae/ds-button": "3.4.0-rc.2",
441
- "@elliemae/ds-circular-progress-indicator": "3.4.0-rc.2",
442
- "@elliemae/ds-form": "3.4.0-rc.2",
443
- "@elliemae/ds-form-checkbox": "3.4.0-rc.2",
444
- "@elliemae/ds-grid": "3.4.0-rc.2",
445
- "@elliemae/ds-icon": "3.4.0-rc.2",
446
- "@elliemae/ds-icons": "3.4.0-rc.2",
447
- "@elliemae/ds-indeterminate-progress-indicator": "3.4.0-rc.2",
448
- "@elliemae/ds-shared": "3.4.0-rc.2",
449
- "@elliemae/ds-system": "3.4.0-rc.2",
450
- "@elliemae/ds-tabs": "3.4.0-rc.2",
451
- "@elliemae/ds-truncated-expandable-text": "3.4.0-rc.2",
452
- "@elliemae/ds-utilities": "3.4.0-rc.2",
438
+ "@elliemae/ds-accordion": "3.4.0-rc.3",
439
+ "@elliemae/ds-backdrop": "3.4.0-rc.3",
440
+ "@elliemae/ds-button": "3.4.0-rc.3",
441
+ "@elliemae/ds-circular-progress-indicator": "3.4.0-rc.3",
442
+ "@elliemae/ds-form": "3.4.0-rc.3",
443
+ "@elliemae/ds-form-checkbox": "3.4.0-rc.3",
444
+ "@elliemae/ds-grid": "3.4.0-rc.3",
445
+ "@elliemae/ds-icon": "3.4.0-rc.3",
446
+ "@elliemae/ds-icons": "3.4.0-rc.3",
447
+ "@elliemae/ds-indeterminate-progress-indicator": "3.4.0-rc.3",
448
+ "@elliemae/ds-shared": "3.4.0-rc.3",
449
+ "@elliemae/ds-system": "3.4.0-rc.3",
450
+ "@elliemae/ds-tabs": "3.4.0-rc.3",
451
+ "@elliemae/ds-truncated-expandable-text": "3.4.0-rc.3",
452
+ "@elliemae/ds-utilities": "3.4.0-rc.3",
453
453
  "polished": "~3.6.7",
454
454
  "prop-types": "~15.8.1",
455
455
  "react-window": "~1.8.7",