react-native-keyboard-controller 1.3.0 → 1.4.1

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 (48) hide show
  1. package/android/src/main/java/com/reactnativekeyboardcontroller/KeyboardAnimationCallback.kt +8 -4
  2. package/android/src/main/java/com/reactnativekeyboardcontroller/KeyboardControllerViewManagerImpl.kt +6 -3
  3. package/android/src/main/java/com/reactnativekeyboardcontroller/events/KeyboardTransitionEvent.kt +2 -6
  4. package/ios/.swiftlint.yml +4 -0
  5. package/ios/KeyboardControllerView.mm +24 -6
  6. package/ios/KeyboardControllerViewManager.mm +2 -0
  7. package/ios/KeyboardControllerViewManager.swift +4 -1
  8. package/ios/KeyboardMoveEvent.h +1 -0
  9. package/ios/KeyboardMoveEvent.m +2 -1
  10. package/ios/KeyboardMovementObserver.swift +89 -4
  11. package/lib/commonjs/animated.js +32 -6
  12. package/lib/commonjs/animated.js.map +1 -1
  13. package/lib/commonjs/context.js +2 -1
  14. package/lib/commonjs/context.js.map +1 -1
  15. package/lib/commonjs/hooks.js +26 -1
  16. package/lib/commonjs/hooks.js.map +1 -1
  17. package/lib/commonjs/internal.js +66 -2
  18. package/lib/commonjs/internal.js.map +1 -1
  19. package/lib/commonjs/specs/KeyboardControllerViewNativeComponent.js.map +1 -1
  20. package/lib/commonjs/types.js.map +1 -1
  21. package/lib/commonjs/utils.js +11 -0
  22. package/lib/commonjs/utils.js.map +1 -0
  23. package/lib/module/animated.js +34 -8
  24. package/lib/module/animated.js.map +1 -1
  25. package/lib/module/context.js +2 -1
  26. package/lib/module/context.js.map +1 -1
  27. package/lib/module/hooks.js +19 -0
  28. package/lib/module/hooks.js.map +1 -1
  29. package/lib/module/internal.js +64 -3
  30. package/lib/module/internal.js.map +1 -1
  31. package/lib/module/specs/KeyboardControllerViewNativeComponent.js.map +1 -1
  32. package/lib/module/types.js.map +1 -1
  33. package/lib/module/utils.js +2 -0
  34. package/lib/module/utils.js.map +1 -0
  35. package/lib/typescript/context.d.ts +3 -1
  36. package/lib/typescript/hooks.d.ts +4 -0
  37. package/lib/typescript/internal.d.ts +18 -1
  38. package/lib/typescript/specs/KeyboardControllerViewNativeComponent.d.ts +2 -0
  39. package/lib/typescript/types.d.ts +10 -1
  40. package/lib/typescript/utils.d.ts +1 -0
  41. package/package.json +1 -1
  42. package/src/animated.tsx +34 -7
  43. package/src/context.ts +4 -1
  44. package/src/hooks.ts +29 -1
  45. package/src/internal.ts +64 -4
  46. package/src/specs/KeyboardControllerViewNativeComponent.ts +4 -0
  47. package/src/types.ts +19 -1
  48. package/src/utils.ts +1 -0
package/src/internal.ts CHANGED
@@ -1,12 +1,15 @@
1
- import { useEvent, useHandler } from 'react-native-reanimated';
1
+ import { useCallback, useRef } from 'react';
2
+ import { useEvent, useHandler, useSharedValue } from 'react-native-reanimated';
2
3
 
3
- import type { EventWithName, NativeEvent } from './types';
4
+ import type { EventWithName, Handlers, NativeEvent } from './types';
4
5
 
5
6
  export function useAnimatedKeyboardHandler<
6
7
  TContext extends Record<string, unknown>
7
8
  >(
8
9
  handlers: {
10
+ onKeyboardMoveStart?: (e: NativeEvent, context: TContext) => void;
9
11
  onKeyboardMove?: (e: NativeEvent, context: TContext) => void;
12
+ onKeyboardMoveEnd?: (e: NativeEvent, context: TContext) => void;
10
13
  },
11
14
  dependencies?: ReadonlyArray<unknown>
12
15
  ) {
@@ -15,13 +18,70 @@ export function useAnimatedKeyboardHandler<
15
18
  return useEvent(
16
19
  (event: EventWithName<NativeEvent>) => {
17
20
  'worklet';
18
- const { onKeyboardMove } = handlers;
21
+ const { onKeyboardMoveStart, onKeyboardMove, onKeyboardMoveEnd } =
22
+ handlers;
23
+
24
+ if (
25
+ onKeyboardMoveStart &&
26
+ event.eventName.endsWith('onKeyboardMoveStart')
27
+ ) {
28
+ onKeyboardMoveStart(event, context);
29
+ }
19
30
 
20
31
  if (onKeyboardMove && event.eventName.endsWith('onKeyboardMove')) {
21
32
  onKeyboardMove(event, context);
22
33
  }
34
+
35
+ if (onKeyboardMoveEnd && event.eventName.endsWith('onKeyboardMoveEnd')) {
36
+ onKeyboardMoveEnd(event, context);
37
+ }
23
38
  },
24
- ['onKeyboardMove'],
39
+ ['onKeyboardMoveStart', 'onKeyboardMove', 'onKeyboardMoveEnd'],
25
40
  doDependenciesDiffer
26
41
  );
27
42
  }
