From 53b4f591d1cf5fb862d0ce24ecadcb286767b6ed Mon Sep 17 00:00:00 2001 From: Shawn Taylor Date: Tue, 21 Nov 2023 17:24:32 -0500 Subject: [PATCH 01/11] docs(autofocus): autofocus docs and playground --- docs/developing/autofocus.md | 14 +++++ sidebars.js | 1 + .../basic/angular/app_component_html.md | 3 ++ .../basic/angular/app_component_ts.md | 10 ++++ .../autofocus/basic/angular/app_module_ts.md | 19 +++++++ .../basic/angular/app_routing_module_ts.md | 19 +++++++ .../basic/angular/example_component_html.md | 10 ++++ .../basic/angular/example_component_ts.md | 16 ++++++ static/usage/v7/autofocus/basic/demo.html | 32 ++++++++++++ static/usage/v7/autofocus/basic/index.md | 51 +++++++++++++++++++ static/usage/v7/autofocus/basic/javascript.md | 16 ++++++ .../v7/autofocus/basic/react/home_page_tsx.md | 28 ++++++++++ .../v7/autofocus/basic/react/main_tsx.md | 26 ++++++++++ .../usage/v7/autofocus/basic/vue/app_vue.md | 20 ++++++++ .../v7/autofocus/basic/vue/example_vue.md | 32 ++++++++++++ .../usage/v7/autofocus/basic/vue/main_ts.md | 32 ++++++++++++ .../usage/v7/autofocus/basic/vue/router_ts.md | 20 ++++++++ 17 files changed, 349 insertions(+) create mode 100644 docs/developing/autofocus.md create mode 100644 static/usage/v7/autofocus/basic/angular/app_component_html.md create mode 100644 static/usage/v7/autofocus/basic/angular/app_component_ts.md create mode 100644 static/usage/v7/autofocus/basic/angular/app_module_ts.md create mode 100644 static/usage/v7/autofocus/basic/angular/app_routing_module_ts.md create mode 100644 static/usage/v7/autofocus/basic/angular/example_component_html.md create mode 100644 static/usage/v7/autofocus/basic/angular/example_component_ts.md create mode 100644 static/usage/v7/autofocus/basic/demo.html create mode 100644 static/usage/v7/autofocus/basic/index.md create mode 100644 static/usage/v7/autofocus/basic/javascript.md create mode 100644 static/usage/v7/autofocus/basic/react/home_page_tsx.md create mode 100644 static/usage/v7/autofocus/basic/react/main_tsx.md create mode 100644 static/usage/v7/autofocus/basic/vue/app_vue.md create mode 100644 static/usage/v7/autofocus/basic/vue/example_vue.md create mode 100644 static/usage/v7/autofocus/basic/vue/main_ts.md create mode 100644 static/usage/v7/autofocus/basic/vue/router_ts.md diff --git a/docs/developing/autofocus.md b/docs/developing/autofocus.md new file mode 100644 index 00000000000..1865723ebd7 --- /dev/null +++ b/docs/developing/autofocus.md @@ -0,0 +1,14 @@ +--- +title: Autofocus +--- + + + Autofocus + + + +## Basic + +import Basic from '@site/static/usage/v7/autofocus/basic/index.md'; + + diff --git a/sidebars.js b/sidebars.js index 069e5ec59dc..a92cf69609c 100644 --- a/sidebars.js +++ b/sidebars.js @@ -26,6 +26,7 @@ module.exports = { 'developing/hardware-back-button', 'developing/keyboard', 'developing/config', + 'developing/autofocus', ], }, { diff --git a/static/usage/v7/autofocus/basic/angular/app_component_html.md b/static/usage/v7/autofocus/basic/angular/app_component_html.md new file mode 100644 index 00000000000..7636539f28a --- /dev/null +++ b/static/usage/v7/autofocus/basic/angular/app_component_html.md @@ -0,0 +1,3 @@ +```html + +``` diff --git a/static/usage/v7/autofocus/basic/angular/app_component_ts.md b/static/usage/v7/autofocus/basic/angular/app_component_ts.md new file mode 100644 index 00000000000..de26ac4a9f9 --- /dev/null +++ b/static/usage/v7/autofocus/basic/angular/app_component_ts.md @@ -0,0 +1,10 @@ +```ts +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-root', + templateUrl: 'app.component.html', + styleUrls: ['app.component.css'], +}) +export class AppComponent {} +``` diff --git a/static/usage/v7/autofocus/basic/angular/app_module_ts.md b/static/usage/v7/autofocus/basic/angular/app_module_ts.md new file mode 100644 index 00000000000..0d76afbc0ab --- /dev/null +++ b/static/usage/v7/autofocus/basic/angular/app_module_ts.md @@ -0,0 +1,19 @@ +```ts +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { BrowserModule } from '@angular/platform-browser'; + +import { IonicModule } from '@ionic/angular'; + +import { AppComponent } from './app.component'; +import { ExampleComponent } from './example.component'; + +import { AppRoutingModule } from './app-routing.module'; + +@NgModule({ + imports: [BrowserModule, FormsModule, AppRoutingModule, IonicModule.forRoot({ mode: 'md' })], + declarations: [AppComponent, ExampleComponent], + bootstrap: [AppComponent], +}) +export class AppModule {} +``` diff --git a/static/usage/v7/autofocus/basic/angular/app_routing_module_ts.md b/static/usage/v7/autofocus/basic/angular/app_routing_module_ts.md new file mode 100644 index 00000000000..2fd50e2824f --- /dev/null +++ b/static/usage/v7/autofocus/basic/angular/app_routing_module_ts.md @@ -0,0 +1,19 @@ +```ts +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { ExampleComponent } from './example.component'; + +@NgModule({ + imports: [ + RouterModule.forRoot([ + { + path: '', + component: ExampleComponent, + }, + ]), + ], + exports: [RouterModule], +}) +export class AppRoutingModule {} +``` diff --git a/static/usage/v7/autofocus/basic/angular/example_component_html.md b/static/usage/v7/autofocus/basic/angular/example_component_html.md new file mode 100644 index 00000000000..9d2b87499b8 --- /dev/null +++ b/static/usage/v7/autofocus/basic/angular/example_component_html.md @@ -0,0 +1,10 @@ +```html + + + + + + + + +``` diff --git a/static/usage/v7/autofocus/basic/angular/example_component_ts.md b/static/usage/v7/autofocus/basic/angular/example_component_ts.md new file mode 100644 index 00000000000..c5b5e0cd449 --- /dev/null +++ b/static/usage/v7/autofocus/basic/angular/example_component_ts.md @@ -0,0 +1,16 @@ +```ts +import { Component, ElementRef, ViewChild } from '@angular/core'; +import { IonInput } from '@ionic/angular'; + +@Component({ + selector: 'app-example', + templateUrl: 'example.component.html', + styleUrls: ['example.component.css'], +}) +export class ExampleComponent { + @ViewChild('input') input: IonInput; + ionViewWillEnter() { + this.input.setFocus(); + } +} +``` diff --git a/static/usage/v7/autofocus/basic/demo.html b/static/usage/v7/autofocus/basic/demo.html new file mode 100644 index 00000000000..d03d5c4345e --- /dev/null +++ b/static/usage/v7/autofocus/basic/demo.html @@ -0,0 +1,32 @@ + + + + + + Autofocus + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/usage/v7/autofocus/basic/index.md b/static/usage/v7/autofocus/basic/index.md new file mode 100644 index 00000000000..3aee574700b --- /dev/null +++ b/static/usage/v7/autofocus/basic/index.md @@ -0,0 +1,51 @@ +import Playground from '@site/src/components/global/Playground'; + +import javascript from './javascript.md'; + +import angular_app_component_html from './angular/app_component_html.md'; +import angular_app_component_ts from './angular/app_component_ts.md'; +import angular_app_module_ts from './angular/app_module_ts.md'; +import angular_app_routing_module_ts from './angular/app_routing_module_ts.md'; + +import angular_example_component_html from './angular/example_component_html.md'; +import angular_example_component_ts from './angular/example_component_ts.md'; + +import vue_app_vue from './vue/app_vue.md'; +import vue_main_ts from './vue/main_ts.md'; +import vue_example_vue from './vue/example_vue.md'; +import vue_router_ts from './vue/router_ts.md'; + +import react_main_tsx from './react/main_tsx.md'; +import react_home_page_tsx from './react/home_page_tsx.md'; + + diff --git a/static/usage/v7/autofocus/basic/javascript.md b/static/usage/v7/autofocus/basic/javascript.md new file mode 100644 index 00000000000..ce68dfbfe7e --- /dev/null +++ b/static/usage/v7/autofocus/basic/javascript.md @@ -0,0 +1,16 @@ +```html + + + + + + + + + + +``` diff --git a/static/usage/v7/autofocus/basic/react/home_page_tsx.md b/static/usage/v7/autofocus/basic/react/home_page_tsx.md new file mode 100644 index 00000000000..25729633cc0 --- /dev/null +++ b/static/usage/v7/autofocus/basic/react/home_page_tsx.md @@ -0,0 +1,28 @@ +```tsx +import React, { useRef } from 'react'; +import { IonInput, IonItem, IonList, IonPage, useIonViewWillEnter } from '@ionic/react'; + +const HomePage = () => { + const input = useRef(null); + + useIonViewWillEnter(() => { + console.log('useIonViewWillEnter'); + input.current?.setFocus(); + }); + + return ( + + + + + + + + + + + ); +}; + +export default HomePage; +``` diff --git a/static/usage/v7/autofocus/basic/react/main_tsx.md b/static/usage/v7/autofocus/basic/react/main_tsx.md new file mode 100644 index 00000000000..2a12eaba97b --- /dev/null +++ b/static/usage/v7/autofocus/basic/react/main_tsx.md @@ -0,0 +1,26 @@ +```tsx +import React from 'react'; +import { IonRouterOutlet } from '@ionic/react'; +import { IonReactRouter } from '@ionic/react-router'; + +import { Route, Redirect } from 'react-router'; + +import HomePage from './pages/HomePage'; + +function Example() { + return ( + + + + {/* + Use the render method to reduce the number of renders your component will have due to a route change. + + Use the component prop when your component depends on the RouterComponentProps passed in automatically. + */} + } exact={true} /> + + + ); +} +export default Example; +``` diff --git a/static/usage/v7/autofocus/basic/vue/app_vue.md b/static/usage/v7/autofocus/basic/vue/app_vue.md new file mode 100644 index 00000000000..b5f330406db --- /dev/null +++ b/static/usage/v7/autofocus/basic/vue/app_vue.md @@ -0,0 +1,20 @@ +```html + + + +``` diff --git a/static/usage/v7/autofocus/basic/vue/example_vue.md b/static/usage/v7/autofocus/basic/vue/example_vue.md new file mode 100644 index 00000000000..cc3bdc2f190 --- /dev/null +++ b/static/usage/v7/autofocus/basic/vue/example_vue.md @@ -0,0 +1,32 @@ +```html + + + +``` diff --git a/static/usage/v7/autofocus/basic/vue/main_ts.md b/static/usage/v7/autofocus/basic/vue/main_ts.md new file mode 100644 index 00000000000..d3253963fa5 --- /dev/null +++ b/static/usage/v7/autofocus/basic/vue/main_ts.md @@ -0,0 +1,32 @@ +```ts +import { createApp } from 'vue'; +import { IonicVue } from '@ionic/vue'; + +import App from './App.vue'; +import router from './router'; + +/* Core CSS required for Ionic components to work properly */ +import '@ionic/vue/css/core.css'; + +/* Basic CSS for apps built with Ionic */ +import '@ionic/vue/css/normalize.css'; +import '@ionic/vue/css/structure.css'; +import '@ionic/vue/css/typography.css'; + +/* Optional CSS utils that can be commented out */ +import '@ionic/vue/css/padding.css'; +import '@ionic/vue/css/float-elements.css'; +import '@ionic/vue/css/text-alignment.css'; +import '@ionic/vue/css/text-transformation.css'; +import '@ionic/vue/css/flex-utils.css'; +import '@ionic/vue/css/display.css'; + +/* Theme variables */ +import './theme/variables.css'; + +const app = createApp(App).use(IonicVue).use(router); + +router.isReady().then(() => { + app.mount('#app'); +}); +``` diff --git a/static/usage/v7/autofocus/basic/vue/router_ts.md b/static/usage/v7/autofocus/basic/vue/router_ts.md new file mode 100644 index 00000000000..2ca50b0b9bf --- /dev/null +++ b/static/usage/v7/autofocus/basic/vue/router_ts.md @@ -0,0 +1,20 @@ +```ts +import { createRouter, createWebHistory } from '@ionic/vue-router'; +import { RouteRecordRaw } from 'vue-router'; +import Example from './components/Example.vue'; + +const routes: Array = [ + { + path: '/', + component: Example, + }, +]; + +const router = createRouter({ + // Use: createWebHistory(process.env.BASE_URL) in your app + history: createWebHistory(), + routes, +}); + +export default router; +``` From d8e6509149d34d7c5a31cd45e974d819ae0b0b34 Mon Sep 17 00:00:00 2001 From: Shawn Taylor Date: Tue, 21 Nov 2023 18:03:27 -0500 Subject: [PATCH 02/11] Switch to ionViewDidEnter --- .../usage/v7/autofocus/basic/angular/example_component_ts.md | 2 +- static/usage/v7/autofocus/basic/react/home_page_tsx.md | 5 ++--- static/usage/v7/autofocus/basic/vue/example_vue.md | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/static/usage/v7/autofocus/basic/angular/example_component_ts.md b/static/usage/v7/autofocus/basic/angular/example_component_ts.md index c5b5e0cd449..072c71354a7 100644 --- a/static/usage/v7/autofocus/basic/angular/example_component_ts.md +++ b/static/usage/v7/autofocus/basic/angular/example_component_ts.md @@ -9,7 +9,7 @@ import { IonInput } from '@ionic/angular'; }) export class ExampleComponent { @ViewChild('input') input: IonInput; - ionViewWillEnter() { + ionViewDidEnter() { this.input.setFocus(); } } diff --git a/static/usage/v7/autofocus/basic/react/home_page_tsx.md b/static/usage/v7/autofocus/basic/react/home_page_tsx.md index 25729633cc0..9d7d5b39063 100644 --- a/static/usage/v7/autofocus/basic/react/home_page_tsx.md +++ b/static/usage/v7/autofocus/basic/react/home_page_tsx.md @@ -1,12 +1,11 @@ ```tsx import React, { useRef } from 'react'; -import { IonInput, IonItem, IonList, IonPage, useIonViewWillEnter } from '@ionic/react'; +import { IonInput, IonItem, IonList, IonPage, useIonViewDidEnter } from '@ionic/react'; const HomePage = () => { const input = useRef(null); - useIonViewWillEnter(() => { - console.log('useIonViewWillEnter'); + useIonViewDidEnter(() => { input.current?.setFocus(); }); diff --git a/static/usage/v7/autofocus/basic/vue/example_vue.md b/static/usage/v7/autofocus/basic/vue/example_vue.md index cc3bdc2f190..3b09f1a887f 100644 --- a/static/usage/v7/autofocus/basic/vue/example_vue.md +++ b/static/usage/v7/autofocus/basic/vue/example_vue.md @@ -14,15 +14,14 @@ diff --git a/static/usage/v7/autofocus/basic/javascript.md b/static/usage/v7/autofocus/basic/javascript.md index ce68dfbfe7e..1c0f57a98e0 100644 --- a/static/usage/v7/autofocus/basic/javascript.md +++ b/static/usage/v7/autofocus/basic/javascript.md @@ -1,16 +1,17 @@ ```html - + - + ``` diff --git a/static/usage/v7/autofocus/basic/react/home_page_tsx.md b/static/usage/v7/autofocus/basic/react/home_page_tsx.md index 9d7d5b39063..7fd517abc8d 100644 --- a/static/usage/v7/autofocus/basic/react/home_page_tsx.md +++ b/static/usage/v7/autofocus/basic/react/home_page_tsx.md @@ -13,10 +13,10 @@ const HomePage = () => { - + - + diff --git a/static/usage/v7/autofocus/basic/vue/example_vue.md b/static/usage/v7/autofocus/basic/vue/example_vue.md index 9794a04eda9..a9a7554728e 100644 --- a/static/usage/v7/autofocus/basic/vue/example_vue.md +++ b/static/usage/v7/autofocus/basic/vue/example_vue.md @@ -4,32 +4,26 @@ - + - + - ``` From 84b7f068adab30644c3d406e9d560be84c6d318b Mon Sep 17 00:00:00 2001 From: Sean Perkins Date: Wed, 22 Nov 2023 00:17:29 -0500 Subject: [PATCH 05/11] chore: prettier formatting --- docs/developing/autofocus.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/developing/autofocus.md b/docs/developing/autofocus.md index 2e3903ac285..df1122ca2cd 100644 --- a/docs/developing/autofocus.md +++ b/docs/developing/autofocus.md @@ -4,7 +4,10 @@ title: Autofocus Autofocus - + Developers that want to set focus to an element on "page load" can use the `setFocus` API to set focus to an element. This API should be used in place of the `autofocus` attribute and called within the `ionViewDidEnter` lifecycle event. From a4c883e3e73178022a8862d682a52a544a62431d Mon Sep 17 00:00:00 2001 From: Sean Perkins Date: Wed, 22 Nov 2023 10:38:51 -0500 Subject: [PATCH 06/11] chore: clean-up --- docs/developing/autofocus.md | 4 ++-- static/usage/v7/autofocus/basic/index.md | 6 +++--- .../basic/react/{home_page_tsx.md => home_tsx.md} | 4 ++-- static/usage/v7/autofocus/basic/react/main_tsx.md | 15 +++++++-------- 4 files changed, 14 insertions(+), 15 deletions(-) rename static/usage/v7/autofocus/basic/react/{home_page_tsx.md => home_tsx.md} (92%) diff --git a/docs/developing/autofocus.md b/docs/developing/autofocus.md index df1122ca2cd..64ebc687e6b 100644 --- a/docs/developing/autofocus.md +++ b/docs/developing/autofocus.md @@ -10,7 +10,7 @@ title: Autofocus /> -Developers that want to set focus to an element on "page load" can use the `setFocus` API to set focus to an element. This API should be used in place of the `autofocus` attribute and called within the `ionViewDidEnter` lifecycle event. +Developers that want to set focus to an element on "page load" can use the `setFocus` API to set focus to an element. This API should be used in place of the `autofocus` attribute and called within the `ionViewDidEnter` lifecycle event for routing applications and the `appload` event for vanilla JavaScript applications. The example below highlights the difference in behavior between the `autofocus` attribute and the `setFocus` API. @@ -18,7 +18,7 @@ import Basic from '@site/static/usage/v7/autofocus/basic/index.md'; -:::warning +:::warning Warning Developers will receive a warning in their console when using the `autofocus` attribute in the StackBlitz examples due to cross-origin restrictions. diff --git a/static/usage/v7/autofocus/basic/index.md b/static/usage/v7/autofocus/basic/index.md index 3aee574700b..8e9d829ff6c 100644 --- a/static/usage/v7/autofocus/basic/index.md +++ b/static/usage/v7/autofocus/basic/index.md @@ -16,7 +16,7 @@ import vue_example_vue from './vue/example_vue.md'; import vue_router_ts from './vue/router_ts.md'; import react_main_tsx from './react/main_tsx.md'; -import react_home_page_tsx from './react/home_page_tsx.md'; +import react_home_tsx from './react/home_tsx.md'; { +const Home = () => { const input = useRef(null); useIonViewDidEnter(() => { @@ -23,5 +23,5 @@ const HomePage = () => { ); }; -export default HomePage; +export default Home; ``` diff --git a/static/usage/v7/autofocus/basic/react/main_tsx.md b/static/usage/v7/autofocus/basic/react/main_tsx.md index 2a12eaba97b..74488b6069e 100644 --- a/static/usage/v7/autofocus/basic/react/main_tsx.md +++ b/static/usage/v7/autofocus/basic/react/main_tsx.md @@ -5,19 +5,18 @@ import { IonReactRouter } from '@ionic/react-router'; import { Route, Redirect } from 'react-router'; -import HomePage from './pages/HomePage'; +import Home from './pages/Home'; function Example() { return ( - - {/* - Use the render method to reduce the number of renders your component will have due to a route change. - - Use the component prop when your component depends on the RouterComponentProps passed in automatically. - */} - } exact={true} /> + + + + + + ); From 5141a893309c01a642d152a0460356f61c7be5ef Mon Sep 17 00:00:00 2001 From: Sean Perkins Date: Wed, 22 Nov 2023 11:05:54 -0500 Subject: [PATCH 07/11] chore: update content --- docs/developing/autofocus.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/developing/autofocus.md b/docs/developing/autofocus.md index 64ebc687e6b..c9df6484644 100644 --- a/docs/developing/autofocus.md +++ b/docs/developing/autofocus.md @@ -10,7 +10,11 @@ title: Autofocus /> -Developers that want to set focus to an element on "page load" can use the `setFocus` API to set focus to an element. This API should be used in place of the `autofocus` attribute and called within the `ionViewDidEnter` lifecycle event for routing applications and the `appload` event for vanilla JavaScript applications. +The `autofocus` attribute is a standard HTML attribute that allows developers to set focus to an element when a page loads. This attribute is commonly used to set focus to the first input element on a page. However, the `autofocus` attribute can cause issues in routing applications when navigating between pages. This is because the `autofocus` attribute will set focus to the element when the page loads, but will not set focus to the element when the page is revisited. + +# Managing Focus + +Ionic provides a `setFocus` API that allows developers to manually set focus to an element. This API should be used in place of the `autofocus` attribute and called within the `ionViewDidEnter` lifecycle event for routing applications, within the `didPresent` lifecycle event for overlays, and the `appload` event for vanilla JavaScript applications. The example below highlights the difference in behavior between the `autofocus` attribute and the `setFocus` API. From 622d83d858dc8fe4cd23e45121dc11283ada61fe Mon Sep 17 00:00:00 2001 From: Sean Perkins Date: Wed, 22 Nov 2023 14:05:13 -0500 Subject: [PATCH 08/11] chore: overhaul example --- docs/developing/autofocus.md | 29 --- docs/developing/managing-focus.md | 244 ++++++++++++++++++ sidebars.js | 2 +- .../basic/angular/app_component_html.md | 3 - .../basic/angular/app_component_ts.md | 10 - .../autofocus/basic/angular/app_module_ts.md | 19 -- .../basic/angular/app_routing_module_ts.md | 19 -- .../basic/angular/example_component_html.md | 10 - .../basic/angular/example_component_ts.md | 17 -- static/usage/v7/autofocus/basic/index.md | 51 ---- static/usage/v7/autofocus/basic/javascript.md | 17 -- .../v7/autofocus/basic/react/home_tsx.md | 27 -- .../v7/autofocus/basic/react/main_tsx.md | 25 -- .../usage/v7/autofocus/basic/vue/app_vue.md | 20 -- .../v7/autofocus/basic/vue/example_vue.md | 29 --- .../usage/v7/autofocus/basic/vue/main_ts.md | 32 --- .../usage/v7/autofocus/basic/vue/router_ts.md | 20 -- static/usage/v7/input/set-focus/angular.md | 10 + .../basic => input/set-focus}/demo.html | 12 +- static/usage/v7/input/set-focus/index.md | 17 ++ static/usage/v7/input/set-focus/javascript.md | 17 ++ static/usage/v7/input/set-focus/react.md | 23 ++ static/usage/v7/input/set-focus/vue.md | 25 ++ 23 files changed, 343 insertions(+), 335 deletions(-) delete mode 100644 docs/developing/autofocus.md create mode 100644 docs/developing/managing-focus.md delete mode 100644 static/usage/v7/autofocus/basic/angular/app_component_html.md delete mode 100644 static/usage/v7/autofocus/basic/angular/app_component_ts.md delete mode 100644 static/usage/v7/autofocus/basic/angular/app_module_ts.md delete mode 100644 static/usage/v7/autofocus/basic/angular/app_routing_module_ts.md delete mode 100644 static/usage/v7/autofocus/basic/angular/example_component_html.md delete mode 100644 static/usage/v7/autofocus/basic/angular/example_component_ts.md delete mode 100644 static/usage/v7/autofocus/basic/index.md delete mode 100644 static/usage/v7/autofocus/basic/javascript.md delete mode 100644 static/usage/v7/autofocus/basic/react/home_tsx.md delete mode 100644 static/usage/v7/autofocus/basic/react/main_tsx.md delete mode 100644 static/usage/v7/autofocus/basic/vue/app_vue.md delete mode 100644 static/usage/v7/autofocus/basic/vue/example_vue.md delete mode 100644 static/usage/v7/autofocus/basic/vue/main_ts.md delete mode 100644 static/usage/v7/autofocus/basic/vue/router_ts.md create mode 100644 static/usage/v7/input/set-focus/angular.md rename static/usage/v7/{autofocus/basic => input/set-focus}/demo.html (67%) create mode 100644 static/usage/v7/input/set-focus/index.md create mode 100644 static/usage/v7/input/set-focus/javascript.md create mode 100644 static/usage/v7/input/set-focus/react.md create mode 100644 static/usage/v7/input/set-focus/vue.md diff --git a/docs/developing/autofocus.md b/docs/developing/autofocus.md deleted file mode 100644 index c9df6484644..00000000000 --- a/docs/developing/autofocus.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Autofocus ---- - - - Autofocus - - - -The `autofocus` attribute is a standard HTML attribute that allows developers to set focus to an element when a page loads. This attribute is commonly used to set focus to the first input element on a page. However, the `autofocus` attribute can cause issues in routing applications when navigating between pages. This is because the `autofocus` attribute will set focus to the element when the page loads, but will not set focus to the element when the page is revisited. - -# Managing Focus - -Ionic provides a `setFocus` API that allows developers to manually set focus to an element. This API should be used in place of the `autofocus` attribute and called within the `ionViewDidEnter` lifecycle event for routing applications, within the `didPresent` lifecycle event for overlays, and the `appload` event for vanilla JavaScript applications. - -The example below highlights the difference in behavior between the `autofocus` attribute and the `setFocus` API. - -import Basic from '@site/static/usage/v7/autofocus/basic/index.md'; - - - -:::warning Warning - -Developers will receive a warning in their console when using the `autofocus` attribute in the StackBlitz examples due to cross-origin restrictions. - -::: diff --git a/docs/developing/managing-focus.md b/docs/developing/managing-focus.md new file mode 100644 index 00000000000..bf5c61ad7f6 --- /dev/null +++ b/docs/developing/managing-focus.md @@ -0,0 +1,244 @@ +--- +title: Managing Focus +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + Managing Focus + + + +## Autofocus Attribute + +The `autofocus` attribute is a standard HTML attribute that allows developers to set focus to an element when a page loads. This attribute is commonly used to set focus to the first input element on a page. However, the `autofocus` attribute can cause issues in routing applications when navigating between pages. This is because the `autofocus` attribute will set focus to the element when the page loads, but will not set focus to the element when the page is revisited. + +## Managing Focus + +Ionic provides a `setFocus` API that allows developers to manually set focus to an element. This API should be used in place of the `autofocus` attribute and called within: + +- The `ionViewDidEnter` lifecycle event for routing applications when a page is entered. +- The `didPresent` lifecycle event for overlays when an overlay is presented. +- The `appload` event for vanilla JavaScript applications when the application loads. +- The result of a user gesture or interaction. + +### Platform Restrictions + +There are platform restrictions you should be aware of when using the `setFocus` API, including: + +1. Android requires user interaction before setting focus to an element. This can be as simple as a user tapping on the screen. +2. Interactive elements can only focused a result of a user gesture on Mobile Safari (iOS), such as calling `setFocus` as the result of a button click. + +### Basic Usage + +The example below demonstrates how to use the `setFocus` API to request focus on an input when the user clicks a button. + +import Basic from '@site/static/usage/v7/input/set-focus/index.md'; + + + +### Routing + +Developers can use the `ionViewDidEnter` lifecycle event to set focus to an element when a page is entered. + +````mdx-code-block + + + + +```ts +/* example.component.ts */ +import { Component, ViewChild } from '@angular/core'; +import { IonInput } from '@ionic/angular'; + +@Component({ + selector: 'app-example', + templateUrl: './example.component.html', +}) +export class ExampleComponent { + @ViewChild('input') input!: IonInput; + + ionViewDidEnter() { + this.input.setFocus(); + } +} +``` + + + +```tsx +import React, { useRef } from 'react'; +import { IonInput, IonPage, useIonViewDidEnter } from '@ionic/react'; + +const Home = () => { + const input = useRef(null); + + useIonViewDidEnter(() => { + input.current?.setFocus(); + }); + + return ( + + + + ); +}; + +export default Home; +``` + + + + +```html + + + +``` + + + +```` + +### Overlays + +Developers can use the `didPresent` lifecycle event to set focus to an element when an overlay is presented. + +````mdx-code-block + + + + +```html + + + + + +``` + + + + + +```ts +/* example.component.ts */ +import { Component, ViewChild } from '@angular/core'; +import { IonInput } from '@ionic/angular'; + +@Component({ + selector: 'app-example', + templateUrl: './example.component.html', +}) +export class ExampleComponent { + @ViewChild('input') input!: IonInput; + + onDidPresent() { + this.input.setFocus(); + } +} +``` + +```html + + + + +``` + + + + +```tsx +import React, { useRef } from 'react'; +import { IonInput, IonModal, IonPage } from '@ionic/react'; + +const Home = () => { + const input = useRef(null); + + const onDidPresent = () => { + input.current?.setFocus(); + }; + + return ( + + + + + + ); +}; + +export default Home; +``` + + + + +```html + + + +``` + + + +```` diff --git a/sidebars.js b/sidebars.js index a92cf69609c..ac8d9c721d8 100644 --- a/sidebars.js +++ b/sidebars.js @@ -26,7 +26,7 @@ module.exports = { 'developing/hardware-back-button', 'developing/keyboard', 'developing/config', - 'developing/autofocus', + 'developing/managing-focus', ], }, { diff --git a/static/usage/v7/autofocus/basic/angular/app_component_html.md b/static/usage/v7/autofocus/basic/angular/app_component_html.md deleted file mode 100644 index 7636539f28a..00000000000 --- a/static/usage/v7/autofocus/basic/angular/app_component_html.md +++ /dev/null @@ -1,3 +0,0 @@ -```html - -``` diff --git a/static/usage/v7/autofocus/basic/angular/app_component_ts.md b/static/usage/v7/autofocus/basic/angular/app_component_ts.md deleted file mode 100644 index de26ac4a9f9..00000000000 --- a/static/usage/v7/autofocus/basic/angular/app_component_ts.md +++ /dev/null @@ -1,10 +0,0 @@ -```ts -import { Component } from '@angular/core'; - -@Component({ - selector: 'app-root', - templateUrl: 'app.component.html', - styleUrls: ['app.component.css'], -}) -export class AppComponent {} -``` diff --git a/static/usage/v7/autofocus/basic/angular/app_module_ts.md b/static/usage/v7/autofocus/basic/angular/app_module_ts.md deleted file mode 100644 index 0d76afbc0ab..00000000000 --- a/static/usage/v7/autofocus/basic/angular/app_module_ts.md +++ /dev/null @@ -1,19 +0,0 @@ -```ts -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; -import { BrowserModule } from '@angular/platform-browser'; - -import { IonicModule } from '@ionic/angular'; - -import { AppComponent } from './app.component'; -import { ExampleComponent } from './example.component'; - -import { AppRoutingModule } from './app-routing.module'; - -@NgModule({ - imports: [BrowserModule, FormsModule, AppRoutingModule, IonicModule.forRoot({ mode: 'md' })], - declarations: [AppComponent, ExampleComponent], - bootstrap: [AppComponent], -}) -export class AppModule {} -``` diff --git a/static/usage/v7/autofocus/basic/angular/app_routing_module_ts.md b/static/usage/v7/autofocus/basic/angular/app_routing_module_ts.md deleted file mode 100644 index 2fd50e2824f..00000000000 --- a/static/usage/v7/autofocus/basic/angular/app_routing_module_ts.md +++ /dev/null @@ -1,19 +0,0 @@ -```ts -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - -import { ExampleComponent } from './example.component'; - -@NgModule({ - imports: [ - RouterModule.forRoot([ - { - path: '', - component: ExampleComponent, - }, - ]), - ], - exports: [RouterModule], -}) -export class AppRoutingModule {} -``` diff --git a/static/usage/v7/autofocus/basic/angular/example_component_html.md b/static/usage/v7/autofocus/basic/angular/example_component_html.md deleted file mode 100644 index c7c394a9ecb..00000000000 --- a/static/usage/v7/autofocus/basic/angular/example_component_html.md +++ /dev/null @@ -1,10 +0,0 @@ -```html - - - - - - - - -``` diff --git a/static/usage/v7/autofocus/basic/angular/example_component_ts.md b/static/usage/v7/autofocus/basic/angular/example_component_ts.md deleted file mode 100644 index 89e8c215af0..00000000000 --- a/static/usage/v7/autofocus/basic/angular/example_component_ts.md +++ /dev/null @@ -1,17 +0,0 @@ -```ts -import { Component, ElementRef, ViewChild } from '@angular/core'; -import { IonInput } from '@ionic/angular'; - -@Component({ - selector: 'app-example', - templateUrl: 'example.component.html', - styleUrls: ['example.component.css'], -}) -export class ExampleComponent { - @ViewChild('input') input!: IonInput; - - ionViewDidEnter() { - this.input.setFocus(); - } -} -``` diff --git a/static/usage/v7/autofocus/basic/index.md b/static/usage/v7/autofocus/basic/index.md deleted file mode 100644 index 8e9d829ff6c..00000000000 --- a/static/usage/v7/autofocus/basic/index.md +++ /dev/null @@ -1,51 +0,0 @@ -import Playground from '@site/src/components/global/Playground'; - -import javascript from './javascript.md'; - -import angular_app_component_html from './angular/app_component_html.md'; -import angular_app_component_ts from './angular/app_component_ts.md'; -import angular_app_module_ts from './angular/app_module_ts.md'; -import angular_app_routing_module_ts from './angular/app_routing_module_ts.md'; - -import angular_example_component_html from './angular/example_component_html.md'; -import angular_example_component_ts from './angular/example_component_ts.md'; - -import vue_app_vue from './vue/app_vue.md'; -import vue_main_ts from './vue/main_ts.md'; -import vue_example_vue from './vue/example_vue.md'; -import vue_router_ts from './vue/router_ts.md'; - -import react_main_tsx from './react/main_tsx.md'; -import react_home_tsx from './react/home_tsx.md'; - - diff --git a/static/usage/v7/autofocus/basic/javascript.md b/static/usage/v7/autofocus/basic/javascript.md deleted file mode 100644 index 1c0f57a98e0..00000000000 --- a/static/usage/v7/autofocus/basic/javascript.md +++ /dev/null @@ -1,17 +0,0 @@ -```html - - - - - - - - - - -``` diff --git a/static/usage/v7/autofocus/basic/react/home_tsx.md b/static/usage/v7/autofocus/basic/react/home_tsx.md deleted file mode 100644 index 8db1b88d1a7..00000000000 --- a/static/usage/v7/autofocus/basic/react/home_tsx.md +++ /dev/null @@ -1,27 +0,0 @@ -```tsx -import React, { useRef } from 'react'; -import { IonInput, IonItem, IonList, IonPage, useIonViewDidEnter } from '@ionic/react'; - -const Home = () => { - const input = useRef(null); - - useIonViewDidEnter(() => { - input.current?.setFocus(); - }); - - return ( - - - - - - - - - - - ); -}; - -export default Home; -``` diff --git a/static/usage/v7/autofocus/basic/react/main_tsx.md b/static/usage/v7/autofocus/basic/react/main_tsx.md deleted file mode 100644 index 74488b6069e..00000000000 --- a/static/usage/v7/autofocus/basic/react/main_tsx.md +++ /dev/null @@ -1,25 +0,0 @@ -```tsx -import React from 'react'; -import { IonRouterOutlet } from '@ionic/react'; -import { IonReactRouter } from '@ionic/react-router'; - -import { Route, Redirect } from 'react-router'; - -import Home from './pages/Home'; - -function Example() { - return ( - - - - - - - - - - - ); -} -export default Example; -``` diff --git a/static/usage/v7/autofocus/basic/vue/app_vue.md b/static/usage/v7/autofocus/basic/vue/app_vue.md deleted file mode 100644 index b5f330406db..00000000000 --- a/static/usage/v7/autofocus/basic/vue/app_vue.md +++ /dev/null @@ -1,20 +0,0 @@ -```html - - - -``` diff --git a/static/usage/v7/autofocus/basic/vue/example_vue.md b/static/usage/v7/autofocus/basic/vue/example_vue.md deleted file mode 100644 index a9a7554728e..00000000000 --- a/static/usage/v7/autofocus/basic/vue/example_vue.md +++ /dev/null @@ -1,29 +0,0 @@ -```html - - - -``` diff --git a/static/usage/v7/autofocus/basic/vue/main_ts.md b/static/usage/v7/autofocus/basic/vue/main_ts.md deleted file mode 100644 index d3253963fa5..00000000000 --- a/static/usage/v7/autofocus/basic/vue/main_ts.md +++ /dev/null @@ -1,32 +0,0 @@ -```ts -import { createApp } from 'vue'; -import { IonicVue } from '@ionic/vue'; - -import App from './App.vue'; -import router from './router'; - -/* Core CSS required for Ionic components to work properly */ -import '@ionic/vue/css/core.css'; - -/* Basic CSS for apps built with Ionic */ -import '@ionic/vue/css/normalize.css'; -import '@ionic/vue/css/structure.css'; -import '@ionic/vue/css/typography.css'; - -/* Optional CSS utils that can be commented out */ -import '@ionic/vue/css/padding.css'; -import '@ionic/vue/css/float-elements.css'; -import '@ionic/vue/css/text-alignment.css'; -import '@ionic/vue/css/text-transformation.css'; -import '@ionic/vue/css/flex-utils.css'; -import '@ionic/vue/css/display.css'; - -/* Theme variables */ -import './theme/variables.css'; - -const app = createApp(App).use(IonicVue).use(router); - -router.isReady().then(() => { - app.mount('#app'); -}); -``` diff --git a/static/usage/v7/autofocus/basic/vue/router_ts.md b/static/usage/v7/autofocus/basic/vue/router_ts.md deleted file mode 100644 index 2ca50b0b9bf..00000000000 --- a/static/usage/v7/autofocus/basic/vue/router_ts.md +++ /dev/null @@ -1,20 +0,0 @@ -```ts -import { createRouter, createWebHistory } from '@ionic/vue-router'; -import { RouteRecordRaw } from 'vue-router'; -import Example from './components/Example.vue'; - -const routes: Array = [ - { - path: '/', - component: Example, - }, -]; - -const router = createRouter({ - // Use: createWebHistory(process.env.BASE_URL) in your app - history: createWebHistory(), - routes, -}); - -export default router; -``` diff --git a/static/usage/v7/input/set-focus/angular.md b/static/usage/v7/input/set-focus/angular.md new file mode 100644 index 00000000000..92c9d6b2561 --- /dev/null +++ b/static/usage/v7/input/set-focus/angular.md @@ -0,0 +1,10 @@ +```html + + + Click to set focus + + + + + +``` diff --git a/static/usage/v7/autofocus/basic/demo.html b/static/usage/v7/input/set-focus/demo.html similarity index 67% rename from static/usage/v7/autofocus/basic/demo.html rename to static/usage/v7/input/set-focus/demo.html index fbc2c99aea4..7ebd39bec3a 100644 --- a/static/usage/v7/autofocus/basic/demo.html +++ b/static/usage/v7/input/set-focus/demo.html @@ -3,7 +3,7 @@ - Autofocus + setFocus @@ -15,19 +15,19 @@ - + Click to set focus - + diff --git a/static/usage/v7/input/set-focus/index.md b/static/usage/v7/input/set-focus/index.md new file mode 100644 index 00000000000..4728673f041 --- /dev/null +++ b/static/usage/v7/input/set-focus/index.md @@ -0,0 +1,17 @@ +import Playground from '@site/src/components/global/Playground'; + +import javascript from './javascript.md'; +import angular from './angular.md'; +import vue from './vue.md'; +import react from './react.md'; + + diff --git a/static/usage/v7/input/set-focus/javascript.md b/static/usage/v7/input/set-focus/javascript.md new file mode 100644 index 00000000000..1d5a5b4cfbc --- /dev/null +++ b/static/usage/v7/input/set-focus/javascript.md @@ -0,0 +1,17 @@ +```html + + + Click to set focus + + + + + + + +``` diff --git a/static/usage/v7/input/set-focus/react.md b/static/usage/v7/input/set-focus/react.md new file mode 100644 index 00000000000..5828ea42366 --- /dev/null +++ b/static/usage/v7/input/set-focus/react.md @@ -0,0 +1,23 @@ +```tsx +import React, { useRef } from 'react'; +import { IonInput, IonItem, IonList, IonButton, IonPage } from '@ionic/react'; + +const Home = () => { + const input = useRef(null); + + return ( + + + + input.current?.setFocus()}>Click to set focus + + + + + + + ); +}; + +export default Home; +``` diff --git a/static/usage/v7/input/set-focus/vue.md b/static/usage/v7/input/set-focus/vue.md new file mode 100644 index 00000000000..1e43eb8aa7c --- /dev/null +++ b/static/usage/v7/input/set-focus/vue.md @@ -0,0 +1,25 @@ +```html + + + +``` From f340672eea597585bce6bd3fd0ad28251318d853 Mon Sep 17 00:00:00 2001 From: Sean Perkins <13732623+sean-perkins@users.noreply.github.com> Date: Mon, 27 Nov 2023 11:00:00 -0500 Subject: [PATCH 09/11] Update docs/developing/managing-focus.md Co-authored-by: Liam DeBeasi --- docs/developing/managing-focus.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developing/managing-focus.md b/docs/developing/managing-focus.md index bf5c61ad7f6..66064065821 100644 --- a/docs/developing/managing-focus.md +++ b/docs/developing/managing-focus.md @@ -19,7 +19,7 @@ The `autofocus` attribute is a standard HTML attribute that allows developers to ## Managing Focus -Ionic provides a `setFocus` API that allows developers to manually set focus to an element. This API should be used in place of the `autofocus` attribute and called within: +Ionic provides a `setFocus` API on components such as [Input](../api/input), [Searchbar](../api/searchbar), and [Textarea](../api/textarea) that allows developers to manually set focus to an element. This API should be used in place of the `autofocus` attribute and called within: - The `ionViewDidEnter` lifecycle event for routing applications when a page is entered. - The `didPresent` lifecycle event for overlays when an overlay is presented. From e641da72b8f43a4f9e8852f369e899ba5fc6fcd1 Mon Sep 17 00:00:00 2001 From: Sean Perkins Date: Mon, 27 Nov 2023 11:12:04 -0500 Subject: [PATCH 10/11] chore: update content --- docs/developing/managing-focus.md | 40 ++++++++++-------------- static/usage/v7/input/set-focus/react.md | 20 ++++++------ static/usage/v7/input/set-focus/vue.md | 2 +- 3 files changed, 27 insertions(+), 35 deletions(-) diff --git a/docs/developing/managing-focus.md b/docs/developing/managing-focus.md index 66064065821..01b112ea68c 100644 --- a/docs/developing/managing-focus.md +++ b/docs/developing/managing-focus.md @@ -13,12 +13,6 @@ import TabItem from '@theme/TabItem'; /> -## Autofocus Attribute - -The `autofocus` attribute is a standard HTML attribute that allows developers to set focus to an element when a page loads. This attribute is commonly used to set focus to the first input element on a page. However, the `autofocus` attribute can cause issues in routing applications when navigating between pages. This is because the `autofocus` attribute will set focus to the element when the page loads, but will not set focus to the element when the page is revisited. - -## Managing Focus - Ionic provides a `setFocus` API on components such as [Input](../api/input), [Searchbar](../api/searchbar), and [Textarea](../api/textarea) that allows developers to manually set focus to an element. This API should be used in place of the `autofocus` attribute and called within: - The `ionViewDidEnter` lifecycle event for routing applications when a page is entered. @@ -26,14 +20,18 @@ Ionic provides a `setFocus` API on components such as [Input](../api/input), [Se - The `appload` event for vanilla JavaScript applications when the application loads. - The result of a user gesture or interaction. -### Platform Restrictions +## Why not autofocus? + +The `autofocus` attribute is a standard HTML attribute that allows developers to set focus to an element when a page loads. This attribute is commonly used to set focus to the first input element on a page. However, the `autofocus` attribute can cause issues in routing applications when navigating between pages. This is because the `autofocus` attribute will set focus to the element when the page loads, but will not set focus to the element when the page is revisited. Learn more about the `autofocus` attribute in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autofocus). + +## Platform Restrictions There are platform restrictions you should be aware of when using the `setFocus` API, including: 1. Android requires user interaction before setting focus to an element. This can be as simple as a user tapping on the screen. 2. Interactive elements can only focused a result of a user gesture on Mobile Safari (iOS), such as calling `setFocus` as the result of a button click. -### Basic Usage +## Basic Usage The example below demonstrates how to use the `setFocus` API to request focus on an input when the user clicks a button. @@ -41,7 +39,7 @@ import Basic from '@site/static/usage/v7/input/set-focus/index.md'; -### Routing +## Routing Developers can use the `ionViewDidEnter` lifecycle event to set focus to an element when a page is entered. @@ -105,7 +103,7 @@ export default Home; ```html @@ -128,7 +126,7 @@ export default Home; ```` -### Overlays +## Overlays Developers can use the `didPresent` lifecycle event to set focus to an element when an overlay is presented. @@ -194,7 +192,7 @@ export class ExampleComponent { ```tsx import React, { useRef } from 'react'; -import { IonInput, IonModal, IonPage } from '@ionic/react'; +import { IonInput, IonModal } from '@ionic/react'; const Home = () => { const input = useRef(null); @@ -204,11 +202,9 @@ const Home = () => { }; return ( - - - - - + + + ); }; @@ -220,15 +216,13 @@ export default Home; ```html