diff --git a/.github/COMPONENT-GUIDE.md b/.github/COMPONENT-GUIDE.md
index fb9de8eb38..5e54bec125 100644
--- a/.github/COMPONENT-GUIDE.md
+++ b/.github/COMPONENT-GUIDE.md
@@ -11,6 +11,7 @@
* [References](#references)
- [Accessibility](#accessibility)
* [Checkbox](#checkbox)
+ * [Switch](#switch)
- [Rendering Anchor or Button](#rendering-anchor-or-button)
* [Example Components](#example-components-1)
* [Component Structure](#component-structure-1)
@@ -371,7 +372,6 @@ ion-ripple-effect {
#### Example Components
- [ion-checkbox](https://github.com/ionic-team/ionic/tree/master/core/src/components/checkbox)
-- [ion-toggle](https://github.com/ionic-team/ionic/tree/master/core/src/components/toggle)
#### VoiceOver
@@ -432,9 +432,13 @@ const { label, labelId, labelText } = getAriaLabel(el, inputId);
where `el` and `inputId` are the following:
```tsx
-private inputId = `ion-cb-${checkboxIds++}`;
+export class Checkbox implements ComponentInterface {
+ private inputId = `ion-cb-${checkboxIds++}`;
-@Element() el!: HTMLElement;
+ @Element() el!: HTMLElement;
+
+ ...
+}
```
This can then be added to the `Host` like the following:
@@ -448,7 +452,7 @@ This can then be added to the `Host` like the following:
>
```
-In addition to that, the checkbox should have a label added:
+In addition to that, the checkbox input should have a label added:
```tsx
+
+ ...
+
+ );
+}
+```
+
+#### NVDA
+
+It is required to have `aria-checked` on the native input for checked to read properly and `disabled` to prevent tabbing to the input:
+
+```tsx
+render() {
+ const { checked, disabled } = this;
+
+ return (
+
+
+ ...
+
+ );
+}
+```
+
+#### Labels
+
+A helper function has been created to get the proper `aria-label` for the switch. This can be imported as `getAriaLabel` like the following:
+
+```tsx
+const { label, labelId, labelText } = getAriaLabel(el, inputId);
+```
+
+where `el` and `inputId` are the following:
+
+```tsx
+export class Toggle implements ComponentInterface {
+ private inputId = `ion-tg-${toggleIds++}`;
+
+ @Element() el!: HTMLElement;
+
+ ...
+}
+```
+
+This can then be added to the `Host` like the following:
+
+```tsx
+
+```
+
+In addition to that, the checkbox input should have a label added:
+
+```tsx
+
+
+ {labelText}
+
+
+```
+
+
+#### Hidden Input
+
+A helper function to render a hidden input has been added, it can be added in the `render`:
+
+```tsx
+renderHiddenInput(true, el, name, (checked ? value : ''), disabled);
+```
+
+> This is required for the switch to work with forms.
+
+
+#### Known Issues
+
+When using VoiceOver on macOS or iOS, Chrome will announce the switch as a checked or unchecked `checkbox`:
+
+```
+You are currently on a switch. To select or deselect this checkbox, press Control-Option-Space.
+```
+
+There is a WebKit bug open for this: https://bugs.webkit.org/show_bug.cgi?id=196354
+
+
## Rendering Anchor or Button
Certain components can render an `` or a `` depending on the presence of an `href` attribute.
diff --git a/.scripts/common.js b/.scripts/common.js
index 738b5ace7e..f43d416397 100644
--- a/.scripts/common.js
+++ b/.scripts/common.js
@@ -10,7 +10,6 @@ const rootDir = path.join(__dirname, '../');
const packages = [
'core',
- 'core/components',
'docs',
'angular',
'packages/react',
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cb3f266c13..cfc64517f2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,32 @@
+# [5.6.0 Argon](https://github.com/ionic-team/ionic/compare/v5.5.4...v5.6.0) (2021-03-04)
+
+
+### Bug Fixes
+
+* **all:** improve support for ids with special characters when getting label element ([#22680](https://github.com/ionic-team/ionic/issues/22680)) ([19d63f6](https://github.com/ionic-team/ionic/commit/19d63f62431ef9d8279f1726dd63fac2f0d4b46b)), closes [#22678](https://github.com/ionic-team/ionic/issues/22678)
+* **header:** collapsed toolbar is no longer incorrectly shown when using ion-refresher ([#22937](https://github.com/ionic-team/ionic/issues/22937)) ([5300dcc](https://github.com/ionic-team/ionic/commit/5300dcc693caf51a726f8c346cfc9a44474fd3d1)), closes [#22829](https://github.com/ionic-team/ionic/issues/22829)
+* **label:** only show placeholder with floating label when focused ([#22958](https://github.com/ionic-team/ionic/issues/22958)) ([9282aa6](https://github.com/ionic-team/ionic/commit/9282aa68715c088e9c8fcd915e78fb7ae91f551f)), closes [#17571](https://github.com/ionic-team/ionic/issues/17571)
+* **progress-bar:** use correct theme colors in dark mode ([#22965](https://github.com/ionic-team/ionic/issues/22965)) ([b6b2714](https://github.com/ionic-team/ionic/commit/b6b2714d70f71255315510c5e49708944875db72)), closes [#20098](https://github.com/ionic-team/ionic/issues/20098)
+* **radio-group:** pressing space no longer jumps screen to bottom of page ([#22892](https://github.com/ionic-team/ionic/issues/22892)) ([3a0465e](https://github.com/ionic-team/ionic/commit/3a0465e7d6f9e3cb01336a8bdbd7001e4ec34559)), closes [#22716](https://github.com/ionic-team/ionic/issues/22716)
+* **react:** IonRouterOutlet now respects animated={false} prop ([#22905](https://github.com/ionic-team/ionic/issues/22905)) ([da1b7a0](https://github.com/ionic-team/ionic/commit/da1b7a0e7a9a5e6a9120dc4d5459c97d8bca5390)), closes [#22903](https://github.com/ionic-team/ionic/issues/22903)
+* **react:** onIonTabsWillChange and onIonTabsDidChange event handlers are now properly bound to IonTabs ([#22233](https://github.com/ionic-team/ionic/issues/22233)) ([b064fde](https://github.com/ionic-team/ionic/commit/b064fdebef14018b77242b791914d5bb10863d39))
+* **react, vue:** navigating using ion-back-button now selects correct page ([#22974](https://github.com/ionic-team/ionic/issues/22974)) ([cd8ffd8](https://github.com/ionic-team/ionic/commit/cd8ffd82a03ee69ef4cbd7922544bfc39680def9)), closes [#22830](https://github.com/ionic-team/ionic/issues/22830)
+* **react, vue:** tab buttons no longer throw an error if href is undefined ([#22998](https://github.com/ionic-team/ionic/issues/22998)) ([943e3f6](https://github.com/ionic-team/ionic/commit/943e3f6ae37ecc56f21168f057dde77a05e4e144)), closes [#22997](https://github.com/ionic-team/ionic/issues/22997)
+* **refresher:** add correct dark mode styles ([#22639](https://github.com/ionic-team/ionic/issues/22639)) ([c05476b](https://github.com/ionic-team/ionic/commit/c05476b88e3e6884b4c490461c9c67dee3dca83d)), closes [#22637](https://github.com/ionic-team/ionic/issues/22637)
+* **vue:** correctly remove active state from tab button when navigating away from tab ([#23000](https://github.com/ionic-team/ionic/issues/23000)) ([a2763af](https://github.com/ionic-team/ionic/commit/a2763afe8e1fe1dc0decdbcb757a03bc5038045e)), closes [#22597](https://github.com/ionic-team/ionic/issues/22597)
+* **vue:** prevent race conditions when opening overlays ([#22883](https://github.com/ionic-team/ionic/issues/22883)) ([68a9b80](https://github.com/ionic-team/ionic/commit/68a9b800532f9c0b308a3b74ed18a7068a942301)), closes [#22880](https://github.com/ionic-team/ionic/issues/22880)
+
+
+### Features
+
+* **custom-elements:** add experimental custom elements build ([#22863](https://github.com/ionic-team/ionic/issues/22863)) ([0de75af](https://github.com/ionic-team/ionic/commit/0de75afbefc521c1d76adcd587f77ba19c285a95))
+* **progress-bar:** add parts for more design customization ([#22938](https://github.com/ionic-team/ionic/issues/22938)) ([e256d3f](https://github.com/ionic-team/ionic/commit/e256d3f09fd6f231c4d9e1d0f0927612a591466b)), closes [#20062](https://github.com/ionic-team/ionic/issues/20062) [#21820](https://github.com/ionic-team/ionic/issues/21820)
+* **react:** add react hooks to control overlay components ([#22484](https://github.com/ionic-team/ionic/issues/22484)) ([b83e009](https://github.com/ionic-team/ionic/commit/b83e00934e794a936c9d3d23d7f94bbe89cedcd5))
+* **searchbar:** add showClearIcon property ([#22759](https://github.com/ionic-team/ionic/issues/22759)) ([215eb5d](https://github.com/ionic-team/ionic/commit/215eb5d4efbb9ade942dba1687469caf61da21e7)), closes [#22738](https://github.com/ionic-team/ionic/issues/22738)
+* **vue:** add composition API ionic lifecycle hooks ([#22970](https://github.com/ionic-team/ionic/issues/22970)) ([dd1c8db](https://github.com/ionic-team/ionic/commit/dd1c8dbf3b20fbd423f70c96846d9c366d90e7c5)), closes [#22769](https://github.com/ionic-team/ionic/issues/22769)
+
+
+
## [5.5.5](https://github.com/ionic-team/ionic/compare/v5.5.4...v5.5.5) (2021-02-26)
diff --git a/angular/package-lock.json b/angular/package-lock.json
index 99181eb548..cd759d1bc0 100644
--- a/angular/package-lock.json
+++ b/angular/package-lock.json
@@ -1,15 +1,15 @@
{
"name": "@ionic/angular",
- "version": "5.5.5",
+ "version": "5.6.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/angular",
- "version": "5.5.5",
+ "version": "5.6.0",
"license": "MIT",
"dependencies": {
- "@ionic/core": "5.5.4",
+ "@ionic/core": "5.5.5",
"tslib": "^1.9.3"
},
"devDependencies": {
@@ -204,9 +204,9 @@
}
},
"node_modules/@ionic/core": {
- "version": "5.5.4",
- "resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.5.4.tgz",
- "integrity": "sha512-IjbGN8vh3XuJ2ulo3BMlMflcWlUhvEGEexr29JKFvb+O4bWKP5sC2fkqSrswrIstOmv7axm7CeIi2MNRkwYwVA==",
+ "version": "5.5.5",
+ "resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.5.5.tgz",
+ "integrity": "sha512-i5KTiRuGa9PTUULy8rTQDDDw3FbxzYiOoSdKGNC0v7UOpMv9ReRixMWd5J0cfY17VRrua2aqNsqZXYwuInVnRQ==",
"dependencies": {
"ionicons": "^5.1.2",
"tslib": "^1.10.0"
@@ -5150,9 +5150,9 @@
}
},
"@ionic/core": {
- "version": "5.5.4",
- "resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.5.4.tgz",
- "integrity": "sha512-IjbGN8vh3XuJ2ulo3BMlMflcWlUhvEGEexr29JKFvb+O4bWKP5sC2fkqSrswrIstOmv7axm7CeIi2MNRkwYwVA==",
+ "version": "5.5.5",
+ "resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.5.5.tgz",
+ "integrity": "sha512-i5KTiRuGa9PTUULy8rTQDDDw3FbxzYiOoSdKGNC0v7UOpMv9ReRixMWd5J0cfY17VRrua2aqNsqZXYwuInVnRQ==",
"requires": {
"ionicons": "^5.1.2",
"tslib": "^1.10.0"
diff --git a/angular/package.json b/angular/package.json
index 2cef7e5356..891fd9e647 100644
--- a/angular/package.json
+++ b/angular/package.json
@@ -1,6 +1,6 @@
{
"name": "@ionic/angular",
- "version": "5.5.5",
+ "version": "5.6.0",
"description": "Angular specific wrappers for @ionic/core",
"keywords": [
"ionic",
@@ -42,7 +42,7 @@
"validate": "npm i && npm run lint && npm run test && npm run build"
},
"dependencies": {
- "@ionic/core": "5.5.5",
+ "@ionic/core": "5.6.0",
"tslib": "^1.9.3"
},
"peerDependencies": {
diff --git a/angular/test/test-app/package.json b/angular/test/test-app/package.json
index 037fc52676..7e21824abf 100644
--- a/angular/test/test-app/package.json
+++ b/angular/test/test-app/package.json
@@ -8,7 +8,7 @@
"sync:build": "sh scripts/build-ionic.sh",
"sync": "sh scripts/sync.sh",
"build": "npm run sync && ng build --prod --no-progress",
- "pretest": "webdriver-manager update --versions.chrome 87.0.4280.20",
+ "pretest": "webdriver-manager update --versions.chrome 89.0.4389.23",
"test": "ng e2e --prod --webdriver-update=false",
"test.dev": "npm run sync && ng e2e",
"lint": "ng lint",
diff --git a/core/api.txt b/core/api.txt
index 64adb53dd2..5d34b7902c 100644
--- a/core/api.txt
+++ b/core/api.txt
@@ -844,6 +844,9 @@ ion-progress-bar,prop,value,number,0,false,false
ion-progress-bar,css-prop,--background
ion-progress-bar,css-prop,--buffer-background
ion-progress-bar,css-prop,--progress-background
+ion-progress-bar,part,progress
+ion-progress-bar,part,stream
+ion-progress-bar,part,track
ion-radio,shadow
ion-radio,prop,color,string | undefined,undefined,false,false
diff --git a/core/package-lock.json b/core/package-lock.json
index af09a28e5f..f98a2e5f2e 100644
--- a/core/package-lock.json
+++ b/core/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@ionic/core",
- "version": "5.5.5",
+ "version": "5.6.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/core",
- "version": "5.5.5",
+ "version": "5.6.0",
"license": "MIT",
"dependencies": {
"@stencil/core": "^2.4.0",
diff --git a/core/package.json b/core/package.json
index d25db533e8..3eeb39278a 100644
--- a/core/package.json
+++ b/core/package.json
@@ -1,6 +1,6 @@
{
"name": "@ionic/core",
- "version": "5.5.5",
+ "version": "5.6.0",
"description": "Base components for Ionic",
"keywords": [
"ionic",
diff --git a/core/src/components.d.ts b/core/src/components.d.ts
index a91597b370..69feb020ca 100644
--- a/core/src/components.d.ts
+++ b/core/src/components.d.ts
@@ -1225,7 +1225,7 @@ export namespace Components {
*/
"close": (animated?: boolean) => Promise;
/**
- * The content's id the menu should use.
+ * The `id` of the main content. When using a router this is typically `ion-router-outlet`. When not using a router, this is typically your main view's `ion-content`. This is not the id of the `ion-content` inside of your `ion-menu`.
*/
"contentId"?: string;
/**
@@ -2303,7 +2303,7 @@ export namespace Components {
}
interface IonSplitPane {
/**
- * The content `id` of the split-pane's main content.
+ * The `id` of the main content. When using a router this is typically `ion-router-outlet`. When not using a router, this is typically your main view's `ion-content`. This is not the id of the `ion-content` inside of your `ion-menu`.
*/
"contentId"?: string;
/**
@@ -4568,7 +4568,7 @@ declare namespace LocalJSX {
}
interface IonMenu {
/**
- * The content's id the menu should use.
+ * The `id` of the main content. When using a router this is typically `ion-router-outlet`. When not using a router, this is typically your main view's `ion-content`. This is not the id of the `ion-content` inside of your `ion-menu`.
*/
"contentId"?: string;
/**
@@ -5625,7 +5625,7 @@ declare namespace LocalJSX {
}
interface IonSplitPane {
/**
- * The content `id` of the split-pane's main content.
+ * The `id` of the main content. When using a router this is typically `ion-router-outlet`. When not using a router, this is typically your main view's `ion-content`. This is not the id of the `ion-content` inside of your `ion-menu`.
*/
"contentId"?: string;
/**
diff --git a/core/src/components/action-sheet/readme.md b/core/src/components/action-sheet/readme.md
index 83690632c5..d43895b277 100644
--- a/core/src/components/action-sheet/readme.md
+++ b/core/src/components/action-sheet/readme.md
@@ -155,6 +155,59 @@ async function presentActionSheet() {
### React
```tsx
+/* Using with useIonActionSheet Hook */
+
+import React from 'react';
+import {
+ IonButton,
+ IonContent,
+ IonPage,
+ useIonActionSheet,
+} from '@ionic/react';
+
+const ActionSheetExample: React.FC = () => {
+ const [present, dismiss] = useIonActionSheet();
+
+ return (
+
+
+
+ present({
+ buttons: [{ text: 'Ok' }, { text: 'Cancel' }],
+ header: 'Action Sheet'
+ })
+ }
+ >
+ Show ActionSheet
+
+
+ present([{ text: 'Ok' }, { text: 'Cancel' }], 'Action Sheet')
+ }
+ >
+ Show ActionSheet using params
+
+ {
+ present([{ text: 'Ok' }, { text: 'Cancel' }], 'Action Sheet');
+ setTimeout(dismiss, 3000);
+ }}
+ >
+ Show ActionSheet, hide after 3 seconds
+
+
+
+ );
+};
+```
+
+```tsx
+/* Using with IonActionSheet Component */
+
import React, { useState } from 'react';
import { IonActionSheet, IonContent, IonButton } from '@ionic/react';
import { trash, share, caretForwardCircle, heart, close } from 'ionicons/icons';
diff --git a/core/src/components/action-sheet/usage/react.md b/core/src/components/action-sheet/usage/react.md
index ed9cc8505c..7259fed327 100644
--- a/core/src/components/action-sheet/usage/react.md
+++ b/core/src/components/action-sheet/usage/react.md
@@ -1,4 +1,57 @@
```tsx
+/* Using with useIonActionSheet Hook */
+
+import React from 'react';
+import {
+ IonButton,
+ IonContent,
+ IonPage,
+ useIonActionSheet,
+} from '@ionic/react';
+
+const ActionSheetExample: React.FC = () => {
+ const [present, dismiss] = useIonActionSheet();
+
+ return (
+
+
+
+ present({
+ buttons: [{ text: 'Ok' }, { text: 'Cancel' }],
+ header: 'Action Sheet'
+ })
+ }
+ >
+ Show ActionSheet
+
+
+ present([{ text: 'Ok' }, { text: 'Cancel' }], 'Action Sheet')
+ }
+ >
+ Show ActionSheet using params
+
+ {
+ present([{ text: 'Ok' }, { text: 'Cancel' }], 'Action Sheet');
+ setTimeout(dismiss, 3000);
+ }}
+ >
+ Show ActionSheet, hide after 3 seconds
+
+
+
+ );
+};
+```
+
+```tsx
+/* Using with IonActionSheet Component */
+
import React, { useState } from 'react';
import { IonActionSheet, IonContent, IonButton } from '@ionic/react';
import { trash, share, caretForwardCircle, heart, close } from 'ionicons/icons';
diff --git a/core/src/components/alert/readme.md b/core/src/components/alert/readme.md
index ab7fa95b9b..28f0cd6089 100644
--- a/core/src/components/alert/readme.md
+++ b/core/src/components/alert/readme.md
@@ -588,6 +588,48 @@ function presentAlertCheckbox() {
### React
```tsx
+/* Using with useIonAlert Hook */
+
+import React from 'react';
+import { IonButton, IonContent, IonPage, useIonAlert } from '@ionic/react';
+
+const AlertExample: React.FC = () => {
+ const [present] = useIonAlert();
+ return (
+
+
+
+ present({
+ cssClass: 'my-css',
+ header: 'Alert',
+ message: 'alert from hook',
+ buttons: [
+ 'Cancel',
+ { text: 'Ok', handler: (d) => console.log('ok pressed') },
+ ],
+ onDidDismiss: (e) => console.log('did dismiss'),
+ })
+ }
+ >
+ Show Alert
+
+ present('hello with params', [{ text: 'Ok' }])}
+ >
+ Show Alert using params
+
+
+
+ );
+};
+```
+
+```tsx
+/* Using with IonAlert Component */
+
import React, { useState } from 'react';
import { IonAlert, IonButton, IonContent } from '@ionic/react';
diff --git a/core/src/components/alert/usage/react.md b/core/src/components/alert/usage/react.md
index 4776e11bb3..17a365d434 100644
--- a/core/src/components/alert/usage/react.md
+++ b/core/src/components/alert/usage/react.md
@@ -1,4 +1,46 @@
```tsx
+/* Using with useIonAlert Hook */
+
+import React from 'react';
+import { IonButton, IonContent, IonPage, useIonAlert } from '@ionic/react';
+
+const AlertExample: React.FC = () => {
+ const [present] = useIonAlert();
+ return (
+
+
+
+ present({
+ cssClass: 'my-css',
+ header: 'Alert',
+ message: 'alert from hook',
+ buttons: [
+ 'Cancel',
+ { text: 'Ok', handler: (d) => console.log('ok pressed') },
+ ],
+ onDidDismiss: (e) => console.log('did dismiss'),
+ })
+ }
+ >
+ Show Alert
+
+ present('hello with params', [{ text: 'Ok' }])}
+ >
+ Show Alert using params
+
+
+
+ );
+};
+```
+
+```tsx
+/* Using with IonAlert Component */
+
import React, { useState } from 'react';
import { IonAlert, IonButton, IonContent } from '@ionic/react';
diff --git a/core/src/components/input/input.scss b/core/src/components/input/input.scss
index fed9c749ad..d0c1a28802 100644
--- a/core/src/components/input/input.scss
+++ b/core/src/components/input/input.scss
@@ -169,3 +169,18 @@
:host(.has-focus) button {
pointer-events: auto;
}
+
+
+// Item Floating: Placeholder
+// ----------------------------------------------------------------
+// When used with a floating item the placeholder should hide
+
+:host-context(.item-label-floating.item-has-placeholder:not(.item-has-value)) {
+ transition: opacity 0.15s cubic-bezier(0.4, 0, 0.2, 1);
+
+ opacity: 0;
+}
+
+:host-context(.item-label-floating.item-has-placeholder:not(.item-has-value).item-has-focus) {
+ opacity: 1;
+}
diff --git a/core/src/components/input/input.tsx b/core/src/components/input/input.tsx
index 6b579e2012..8615969850 100644
--- a/core/src/components/input/input.tsx
+++ b/core/src/components/input/input.tsx
@@ -190,15 +190,6 @@ export class Input implements ComponentInterface {
*/
@Prop({ mutable: true }) value?: string | number | null = '';
- /**
- * Update the native input element when the value changes
- */
- @Watch('value')
- protected valueChanged() {
- this.emitStyle();
- this.ionChange.emit({ value: this.value == null ? this.value : this.value.toString() });
- }
-
/**
* Emitted when a keyboard input occurred.
*/
@@ -225,6 +216,23 @@ export class Input implements ComponentInterface {
*/
@Event() ionStyle!: EventEmitter;
+ /**
+ * Update the item classes when the placeholder changes
+ */
+ @Watch('placeholder')
+ protected placeholderChanged() {
+ this.emitStyle();
+ }
+
+ /**
+ * Update the native input element when the value changes
+ */
+ @Watch('value')
+ protected valueChanged() {
+ this.emitStyle();
+ this.ionChange.emit({ value: this.value == null ? this.value : this.value.toString() });
+ }
+
componentWillLoad() {
this.inheritedAttributes = inheritAttributes(this.el, ['tabindex', 'title']);
}
diff --git a/core/src/components/input/test/basic/index.html b/core/src/components/input/test/basic/index.html
index aa8a3cc3c1..48b543e4c1 100644
--- a/core/src/components/input/test/basic/index.html
+++ b/core/src/components/input/test/basic/index.html
@@ -132,11 +132,11 @@
Right
-