--- name: ionic-design description: Guide to using Ionic Framework components for beautiful native-looking Capacitor apps. Covers component usage, theming, platform-specific styling, and best practices for mobile UI. Use this skill when users need help with Ionic components or mobile UI design. --- # Ionic Framework Design Guide Build beautiful, native-looking mobile apps with Ionic Framework and Capacitor. ## When to Use This Skill - User is using Ionic components - User wants native-looking UI - User asks about Ionic theming - User needs mobile UI patterns - User wants platform-specific styling ## What is Ionic Framework? Ionic provides: - 100+ mobile-optimized UI components - Automatic iOS/Android platform styling - Built-in dark mode support - Accessibility out of the box - Works with React, Vue, Angular, or vanilla JS ## Getting Started ### Installation ```bash # For React bun create vite my-app --template react-ts cd my-app bun add @ionic/react @ionic/react-router # For Vue bun create vite my-app --template vue-ts cd my-app bun add @ionic/vue @ionic/vue-router # Add Capacitor bun add @capacitor/core @capacitor/cli bunx cap init ``` ### Setup (React) ```typescript // main.tsx import React from 'react'; import { createRoot } from 'react-dom/client'; import { IonApp, setupIonicReact } from '@ionic/react'; import App from './App'; /* Core CSS required for Ionic components to work properly */ import '@ionic/react/css/core.css'; /* Basic CSS for apps built with Ionic */ import '@ionic/react/css/normalize.css'; import '@ionic/react/css/structure.css'; import '@ionic/react/css/typography.css'; /* Optional CSS utils */ import '@ionic/react/css/padding.css'; import '@ionic/react/css/float-elements.css'; import '@ionic/react/css/text-alignment.css'; import '@ionic/react/css/text-transformation.css'; import '@ionic/react/css/flex-utils.css'; import '@ionic/react/css/display.css'; /* Theme */ import './theme/variables.css'; setupIonicReact(); const root = createRoot(document.getElementById('root')!); root.render( ); ``` ## Core Components ### Page Structure ```tsx import { IonPage, IonHeader, IonToolbar, IonTitle, IonContent, IonButtons, IonBackButton, } from '@ionic/react'; function MyPage() { return ( Page Title {/* Large title for iOS */} Page Title {/* Page content */}
Your content here
); } ``` ### Lists ```tsx import { IonList, IonItem, IonLabel, IonNote, IonAvatar, IonIcon, IonItemSliding, IonItemOptions, IonItemOption, } from '@ionic/react'; import { chevronForward, trash, archive } from 'ionicons/icons'; function ContactList() { return ( {/* Simple item */} Simple Item {/* Item with detail */}

Item Title

Item description text

Note
{/* Item with avatar */}

John Doe

john@example.com

{/* Sliding item */} Swipe me
); } ``` ### Forms ```tsx import { IonInput, IonTextarea, IonSelect, IonSelectOption, IonToggle, IonCheckbox, IonRadioGroup, IonRadio, IonItem, IonLabel, IonButton, } from '@ionic/react'; function MyForm() { return (
{/* Text input */} {/* Password */} {/* Textarea */} {/* Select */} United States United Kingdom Germany {/* Toggle */} Enable notifications {/* Checkbox */} I agree to terms {/* Radio group */} Small Medium Large Submit
); } ``` ### Buttons ```tsx import { IonButton, IonIcon } from '@ionic/react'; import { heart, share, download } from 'ionicons/icons'; function Buttons() { return ( <> {/* Fill variants */} Solid Outline Clear {/* Colors */} Primary Secondary Danger Success {/* Sizes */} Small Default Large {/* With icons */} Like {/* Icon only */} {/* Full width */} Block Button Full Width ); } ``` ### Cards ```tsx import { IonCard, IonCardHeader, IonCardTitle, IonCardSubtitle, IonCardContent, IonImg, IonButton, } from '@ionic/react'; function Cards() { return ( Card Subtitle Card Title Card content goes here. This is a standard card with an image, title, subtitle, and content.
Action 1 Action 2
); } ``` ### Modals and Sheets ```tsx import { IonModal, IonButton, IonContent, IonHeader, IonToolbar, IonTitle } from '@ionic/react'; import { useState, useRef } from 'react'; function ModalExample() { const [isOpen, setIsOpen] = useState(false); const modal = useRef(null); return ( <> setIsOpen(true)}>Open Modal {/* Full page modal */} setIsOpen(false)}> Modal Title setIsOpen(false)}> Close

