react-native-keyboard-controller 1.21.4 → 1.21.6
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/android/src/main/java/com/reactnativekeyboardcontroller/extensions/ReactContext.kt +10 -0
- package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/View.kt +0 -40
- package/android/src/main/java/com/reactnativekeyboardcontroller/modules/KeyboardControllerModuleImpl.kt +3 -11
- package/android/src/main/java/com/reactnativekeyboardcontroller/views/ClippingScrollViewDecoratorView.kt +1 -1
- package/android/src/main/java/com/reactnativekeyboardcontroller/views/EdgeToEdgeReactViewGroup.kt +19 -22
- package/lib/commonjs/components/KeyboardChatScrollView/index.js +3 -2
- package/lib/commonjs/components/KeyboardChatScrollView/index.js.map +1 -1
- package/lib/commonjs/components/KeyboardChatScrollView/types.js.map +1 -1
- package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js +3 -3
- package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js.map +1 -1
- package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.js +4 -4
- package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.js.map +1 -1
- package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/types.js.map +1 -1
- package/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js +2 -2
- package/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js.map +1 -1
- package/lib/commonjs/components/KeyboardToolbar/index.js +12 -3
- package/lib/commonjs/components/KeyboardToolbar/index.js.map +1 -1
- package/lib/commonjs/components/ScrollViewWithBottomPadding/index.js +1 -10
- package/lib/commonjs/components/ScrollViewWithBottomPadding/index.js.map +1 -1
- package/lib/commonjs/hooks/useKeyboardState/index.js +1 -7
- package/lib/commonjs/hooks/useKeyboardState/index.js.map +1 -1
- package/lib/commonjs/module.js +1 -1
- package/lib/commonjs/module.js.map +1 -1
- package/lib/module/components/KeyboardChatScrollView/index.js +3 -2
- package/lib/module/components/KeyboardChatScrollView/index.js.map +1 -1
- package/lib/module/components/KeyboardChatScrollView/types.js.map +1 -1
- package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js +3 -3
- package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js.map +1 -1
- package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.js +4 -4
- package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.js.map +1 -1
- package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/types.js.map +1 -1
- package/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js +2 -2
- package/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js.map +1 -1
- package/lib/module/components/KeyboardToolbar/index.js +12 -3
- package/lib/module/components/KeyboardToolbar/index.js.map +1 -1
- package/lib/module/components/ScrollViewWithBottomPadding/index.js +2 -11
- package/lib/module/components/ScrollViewWithBottomPadding/index.js.map +1 -1
- package/lib/module/hooks/useKeyboardState/index.js +1 -7
- package/lib/module/hooks/useKeyboardState/index.js.map +1 -1
- package/lib/module/module.js +1 -1
- package/lib/module/module.js.map +1 -1
- package/lib/typescript/components/KeyboardChatScrollView/index.d.ts +1 -1
- package/lib/typescript/components/KeyboardChatScrollView/types.d.ts +1 -1
- package/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/types.d.ts +1 -1
- package/lib/typescript/components/KeyboardChatScrollView/useExtraContentPadding/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/KeyboardChatScrollView/index.tsx +5 -2
- package/src/components/KeyboardChatScrollView/types.ts +1 -1
- package/src/components/KeyboardChatScrollView/useChatKeyboard/index.ios.ts +3 -3
- package/src/components/KeyboardChatScrollView/useChatKeyboard/index.ts +4 -4
- package/src/components/KeyboardChatScrollView/useChatKeyboard/types.ts +1 -1
- package/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts +3 -3
- package/src/components/KeyboardToolbar/index.tsx +13 -4
- package/src/components/ScrollViewWithBottomPadding/index.tsx +2 -12
- package/src/hooks/useKeyboardState/index.ts +1 -8
- package/src/module.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["scrollTo","useSharedValue","useKeyboardHandler","useScrollState","clampedScrollTarget","getEffectiveHeight","getMinimumPaddingAbsorbed","getScrollEffective","getVisibleMinimumPaddingFraction","isScrollAtEnd","shouldShiftContent","useChatKeyboard","scrollViewRef","options","inverted","keyboardLiftBehavior","freeze","offset","blankSpace","extraContentPadding","padding","currentHeight","offsetBeforeScroll","targetKeyboardHeight","closing","minimumPaddingFractionOnOpen","actualOpenShift","layout","size","scroll","onLayout","onContentSizeChange","clampScrollIfNeeded","effective","totalPaddingForMaxScroll","paddingForMax","undefined","maxScroll","Math","max","value","height","onStart","e","atEnd","visibleFraction","minimumPaddingAbsorbed","scrollEffective","duration","onMove","actualTotalPadding","wasAtEnd","currentShift","target","keepAt","min","onEnd","contentOffsetY"],"sources":["index.ts"],"sourcesContent":["import { scrollTo, useSharedValue } from \"react-native-reanimated\";\n\nimport { useKeyboardHandler } from \"../../../hooks\";\nimport useScrollState from \"../../hooks/useScrollState\";\n\nimport {\n clampedScrollTarget,\n getEffectiveHeight,\n getMinimumPaddingAbsorbed,\n getScrollEffective,\n getVisibleMinimumPaddingFraction,\n isScrollAtEnd,\n shouldShiftContent,\n} from \"./helpers\";\n\nimport type { UseChatKeyboardOptions, UseChatKeyboardReturn } from \"./types\";\nimport type { AnimatedRef } from \"react-native-reanimated\";\nimport type Reanimated from \"react-native-reanimated\";\n\n/**\n * Hook that manages keyboard-driven scrolling for chat-style scroll views.\n * Calculates padding (extra scrollable space) and content shift values,\n * using per-frame scrollTo updates (Android and other platforms).\n *\n * @param scrollViewRef - Animated ref to the scroll view.\n * @param options - Configuration for inverted and keyboardLiftBehavior.\n * @returns Shared values for padding and contentOffsetY (always `undefined`).\n * @example\n * ```tsx\n * const { padding } = useChatKeyboard(ref, { inverted: false, keyboardLiftBehavior: \"always\" });\n * ```\n */\nfunction useChatKeyboard(\n scrollViewRef: AnimatedRef<Reanimated.ScrollView>,\n options: UseChatKeyboardOptions,\n): UseChatKeyboardReturn {\n const {\n inverted,\n keyboardLiftBehavior,\n freeze,\n offset,\n blankSpace,\n extraContentPadding,\n } = options;\n\n const padding = useSharedValue(0);\n const currentHeight = useSharedValue(0);\n const offsetBeforeScroll = useSharedValue(0);\n const targetKeyboardHeight = useSharedValue(0);\n const closing = useSharedValue(false);\n const minimumPaddingFractionOnOpen = useSharedValue(0);\n const actualOpenShift = useSharedValue(0);\n const {\n layout,\n size,\n offset: scroll,\n onLayout,\n onContentSizeChange,\n } = useScrollState(scrollViewRef);\n const clampScrollIfNeeded = (\n effective: number,\n totalPaddingForMaxScroll?: number,\n ) => {\n \"worklet\";\n\n const paddingForMax =\n totalPaddingForMaxScroll !== undefined\n ? totalPaddingForMaxScroll\n : effective;\n const maxScroll = Math.max(\n size.value.height - layout.value.height + paddingForMax,\n 0,\n );\n\n if (scroll.value > maxScroll) {\n scrollTo(scrollViewRef, 0, maxScroll, false);\n }\n };\n\n useKeyboardHandler(\n {\n onStart: (e) => {\n \"worklet\";\n\n if (freeze) {\n return;\n }\n\n if (e.height > 0) {\n // eslint-disable-next-line react-compiler/react-compiler\n targetKeyboardHeight.value = e.height;\n closing.value = false;\n } else {\n closing.value = true;\n }\n\n const effective = getEffectiveHeight(\n e.height,\n targetKeyboardHeight.value,\n offset,\n );\n\n const atEnd = isScrollAtEnd(\n scroll.value,\n layout.value.height,\n size.value.height,\n inverted,\n );\n\n // Scale minimum padding absorption by how much of it is visible.\n // Fully visible → full absorption; fully off-screen → no absorption.\n const visibleFraction = getVisibleMinimumPaddingFraction(\n scroll.value,\n layout.value.height,\n size.value.height,\n blankSpace.value,\n inverted,\n );\n const minimumPaddingAbsorbed =\n visibleFraction >= 1\n ? getMinimumPaddingAbsorbed(\n blankSpace.value,\n extraContentPadding.value,\n )\n : 0;\n const scrollEffective = getScrollEffective(\n effective,\n minimumPaddingAbsorbed,\n );\n\n if (inverted && e.duration === -1) {\n // Android inverted: skip post-interactive snap-back events\n // (duration === -1 means the keyboard is re-establishing its\n // position after an interactive gesture, not a real animation)\n return;\n } else if (e.height > 0) {\n // Android: keyboard opening — set padding + capture scroll position\n minimumPaddingFractionOnOpen.value = visibleFraction >= 1 ? 1 : 0;\n padding.value = effective;\n offsetBeforeScroll.value = scroll.value;\n\n if (!inverted && keyboardLiftBehavior === \"whenAtEnd\" && !atEnd) {\n // Sentinel: don't scroll in onMove (non-inverted only)\n offsetBeforeScroll.value = -1;\n } else if (!inverted && scrollEffective === 0) {\n // blankSpace fully absorbs the keyboard — prevent scroll\n offsetBeforeScroll.value = -1;\n } else if (inverted && scrollEffective === 0) {\n // blankSpace fully absorbs the keyboard — guard for inverted\n offsetBeforeScroll.value = scroll.value;\n }\n } else {\n // Android: keyboard closing — re-capture scroll position\n if (inverted) {\n offsetBeforeScroll.value = scroll.value;\n } else {\n // Preserve \"whenAtEnd\" sentinel: if open didn't shift, close shouldn't either\n if (offsetBeforeScroll.value !== -1) {\n // Use the actual displacement recorded at end of open animation\n // (not the theoretical value) so close is symmetric with open\n offsetBeforeScroll.value = scroll.value - actualOpenShift.value;\n }\n }\n }\n },\n onMove: (e) => {\n \"worklet\";\n\n if (freeze) {\n return;\n }\n\n currentHeight.value = e.height;\n\n if (inverted) {\n // Skip post-interactive snap-back (duration === -1)\n if (e.duration === -1) {\n return;\n }\n\n const effective = getEffectiveHeight(\n e.height,\n targetKeyboardHeight.value,\n offset,\n );\n\n const minimumPaddingAbsorbed =\n getMinimumPaddingAbsorbed(\n blankSpace.value,\n extraContentPadding.value,\n ) * minimumPaddingFractionOnOpen.value;\n const scrollEffective = getScrollEffective(\n effective,\n minimumPaddingAbsorbed,\n );\n const actualTotalPadding = Math.max(\n blankSpace.value,\n effective + extraContentPadding.value,\n );\n\n // Check if we should shift content based on position when keyboard started\n const wasAtEnd = isScrollAtEnd(\n offsetBeforeScroll.value,\n layout.value.height,\n size.value.height,\n inverted,\n );\n\n // \"never\" at end: scroll along when keyboard closes to avoid jump\n if (\n keyboardLiftBehavior === \"never\" &&\n wasAtEnd &&\n effective < padding.value\n ) {\n padding.value = effective;\n\n if (scrollEffective === 0 && minimumPaddingAbsorbed > 0) {\n return;\n }\n\n scrollTo(scrollViewRef, 0, 0, false);\n\n return;\n }\n\n if (!shouldShiftContent(keyboardLiftBehavior, wasAtEnd)) {\n // Closing, not shifting: reduce padding to avoid gap\n if (closing.value && effective < padding.value) {\n padding.value = effective;\n clampScrollIfNeeded(effective, actualTotalPadding);\n }\n\n return;\n }\n\n // When blankSpace fully absorbs the keyboard, skip scroll\n if (scrollEffective === 0 && minimumPaddingAbsorbed > 0) {\n return;\n }\n\n // Persistent: don't let shift decrease\n if (keyboardLiftBehavior === \"persistent\") {\n const currentShift =\n offsetBeforeScroll.value + padding.value - scroll.value;\n\n if (effective < currentShift) {\n // When at end, allow scrolling back (snap to end + reduce padding)\n if (wasAtEnd) {\n padding.value = effective;\n scrollTo(scrollViewRef, 0, 0, false);\n } else if (closing.value) {\n // Not at end: reduce padding to avoid gap\n padding.value = effective;\n clampScrollIfNeeded(effective, actualTotalPadding);\n }\n\n return;\n }\n }\n\n const target =\n offsetBeforeScroll.value + padding.value - scrollEffective;\n\n scrollTo(scrollViewRef, 0, target, false);\n } else {\n const effective = getEffectiveHeight(\n e.height,\n targetKeyboardHeight.value,\n offset,\n );\n\n const minimumPaddingAbsorbed =\n getMinimumPaddingAbsorbed(\n blankSpace.value,\n extraContentPadding.value,\n ) * minimumPaddingFractionOnOpen.value;\n const scrollEffective = getScrollEffective(\n effective,\n minimumPaddingAbsorbed,\n );\n const actualTotalPadding = Math.max(\n blankSpace.value,\n effective + extraContentPadding.value,\n );\n\n // \"never\" closing: clamp scroll to valid range as inset shrinks\n if (\n keyboardLiftBehavior === \"never\" &&\n closing.value &&\n effective < padding.value\n ) {\n clampScrollIfNeeded(effective, actualTotalPadding);\n\n return;\n }\n\n if (!shouldShiftContent(keyboardLiftBehavior, true)) {\n return;\n }\n\n // \"whenAtEnd\" sentinel check (also used for blankSpace full absorption)\n if (offsetBeforeScroll.value === -1) {\n if (closing.value) {\n // Keyboard didn't shift on open; ensure valid position on close\n clampScrollIfNeeded(effective, actualTotalPadding);\n }\n\n return;\n }\n\n // \"persistent\" closing: maintain position, clamped to valid range\n if (keyboardLiftBehavior === \"persistent\" && closing.value) {\n const keepAt = offsetBeforeScroll.value + padding.value;\n const maxScroll = Math.max(\n size.value.height - layout.value.height + actualTotalPadding,\n 0,\n );\n\n scrollTo(scrollViewRef, 0, Math.min(keepAt, maxScroll), false);\n\n return;\n }\n\n const target = clampedScrollTarget(\n offsetBeforeScroll.value,\n scrollEffective,\n size.value.height,\n layout.value.height,\n actualTotalPadding,\n );\n\n scrollTo(scrollViewRef, 0, target, false);\n\n // Track actual (clamped) displacement during open for symmetric close\n if (!closing.value) {\n actualOpenShift.value = target - offsetBeforeScroll.value;\n }\n }\n },\n onEnd: (e) => {\n \"worklet\";\n\n if (freeze) {\n return;\n }\n\n const effective = getEffectiveHeight(\n e.height,\n targetKeyboardHeight.value,\n offset,\n );\n\n padding.value = effective;\n\n // Record actual scroll displacement so close can be symmetric\n if (effective > 0 && offsetBeforeScroll.value !== -1) {\n actualOpenShift.value = scroll.value - offsetBeforeScroll.value;\n }\n },\n },\n [inverted, keyboardLiftBehavior, freeze, offset],\n );\n\n return {\n padding,\n currentHeight,\n contentOffsetY: undefined,\n scroll,\n layout,\n size,\n onLayout,\n onContentSizeChange,\n };\n}\n\nexport { useChatKeyboard };\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["scrollTo","useSharedValue","useKeyboardHandler","useScrollState","clampedScrollTarget","getEffectiveHeight","getMinimumPaddingAbsorbed","getScrollEffective","getVisibleMinimumPaddingFraction","isScrollAtEnd","shouldShiftContent","useChatKeyboard","scrollViewRef","options","inverted","keyboardLiftBehavior","freeze","offset","blankSpace","extraContentPadding","padding","currentHeight","offsetBeforeScroll","targetKeyboardHeight","closing","minimumPaddingFractionOnOpen","actualOpenShift","layout","size","scroll","onLayout","onContentSizeChange","clampScrollIfNeeded","effective","totalPaddingForMaxScroll","paddingForMax","undefined","maxScroll","Math","max","value","height","onStart","e","atEnd","visibleFraction","minimumPaddingAbsorbed","scrollEffective","duration","onMove","actualTotalPadding","wasAtEnd","currentShift","target","keepAt","min","onEnd","contentOffsetY"],"sources":["index.ts"],"sourcesContent":["import { scrollTo, useSharedValue } from \"react-native-reanimated\";\n\nimport { useKeyboardHandler } from \"../../../hooks\";\nimport useScrollState from \"../../hooks/useScrollState\";\n\nimport {\n clampedScrollTarget,\n getEffectiveHeight,\n getMinimumPaddingAbsorbed,\n getScrollEffective,\n getVisibleMinimumPaddingFraction,\n isScrollAtEnd,\n shouldShiftContent,\n} from \"./helpers\";\n\nimport type { UseChatKeyboardOptions, UseChatKeyboardReturn } from \"./types\";\nimport type { AnimatedRef } from \"react-native-reanimated\";\nimport type Reanimated from \"react-native-reanimated\";\n\n/**\n * Hook that manages keyboard-driven scrolling for chat-style scroll views.\n * Calculates padding (extra scrollable space) and content shift values,\n * using per-frame scrollTo updates (Android and other platforms).\n *\n * @param scrollViewRef - Animated ref to the scroll view.\n * @param options - Configuration for inverted and keyboardLiftBehavior.\n * @returns Shared values for padding and contentOffsetY (always `undefined`).\n * @example\n * ```tsx\n * const { padding } = useChatKeyboard(ref, { inverted: false, keyboardLiftBehavior: \"always\" });\n * ```\n */\nfunction useChatKeyboard(\n scrollViewRef: AnimatedRef<Reanimated.ScrollView>,\n options: UseChatKeyboardOptions,\n): UseChatKeyboardReturn {\n const {\n inverted,\n keyboardLiftBehavior,\n freeze,\n offset,\n blankSpace,\n extraContentPadding,\n } = options;\n\n const padding = useSharedValue(0);\n const currentHeight = useSharedValue(0);\n const offsetBeforeScroll = useSharedValue(0);\n const targetKeyboardHeight = useSharedValue(0);\n const closing = useSharedValue(false);\n const minimumPaddingFractionOnOpen = useSharedValue(0);\n const actualOpenShift = useSharedValue(0);\n const {\n layout,\n size,\n offset: scroll,\n onLayout,\n onContentSizeChange,\n } = useScrollState(scrollViewRef);\n const clampScrollIfNeeded = (\n effective: number,\n totalPaddingForMaxScroll?: number,\n ) => {\n \"worklet\";\n\n const paddingForMax =\n totalPaddingForMaxScroll !== undefined\n ? totalPaddingForMaxScroll\n : effective;\n const maxScroll = Math.max(\n size.value.height - layout.value.height + paddingForMax,\n 0,\n );\n\n if (scroll.value > maxScroll) {\n scrollTo(scrollViewRef, 0, maxScroll, false);\n }\n };\n\n useKeyboardHandler(\n {\n onStart: (e) => {\n \"worklet\";\n\n if (freeze.value) {\n return;\n }\n\n if (e.height > 0) {\n // eslint-disable-next-line react-compiler/react-compiler\n targetKeyboardHeight.value = e.height;\n closing.value = false;\n } else {\n closing.value = true;\n }\n\n const effective = getEffectiveHeight(\n e.height,\n targetKeyboardHeight.value,\n offset,\n );\n\n const atEnd = isScrollAtEnd(\n scroll.value,\n layout.value.height,\n size.value.height,\n inverted,\n );\n\n // Scale minimum padding absorption by how much of it is visible.\n // Fully visible → full absorption; fully off-screen → no absorption.\n const visibleFraction = getVisibleMinimumPaddingFraction(\n scroll.value,\n layout.value.height,\n size.value.height,\n blankSpace.value,\n inverted,\n );\n const minimumPaddingAbsorbed =\n visibleFraction >= 1\n ? getMinimumPaddingAbsorbed(\n blankSpace.value,\n extraContentPadding.value,\n )\n : 0;\n const scrollEffective = getScrollEffective(\n effective,\n minimumPaddingAbsorbed,\n );\n\n if (inverted && e.duration === -1) {\n // Android inverted: skip post-interactive snap-back events\n // (duration === -1 means the keyboard is re-establishing its\n // position after an interactive gesture, not a real animation)\n return;\n } else if (e.height > 0) {\n // Android: keyboard opening — set padding + capture scroll position\n minimumPaddingFractionOnOpen.value = visibleFraction >= 1 ? 1 : 0;\n padding.value = effective;\n offsetBeforeScroll.value = scroll.value;\n\n if (!inverted && keyboardLiftBehavior === \"whenAtEnd\" && !atEnd) {\n // Sentinel: don't scroll in onMove (non-inverted only)\n offsetBeforeScroll.value = -1;\n } else if (!inverted && scrollEffective === 0) {\n // blankSpace fully absorbs the keyboard — prevent scroll\n offsetBeforeScroll.value = -1;\n } else if (inverted && scrollEffective === 0) {\n // blankSpace fully absorbs the keyboard — guard for inverted\n offsetBeforeScroll.value = scroll.value;\n }\n } else {\n // Android: keyboard closing — re-capture scroll position\n if (inverted) {\n offsetBeforeScroll.value = scroll.value;\n } else {\n // Preserve \"whenAtEnd\" sentinel: if open didn't shift, close shouldn't either\n if (offsetBeforeScroll.value !== -1) {\n // Use the actual displacement recorded at end of open animation\n // (not the theoretical value) so close is symmetric with open\n offsetBeforeScroll.value = scroll.value - actualOpenShift.value;\n }\n }\n }\n },\n onMove: (e) => {\n \"worklet\";\n\n if (freeze.value) {\n return;\n }\n\n currentHeight.value = e.height;\n\n if (inverted) {\n // Skip post-interactive snap-back (duration === -1)\n if (e.duration === -1) {\n return;\n }\n\n const effective = getEffectiveHeight(\n e.height,\n targetKeyboardHeight.value,\n offset,\n );\n\n const minimumPaddingAbsorbed =\n getMinimumPaddingAbsorbed(\n blankSpace.value,\n extraContentPadding.value,\n ) * minimumPaddingFractionOnOpen.value;\n const scrollEffective = getScrollEffective(\n effective,\n minimumPaddingAbsorbed,\n );\n const actualTotalPadding = Math.max(\n blankSpace.value,\n effective + extraContentPadding.value,\n );\n\n // Check if we should shift content based on position when keyboard started\n const wasAtEnd = isScrollAtEnd(\n offsetBeforeScroll.value,\n layout.value.height,\n size.value.height,\n inverted,\n );\n\n // \"never\" at end: scroll along when keyboard closes to avoid jump\n if (\n keyboardLiftBehavior === \"never\" &&\n wasAtEnd &&\n effective < padding.value\n ) {\n padding.value = effective;\n\n if (scrollEffective === 0 && minimumPaddingAbsorbed > 0) {\n return;\n }\n\n scrollTo(scrollViewRef, 0, 0, false);\n\n return;\n }\n\n if (!shouldShiftContent(keyboardLiftBehavior, wasAtEnd)) {\n // Closing, not shifting: reduce padding to avoid gap\n if (closing.value && effective < padding.value) {\n padding.value = effective;\n clampScrollIfNeeded(effective, actualTotalPadding);\n }\n\n return;\n }\n\n // When blankSpace fully absorbs the keyboard, skip scroll\n if (scrollEffective === 0 && minimumPaddingAbsorbed > 0) {\n return;\n }\n\n // Persistent: don't let shift decrease\n if (keyboardLiftBehavior === \"persistent\") {\n const currentShift =\n offsetBeforeScroll.value + padding.value - scroll.value;\n\n if (effective < currentShift) {\n // When at end, allow scrolling back (snap to end + reduce padding)\n if (wasAtEnd) {\n padding.value = effective;\n scrollTo(scrollViewRef, 0, 0, false);\n } else if (closing.value) {\n // Not at end: reduce padding to avoid gap\n padding.value = effective;\n clampScrollIfNeeded(effective, actualTotalPadding);\n }\n\n return;\n }\n }\n\n const target =\n offsetBeforeScroll.value + padding.value - scrollEffective;\n\n scrollTo(scrollViewRef, 0, target, false);\n } else {\n const effective = getEffectiveHeight(\n e.height,\n targetKeyboardHeight.value,\n offset,\n );\n\n const minimumPaddingAbsorbed =\n getMinimumPaddingAbsorbed(\n blankSpace.value,\n extraContentPadding.value,\n ) * minimumPaddingFractionOnOpen.value;\n const scrollEffective = getScrollEffective(\n effective,\n minimumPaddingAbsorbed,\n );\n const actualTotalPadding = Math.max(\n blankSpace.value,\n effective + extraContentPadding.value,\n );\n\n // \"never\" closing: clamp scroll to valid range as inset shrinks\n if (\n keyboardLiftBehavior === \"never\" &&\n closing.value &&\n effective < padding.value\n ) {\n clampScrollIfNeeded(effective, actualTotalPadding);\n\n return;\n }\n\n if (!shouldShiftContent(keyboardLiftBehavior, true)) {\n return;\n }\n\n // \"whenAtEnd\" sentinel check (also used for blankSpace full absorption)\n if (offsetBeforeScroll.value === -1) {\n if (closing.value) {\n // Keyboard didn't shift on open; ensure valid position on close\n clampScrollIfNeeded(effective, actualTotalPadding);\n }\n\n return;\n }\n\n // \"persistent\" closing: maintain position, clamped to valid range\n if (keyboardLiftBehavior === \"persistent\" && closing.value) {\n const keepAt = offsetBeforeScroll.value + padding.value;\n const maxScroll = Math.max(\n size.value.height - layout.value.height + actualTotalPadding,\n 0,\n );\n\n scrollTo(scrollViewRef, 0, Math.min(keepAt, maxScroll), false);\n\n return;\n }\n\n const target = clampedScrollTarget(\n offsetBeforeScroll.value,\n scrollEffective,\n size.value.height,\n layout.value.height,\n actualTotalPadding,\n );\n\n scrollTo(scrollViewRef, 0, target, false);\n\n // Track actual (clamped) displacement during open for symmetric close\n if (!closing.value) {\n actualOpenShift.value = target - offsetBeforeScroll.value;\n }\n }\n },\n onEnd: (e) => {\n \"worklet\";\n\n if (freeze.value) {\n return;\n }\n\n const effective = getEffectiveHeight(\n e.height,\n targetKeyboardHeight.value,\n offset,\n );\n\n padding.value = effective;\n\n // Record actual scroll displacement so close can be symmetric\n if (effective > 0 && offsetBeforeScroll.value !== -1) {\n actualOpenShift.value = scroll.value - offsetBeforeScroll.value;\n }\n },\n },\n [inverted, keyboardLiftBehavior, offset],\n );\n\n return {\n padding,\n currentHeight,\n contentOffsetY: undefined,\n scroll,\n layout,\n size,\n onLayout,\n onContentSizeChange,\n };\n}\n\nexport { useChatKeyboard };\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type { LayoutChangeEvent } from \"react-native\";\nimport type { SharedValue } from \"react-native-reanimated\";\n\ntype KeyboardLiftBehavior = \"always\" | \"whenAtEnd\" | \"persistent\" | \"never\";\n\ntype UseChatKeyboardOptions = {\n inverted: boolean;\n keyboardLiftBehavior: KeyboardLiftBehavior;\n freeze: boolean
|
|
1
|
+
{"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type { LayoutChangeEvent } from \"react-native\";\nimport type { SharedValue } from \"react-native-reanimated\";\n\ntype KeyboardLiftBehavior = \"always\" | \"whenAtEnd\" | \"persistent\" | \"never\";\n\ntype UseChatKeyboardOptions = {\n inverted: boolean;\n keyboardLiftBehavior: KeyboardLiftBehavior;\n freeze: SharedValue<boolean>;\n offset: number;\n blankSpace: SharedValue<number>;\n /** Extra content padding shared value — needed on iOS to correctly clamp contentOffset. */\n extraContentPadding: SharedValue<number>;\n};\n\ntype UseChatKeyboardReturn = {\n /** Extra scrollable space (= keyboard height). Used as contentInset on iOS, contentInsetBottom/contentInsetTop on Android. */\n padding: SharedValue<number>;\n /** Raw keyboard height updated every frame in onMove. Used to force Reanimated commits on Fabric. */\n currentHeight: SharedValue<number>;\n /** Absolute Y content offset for iOS (set once in onStart). `undefined` on Android. */\n contentOffsetY: SharedValue<number> | undefined;\n /** Current vertical scroll offset. */\n scroll: SharedValue<number>;\n /** Visible viewport dimensions. */\n layout: SharedValue<{ width: number; height: number }>;\n /** Total content dimensions. */\n size: SharedValue<{ width: number; height: number }>;\n /** Callback to attach to ScrollView's onLayout prop to capture initial viewport dimensions. */\n onLayout: (e: LayoutChangeEvent) => void;\n /** Callback to attach to ScrollView's onContentSizeChange prop to capture initial content dimensions. */\n onContentSizeChange: (w: number, h: number) => void;\n};\n\nexport type {\n KeyboardLiftBehavior,\n UseChatKeyboardOptions,\n UseChatKeyboardReturn,\n};\n"],"mappings":"","ignoreList":[]}
|
|
@@ -48,7 +48,7 @@ function useExtraContentPadding(options) {
|
|
|
48
48
|
}
|
|
49
49
|
}, [scrollViewRef, contentOffsetY]);
|
|
50
50
|
useAnimatedReaction(() => extraContentPadding.value, (current, previous) => {
|
|
51
|
-
if (freeze || previous === null) {
|
|
51
|
+
if (freeze.value || previous === null) {
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
const rawDelta = current - previous;
|
|
@@ -81,7 +81,7 @@ function useExtraContentPadding(options) {
|
|
|
81
81
|
const target = Math.min(scroll.value + effectiveDelta, maxScroll);
|
|
82
82
|
scrollToTarget(target);
|
|
83
83
|
}
|
|
84
|
-
}, [inverted, keyboardLiftBehavior
|
|
84
|
+
}, [inverted, keyboardLiftBehavior]);
|
|
85
85
|
}
|
|
86
86
|
export { useExtraContentPadding };
|
|
87
87
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","Platform","scrollTo","useAnimatedReaction","IS_FABRIC","isScrollAtEnd","shouldShiftContent","useExtraContentPadding","options","scrollViewRef","extraContentPadding","keyboardPadding","blankSpace","scroll","layout","size","contentOffsetY","inverted","keyboardLiftBehavior","freeze","scrollToTarget","target","value","OS","requestAnimationFrame","current","previous","rawDelta","previousTotal","Math","max","currentTotal","effectiveDelta","atEnd","height","maxScroll","min"],"sources":["index.ts"],"sourcesContent":["import { useCallback } from \"react\";\nimport { Platform } from \"react-native\";\nimport { scrollTo, useAnimatedReaction } from \"react-native-reanimated\";\n\nimport { IS_FABRIC } from \"../../../architecture\";\nimport { isScrollAtEnd, shouldShiftContent } from \"../useChatKeyboard/helpers\";\n\nimport type { KeyboardLiftBehavior } from \"../useChatKeyboard/types\";\nimport type { AnimatedRef, SharedValue } from \"react-native-reanimated\";\nimport type Reanimated from \"react-native-reanimated\";\n\ntype UseExtraContentPaddingOptions = {\n scrollViewRef: AnimatedRef<Reanimated.ScrollView>;\n extraContentPadding: SharedValue<number>;\n /** Keyboard-only padding from useChatKeyboard — used to compute total padding for clamping. */\n keyboardPadding: SharedValue<number>;\n /** Minimum inset floor — used to absorb keyboard and extraContentPadding changes. */\n blankSpace: SharedValue<number>;\n /** Current vertical scroll offset. */\n scroll: SharedValue<number>;\n /** Visible viewport dimensions. */\n layout: SharedValue<{ width: number; height: number }>;\n /** Total content dimensions. */\n size: SharedValue<{ width: number; height: number }>;\n /** IOS only — when provided, sets contentOffset atomically with contentInset. */\n contentOffsetY?: SharedValue<number>;\n inverted: boolean;\n keyboardLiftBehavior: KeyboardLiftBehavior;\n freeze: boolean
|
|
1
|
+
{"version":3,"names":["useCallback","Platform","scrollTo","useAnimatedReaction","IS_FABRIC","isScrollAtEnd","shouldShiftContent","useExtraContentPadding","options","scrollViewRef","extraContentPadding","keyboardPadding","blankSpace","scroll","layout","size","contentOffsetY","inverted","keyboardLiftBehavior","freeze","scrollToTarget","target","value","OS","requestAnimationFrame","current","previous","rawDelta","previousTotal","Math","max","currentTotal","effectiveDelta","atEnd","height","maxScroll","min"],"sources":["index.ts"],"sourcesContent":["import { useCallback } from \"react\";\nimport { Platform } from \"react-native\";\nimport { scrollTo, useAnimatedReaction } from \"react-native-reanimated\";\n\nimport { IS_FABRIC } from \"../../../architecture\";\nimport { isScrollAtEnd, shouldShiftContent } from \"../useChatKeyboard/helpers\";\n\nimport type { KeyboardLiftBehavior } from \"../useChatKeyboard/types\";\nimport type { AnimatedRef, SharedValue } from \"react-native-reanimated\";\nimport type Reanimated from \"react-native-reanimated\";\n\ntype UseExtraContentPaddingOptions = {\n scrollViewRef: AnimatedRef<Reanimated.ScrollView>;\n extraContentPadding: SharedValue<number>;\n /** Keyboard-only padding from useChatKeyboard — used to compute total padding for clamping. */\n keyboardPadding: SharedValue<number>;\n /** Minimum inset floor — used to absorb keyboard and extraContentPadding changes. */\n blankSpace: SharedValue<number>;\n /** Current vertical scroll offset. */\n scroll: SharedValue<number>;\n /** Visible viewport dimensions. */\n layout: SharedValue<{ width: number; height: number }>;\n /** Total content dimensions. */\n size: SharedValue<{ width: number; height: number }>;\n /** IOS only — when provided, sets contentOffset atomically with contentInset. */\n contentOffsetY?: SharedValue<number>;\n inverted: boolean;\n keyboardLiftBehavior: KeyboardLiftBehavior;\n freeze: SharedValue<boolean>;\n};\n\n/**\n * Hook that reacts to `extraContentPadding` changes and conditionally\n * adjusts the scroll position using `scrollTo` on both iOS and Android.\n *\n * Padding extension (scrollable range) is handled externally via a\n * `useDerivedValue` that sums keyboard padding + extra content padding.\n * This hook only handles the scroll correction.\n *\n * @param options - Configuration and shared values.\n * @example\n * ```tsx\n * useExtraContentPadding({ scrollViewRef, extraContentPadding, ... });\n * ```\n */\nfunction useExtraContentPadding(options: UseExtraContentPaddingOptions): void {\n const {\n scrollViewRef,\n extraContentPadding,\n keyboardPadding,\n blankSpace,\n scroll,\n layout,\n size,\n contentOffsetY,\n inverted,\n keyboardLiftBehavior,\n freeze,\n } = options;\n\n const scrollToTarget = useCallback(\n (target: number) => {\n \"worklet\";\n\n if (contentOffsetY && IS_FABRIC) {\n // eslint-disable-next-line react-compiler/react-compiler\n contentOffsetY.value = target;\n } else if (Platform.OS === \"android\") {\n // Defer scrollTo so the animatedProps inset commit lands first;\n // otherwise the native ScrollView clamps to the old range.\n requestAnimationFrame(() => {\n scrollTo(scrollViewRef, 0, target, false);\n });\n } else {\n scrollTo(scrollViewRef, 0, target, false);\n }\n },\n [scrollViewRef, contentOffsetY],\n );\n\n useAnimatedReaction(\n () => extraContentPadding.value,\n (current, previous) => {\n if (freeze.value || previous === null) {\n return;\n }\n\n const rawDelta = current - previous;\n\n if (rawDelta === 0) {\n return;\n }\n\n // Compute effective delta considering blankSpace floor\n const previousTotal = Math.max(\n blankSpace.value,\n keyboardPadding.value + previous,\n );\n const currentTotal = Math.max(\n blankSpace.value,\n keyboardPadding.value + current,\n );\n const effectiveDelta = currentTotal - previousTotal;\n\n if (effectiveDelta === 0) {\n // blankSpace absorbed the change\n return;\n }\n\n const atEnd = isScrollAtEnd(\n scroll.value,\n layout.value.height,\n size.value.height,\n inverted,\n );\n\n // \"persistent\": scroll on grow, hold position on shrink (unless at end)\n if (\n keyboardLiftBehavior === \"persistent\" &&\n effectiveDelta < 0 &&\n !atEnd\n ) {\n return;\n }\n\n if (!shouldShiftContent(keyboardLiftBehavior, atEnd)) {\n return;\n }\n\n if (inverted) {\n const target = Math.max(scroll.value - effectiveDelta, -currentTotal);\n\n scrollToTarget(target);\n } else {\n const maxScroll = Math.max(\n size.value.height - layout.value.height + currentTotal,\n 0,\n );\n const target = Math.min(scroll.value + effectiveDelta, maxScroll);\n\n scrollToTarget(target);\n }\n },\n [inverted, keyboardLiftBehavior],\n );\n}\n\nexport { useExtraContentPadding };\nexport type { UseExtraContentPaddingOptions };\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -67,9 +67,11 @@ const KeyboardToolbar = props => {
|
|
|
67
67
|
paddingLeft: insets === null || insets === void 0 ? void 0 : insets.left,
|
|
68
68
|
paddingRight: insets === null || insets === void 0 ? void 0 : insets.right
|
|
69
69
|
} : null, KEYBOARD_HAS_ROUNDED_CORNERS ? styles.floating : null], [colorScheme, opacity, theme, insets]);
|
|
70
|
-
const containerStyle = useMemo(() => [
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
const containerStyle = useMemo(() => [
|
|
71
|
+
// CRUCIAL: gives the native view real bounds
|
|
72
|
+
styles.sticky, KEYBOARD_HAS_ROUNDED_CORNERS ? {
|
|
73
|
+
left: ((insets === null || insets === void 0 ? void 0 : insets.left) ?? 0) + 16,
|
|
74
|
+
right: ((insets === null || insets === void 0 ? void 0 : insets.right) ?? 0) + 16
|
|
73
75
|
} : null], [insets]);
|
|
74
76
|
const offset = useMemo(() => ({
|
|
75
77
|
closed: closed + KEYBOARD_TOOLBAR_HEIGHT,
|
|
@@ -145,6 +147,13 @@ const KeyboardToolbar = props => {
|
|
|
145
147
|
}), backgroundElement, arrowsElement, contentContainer, doneElement)));
|
|
146
148
|
};
|
|
147
149
|
const styles = StyleSheet.create({
|
|
150
|
+
sticky: {
|
|
151
|
+
position: "absolute",
|
|
152
|
+
left: 0,
|
|
153
|
+
right: 0,
|
|
154
|
+
bottom: 0,
|
|
155
|
+
height: KEYBOARD_TOOLBAR_HEIGHT
|
|
156
|
+
},
|
|
148
157
|
toolbar: {
|
|
149
158
|
position: "absolute",
|
|
150
159
|
bottom: 0,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useEffect","useMemo","useState","StyleSheet","View","FocusedInputEvents","RCTKeyboardToolbarGroupView","useKeyboardState","KeyboardStickyView","Arrow","Button","colors","Background","Content","Done","Next","Prev","ToolbarContext","DEFAULT_OPACITY","KEYBOARD_HAS_ROUNDED_CORNERS","KEYBOARD_TOOLBAR_HEIGHT","OPENED_OFFSET","TEST_ID_KEYBOARD_TOOLBAR","KeyboardToolbar","props","children","content","theme","doneText","button","icon","showArrows","onNextCallback","onPrevCallback","onDoneCallback","blur","opacity","offset","closed","opened","enabled","insets","rest","colorScheme","state","appearance","inputs","setInputs","current","count","isPrevDisabled","isNextDisabled","buttonContainer","iconContainer","subscription","addListener","e","remove","toolbarStyle","styles","toolbar","backgroundColor","background","paddingLeft","left","paddingRight","right","floating","containerStyle","marginLeft","marginRight","backgroundElement","arrowsElement","contentContainer","doneElement","prevChild","nextChild","contentChild","doneChild","backgroundChild","Children","forEach","child","isValidElement","type","createElement","style","arrows","onPress","text","contextValue","Provider","value","_extends","testID","create","position","bottom","alignItems","width","flexDirection","height","alignSelf","borderRadius","overflow","Group","DefaultKeyboardToolbarTheme"],"sources":["index.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useState } from \"react\";\nimport { StyleSheet, View } from \"react-native\";\n\nimport {\n FocusedInputEvents,\n RCTKeyboardToolbarGroupView,\n} from \"../../bindings\";\nimport { useKeyboardState } from \"../../hooks\";\nimport KeyboardStickyView from \"../KeyboardStickyView\";\n\nimport Arrow from \"./Arrow\";\nimport Button from \"./Button\";\nimport { colors } from \"./colors\";\nimport { Background, Content, Done, Next, Prev } from \"./compound/components\";\nimport { ToolbarContext } from \"./compound/context\";\nimport {\n DEFAULT_OPACITY,\n KEYBOARD_HAS_ROUNDED_CORNERS,\n KEYBOARD_TOOLBAR_HEIGHT,\n OPENED_OFFSET,\n TEST_ID_KEYBOARD_TOOLBAR,\n} from \"./constants\";\n\nimport type { KeyboardToolbarProps } from \"./types\";\nimport type { ReactNode } from \"react\";\n\n/**\n * `KeyboardToolbar` is a component that is shown above the keyboard with `Prev`/`Next` buttons from left and\n * `Done` button from the right (to dismiss the keyboard). Allows to add customizable content (yours UI elements) in the middle.\n *\n * @param props - Component props.\n * @returns A component that is shown above the keyboard with `Prev`/`Next` and `Done` buttons.\n * @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/components/keyboard-toolbar|Documentation} page for more details.\n * @example\n * ```tsx\n * <KeyboardToolbar>\n * <KeyboardToolbar.Done text=\"Close\" />\n * </KeyboardToolbar>\n * ```\n */\nconst KeyboardToolbar: React.FC<KeyboardToolbarProps> & {\n Background: typeof Background;\n Content: typeof Content;\n Prev: typeof Prev;\n Next: typeof Next;\n Done: typeof Done;\n Group: typeof RCTKeyboardToolbarGroupView;\n} = (props) => {\n const {\n children,\n content,\n theme = colors,\n doneText = \"Done\",\n button,\n icon,\n showArrows = true,\n onNextCallback,\n onPrevCallback,\n onDoneCallback,\n blur = null,\n opacity = DEFAULT_OPACITY,\n offset: { closed = 0, opened = 0 } = {},\n enabled = true,\n insets,\n ...rest\n } = props;\n const colorScheme = useKeyboardState((state) => state.appearance);\n const [inputs, setInputs] = useState({\n current: 0,\n count: 0,\n });\n const isPrevDisabled = inputs.current === 0;\n const isNextDisabled = inputs.current === inputs.count - 1;\n const buttonContainer = button ?? Button;\n const iconContainer = icon ?? Arrow;\n\n useEffect(() => {\n const subscription = FocusedInputEvents.addListener(\"focusDidSet\", (e) => {\n setInputs(e);\n });\n\n return subscription.remove;\n }, []);\n const toolbarStyle = useMemo(\n () => [\n styles.toolbar,\n {\n backgroundColor: `${theme[colorScheme].background}${opacity}`,\n },\n !KEYBOARD_HAS_ROUNDED_CORNERS\n ? {\n paddingLeft: insets?.left,\n paddingRight: insets?.right,\n }\n : null,\n KEYBOARD_HAS_ROUNDED_CORNERS ? styles.floating : null,\n ],\n [colorScheme, opacity, theme, insets],\n );\n const containerStyle = useMemo(\n () => [\n KEYBOARD_HAS_ROUNDED_CORNERS\n ? {\n marginLeft: (insets?.left ?? 0) + 16,\n marginRight: (insets?.right ?? 0) + 16,\n }\n : null,\n ],\n [insets],\n );\n const offset = useMemo(\n () => ({\n closed: closed + KEYBOARD_TOOLBAR_HEIGHT,\n opened: opened + OPENED_OFFSET,\n }),\n [closed, opened],\n );\n\n let backgroundElement: ReactNode = null;\n let arrowsElement: ReactNode = null;\n let contentContainer: ReactNode = null;\n let doneElement: ReactNode = null;\n\n if (children) {\n let prevChild: ReactNode = null;\n let nextChild: ReactNode = null;\n let contentChild: ReactNode = null;\n let doneChild: ReactNode = null;\n let backgroundChild: ReactNode = null;\n\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) {\n return;\n }\n const type = child.type;\n\n if (type === Background) {\n backgroundChild = child;\n } else if (type === Content) {\n contentChild = child;\n } else if (type === Prev) {\n prevChild = child;\n } else if (type === Next) {\n nextChild = child;\n } else if (type === Done) {\n doneChild = child;\n }\n });\n\n backgroundElement = backgroundChild;\n doneElement = doneChild;\n arrowsElement =\n prevChild || nextChild ? (\n <View style={styles.arrows}>\n {prevChild}\n {nextChild}\n </View>\n ) : null;\n contentContainer = contentChild ?? <Content>{contentChild}</Content>;\n } else {\n backgroundElement = blur;\n arrowsElement = showArrows ? (\n <View style={styles.arrows}>\n <Prev\n button={buttonContainer}\n icon={iconContainer}\n onPress={onPrevCallback}\n />\n <Next\n button={buttonContainer}\n icon={iconContainer}\n onPress={onNextCallback}\n />\n </View>\n ) : null;\n contentContainer = <Content>{content}</Content>;\n doneElement = doneText ? (\n <Done button={buttonContainer} text={doneText} onPress={onDoneCallback} />\n ) : null;\n }\n\n const contextValue = useMemo(\n () => ({\n theme,\n isPrevDisabled,\n isNextDisabled,\n }),\n [theme, isPrevDisabled, isNextDisabled],\n );\n\n return (\n <ToolbarContext.Provider value={contextValue}>\n <KeyboardStickyView\n enabled={enabled}\n offset={offset}\n style={containerStyle}\n >\n <View {...rest} style={toolbarStyle} testID={TEST_ID_KEYBOARD_TOOLBAR}>\n {backgroundElement}\n {arrowsElement}\n {contentContainer}\n {doneElement}\n </View>\n </KeyboardStickyView>\n </ToolbarContext.Provider>\n );\n};\n\nconst styles = StyleSheet.create({\n toolbar: {\n position: \"absolute\",\n bottom: 0,\n alignItems: \"center\",\n width: \"100%\",\n flexDirection: \"row\",\n height: KEYBOARD_TOOLBAR_HEIGHT,\n },\n arrows: {\n flexDirection: \"row\",\n paddingLeft: 8,\n },\n floating: {\n alignSelf: \"center\",\n borderRadius: 20,\n overflow: \"hidden\",\n },\n});\n\nKeyboardToolbar.Background = Background;\nKeyboardToolbar.Content = Content;\nKeyboardToolbar.Prev = Prev;\nKeyboardToolbar.Next = Next;\nKeyboardToolbar.Done = Done;\nKeyboardToolbar.Group = RCTKeyboardToolbarGroupView;\n\nexport { colors as DefaultKeyboardToolbarTheme, KeyboardToolbarProps };\nexport default KeyboardToolbar;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["React","useEffect","useMemo","useState","StyleSheet","View","FocusedInputEvents","RCTKeyboardToolbarGroupView","useKeyboardState","KeyboardStickyView","Arrow","Button","colors","Background","Content","Done","Next","Prev","ToolbarContext","DEFAULT_OPACITY","KEYBOARD_HAS_ROUNDED_CORNERS","KEYBOARD_TOOLBAR_HEIGHT","OPENED_OFFSET","TEST_ID_KEYBOARD_TOOLBAR","KeyboardToolbar","props","children","content","theme","doneText","button","icon","showArrows","onNextCallback","onPrevCallback","onDoneCallback","blur","opacity","offset","closed","opened","enabled","insets","rest","colorScheme","state","appearance","inputs","setInputs","current","count","isPrevDisabled","isNextDisabled","buttonContainer","iconContainer","subscription","addListener","e","remove","toolbarStyle","styles","toolbar","backgroundColor","background","paddingLeft","left","paddingRight","right","floating","containerStyle","sticky","backgroundElement","arrowsElement","contentContainer","doneElement","prevChild","nextChild","contentChild","doneChild","backgroundChild","Children","forEach","child","isValidElement","type","createElement","style","arrows","onPress","text","contextValue","Provider","value","_extends","testID","create","position","bottom","height","alignItems","width","flexDirection","alignSelf","borderRadius","overflow","Group","DefaultKeyboardToolbarTheme"],"sources":["index.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useState } from \"react\";\nimport { StyleSheet, View } from \"react-native\";\n\nimport {\n FocusedInputEvents,\n RCTKeyboardToolbarGroupView,\n} from \"../../bindings\";\nimport { useKeyboardState } from \"../../hooks\";\nimport KeyboardStickyView from \"../KeyboardStickyView\";\n\nimport Arrow from \"./Arrow\";\nimport Button from \"./Button\";\nimport { colors } from \"./colors\";\nimport { Background, Content, Done, Next, Prev } from \"./compound/components\";\nimport { ToolbarContext } from \"./compound/context\";\nimport {\n DEFAULT_OPACITY,\n KEYBOARD_HAS_ROUNDED_CORNERS,\n KEYBOARD_TOOLBAR_HEIGHT,\n OPENED_OFFSET,\n TEST_ID_KEYBOARD_TOOLBAR,\n} from \"./constants\";\n\nimport type { KeyboardToolbarProps } from \"./types\";\nimport type { ReactNode } from \"react\";\n\n/**\n * `KeyboardToolbar` is a component that is shown above the keyboard with `Prev`/`Next` buttons from left and\n * `Done` button from the right (to dismiss the keyboard). Allows to add customizable content (yours UI elements) in the middle.\n *\n * @param props - Component props.\n * @returns A component that is shown above the keyboard with `Prev`/`Next` and `Done` buttons.\n * @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/components/keyboard-toolbar|Documentation} page for more details.\n * @example\n * ```tsx\n * <KeyboardToolbar>\n * <KeyboardToolbar.Done text=\"Close\" />\n * </KeyboardToolbar>\n * ```\n */\nconst KeyboardToolbar: React.FC<KeyboardToolbarProps> & {\n Background: typeof Background;\n Content: typeof Content;\n Prev: typeof Prev;\n Next: typeof Next;\n Done: typeof Done;\n Group: typeof RCTKeyboardToolbarGroupView;\n} = (props) => {\n const {\n children,\n content,\n theme = colors,\n doneText = \"Done\",\n button,\n icon,\n showArrows = true,\n onNextCallback,\n onPrevCallback,\n onDoneCallback,\n blur = null,\n opacity = DEFAULT_OPACITY,\n offset: { closed = 0, opened = 0 } = {},\n enabled = true,\n insets,\n ...rest\n } = props;\n const colorScheme = useKeyboardState((state) => state.appearance);\n const [inputs, setInputs] = useState({\n current: 0,\n count: 0,\n });\n const isPrevDisabled = inputs.current === 0;\n const isNextDisabled = inputs.current === inputs.count - 1;\n const buttonContainer = button ?? Button;\n const iconContainer = icon ?? Arrow;\n\n useEffect(() => {\n const subscription = FocusedInputEvents.addListener(\"focusDidSet\", (e) => {\n setInputs(e);\n });\n\n return subscription.remove;\n }, []);\n const toolbarStyle = useMemo(\n () => [\n styles.toolbar,\n {\n backgroundColor: `${theme[colorScheme].background}${opacity}`,\n },\n !KEYBOARD_HAS_ROUNDED_CORNERS\n ? {\n paddingLeft: insets?.left,\n paddingRight: insets?.right,\n }\n : null,\n KEYBOARD_HAS_ROUNDED_CORNERS ? styles.floating : null,\n ],\n [colorScheme, opacity, theme, insets],\n );\n const containerStyle = useMemo(\n () => [\n // CRUCIAL: gives the native view real bounds\n styles.sticky,\n KEYBOARD_HAS_ROUNDED_CORNERS\n ? ({\n left: (insets?.left ?? 0) + 16,\n right: (insets?.right ?? 0) + 16,\n } as const)\n : null,\n ],\n [insets],\n );\n const offset = useMemo(\n () => ({\n closed: closed + KEYBOARD_TOOLBAR_HEIGHT,\n opened: opened + OPENED_OFFSET,\n }),\n [closed, opened],\n );\n\n let backgroundElement: ReactNode = null;\n let arrowsElement: ReactNode = null;\n let contentContainer: ReactNode = null;\n let doneElement: ReactNode = null;\n\n if (children) {\n let prevChild: ReactNode = null;\n let nextChild: ReactNode = null;\n let contentChild: ReactNode = null;\n let doneChild: ReactNode = null;\n let backgroundChild: ReactNode = null;\n\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) {\n return;\n }\n const type = child.type;\n\n if (type === Background) {\n backgroundChild = child;\n } else if (type === Content) {\n contentChild = child;\n } else if (type === Prev) {\n prevChild = child;\n } else if (type === Next) {\n nextChild = child;\n } else if (type === Done) {\n doneChild = child;\n }\n });\n\n backgroundElement = backgroundChild;\n doneElement = doneChild;\n arrowsElement =\n prevChild || nextChild ? (\n <View style={styles.arrows}>\n {prevChild}\n {nextChild}\n </View>\n ) : null;\n contentContainer = contentChild ?? <Content>{contentChild}</Content>;\n } else {\n backgroundElement = blur;\n arrowsElement = showArrows ? (\n <View style={styles.arrows}>\n <Prev\n button={buttonContainer}\n icon={iconContainer}\n onPress={onPrevCallback}\n />\n <Next\n button={buttonContainer}\n icon={iconContainer}\n onPress={onNextCallback}\n />\n </View>\n ) : null;\n contentContainer = <Content>{content}</Content>;\n doneElement = doneText ? (\n <Done button={buttonContainer} text={doneText} onPress={onDoneCallback} />\n ) : null;\n }\n\n const contextValue = useMemo(\n () => ({\n theme,\n isPrevDisabled,\n isNextDisabled,\n }),\n [theme, isPrevDisabled, isNextDisabled],\n );\n\n return (\n <ToolbarContext.Provider value={contextValue}>\n <KeyboardStickyView\n enabled={enabled}\n offset={offset}\n style={containerStyle}\n >\n <View {...rest} style={toolbarStyle} testID={TEST_ID_KEYBOARD_TOOLBAR}>\n {backgroundElement}\n {arrowsElement}\n {contentContainer}\n {doneElement}\n </View>\n </KeyboardStickyView>\n </ToolbarContext.Provider>\n );\n};\n\nconst styles = StyleSheet.create({\n sticky: {\n position: \"absolute\",\n left: 0,\n right: 0,\n bottom: 0,\n height: KEYBOARD_TOOLBAR_HEIGHT,\n },\n toolbar: {\n position: \"absolute\",\n bottom: 0,\n alignItems: \"center\",\n width: \"100%\",\n flexDirection: \"row\",\n height: KEYBOARD_TOOLBAR_HEIGHT,\n },\n arrows: {\n flexDirection: \"row\",\n paddingLeft: 8,\n },\n floating: {\n alignSelf: \"center\",\n borderRadius: 20,\n overflow: \"hidden\",\n },\n});\n\nKeyboardToolbar.Background = Background;\nKeyboardToolbar.Content = Content;\nKeyboardToolbar.Prev = Prev;\nKeyboardToolbar.Next = Next;\nKeyboardToolbar.Done = Done;\nKeyboardToolbar.Group = RCTKeyboardToolbarGroupView;\n\nexport { colors as DefaultKeyboardToolbarTheme, KeyboardToolbarProps };\nexport default KeyboardToolbar;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
2
2
|
import React, { forwardRef } from "react";
|
|
3
|
-
import { Platform
|
|
3
|
+
import { Platform } from "react-native";
|
|
4
4
|
import Reanimated, { useAnimatedProps, useSharedValue } from "react-native-reanimated";
|
|
5
5
|
import { ClippingScrollView } from "../../bindings";
|
|
6
6
|
import styles from "./styles";
|
|
@@ -65,16 +65,7 @@ const ScrollViewWithBottomPadding = /*#__PURE__*/forwardRef(({
|
|
|
65
65
|
}, /*#__PURE__*/React.createElement(ScrollViewComponent, _extends({
|
|
66
66
|
ref: ref,
|
|
67
67
|
animatedProps: animatedProps
|
|
68
|
-
}, rest),
|
|
69
|
-
/*#__PURE__*/
|
|
70
|
-
// The only thing it can break is `StickyHeader`, but it's already broken in FlatList and other lists
|
|
71
|
-
// don't support this functionality, so we can add additional view here
|
|
72
|
-
// The correct fix would be to add a new prop in ScrollView that allows
|
|
73
|
-
// to customize children extraction logic and skip custom view
|
|
74
|
-
React.createElement(View, {
|
|
75
|
-
collapsable: false,
|
|
76
|
-
nativeID: "container"
|
|
77
|
-
}, children) : children));
|
|
68
|
+
}, rest), children));
|
|
78
69
|
});
|
|
79
70
|
export default ScrollViewWithBottomPadding;
|
|
80
71
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","forwardRef","Platform","
|
|
1
|
+
{"version":3,"names":["React","forwardRef","Platform","Reanimated","useAnimatedProps","useSharedValue","ClippingScrollView","styles","OS","ReanimatedClippingScrollView","createAnimatedComponent","ScrollViewWithBottomPadding","ScrollViewComponent","bottomPadding","scrollIndicatorPadding","contentInset","scrollIndicatorInsets","inverted","contentOffsetY","applyWorkaroundForContentInsetHitTestBug","children","rest","ref","prevContentOffsetY","animatedProps","insetTop","value","insetBottom","bottom","top","indicatorPadding","indicatorTop","indicatorBottom","result","right","left","contentInsetBottom","contentInsetTop","curr","contentOffset","x","y","createElement","style","container","_extends"],"sources":["index.tsx"],"sourcesContent":["import React, { forwardRef } from \"react\";\nimport { Platform } from \"react-native\";\nimport Reanimated, {\n useAnimatedProps,\n useSharedValue,\n} from \"react-native-reanimated\";\n\nimport { ClippingScrollView } from \"../../bindings\";\n\nimport styles from \"./styles\";\n\nimport type { ScrollViewProps } from \"react-native\";\nimport type { SharedValue } from \"react-native-reanimated\";\n\nconst OS = Platform.OS;\nconst ReanimatedClippingScrollView =\n OS === \"android\"\n ? Reanimated.createAnimatedComponent(ClippingScrollView)\n : ClippingScrollView;\n\ntype AnimatedScrollViewProps = React.ComponentProps<\n typeof Reanimated.ScrollView\n>;\n\nexport type AnimatedScrollViewComponent = React.ForwardRefExoticComponent<\n AnimatedScrollViewProps & React.RefAttributes<Reanimated.ScrollView>\n>;\n\ntype ScrollViewWithBottomPaddingProps = {\n ScrollViewComponent: AnimatedScrollViewComponent;\n children?: React.ReactNode;\n inverted?: boolean;\n bottomPadding: SharedValue<number>;\n /** Padding for scroll indicator insets (excludes blankSpace). Falls back to bottomPadding when not provided. */\n scrollIndicatorPadding?: SharedValue<number>;\n /** Absolute Y content offset (iOS only, for KeyboardChatScrollView). */\n contentOffsetY?: SharedValue<number>;\n applyWorkaroundForContentInsetHitTestBug?: boolean;\n} & ScrollViewProps;\n\nconst ScrollViewWithBottomPadding = forwardRef<\n Reanimated.ScrollView,\n ScrollViewWithBottomPaddingProps\n>(\n (\n {\n ScrollViewComponent,\n bottomPadding,\n scrollIndicatorPadding,\n contentInset,\n scrollIndicatorInsets,\n inverted,\n contentOffsetY,\n applyWorkaroundForContentInsetHitTestBug,\n children,\n ...rest\n },\n ref,\n ) => {\n const prevContentOffsetY = useSharedValue<number | null>(null);\n\n const animatedProps = useAnimatedProps(() => {\n const insetTop = inverted ? bottomPadding.value : 0;\n const insetBottom = !inverted ? bottomPadding.value : 0;\n const bottom = insetBottom + (contentInset?.bottom || 0);\n const top = insetTop + (contentInset?.top || 0);\n\n const indicatorPadding = scrollIndicatorPadding ?? bottomPadding;\n const indicatorTop =\n (inverted ? indicatorPadding.value : 0) +\n (scrollIndicatorInsets?.top || 0);\n const indicatorBottom =\n (!inverted ? indicatorPadding.value : 0) +\n (scrollIndicatorInsets?.bottom || 0);\n\n const result: Record<string, unknown> = {\n // iOS prop\n contentInset: {\n bottom: bottom,\n top: top,\n right: contentInset?.right,\n left: contentInset?.left,\n },\n scrollIndicatorInsets: {\n bottom: indicatorBottom,\n top: indicatorTop,\n right: scrollIndicatorInsets?.right,\n left: scrollIndicatorInsets?.left,\n },\n // Android prop\n contentInsetBottom: insetBottom,\n contentInsetTop: insetTop,\n };\n\n if (contentOffsetY) {\n const curr = contentOffsetY.value;\n\n if (curr !== prevContentOffsetY.value) {\n // eslint-disable-next-line react-compiler/react-compiler\n prevContentOffsetY.value = curr;\n result.contentOffset = { x: 0, y: curr };\n }\n }\n\n return result;\n }, [\n contentInset?.bottom,\n contentInset?.top,\n contentInset?.right,\n contentInset?.left,\n scrollIndicatorInsets?.bottom,\n scrollIndicatorInsets?.top,\n scrollIndicatorInsets?.right,\n scrollIndicatorInsets?.left,\n inverted,\n contentOffsetY,\n ]);\n\n return (\n <ReanimatedClippingScrollView\n animatedProps={animatedProps}\n applyWorkaroundForContentInsetHitTestBug={\n applyWorkaroundForContentInsetHitTestBug\n }\n style={styles.container}\n >\n <ScrollViewComponent ref={ref} animatedProps={animatedProps} {...rest}>\n {children}\n </ScrollViewComponent>\n </ReanimatedClippingScrollView>\n );\n },\n);\n\nexport default ScrollViewWithBottomPadding;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect, useState } from "react";
|
|
2
2
|
import { KeyboardEvents } from "../../bindings";
|
|
3
3
|
import { KeyboardController } from "../../module";
|
|
4
|
-
const EVENTS = ["
|
|
4
|
+
const EVENTS = ["keyboardWillShow", "keyboardDidHide"];
|
|
5
5
|
const getLatestState = () => ({
|
|
6
6
|
...KeyboardController.state(),
|
|
7
7
|
isVisible: KeyboardController.isVisible()
|
|
@@ -39,11 +39,6 @@ function useKeyboardState(selector = defaultSelector) {
|
|
|
39
39
|
// state will be updated by global listener first,
|
|
40
40
|
// so we simply read it and don't derive data from the event
|
|
41
41
|
setState(selector(getLatestState()))));
|
|
42
|
-
// update `appearance` prematurely
|
|
43
|
-
const willShowSubscription = KeyboardEvents.addListener("keyboardWillShow", e => setState(selector({
|
|
44
|
-
...getLatestState(),
|
|
45
|
-
appearance: e.appearance
|
|
46
|
-
})));
|
|
47
42
|
|
|
48
43
|
// we might have missed an update between reading a value in render and
|
|
49
44
|
// `addListener` in this handler, so we set it here. If there was
|
|
@@ -51,7 +46,6 @@ function useKeyboardState(selector = defaultSelector) {
|
|
|
51
46
|
setState(selector(getLatestState()));
|
|
52
47
|
return () => {
|
|
53
48
|
subscriptions.forEach(subscription => subscription.remove());
|
|
54
|
-
willShowSubscription.remove();
|
|
55
49
|
};
|
|
56
50
|
}, []);
|
|
57
51
|
return state;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useEffect","useState","KeyboardEvents","KeyboardController","EVENTS","getLatestState","state","isVisible","defaultSelector","useKeyboardState","selector","setState","subscriptions","map","event","addListener","
|
|
1
|
+
{"version":3,"names":["useEffect","useState","KeyboardEvents","KeyboardController","EVENTS","getLatestState","state","isVisible","defaultSelector","useKeyboardState","selector","setState","subscriptions","map","event","addListener","forEach","subscription","remove"],"sources":["index.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\n\nimport { KeyboardEvents } from \"../../bindings\";\nimport { KeyboardController } from \"../../module\";\n\nimport type { IKeyboardState } from \"../../types\";\n\nconst EVENTS = [\"keyboardWillShow\", \"keyboardDidHide\"] as const;\n\nconst getLatestState = () => ({\n ...KeyboardController.state(),\n isVisible: KeyboardController.isVisible(),\n});\n\ntype KeyboardStateSelector<T> = (state: IKeyboardState) => T;\n\nconst defaultSelector: KeyboardStateSelector<IKeyboardState> = (state) => state;\n\n/**\n * React Hook that represents the current keyboard state on iOS and Android.\n * It tracks keyboard visibility, height, appearance, type and other properties.\n * This hook subscribes to keyboard events and updates the state reactively.\n *\n * @template T - A type of the returned object from the `selector`.\n * @param selector - A function that receives the current keyboard state and picks only necessary properties to avoid frequent re-renders.\n * @returns Object {@link KeyboardState|containing} keyboard state information.\n * @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/hooks/keyboard/use-keyboard-state|Documentation} page for more details.\n * @example\n * ```tsx\n * function MyComponent() {\n * const isVisible = useKeyboardState((state) => state.isVisible);\n * const height = useKeyboardState((state) => state.height);\n *\n * return (\n * <View>\n * <Text>Keyboard is {isVisible ? 'visible' : 'hidden'}</Text>\n * <Text>Keyboard height: {height}</Text>\n * </View>\n * );\n * }\n * ```\n */\nfunction useKeyboardState<T = IKeyboardState>(\n selector: KeyboardStateSelector<T> = defaultSelector as KeyboardStateSelector<T>,\n): T {\n const [state, setState] = useState<T>(() => selector(getLatestState()));\n\n useEffect(() => {\n const subscriptions = EVENTS.map((event) =>\n KeyboardEvents.addListener(event, () =>\n // state will be updated by global listener first,\n // so we simply read it and don't derive data from the event\n setState(selector(getLatestState())),\n ),\n );\n\n // we might have missed an update between reading a value in render and\n // `addListener` in this handler, so we set it here. If there was\n // no change, React will filter out this update as a no-op.\n setState(selector(getLatestState()));\n\n return () => {\n subscriptions.forEach((subscription) => subscription.remove());\n };\n }, []);\n\n return state;\n}\n\nexport { useKeyboardState };\n"],"mappings":"AAAA,SAASA,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAE3C,SAASC,cAAc,QAAQ,gBAAgB;AAC/C,SAASC,kBAAkB,QAAQ,cAAc;AAIjD,MAAMC,MAAM,GAAG,CAAC,kBAAkB,EAAE,iBAAiB,CAAU;AAE/D,MAAMC,cAAc,GAAGA,CAAA,MAAO;EAC5B,GAAGF,kBAAkB,CAACG,KAAK,CAAC,CAAC;EAC7BC,SAAS,EAAEJ,kBAAkB,CAACI,SAAS,CAAC;AAC1C,CAAC,CAAC;AAIF,MAAMC,eAAsD,GAAIF,KAAK,IAAKA,KAAK;;AAE/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASG,gBAAgBA,CACvBC,QAAkC,GAAGF,eAA2C,EAC7E;EACH,MAAM,CAACF,KAAK,EAAEK,QAAQ,CAAC,GAAGV,QAAQ,CAAI,MAAMS,QAAQ,CAACL,cAAc,CAAC,CAAC,CAAC,CAAC;EAEvEL,SAAS,CAAC,MAAM;IACd,MAAMY,aAAa,GAAGR,MAAM,CAACS,GAAG,CAAEC,KAAK,IACrCZ,cAAc,CAACa,WAAW,CAACD,KAAK,EAAE;IAChC;IACA;IACAH,QAAQ,CAACD,QAAQ,CAACL,cAAc,CAAC,CAAC,CAAC,CACrC,CACF,CAAC;;IAED;IACA;IACA;IACAM,QAAQ,CAACD,QAAQ,CAACL,cAAc,CAAC,CAAC,CAAC,CAAC;IAEpC,OAAO,MAAM;MACXO,aAAa,CAACI,OAAO,CAAEC,YAAY,IAAKA,YAAY,CAACC,MAAM,CAAC,CAAC,CAAC;IAChE,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EAEN,OAAOZ,KAAK;AACd;AAEA,SAASG,gBAAgB","ignoreList":[]}
|
package/lib/module/module.js
CHANGED
package/lib/module/module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["KeyboardControllerNative","KeyboardEvents","isClosed","lastState","height","duration","timestamp","Date","getTime","target","type","appearance","addListener","e","dismiss","options","keepFocus","animated","Promise","resolve","subscription","undefined","remove","isVisible","state","KeyboardController","setDefaultMode","setInputMode","setFocusTo","preload"],"sources":["module.ts"],"sourcesContent":["import { KeyboardControllerNative, KeyboardEvents } from \"./bindings\";\n\nimport type {\n DismissOptions,\n KeyboardControllerModule,\n KeyboardEventData,\n} from \"./types\";\n\nlet isClosed = true;\nlet lastState: KeyboardEventData = {\n height: 0,\n duration: 0,\n timestamp: new Date().getTime(),\n target: -1,\n type: \"default\",\n appearance: \"light\",\n};\n\nKeyboardEvents.addListener(\"keyboardDidHide\", (e) => {\n isClosed = true;\n lastState = e;\n});\n\nKeyboardEvents.addListener(\"
|
|
1
|
+
{"version":3,"names":["KeyboardControllerNative","KeyboardEvents","isClosed","lastState","height","duration","timestamp","Date","getTime","target","type","appearance","addListener","e","dismiss","options","keepFocus","animated","Promise","resolve","subscription","undefined","remove","isVisible","state","KeyboardController","setDefaultMode","setInputMode","setFocusTo","preload"],"sources":["module.ts"],"sourcesContent":["import { KeyboardControllerNative, KeyboardEvents } from \"./bindings\";\n\nimport type {\n DismissOptions,\n KeyboardControllerModule,\n KeyboardEventData,\n} from \"./types\";\n\nlet isClosed = true;\nlet lastState: KeyboardEventData = {\n height: 0,\n duration: 0,\n timestamp: new Date().getTime(),\n target: -1,\n type: \"default\",\n appearance: \"light\",\n};\n\nKeyboardEvents.addListener(\"keyboardDidHide\", (e) => {\n isClosed = true;\n lastState = e;\n});\n\nKeyboardEvents.addListener(\"keyboardWillShow\", (e) => {\n isClosed = false;\n lastState = e;\n});\n\nconst dismiss = async (options?: Partial<DismissOptions>): Promise<void> => {\n const keepFocus = options?.keepFocus ?? false;\n const animated = options?.animated ?? true;\n\n return new Promise((resolve) => {\n if (isClosed) {\n resolve();\n\n return;\n }\n\n const subscription = KeyboardEvents.addListener(\"keyboardDidHide\", () => {\n resolve(undefined);\n subscription.remove();\n });\n\n KeyboardControllerNative.dismiss(keepFocus, animated);\n });\n};\nconst isVisible = () => !isClosed;\nconst state = () => lastState;\n\n/**\n * KeyboardController module. Helps to perform imperative actions/checks with keyboard.\n */\nexport const KeyboardController: KeyboardControllerModule = {\n setDefaultMode: KeyboardControllerNative.setDefaultMode,\n setInputMode: KeyboardControllerNative.setInputMode,\n setFocusTo: KeyboardControllerNative.setFocusTo,\n preload: KeyboardControllerNative.preload,\n dismiss,\n isVisible,\n state,\n};\n"],"mappings":"AAAA,SAASA,wBAAwB,EAAEC,cAAc,QAAQ,YAAY;AAQrE,IAAIC,QAAQ,GAAG,IAAI;AACnB,IAAIC,SAA4B,GAAG;EACjCC,MAAM,EAAE,CAAC;EACTC,QAAQ,EAAE,CAAC;EACXC,SAAS,EAAE,IAAIC,IAAI,CAAC,CAAC,CAACC,OAAO,CAAC,CAAC;EAC/BC,MAAM,EAAE,CAAC,CAAC;EACVC,IAAI,EAAE,SAAS;EACfC,UAAU,EAAE;AACd,CAAC;AAEDV,cAAc,CAACW,WAAW,CAAC,iBAAiB,EAAGC,CAAC,IAAK;EACnDX,QAAQ,GAAG,IAAI;EACfC,SAAS,GAAGU,CAAC;AACf,CAAC,CAAC;AAEFZ,cAAc,CAACW,WAAW,CAAC,kBAAkB,EAAGC,CAAC,IAAK;EACpDX,QAAQ,GAAG,KAAK;EAChBC,SAAS,GAAGU,CAAC;AACf,CAAC,CAAC;AAEF,MAAMC,OAAO,GAAG,MAAOC,OAAiC,IAAoB;EAC1E,MAAMC,SAAS,GAAG,CAAAD,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEC,SAAS,KAAI,KAAK;EAC7C,MAAMC,QAAQ,GAAG,CAAAF,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEE,QAAQ,KAAI,IAAI;EAE1C,OAAO,IAAIC,OAAO,CAAEC,OAAO,IAAK;IAC9B,IAAIjB,QAAQ,EAAE;MACZiB,OAAO,CAAC,CAAC;MAET;IACF;IAEA,MAAMC,YAAY,GAAGnB,cAAc,CAACW,WAAW,CAAC,iBAAiB,EAAE,MAAM;MACvEO,OAAO,CAACE,SAAS,CAAC;MAClBD,YAAY,CAACE,MAAM,CAAC,CAAC;IACvB,CAAC,CAAC;IAEFtB,wBAAwB,CAACc,OAAO,CAACE,SAAS,EAAEC,QAAQ,CAAC;EACvD,CAAC,CAAC;AACJ,CAAC;AACD,MAAMM,SAAS,GAAGA,CAAA,KAAM,CAACrB,QAAQ;AACjC,MAAMsB,KAAK,GAAGA,CAAA,KAAMrB,SAAS;;AAE7B;AACA;AACA;AACA,OAAO,MAAMsB,kBAA4C,GAAG;EAC1DC,cAAc,EAAE1B,wBAAwB,CAAC0B,cAAc;EACvDC,YAAY,EAAE3B,wBAAwB,CAAC2B,YAAY;EACnDC,UAAU,EAAE5B,wBAAwB,CAAC4B,UAAU;EAC/CC,OAAO,EAAE7B,wBAAwB,CAAC6B,OAAO;EACzCf,OAAO;EACPS,SAAS;EACTC;AACF,CAAC","ignoreList":[]}
|
|
@@ -5,7 +5,7 @@ declare const KeyboardChatScrollView: React.ForwardRefExoticComponent<{
|
|
|
5
5
|
inverted?: boolean;
|
|
6
6
|
offset?: number;
|
|
7
7
|
keyboardLiftBehavior?: import("./hooks").KeyboardLiftBehavior;
|
|
8
|
-
freeze?: boolean
|
|
8
|
+
freeze?: boolean | import("react-native-reanimated").SharedValue<boolean>;
|
|
9
9
|
extraContentPadding?: import("react-native-reanimated").SharedValue<number>;
|
|
10
10
|
applyWorkaroundForContentInsetHitTestBug?: boolean;
|
|
11
11
|
blankSpace?: import("react-native-reanimated").SharedValue<number>;
|
|
@@ -45,7 +45,7 @@ export type KeyboardChatScrollViewProps = {
|
|
|
45
45
|
*
|
|
46
46
|
* Default is `false`.
|
|
47
47
|
*/
|
|
48
|
-
freeze?: boolean
|
|
48
|
+
freeze?: boolean | SharedValue<boolean>;
|
|
49
49
|
/**
|
|
50
50
|
* A shared value representing additional padding from external elements
|
|
51
51
|
* (e.g., a growing multiline `TextInput` in a `KeyboardStickyView`).
|
|
@@ -4,7 +4,7 @@ type KeyboardLiftBehavior = "always" | "whenAtEnd" | "persistent" | "never";
|
|
|
4
4
|
type UseChatKeyboardOptions = {
|
|
5
5
|
inverted: boolean;
|
|
6
6
|
keyboardLiftBehavior: KeyboardLiftBehavior;
|
|
7
|
-
freeze: boolean
|
|
7
|
+
freeze: SharedValue<boolean>;
|
|
8
8
|
offset: number;
|
|
9
9
|
blankSpace: SharedValue<number>;
|
|
10
10
|
/** Extra content padding shared value — needed on iOS to correctly clamp contentOffset. */
|
|
@@ -24,7 +24,7 @@ type UseExtraContentPaddingOptions = {
|
|
|
24
24
|
contentOffsetY?: SharedValue<number>;
|
|
25
25
|
inverted: boolean;
|
|
26
26
|
keyboardLiftBehavior: KeyboardLiftBehavior;
|
|
27
|
-
freeze: boolean
|
|
27
|
+
freeze: SharedValue<boolean>;
|
|
28
28
|
};
|
|
29
29
|
/**
|
|
30
30
|
* Hook that reacts to `extraContentPadding` changes and conditionally
|
package/package.json
CHANGED
|
@@ -43,6 +43,9 @@ const KeyboardChatScrollView = forwardRef<
|
|
|
43
43
|
) => {
|
|
44
44
|
const scrollViewRef = useAnimatedRef<Reanimated.ScrollView>();
|
|
45
45
|
const onRef = useCombinedRef(ref, scrollViewRef);
|
|
46
|
+
const freezeSV = useDerivedValue(() =>
|
|
47
|
+
typeof freeze === "boolean" ? freeze : freeze.value,
|
|
48
|
+
);
|
|
46
49
|
const {
|
|
47
50
|
padding,
|
|
48
51
|
currentHeight,
|
|
@@ -55,7 +58,7 @@ const KeyboardChatScrollView = forwardRef<
|
|
|
55
58
|
} = useChatKeyboard(scrollViewRef, {
|
|
56
59
|
inverted,
|
|
57
60
|
keyboardLiftBehavior,
|
|
58
|
-
freeze,
|
|
61
|
+
freeze: freezeSV,
|
|
59
62
|
offset,
|
|
60
63
|
blankSpace,
|
|
61
64
|
extraContentPadding,
|
|
@@ -72,7 +75,7 @@ const KeyboardChatScrollView = forwardRef<
|
|
|
72
75
|
contentOffsetY,
|
|
73
76
|
inverted,
|
|
74
77
|
keyboardLiftBehavior,
|
|
75
|
-
freeze,
|
|
78
|
+
freeze: freezeSV,
|
|
76
79
|
});
|
|
77
80
|
|
|
78
81
|
const totalPadding = useDerivedValue(() =>
|
|
@@ -46,7 +46,7 @@ export type KeyboardChatScrollViewProps = {
|
|
|
46
46
|
*
|
|
47
47
|
* Default is `false`.
|
|
48
48
|
*/
|
|
49
|
-
freeze?: boolean
|
|
49
|
+
freeze?: boolean | SharedValue<boolean>;
|
|
50
50
|
/**
|
|
51
51
|
* A shared value representing additional padding from external elements
|
|
52
52
|
* (e.g., a growing multiline `TextInput` in a `KeyboardStickyView`).
|
|
@@ -64,7 +64,7 @@ function useChatKeyboard(
|
|
|
64
64
|
onStart: (e) => {
|
|
65
65
|
"worklet";
|
|
66
66
|
|
|
67
|
-
if (freeze) {
|
|
67
|
+
if (freeze.value) {
|
|
68
68
|
return;
|
|
69
69
|
}
|
|
70
70
|
|
|
@@ -229,7 +229,7 @@ function useChatKeyboard(
|
|
|
229
229
|
onEnd: (e) => {
|
|
230
230
|
"worklet";
|
|
231
231
|
|
|
232
|
-
if (freeze) {
|
|
232
|
+
if (freeze.value) {
|
|
233
233
|
return;
|
|
234
234
|
}
|
|
235
235
|
|
|
@@ -242,7 +242,7 @@ function useChatKeyboard(
|
|
|
242
242
|
padding.value = effective;
|
|
243
243
|
},
|
|
244
244
|
},
|
|
245
|
-
[inverted, keyboardLiftBehavior,
|
|
245
|
+
[inverted, keyboardLiftBehavior, offset, extraContentPadding],
|
|
246
246
|
);
|
|
247
247
|
|
|
248
248
|
return {
|
|
@@ -82,7 +82,7 @@ function useChatKeyboard(
|
|
|
82
82
|
onStart: (e) => {
|
|
83
83
|
"worklet";
|
|
84
84
|
|
|
85
|
-
if (freeze) {
|
|
85
|
+
if (freeze.value) {
|
|
86
86
|
return;
|
|
87
87
|
}
|
|
88
88
|
|
|
@@ -166,7 +166,7 @@ function useChatKeyboard(
|
|
|
166
166
|
onMove: (e) => {
|
|
167
167
|
"worklet";
|
|
168
168
|
|
|
169
|
-
if (freeze) {
|
|
169
|
+
if (freeze.value) {
|
|
170
170
|
return;
|
|
171
171
|
}
|
|
172
172
|
|
|
@@ -340,7 +340,7 @@ function useChatKeyboard(
|
|
|
340
340
|
onEnd: (e) => {
|
|
341
341
|
"worklet";
|
|
342
342
|
|
|
343
|
-
if (freeze) {
|
|
343
|
+
if (freeze.value) {
|
|
344
344
|
return;
|
|
345
345
|
}
|
|
346
346
|
|
|
@@ -358,7 +358,7 @@ function useChatKeyboard(
|
|
|
358
358
|
}
|
|
359
359
|
},
|
|
360
360
|
},
|
|
361
|
-
[inverted, keyboardLiftBehavior,
|
|
361
|
+
[inverted, keyboardLiftBehavior, offset],
|
|
362
362
|
);
|
|
363
363
|
|
|
364
364
|
return {
|
|
@@ -6,7 +6,7 @@ type KeyboardLiftBehavior = "always" | "whenAtEnd" | "persistent" | "never";
|
|
|
6
6
|
type UseChatKeyboardOptions = {
|
|
7
7
|
inverted: boolean;
|
|
8
8
|
keyboardLiftBehavior: KeyboardLiftBehavior;
|
|
9
|
-
freeze: boolean
|
|
9
|
+
freeze: SharedValue<boolean>;
|
|
10
10
|
offset: number;
|
|
11
11
|
blankSpace: SharedValue<number>;
|
|
12
12
|
/** Extra content padding shared value — needed on iOS to correctly clamp contentOffset. */
|