@korsolutions/guidon 1.0.18 → 1.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/README.md +63 -0
  2. package/dist/commonjs/hooks/index.js +7 -0
  3. package/dist/commonjs/hooks/index.js.map +1 -1
  4. package/dist/commonjs/hooks/useGuidonScrollContainer.js +60 -0
  5. package/dist/commonjs/hooks/useGuidonScrollContainer.js.map +1 -0
  6. package/dist/commonjs/index.js +6 -0
  7. package/dist/commonjs/index.js.map +1 -1
  8. package/dist/module/hooks/index.js +1 -0
  9. package/dist/module/hooks/index.js.map +1 -1
  10. package/dist/module/hooks/useGuidonScrollContainer.js +57 -0
  11. package/dist/module/hooks/useGuidonScrollContainer.js.map +1 -0
  12. package/dist/module/index.js +1 -1
  13. package/dist/module/index.js.map +1 -1
  14. package/dist/typescript/commonjs/hooks/index.d.ts +1 -0
  15. package/dist/typescript/commonjs/hooks/index.d.ts.map +1 -1
  16. package/dist/typescript/commonjs/hooks/useGuidonScrollContainer.d.ts +41 -0
  17. package/dist/typescript/commonjs/hooks/useGuidonScrollContainer.d.ts.map +1 -0
  18. package/dist/typescript/commonjs/index.d.ts +1 -1
  19. package/dist/typescript/commonjs/index.d.ts.map +1 -1
  20. package/dist/typescript/module/hooks/index.d.ts +1 -0
  21. package/dist/typescript/module/hooks/index.d.ts.map +1 -1
  22. package/dist/typescript/module/hooks/useGuidonScrollContainer.d.ts +41 -0
  23. package/dist/typescript/module/hooks/useGuidonScrollContainer.d.ts.map +1 -0
  24. package/dist/typescript/module/index.d.ts +1 -1
  25. package/dist/typescript/module/index.d.ts.map +1 -1
  26. package/package.json +1 -1
  27. package/src/hooks/index.ts +4 -0
  28. package/src/hooks/useGuidonScrollContainer.ts +80 -0
  29. package/src/index.ts +5 -1