Modal content

{/* Bottom sheet */}

Sheet Content

Drag to resize

Open Sheet ); } ``` ## Navigation ### Tab Navigation ```tsx import { IonTabs, IonTabBar, IonTabButton, IonIcon, IonLabel, IonRouterOutlet, } from '@ionic/react'; import { Route, Redirect } from 'react-router-dom'; import { home, search, person } from 'ionicons/icons'; function TabsLayout() { return ( Home Search Profile ); } ``` ### Stack Navigation ```tsx import { IonReactRouter } from '@ionic/react-router'; import { IonRouterOutlet } from '@ionic/react'; import { Route } from 'react-router-dom'; function App() { return ( ); } ``` ## Theming ### Theme Variables ```css /* theme/variables.css */ :root { /* Primary */ --ion-color-primary: #3880ff; --ion-color-primary-rgb: 56, 128, 255; --ion-color-primary-contrast: #ffffff; --ion-color-primary-shade: #3171e0; --ion-color-primary-tint: #4c8dff; /* Secondary */ --ion-color-secondary: #3dc2ff; /* Custom colors */ --ion-color-brand: #ff6b35; --ion-color-brand-rgb: 255, 107, 53; --ion-color-brand-contrast: #ffffff; --ion-color-brand-shade: #e05e2f; --ion-color-brand-tint: #ff7a49; } /* Dark mode */ @media (prefers-color-scheme: dark) { :root { --ion-background-color: #121212; --ion-text-color: #ffffff; --ion-color-step-50: #1e1e1e; --ion-color-step-100: #2a2a2a; } } /* iOS specific */ .ios { --ion-toolbar-background: #f8f8f8; } /* Android specific */ .md { --ion-toolbar-background: #ffffff; } ``` ### Custom Component Styling ```css /* Global styles */ ion-content { --background: var(--ion-background-color); } ion-card { --background: #ffffff; border-radius: 16px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1); } /* Platform-specific */ .ios ion-toolbar { --border-width: 0; } .md ion-toolbar { --border-width: 0 0 1px 0; } ``` ## Platform-Specific Code ### Detect Platform ```typescript import { isPlatform } from '@ionic/react'; // Check platform if (isPlatform('ios')) { // iOS-specific code } if (isPlatform('android')) { // Android-specific code } if (isPlatform('hybrid')) { // Running in native app } if (isPlatform('mobileweb')) { // Running in mobile browser } ``` ### Conditional Rendering ```tsx import { isPlatform, IonIcon } from '@ionic/react'; import { chevronBack, arrowBack } from 'ionicons/icons'; function BackButton() { return ( ); } ``` ## Best Practices ### Performance ```tsx // Use IonVirtualScroll for long lists import { IonVirtualScroll } from '@ionic/react'; ( {item.name} )} /> // Lazy load images // Automatically lazy loads ``` ### Accessibility ```tsx // Always provide labels // Use semantic elements Clickable item ``` ### Safe Area ```tsx // Content respects safe areas by default {/* Auto padding for notch/home indicator */} // Custom safe area handling
Custom header
``` ## Resources - Ionic Documentation: https://ionicframework.com/docs - Ionic Components: https://ionicframework.com/docs/components - Ionicons: https://ionic.io/ionicons - Color Generator: https://ionicframework.com/docs/theming/color-generator