@impulse-ui-native/scroll-view 9.1.1 → 10.0.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.
@@ -1,4 +1,4 @@
1
1
  export { useScrollViewInitialScroll } from './use-scroll-view-initial-scroll.hook.mjs';
2
2
  import 'react-native';
3
- import 'react';
4
3
  import '../types/use-scroll-view-initial-scroll.types.mjs';
4
+ import 'react';
@@ -1,14 +1,7 @@
1
- import { ScrollView, View, LayoutChangeEvent, NativeSyntheticEvent, NativeScrollEvent } from 'react-native';
2
- import * as react from 'react';
3
- import { UseScrollViewInitialScrollOptions } from '../types/use-scroll-view-initial-scroll.types.mjs';
1
+ import 'react-native';
2
+ import { UseScrollViewInitialScrollOptions, UseScrollViewInitialScrollResult } from '../types/use-scroll-view-initial-scroll.types.mjs';
3
+ import 'react';
4
4
 
5
- declare function useScrollViewInitialScroll({ enabled, horizontal, contentOffset, onLayout, onContentSizeChange, onScrollBeginDrag, }?: UseScrollViewInitialScrollOptions): {
6
- scrollViewRef: react.RefObject<ScrollView | null>;
7
- targetRef: react.RefObject<View | null>;
8
- onTargetLayout: () => void;
9
- onLayout: (event: LayoutChangeEvent) => void;
10
- onContentSizeChange: (width: number, height: number) => void;
11
- onScrollBeginDrag: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
12
- };
5
+ declare function useScrollViewInitialScroll({ enabled, horizontal, contentOffset, onLayout, onContentSizeChange, onScrollBeginDrag, }?: UseScrollViewInitialScrollOptions): UseScrollViewInitialScrollResult;
13
6
 