package/README.md CHANGED
@@ -396,6 +396,69 @@ function GuidonStatus() {
396
396
  >
397
397
  ```
398
398
 
399
+ ## Auto-Scroll Behavior
400
+
401
+ ### Web
402
+ On web, targets automatically scroll into view using the native `scrollIntoView()` API. You can customize this via theme:
403
+
404
+ ```tsx
405
+ const config = {
406
+ theme: {
407
+ scrollOptions: {
408
+ behavior: 'smooth', // 'smooth' | 'instant'
409
+ block: 'center', // 'start' | 'center' | 'end' | 'nearest'
410
+ inline: 'nearest', // 'start' | 'center' | 'end' | 'nearest'
411
+ },
412
+ },
413
+ tours: { ... },
414
+ } satisfies GuidonToursConfig;
415
+ ```
416
+
417
+ ### Mobile (React Native)
418
+ For mobile, use the `useGuidonScrollContainer` hook to enable auto-scrolling:
419
+
420
+ ```tsx
421
+ import { useRef } from 'react';
422
+ import { ScrollView } from 'react-native';
423
+ import { useGuidon, useGuidonScrollContainer } from '@korsolutions/guidon';
424
+
425
+ function MyScreen() {
426
+ const scrollRef = useRef<ScrollView>(null);
427
+ const { register } = useGuidon();
428
+
429
+ // Enable auto-scroll when steps change
430
+ useGuidonScrollContainer(scrollRef);
431
+
432
+ return (
433
+ <ScrollView ref={scrollRef}>
434
+ <View ref={register('step-1')}>First target</View>
435
+ <View ref={register('step-2')}>Second target</View>
436
+ </ScrollView>
437
+ );
438
+ }
439
+ ```
440
+
441
+ Options:
442
+ ```tsx
443
+ useGuidonScrollContainer(scrollRef, {
444
+ padding: 150, // Distance from top of viewport (default: 100)
445
+ enabled: false, // Temporarily disable (default: true)
446
+ });
447
+ ```
448
+
449
+ ### Disabling Scroll Per Step
450
+ Disable auto-scroll for individual steps:
451
+
452
+ ```tsx
453
+ {
454
+ id: 'modal-step',
455
+ targetId: 'modal-button',
456
+ title: 'Modal Content',
457
+ description: 'This element is already visible',
458
+ scrollIntoView: false, // Don't scroll for this step
459
+ }
460
+ ```
461
+
399
462
  ## Platform Support
400
463
 
401
464
  - iOS
@@ -9,5 +9,12 @@ Object.defineProperty(exports, "useGuidon", {
9
9
  return _useGuidonRef.useGuidon;
10
10
  }
11
11
  });
12
+ Object.defineProperty(exports, "useGuidonScrollContainer", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _useGuidonScrollContainer.useGuidonScrollContainer;
16
+ }
17
+ });
12
18
  var _useGuidonRef = require("./useGuidonRef.js");
19
+ var _useGuidonScrollContainer = require("./useGuidonScrollContainer.js");
13
20
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_useGuidonRef","require"],"sourceRoot":"../../../src","sources":["hooks/index.ts"],"mappings":";;;;;;;;;;;AAAA,IAAAA,aAAA,GAAAC,OAAA","ignoreList":[]}
1
+ {"version":3,"names":["_useGuidonRef","require","_useGuidonScrollContainer"],"sourceRoot":"../../../src","sources":["hooks/index.ts"],"mappings":";;;;;;;;;;;;;;;;;AAAA,IAAAA,aAAA,GAAAC,OAAA;AACA,IAAAC,yBAAA,GAAAD,OAAA","ignoreList":[]}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useGuidonScrollContainer = useGuidonScrollContainer;
7
+ var _react = require("react");
8
+ var _reactNative = require("react-native");
9
+ var _store = require("../store.js");
10
+ /**
11
+ * Scrollable container interface (ScrollView, FlatList, etc.)
12
+ */
13
+
14
+ /**
15
+ * Hook that registers a ScrollView for auto-scrolling on mobile platforms.
16
+ * When a guidon step changes, automatically scrolls to bring the target into view.
17
+ *
18
+ * @param scrollViewRef - Ref to a ScrollView or FlatList
19
+ * @param options - Configuration options
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * function MyScreen() {
24
+ * const scrollRef = useRef<ScrollView>(null);
25
+ * useGuidonScrollContainer(scrollRef);
26
+ *
27
+ * return (
28
+ * <ScrollView ref={scrollRef}>
29
+ * <View ref={register('step-1')}>...</View>
30
+ * </ScrollView>
31
+ * );
32
+ * }
33
+ * ```
34
+ */
35
+ function useGuidonScrollContainer(scrollViewRef, options) {
36
+ const currentStepIndex = (0, _store.useGuidonStore)(s => s.currentStepIndex);
37
+ const config = (0, _store.useGuidonStore)(s => s.config);
38
+ const isActive = (0, _store.useGuidonStore)(s => s.isActive);
39
+ const targetMeasurements = (0, _store.useGuidonStore)(s => s.targetMeasurements);
40
+ const padding = options?.padding ?? 100;
41
+ const enabled = options?.enabled ?? true;
42
+ (0, _react.useEffect)(() => {
43
+ // Only handle mobile platforms - web uses native scrollIntoView
44
+ if (_reactNative.Platform.OS === "web" || !isActive || !config || !enabled) return;
45
+ const step = config.steps[currentStepIndex];
46
+ if (!step?.targetId || step.scrollIntoView === false) return;
47
+ const measurements = targetMeasurements[step.targetId];
48
+ if (!measurements) return;
49
+
50
+ // Small delay to ensure measurements are settled after step transition
51
+ const timeoutId = setTimeout(() => {
52
+ scrollViewRef.current?.scrollTo?.({
53
+ y: Math.max(0, measurements.y - padding),
54
+ animated: true
55
+ });
56
+ }, 50);
57
+ return () => clearTimeout(timeoutId);
58
+ }, [currentStepIndex, isActive, config, targetMeasurements, scrollViewRef, padding, enabled]);
59
+ }
60
+ //# sourceMappingURL=useGuidonScrollContainer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","require","_reactNative","_store","useGuidonScrollContainer","scrollViewRef","options","currentStepIndex","useGuidonStore","s","config","isActive","targetMeasurements","padding","enabled","useEffect","Platform","OS","step","steps","targetId","scrollIntoView","measurements","timeoutId","setTimeout","current","scrollTo","y","Math","max","animated","clearTimeout"],"sourceRoot":"../../../src","sources":["hooks/useGuidonScrollContainer.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AACA,IAAAE,MAAA,GAAAF,OAAA;AAEA;AACA;AACA;;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASG,wBAAwBA,CACtCC,aAA8C,EAC9CC,OAAyC,EACzC;EACA,MAAMC,gBAAgB,GAAG,IAAAC,qBAAc,EAAEC,CAAC,IAAKA,CAAC,CAACF,gBAAgB,CAAC;EAClE,MAAMG,MAAM,GAAG,IAAAF,qBAAc,EAAEC,CAAC,IAAKA,CAAC,CAACC,MAAM,CAAC;EAC9C,MAAMC,QAAQ,GAAG,IAAAH,qBAAc,EAAEC,CAAC,IAAKA,CAAC,CAACE,QAAQ,CAAC;EAClD,MAAMC,kBAAkB,GAAG,IAAAJ,qBAAc,EAAEC,CAAC,IAAKA,CAAC,CAACG,kBAAkB,CAAC;EAEtE,MAAMC,OAAO,GAAGP,OAAO,EAAEO,OAAO,IAAI,GAAG;EACvC,MAAMC,OAAO,GAAGR,OAAO,EAAEQ,OAAO,IAAI,IAAI;EAExC,IAAAC,gBAAS,EAAC,MAAM;IACd;IACA,IAAIC,qBAAQ,CAACC,EAAE,KAAK,KAAK,IAAI,CAACN,QAAQ,IAAI,CAACD,MAAM,IAAI,CAACI,OAAO,EAAE;IAE/D,MAAMI,IAAI,GAAGR,MAAM,CAACS,KAAK,CAACZ,gBAAgB,CAAC;IAC3C,IAAI,CAACW,IAAI,EAAEE,QAAQ,IAAIF,IAAI,CAACG,cAAc,KAAK,KAAK,EAAE;IAEtD,MAAMC,YAAY,GAAGV,kBAAkB,CAACM,IAAI,CAACE,QAAQ,CAAC;IACtD,IAAI,CAACE,YAAY,EAAE;;IAEnB;IACA,MAAMC,SAAS,GAAGC,UAAU,CAAC,MAAM;MACjCnB,aAAa,CAACoB,OAAO,EAAEC,QAAQ,GAAG;QAChCC,CAAC,EAAEC,IAAI,CAACC,GAAG,CAAC,CAAC,EAAEP,YAAY,CAACK,CAAC,GAAGd,OAAO,CAAC;QACxCiB,QAAQ,EAAE;MACZ,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC;IAEN,OAAO,MAAMC,YAAY,CAACR,SAAS,CAAC;EACtC,CAAC,EAAE,CACDhB,gBAAgB,EAChBI,QAAQ,EACRD,MAAM,EACNE,kBAAkB,EAClBP,aAAa,EACbQ,OAAO,EACPC,OAAO,CACR,CAAC;AACJ","ignoreList":[]}
@@ -99,6 +99,12 @@ Object.defineProperty(exports, "useGuidonProgress", {
99
99
  return _store.useGuidonProgress;
100
100
  }
101
101
  });
