Skip to content

Commit 2d9c682

Browse files
docs(toggle): add helperText and errorText section (#4033)
Co-authored-by: Brandy Smith <[email protected]>
1 parent cd309cc commit 2d9c682

File tree

8 files changed

+236
-0
lines changed

8 files changed

+236
-0
lines changed

docs/api/toggle.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,16 @@ import Justify from '@site/static/usage/v8/toggle/justify/index.md';
7373

7474
<Justify />
7575

76+
## Helper & Error Text
77+
78+
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.
79+
80+
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.
81+
82+
import HelperError from '@site/static/usage/v8/toggle/helper-error/index.md';
83+
84+
<HelperError />
85+
7686
## Theming
7787

7888
### Colors
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
```html
2+
<form [formGroup]="myForm">
3+
<ion-toggle
4+
formControlName="wifi"
5+
helperText="Enable to connect to available networks"
6+
errorText="Must be enabled to access the internet"
7+
justify="space-between"
8+
(ionChange)="onChange()"
9+
>
10+
Wi-Fi
11+
</ion-toggle>
12+
</form>
13+
```
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
```ts
2+
import { Component } from '@angular/core';
3+
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
4+
import { IonToggle } from '@ionic/angular/standalone';
5+
6+
@Component({
7+
selector: 'app-example',
8+
standalone: true,
9+
imports: [IonToggle, ReactiveFormsModule],
10+
templateUrl: './example.component.html',
11+
styleUrl: './example.component.css',
12+
})
13+
export class ExampleComponent {
14+
myForm: FormGroup;
15+
16+
constructor(private fb: FormBuilder) {
17+
this.myForm = this.fb.group({
18+
wifi: [true, Validators.requiredTrue],
19+
});
20+
}
21+
22+
onChange() {
23+
// Mark the control as touched to trigger the error message
24+
// without requiring the toggle to be blurred first
25+
this.myForm.get('wifi')!.markAsTouched();
26+
}
27+
}
28+
```
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Input</title>
7+
<link rel="stylesheet" href="../../common.css" />
8+
<script src="../../common.js"></script>
9+
<script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core@8/dist/ionic/ionic.esm.js"></script>
10+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core@8/css/ionic.bundle.css" />
11+
</head>
12+
13+
<body>
14+
<style>
15+
ion-toggle {
16+
width: 300px;
17+
}
18+
</style>
19+
20+
<div class="container">
21+
<ion-toggle
22+
helper-text="Enable to connect to available networks"
23+
error-text="Must be enabled to access the internet"
24+
checked
25+
>
26+
Wi-Fi
27+
</ion-toggle>
28+
</div>
29+
30+
<script>
31+
const wifi = document.querySelector('ion-toggle');
32+
33+
wifi.addEventListener('ionChange', (event) => validateToggle(event));
34+
35+
const validateToggle = (event) => {
36+
wifi.classList.add('ion-touched');
37+
38+
if (!event.detail.checked) {
39+
wifi.classList.add('ion-invalid');
40+
wifi.classList.remove('ion-valid');
41+
} else {
42+
wifi.classList.remove('ion-invalid');
43+
wifi.classList.add('ion-valid');
44+
}
45+
};
46+
</script>
47+
</body>
48+
</html>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import Playground from '@site/src/components/global/Playground';
2+
3+
import javascript from './javascript.md';
4+
import react from './react.md';
5+
import vue from './vue.md';
6+
7+
import angular_example_component_html from './angular/example_component_html.md';
8+
import angular_example_component_ts from './angular/example_component_ts.md';
9+
10+
<Playground
11+
version="8"
12+
code={{
13+
javascript,
14+
react,
15+
vue,
16+
angular: {
17+
files: {
18+
'src/app/example.component.html': angular_example_component_html,
19+
'src/app/example.component.ts': angular_example_component_ts,
20+
},
21+
},
22+
}}
23+
src="usage/v8/toggle/helper-error/demo.html"
24+
/>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
```html
2+
<ion-toggle
3+
helper-text="Enable to connect to available networks"
4+
error-text="Must be enabled to access the internet"
5+
justify="space-between"
6+
checked
7+
>
8+
Wi-Fi
9+
</ion-toggle>
10+
11+
<script>
12+
const wifi = document.querySelector('ion-toggle');
13+
14+
wifi.addEventListener('ionChange', (event) => validateToggle(event));
15+
16+
const validateToggle = (event) => {
17+
wifi.classList.add('ion-touched');
18+
19+
if (!event.detail.checked) {
20+
wifi.classList.add('ion-invalid');
21+
wifi.classList.remove('ion-valid');
22+
} else {
23+
wifi.classList.remove('ion-invalid');
24+
wifi.classList.add('ion-valid');
25+
}
26+
};
27+
</script>
28+
```
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
```tsx
2+
import React, { useRef, useState } from 'react';
3+
import { IonToggle, ToggleCustomEvent } from '@ionic/react';
4+
5+
function Example() {
6+
const wifiRef = useRef<HTMLIonToggleElement>(null);
7+
8+
const [isTouched, setIsTouched] = useState<boolean>(false);
9+
const [isValid, setIsValid] = useState<boolean | undefined>();
10+
const [isChecked, setIsChecked] = useState<boolean>(true);
11+
12+
const validateToggle = (event: ToggleCustomEvent<{ checked: boolean }>) => {
13+
setIsTouched(true);
14+
setIsChecked(event.detail.checked);
15+
setIsValid(event.detail.checked);
16+
};
17+
18+
return (
19+
<>
20+
<IonToggle
21+
ref={wifiRef}
22+
className={`${isValid ? 'ion-valid' : ''} ${isValid === false ? 'ion-invalid' : ''} ${
23+
isTouched ? 'ion-touched' : ''
24+
}`}
25+
helperText="Enable to connect to available networks"
26+
errorText="Must be enabled to access the internet"
27+
justify="space-between"
28+
checked={isChecked}
29+
onIonChange={(event) => validateToggle(event)}
30+
>
31+
Wi-Fi
32+
</IonToggle>
33+
</>
34+
);
35+
}
36+
37+
export default Example;
38+
```
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
```html
2+
<template>
3+
<ion-toggle
4+
v-model="wifi"
5+
helper-text="Enable to connect to available networks"
6+
error-text="Must be enabled to access the internet"
7+
justify="space-between"
8+
@ionChange="validateToggle"
9+
:class="{
10+
'ion-valid': isValid,
11+
'ion-invalid': isValid === false,
12+
'ion-touched': isTouched,
13+
}"
14+
>
15+
Wi-Fi
16+
</ion-toggle>
17+
</template>
18+
19+
<script lang="ts">
20+
import { defineComponent, ref } from 'vue';
21+
import { IonToggle, IonButton, ToggleCustomEvent } from '@ionic/vue';
22+
23+
export default defineComponent({
24+
components: {
25+
IonToggle,
26+
IonButton,
27+
},
28+
setup() {
29+
const wifi = ref(true);
30+
const isTouched = ref(false);
31+
const isValid = ref<boolean | undefined>();
32+
33+
const validateToggle = (event: ToggleCustomEvent<{ checked: boolean }>) => {
34+
isTouched.value = true;
35+
isValid.value = event.detail.checked;
36+
};
37+
38+
return {
39+
wifi,
40+
isTouched,
41+
isValid,
42+
validateToggle,
43+
};
44+
},
45+
});
46+
</script>
47+
```

0 commit comments

Comments
 (0)