14
7
  export { useScrollViewInitialScroll };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hooks/use-scroll-view-initial-scroll.hook.ts"],"sourcesContent":["import type {\n LayoutChangeEvent,\n NativeScrollEvent,\n NativeSyntheticEvent,\n ScrollView,\n View,\n} from \"react-native\";\nimport { useRef } from \"react\";\n\nimport { useEventCallback } from \"@impulse-ui-native/core\";\n\nimport type { UseScrollViewInitialScrollOptions } from \"../types\";\nimport type { ScrollViewMeasurement } from \"../types/scroll-view-measurement.types\";\nimport { getScrollViewRevealOffset } from \"../utils/get-scroll-view-reveal-offset\";\n\nexport function useScrollViewInitialScroll({\n enabled = true,\n horizontal = false,\n contentOffset,\n onLayout,\n onContentSizeChange,\n onScrollBeginDrag,\n}: UseScrollViewInitialScrollOptions = {}) {\n const scrollViewRef = useRef<ScrollView>(null);\n const targetRef = useRef<View>(null);\n const viewportSizeRef = useRef(0);\n const contentSizeRef = useRef(0);\n const completedRef = useRef(false);\n const measuringRef = useRef(false);\n\n const handleMeasurement = useEventCallback(\n ({ scrollView, target, layout }: ScrollViewMeasurement) => {\n measuringRef.current = false;\n\n if (!enabled || contentOffset || completedRef.current) {\n return;\n }\n\n if (\n scrollViewRef.current !== scrollView ||\n targetRef.current !== target\n ) {\n return;\n }\n\n const targetSize = horizontal ? layout.width : layout.height;\n\n if (targetSize <= 0) {\n return;\n }\n\n const offset = getScrollViewRevealOffset({\n layout,\n viewportSize: viewportSizeRef.current,\n contentSize: contentSizeRef.current,\n horizontal: Boolean(horizontal),\n });\n\n completedRef.current = true;\n\n if (offset !== null) {\n scrollView.scrollTo(\n horizontal\n ? { x: offset, animated: false }\n : { y: offset, animated: false },\n );\n }\n },\n );\n\n const handleMeasurementFailure = useEventCallback(() => {\n measuringRef.current = false;\n });\n\n const revealTarget = useEventCallback(() => {\n const scrollView = scrollViewRef.current;\n const target = targetRef.current;\n\n if (\n !enabled ||\n contentOffset ||\n completedRef.current ||\n measuringRef.current\n ) {\n return;\n }\n\n if (\n !scrollView ||\n !target ||\n viewportSizeRef.current <= 0 ||\n contentSizeRef.current <= 0\n ) {\n return;\n }\n\n const nativeScrollView = scrollView.getNativeScrollRef();\n\n if (nativeScrollView == null) {\n return;\n }\n\n measuringRef.current = true;\n target.measureLayout(\n nativeScrollView,\n (x, y, width, height) => {\n handleMeasurement({\n scrollView,\n target,\n layout: { x, y, width, height },\n });\n },\n handleMeasurementFailure,\n );\n });\n\n const handleLayout = useEventCallback((event: LayoutChangeEvent) => {\n viewportSizeRef.current = horizontal\n ? event.nativeEvent.layout.width\n : event.nativeEvent.layout.height;\n\n revealTarget();\n onLayout?.(event);\n });\n\n const handleContentSizeChange = useEventCallback(\n (width: number, height: number) => {\n contentSizeRef.current = horizontal ? width : height;\n\n revealTarget();\n onContentSizeChange?.(width, height);\n },\n );\n\n const handleScrollBeginDrag = useEventCallback(\n (event: NativeSyntheticEvent<NativeScrollEvent>) => {\n completedRef.current = true;\n\n onScrollBeginDrag?.(event);\n },\n );\n\n return {\n scrollViewRef,\n targetRef,\n onTargetLayout: revealTarget,\n onLayout: handleLayout,\n onContentSizeChange: handleContentSizeChange,\n onScrollBeginDrag: handleScrollBeginDrag,\n };\n}\n"],"mappings":"AAOA,SAAS,cAAc;AAEvB,SAAS,wBAAwB;AAIjC,SAAS,iCAAiC;AAEnC,SAAS,2BAA2B;AAAA,EACzC,UAAU;AAAA,EACV,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,IAAuC,CAAC,GAAG;AACzC,QAAM,gBAAgB,OAAmB,IAAI;AAC7C,QAAM,YAAY,OAAa,IAAI;AACnC,QAAM,kBAAkB,OAAO,CAAC;AAChC,QAAM,iBAAiB,OAAO,CAAC;AAC/B,QAAM,eAAe,OAAO,KAAK;AACjC,QAAM,eAAe,OAAO,KAAK;AAEjC,QAAM,oBAAoB;AAAA,IACxB,CAAC,EAAE,YAAY,QAAQ,OAAO,MAA6B;AACzD,mBAAa,UAAU;AAEvB,UAAI,CAAC,WAAW,iBAAiB,aAAa,SAAS;AACrD;AAAA,MACF;AAEA,UACE,cAAc,YAAY,cAC1B,UAAU,YAAY,QACtB;AACA;AAAA,MACF;AAEA,YAAM,aAAa,aAAa,OAAO,QAAQ,OAAO;AAEtD,UAAI,cAAc,GAAG;AACnB;AAAA,MACF;AAEA,YAAM,SAAS,0BAA0B;AAAA,QACvC;AAAA,QACA,cAAc,gBAAgB;AAAA,QAC9B,aAAa,eAAe;AAAA,QAC5B,YAAY,QAAQ,UAAU;AAAA,MAChC,CAAC;AAED,mBAAa,UAAU;AAEvB,UAAI,WAAW,MAAM;AACnB,mBAAW;AAAA,UACT,aACI,EAAE,GAAG,QAAQ,UAAU,MAAM,IAC7B,EAAE,GAAG,QAAQ,UAAU,MAAM;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,2BAA2B,iBAAiB,MAAM;AACtD,iBAAa,UAAU;AAAA,EACzB,CAAC;AAED,QAAM,eAAe,iBAAiB,MAAM;AAC1C,UAAM,aAAa,cAAc;AACjC,UAAM,SAAS,UAAU;AAEzB,QACE,CAAC,WACD,iBACA,aAAa,WACb,aAAa,SACb;AACA;AAAA,IACF;AAEA,QACE,CAAC,cACD,CAAC,UACD,gBAAgB,WAAW,KAC3B,eAAe,WAAW,GAC1B;AACA;AAAA,IACF;AAEA,UAAM,mBAAmB,WAAW,mBAAmB;AAEvD,QAAI,oBAAoB,MAAM;AAC5B;AAAA,IACF;AAEA,iBAAa,UAAU;AACvB,WAAO;AAAA,MACL;AAAA,MACA,CAAC,GAAG,GAAG,OAAO,WAAW;AACvB,0BAAkB;AAAA,UAChB;AAAA,UACA;AAAA,UACA,QAAQ,EAAE,GAAG,GAAG,OAAO,OAAO;AAAA,QAChC,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,eAAe,iBAAiB,CAAC,UAA6B;AAClE,oBAAgB,UAAU,aACtB,MAAM,YAAY,OAAO,QACzB,MAAM,YAAY,OAAO;AAE7B,iBAAa;AACb,eAAW,KAAK;AAAA,EAClB,CAAC;AAED,QAAM,0BAA0B;AAAA,IAC9B,CAAC,OAAe,WAAmB;AACjC,qBAAe,UAAU,aAAa,QAAQ;AAE9C,mBAAa;AACb,4BAAsB,OAAO,MAAM;AAAA,IACrC;AAAA,EACF;AAEA,QAAM,wBAAwB;AAAA,IAC5B,CAAC,UAAmD;AAClD,mBAAa,UAAU;AAEvB,0BAAoB,KAAK;AAAA,IAC3B;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,qBAAqB;AAAA,IACrB,mBAAmB;AAAA,EACrB;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/hooks/use-scroll-view-initial-scroll.hook.ts"],"sourcesContent":["import type { ComponentRef } from \"react\";\nimport type {\n LayoutChangeEvent,\n NativeScrollEvent,\n NativeSyntheticEvent,\n ScrollView,\n View,\n} from \"react-native\";\nimport { useRef } from \"react\";\n\nimport { useEventCallback } from \"@impulse-ui-native/core\";\n\nimport type {\n UseScrollViewInitialScrollOptions,\n UseScrollViewInitialScrollResult,\n} from \"../types\";\nimport type { ScrollViewMeasurement } from \"../types/scroll-view-measurement.types\";\nimport { getScrollViewRevealOffset } from \"../utils/get-scroll-view-reveal-offset\";\n\nexport function useScrollViewInitialScroll({\n enabled = true,\n horizontal = false,\n contentOffset,\n onLayout,\n onContentSizeChange,\n onScrollBeginDrag,\n}: UseScrollViewInitialScrollOptions = {}): UseScrollViewInitialScrollResult {\n const scrollViewRef = useRef<ComponentRef<typeof ScrollView>>(null);\n const targetRef = useRef<ComponentRef<typeof View>>(null);\n const viewportSizeRef = useRef(0);\n const contentSizeRef = useRef(0);\n const completedRef = useRef(false);\n const measuringRef = useRef(false);\n\n const handleMeasurement = useEventCallback(\n ({ scrollView, target, layout }: ScrollViewMeasurement) => {\n measuringRef.current = false;\n\n if (!enabled || contentOffset || completedRef.current) {\n return;\n }\n\n if (\n scrollViewRef.current !== scrollView ||\n targetRef.current !== target\n ) {\n return;\n }\n\n const targetSize = horizontal ? layout.width : layout.height;\n\n if (targetSize <= 0) {\n return;\n }\n\n const offset = getScrollViewRevealOffset({\n layout,\n viewportSize: viewportSizeRef.current,\n contentSize: contentSizeRef.current,\n horizontal: Boolean(horizontal),\n });\n\n completedRef.current = true;\n\n if (offset !== null) {\n scrollView.scrollTo(\n horizontal\n ? { x: offset, animated: false }\n : { y: offset, animated: false },\n );\n }\n },\n );\n\n const handleMeasurementFailure = useEventCallback(() => {\n measuringRef.current = false;\n });\n\n const revealTarget = useEventCallback(() => {\n const scrollView = scrollViewRef.current;\n const target = targetRef.current;\n\n if (\n !enabled ||\n contentOffset ||\n completedRef.current ||\n measuringRef.current\n ) {\n return;\n }\n\n if (\n !scrollView ||\n !target ||\n viewportSizeRef.current <= 0 ||\n contentSizeRef.current <= 0\n ) {\n return;\n }\n\n const nativeScrollView = scrollView.getNativeScrollRef();\n\n if (nativeScrollView == null) {\n return;\n }\n\n measuringRef.current = true;\n target.measureLayout(\n nativeScrollView,\n (x, y, width, height) => {\n handleMeasurement({\n scrollView,\n target,\n layout: { x, y, width, height },\n });\n },\n handleMeasurementFailure,\n );\n });\n\n const handleLayout = useEventCallback((event: LayoutChangeEvent) => {\n viewportSizeRef.current = horizontal\n ? event.nativeEvent.layout.width\n : event.nativeEvent.layout.height;\n\n revealTarget();\n onLayout?.(event);\n });\n\n const handleContentSizeChange = useEventCallback(\n (width: number, height: number) => {\n contentSizeRef.current = horizontal ? width : height;\n\n revealTarget();\n onContentSizeChange?.(width, height);\n },\n );\n\n const handleScrollBeginDrag = useEventCallback(\n (event: NativeSyntheticEvent<NativeScrollEvent>) => {\n completedRef.current = true;\n\n onScrollBeginDrag?.(event);\n },\n );\n\n return {\n scrollViewRef,\n targetRef,\n onTargetLayout: revealTarget,\n onLayout: handleLayout,\n onContentSizeChange: handleContentSizeChange,\n onScrollBeginDrag: handleScrollBeginDrag,\n };\n}\n"],"mappings":"AAQA,SAAS,cAAc;AAEvB,SAAS,wBAAwB;AAOjC,SAAS,iCAAiC;AAEnC,SAAS,2BAA2B;AAAA,EACzC,UAAU;AAAA,EACV,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,IAAuC,CAAC,GAAqC;AAC3E,QAAM,gBAAgB,OAAwC,IAAI;AAClE,QAAM,YAAY,OAAkC,IAAI;AACxD,QAAM,kBAAkB,OAAO,CAAC;AAChC,QAAM,iBAAiB,OAAO,CAAC;AAC/B,QAAM,eAAe,OAAO,KAAK;AACjC,QAAM,eAAe,OAAO,KAAK;AAEjC,QAAM,oBAAoB;AAAA,IACxB,CAAC,EAAE,YAAY,QAAQ,OAAO,MAA6B;AACzD,mBAAa,UAAU;AAEvB,UAAI,CAAC,WAAW,iBAAiB,aAAa,SAAS;AACrD;AAAA,MACF;AAEA,UACE,cAAc,YAAY,cAC1B,UAAU,YAAY,QACtB;AACA;AAAA,MACF;AAEA,YAAM,aAAa,aAAa,OAAO,QAAQ,OAAO;AAEtD,UAAI,cAAc,GAAG;AACnB;AAAA,MACF;AAEA,YAAM,SAAS,0BAA0B;AAAA,QACvC;AAAA,QACA,cAAc,gBAAgB;AAAA,QAC9B,aAAa,eAAe;AAAA,QAC5B,YAAY,QAAQ,UAAU;AAAA,MAChC,CAAC;AAED,mBAAa,UAAU;AAEvB,UAAI,WAAW,MAAM;AACnB,mBAAW;AAAA,UACT,aACI,EAAE,GAAG,QAAQ,UAAU,MAAM,IAC7B,EAAE,GAAG,QAAQ,UAAU,MAAM;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,2BAA2B,iBAAiB,MAAM;AACtD,iBAAa,UAAU;AAAA,EACzB,CAAC;AAED,QAAM,eAAe,iBAAiB,MAAM;AAC1C,UAAM,aAAa,cAAc;AACjC,UAAM,SAAS,UAAU;AAEzB,QACE,CAAC,WACD,iBACA,aAAa,WACb,aAAa,SACb;AACA;AAAA,IACF;AAEA,QACE,CAAC,cACD,CAAC,UACD,gBAAgB,WAAW,KAC3B,eAAe,WAAW,GAC1B;AACA;AAAA,IACF;AAEA,UAAM,mBAAmB,WAAW,mBAAmB;AAEvD,QAAI,oBAAoB,MAAM;AAC5B;AAAA,IACF;AAEA,iBAAa,UAAU;AACvB,WAAO;AAAA,MACL;AAAA,MACA,CAAC,GAAG,GAAG,OAAO,WAAW;AACvB,0BAAkB;AAAA,UAChB;AAAA,UACA;AAAA,UACA,QAAQ,EAAE,GAAG,GAAG,OAAO,OAAO;AAAA,QAChC,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,eAAe,iBAAiB,CAAC,UAA6B;AAClE,oBAAgB,UAAU,aACtB,MAAM,YAAY,OAAO,QACzB,MAAM,YAAY,OAAO;AAE7B,iBAAa;AACb,eAAW,KAAK;AAAA,EAClB,CAAC;AAED,QAAM,0BAA0B;AAAA,IAC9B,CAAC,OAAe,WAAmB;AACjC,qBAAe,UAAU,aAAa,QAAQ;AAE9C,mBAAa;AACb,4BAAsB,OAAO,MAAM;AAAA,IACrC;AAAA,EACF;AAEA,QAAM,wBAAwB;AAAA,IAC5B,CAAC,UAAmD;AAClD,mBAAa,UAAU;AAEvB,0BAAoB,KAAK;AAAA,IAC3B;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,qBAAqB;AAAA,IACrB,mBAAmB;AAAA,EACrB;AACF;","names":[]}
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { ScrollView, ScrollViewProps } from 'react-native';
2
2
  export { useScrollViewInitialScroll } from './hooks/use-scroll-view-initial-scroll.hook.mjs';
