iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

UI Components

Ionic ships ~100 UI components that render native-looking on iOS, Android, and the web. ion-button, ion-list, ion-card, ion-modal — all theme-able, all accessible by default.

Buttons, cards, lists, toasts, alerts

EXAMPLE
<!-- 1) Buttons -->
<ion-button>Primary</ion-button>
<ion-button color="secondary">Secondary</ion-button>
<ion-button color="danger" fill="outline">Cancel</ion-button>
<ion-button color="success" fill="clear">Maybe</ion-button>
<ion-button expand="block">Full width</ion-button>
<ion-button size="small">Small</ion-button>
<ion-button shape="round">Round</ion-button>

<!-- With an icon -->
<ion-button>
    <ion-icon slot="start" name="save"></ion-icon>
    Save
</ion-button>

<ion-button>
    Next
    <ion-icon slot="end" name="arrow-forward"></ion-icon>
</ion-button>

<!-- Icon-only button -->
<ion-button fill="clear" aria-label="Settings">
    <ion-icon slot="icon-only" name="settings"></ion-icon>
</ion-button>

<!-- 2) Cards -->
<ion-card>
    <img alt="Cover" src="https://example.com/photo.jpg" />
    <ion-card-header>
        <ion-card-subtitle>Updated 2 hours ago</ion-card-subtitle>
        <ion-card-title>Product launch</ion-card-title>
    </ion-card-header>
    <ion-card-content>
        Read about the new features shipping today.
    </ion-card-content>
    <ion-button fill="clear">Read more</ion-button>
</ion-card>

<!-- 3) Lists + items -->
<ion-list>
    <ion-list-header><ion-label>Settings</ion-label></ion-list-header>

    <ion-item button (click)="openProfile()">
        <ion-icon slot="start" name="person"></ion-icon>
        <ion-label>Profile</ion-label>
        <ion-note slot="end">Ada</ion-note>
    </ion-item>

    <ion-item>
        <ion-icon slot="start" name="notifications"></ion-icon>
        <ion-label>Notifications</ion-label>
        <ion-toggle slot="end"></ion-toggle>
    </ion-item>

    <ion-item>
        <ion-icon slot="start" name="moon"></ion-icon>
        <ion-label>Theme</ion-label>
        <ion-select slot="end" interface="action-sheet">
            <ion-select-option value="light">Light</ion-select-option>
            <ion-select-option value="dark">Dark</ion-select-option>
            <ion-select-option value="auto">Auto</ion-select-option>
        </ion-select>
    </ion-item>

    <ion-item button (click)="logout()" detail="false" color="danger">
        <ion-icon slot="start" name="log-out"></ion-icon>
        <ion-label>Log out</ion-label>
    </ion-item>
</ion-list>

<!-- 4) Sliding items — swipe for actions -->
<ion-list>
    <ion-item-sliding *ngFor="let m of messages">
        <ion-item-options side="start">
            <ion-item-option color="primary" (click)="archive(m)">
                <ion-icon slot="icon-only" name="archive"></ion-icon>
            </ion-item-option>
        </ion-item-options>

        <ion-item>
            <ion-label>
                <h3>{{ m.from }}</h3>
                <p>{{ m.preview }}</p>
            </ion-label>
        </ion-item>

        <ion-item-options side="end">
            <ion-item-option color="danger" (click)="delete(m)">
                <ion-icon slot="icon-only" name="trash"></ion-icon>
            </ion-item-option>
        </ion-item-options>
    </ion-item-sliding>
</ion-list>

<!-- 5) Toast — quick feedback -->
// Angular
import { ToastController } from '@ionic/angular';
constructor(private toast: ToastController) {}

async showToast() {
    const t = await this.toast.create({
        message:  'Saved.',
        duration: 2000,
        position: 'bottom',
        color:    'success',
        buttons:  [{ text: 'Undo', handler: () => this.undo() }],
    });
    await t.present();
}

<!-- 6) Alert — confirmation dialog -->
import { AlertController } from '@ionic/angular';
constructor(private alert: AlertController) {}

async confirm() {
    const a = await this.alert.create({
        header: 'Delete this item?',
        message: 'This action cannot be undone.',
        buttons: [
            { text: 'Cancel', role: 'cancel' },
            { text: 'Delete', role: 'destructive', handler: () => this.doDelete() },
        ],
    });
    await a.present();
}

<!-- 7) Modal — sheet-style + full-screen -->
import { ModalController } from '@ionic/angular';
import { EditPage } from './edit.page';

async openEdit(id: string) {
    const m = await this.modalCtrl.create({
        component: EditPage,
        componentProps: { id },
        breakpoints: [0, 0.4, 0.8, 1],
        initialBreakpoint: 0.4,
    });
    await m.present();
    const { data } = await m.onDidDismiss();
    if (data?.saved) this.refresh();
}

<!-- 8) Refresher — pull-to-refresh -->
<ion-content>
    <ion-refresher slot="fixed" (ionRefresh)="refresh($event)">
        <ion-refresher-content></ion-refresher-content>
    </ion-refresher>

    <ion-list>…</ion-list>
</ion-content>

async refresh(ev) {
    await this.loadData();
    ev.target.complete();
}

<!-- 9) Infinite scroll -->
<ion-content>
    <ion-list>…</ion-list>
    <ion-infinite-scroll (ionInfinite)="loadMore($event)">
        <ion-infinite-scroll-content loadingText="Loading…"></ion-infinite-scroll-content>
    </ion-infinite-scroll>
</ion-content>

<!-- 10) Theming -->
<!-- variables.scss -->
/*
:root {
    --ion-color-primary:        #0ea5e9;
    --ion-color-primary-shade:  #0284c7;
    --ion-color-primary-tint:   #38bdf8;
}
[data-theme='dark'] {
    --ion-background-color:     #0b0b0b;
    --ion-text-color:           #eee;
}
*/

<!-- 11) Pick the right component -->
<!--   Single tap action          ion-button (with fill / color / size variants) -->
<!--   Sheet of options           ion-action-sheet -->
<!--   Confirm / inform           ion-alert (single button or two) -->
<!--   Brief feedback             ion-toast -->
<!--   Long-form input            ion-modal (with breakpoints for bottom-sheet) -->
<!--   Multi-step flow            ion-modal + ion-segment -->
<!--   List of actions on a row   ion-item-sliding -->

Why it matters

Ionic components are accessible (ARIA roles, keyboard focus) and theme-able (CSS custom properties) out of the box. Resist re-inventing — most native-app interactions already have a matching ion-* component.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
<ion-button color="primary" (click)="save()">Save</ion-button>
<ion-card>
    <ion-card-header><ion-card-title>Title</ion-card-title></ion-card-header>
    <ion-card-content>Content</ion-card-content>
</ion-card>
Try it Yourself »

Exercise

Primary call-to-action element.

<ion- >Save</ion- >

Discussion

Loading…