Ionic provides form components optimized for touch input on mobile devices.

Basic Input

  import { IonInput, IonItem, IonLabel } from '@ionic/react';

<IonItem>
    <IonLabel position="stacked">Email</IonLabel>
    <IonInput
        type="email"
        placeholder="[email protected]"
        value={email}
        onIonChange={(e) => setEmail(e.detail.value!)}
    />
</IonItem>
  

Controlled Form State

  import { useState } from 'react';

function LoginForm() {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');

    const handleSubmit = (e: React.FormEvent) => {
        e.preventDefault();
        console.log({ email, password });
    };

    return (
        <form onSubmit={handleSubmit}>
            <IonItem>
                <IonLabel position="floating">Email</IonLabel>
                <IonInput
                    type="email"
                    value={email}
                    onIonInput={(e) => setEmail(e.detail.value!)}
                    required
                />
            </IonItem>
            <IonItem>
                <IonLabel position="floating">Password</IonLabel>
                <IonInput
                    type="password"
                    value={password}
                    onIonInput={(e) => setPassword(e.detail.value!)}
                    required
                />
            </IonItem>
            <IonButton expand="block" type="submit">
                Log In
            </IonButton>
        </form>
    );
}
  

Validation Feedback

  <IonItem className={errors.email ? 'ion-invalid' : ''}>
    <IonLabel position="stacked">Email</IonLabel>
    <IonInput type="email" value={email} onIonInput={handleEmailChange} />
    {errors.email && (
        <IonNote slot="error">{errors.email}</IonNote>
    )}
</IonItem>
  

Select and Toggle

  import { IonSelect, IonSelectOption, IonToggle } from '@ionic/react';

<IonItem>
    <IonLabel>Country</IonLabel>
    <IonSelect value={country} onIonChange={(e) => setCountry(e.detail.value)}>
        <IonSelectOption value="us">United States</IonSelectOption>
        <IonSelectOption value="uk">United Kingdom</IonSelectOption>
    </IonSelect>
</IonItem>

<IonItem>
    <IonLabel>Notifications</IonLabel>
    <IonToggle checked={enabled} onIonChange={(e) => setEnabled(e.detail.checked)} />
</IonItem>
  

Loading and Toast Feedback

  import { useIonLoading, useIonToast } from '@ionic/react';

const [presentLoading] = useIonLoading();
const [presentToast] = useIonToast();

async function submitForm() {
    await presentLoading({ message: 'Saving...' });
    await saveData();
    presentToast({ message: 'Saved!', duration: 2000, color: 'success' });
}
  

Best Practices

  • Use floating or stacked labels for clarity on small screens
  • Show inline validation errors with IonNote
  • Disable submit buttons until the form is valid

Next: build and publish your app to app stores.