New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

react-native-smart-scroll-view

Package Overview
Dependencies
Maintainers
2
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-native-smart-scroll-view - npm Package Compare versions

Comparing version 1.3.5 to 1.3.6

2

package.json
{
"name": "react-native-smart-scroll-view",
"version": "1.3.5",
"version": "1.3.6",
"description": "Handles keyboard events and auto adjusts content to be visible above keyboard on focus. Further scrolling features available.",

@@ -5,0 +5,0 @@ "main": "SmartScrollView.js",

import React, {
Component,
PropTypes,
} from 'react';
import ReactNative, {
View,
StyleSheet,
ScrollView,
DeviceEventEmitter,
Keyboard,
Dimensions,
LayoutAnimation,
PropTypes,
TouchableOpacity
Platform
} from 'react-native';
import dismissKeyboard from 'react-native/Libraries/Utilities/dismissKeyboard';
import Picker from './Picker.js';
export { default as PickerInput } from './PickerInput.js';
const animations = {
const { height: screenHeight } = Dimensions.get('window');
const animations = {
layout: {

@@ -34,17 +33,2 @@ easeInEaseOut: {

const { height: screenHeight, width: screenWidth } = Dimensions.get('window');
let keyboardHeight;
switch (screenHeight) {
case 736:
keyboardHeight = 226;
break;
case 1024:
keyboardHeight = 264;
break;
default:
keyboardHeight = 226;
};
class SmartScrollView extends Component {

@@ -54,26 +38,21 @@

super();
this.state = { scrollPosition: 0, pickerOpen: false };
[
'_focusNode',
'_keyboardWillHide',
'_keyboardWillShow',
'_updateScrollPosition',
'_dismissPicker',
'_openPicker',
'_dismissKeyboard',
'_generateSmartContent',
'_renderPicker',
'_findHeights'
].forEach((method) => this[method] = this[method].bind(this))
this.state = {
scrollPosition : 0,
}
this._refCreator = this._refCreator.bind(this);
this._focusNode = this._focusNode.bind(this);
this._keyboardWillHide = this._keyboardWillHide.bind(this);
this._keyboardWillShow = this._keyboardWillShow.bind(this);
this._updateScrollPosition = this._updateScrollPosition.bind(this);
}
componentDidMount() {
setTimeout(this._findHeights, 0);
this._listeners = [
DeviceEventEmitter.addListener('keyboardWillShow', this._keyboardWillShow),
DeviceEventEmitter.addListener('keyboardWillHide', this._keyboardWillHide),
];
if (this.props.forceFocusField !== this.state.focusedField){
this._focusField('input_' + this.props.forceFocusField)
}
this._listeners = [
Keyboard.addListener(Platform.OS == 'IOS' ? 'keyboardWillShow' : 'keyboardDidShow', this._keyboardWillShow),
Keyboard.addListener(Platform.OS == 'IOS' ? 'keyboardWillHide' : 'keyboardDidHide', this._keyboardWillHide),
];
}

@@ -88,7 +67,5 @@

componentWillReceiveProps(props) {
setTimeout(this._findHeights,0);
if (
this.props.forceFocusField !== props.forceFocusField &&
this.props.forceFocusField !== this.state.focusedField
) { this._focusField('input_' + props.forceFocusField, true) }
if (props.forceFocusField !== undefined && props.forceFocusField !== this.state.focusedField){
this._focusField('input_' + props.forceFocusField)
}
}

@@ -100,117 +77,73 @@

_findHeights () {
this._container.measureLayout(1, (x, y, w, height) => {
this._findScrollWindowHeight = keyboardHeight => {
const spaceBelow = screenHeight - y - height;
// TODO: fix adjusting of height when there is space below the smart scroll view
return height - Math.max(keyboardHeight, 0);
}
this.setState({ SVDisplacementFromTop: y, originalHeight: height })
this._smartScroll.refs.InnerScrollView.measure((x,y,w,height) => {
this.setState({contentHeight:height});
});
})
_findScrollWindowHeight(keyboardHeight){
const {x, y, width, height} = this._layout
const spaceBelow = screenHeight - y - height;
return height - Math.max(keyboardHeight - spaceBelow, 0);
}
_focusField (ref, forced) {
const node = this[ref];
const { type } = node.props.smartScrollOptions;
const strippedBackRef = ref.slice('input_'.length);
this.setState({focusedField: strippedBackRef}, () => {
switch (type) {
case 'text':
if (forced) { return this[ref].focus() }
else { this._dismissPicker() }
break;
case 'picker':
dismissKeyboard();
this._openPicker();
break;
case 'custom':
dismissKeyboard();
this._dismissPicker();
this.setState({scrollWindowHeight:this.state.originalHeight});
break;
this.props.onRefFocus(strippedBackRef);
}
setTimeout(this._focusNode, 1)
})
}
_focusNode () {
const {
state: { scrollPosition, scrollWindowHeight, contentHeight, focusedField: ref },
props: { scrollPadding },
_smartScroll
} = this;
const num = React.findNodeHandle(_smartScroll);
setTimeout(() => {
this['input_'+ref].measureLayout(num, (X,Y,W,H) => {
const py = Y - scrollPosition;
if (py + H > scrollWindowHeight) {
_smartScroll.scrollTo((Y + H) - scrollWindowHeight + scrollPadding)
} else if ( py < 0 ) {
_smartScroll.scrollTo(Y - scrollPadding)
} else if (scrollPosition > (contentHeight - scrollWindowHeight)) {
_smartScroll.scrollTo(contentHeight - scrollWindowHeight);
}
});
}, 0);
}
_keyboardWillShow(e) {
const scrollWindowHeight = this._findScrollWindowHeight(e.endCoordinates.height)
this.setState({ scrollWindowHeight, keyboardUp: true});
this.setState({
scrollWindowHeight,
keyBoardUp: true
})
}
_keyboardWillHide() {
this._dismissKeyboard();
this.setState({
keyBoardUp: false
});
this._smartScroll && this._smartScroll.scrollTo({y: 0});
}
_dismissKeyboard () {
this.setState({keyboardUp: false});
_refCreator () {
const refs = arguments;
return component => Object.keys(refs).forEach(i => this[refs[i]] = component);
}
_dismissPicker () {
this.setState({pickerOpen: false});
}
_focusField (ref) {
const node = this[ref];
const {type} = node.props.smartScrollOptions;
_openPicker () {
this.setState({
pickerOpen: true,
scrollWindowHeight: this._findScrollWindowHeight(keyboardHeight),
});
switch(type) {
case 'text':
this[ref].focus();
break;
case 'custom':
this._focusNode(ref);
}
}
_renderPicker () {
_focusNode (ref) {
const {
state: {focusedField, SVDisplacementFromTop},
_dismissPicker
} = this;
const { props: {
smartScrollOptions: { type, pickerType, pickerProps, pickerTitle, onPickerDone },
onSubmitEditing
}} = this['input_' + focusedField];
scrollPosition,
scrollWindowHeight,
} = this.state;
const {
scrollPadding,
onRefFocus
} = this.props;
const num = ReactNative.findNodeHandle(this._smartScroll);
const strippedBackRef = ref.slice('input_'.length);
if (type === 'picker') {
return (
<View style = {[styles.picker, {top: screenHeight - SVDisplacementFromTop - keyboardHeight}]}>
<Picker
pickerType = { pickerType }
pickerProps = { pickerProps }
pickerTitle = { pickerTitle }
onDone = { () => {
_dismissPicker();
if ( onSubmitEditing !== undefined ) { onSubmitEditing() }
if ( onPickerDone !== undefined ) { onPickerDone() }
}}
/>
</View>
);
}
setTimeout(() => {
onRefFocus(strippedBackRef);
this.setState({focusedField: strippedBackRef})
this[ref].measureLayout(num, (X,Y,W,H) => {
const py = Y - scrollPosition;
if ( py + H > scrollWindowHeight ){
const nextScrollPosition = (Y + H) - scrollWindowHeight + scrollPadding;
this._smartScroll.scrollTo({y: nextScrollPosition});
this.setState({scrollPosition: nextScrollPosition })
} else if ( py < 0 ) {
const nextScrollPosition = Y - scrollPadding;
this._smartScroll.scrollTo({y: nextScrollPosition})
this.setState({ scrollPosition: nextScrollPosition})
}
});
}, 0);
}

@@ -222,49 +155,51 @@

_generateSmartContent (scrollChildren) {
render () {
const {
children: scrollChildren,
contentContainerStyle,
scrollContainerStyle,
zoomScale,
showsVerticalScrollIndicator,
contentInset,
onScroll
} = this.props;
let inputIndex = 0;
const smartClone = (element, i) => {
const { smartScrollOptions } = element.props;
const { type, scrollRef, moveToNext, onSubmitEditing, style, onPress } = smartScrollOptions;
let smartProps = { key: i };
const { smartScrollOptions } = element.props;
let smartProps = { key: i };
if (type !== undefined) {
const ref = 'input_' + inputIndex;
smartProps.ref = component => [ref, scrollRef && 'input_' + scrollRef]
.forEach(ref => this[ref] = component);
if (smartScrollOptions.type !== undefined) {
const ref = 'input_' + inputIndex;
if (moveToNext === true) {
const nextRef = 'input_' + (inputIndex+1);
const focusNextField = () => this._focusField(nextRef, true)
smartProps.blurOnSubmit = false;
smartProps.onSubmitEditing = onSubmitEditing ?
() => onSubmitEditing(focusNextField) :
focusNextField
}
if (type === 'text') {
smartProps.ref = this._refCreator(ref, smartScrollOptions.scrollRef && 'input_' + smartScrollOptions.scrollRef);
if (smartScrollOptions.type === 'text') {
smartProps.onFocus = () => {
element.props.onFocus && element.props.onFocus();
this._focusField(ref)
smartProps.onFocus = element.props.onFocus && element.props.onFocus();
this._focusNode(ref)
};
} else if (type === 'picker') {
smartProps.onPress = () => { this._focusField(ref); if (onPress!== undefined) { onPress()} };
smartProps.smartScrollOptions = smartScrollOptions;
smartProps.style = style;
inputIndex += 1;
return React.cloneElement(<TouchableOpacity/>, smartProps, element);
} else if (type === 'custom') {
smartProps.onPress = () => this._focusField(ref);
smartProps.smartScrollOptions = smartScrollOptions;
smartProps.activeOpacity = 0.95;
inputIndex += 1;
smartProps.style = style;
if (smartScrollOptions.moveToNext === true) {
const nextRef = 'input_' + (inputIndex+1);
const focusNextField = () => this._focusField(nextRef)
return React.cloneElement(<TouchableOpacity/>, smartProps, element.props.children)
if(typeof(element.props.returnKeyType) === 'undefined'){
smartProps.returnKeyType = 'next'
}
smartProps.blurOnSubmit = false;
smartProps.onSubmitEditing = smartScrollOptions.onSubmitEditing ?
() => smartScrollOptions.onSubmitEditing(focusNextField) :
focusNextField
}
}
inputIndex += 1
}
return React.cloneElement(element, smartProps);
return React.cloneElement(element, smartProps)
}
const recursivelyCheckAndAdd = (children, i) => {
function recursivelyCheckAndAdd(children, i) {
return React.Children.map(children, (child, j) => {

@@ -280,3 +215,3 @@ if (child && child.props !== undefined) {

} else {
return child;
return child
}

@@ -286,27 +221,4 @@ })

return recursivelyCheckAndAdd(scrollChildren, '0');
}
const content = recursivelyCheckAndAdd(scrollChildren, '0');
render () {
const {
props: {
children: scrollChildren,
contentContainerStyle,
scrollContainerStyle,
zoomScale,
showsVerticalScrollIndicator,
contentInset,
onScroll
},
state: {
pickerOpen,
scrollWindowHeight,
keyboardUp
},
_generateSmartContent,
_updateScrollPosition,
_renderPicker
} = this;
const content = _generateSmartContent(scrollChildren);
return (

@@ -316,4 +228,7 @@ <View

style = {scrollContainerStyle}
onLayout={(e) => this._layout = e.nativeEvent.layout}
>
<View style = {(keyboardUp || pickerOpen) ? { height: scrollWindowHeight } : styles.flex1} >
<View
style = {this.state.keyBoardUp ? { height: this.state.scrollWindowHeight } : styles.flex1}
>
<ScrollView

@@ -325,4 +240,4 @@ ref = { component => this._smartScroll=component }

onScroll = { (event) => {
_updateScrollPosition(event);
onScroll(event);
this._updateScrollPosition(event)
onScroll(event)
}}

@@ -339,3 +254,2 @@ scrollEventThrottle = { 16 }

</ScrollView>
{ pickerOpen && _renderPicker() }
</View>

@@ -350,8 +264,2 @@ </View>

flex: 1
},
picker: {
height: keyboardHeight,
position: 'absolute',
width: screenWidth,
alignItems: 'stretch'
}

@@ -361,5 +269,5 @@ });

SmartScrollView.propTypes = {
forceFocusField: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
scrollContainerStyle: PropTypes.number,
contentContainerStyle: PropTypes.number,
forceFocusField: PropTypes.oneOf(PropTypes.number, PropTypes.string),
scrollContainerStyle: View.propTypes.style,
contentContainerStyle: View.propTypes.style,
zoomScale: PropTypes.number,

@@ -383,1 +291,18 @@ showsVerticalScrollIndicator: PropTypes.bool,

export default SmartScrollView;
// import dismissKeyboard from 'dismissKeyboard';
// this._scrollTap = this._scrollTap.bind(this);
// lastTap: 0
// _scrollTap () {
// const {lastTap} = this.state;
// const currentTap = new Date().getTime();
// console.log("tap")
//
// if (currentTap - lastTap < 500) {
// dismissKeyboard()
// }
//
// this.setState({
// lastTap: currentTap
// })
// }
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc