Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 122 additions & 40 deletions docs/react/your-first-app.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a code block that has the following comment: <!-- some filler -->. This needs to be replaced to be the entire code. Review this PR for how it should be.

Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ sidebar_label: Build Your First App
---

<head>
<title>React Apps | Build Your First Ionic Framework React Application</title>
<title>Build Your First Ionic Mobile App: React Development Tutorial</title>
<meta
name="description"
content="Build your first Ionic React App. With one codebase, you can build an Ionic Framework application for any platform using just HTML, CSS, and JavaScript."
content="Ionic's single codebase builds for any platform using just HTML, CSS, & JavaScript. Develop your first mobile app with our step-by-step React tutorial."
/>
</head>

Expand Down Expand Up @@ -43,9 +43,8 @@ Download and install these right away to ensure an optimal Ionic development exp
- **Node.js** for interacting with the Ionic ecosystem. [Download the LTS version here](https://nodejs.org/en/).
- **A code editor** for... writing code! We are fans of [Visual Studio Code](https://code.visualstudio.com/).
- **Command-line interface/terminal (CLI)**:
- **Windows** users: for the best Ionic experience, we recommend the built-in command line (cmd) or the Powershell
CLI, running in Administrator mode.
- **Mac/Linux** users, virtually any terminal will work.
- **Windows** users: for the best Ionic experience, we recommend the built-in command line (cmd) or the Powershell CLI, running in Administrator mode.
- **Mac/Linux** users: virtually any terminal will work.

## Install Ionic Tooling

Expand Down Expand Up @@ -97,22 +96,32 @@ It's a separate dependency, so install it next:
npm install @ionic/pwa-elements
```

After installation, open up the project in your code editor of choice.

Next, import `@ionic/pwa-elements` by editing `src/main.tsx`.

```tsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';
// CHANGE: Add the following import.
import { defineCustomElements } from '@ionic/pwa-elements/loader';

// Call the element loader before the render call
// CHANGE: Call the element loader before the render call.
defineCustomElements(window);

const container = document.getElementById('root');
const root = createRoot(container!);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
```

That’s it! Now for the fun part - let’s see the app in action.

## Run the App

Run this command in your shell:
Run this command next:

```shell
ionic serve
Expand All @@ -129,28 +138,45 @@ There are three tabs. Click on the Tab2 tab. It’s a blank canvas, aka the perf
Open `/src/pages/Tab2.tsx`. We see:

```tsx
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Tab 2</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent>
<!-- some filler -->
</IonContent>
</IonPage>
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react';
import ExploreContainer from '../components/ExploreContainer';
import './Tab2.css';

const Tab2: React.FC = () => {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Tab 2</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent fullscreen>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">Tab 2</IonTitle>
</IonToolbar>
</IonHeader>
<ExploreContainer name="Tab 2 page" />
</IonContent>
</IonPage>
);
};

export default Tab2;
```

`IonHeader` represents the top navigation and toolbar, with "Tab 2" as the title. Let’s rename it:
`IonHeader` represents the top navigation and toolbar, with "Tab 2" as the title (there are two of them due to iOS [Collapsible Large Title](../api/title.md#collapsible-large-titles) support). Let’s rename both `IonTitle` elements to:

```tsx
<IonTitle>Photo Gallery</IonTitle>
```

We put the visual aspects of our app into `<IonContent>`. In this case, it’s where we’ll add a button that opens the device’s camera as well as displays the image captured by the camera. Start by adding a [floating action button](https://ionicframework.com/docs/api/fab) (FAB). First, update the imports at the top of the page to include the Camera icon as well as some of the Ionic components we'll use shortly:
We put the visual aspects of our app into `<IonContent>`. In this case, it’s where we’ll add a button that opens the device’s camera as well as displays the image captured by the camera. Start by adding a [floating action button](../api/fab.md) (FAB) to the bottom of the page and set the camera image as the icon.

```tsx
// CHANGE: Add the following import.
import { camera, trash, close } from 'ionicons/icons';
// CHANGE: Update the following import.
import {
IonContent,
IonHeader,
Expand All @@ -166,23 +192,41 @@ import {
IonImg,
IonActionSheet,
} from '@ionic/react';
// CHANGE: Remove or comment out `ExploreContainer`.
// import ExploreContainer from '../components/ExploreContainer';
import './Tab2.css';

const Tab2: React.FC = () => {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Photo Gallery</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">Photo Gallery</IonTitle>
</IonToolbar>
</IonHeader>
{/* CHANGE: Add the floating action button. */}
<IonFab vertical="bottom" horizontal="center" slot="fixed">
<IonFabButton>
<IonIcon icon={camera}></IonIcon>
</IonFabButton>
</IonFab>
</IonContent>
{/* CHANGE: Remove or comment out `ExploreContainer`. */}
{/* <ExploreContainer name="Tab 2 page" /> */}
</IonPage>
);
};

export default Tab2;
```

Then, add the FAB to the bottom of the page. Use the camera image as the icon, and call the `takePhoto()` function when this button is clicked (to be implemented soon):

```tsx
<IonContent>
<IonFab vertical="bottom" horizontal="center" slot="fixed">
<IonFabButton onClick={() => takePhoto()}>
<IonIcon icon={camera}></IonIcon>
</IonFabButton>
</IonFab>
</IonContent>
```

We’ll be creating the `takePhoto` method and the logic to use the Camera and other native features in a moment.

Next, open `src/App.tsx`, remove the `ellipse` icon from the import and import the `images` icon instead:
Next, open `src/App.tsx` and replace the imported `ellipse` icon with the `images` icon.

```tsx
import { images, square, triangle } from 'ionicons/icons';
Expand All @@ -191,10 +235,48 @@ import { images, square, triangle } from 'ionicons/icons';
Within the tab bar (`<IonTabBar>`), change the label to “Photos” and the `ellipse` icon to `images` for the middle tab button:

```tsx
<IonTabButton tab="tab2" href="/tab2">
<IonIcon icon={images} />
<IonLabel>Photos</IonLabel>
</IonTabButton>
// Keep other imports
// CHANGE: Update the following import.
import { images, square, triangle } from 'ionicons/icons';

const App: React.FC = () => (
<IonApp>
<IonReactRouter>
<IonTabs>
<IonRouterOutlet>
<Route exact path="/tab1">
<Tab1 />
</Route>
<Route exact path="/tab2">
<Tab2 />
</Route>
<Route path="/tab3">
<Tab3 />
</Route>
<Route exact path="/">
<Redirect to="/tab1" />
</Route>
</IonRouterOutlet>
<IonTabBar slot="bottom">
<IonTabButton tab="tab1" href="/tab1">
<IonIcon aria-hidden="true" icon={triangle} />
<IonLabel>Tab 1</IonLabel>
</IonTabButton>
<IonTabButton tab="tab2" href="/tab2">
{/* CHANGE: Update icon. */}
<IonIcon aria-hidden="true" icon={images} />
{/* CHANGE: Update label. */}
<IonLabel>Photos</IonLabel>
</IonTabButton>
<IonTabButton tab="tab3" href="/tab3">
<IonIcon aria-hidden="true" icon={square} />
<IonLabel>Tab 3</IonLabel>
</IonTabButton>
</IonTabBar>
</IonTabs>
</IonReactRouter>
</IonApp>
);
```

:::note
Expand Down
Loading