43
+
44
+ /**
45
+ * Hook for storing worklet handlers (objects with keys, where values are worklets).
46
+ * Returns methods for setting handlers and broadcasting events in them.
47
+ *
48
+ * T is a generic that looks like:
49
+ * @example
50
+ * {
51
+ * onEvent: () => {},
52
+ * onEvent2: () => {},
53
+ * }
54
+ */
55
+ export function useSharedHandlers<T extends Record<string, Function>>() {
56
+ const handlers = useSharedValue<Handlers<T>>({});
57
+ const jsHandlers = useRef<Handlers<T>>({});
58
+
59
+ // since js -> worklet -> js call is asynchronous, we can not write handlers
60
+ // straight into shared variable (using current shared value as a previous result),
61
+ // since there may be a race condition in a call, and closure may have out-of-dated
62
+ // values. As a result, some of handlers may be not written to "all handlers" object.
63
+ // Below we are writing all handlers to `ref` and afterwards synchronize them with
64
+ // shared value (since `refs` are not referring to actual value in worklets).
65
+ // This approach allow us to update synchronously handlers in js thread (and it assures,
66
+ // that it will have all of them) and then update them in worklet thread (calls are
67
+ // happening in FIFO order, so we will always have actual value).
68
+ const updateSharedHandlers = () => {
69
+ handlers.value = jsHandlers.current;
70
+ };
71
+ const setHandlers = useCallback((handler: Handlers<T>) => {
72
+ jsHandlers.current = {
73
+ ...jsHandlers.current,
74
+ ...handler,
75
+ };
76
+ updateSharedHandlers();
77
+ }, []);
78
+ const broadcast = (type: keyof T, event: NativeEvent) => {
79
+ 'worklet';
80
+
81
+ Object.keys(handlers.value).forEach((key) =>
82
+ handlers.value[key]?.[type]?.(event)
83
+ );
84
+ };
85
+
86
+ return { setHandlers, broadcast };
87
+ }
@@ -14,8 +14,12 @@ type KeyboardMoveEvent = Readonly<{
14
14
  }>;
15
15
 
16
16
  export interface NativeProps extends ViewProps {
17
+ // props
17
18
  statusBarTranslucent?: boolean;
19
+ // callbacks
18
20
  onKeyboardMove?: DirectEventHandler<KeyboardMoveEvent>;
21
+ onKeyboardMoveStart?: DirectEventHandler<KeyboardMoveEvent>;
22
+ onKeyboardMoveEnd?: DirectEventHandler<KeyboardMoveEvent>;
19
23
  }
20
24
 
21
25
  export default codegenNativeComponent<NativeProps>(
package/src/types.ts CHANGED
@@ -13,7 +13,15 @@ export type EventWithName<T> = {
13
13
  // native View/Module declarations
14
14
 
15
15
  export type KeyboardControllerProps = {
16
- onKeyboardMove: (e: NativeSyntheticEvent<EventWithName<NativeEvent>>) => void;
16
+ onKeyboardMoveStart?: (
17
+ e: NativeSyntheticEvent<EventWithName<NativeEvent>>
18
+ ) => void;
19
+ onKeyboardMove?: (
20
+ e: NativeSyntheticEvent<EventWithName<NativeEvent>>
21
+ ) => void;
22
+ onKeyboardMoveEnd?: (
23
+ e: NativeSyntheticEvent<EventWithName<NativeEvent>>
24
+ ) => void;
17
25
  // fake prop used to activate reanimated bindings
18
26
  onKeyboardMoveReanimated: (
19
27
  e: NativeSyntheticEvent<EventWithName<NativeEvent>>
@@ -40,3 +48,13 @@ export type KeyboardControllerEvents =
40
48
  export type KeyboardEventData = {
41
49
  height: number;
42
50
  };
51
+
52
+ // package types
53
+
54
+ export type Handlers<T> = Record<string, T | undefined>;
55
+ export type KeyboardHandler = {
56
+ onStart?: (e: NativeEvent) => void;
57
+ onMove?: (e: NativeEvent) => void;
58
+ onEnd?: (e: NativeEvent) => void;
59
+ };
60
+ export type KeyboardHandlers = Handlers<KeyboardHandler>;
package/src/utils.ts ADDED
@@ -0,0 +1 @@
1
+ export const uuid = () => Math.random().toString(36).slice(-6);