102
+ Object.defineProperty(exports, "useGuidonScrollContainer", {
103
+ enumerable: true,
104
+ get: function () {
105
+ return _index2.useGuidonScrollContainer;
106
+ }
107
+ });
102
108
  Object.defineProperty(exports, "useGuidonStep", {
103
109
  enumerable: true,
104
110
  get: function () {
@@ -1 +1 @@
1
- {"version":3,"names":["_index","require","_index2","_store","_adapters","_hooks"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,IAAAA,MAAA,GAAAC,OAAA;AASA,IAAAC,OAAA,GAAAD,OAAA;AAGA,IAAAE,MAAA,GAAAF,OAAA;AAmCA,IAAAG,SAAA,GAAAH,OAAA;AASA,IAAAI,MAAA,GAAAJ,OAAA","ignoreList":[]}
1
+ {"version":3,"names":["_index","require","_index2","_store","_adapters","_hooks"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,IAAAA,MAAA,GAAAC,OAAA;AASA,IAAAC,OAAA,GAAAD,OAAA;AAOA,IAAAE,MAAA,GAAAF,OAAA;AAmCA,IAAAG,SAAA,GAAAH,OAAA;AASA,IAAAI,MAAA,GAAAJ,OAAA","ignoreList":[]}
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
2
 
3
3
  export { useGuidon } from "./useGuidonRef.js";
4
+ export { useGuidonScrollContainer } from "./useGuidonScrollContainer.js";
4
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["useGuidon"],"sourceRoot":"../../../src","sources":["hooks/index.ts"],"mappings":";;AAAA,SAASA,SAAS,QAAQ,mBAAgB","ignoreList":[]}
1
+ {"version":3,"names":["useGuidon","useGuidonScrollContainer"],"sourceRoot":"../../../src","sources":["hooks/index.ts"],"mappings":";;AAAA,SAASA,SAAS,QAAQ,mBAAgB;AAC1C,SACEC,wBAAwB,QAEnB,+BAA4B","ignoreList":[]}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+
3
+ import { useEffect } from "react";
4
+ import { Platform } from "react-native";
5
+ import { useGuidonStore } from "../store.js";
6
+
7
+ /**
8
+ * Scrollable container interface (ScrollView, FlatList, etc.)
9
+ */
10
+
11
+ /**
12
+ * Hook that registers a ScrollView for auto-scrolling on mobile platforms.
13
+ * When a guidon step changes, automatically scrolls to bring the target into view.
14
+ *
15
+ * @param scrollViewRef - Ref to a ScrollView or FlatList
16
+ * @param options - Configuration options
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * function MyScreen() {
21
+ * const scrollRef = useRef<ScrollView>(null);
22
+ * useGuidonScrollContainer(scrollRef);
23
+ *
24
+ * return (
25
+ * <ScrollView ref={scrollRef}>
26
+ * <View ref={register('step-1')}>...</View>
27
+ * </ScrollView>
28
+ * );
29
+ * }
30
+ * ```
31
+ */
32
+ export function useGuidonScrollContainer(scrollViewRef, options) {
33
+ const currentStepIndex = useGuidonStore(s => s.currentStepIndex);
34
+ const config = useGuidonStore(s => s.config);
35
+ const isActive = useGuidonStore(s => s.isActive);
36
+ const targetMeasurements = useGuidonStore(s => s.targetMeasurements);
37
+ const padding = options?.padding ?? 100;
38
+ const enabled = options?.enabled ?? true;
39
+ useEffect(() => {
40
+ // Only handle mobile platforms - web uses native scrollIntoView
41
+ if (Platform.OS === "web" || !isActive || !config || !enabled) return;
42
+ const step = config.steps[currentStepIndex];
43
+ if (!step?.targetId || step.scrollIntoView === false) return;
44
+ const measurements = targetMeasurements[step.targetId];
45
+ if (!measurements) return;
46
+
47
+ // Small delay to ensure measurements are settled after step transition
48
+ const timeoutId = setTimeout(() => {
49
+ scrollViewRef.current?.scrollTo?.({
50
+ y: Math.max(0, measurements.y - padding),
51
+ animated: true
52
+ });
53
+ }, 50);
54
+ return () => clearTimeout(timeoutId);
55
+ }, [currentStepIndex, isActive, config, targetMeasurements, scrollViewRef, padding, enabled]);
56
+ }
57
+ //# sourceMappingURL=useGuidonScrollContainer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useEffect","Platform","useGuidonStore","useGuidonScrollContainer","scrollViewRef","options","currentStepIndex","s","config","isActive","targetMeasurements","padding","enabled","OS","step","steps","targetId","scrollIntoView","measurements","timeoutId","setTimeout","current","scrollTo","y","Math","max","animated","clearTimeout"],"sourceRoot":"../../../src","sources":["hooks/useGuidonScrollContainer.ts"],"mappings":";;AAAA,SAASA,SAAS,QAAwB,OAAO;AACjD,SAASC,QAAQ,QAAQ,cAAc;AACvC,SAASC,cAAc,QAAQ,aAAU;;AAEzC;AACA;AACA;;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,wBAAwBA,CACtCC,aAA8C,EAC9CC,OAAyC,EACzC;EACA,MAAMC,gBAAgB,GAAGJ,cAAc,CAAEK,CAAC,IAAKA,CAAC,CAACD,gBAAgB,CAAC;EAClE,MAAME,MAAM,GAAGN,cAAc,CAAEK,CAAC,IAAKA,CAAC,CAACC,MAAM,CAAC;EAC9C,MAAMC,QAAQ,GAAGP,cAAc,CAAEK,CAAC,IAAKA,CAAC,CAACE,QAAQ,CAAC;EAClD,MAAMC,kBAAkB,GAAGR,cAAc,CAAEK,CAAC,IAAKA,CAAC,CAACG,kBAAkB,CAAC;EAEtE,MAAMC,OAAO,GAAGN,OAAO,EAAEM,OAAO,IAAI,GAAG;EACvC,MAAMC,OAAO,GAAGP,OAAO,EAAEO,OAAO,IAAI,IAAI;EAExCZ,SAAS,CAAC,MAAM;IACd;IACA,IAAIC,QAAQ,CAACY,EAAE,KAAK,KAAK,IAAI,CAACJ,QAAQ,IAAI,CAACD,MAAM,IAAI,CAACI,OAAO,EAAE;IAE/D,MAAME,IAAI,GAAGN,MAAM,CAACO,KAAK,CAACT,gBAAgB,CAAC;IAC3C,IAAI,CAACQ,IAAI,EAAEE,QAAQ,IAAIF,IAAI,CAACG,cAAc,KAAK,KAAK,EAAE;IAEtD,MAAMC,YAAY,GAAGR,kBAAkB,CAACI,IAAI,CAACE,QAAQ,CAAC;IACtD,IAAI,CAACE,YAAY,EAAE;;IAEnB;IACA,MAAMC,SAAS,GAAGC,UAAU,CAAC,MAAM;MACjChB,aAAa,CAACiB,OAAO,EAAEC,QAAQ,GAAG;QAChCC,CAAC,EAAEC,IAAI,CAACC,GAAG,CAAC,CAAC,EAAEP,YAAY,CAACK,CAAC,GAAGZ,OAAO,CAAC;QACxCe,QAAQ,EAAE;MACZ,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC;IAEN,OAAO,MAAMC,YAAY,CAACR,SAAS,CAAC;EACtC,CAAC,EAAE,CACDb,gBAAgB,EAChBG,QAAQ,EACRD,MAAM,EACNE,kBAAkB,EAClBN,aAAa,EACbO,OAAO,EACPC,OAAO,CACR,CAAC;AACJ","ignoreList":[]}
@@ -4,7 +4,7 @@
4
4
  export { GuidonTarget, GuidonOverlay, GuidonTooltip, GuidonProvider, useGuidonContext } from "./components/index.js";
5
5
 
6
6
  // Hooks
7
- export { useGuidon } from "./hooks/index.js";
7
+ export { useGuidon, useGuidonScrollContainer } from "./hooks/index.js";
8
8
 
9
9
  // Store and API
10
10
  export { useGuidonStore, Guidon, useGuidonActive, useGuidonStep, useGuidonProgress, useTargetMeasurements, useWaitingState, useIsFloatingStep } from "./store.js";
@@ -1 +1 @@
1
- {"version":3,"names":["GuidonTarget","GuidonOverlay","GuidonTooltip","GuidonProvider","useGuidonContext","useGuidon","useGuidonStore","Guidon","useGuidonActive","useGuidonStep","useGuidonProgress","useTargetMeasurements","useWaitingState","useIsFloatingStep","createNoopAdapter","createMemoryAdapter","createLocalStorageAdapter","createAsyncStorageAdapter","createApiAdapter","createCompositeAdapter","useGuidonPersistence","useShouldShowGuidon"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA;AACA,SACEA,YAAY,EACZC,aAAa,EACbC,aAAa,EACbC,cAAc,EACdC,gBAAgB,QACX,uBAAc;;AAErB;AACA,SAASC,SAAS,QAAQ,kBAAS;;AAEnC;AACA,SACEC,cAAc,EACdC,MAAM,EACNC,eAAe,EACfC,aAAa,EACbC,iBAAiB,EACjBC,qBAAqB,EACrBC,eAAe,EACfC,iBAAiB,QACZ,YAAS;;AAEhB;;AAuBA;AACA,SACEC,iBAAiB,EACjBC,mBAAmB,EACnBC,yBAAyB,EACzBC,yBAAyB,EACzBC,gBAAgB,EAChBC,sBAAsB,QACjB,2BAAwB;AAE/B,SAASC,oBAAoB,EAAEC,mBAAmB,QAAQ,wBAAqB","ignoreList":[]}
1
+ {"version":3,"names":["GuidonTarget","GuidonOverlay","GuidonTooltip","GuidonProvider","useGuidonContext","useGuidon","useGuidonScrollContainer","useGuidonStore","Guidon","useGuidonActive","useGuidonStep","useGuidonProgress","useTargetMeasurements","useWaitingState","useIsFloatingStep","createNoopAdapter","createMemoryAdapter","createLocalStorageAdapter","createAsyncStorageAdapter","createApiAdapter","createCompositeAdapter","useGuidonPersistence","useShouldShowGuidon"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA;AACA,SACEA,YAAY,EACZC,aAAa,EACbC,aAAa,EACbC,cAAc,EACdC,gBAAgB,QACX,uBAAc;;AAErB;AACA,SACEC,SAAS,EACTC,wBAAwB,QAEnB,kBAAS;;AAEhB;AACA,SACEC,cAAc,EACdC,MAAM,EACNC,eAAe,EACfC,aAAa,EACbC,iBAAiB,EACjBC,qBAAqB,EACrBC,eAAe,EACfC,iBAAiB,QACZ,YAAS;;AAEhB;;AAuBA;AACA,SACEC,iBAAiB,EACjBC,mBAAmB,EACnBC,yBAAyB,EACzBC,yBAAyB,EACzBC,gBAAgB,EAChBC,sBAAsB,QACjB,2BAAwB;AAE/B,SAASC,oBAAoB,EAAEC,mBAAmB,QAAQ,wBAAqB","ignoreList":[]}
@@ -1,2 +1,3 @@
1
1
  export { useGuidon } from "./useGuidonRef";
2
+ export { useGuidonScrollContainer, type UseGuidonScrollContainerOptions, } from "./useGuidonScrollContainer";
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EACL,wBAAwB,EACxB,KAAK,+BAA+B,GACrC,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { type RefObject } from "react";
2
+ /**
3
+ * Scrollable container interface (ScrollView, FlatList, etc.)
4
+ */
5
+ type ScrollableRef = {
6
+ scrollTo?: (options: {
7
+ x?: number;
8
+ y: number;
9
+ animated?: boolean;
10
+ }) => void;
11
+ };
12
+ export interface UseGuidonScrollContainerOptions {
13
+ /** Padding from the top when scrolling to target (default: 100) */
14
+ padding?: number;
15
+ /** Whether scrolling is enabled (default: true) */
16
+ enabled?: boolean;
17
+ }
18
+ /**
19
+ * Hook that registers a ScrollView for auto-scrolling on mobile platforms.
20
+ * When a guidon step changes, automatically scrolls to bring the target into view.
21
+ *
22
+ * @param scrollViewRef - Ref to a ScrollView or FlatList
23
+ * @param options - Configuration options
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * function MyScreen() {
28
+ * const scrollRef = useRef<ScrollView>(null);
29
+ * useGuidonScrollContainer(scrollRef);
30
+ *
31
+ * return (
32
+ * <ScrollView ref={scrollRef}>
33
+ * <View ref={register('step-1')}>...</View>
34
+ * </ScrollView>
35
+ * );
36
+ * }
37
+ * ```
38
+ */
39
+ export declare function useGuidonScrollContainer(scrollViewRef: RefObject<ScrollableRef | null>, options?: UseGuidonScrollContainerOptions): void;
40
+ export {};
41
+ //# sourceMappingURL=useGuidonScrollContainer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGuidonScrollContainer.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useGuidonScrollContainer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIlD;;GAEG;AACH,KAAK,aAAa,GAAG;IACnB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC7E,CAAC;AAEF,MAAM,WAAW,+BAA+B;IAC9C,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,SAAS,CAAC,aAAa,GAAG,IAAI,CAAC,EAC9C,OAAO,CAAC,EAAE,+BAA+B,QAsC1C"}
@@ -1,5 +1,5 @@
1
1
  export { GuidonTarget, GuidonOverlay, GuidonTooltip, GuidonProvider, useGuidonContext, } from "./components";
2
- export { useGuidon } from "./hooks";
2
+ export { useGuidon, useGuidonScrollContainer, type UseGuidonScrollContainerOptions, } from "./hooks";
3
3
  export { useGuidonStore, Guidon, useGuidonActive, useGuidonStep, useGuidonProgress, useTargetMeasurements, useWaitingState, useIsFloatingStep, } from "./store";
4
4
  export type { GuidonStep, GuidonConfig, GuidonTours, GuidonToursConfig, GuidonTourDefinition, GuidonTheme, GuidonScrollOptions, GuidonProgress, GuidonPersistenceAdapter, GuidonProviderProps, GuidonTargetProps, GuidonTooltipLabels, GuidonTooltipRenderProps, TooltipPosition, FloatingPosition, TargetMeasurements, GuidonState, GuidonActions, GuidonStore, } from "./types";
5
5
  export { createNoopAdapter, createMemoryAdapter, createLocalStorageAdapter, createAsyncStorageAdapter, createApiAdapter, createCompositeAdapter, } from "./persistence/adapters";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGpC,OAAO,EACL,cAAc,EACd,MAAM,EACN,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,UAAU,EACV,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,wBAAwB,EACxB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,WAAW,GACZ,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,SAAS,EACT,wBAAwB,EACxB,KAAK,+BAA+B,GACrC,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,cAAc,EACd,MAAM,EACN,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,UAAU,EACV,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,wBAAwB,EACxB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,WAAW,GACZ,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -1,2 +1,3 @@
1
1
  export { useGuidon } from "./useGuidonRef";
2
+ export { useGuidonScrollContainer, type UseGuidonScrollContainerOptions, } from "./useGuidonScrollContainer";
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EACL,wBAAwB,EACxB,KAAK,+BAA+B,GACrC,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { type RefObject } from "react";
2
+ /**
3
+ * Scrollable container interface (ScrollView, FlatList, etc.)
4
+ */
5
+ type ScrollableRef = {
6
+ scrollTo?: (options: {
7
+ x?: number;
8
+ y: number;
9
+ animated?: boolean;
10
+ }) => void;
11
+ };
12
+ export interface UseGuidonScrollContainerOptions {
13
+ /** Padding from the top when scrolling to target (default: 100) */
14
+ padding?: number;
15
+ /** Whether scrolling is enabled (default: true) */
16
+ enabled?: boolean;
17
+ }
18
+ /**
19
+ * Hook that registers a ScrollView for auto-scrolling on mobile platforms.
20
+ * When a guidon step changes, automatically scrolls to bring the target into view.
21
+ *
22
+ * @param scrollViewRef - Ref to a ScrollView or FlatList
23
+ * @param options - Configuration options
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * function MyScreen() {
28
+ * const scrollRef = useRef<ScrollView>(null);
29
+ * useGuidonScrollContainer(scrollRef);
30
+ *
31
+ * return (
32
+ * <ScrollView ref={scrollRef}>
33
+ * <View ref={register('step-1')}>...</View>
34
+ * </ScrollView>
35
+ * );
36
+ * }
37
+ * ```
38
+ */
39
+ export declare function useGuidonScrollContainer(scrollViewRef: RefObject<ScrollableRef | null>, options?: UseGuidonScrollContainerOptions): void;
40
+ export {};
41
+ //# sourceMappingURL=useGuidonScrollContainer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGuidonScrollContainer.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useGuidonScrollContainer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIlD;;GAEG;AACH,KAAK,aAAa,GAAG;IACnB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC7E,CAAC;AAEF,MAAM,WAAW,+BAA+B;IAC9C,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,SAAS,CAAC,aAAa,GAAG,IAAI,CAAC,EAC9C,OAAO,CAAC,EAAE,+BAA+B,QAsC1C"}
@@ -1,5 +1,5 @@
1
1
  export { GuidonTarget, GuidonOverlay, GuidonTooltip, GuidonProvider, useGuidonContext, } from "./components";
2
- export { useGuidon } from "./hooks";
2
+ export { useGuidon, useGuidonScrollContainer, type UseGuidonScrollContainerOptions, } from "./hooks";
3
3
  export { useGuidonStore, Guidon, useGuidonActive, useGuidonStep, useGuidonProgress, useTargetMeasurements, useWaitingState, useIsFloatingStep, } from "./store";
4
4
  export type { GuidonStep, GuidonConfig, GuidonTours, GuidonToursConfig, GuidonTourDefinition, GuidonTheme, GuidonScrollOptions, GuidonProgress, GuidonPersistenceAdapter, GuidonProviderProps, GuidonTargetProps, GuidonTooltipLabels, GuidonTooltipRenderProps, TooltipPosition, FloatingPosition, TargetMeasurements, GuidonState, GuidonActions, GuidonStore, } from "./types";
5
5
  export { createNoopAdapter, createMemoryAdapter, createLocalStorageAdapter, createAsyncStorageAdapter, createApiAdapter, createCompositeAdapter, } from "./persistence/adapters";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGpC,OAAO,EACL,cAAc,EACd,MAAM,EACN,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,UAAU,EACV,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,wBAAwB,EACxB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,WAAW,GACZ,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,SAAS,EACT,wBAAwB,EACxB,KAAK,+BAA+B,GACrC,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,cAAc,EACd,MAAM,EACN,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,UAAU,EACV,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,wBAAwB,EACxB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,WAAW,GACZ,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@korsolutions/guidon",
3
- "version": "1.0.18",
3
+ "version": "1.0.20",
4
4
  "description": "A cross-platform walkthrough/onboarding component library for React Native with web support. Features spotlight effects, customizable tooltips, and flexible persistence options. ",
5
5
  "repository": "https://github.com/KorSoftwareSolutions/guidon.git",
6
6
  "author": "Christian Jimenez <christianjimenezfael@gmail.com>",
@@ -1 +1,5 @@
1
1
  export { useGuidon } from "./useGuidonRef";
2
+ export {
3
+ useGuidonScrollContainer,
4
+ type UseGuidonScrollContainerOptions,
5
+ } from "./useGuidonScrollContainer";
@@ -0,0 +1,80 @@
1
+ import { useEffect, type RefObject } from "react";
2
+ import { Platform } from "react-native";
3
+ import { useGuidonStore } from "../store";
4
+
5
+ /**
6
+ * Scrollable container interface (ScrollView, FlatList, etc.)
7
+ */
8
+ type ScrollableRef = {
9
+ scrollTo?: (options: { x?: number; y: number; animated?: boolean }) => void;
10
+ };
11
+
12
+ export interface UseGuidonScrollContainerOptions {
13
+ /** Padding from the top when scrolling to target (default: 100) */
14
+ padding?: number;
15
+ /** Whether scrolling is enabled (default: true) */
16
+ enabled?: boolean;
17
+ }
18
+
19
+ /**
20
+ * Hook that registers a ScrollView for auto-scrolling on mobile platforms.
21
+ * When a guidon step changes, automatically scrolls to bring the target into view.
22
+ *
23
+ * @param scrollViewRef - Ref to a ScrollView or FlatList
24
+ * @param options - Configuration options
25
+ *
26
+ * @example
27
+ * ```tsx
28
+ * function MyScreen() {
29
+ * const scrollRef = useRef<ScrollView>(null);
30
+ * useGuidonScrollContainer(scrollRef);
31
+ *
32
+ * return (
33
+ * <ScrollView ref={scrollRef}>
34
+ * <View ref={register('step-1')}>...</View>
35
+ * </ScrollView>
36
+ * );
37
+ * }
38
+ * ```
39
+ */
40
+ export function useGuidonScrollContainer(
41
+ scrollViewRef: RefObject<ScrollableRef | null>,
42
+ options?: UseGuidonScrollContainerOptions,
43
+ ) {
44
+ const currentStepIndex = useGuidonStore((s) => s.currentStepIndex);
45
+ const config = useGuidonStore((s) => s.config);
46
+ const isActive = useGuidonStore((s) => s.isActive);
47
+ const targetMeasurements = useGuidonStore((s) => s.targetMeasurements);
48
+
49
+ const padding = options?.padding ?? 100;
50
+ const enabled = options?.enabled ?? true;
51
+
52
+ useEffect(() => {
53
+ // Only handle mobile platforms - web uses native scrollIntoView
54
+ if (Platform.OS === "web" || !isActive || !config || !enabled) return;
55
+
56
+ const step = config.steps[currentStepIndex];
57
+ if (!step?.targetId || step.scrollIntoView === false) return;
58
+
59
+ const measurements = targetMeasurements[step.targetId];
60
+ if (!measurements) return;
61
+
62
+ // Small delay to ensure measurements are settled after step transition
63
+ const timeoutId = setTimeout(() => {
64
+ scrollViewRef.current?.scrollTo?.({
65
+ y: Math.max(0, measurements.y - padding),
66
+ animated: true,
67
+ });
68
+ }, 50);
69
+
70
+ return () => clearTimeout(timeoutId);
71
+ }, [
72
+ currentStepIndex,
73
+ isActive,
74
+ config,
75
+ targetMeasurements,
76
+ scrollViewRef,
77
+ padding,
78
+ enabled,
79
+ ]);
80
+ }
package/src/index.ts CHANGED
@@ -8,7 +8,11 @@ export {
8
8
  } from "./components";
9
9
 
10
10
  // Hooks
11
- export { useGuidon } from "./hooks";
11
+ export {
12
+ useGuidon,
13
+ useGuidonScrollContainer,
14
+ type UseGuidonScrollContainerOptions,
15
+ } from "./hooks";
12
16
 
13
17
  // Store and API
14
18
  export {