Related
I'm using react functional components inside that, I have two different array objects. I would like to render the array objects based on the condition which I have. I'm using the function hooks to define a reference and assign to it dynamically. But, this is returning null. can someone help me on this ? In the below code isDemandGraph is returning null while rendering.
function gridHeatMap(props) {
const heatMap = [
{ color: 'redVeryHigh', value: 50 },
{ color: 'redHigh', value: 25 },
{ color: 'redMedium', value: 20 },
{ color: 'redLow', value: 15 },
{ color: 'white', value: 0 },
{ color: 'greenLow', value: 15 },
{ color: 'greenMedium', value: 20 },
{ color: 'greenHigh', value: 25 },
{ color: 'greenVeryHigh', value: 50 },
];
const demandHeatMap = heatMap.reverse();
const isDemandGraph = useRef(null);
const { height, title, viewName } = props;
const classes = useStyles();
return (
<div className={classes.root}>
<div className={classes.title}>{title}</div>
<Grid container spacing={0}>
{viewName === 'demand' ? { isDemandGraph: heatMap } : { isDemandGraph: demandHeatMap }}
{isDemandGraph.map((item, index) => {
return (
<Grid item style={{ flexGrow: '1', height, width: '11%' }} className={item.color}>
</Grid>
</Grid>
</div>
)
It won't work that way, calling the isDemandGraph inside the ternary operator does not assign value to the same.
Also, you should use useState instead of useRef for your usecase.
I am adding the updated code snippet, it should work as expected:
function gridHeatMap(props) {
const heatMap = [
{ color: 'redVeryHigh', value: 50 },
{ color: 'redHigh', value: 25 },
{ color: 'redMedium', value: 20 },
{ color: 'redLow', value: 15 },
{ color: 'white', value: 0 },
{ color: 'greenLow', value: 15 },
{ color: 'greenMedium', value: 20 },
{ color: 'greenHigh', value: 25 },
{ color: 'greenVeryHigh', value: 50 },
];
const demandHeatMap = heatMap.reverse();
const { height, title, viewName } = props;
const [isDemandGraph, setIsDemandGraph ] = useState(viewName === 'demand' ? heatMap : demandHeatMap);
// setIsDemandGraph can be used to update the value of `isDemandGraph`
const classes = useStyles();
return (
<div className={classes.root}>
<div className={classes.title}>{title}</div>
<Grid container spacing={0}>
{isDemandGraph.map((item, index) => {
return (
<Grid item style={{ flexGrow: '1', height, width: '11%' }} className={item.color}>
</Grid>
</div>
I suggest you to use useState instead of useRef and use useEffect to listen prop changes like:
function gridHeatMap(props) {
const { height, title, viewName } = props;
const [isDemandGraph, setisDemandGraph] = useState([]);
const classes = useStyles();
const heatMap = [
{ color: 'redVeryHigh', value: 50 },
{ color: 'redHigh', value: 25 },
{ color: 'redMedium', value: 20 },
{ color: 'redLow', value: 15 },
{ color: 'white', value: 0 },
{ color: 'greenLow', value: 15 },
{ color: 'greenMedium', value: 20 },
{ color: 'greenHigh', value: 25 },
{ color: 'greenVeryHigh', value: 50 },
];
const demandHeatMap = heatMap.reverse();
useEffect(() => {
viewName === 'demand' ? setisDemandGraph(heatMap) : setisDemandGraph(demandHeatMap);
}, [viewName]);
return (
<div className={classes.root}>
<div className={classes.title}>{title}</div>
<Grid container spacing={0}>
{isDemandGraph.map((item, index) => {
return (
<Grid item style={{ flexGrow: '1', height, width: '11%' }} className={item.color}>
</Grid>
</div>
)
I think this is how I would go (please notice I modified a bit the returned JSX, as the one in your code did not look correct to me, so you might want to double check it):
import React, { useState, useMemo, useEffect } from 'react';
// ... other imports
function gridHeatMap({ height, title, viewName }) {
const heatMap = useMemo(() => ([
{ color: 'redVeryHigh', value: 50 },
{ color: 'redHigh', value: 25 },
{ color: 'redMedium', value: 20 },
{ color: 'redLow', value: 15 },
{ color: 'white', value: 0 },
{ color: 'greenLow', value: 15 },
{ color: 'greenMedium', value: 20 },
{ color: 'greenHigh', value: 25 },
{ color: 'greenVeryHigh', value: 50 },
]), []);
const [currentHeatMap, setCurrentHeatMap] = useState(heatMap);
useEffect(() => {
viewName === 'demand'
? setCurrentHeatMap(heatMap)
: setCurrentHeatMap(heatMap.reverse());
}, [viewName]);
const classes = useStyles();
return (
<div className={classes.root}>
<div className={classes.title}>{title}</div>
<GridContainer spacing={0}>
{
currentHeatMap.map((item, index) => (
<Grid
key={`grid-${index}-${item.color}`}
className={item.color}
style={{ flexGrow: '1', height, width: '11%' }}
item
/>
));
}
</GridContainer>
</div>
);
}
export default gridHeatMap;
React beginner here, i'm currently learning Reactjs, since everybody is saying React hooks is easier to start with, so i started with hooks, but everywhere is mainly react with classes, here in this example (antd table) it is coded using classes, if i have understood it currently, i should put 'searchText:'',searchedColumn:'',' into useState, and dont need useEffect ? since there is no componentdimount or udpate .. ? just for learning want to change this class code into Hooks, sory for mistakes because english is not my mother language:
import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Table, Input, Button, Space } from 'antd';
import Highlighter from 'react-highlight-words';
import { SearchOutlined } from '#ant-design/icons';
const data = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
},
{
key: '2',
name: 'Joe Black',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Jim Green',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
{
key: '4',
name: 'Jim Red',
age: 32,
address: 'London No. 2 Lake Park',
},
];
class App extends React.Component {
state = {
searchText: '',
searchedColumn: '',
};
getColumnSearchProps = dataIndex => ({
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
<div style={{ padding: 8 }}>
<Input
ref={node => {
this.searchInput = node;
}}
placeholder={`Search ${dataIndex}`}
value={selectedKeys[0]}
onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
onPressEnter={() => this.handleSearch(selectedKeys, confirm, dataIndex)}
style={{ width: 188, marginBottom: 8, display: 'block' }}
/>
<Space>
<Button
type="primary"
onClick={() => this.handleSearch(selectedKeys, confirm, dataIndex)}
icon={<SearchOutlined />}
size="small"
style={{ width: 90 }}
>
Search
</Button>
<Button onClick={() => this.handleReset(clearFilters)} size="small" style={{ width: 90 }}>
Reset
</Button>
<Button
type="link"
size="small"
onClick={() => {
confirm({ closeDropdown: false });
this.setState({
searchText: selectedKeys[0],
searchedColumn: dataIndex,
});
}}
>
Filter
</Button>
</Space>
</div>
),
filterIcon: filtered => <SearchOutlined style={{ color: filtered ? '#1890ff' : undefined }} />,
onFilter: (value, record) =>
record[dataIndex]
? record[dataIndex].toString().toLowerCase().includes(value.toLowerCase())
: '',
onFilterDropdownVisibleChange: visible => {
if (visible) {
setTimeout(() => this.searchInput.select(), 100);
}
},
render: text =>
this.state.searchedColumn === dataIndex ? (
<Highlighter
highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }}
searchWords={[this.state.searchText]}
autoEscape
textToHighlight={text ? text.toString() : ''}
/>
) : (
text
),
});
handleSearch = (selectedKeys, confirm, dataIndex) => {
confirm();
this.setState({
searchText: selectedKeys[0],
searchedColumn: dataIndex,
});
};
handleReset = clearFilters => {
clearFilters();
this.setState({ searchText: '' });
};
render() {
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
width: '30%',
...this.getColumnSearchProps('name'),
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
width: '20%',
...this.getColumnSearchProps('age'),
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
...this.getColumnSearchProps('address'),
},
];
return <Table columns={columns} dataSource={data} />;
}
}
ReactDOM.render(<App />, document.getElementById('container'));
Code can also be found here: https://codesandbox.io/s/lq2it?file=/package.json
Yes, searchText and searchedColumn are states and should be declared with useState like so:
const [searchText, updateSearchText] = useState('default_state');
const [searchedColumn, updateSearchedColumn] = useState('default_state');
updateSearchText(some_value) is the equivalent for
this.setState({
searchText : some_value
})
and updateSearchedColumn is the same said above but for the state: searchedColumn
I used the code from this article as an example.
It is possible to read the data, but not to save it.
Code:
const { Component, Fragment } = wp.element;
const {
RichText,
InspectorControls,
PanelColorSettings,
AlignmentToolbar,
BlockControls,
} = wp.editor;
const { Button, PanelBody, SelectControl, TextControl } = wp.components;
const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;
const { withSelect, withDispatch } = wp.data;
class Inspector extends Component {
constructor(props) {
super(...arguments);
}
render() {
const backgroundColors = [
{ color: "#525252", name: "Черный" },
{ color: "#872d2d", name: "Акцентный красный" },
{ color: "#e49312", name: "Акцентный желтый" },
{ color: "#bab3a6", name: "Акцентный кремовый" },
];
const fontSizeOptions = [
{ value: "14px", label: __("14px") },
{ value: "16px", label: __("16px") },
{ value: "18px", label: __("18px") },
{ value: "22px", label: __("22px") },
{ value: "28px", label: __("28px") },
];
const paddingTopOptions = [
{ value: "0px", label: __("0px") },
{ value: "10px", label: __("10px") },
{ value: "25px", label: __("25px") },
{ value: "50px", label: __("50px") },
];
const paddingBottomOptions = [
{ value: "0px", label: __("0px") },
{ value: "10px", label: __("10px") },
{ value: "25px", label: __("25px") },
{ value: "50px", label: __("50px") },
];
const {
setAttributes,
attributes: { text_color, font_size, padding_top, padding_bottom },
} = this.props;
let PluginMetaFields = (props) => {
return (
<>
<TextControl
value={props.text_metafield}
label={__("Text Meta", "textdomain")}
onChange={(value) => props.onMetaFieldChange(value)}
/>
</>
);
};
PluginMetaFields = withSelect((select) => {
return {
text_metafield: select("core/editor").getEditedPostAttribute("meta")[
"_myprefix_text_metafield"
],
};
})(PluginMetaFields);
PluginMetaFields = withDispatch((dispatch) => {
return {
onMetaFieldChange: (value) => {
dispatch("core/editor").editPost({
meta: { _myprefix_text_metafield: value },
});
},
};
})(PluginMetaFields);
return (
<InspectorControls key="inspector">
<PanelBody title={__("Настройки абзаца")}>
<PanelColorSettings
title={__("Цвет шрифта")}
initialOpen={true}
colorSettings={[
{
value: text_color,
colors: backgroundColors,
onChange: (value) => setAttributes({ text_color: value }),
label: __("Цвет шрифта"),
},
]}
/>
<SelectControl
label={__("Размер шрифта")}
options={fontSizeOptions}
value={font_size}
onChange={(value) => this.props.setAttributes({ font_size: value })}
/>
<SelectControl
label={__("Отступ сверху")}
options={paddingTopOptions}
value={padding_top}
onChange={(value) =>
this.props.setAttributes({ padding_top: value })
}
/>
<SelectControl
label={__("Отступ снизу")}
options={paddingBottomOptions}
value={padding_bottom}
onChange={(value) =>
this.props.setAttributes({ padding_bottom: value })
}
/>
<PluginMetaFields />
</PanelBody>
</InspectorControls>
);
}
}
class HeadlineBlock extends Component {
render() {
const {
attributes: {
headline,
text_color,
font_size,
padding_top,
padding_bottom,
alignment,
},
setAttributes,
} = this.props;
const onChangeAlignment = (newAlignment) => {
this.props.setAttributes({
alignment: newAlignment === undefined ? "none" : newAlignment,
});
};
return [
<Inspector {...{ setAttributes, ...this.props }} />,
<div>
{
<BlockControls>
<AlignmentToolbar value={alignment} onChange={onChangeAlignment} />
</BlockControls>
}
<RichText
tagName="p"
placeholder={__("Текст...")}
keepPlaceholderOnFocus
value={headline}
formattingControls={["bold", "italic", "strikethrough", "link"]}
className={"font-" + font_size + " post-desc__p-text"}
style={{
color: text_color,
textAlign: alignment,
}}
onChange={(value) => setAttributes({ headline: value })}
/>
</div>,
];
}
}
registerBlockType("amm-custom-block/test-block", {
title: __("Тест блок"),
icon: "shield",
category: "AMM",
attributes: {
headline: {
type: "string",
},
alignment: {
type: "string",
default: "none",
},
text_color: {
type: "string",
default: "#525252",
},
font_size: {
type: "string",
default: "14px",
},
padding_top: {
type: "string",
default: "50px",
},
padding_bottom: {
type: "string",
default: "0px",
},
},
edit: HeadlineBlock,
save: function (props) {
const {
attributes: {
headline,
text_color,
font_size,
padding_top,
padding_bottom,
alignment,
},
} = props;
return (
<Fragment>
{headline && !!headline.length && (
<RichText.Content
tagName="p"
className={"font-" + font_size + " post-desc__p-text"}
style={{
color: text_color,
paddingTop: padding_top,
paddingBottom: padding_bottom,
textAlign: alignment,
}}
value={headline}
/>
)}
</Fragment>
);
},
});
So far just added a text field to the block and am trying to read and save the data.
With reading everything is OK, but saving the data does not work and there are no errors.
Any idea why this is happening?
sorry english is not a native language
The meta field _myprefix_text_metafield is a protected field as it starts with a "_" (underscore). This is why you can read the value in withSelect() but not save over it withDispatch() without passing auth_callback.
To save to a protected field, the auth_callback is required, eg:
<?php
register_post_meta( 'post', '_myprefix_text_metafield', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'auth_callback' => function() {
return current_user_can( 'edit_posts' );
})
);
?>
There is an example in the tutorial you are following:
https://css-tricks.com/managing-wordpress-metadata-in-gutenberg-using-a-sidebar-plugin/#post-291605
Alternatively, if your meta field is not required to be protected/private: re-register your meta field as myprefix_text_metafield (no underscore in the name and no auth_callback) and your current code will work, eg:
<?php
register_post_meta( 'post', 'myprefix_text_metafield', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string'
);
?>
I am trying to identify a specific panel in an array when it is expanded and be able to connect that panel's id to the button, as well as disable the button if no panel is expanded or more than 1 panel is expanded. For whatever reason, it's not taking in the id at all. Also, I am having problems with how to disable the button correctly.
export default class WorkoutList extends Component {
constructor(props) {
super(props);
this.state = {
workoutlist: [
{
id: uuid.v4(),
name: 'Leg Day',
date: '08/09/19',
duration: 60,
exerciselist: [
{
id: uuid.v4(),
exerciseName: 'Squats',
numberOfSets: 3,
reps: 12,
weight: 135,
},
{
id: uuid.v4(),
exerciseName: 'Leg press',
numberOfSets: 3,
reps: 10,
weight: 150,
},
{
id: uuid.v4(),
exerciseName: 'Lunges',
numberOfSets: 4,
reps: 12,
},
],
selected: false,
},
{
id: uuid.v4(),
name: 'Arm Day',
date: '08/10/19',
duration: 90,
exerciselist: [
{
id: uuid.v4(),
exerciseName: 'Bench Press',
numberOfSets: 5,
reps: 5,
weight: 225,
},
{
id: uuid.v4(),
exerciseName: 'Chest Flies',
numberOfSets: 3,
reps: 10,
weight: 50,
},
{
id: uuid.v4(),
exerciseName: 'Tricep Extensions',
numberOfSets: 4,
reps: 12,
weight: 70,
},
],
selected: false,
},
{
id: uuid.v4(),
name: 'Running',
date: '08/11/19',
duration: 40,
exerciselist: [],
selected: false,
},
],
disabled: false
}
this.handleSelectedPanel = this.handleSelectedPanel.bind(this);
this.handleButton = this.handleButton.bind(this);
}
handleSelectedPanel(id) {
const { workoutlist } = this.state;
this.setState({
workoutlist: workoutlist.map(workout => {
if (workout.id === id) {
workout.selected = !workout.selected
}
return workout;
})
})
}
handleButton(){
const { workoutlist, disabled } = this.state;
let count = 0;
workoutlist.map((workout) => {
if(workout.selected === true) {
count = count + 1;
}
return count;
})
if (count !== 1) {
this.setState({
disabled: true
})
} else {
this.setState({
disabled: false
})
}
return disabled;
}
render() {
const { workoutlist } = this.state;
return (
<div>
<CssBaseline />
<ClientMenuBar title="My Workouts" />
<div style={styles.workoutlist}>
<Paper style={styles.paper} elevation={0}>
{workoutlist.map((workout) => (
<WorkoutItem
key={workout.id}
workout={workout}
onSelectedPanel={this.handleSelectedPanel}
/>
))}
</Paper>
<Button
variant="contained"
color="primary"
size="small"
style={styles.button}
disabled={this.handleButton}
>
Start Workout
</Button>
</div>
</div>
)
}
}
export default class WorkoutItem extends Component {
constructor(props){
super(props);
this.handleSelectedPanel = this.handleSelectedPanel.bind(this);
}
handleSelectedPanel(e) {
this.props.onSelectedPanel(e.target.id);
}
render() {
const { id, name, date, duration, exerciselist } = this.props.workout;
return (
<ExpansionPanel style={styles.panel} id={id} onChange={this.handleSelectedPanel}>
<ExpansionPanelSummary>
<Typography variant="button" style={{ width: "33%" }}>
{name}
</Typography>
<Typography variant="button" style={{ width: "33%" }}>
({date})
</Typography>
<Typography align="right" style={{ width: "33%" }}>
~{duration} mins
</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<Table size="medium" style={styles.table}>
<TableHead>
<TableRow>
<TableCell padding="none">Name</TableCell>
<TableCell padding="none" align="right"># of sets</TableCell>
<TableCell padding="none" align="right">reps</TableCell>
<TableCell padding="none" align="right">weight</TableCell>
</TableRow>
</TableHead>
<TableBody>
{exerciselist.map((exercise) => (
<ExerciseList
key={exercise.id}
exercise={exercise}
/>
))}
</TableBody>
</Table>
<ExpansionPanelActions disableSpacing style={styles.actionButton}>
<Button color="primary" size="small" disableRipple>
edit
</Button>
</ExpansionPanelActions>
</ExpansionPanelDetails>
</ExpansionPanel>
)
}
}
It doesn't seem to be taking in the id at all, and when i try to disable the button, it throws this error:
Warning: Failed prop type: Invalid prop disabled of type function supplied to ForwardRef(Button), expected boolean.
The warning you are seeing comes from:
<Button
variant="contained"
color="primary"
size="small"
style={styles.button}
disabled={this.handleButton}
>
In the error it says a function is passed to disabled which should be a boolean, so change the prop that disabled takes to be that boolean (rather than the function this.handleButton).
e.target.id doesn't have what you actually want in there (it actually probably isn't a thing). You can use e.target.value to get a value out of something like an input where you want to get something information from the DOM node you are working with but in this case the information isn't something entered and actually something that the component already has in its scope (in the props). So instead of:
handleSelectedPanel(e) {
this.props.onSelectedPanel(e.target.id);
}
do this
handleSelectedPanel(e) {
this.props.onSelectedPanel(this.props.workout.id);
}
I'm currently working on an input with mask in react-native, however I'd like to avoid input of non-numeric characters. I did, however I'd like to avoid the behavior below:
enter image description here
'use strict';
import React, { Component, PropTypes } from 'react';
import { styles, cleanStyle, dirtyStyle } from './styles';
import { colors } from '../../config/styles';
import {
Animated,
Easing,
Platform,
StyleSheet,
Text,
TextInput,
View,
Keyboard,
} from 'react-native';
const textPropTypes = Text.propTypes || View.propTypes;
const textInputPropTypes = TextInput.propTypes || textPropTypes;
const propTypes = {
...textInputPropTypes,
inputStyle: textInputPropTypes.style,
labelStyle: textPropTypes.style,
disabled: PropTypes.bool,
style: View.propTypes.style,
};
const SMInput = React.createClass({
propTypes,
getDefaultProps() {
return {
editable: true,
onlyNumbers: false,
underlineColorAndroid: 'transparent'
};
},
getInitialState() {
Keyboard.addListener('keyboardDidChangeFrame', () => {
console.log('keyboardDidChangeFrame');
});
const state = {
text: (this.props.value) ? this.props.value.toString() : '',
dirty: !!this.props.value,
borderColor: new Animated.Value(0),
labelColor: new Animated.Value(0),
maxLength: this.props.maxLength,
placeHolder: '',
};
const style = state.dirty ? dirtyStyle : cleanStyle;
state.labelStyle = {
fontSize: new Animated.Value(style.fontSize),
top: new Animated.Value(style.top),
position: new Animated.Value(style.position),
}
return state;
},
_animate(dirty) {
const animateTime = 150;
const nextStyle = dirty ? dirtyStyle : cleanStyle;
const labelStyle = this.state.labelStyle;
const anims = Object.keys(nextStyle).map(prop => {
return Animated.timing(
labelStyle[prop],
{
toValue: nextStyle[prop],
duration: animateTime,
},
Easing.ease
)
});
setTimeout(() => {
if (this.props.placeholder && dirty) {
this.setState({
placeHolder: this.props.placeholder
});
}
}, 120);
anims.push(
Animated.timing (
this.state.borderColor, {
toValue: dirty ? 1 : 0,
duration: animateTime,
}
)
);
anims.push(
Animated.timing (
this.state.labelColor, {
toValue: dirty ? 1 : 0,
duration: animateTime,
}
)
);
Animated.parallel(anims).start();
},
_onFocus() {
this._animate(true);
this.setState({ dirty: true });
if (this.props.onFocus) {
this.props.onFocus(arguments);
}
},
_onBlur() {
if (!this.state.text) {
this._animate(false);
this.setState({ dirty: false });
}
if (this.props.onBlur) {
this.props.onBlur(arguments);
}
if (this.props.placeholder) {
this.setState({
placeHolder: ''
});
}
},
onChangeText(text) {
this.setMask(text);
if (this.props.onChangeText) {
this.props.onChangeText(text);
}
},
setMask(text) {
//function mask(inputName, mask) {
var mask = '00/00/0000';
this.setState({
maxLength: mask.length
});
var value = text;
var literalPattern = /[0\*]/;
var numberPattern = /[0-9]/;
var newValue = '';
for (var vId = 0, mId = 0 ; mId < mask.length ; ) {
if (mId >= value.length) {
break;
}
// Number expected but got a different value, store only the valid portion
if (mask[mId] == '0' && value[vId].match(numberPattern) == null) {
break;
}
// Found a literal
while (mask[mId].match(literalPattern) == null) {
if (value[vId] == mask[mId]) {
break;
}
newValue += mask[mId++];
}
newValue += value[vId++];
mId++;
}
this.setState({
text: newValue
})
},
updateText(event) {
const text = event.nativeEvent.text;
this.setState({ text })
if (this.props.onEndEditing) {
this.props.onEndEditing(event);
}
},
_renderLabel() {
const labelColor = this.state.labelColor.interpolate({
inputRange: [ 0, 1 ],
outputRange: [ colors.darkPurple50, colors.purple100 ]
});
return (
<View style={ styles.wrapper }>
<Animated.Text
ref='label'
style={ [this.state.labelStyle, styles.label, this.props.labelStyle, { color: labelColor } ] }
>
{this.props.children}
</Animated.Text>
</View>
)
},
render() {
const borderColor = this.state.borderColor.interpolate({
inputRange: [ 0, 1 ],
outputRange: [ colors.gray80, colors.purple100 ]
});
const props = {
autoCapitalize: this.props.autoCapitalize,
autoCorrect: this.props.autoCorrect,
autoFocus: this.props.autoFocus,
bufferDelay: this.props.bufferDelay,
clearButtonMode: this.props.clearButtonMode,
clearTextOnFocus: this.props.clearTextOnFocus,
controlled: this.props.controlled,
editable: this.props.editable,
enablesReturnKeyAutomatically: this.props.enablesReturnKeyAutomatically,
keyboardType: this.props.keyboardType,
multiline: this.props.multiline,
onBlur: this._onBlur,
onChange: this.props.onChange,
onChangeText: this.onChangeText,
onEndEditing: this.updateText,
onFocus: this._onFocus,
onSubmitEditing: this.props.onSubmitEditing,
password: this.props.password,
returnKeyType: this.props.returnKeyType,
selectTextOnFocus: this.props.selectTextOnFocus,
selectionState: this.props.selectionState,
style: [styles.input],
maxLength: this.state.maxLength,
underlineColorAndroid: this.props.underlineColorAndroid, // android TextInput will show the default bottom border
onKeyPress: this.props.onKeyPress,
spellCheck: this.props.spellCheck,
mask: this.props.mask,
placeholder: this.state.placeHolder,
placeholderTextColor: colors.darkPurple50,
value: this.state.text,
};
const elementStyles = [styles.element];
if (this.props.inputStyle) {
props.style.push(this.props.inputStyle);
}
if (this.props.style) {
elementStyles.push(this.props.style);
}
if (!this.props.editable) {
elementStyles.push(styles.elementNotEditable);
props.style.push(styles.inputNotEditable);
}
return (
<Animated.View style={ [elementStyles, { borderColor: borderColor }] }>
{ this._renderLabel() }
<TextInput
{ ...props }
>
</TextInput>
</Animated.View>
);
},
});
SMInput.propTypes = {
disabled: PropTypes.bool,
style: Text.propTypes.style,
};
export default SMInput;