Skip to content

Commit 2a81c8e

Browse files
joesphchangthetaPCbrandyscarneyShaneK
authored
docs(react): show complete code context in the "Your First App" tutorial (#4201)
Co-authored-by: Maria Hutt <[email protected]> Co-authored-by: Brandy Smith <[email protected]> Co-authored-by: Shane <[email protected]>
1 parent 337f243 commit 2a81c8e

16 files changed

+2224
-664
lines changed

docs/react/your-first-app.md

Lines changed: 162 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ sidebar_label: Build Your First App
44
---
55

66
<head>
7-
<title>React Apps | Build Your First Ionic Framework React Application</title>
7+
<title>Build Your First Ionic Mobile App with React | Ionic Capacitor Camera</title>
88
<meta
99
name="description"
10-
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."
10+
content="This React tutorial teaches the fundamentals of Ionic app development by creating a realistic app step-by-step. Learn to run your first Ionic app with React."
1111
/>
1212
</head>
1313

@@ -30,11 +30,11 @@ We'll create a Photo Gallery app that offers the ability to take photos with you
3030

3131
Highlights include:
3232

33-
- One React-based codebase that runs on the web, iOS, and Android using Ionic Framework [UI components](https://ionicframework.com/docs/components).
33+
- One React-based codebase that runs on the web, iOS, and Android using Ionic Framework [UI components](../components.md).
3434
- Deployed as a native iOS and Android mobile app using [Capacitor](https://capacitorjs.com), Ionic's official native app runtime.
35-
- Photo Gallery functionality powered by the Capacitor [Camera](https://capacitorjs.com/docs/apis/camera), [Filesystem](https://capacitorjs.com/docs/apis/filesystem), and [Preferences](https://capacitorjs.com/docs/apis/preferences) APIs.
35+
- Photo Gallery functionality powered by the Capacitor [Camera](../native/camera.md), [Filesystem](../native/filesystem.md), and [Preferences](../native/preferences.md) APIs.
3636

37-
Find the complete app code referenced in this guide [on GitHub](https://github.com/ionic-team/photo-gallery-capacitor-react).
37+
Find the [complete app code](https://github.com/ionic-team/tutorial-photo-gallery-react) referenced in this guide on GitHub.
3838

3939
## Download Required Tools
4040

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

5049
## Install Ionic Tooling
5150

@@ -67,10 +66,10 @@ Consider setting up npm to operate globally without elevated permissions. See [R
6766

6867
## Create an App
6968

70-
Next, create an Ionic React app that uses the Tabs starter template and adds Capacitor for native functionality:
69+
Next, create an Ionic React app that uses the "Tabs" starter template and adds Capacitor for native functionality:
7170

7271
```shell
73-
ionic start photo-gallery tabs --type=react --capacitor
72+
ionic start photo-gallery tabs --type=react
7473
```
7574

7675
This starter project comes complete with three pre-built pages and best practices for Ionic development. With common building blocks already in place, we can add more features easily!
@@ -89,116 +88,212 @@ npm install @capacitor/camera @capacitor/preferences @capacitor/filesystem
8988

9089
### PWA Elements
9190

92-
Some Capacitor plugins, including the Camera API, provide the web-based functionality and UI via the Ionic [PWA Elements library](https://github.com/ionic-team/pwa-elements).
91+
Some Capacitor plugins, including the [Camera API](../native/camera.md), provide the web-based functionality and UI via the Ionic [PWA Elements library](https://github.com/ionic-team/pwa-elements).
9392

9493
It's a separate dependency, so install it next:
9594

9695
```shell
9796
npm install @ionic/pwa-elements
9897
```
9998

100-
After installation, open up the project in your code editor of choice.
101-
10299
Next, import `@ionic/pwa-elements` by editing `src/main.tsx`.
103100

104101
```tsx
102+
import React from 'react';
103+
import { createRoot } from 'react-dom/client';
104+
import App from './App';
105+
// CHANGE: Add the following import
105106
import { defineCustomElements } from '@ionic/pwa-elements/loader';
106107

107-
// Call the element loader before the render call
108+
// CHANGE: Call the element loader before the render call
108109
defineCustomElements(window);
110+
111+
const container = document.getElementById('root');
112+
const root = createRoot(container!);
113+
root.render(
114+
<React.StrictMode>
115+
<App />
116+
</React.StrictMode>
117+
);
109118
```
110119

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

113122
## Run the App
114123

115-
Run this command in your shell:
124+
Run this command next:
116125

117126
```shell
118127
ionic serve
119128
```
120129

121130
And voilà! Your Ionic app is now running in a web browser. Most of your app can be built and tested right in the browser, greatly increasing development and testing speed.
122131

123-
## Photo Gallery!!!
132+
## Photo Gallery
124133

125-
There are three tabs. Click on the Tab2 tab. It’s a blank canvas, aka the perfect spot to transform into a Photo Gallery. The Ionic CLI features Live Reload, so when you make changes and save them, the app is updated immediately!
134+
There are three tabs. Click on the "Tab2" tab. It’s a blank canvas, aka the perfect spot to transform into a Photo Gallery. The Ionic CLI features Live Reload, so when you make changes and save them, the app is updated immediately!
126135

127136
![Animated GIF showing the live reload feature in an Ionic app, with changes in code immediately updating the app in a web browser.](/img/guides/react/first-app/live-reload.gif 'Live Reload Feature in Ionic App')
128137

129138
Open `/src/pages/Tab2.tsx`. We see:
130139

140+
```tsx
141+
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react';
142+
import ExploreContainer from '../components/ExploreContainer';
143+
import './Tab2.css';
144+
145+
const Tab2: React.FC = () => {
146+
return (
147+
<IonPage>
148+
<IonHeader>
149+
<IonToolbar>
150+
<IonTitle>Tab 2</IonTitle>
151+
</IonToolbar>
152+
</IonHeader>
153+
<IonContent fullscreen>
154+
<IonHeader collapse="condense">
155+
<IonToolbar>
156+
<IonTitle size="large">Tab 2</IonTitle>
157+
</IonToolbar>
158+
</IonHeader>
159+
<ExploreContainer name="Tab 2 page" />
160+
</IonContent>
161+
</IonPage>
162+
);
163+
};
164+
165+
export default Tab2;
166+
```
167+
168+
`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:
169+
131170
```tsx
132171
<IonPage>
133172
<IonHeader>
134173
<IonToolbar>
135-
<IonTitle>Tab 2</IonTitle>
174+
{/* CHANGE: Update title */}
175+
<IonTitle>Photo Gallery</IonTitle>
136176
</IonToolbar>
137177
</IonHeader>
138178
<IonContent>
139-
<!-- some filler -->
179+
<IonHeader collapse="condense">
180+
<IonToolbar>
181+
{/* CHANGE: Update title */}
182+
<IonTitle size="large">Photo Gallery</IonTitle>
183+
</IonToolbar>
184+
</IonHeader>
185+
186+
{/* ...existing code... */}
140187
</IonContent>
141188
</IonPage>
142189
```
143190

144-
`IonHeader` represents the top navigation and toolbar, with "Tab 2" as the title. Let’s rename it:
191+
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.
145192

146193
```tsx
147-
<IonTitle>Photo Gallery</IonTitle>
194+
// CHANGE: Add the following import
195+
import { camera } from 'ionicons/icons';
196+
// CHANGE: Update the following import
197+
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar, IonFab, IonFabButton, IonIcon } from '@ionic/react';
198+
// CHANGE: Remove or comment out `ExploreContainer`
199+
// import ExploreContainer from '../components/ExploreContainer';
200+
import './Tab2.css';
201+
202+
const Tab2: React.FC = () => {
203+
return (
204+
<IonPage>
205+
<IonHeader>
206+
<IonToolbar>
207+
<IonTitle>Photo Gallery</IonTitle>
208+
</IonToolbar>
209+
</IonHeader>
210+
<IonContent fullscreen>
211+
<IonHeader collapse="condense">
212+
<IonToolbar>
213+
<IonTitle size="large">Photo Gallery</IonTitle>
214+
</IonToolbar>
215+
</IonHeader>
216+
217+
{/* CHANGE: Add the floating action button */}
218+
<IonFab vertical="bottom" horizontal="center" slot="fixed">
219+
<IonFabButton>
220+
<IonIcon icon={camera}></IonIcon>
221+
</IonFabButton>
222+
</IonFab>
223+
224+
{/* CHANGE: Remove or comment out `ExploreContainer` */}
225+
{/* <ExploreContainer name="Tab 2 page" /> */}
226+
</IonContent>
227+
</IonPage>
228+
);
229+
};
230+
231+
export default Tab2;
148232
```
149233

150-
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:
234+
Next, open `src/App.tsx`. Change the label to "Photos" and the `ellipse` icon to `images` for the middle tab button.
151235

152236
```tsx
153-
import { camera, trash, close } from 'ionicons/icons';
237+
import { Redirect, Route } from 'react-router-dom';
154238
import {
155-
IonContent,
156-
IonHeader,
157-
IonPage,
158-
IonTitle,
159-
IonToolbar,
160-
IonFab,
161-
IonFabButton,
239+
IonApp,
162240
IonIcon,
163-
IonGrid,
164-
IonRow,
165-
IonCol,
166-
IonImg,
167-
IonActionSheet,
241+
IonLabel,
242+
IonRouterOutlet,
243+
IonTabBar,
244+
IonTabButton,
245+
IonTabs,
246+
setupIonicReact,
168247
} from '@ionic/react';
169-
```
170-
171-
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):
172-
173-
```tsx
174-
<IonContent>
175-
<IonFab vertical="bottom" horizontal="center" slot="fixed">
176-
<IonFabButton onClick={() => takePhoto()}>
177-
<IonIcon icon={camera}></IonIcon>
178-
</IonFabButton>
179-
</IonFab>
180-
</IonContent>
181-
```
182-
183-
We’ll be creating the `takePhoto` method and the logic to use the Camera and other native features in a moment.
184-
185-
Next, open `src/App.tsx`, remove the `ellipse` icon from the import and import the `images` icon instead:
186-
187-
```tsx
248+
import { IonReactRouter } from '@ionic/react-router';
249+
// CHANGE: Update the following import
188250
import { images, square, triangle } from 'ionicons/icons';
251+
import Tab1 from './pages/Tab1';
252+
import Tab2 from './pages/Tab2';
253+
import Tab3 from './pages/Tab3';
254+
255+
/* ...existing Ionic styles... */
256+
257+
const App: React.FC = () => (
258+
<IonApp>
259+
<IonReactRouter>
260+
<IonTabs>
261+
<IonRouterOutlet>
262+
<Route exact path="/tab1">
263+
<Tab1 />
264+
</Route>
265+
<Route exact path="/tab2">
266+
<Tab2 />
267+
</Route>
268+
<Route path="/tab3">
269+
<Tab3 />
270+
</Route>
271+
<Route exact path="/">
272+
<Redirect to="/tab1" />
273+
</Route>
274+
</IonRouterOutlet>
275+
<IonTabBar slot="bottom">
276+
<IonTabButton tab="tab1" href="/tab1">
277+
<IonIcon aria-hidden="true" icon={triangle} />
278+
<IonLabel>Tab 1</IonLabel>
279+
</IonTabButton>
280+
<IonTabButton tab="tab2" href="/tab2">
281+
{/* CHANGE: Update icon */}
282+
<IonIcon aria-hidden="true" icon={images} />
283+
{/* CHANGE: Update label */}
284+
<IonLabel>Photos</IonLabel>
285+
</IonTabButton>
286+
<IonTabButton tab="tab3" href="/tab3">
287+
<IonIcon aria-hidden="true" icon={square} />
288+
<IonLabel>Tab 3</IonLabel>
289+
</IonTabButton>
290+
</IonTabBar>
291+
</IonTabs>
292+
</IonReactRouter>
293+
</IonApp>
294+
);
295+
296+
export default App;
189297
```
190298

191-
Within the tab bar (`<IonTabBar>`), change the label to “Photos” and the `ellipse` icon to `images` for the middle tab button:
192-
193-
```tsx
194-
<IonTabButton tab="tab2" href="/tab2">
195-
<IonIcon icon={images} />
196-
<IonLabel>Photos</IonLabel>
197-
</IonTabButton>
198-
```
199-
200-
:::note
201-
In Ionic React, icons are imported individually from `ionicons/icons` and set to the icon prop.
202-
:::
203-
204299
That’s just the start of all the cool things we can do with Ionic. Up next, implement camera taking functionality on the web, then build it for iOS and Android.

0 commit comments

Comments
 (0)