├── .gitignore ├── .travis.yml ├── CNAME ├── README.md ├── demo.gif ├── index.js ├── license.md └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "node" 4 | deploy: 5 | provider: npm 6 | email: patel.mayank@outlook.com 7 | api_key: 8 | secure: wVytlKecwCh6pGhC3LvZ1Qav7WaPNqBPd20aEt44O4qHfYP5KGAtitdBkcO4LirnCMDV6H48OCMhjabKwXD3Hl9D7LnUHE12n1Dz7x6RrEwtzsZ5X2PQyBc9Jk9W3vRHtRX9z3sugpTcNUUg5hRZMkyJifDW/DiQPGjnAYlWmyDmQyoJPAmYexPekB/lQ81R+s8e4UhCeW2ysCZBtebhP43Lb5axsvt3RNVFHm+6cY1EjT4zAYBVNtdue4LlcKz2eX9JP4A6K5K0sQQ/zCa2GqsD9Mgr30ZtPHhdbL7DmY11qdw1Ps2TkKeTGwrizGvp/kIBWb3Ys7oz2CEnMagksv9jRaD4JOJ2cvL1qBsF7fC74oIuBnWMl/8gKqPPbHyzc3yMr7kW4zcq8McBjUFZHF+GVe4aEVNfx0VEMlfjSKD9DEXJakRUR+NIE2jh8fVOt5NSrMVxzAMHOnujPaaL2C/LI593DlPh+ejEEydPZOVLYNBN6sz1FYMg7PiDB4Oa2oBRn2+KMrDlTfHgkhQZaNXyOSd3jBzIoUwStaRvw6+5tjpBxtdvWjSETQyfwGQ4sarGkuG+E6J3kdvNgYot6dZxdzRyav47ffUniouBx+kB+OBAFl8Jl5vPVse0oBKEoYNdPWSHqyC4LMl1VxIjrR+jraLOJw+asVgXGCylvdY= 9 | on: 10 | repo: mayank-patel/react-native-floating-labels 11 | branch: release 12 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | react-native-floating-labels.js.org 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## react-native-floating-labels [![Build Status](https://travis-ci.org/mayank-patel/react-native-floating-labels.svg?branch=master)](https://travis-ci.org/mayank-patel/react-native-floating-labels) [![npm version](https://badge.fury.io/js/react-native-floating-labels.svg)](https://badge.fury.io/js/react-native-floating-labels) [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) [![Code Climate](https://codeclimate.com/github/mayank-patel/react-native-floating-labels/badges/gpa.svg)](https://codeclimate.com/github/mayank-patel/react-native-floating-labels) 2 | 3 | A `` component for react-native. This is still very much a work 4 | in progress and only handles the simplest of cases, ideas and 5 | contributions are very welcome. 6 | 7 | ![Demo](https://raw.githubusercontent.com/mayank-patel/react-native-floating-labels/master/demo.gif) 8 | 9 | ## Add it to your project 10 | 11 | 12 | 1. Run `npm install react-native-floating-labels --save` 13 | 2. `var FloatingLabel = require('react-native-floating-labels');` 14 | 15 | ## Usage 16 | 17 | ```javascript 18 | 'use strict'; 19 | 20 | var React = require('react-native'); 21 | 22 | var FloatingLabel = require('react-native-floating-labels'); 23 | 24 | var { 25 | AppRegistry, 26 | StyleSheet, 27 | View, 28 | } = React; 29 | 30 | class form extends React.Component { 31 | 32 | constructor(props, context) { 33 | super(props, context); 34 | 35 | this.state = { 36 | dirty: false, 37 | }; 38 | } 39 | 40 | onBlur() { 41 | console.log('#####: onBlur'); 42 | } 43 | 44 | render() { 45 | return ( 46 | 47 | Email 54 | First Name 60 | Last Name 65 | 66 | ); 67 | } 68 | }; 69 | 70 | var styles = StyleSheet.create({ 71 | container: { 72 | flex: 1, 73 | paddingTop: 65, 74 | backgroundColor: 'white', 75 | }, 76 | labelInput: { 77 | color: '#673AB7', 78 | }, 79 | formInput: { 80 | borderBottomWidth: 1.5, 81 | marginLeft: 20, 82 | borderColor: '#333', 83 | }, 84 | input: { 85 | borderWidth: 0 86 | } 87 | }); 88 | 89 | AppRegistry.registerComponent('form', () => form); 90 | 91 | 92 | 93 | 94 | ``` 95 | 96 | Additional Props: 97 | 98 | FloatingLabel is just like any TextInput. It supports the below mentioned events handlers: 99 | 100 | ``` 101 | Following properties of TextInput are supported: 102 | 103 | - autoCapitalize 104 | - autoCorrect 105 | - autoFocus 106 | - bufferDelay 107 | - clearButtonMode 108 | - clearTextOnFocus 109 | - controlled 110 | - editable 111 | - enablesReturnKeyAutomatically 112 | - keyboardType 113 | - multiline 114 | - password 115 | - returnKeyType 116 | - selectTextOnFocus 117 | - selectionState 118 | - style 119 | - testID 120 | - value 121 | 122 | Following events are supported: 123 | 124 | - onBlur 125 | - onChange 126 | - onChangeText 127 | - onEndEditing 128 | - onFocus 129 | - onSubmitEditing 130 | 131 | ``` 132 | 133 | 134 | 135 | 136 | **MIT Licensed** 137 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayank-patel/react-native-floating-labels/93d6e67e3dafb07a23c702b9114b891194788b39/demo.gif -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | import React from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import createReactClass from 'create-react-class'; 5 | 6 | import { 7 | StyleSheet, 8 | TextInput, 9 | Animated, 10 | Easing, 11 | Text, 12 | View, 13 | Platform, 14 | ViewPropTypes 15 | } from 'react-native'; 16 | 17 | var textPropTypes = Text.propTypes || ViewPropTypes 18 | var textInputPropTypes = TextInput.propTypes || textPropTypes 19 | var propTypes = { 20 | ...textInputPropTypes, 21 | inputStyle: textInputPropTypes.style, 22 | labelStyle: textPropTypes.style, 23 | disabled: PropTypes.bool, 24 | style: ViewPropTypes.style, 25 | } 26 | 27 | var FloatingLabel = createReactClass({ 28 | propTypes: propTypes, 29 | 30 | getInitialState() { 31 | var state = { 32 | text: this.props.value, 33 | dirty: (this.props.value || this.props.placeholder) 34 | }; 35 | 36 | var style = state.dirty ? dirtyStyle : cleanStyle 37 | state.labelStyle = { 38 | fontSize: new Animated.Value(style.fontSize), 39 | top: new Animated.Value(style.top) 40 | } 41 | 42 | return state 43 | }, 44 | 45 | componentDidUpdate(props) { 46 | if (typeof props.value !== 'undefined' && props.value !== this.state.text) { 47 | this.setState({ text: props.value, dirty: !!props.value }) 48 | this._animate(!!props.value) 49 | } 50 | }, 51 | 52 | _animate(dirty) { 53 | var nextStyle = dirty ? dirtyStyle : cleanStyle 54 | var labelStyle = this.state.labelStyle 55 | var anims = Object.keys(nextStyle).map(prop => { 56 | return Animated.timing( 57 | labelStyle[prop], 58 | { 59 | toValue: nextStyle[prop], 60 | duration: 200, 61 | useNativeDriver: false 62 | }, 63 | Easing.ease 64 | ) 65 | }) 66 | 67 | Animated.parallel(anims).start() 68 | }, 69 | 70 | _onFocus() { 71 | this._animate(true) 72 | this.setState({ dirty: true }) 73 | if (this.props.onFocus) { 74 | this.props.onFocus(arguments); 75 | } 76 | }, 77 | 78 | _onBlur() { 79 | if (!this.state.text) { 80 | this._animate(false) 81 | this.setState({ dirty: false }); 82 | } 83 | 84 | if (this.props.onBlur) { 85 | this.props.onBlur(arguments); 86 | } 87 | }, 88 | 89 | onChangeText(text) { 90 | this.setState({ text }) 91 | if (this.props.onChangeText) { 92 | this.props.onChangeText(text) 93 | } 94 | }, 95 | 96 | updateText(event) { 97 | var text = event.nativeEvent.text 98 | this.setState({ text }) 99 | 100 | if (this.props.onEndEditing) { 101 | this.props.onEndEditing(event) 102 | } 103 | }, 104 | 105 | _renderLabel() { 106 | return ( 107 | 111 | {this.props.children} 112 | 113 | ) 114 | }, 115 | 116 | render() { 117 | var props = { 118 | autoCapitalize: this.props.autoCapitalize, 119 | autoCorrect: this.props.autoCorrect, 120 | autoFocus: this.props.autoFocus, 121 | bufferDelay: this.props.bufferDelay, 122 | clearButtonMode: this.props.clearButtonMode, 123 | clearTextOnFocus: this.props.clearTextOnFocus, 124 | controlled: this.props.controlled, 125 | editable: this.props.editable, 126 | enablesReturnKeyAutomatically: this.props.enablesReturnKeyAutomatically, 127 | keyboardType: this.props.keyboardType, 128 | multiline: this.props.multiline, 129 | numberOfLines: this.props.numberOfLines, 130 | onBlur: this._onBlur, 131 | onChange: this.props.onChange, 132 | onChangeText: this.onChangeText, 133 | onEndEditing: this.updateText, 134 | onFocus: this._onFocus, 135 | ref: this.props.myRef, 136 | onSubmitEditing: this.props.onSubmitEditing, 137 | password: this.props.secureTextEntry || this.props.password, // Compatibility 138 | placeholder: this.props.placeholder, 139 | secureTextEntry: this.props.secureTextEntry || this.props.password, // Compatibility 140 | returnKeyType: this.props.returnKeyType, 141 | selectTextOnFocus: this.props.selectTextOnFocus, 142 | selectionState: this.props.selectionState, 143 | selectionColor: this.props.selectionColor, 144 | style: [styles.input], 145 | testID: this.props.testID, 146 | accessibilityLabel: this.props.accessibilityLabel, 147 | value: this.state.text, 148 | underlineColorAndroid: this.props.underlineColorAndroid, // android TextInput will show the default bottom border 149 | onKeyPress: this.props.onKeyPress 150 | }, 151 | elementStyles = [styles.element]; 152 | 153 | if (this.props.inputStyle) { 154 | props.style.push(this.props.inputStyle); 155 | } 156 | 157 | if (this.props.style) { 158 | elementStyles.push(this.props.style); 159 | } 160 | 161 | return ( 162 | 163 | {this._renderLabel()} 164 | 167 | 168 | 169 | ); 170 | }, 171 | }); 172 | 173 | var labelStyleObj = { 174 | marginTop: 21, 175 | paddingLeft: 9, 176 | color: '#AAA', 177 | position: 'absolute' 178 | } 179 | 180 | if (Platform.OS === 'web') { 181 | labelStyleObj.pointerEvents = 'none' 182 | } 183 | 184 | var styles = StyleSheet.create({ 185 | element: { 186 | position: 'relative' 187 | }, 188 | input: { 189 | height: 40, 190 | borderColor: 'gray', 191 | backgroundColor: 'transparent', 192 | justifyContent: 'center', 193 | borderWidth: 1, 194 | color: 'black', 195 | fontSize: 20, 196 | borderRadius: 4, 197 | paddingLeft: 10, 198 | marginTop: 20, 199 | }, 200 | label: labelStyleObj 201 | }) 202 | 203 | var cleanStyle = { 204 | fontSize: 20, 205 | top: 7 206 | } 207 | 208 | var dirtyStyle = { 209 | fontSize: 12, 210 | top: -17, 211 | } 212 | 213 | module.exports = FloatingLabel; 214 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-present Mayank Patel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-floating-labels", 3 | "version": "1.1.10", 4 | "description": "Reusabe floating lable component for react native", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/mayank-patel/react-native-floating-labels" 9 | }, 10 | "keywords": [ 11 | "react-component", 12 | "react-native", 13 | "floating-labels", 14 | "ios", 15 | "android" 16 | ], 17 | "dependencies": { 18 | 19 | }, 20 | "scripts": { 21 | "test": "echo 'Success'" 22 | }, 23 | "author": "Mayank Patel", 24 | "license": "MIT" 25 | } 26 | --------------------------------------------------------------------------------