From e2f96bf2546bf7d9d30b6bdf7fc04a2c53fd3825 Mon Sep 17 00:00:00 2001 From: Brandy Smith Date: Mon, 20 Jan 2025 16:44:25 -0500 Subject: [PATCH 1/6] docs(config): add logLevel to config options (#3998) --- docs/developing/config.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/developing/config.md b/docs/developing/config.md index 02ac03567e2..0f70b8da46d 100644 --- a/docs/developing/config.md +++ b/docs/developing/config.md @@ -178,6 +178,7 @@ Below are the config options that Ionic uses. | `loadingEnter` | `AnimationBuilder` | Provides a custom enter animation for all `ion-loading`, overriding the default "animation". | | `loadingLeave` | `AnimationBuilder` | Provides a custom leave animation for all `ion-loading`, overriding the default "animation". | | `loadingSpinner` | `SpinnerTypes` | Overrides the default spinner for all `ion-loading` overlays. | +| `logLevel` | `'OFF' \| 'ERROR' \| 'WARN'` | Configures the logging level for Ionic Framework. If `'OFF'`, no errors or warnings are logged. If `'ERROR'`, only errors are logged. If `'WARN'`, errors and warnings are logged. | | `menuIcon` | `string` | Overrides the default icon in all `` components. | | `menuType` | `string` | Overrides the default menu type for all `` components. | | `modalEnter` | `AnimationBuilder` | Provides a custom enter animation for all `ion-modal`, overriding the default "animation". | From 65ef887506a483691c7823e80acbd16db1e824bc Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Tue, 11 Mar 2025 12:07:37 -0700 Subject: [PATCH 2/6] feat(modal): add expandToScroll section (#4021) --- docs/api/modal.md | 8 + .../angular/example_component_html.md | 165 ++++++++++++++++ .../angular/example_component_ts.md | 36 ++++ .../v8/modal/sheet/expand-to-scroll/demo.html | 179 +++++++++++++++++ .../v8/modal/sheet/expand-to-scroll/index.md | 26 +++ .../sheet/expand-to-scroll/javascript.md | 140 +++++++++++++ .../v8/modal/sheet/expand-to-scroll/react.md | 185 ++++++++++++++++++ .../v8/modal/sheet/expand-to-scroll/vue.md | 181 +++++++++++++++++ 8 files changed, 920 insertions(+) create mode 100644 static/usage/v8/modal/sheet/expand-to-scroll/angular/example_component_html.md create mode 100644 static/usage/v8/modal/sheet/expand-to-scroll/angular/example_component_ts.md create mode 100644 static/usage/v8/modal/sheet/expand-to-scroll/demo.html create mode 100644 static/usage/v8/modal/sheet/expand-to-scroll/index.md create mode 100644 static/usage/v8/modal/sheet/expand-to-scroll/javascript.md create mode 100644 static/usage/v8/modal/sheet/expand-to-scroll/react.md create mode 100644 static/usage/v8/modal/sheet/expand-to-scroll/vue.md diff --git a/docs/api/modal.md b/docs/api/modal.md index d8fb298ded3..1249e2a813b 100644 --- a/docs/api/modal.md +++ b/docs/api/modal.md @@ -157,6 +157,14 @@ import SheetHandleBehaviorExample from '@site/static/usage/v8/modal/sheet/handle +### Scrolling content at all breakpoints + +Sheet modals can be configured to allow scrolling content at all breakpoints, making them ideal for displaying content larger than the viewport. By setting the `expandToScroll` property to `false`, the content remains scrollable at every breakpoint. Otherwise, by default, scrolling is only enabled when the sheet modal is fully expanded. + +import SheetScrollingContentExample from '@site/static/usage/v8/modal/sheet/expand-to-scroll/index.md'; + + + ## Styling Modals are presented at the root of your application so they overlay your entire app. This behavior applies to both inline modals and modals presented from a controller. As a result, custom modal styles can not be scoped to a particular component as they will not apply to the modal. Instead, styles must be applied globally. For most developers, placing the custom styles in `global.css` is sufficient. diff --git a/static/usage/v8/modal/sheet/expand-to-scroll/angular/example_component_html.md b/static/usage/v8/modal/sheet/expand-to-scroll/angular/example_component_html.md new file mode 100644 index 00000000000..5357e9e82ef --- /dev/null +++ b/static/usage/v8/modal/sheet/expand-to-scroll/angular/example_component_html.md @@ -0,0 +1,165 @@ +```html + + + App + + + + Open Sheet Modal + + + + + + + + + + +

Connor Smith

+

Sales Rep

+
+
+ + + + + +

Jack Smith

+

Product Designer

+
+
+ + + + + +

Daniel Smith

+

Product Designer

+
+
+ + + + + +

Claire Smith

+

Graphic Designer

+
+
+ + + + + +

Kim Smith

+

Software Engineer

+
+
+ + + + + +

Alex Smith

+

Software Engineer

+
+
+ + + + + +

Eric Smith

+

Product Manager

+
+
+ + + + + +

Grace Smith

+

Product Manager

+
+
+ + + + + +

Henry Smith

+

Product Owner

+
+
+ + + + + +

Greg Smith

+

Director of Operations

+
+
+ + + + + +

Zoey Smith

+

CEO

+
+
+ + + + + +

Oliver Smith

+

COO

+
+
+ + + + + +

Emma Smith

+

CTO

+
+
+
+
+
+
+
+``` diff --git a/static/usage/v8/modal/sheet/expand-to-scroll/angular/example_component_ts.md b/static/usage/v8/modal/sheet/expand-to-scroll/angular/example_component_ts.md new file mode 100644 index 00000000000..c41fa70b4e3 --- /dev/null +++ b/static/usage/v8/modal/sheet/expand-to-scroll/angular/example_component_ts.md @@ -0,0 +1,36 @@ +```ts +import { Component } from '@angular/core'; +import { + IonAvatar, + IonButton, + IonContent, + IonHeader, + IonImg, + IonItem, + IonLabel, + IonList, + IonModal, + IonTitle, + IonToolbar, +} from '@ionic/angular/standalone'; + +@Component({ + selector: 'app-example', + templateUrl: 'example.component.html', + styleUrls: ['example.component.css'], + imports: [ + IonAvatar, + IonButton, + IonContent, + IonHeader, + IonImg, + IonItem, + IonLabel, + IonList, + IonModal, + IonTitle, + IonToolbar, + ], +}) +export class ExampleComponent {} +``` diff --git a/static/usage/v8/modal/sheet/expand-to-scroll/demo.html b/static/usage/v8/modal/sheet/expand-to-scroll/demo.html new file mode 100644 index 00000000000..79516adaef7 --- /dev/null +++ b/static/usage/v8/modal/sheet/expand-to-scroll/demo.html @@ -0,0 +1,179 @@ + + + + + + Modal | Sheet + + + + + + + + + + + App + + + + Open Sheet Modal + + + + + + + + + +

Connor Smith

+

Sales Rep

+
+
+ + + + + +

Jack Smith

+

Product Designer

+
+
+ + + + + +

Daniel Smith

+

Product Designer

+
+
+ + + + + +

Claire Smith

+

Graphic Designer

+
+
+ + + + + +

Kim Smith

+

Software Engineer

+
+
+ + + + + +

Alex Smith

+

Software Engineer

+
+
+ + + + + +

Eric Smith

+

Product Manager

+
+
+ + + + + +

Grace Smith

+

Product Manager

+
+
+ + + + + +

Henry Smith

+

Product Owner

+
+
+ + + + + +

Greg Smith

+

Director of Operations

+
+
+ + + + + +

Zoey Smith

+

CEO

+
+
+ + + + + +

Oliver Smith

+

COO

+
+
+ + + + + +

Emma Smith

+

CTO

+
+
+
+
+
+
+
+ + + + diff --git a/static/usage/v8/modal/sheet/expand-to-scroll/index.md b/static/usage/v8/modal/sheet/expand-to-scroll/index.md new file mode 100644 index 00000000000..f656ead1a57 --- /dev/null +++ b/static/usage/v8/modal/sheet/expand-to-scroll/index.md @@ -0,0 +1,26 @@ +import Playground from '@site/src/components/global/Playground'; + +import javascript from './javascript.md'; +import react from './react.md'; +import vue from './vue.md'; + +import angular_example_component_html from './angular/example_component_html.md'; +import angular_example_component_ts from './angular/example_component_ts.md'; + + diff --git a/static/usage/v8/modal/sheet/expand-to-scroll/javascript.md b/static/usage/v8/modal/sheet/expand-to-scroll/javascript.md new file mode 100644 index 00000000000..b4f04b5a634 --- /dev/null +++ b/static/usage/v8/modal/sheet/expand-to-scroll/javascript.md @@ -0,0 +1,140 @@ +```html + + + App + + + + Open Sheet Modal + + + + + + + + + +

Connor Smith

+

Sales Rep

+
+
+ + + + + +

Jack Smith

+

Product Designer

+
+
+ + + + + +

Daniel Smith

+

Product Designer

+
+
+ + + + + +

Claire Smith

+

Graphic Designer

+
+
+ + + + + +

Kim Smith

+

Software Engineer

+
+
+ + + + + +

Alex Smith

+

Software Engineer

+
+
+ + + + + +

Eric Smith

+

Product Manager

+
+
+ + + + + +

Grace Smith

+

Product Manager

+
+
+ + + + + +

Henry Smith

+

Product Owner

+
+
+ + + + + +

Greg Smith

+

Director of Operations

+
+
+ + + + + +

Zoey Smith

+

CEO

+
+
+ + + + + +

Oliver Smith

+

COO

+
+
+ + + + + +

Emma Smith

+

CTO

+
+
+
+
+
+
+ + +``` diff --git a/static/usage/v8/modal/sheet/expand-to-scroll/react.md b/static/usage/v8/modal/sheet/expand-to-scroll/react.md new file mode 100644 index 00000000000..e6afd40b516 --- /dev/null +++ b/static/usage/v8/modal/sheet/expand-to-scroll/react.md @@ -0,0 +1,185 @@ +```tsx +import React from 'react'; +import { + IonButton, + IonModal, + IonHeader, + IonContent, + IonToolbar, + IonTitle, + IonPage, + IonList, + IonItem, + IonLabel, + IonAvatar, + IonImg, +} from '@ionic/react'; + +function Example() { + return ( + + + + App + + + + + Open Sheet Modal + + + + + + + + + +

Connor Smith

+

Sales Rep

+
+
+ + + + + +

Jack Smith

+

Product Designer

+
+
+ + + + + +

Daniel Smith

+

Product Designer

+
+
+ + + + + +

Claire Smith

+

Graphic Designer

+
+
+ + + + + +

Kim Smith

+

Software Engineer

+
+
+ + + + + +

Alex Smith

+

Software Engineer

+
+
+ + + + + +

Eric Smith

+

Product Manager

+
+
+ + + + + +

Grace Smith

+

Product Manager

+
+
+ + + + + +

Henry Smith

+

Product Owner

+
+
+ + + + + +

Greg Smith

+

Director of Operations

+
+
+ + + + + +

Zoey Smith

+

CEO

+
+
+ + + + + +

Oliver Smith

+

COO

+
+
+ + + + + +

Emma Smith

+

CTO

+
+
+
+
+
+
+
+ ); +} + +export default Example; +``` diff --git a/static/usage/v8/modal/sheet/expand-to-scroll/vue.md b/static/usage/v8/modal/sheet/expand-to-scroll/vue.md new file mode 100644 index 00000000000..57526a20fed --- /dev/null +++ b/static/usage/v8/modal/sheet/expand-to-scroll/vue.md @@ -0,0 +1,181 @@ +```html + + + +``` From cd309cc68b8ec8c5d8bab2e8a997063922169072 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Tue, 11 Mar 2025 12:08:37 -0700 Subject: [PATCH 3/6] docs(radio): add helperText and errorText section through radio-group (#4034) Co-authored-by: Brandy Smith --- docs/api/radio.md | 10 +++ .../angular/example_component_html.md | 18 ++++++ .../angular/example_component_ts.md | 29 +++++++++ static/usage/v8/radio/helper-error/demo.html | 62 +++++++++++++++++++ static/usage/v8/radio/helper-error/index.md | 24 +++++++ .../usage/v8/radio/helper-error/javascript.md | 40 ++++++++++++ static/usage/v8/radio/helper-error/react.md | 58 +++++++++++++++++ static/usage/v8/radio/helper-error/vue.md | 57 +++++++++++++++++ 8 files changed, 298 insertions(+) create mode 100644 static/usage/v8/radio/helper-error/angular/example_component_html.md create mode 100644 static/usage/v8/radio/helper-error/angular/example_component_ts.md create mode 100644 static/usage/v8/radio/helper-error/demo.html create mode 100644 static/usage/v8/radio/helper-error/index.md create mode 100644 static/usage/v8/radio/helper-error/javascript.md create mode 100644 static/usage/v8/radio/helper-error/react.md create mode 100644 static/usage/v8/radio/helper-error/vue.md diff --git a/docs/api/radio.md b/docs/api/radio.md index c22b839f24e..fb717c14835 100644 --- a/docs/api/radio.md +++ b/docs/api/radio.md @@ -76,6 +76,16 @@ import EmptySelection from '@site/static/usage/v8/radio/empty-selection/index.md +## Helper & Error Text + +Helper and error text can be used inside of a radio group with the `helperText` and `errorText` property. The error text will not be displayed unless the `ion-invalid` and `ion-touched` classes are added to the `ion-radio-group`. This ensures errors are not shown before the user has a chance to enter data. + +In Angular, this is done automatically through form validation. In JavaScript, React and Vue, the class needs to be manually added based on your own validation. + +import HelperError from '@site/static/usage/v8/radio/helper-error/index.md'; + + + ## Theming diff --git a/static/usage/v8/radio/helper-error/angular/example_component_html.md b/static/usage/v8/radio/helper-error/angular/example_component_html.md new file mode 100644 index 00000000000..87b06290e49 --- /dev/null +++ b/static/usage/v8/radio/helper-error/angular/example_component_html.md @@ -0,0 +1,18 @@ +```html +
+ + Grapes
+ Strawberries
+ Pineapple
+ Cherries +
+ +
+ + Submit +
+``` diff --git a/static/usage/v8/radio/helper-error/angular/example_component_ts.md b/static/usage/v8/radio/helper-error/angular/example_component_ts.md new file mode 100644 index 00000000000..463765b9cb6 --- /dev/null +++ b/static/usage/v8/radio/helper-error/angular/example_component_ts.md @@ -0,0 +1,29 @@ +```ts +import { Component } from '@angular/core'; +import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms'; +import { IonRadioGroup, IonRadio, IonButton } from '@ionic/angular/standalone'; + +@Component({ + selector: 'app-example', + standalone: true, + imports: [IonRadioGroup, IonRadio, IonButton, ReactiveFormsModule], + templateUrl: './example.component.html', + styleUrl: './example.component.css', +}) +export class ExampleComponent { + myForm: FormGroup; + + constructor(private fb: FormBuilder) { + this.myForm = this.fb.group({ + favFruit: ['', Validators.required], + }); + } + + onSubmit() { + // Mark the control as touched to trigger the error message. + // This is needed if the user submits the form without interacting + // with the toggle. + this.myForm.get('favFruit')!.markAsTouched(); + } +} +``` diff --git a/static/usage/v8/radio/helper-error/demo.html b/static/usage/v8/radio/helper-error/demo.html new file mode 100644 index 00000000000..7a8d6abfccf --- /dev/null +++ b/static/usage/v8/radio/helper-error/demo.html @@ -0,0 +1,62 @@ + + + + + + Input + + + + + + + + + +
+
+ + Grapes
+ Strawberries
+ Pineapple
+ Cherries +
+ +
+ + Submit +
+
+ + + + diff --git a/static/usage/v8/radio/helper-error/index.md b/static/usage/v8/radio/helper-error/index.md new file mode 100644 index 00000000000..d8fb76a225a --- /dev/null +++ b/static/usage/v8/radio/helper-error/index.md @@ -0,0 +1,24 @@ +import Playground from '@site/src/components/global/Playground'; + +import javascript from './javascript.md'; +import react from './react.md'; +import vue from './vue.md'; + +import angular_example_component_html from './angular/example_component_html.md'; +import angular_example_component_ts from './angular/example_component_ts.md'; + + diff --git a/static/usage/v8/radio/helper-error/javascript.md b/static/usage/v8/radio/helper-error/javascript.md new file mode 100644 index 00000000000..64507f303fb --- /dev/null +++ b/static/usage/v8/radio/helper-error/javascript.md @@ -0,0 +1,40 @@ +```html +
+ + Grapes
+ Strawberries
+ Pineapple
+ Cherries +
+ +
+ + Submit +
+ + +``` diff --git a/static/usage/v8/radio/helper-error/react.md b/static/usage/v8/radio/helper-error/react.md new file mode 100644 index 00000000000..07eabf323c3 --- /dev/null +++ b/static/usage/v8/radio/helper-error/react.md @@ -0,0 +1,58 @@ +```tsx +import React, { useRef, useState } from 'react'; +import { IonRadioGroup, IonRadio, IonButton, RadioGroupCustomEvent } from '@ionic/react'; + +function Example() { + const [isTouched, setIsTouched] = useState(false); + const [isValid, setIsValid] = useState(); + + const favFruitRef = useRef(null); + + const validateRadioGroup = (event: RadioGroupCustomEvent<{ value: string }>) => { + setIsTouched(true); + setIsValid(event.detail.value ? true : false); + }; + + const submit = (event: React.FormEvent) => { + event.preventDefault(); + + if (favFruitRef.current) { + validateRadioGroup({ detail: { value: favFruitRef.current.value } } as RadioGroupCustomEvent<{ + value: string; + }>); + } + }; + + return ( + <> +
+ validateRadioGroup(event)} + > + Grapes +
+ Strawberries +
+ Pineapple +
+ Cherries +
+ +
+ + + Submit + +
+ + ); +} + +export default Example; +``` diff --git a/static/usage/v8/radio/helper-error/vue.md b/static/usage/v8/radio/helper-error/vue.md new file mode 100644 index 00000000000..7b823c392d5 --- /dev/null +++ b/static/usage/v8/radio/helper-error/vue.md @@ -0,0 +1,57 @@ +```html + + + +``` From 2d9c68256d017cd76b2866bfe1dabea5207ae782 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Tue, 11 Mar 2025 12:08:58 -0700 Subject: [PATCH 4/6] docs(toggle): add helperText and errorText section (#4033) Co-authored-by: Brandy Smith --- docs/api/toggle.md | 10 ++++ .../angular/example_component_html.md | 13 +++++ .../angular/example_component_ts.md | 28 +++++++++++ static/usage/v8/toggle/helper-error/demo.html | 48 +++++++++++++++++++ static/usage/v8/toggle/helper-error/index.md | 24 ++++++++++ .../v8/toggle/helper-error/javascript.md | 28 +++++++++++ static/usage/v8/toggle/helper-error/react.md | 38 +++++++++++++++ static/usage/v8/toggle/helper-error/vue.md | 47 ++++++++++++++++++ 8 files changed, 236 insertions(+) create mode 100644 static/usage/v8/toggle/helper-error/angular/example_component_html.md create mode 100644 static/usage/v8/toggle/helper-error/angular/example_component_ts.md create mode 100644 static/usage/v8/toggle/helper-error/demo.html create mode 100644 static/usage/v8/toggle/helper-error/index.md create mode 100644 static/usage/v8/toggle/helper-error/javascript.md create mode 100644 static/usage/v8/toggle/helper-error/react.md create mode 100644 static/usage/v8/toggle/helper-error/vue.md diff --git a/docs/api/toggle.md b/docs/api/toggle.md index b5a489705ce..c0b7445b2ac 100644 --- a/docs/api/toggle.md +++ b/docs/api/toggle.md @@ -73,6 +73,16 @@ import Justify from '@site/static/usage/v8/toggle/justify/index.md'; +## Helper & Error Text + +Helper and error text can be used inside of a toggle with the `helperText` and `errorText` property. The error text will not be displayed unless the `ion-invalid` and `ion-touched` classes are added to the `ion-toggle`. This ensures errors are not shown before the user has a chance to enter data. + +In Angular, this is done automatically through form validation. In JavaScript, React and Vue, the class needs to be manually added based on your own validation. + +import HelperError from '@site/static/usage/v8/toggle/helper-error/index.md'; + + + ## Theming ### Colors diff --git a/static/usage/v8/toggle/helper-error/angular/example_component_html.md b/static/usage/v8/toggle/helper-error/angular/example_component_html.md new file mode 100644 index 00000000000..d5d477aa14a --- /dev/null +++ b/static/usage/v8/toggle/helper-error/angular/example_component_html.md @@ -0,0 +1,13 @@ +```html +
+ + Wi-Fi + +
+``` diff --git a/static/usage/v8/toggle/helper-error/angular/example_component_ts.md b/static/usage/v8/toggle/helper-error/angular/example_component_ts.md new file mode 100644 index 00000000000..3605e2794b2 --- /dev/null +++ b/static/usage/v8/toggle/helper-error/angular/example_component_ts.md @@ -0,0 +1,28 @@ +```ts +import { Component } from '@angular/core'; +import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms'; +import { IonToggle } from '@ionic/angular/standalone'; + +@Component({ + selector: 'app-example', + standalone: true, + imports: [IonToggle, ReactiveFormsModule], + templateUrl: './example.component.html', + styleUrl: './example.component.css', +}) +export class ExampleComponent { + myForm: FormGroup; + + constructor(private fb: FormBuilder) { + this.myForm = this.fb.group({ + wifi: [true, Validators.requiredTrue], + }); + } + + onChange() { + // Mark the control as touched to trigger the error message + // without requiring the toggle to be blurred first + this.myForm.get('wifi')!.markAsTouched(); + } +} +``` diff --git a/static/usage/v8/toggle/helper-error/demo.html b/static/usage/v8/toggle/helper-error/demo.html new file mode 100644 index 00000000000..25c9bd8ec59 --- /dev/null +++ b/static/usage/v8/toggle/helper-error/demo.html @@ -0,0 +1,48 @@ + + + + + + Input + + + + + + + + + +
+ + Wi-Fi + +
+ + + + diff --git a/static/usage/v8/toggle/helper-error/index.md b/static/usage/v8/toggle/helper-error/index.md new file mode 100644 index 00000000000..a7b0d15d25d --- /dev/null +++ b/static/usage/v8/toggle/helper-error/index.md @@ -0,0 +1,24 @@ +import Playground from '@site/src/components/global/Playground'; + +import javascript from './javascript.md'; +import react from './react.md'; +import vue from './vue.md'; + +import angular_example_component_html from './angular/example_component_html.md'; +import angular_example_component_ts from './angular/example_component_ts.md'; + + diff --git a/static/usage/v8/toggle/helper-error/javascript.md b/static/usage/v8/toggle/helper-error/javascript.md new file mode 100644 index 00000000000..a4eb832ef06 --- /dev/null +++ b/static/usage/v8/toggle/helper-error/javascript.md @@ -0,0 +1,28 @@ +```html + + Wi-Fi + + + +``` diff --git a/static/usage/v8/toggle/helper-error/react.md b/static/usage/v8/toggle/helper-error/react.md new file mode 100644 index 00000000000..926a0bd0d2e --- /dev/null +++ b/static/usage/v8/toggle/helper-error/react.md @@ -0,0 +1,38 @@ +```tsx +import React, { useRef, useState } from 'react'; +import { IonToggle, ToggleCustomEvent } from '@ionic/react'; + +function Example() { + const wifiRef = useRef(null); + + const [isTouched, setIsTouched] = useState(false); + const [isValid, setIsValid] = useState(); + const [isChecked, setIsChecked] = useState(true); + + const validateToggle = (event: ToggleCustomEvent<{ checked: boolean }>) => { + setIsTouched(true); + setIsChecked(event.detail.checked); + setIsValid(event.detail.checked); + }; + + return ( + <> + validateToggle(event)} + > + Wi-Fi + + + ); +} + +export default Example; +``` diff --git a/static/usage/v8/toggle/helper-error/vue.md b/static/usage/v8/toggle/helper-error/vue.md new file mode 100644 index 00000000000..55a87adc295 --- /dev/null +++ b/static/usage/v8/toggle/helper-error/vue.md @@ -0,0 +1,47 @@ +```html + + + +``` From c0b9336e9eddfbec68f12f965ee6c333b718e964 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Tue, 11 Mar 2025 12:09:17 -0700 Subject: [PATCH 5/6] docs(select): add helperText and errorText section (#4029) Co-authored-by: Brandy Smith --- docs/api/select.md | 10 +++ .../angular/example_component_html.md | 19 +++++ .../angular/example_component_ts.md | 29 ++++++++ static/usage/v8/select/helper-error/demo.html | 68 ++++++++++++++++++ static/usage/v8/select/helper-error/index.md | 25 +++++++ .../v8/select/helper-error/javascript.md | 53 ++++++++++++++ static/usage/v8/select/helper-error/react.md | 72 +++++++++++++++++++ static/usage/v8/select/helper-error/vue.md | 68 ++++++++++++++++++ 8 files changed, 344 insertions(+) create mode 100644 static/usage/v8/select/helper-error/angular/example_component_html.md create mode 100644 static/usage/v8/select/helper-error/angular/example_component_ts.md create mode 100644 static/usage/v8/select/helper-error/demo.html create mode 100644 static/usage/v8/select/helper-error/index.md create mode 100644 static/usage/v8/select/helper-error/javascript.md create mode 100644 static/usage/v8/select/helper-error/react.md create mode 100644 static/usage/v8/select/helper-error/vue.md diff --git a/docs/api/select.md b/docs/api/select.md index 8a310608fce..0642c6e701d 100644 --- a/docs/api/select.md +++ b/docs/api/select.md @@ -253,6 +253,16 @@ import TypeaheadExample from '@site/static/usage/v8/select/typeahead/index.md'; +## Helper & Error Text + +Helper and error text can be used inside of a select with the `helperText` and `errorText` property. The error text will not be displayed unless the `ion-invalid` and `ion-touched` classes are added to the `ion-select`. This ensures errors are not shown before the user has a chance to enter data. + +In Angular, this is done automatically through form validation. In JavaScript, React and Vue, the class needs to be manually added based on your own validation. + +import HelperError from '@site/static/usage/v8/select/helper-error/index.md'; + + + ## Interfaces ### SelectChangeEventDetail diff --git a/static/usage/v8/select/helper-error/angular/example_component_html.md b/static/usage/v8/select/helper-error/angular/example_component_html.md new file mode 100644 index 00000000000..0e65b13e6fe --- /dev/null +++ b/static/usage/v8/select/helper-error/angular/example_component_html.md @@ -0,0 +1,19 @@ +```html +
+ + Apple + Banana + Orange + + +
+ + Submit +
+``` diff --git a/static/usage/v8/select/helper-error/angular/example_component_ts.md b/static/usage/v8/select/helper-error/angular/example_component_ts.md new file mode 100644 index 00000000000..6ac0561c716 --- /dev/null +++ b/static/usage/v8/select/helper-error/angular/example_component_ts.md @@ -0,0 +1,29 @@ +```ts +import { Component } from '@angular/core'; +import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms'; +import { IonSelect, IonSelectOption, IonButton } from '@ionic/angular/standalone'; + +@Component({ + selector: 'app-example', + standalone: true, + imports: [IonSelect, IonSelectOption, IonButton, ReactiveFormsModule], + templateUrl: './example.component.html', + styleUrl: './example.component.css', +}) +export class ExampleComponent { + myForm: FormGroup; + + constructor(private fb: FormBuilder) { + this.myForm = this.fb.group({ + favFruit: ['', Validators.required], + }); + } + + onSubmit() { + // Mark the control as touched to trigger the error message. + // This is needed if the user submits the form without interacting + // with the select. + this.myForm.get('favFruit')!.markAsTouched(); + } +} +``` diff --git a/static/usage/v8/select/helper-error/demo.html b/static/usage/v8/select/helper-error/demo.html new file mode 100644 index 00000000000..1d3a8647b97 --- /dev/null +++ b/static/usage/v8/select/helper-error/demo.html @@ -0,0 +1,68 @@ + + + + + + Input + + + + + + + +
+
+ + Apple + Banana + Orange + + +
+ + Submit +
+
+ + + + diff --git a/static/usage/v8/select/helper-error/index.md b/static/usage/v8/select/helper-error/index.md new file mode 100644 index 00000000000..6de3b40d644 --- /dev/null +++ b/static/usage/v8/select/helper-error/index.md @@ -0,0 +1,25 @@ +import Playground from '@site/src/components/global/Playground'; + +import javascript from './javascript.md'; +import react from './react.md'; +import vue from './vue.md'; + +import angular_example_component_html from './angular/example_component_html.md'; +import angular_example_component_ts from './angular/example_component_ts.md'; + + diff --git a/static/usage/v8/select/helper-error/javascript.md b/static/usage/v8/select/helper-error/javascript.md new file mode 100644 index 00000000000..41e595a05cf --- /dev/null +++ b/static/usage/v8/select/helper-error/javascript.md @@ -0,0 +1,53 @@ +```html +
+ + Apple + Banana + Orange + + +
+ + Submit +
+ + +``` diff --git a/static/usage/v8/select/helper-error/react.md b/static/usage/v8/select/helper-error/react.md new file mode 100644 index 00000000000..b8c4cd16904 --- /dev/null +++ b/static/usage/v8/select/helper-error/react.md @@ -0,0 +1,72 @@ +```tsx +import React, { useRef, useState } from 'react'; +import { IonSelect, IonSelectOption, IonButton, SelectCustomEvent } from '@ionic/react'; + +function Example() { + const [isTouched, setIsTouched] = useState(false); + const [isValid, setIsValid] = useState(); + + const favFruitRef = useRef(null); + + const validateSelect = (event: SelectCustomEvent<{ value: string }>) => { + setIsValid(event.detail.value ? true : false); + }; + + const markTouched = () => { + setIsTouched(true); + }; + + const onIonBlur = () => { + markTouched(); + + if (favFruitRef.current) { + validateSelect({ detail: { value: favFruitRef.current.value } } as SelectCustomEvent<{ + value: string; + }>); + } + }; + + const submit = (event: React.FormEvent) => { + event.preventDefault(); + + markTouched(); + + if (favFruitRef.current) { + validateSelect({ detail: { value: favFruitRef.current.value } } as SelectCustomEvent<{ + value: string; + }>); + } + }; + + return ( + <> +
+ validateSelect(event)} + onIonBlur={onIonBlur} + > + Apple + Banana + Orange + + +
+ + + Submit + +
+ + ); +} + +export default Example; +``` diff --git a/static/usage/v8/select/helper-error/vue.md b/static/usage/v8/select/helper-error/vue.md new file mode 100644 index 00000000000..83a477e922b --- /dev/null +++ b/static/usage/v8/select/helper-error/vue.md @@ -0,0 +1,68 @@ +```html + + + +``` From 0ba7b74bb82437a21b02ef90a43841d60769e38c Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Tue, 11 Mar 2025 12:09:34 -0700 Subject: [PATCH 6/6] docs(checkbox): add helperText and errorText section (#4028) Co-authored-by: Brandy Smith --- docs/api/checkbox.md | 10 ++++ .../angular/example_component_html.md | 15 +++++ .../angular/example_component_ts.md | 29 ++++++++++ .../usage/v8/checkbox/helper-error/demo.html | 55 +++++++++++++++++++ .../usage/v8/checkbox/helper-error/index.md | 24 ++++++++ .../v8/checkbox/helper-error/javascript.md | 37 +++++++++++++ .../usage/v8/checkbox/helper-error/react.md | 52 ++++++++++++++++++ static/usage/v8/checkbox/helper-error/vue.md | 53 ++++++++++++++++++ 8 files changed, 275 insertions(+) create mode 100644 static/usage/v8/checkbox/helper-error/angular/example_component_html.md create mode 100644 static/usage/v8/checkbox/helper-error/angular/example_component_ts.md create mode 100644 static/usage/v8/checkbox/helper-error/demo.html create mode 100644 static/usage/v8/checkbox/helper-error/index.md create mode 100644 static/usage/v8/checkbox/helper-error/javascript.md create mode 100644 static/usage/v8/checkbox/helper-error/react.md create mode 100644 static/usage/v8/checkbox/helper-error/vue.md diff --git a/docs/api/checkbox.md b/docs/api/checkbox.md index 900f827e237..a7b733f201d 100644 --- a/docs/api/checkbox.md +++ b/docs/api/checkbox.md @@ -74,6 +74,16 @@ import LabelLink from '@site/static/usage/v8/checkbox/label-link/index.md'; +## Helper & Error Text + +Helper and error text can be used inside of a checkbox with the `helperText` and `errorText` property. The error text will not be displayed unless the `ion-invalid` and `ion-touched` classes are added to the `ion-checkbox`. This ensures errors are not shown before the user has a chance to enter data. + +In Angular, this is done automatically through form validation. In JavaScript, React and Vue, the class needs to be manually added based on your own validation. + +import HelperError from '@site/static/usage/v8/checkbox/helper-error/index.md'; + + + ## Theming ### CSS Custom Properties diff --git a/static/usage/v8/checkbox/helper-error/angular/example_component_html.md b/static/usage/v8/checkbox/helper-error/angular/example_component_html.md new file mode 100644 index 00000000000..7153841ac36 --- /dev/null +++ b/static/usage/v8/checkbox/helper-error/angular/example_component_html.md @@ -0,0 +1,15 @@ +```html +
+ + I agree to the terms and conditions + + +
+ + Submit +
+``` diff --git a/static/usage/v8/checkbox/helper-error/angular/example_component_ts.md b/static/usage/v8/checkbox/helper-error/angular/example_component_ts.md new file mode 100644 index 00000000000..d8611d00de6 --- /dev/null +++ b/static/usage/v8/checkbox/helper-error/angular/example_component_ts.md @@ -0,0 +1,29 @@ +```ts +import { Component } from '@angular/core'; +import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms'; +import { IonCheckbox, IonButton } from '@ionic/angular/standalone'; + +@Component({ + selector: 'app-example', + standalone: true, + imports: [IonCheckbox, IonButton, ReactiveFormsModule], + templateUrl: './example.component.html', + styleUrl: './example.component.css', +}) +export class ExampleComponent { + myForm: FormGroup; + + constructor(private fb: FormBuilder) { + this.myForm = this.fb.group({ + agree: [false, Validators.requiredTrue], + }); + } + + onSubmit() { + // Mark the control as touched to trigger the error message. + // This is needed if the user submits the form without interacting + // with the checkbox. + this.myForm.get('agree')!.markAsTouched(); + } +} +``` diff --git a/static/usage/v8/checkbox/helper-error/demo.html b/static/usage/v8/checkbox/helper-error/demo.html new file mode 100644 index 00000000000..f16fd9b8503 --- /dev/null +++ b/static/usage/v8/checkbox/helper-error/demo.html @@ -0,0 +1,55 @@ + + + + + + Input + + + + + + + +
+
+ + I agree to the terms and conditions + + +
+ + Submit +
+
+ + + + diff --git a/static/usage/v8/checkbox/helper-error/index.md b/static/usage/v8/checkbox/helper-error/index.md new file mode 100644 index 00000000000..8a49f53d9c8 --- /dev/null +++ b/static/usage/v8/checkbox/helper-error/index.md @@ -0,0 +1,24 @@ +import Playground from '@site/src/components/global/Playground'; + +import javascript from './javascript.md'; +import react from './react.md'; +import vue from './vue.md'; + +import angular_example_component_html from './angular/example_component_html.md'; +import angular_example_component_ts from './angular/example_component_ts.md'; + + diff --git a/static/usage/v8/checkbox/helper-error/javascript.md b/static/usage/v8/checkbox/helper-error/javascript.md new file mode 100644 index 00000000000..0f7d8901ae2 --- /dev/null +++ b/static/usage/v8/checkbox/helper-error/javascript.md @@ -0,0 +1,37 @@ +```html +
+ + I agree to the terms and conditions + + +
+ + Submit +
+ + +``` diff --git a/static/usage/v8/checkbox/helper-error/react.md b/static/usage/v8/checkbox/helper-error/react.md new file mode 100644 index 00000000000..7c861fce639 --- /dev/null +++ b/static/usage/v8/checkbox/helper-error/react.md @@ -0,0 +1,52 @@ +```tsx +import React, { useRef, useState } from 'react'; +import { IonCheckbox, IonButton, CheckboxCustomEvent } from '@ionic/react'; + +function Example() { + const [isTouched, setIsTouched] = useState(false); + const [isValid, setIsValid] = useState(); + + const agreeRef = useRef(null); + + const validateCheckbox = (event: CheckboxCustomEvent<{ checked: boolean }>) => { + setIsTouched(true); + setIsValid(event.detail.checked); + }; + + const submit = (event: React.FormEvent) => { + event.preventDefault(); + + if (agreeRef.current) { + validateCheckbox({ detail: { checked: agreeRef.current.checked } } as CheckboxCustomEvent<{ + checked: boolean; + }>); + } + }; + + return ( + <> +
+ validateCheckbox(event)} + > + I agree to the terms and conditions + + +
+ + + Submit + +
+ + ); +} + +export default Example; +``` diff --git a/static/usage/v8/checkbox/helper-error/vue.md b/static/usage/v8/checkbox/helper-error/vue.md new file mode 100644 index 00000000000..46b554c9553 --- /dev/null +++ b/static/usage/v8/checkbox/helper-error/vue.md @@ -0,0 +1,53 @@ +```html + + + +```