Input

The Input component is a fundamental building block for displaying text in your React Native applications. It is designed to render styled text with various customization options, making it versatile for a wide range of use cases.

Expo component example

Installation

To use the Input component, make sure first that you have initiated the library.

CLI

This command will add the Input component file to your project and install any necessary dependencies.

npx mallaui@latest add Input

Manual

Copy and paste the following code into your project. Make sure to install the necessary dependencies first and update path to match your project setup.

Input.tsx

import React, {ReactNode, useState} from 'react';
import {forwardRef} from 'react';
import {TextInput, TextInputProps, StyleSheet, View, Platform} from 'react-native';
import {AppTheme} from '../../styles/theme';
import {useStyles} from '../../styles/useStyles';
import {useTheme} from '../../styles/useTheme';
import {Text} from './Text';
import {DescriptionText} from './DescriptionText';

const defaultStyles = (theme: AppTheme) => {
  return StyleSheet.create({
    labelText: {
      marginBottom: theme.paddings.inputElementsPadding
    },
    input: {
      backgroundColor: theme.colors.app.background,
      borderRadius: 10,
      borderColor: theme.colors.app.border,
      color: theme.colors.app.foreground,
      paddingHorizontal: 16,
      paddingVertical: 12,
      flex: 1,
      height: 44,
      fontSize: 16,
      lineHeight: 20,
      fontWeight: '400',
      borderWidth: 1
    },
    inputWithRightSlot: {
      paddingRight: 44
    },
    placeholderText: {
      fontWeight: '300'
    },
    rightSlot: {
      alignItems: 'center',
      end: 16,
      height: '100%',
      justifyContent: 'center',
      position: 'absolute',
      backgroundColor: 'transparent'
    },
    disabled: {
      opacity: 0.5
    },
    bottomText: {
      marginTop: theme.paddings.inputElementsPadding
    },
    inputFocus: {
      borderColor: theme.colors.app.secondaryForeground,
      borderWidth: 1
    },
    inputError: {
      borderColor: theme.colors.app.destructive,
      borderWidth: 1
    }
  });
};

interface IInputProps extends TextInputProps {
  /**
   * Label for the input
   */
  label?: string;

  /**
   * The right slot of the input.
   */
  rightSlot?: ReactNode;

  /**
   * Whether the input is disabled.
   */
  isDisabled?: boolean;

  /**
   * Error message to display
   */
  error?: string;

  /**
   * Description text to display
   */
  description?: string;

  /**
   * Style of input wrapper
   */
  wrapperStyle?: any;
}

const Input = forwardRef<TextInput, IInputProps>((props, ref) => {
  const {wrapperStyle, rightSlot, style, label, isDisabled, error, description, value} =
    props;
  const styles = useStyles(defaultStyles);
  const {theme} = useTheme();
  const [isOnFocus, setIsOnFocus] = useState(false);

  return (
    <View style={[wrapperStyle]}>
      {label ? (
        <Text color='primary' size='md' fontWeight='medium' style={styles.labelText}>
          {label}
        </Text>
      ) : null}
      <View>
        <TextInput
          {...props}
          onFocus={() => setIsOnFocus(true)}
          onBlur={() => setIsOnFocus(false)}
          placeholderTextColor={theme.colors.app.mutedForeground}
          selectionColor={
            Platform.OS === 'ios' ? theme.colors.app.foreground : theme.colors.app.input
          }
          cursorColor={theme.colors.app.foreground}
          ref={ref}
          editable={!isDisabled}
          selectTextOnFocus={!isDisabled}
          style={[
            styles.input,
            !!rightSlot && styles.inputWithRightSlot,
            !value && styles.placeholderText,
            isOnFocus && styles.inputFocus,
            !!error && styles.inputError,
            isDisabled && styles.disabled,
            style
          ]}
        />
        {rightSlot ? <View style={[styles.rightSlot]}>{rightSlot}</View> : null}
      </View>
      {error || description ? (
        <DescriptionText isError={!!error} style={[styles.bottomText]}>
          {error || description}
        </DescriptionText>
      ) : null}
    </View>
  );
});

Input.displayName = 'Input';

export {Input};

Usage

import { Input } from './components/ui/Input'
export function ExampleInput() {
const [inputValue, setInputValue] = useState('');

return (
    <View>
      <Input
        value={inputValue}
        onChangeText={setInputValue}
        placeholder='Input'   
      />
    </View>
  );
}

Properties

  • Name
    label
    Type
    string
    Description

    Input label

  • Name
    rightSlot
    Type
    ReactNode
    Description

    Icon or other element to display on the right side of the input

  • Name
    error
    Type
    string
    Description

    Error message to display

  • Name
    description
    Type
    string
    Description

    Description text to display

  • Name
    isDisabled
    Type
    boolean
    Description

    Boolean to disable the input


Label

Expo component example
First Name

Icon

Expo component example

Error

Expo component example
Noop, it's not

Description

Expo component example
Type something in the input

State

Expo component example

Was this page helpful?