3
- export { UseScrollViewInitialScrollOptions } from './types/use-scroll-view-initial-scroll.types.mjs';
3
+ export { UseScrollViewInitialScrollOptions, UseScrollViewInitialScrollResult } from './types/use-scroll-view-initial-scroll.types.mjs';
4
4
  import 'react';
@@ -1,2 +1,3 @@
1
1
  export { ScrollViewProps } from 'react-native';
2
- export { UseScrollViewInitialScrollOptions } from './use-scroll-view-initial-scroll.types.mjs';
2
+ export { UseScrollViewInitialScrollOptions, UseScrollViewInitialScrollResult } from './use-scroll-view-initial-scroll.types.mjs';
3
+ import 'react';
@@ -1,8 +1,9 @@
1
+ import { ComponentRef } from 'react';
1
2
  import { ScrollView, View, LayoutRectangle } from 'react-native';
2
3
 
3
4
  interface ScrollViewMeasurement {
4
- scrollView: ScrollView;
5
- target: View;
5
+ scrollView: ComponentRef<typeof ScrollView>;
6
+ target: ComponentRef<typeof View>;
6
7
  layout: LayoutRectangle;
7
8
  }
8
9
  interface ScrollViewRevealOptions {
@@ -1,8 +1,17 @@
1
- import { ScrollViewProps } from 'react-native';
1
+ import { ScrollViewProps, ScrollView, View } from 'react-native';
2
+ import { RefObject, ComponentRef } from 'react';
2
3
 
4
+ interface UseScrollViewInitialScrollResult {
5
+ scrollViewRef: RefObject<ComponentRef<typeof ScrollView> | null>;
6
+ targetRef: RefObject<ComponentRef<typeof View> | null>;
7
+ onTargetLayout: () => void;
8
+ onLayout: NonNullable<ScrollViewProps["onLayout"]>;
9
+ onContentSizeChange: NonNullable<ScrollViewProps["onContentSizeChange"]>;
10
+ onScrollBeginDrag: NonNullable<ScrollViewProps["onScrollBeginDrag"]>;
11
+ }
3
12
  interface UseScrollViewInitialScrollOptions extends Pick<ScrollViewProps, "horizontal" | "contentOffset" | "onLayout" | "onContentSizeChange" | "onScrollBeginDrag"> {
4
13
  /** Reveal the target once per mount. Explicit contentOffset takes precedence. */
5
14
  enabled?: boolean;
6
15
  }
7
16
 
8
- export type { UseScrollViewInitialScrollOptions };
17
+ export type { UseScrollViewInitialScrollOptions, UseScrollViewInitialScrollResult };
@@ -1,4 +1,5 @@
1
1
  import { ScrollViewRevealOptions } from '../types/scroll-view-measurement.types.mjs';
2
+ import 'react';
2
3
  import 'react-native';
3
4
 
4
5
  /** Returns null when the target is already visible at the native initial offset. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@impulse-ui-native/scroll-view",
3
- "version": "9.1.1",
3
+ "version": "10.0.0",
4
4
  "description": "Native ScrollView and a small hook to reveal an initially selected child.",
5
5
  "keywords": [
6
6
  "react-native",
@@ -11,11 +11,11 @@
11
11
  "source": "src/index.ts",
12
12
  "module": "dist/index.js",
13
13
  "types": "dist/index.d.mts",
14
- "react-native": "src/index.ts",
14
+ "react-native": "dist/index.js",
15
15
  "exports": {
16
16
  ".": {
17
17
  "types": "./dist/index.d.mts",
18
- "react-native": "./src/index.ts",
18
+ "react-native": "./dist/index.js",
19
19
  "import": "./dist/index.js"
20
20
  }
21
21
  },
@@ -26,11 +26,11 @@
26
26
  ],
27
27
  "sideEffects": false,
28
28
  "devDependencies": {
29
- "@types/react": "~19.2.14",
29
+ "@types/react": "~19.3.0",
30
30
  "eslint": "^9.38.0",
31
31
  "prettier": "^3.6.2",
32
- "react": "19.2.3",
33
- "react-native": "0.86.2",
32
+ "react": "19.3.0",
33
+ "react-native": "0.88.0",
34
34
  "typescript": "~6.0.3",
35
35
  "@impulse-ui-native/eslint-config": "1.0.0",
36
36
  "@impulse-ui-native/prettier-config": "1.0.0",
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "prettier": "@impulse-ui-native/prettier-config",
47
47
  "dependencies": {
48
- "@impulse-ui-native/core": "9.1.1"
48
+ "@impulse-ui-native/core": "10.0.0"
49
49
  },
50
50
  "scripts": {
51
51
  "build": "tsup --config tsup.config.ts",